38#include "opt_platform.h"
43#include <sys/kernel.h>
44#include <sys/module.h>
47#include <dev/gpio/gpiobusvar.h>
53#include <dev/ofw/ofw_bus.h>
54#include <dev/ofw/ofw_bus_subr.h>
55#include <dev/ofw/openfirm.h>
58 {
"i2c-mux-gpio",
true},
98 for (i = 0; i < sc->
numpins; ++i)
99 gpio_pin_set_active(sc->
pins[i],
busidx & (1u << i));
112 if (ofw_bus_status_okay(
dev) &&
114 rv = BUS_PROBE_DEFAULT;
117 device_set_desc(
dev,
"I2C GPIO Mux");
127 for (i = 0; i < sc->
numpins; ++i)
128 gpio_pin_release(sc->
pins[i]);
137 int err, i, idlebits, numchannels;
141 node = ofw_bus_get_node(
dev);
148 err = gpio_pin_get_by_ofw_propidx(
dev, node,
"mux-gpios", i,
156 device_printf(
dev,
"cannot acquire pins listed in mux-gpios\n");
161 numchannels = 1u << sc->
numpins;
163 device_printf(
dev,
"too many mux-gpios pins for max %d buses\n",
175 len = OF_getencprop(node,
"i2c-parent", &propval,
sizeof(propval));
176 if (
len !=
sizeof(propval)) {
177 device_printf(
dev,
"cannot obtain i2c-parent property\n");
181 busdev = OF_device_from_xref((phandle_t)propval);
182 if (busdev == NULL) {
184 "cannot find device referenced by i2c-parent property\n");
188 device_printf(
dev,
"upstream bus is %s\n", device_get_nameunit(busdev));
195 len = OF_getencprop(node,
"idle-state", &propval,
sizeof(propval));
196 if (
len ==
sizeof(propval)) {
197 if ((
int)propval >= numchannels) {
199 "idle-state property %d exceeds channel count\n",
210 for (i = 0; i < sc->
numpins; ++i) {
211 gpio_pin_setflags(sc->
pins[i], GPIO_PIN_OUTPUT);
212 gpio_pin_set_active(sc->
pins[i], idlebits & (1u << i));
217 bus_generic_attach(
dev);
static ds13_compat_data compat_data[]
static int gpiomux_bus_select(device_t dev, int busidx, struct iic_reqbus_data *rd)
static void gpiomux_release_pins(struct gpiomux_softc *sc)
static device_method_t gpiomux_methods[]
static devclass_t gpiomux_devclass
static int gpiomux_probe(device_t dev)
static int gpiomux_detach(device_t dev)
static int gpiomux_attach(device_t dev)
DEFINE_CLASS_1(iic_gpiomux, iic_gpiomux_driver, gpiomux_methods, sizeof(struct gpiomux_softc), iicmux_driver)
MODULE_DEPEND(iic_gpiomux, iicmux, 1, 1, 1)
DRIVER_MODULE(iic_gpiomux, simplebus, iic_gpiomux_driver, gpiomux_devclass, 0, 0)
devclass_t iicbus_devclass
devclass_t ofw_iicbus_devclass
driver_t ofw_iicbus_driver
int iicmux_detach(device_t dev)
int iicmux_attach(device_t dev, device_t busdev, int numbuses)
#define IICMUX_SELECT_IDLE
struct iic_reqbus_data * rd
SIMPLEBUS_PNP_INFO(compat_data)
gpio_pin_t pins[IICMUX_MAX_BUSES]