2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2009 Oleksandr Tymoshenko <gonzo@freebsd.org>
5 * Copyright (c) 2010 Luiz Otavio O Souza
6 * Copyright (c) 2019 Ian Lepore <ian@freebsd.org>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include "opt_platform.h"
35 #include <sys/param.h>
36 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/module.h>
42 #include <dev/gpio/gpiobusvar.h>
43 #include <dev/iicbus/iiconf.h>
45 #include "gpiobus_if.h"
48 #define GPIOIIC_SCL_DFLT 0
49 #define GPIOIIC_SDA_DFLT 1
50 #define GPIOIIC_MIN_PINS 2
61 #include <dev/ofw/ofw_bus.h>
63 static struct ofw_compat_data compat_data[] = {
64 {"i2c-gpio", true}, /* Standard devicetree compat string */
65 {"gpioiic", true}, /* Deprecated old freebsd compat string */
68 OFWBUS_PNP_INFO(compat_data);
69 SIMPLEBUS_PNP_INFO(compat_data);
72 gpioiic_get_node(device_t bus, device_t dev)
75 /* Share our fdt node with iicbus so it can find its child nodes. */
76 return (ofw_bus_get_node(bus));
80 gpioiic_setup_fdt_pins(struct gpioiic_softc *sc)
85 node = ofw_bus_get_node(sc->dev);
88 * Historically, we used the first two array elements of the gpios
89 * property. The modern bindings specify separate scl-gpios and
90 * sda-gpios properties. We cope with whichever is present.
92 if (OF_hasprop(node, "gpios")) {
93 if ((err = gpio_pin_get_by_ofw_idx(sc->dev, node,
94 GPIOIIC_SCL_DFLT, &sc->sclpin)) != 0) {
95 device_printf(sc->dev, "invalid gpios property\n");
98 if ((err = gpio_pin_get_by_ofw_idx(sc->dev, node,
99 GPIOIIC_SDA_DFLT, &sc->sdapin)) != 0) {
100 device_printf(sc->dev, "ivalid gpios property\n");
104 if ((err = gpio_pin_get_by_ofw_property(sc->dev, node,
105 "scl-gpios", &sc->sclpin)) != 0) {
106 device_printf(sc->dev, "missing scl-gpios property\n");
109 if ((err = gpio_pin_get_by_ofw_property(sc->dev, node,
110 "sda-gpios", &sc->sdapin)) != 0) {
111 device_printf(sc->dev, "missing sda-gpios property\n");
120 gpioiic_setup_hinted_pins(struct gpioiic_softc *sc)
123 const char *busname, *devname;
124 int err, numpins, sclnum, sdanum, unit;
126 devname = device_get_name(sc->dev);
127 unit = device_get_unit(sc->dev);
128 busdev = device_get_parent(sc->dev);
131 * If there is not an "at" hint naming our actual parent, then we
132 * weren't instantiated as a child of gpiobus via hints, and we thus
133 * can't access ivars that only exist for such children.
135 if (resource_string_value(devname, unit, "at", &busname) != 0 ||
136 (strcmp(busname, device_get_nameunit(busdev)) != 0 &&
137 strcmp(busname, device_get_name(busdev)) != 0)) {
141 /* Make sure there were hints for at least two pins. */
142 numpins = gpiobus_get_npins(sc->dev);
143 if (numpins < GPIOIIC_MIN_PINS) {
146 * Be silent when there are no hints on FDT systems; the FDT
147 * data will provide the pin config (we'll whine if it doesn't).
153 device_printf(sc->dev,
154 "invalid pins hint; it must contain at least %d pins\n",
160 * Our parent bus has already parsed the pins hint and it will use that
161 * info when we call gpio_pin_get_by_child_index(). But we have to
162 * handle the scl/sda index hints that tell us which of the two pins is
163 * the clock and which is the data. They're optional, but if present
164 * they must be a valid index (0 <= index < numpins).
166 if ((err = resource_int_value(devname, unit, "scl", &sclnum)) != 0)
167 sclnum = GPIOIIC_SCL_DFLT;
168 else if (sclnum < 0 || sclnum >= numpins) {
169 device_printf(sc->dev, "invalid scl hint %d\n", sclnum);
172 if ((err = resource_int_value(devname, unit, "sda", &sdanum)) != 0)
173 sdanum = GPIOIIC_SDA_DFLT;
174 else if (sdanum < 0 || sdanum >= numpins) {
175 device_printf(sc->dev, "invalid sda hint %d\n", sdanum);
179 /* Allocate gpiobus_pin structs for the pins we found above. */
180 if ((err = gpio_pin_get_by_child_index(sc->dev, sclnum,
183 if ((err = gpio_pin_get_by_child_index(sc->dev, sdanum,
191 gpioiic_setsda(device_t dev, int val)
193 struct gpioiic_softc *sc = device_get_softc(dev);
196 gpio_pin_setflags(sc->sdapin, GPIO_PIN_INPUT);
198 gpio_pin_setflags(sc->sdapin,
199 GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN);
200 gpio_pin_set_active(sc->sdapin, 0);
205 gpioiic_setscl(device_t dev, int val)
207 struct gpioiic_softc *sc = device_get_softc(dev);
210 gpio_pin_setflags(sc->sclpin, GPIO_PIN_INPUT);
212 gpio_pin_setflags(sc->sclpin,
213 GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN);
214 gpio_pin_set_active(sc->sclpin, 0);
219 gpioiic_getscl(device_t dev)
221 struct gpioiic_softc *sc = device_get_softc(dev);
224 gpio_pin_setflags(sc->sclpin, GPIO_PIN_INPUT);
225 gpio_pin_is_active(sc->sclpin, &val);
230 gpioiic_getsda(device_t dev)
232 struct gpioiic_softc *sc = device_get_softc(dev);
235 gpio_pin_setflags(sc->sdapin, GPIO_PIN_INPUT);
236 gpio_pin_is_active(sc->sdapin, &val);
241 gpioiic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
243 struct gpioiic_softc *sc = device_get_softc(dev);
245 /* Stop driving the bus pins. */
246 gpio_pin_setflags(sc->sdapin, GPIO_PIN_INPUT);
247 gpio_pin_setflags(sc->sclpin, GPIO_PIN_INPUT);
249 /* Indicate that we have no slave address (master mode). */
250 return (IIC_ENOADDR);
254 gpioiic_cleanup(struct gpioiic_softc *sc)
257 device_delete_children(sc->dev);
259 if (sc->sclpin != NULL)
260 gpio_pin_release(sc->sclpin);
262 if (sc->sdapin != NULL)
263 gpio_pin_release(sc->sdapin);
267 gpioiic_probe(device_t dev)
272 * By default we only bid to attach if specifically added by our parent
273 * (usually via hint.gpioiic.#.at=busname). On FDT systems we bid as
274 * the default driver based on being configured in the FDT data.
276 rv = BUS_PROBE_NOWILDCARD;
279 if (ofw_bus_status_okay(dev) &&
280 ofw_bus_search_compatible(dev, compat_data)->ocd_data)
281 rv = BUS_PROBE_DEFAULT;
284 device_set_desc(dev, "GPIO I2C");
290 gpioiic_attach(device_t dev)
292 struct gpioiic_softc *sc = device_get_softc(dev);
297 /* Acquire our gpio pins. */
298 err = gpioiic_setup_hinted_pins(sc);
301 err = gpioiic_setup_fdt_pins(sc);
304 device_printf(sc->dev, "no pins configured\n");
310 * Say what we came up with for pin config.
311 * NB: in the !FDT case the controller driver might not be set up enough
312 * for GPIO_GET_BUS() to work. Also, our parent is the only gpiobus
313 * that can provide our pins.
315 device_printf(dev, "SCL pin: %s:%d, SDA pin: %s:%d\n",
317 device_get_nameunit(GPIO_GET_BUS(sc->sclpin->dev)), sc->sclpin->pin,
318 device_get_nameunit(GPIO_GET_BUS(sc->sdapin->dev)), sc->sdapin->pin);
320 device_get_nameunit(device_get_parent(dev)), sc->sclpin->pin,
321 device_get_nameunit(device_get_parent(dev)), sc->sdapin->pin);
324 /* Add the bitbang driver as our only child; it will add iicbus. */
325 device_add_child(sc->dev, "iicbb", -1);
326 return (bus_generic_attach(dev));
330 gpioiic_detach(device_t dev)
332 struct gpioiic_softc *sc = device_get_softc(dev);
335 if ((err = bus_generic_detach(dev)) != 0)
343 static devclass_t gpioiic_devclass;
345 static device_method_t gpioiic_methods[] = {
346 /* Device interface */
347 DEVMETHOD(device_probe, gpioiic_probe),
348 DEVMETHOD(device_attach, gpioiic_attach),
349 DEVMETHOD(device_detach, gpioiic_detach),
351 /* iicbb interface */
352 DEVMETHOD(iicbb_setsda, gpioiic_setsda),
353 DEVMETHOD(iicbb_setscl, gpioiic_setscl),
354 DEVMETHOD(iicbb_getsda, gpioiic_getsda),
355 DEVMETHOD(iicbb_getscl, gpioiic_getscl),
356 DEVMETHOD(iicbb_reset, gpioiic_reset),
359 /* OFW bus interface */
360 DEVMETHOD(ofw_bus_get_node, gpioiic_get_node),
366 static driver_t gpioiic_driver = {
369 sizeof(struct gpioiic_softc),
372 DRIVER_MODULE(gpioiic, gpiobus, gpioiic_driver, gpioiic_devclass, 0, 0);
373 DRIVER_MODULE(gpioiic, simplebus, gpioiic_driver, gpioiic_devclass, 0, 0);
374 DRIVER_MODULE(iicbb, gpioiic, iicbb_driver, iicbb_devclass, 0, 0);
375 MODULE_DEPEND(gpioiic, iicbb, IICBB_MINVER, IICBB_PREFVER, IICBB_MAXVER);
376 MODULE_DEPEND(gpioiic, gpiobus, 1, 1, 1);