1 /* $NetBSD: connector_fdt.c,v 1.5 2021/01/27 03:10:21 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 2018 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Manuel Bouyer. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * connector driver. 34 * specified in linux/Documentation/devicetree/bindings/display/connector/ 35 * basically it only register its endpoint. 36 */ 37 38 #include <sys/cdefs.h> 39 40 __KERNEL_RCSID(1, "$NetBSD: connector_fdt.c,v 1.5 2021/01/27 03:10:21 thorpej Exp $"); 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/device.h> 45 #include <sys/bus.h> 46 #include <sys/kmem.h> 47 48 #include <dev/fdt/fdtvar.h> 49 #include <dev/fdt/fdt_port.h> 50 #include <dev/fdt/connector_fdt.h> 51 52 static int fdt_connector_match(device_t, cfdata_t, void *); 53 static void fdt_connector_attach(device_t, device_t, void *); 54 static void *fdt_connector_get_data(device_t, struct fdt_endpoint *); 55 56 SLIST_HEAD(, fdt_connector_softc) fdt_connectors = 57 SLIST_HEAD_INITIALIZER(&fdt_connectors); 58 59 struct fdt_connector_softc { 60 device_t sc_dev; 61 int sc_phandle; 62 struct fdt_connector sc_con; 63 SLIST_ENTRY(fdt_connector_softc) sc_list; 64 struct fdt_device_ports sc_ports; 65 }; 66 67 #define sc_type sc_con.con_type 68 69 CFATTACH_DECL_NEW(fdt_connector, sizeof(struct fdt_connector_softc), 70 fdt_connector_match, fdt_connector_attach, NULL, NULL); 71 72 static const struct device_compatible_entry compat_data[] = { 73 { .compat = "composite-video-connector", .value = CON_TV}, 74 { .compat = "dvi-connector", .value = CON_DVI}, 75 { .compat = "hdmi-connector", .value = CON_HDMI}, 76 { .compat = "vga-connector", .value = CON_VGA}, 77 DEVICE_COMPAT_EOL 78 }; 79 80 static int 81 fdt_connector_match(device_t parent, cfdata_t cf, void *aux) 82 { 83 const struct fdt_attach_args *faa = aux; 84 85 return of_compatible_match(faa->faa_phandle, compat_data); 86 } 87 88 static void 89 fdt_connector_attach(device_t parent, device_t self, void *aux) 90 { 91 struct fdt_connector_softc *sc = device_private(self); 92 const struct fdt_attach_args * const faa = aux; 93 const int phandle = faa->faa_phandle; 94 95 sc->sc_dev = self; 96 sc->sc_phandle = phandle; 97 sc->sc_type = of_compatible_lookup(phandle, compat_data)->value; 98 99 SLIST_INSERT_HEAD(&fdt_connectors, sc, sc_list); 100 101 aprint_naive("\n"); 102 switch(sc->sc_type) { 103 case CON_VGA: 104 aprint_normal(": VGA"); 105 break; 106 case CON_DVI: 107 aprint_normal(": DVI"); 108 break; 109 case CON_HDMI: 110 aprint_normal(": HDMI"); 111 break; 112 case CON_TV: 113 aprint_normal(": composite"); 114 break; 115 default: 116 panic("unknown connector type %d\n", sc->sc_type); 117 } 118 aprint_normal(" connector\n"); 119 sc->sc_ports.dp_ep_get_data = fdt_connector_get_data; 120 fdt_ports_register(&sc->sc_ports, self, phandle, EP_CONNECTOR); 121 } 122 123 static void * 124 fdt_connector_get_data(device_t dev, struct fdt_endpoint *ep) 125 { 126 struct fdt_connector_softc *sc = device_private(dev); 127 128 return &sc->sc_con; 129 } 130