Lines Matching +full:i2c +full:- +full:bus +full:- +full:name
1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
14 * 3. The name of the author may not be used to endorse or promote products
32 * Support routines for the Keywest I2C controller.
39 #include <sys/bus.h>
43 #include <machine/bus.h>
51 /* Keywest I2C Register offsets */
93 /* I2C flags */
125 static phandle_t kiic_get_node(device_t bus, device_t dev);
153 const char *name; in kiic_probe() local
155 name = ofw_bus_get_name(self); in kiic_probe()
156 if (name && strcmp(name, "i2c") == 0) { in kiic_probe()
157 device_set_desc(self, "Keywest I2C controller"); in kiic_probe()
170 char name[64]; in kiic_attach() local
173 sc->sc_dev = self; in kiic_attach()
176 if (node == 0 || node == -1) { in kiic_attach()
181 sc->sc_reg = bus_alloc_resource_any(self, SYS_RES_MEMORY, in kiic_attach()
183 if (sc->sc_reg == NULL) { in kiic_attach()
187 if (OF_getencprop(node, "AAPL,i2c-rate", &rate, 4) != 4) { in kiic_attach()
188 device_printf(self, "cannot get i2c-rate\n"); in kiic_attach()
191 if (OF_getencprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) { in kiic_attach()
192 device_printf(self, "unable to find i2c address step\n"); in kiic_attach()
197 * Some Keywest I2C devices have their children attached directly in kiic_attach()
200 * OFW I2C layer has the correct node. in kiic_attach()
202 * Note: the I2C children of the Uninorth bridges have two ports. in kiic_attach()
203 * In general, the port is designated in the 9th bit of the I2C in kiic_attach()
205 * an i2c-bus node, the port is indicated in the 'reg' property in kiic_attach()
206 * of the i2c-bus node. in kiic_attach()
209 sc->sc_node = node; in kiic_attach()
212 if (OF_getprop(node, "name", name, sizeof(name)) > 0) { in kiic_attach()
213 if (strcmp(name,"i2c-bus") == 0) { in kiic_attach()
216 sc->sc_i2c_base = reg << 8; in kiic_attach()
218 sc->sc_node = node; in kiic_attach()
222 mtx_init(&sc->sc_mutex, "kiic", NULL, MTX_DEF); in kiic_attach()
224 sc->sc_irq = bus_alloc_resource_any(self, SYS_RES_IRQ, &sc->sc_irqrid, in kiic_attach()
226 bus_setup_intr(self, sc->sc_irq, INTR_TYPE_MISC | INTR_MPSAFE, NULL, in kiic_attach()
227 kiic_intr, sc, &sc->sc_ih); in kiic_attach()
241 /* Add the IIC bus layer */ in kiic_attach()
242 sc->sc_iicbus = device_add_child(self, "iicbus", DEVICE_UNIT_ANY); in kiic_attach()
251 bus_write_4(sc->sc_reg, sc->sc_regstep * reg, val); in kiic_writereg()
258 return bus_read_4(sc->sc_reg, sc->sc_regstep * reg) & 0xff; in kiic_readreg()
304 mtx_lock(&sc->sc_mutex); in kiic_intr()
308 sc->sc_flags |= I2C_SELECTED; in kiic_intr()
310 if (sc->sc_flags & I2C_READING) { in kiic_intr()
311 if (sc->sc_resid > 1) { in kiic_intr()
317 kiic_writereg(sc, DATA, *sc->sc_data++); in kiic_intr()
318 sc->sc_resid--; in kiic_intr()
323 if (sc->sc_flags & I2C_READING) { in kiic_intr()
324 if (sc->sc_resid > 0) { in kiic_intr()
325 *sc->sc_data++ = kiic_readreg(sc, DATA); in kiic_intr()
326 sc->sc_resid--; in kiic_intr()
328 if (sc->sc_resid == 0) /* done */ in kiic_intr()
331 if (sc->sc_resid == 0) { in kiic_intr()
336 kiic_writereg(sc, DATA, *sc->sc_data++); in kiic_intr()
337 sc->sc_resid--; in kiic_intr()
344 sc->sc_flags &= ~I2C_SELECTED; in kiic_intr()
345 wakeup(sc->sc_dev); in kiic_intr()
349 mtx_unlock(&sc->sc_mutex); in kiic_intr()
364 mtx_lock(&sc->sc_mutex); in kiic_transfer()
366 if (sc->sc_flags & I2C_BUSY) in kiic_transfer()
367 mtx_sleep(dev, &sc->sc_mutex, 0, "kiic", timo); in kiic_transfer()
369 if (sc->sc_flags & I2C_BUSY) { in kiic_transfer()
370 mtx_unlock(&sc->sc_mutex); in kiic_transfer()
374 sc->sc_flags = I2C_BUSY; in kiic_transfer()
386 KASSERT(msgs[i].len == 1, ("oversize I2C message")); in kiic_transfer()
393 sc->sc_data = msgs[i].buf; in kiic_transfer()
394 sc->sc_resid = msgs[i].len; in kiic_transfer()
395 sc->sc_flags = I2C_BUSY; in kiic_transfer()
397 timo = 1000 + sc->sc_resid * 200; in kiic_transfer()
401 sc->sc_flags |= I2C_READING; in kiic_transfer()
405 addr |= sc->sc_i2c_base; in kiic_transfer()
414 err = mtx_sleep(dev, &sc->sc_mutex, 0, "kiic", timo); in kiic_transfer()
416 msgs[i].len -= sc->sc_resid; in kiic_transfer()
418 if ((sc->sc_flags & I2C_ERROR) || err == EWOULDBLOCK) { in kiic_transfer()
419 device_printf(sc->sc_dev, "I2C error\n"); in kiic_transfer()
420 sc->sc_flags = 0; in kiic_transfer()
421 mtx_unlock(&sc->sc_mutex); in kiic_transfer()
426 sc->sc_flags = 0; in kiic_transfer()
428 mtx_unlock(&sc->sc_mutex); in kiic_transfer()
434 kiic_get_node(device_t bus, device_t dev) in kiic_get_node() argument
438 sc = device_get_softc(bus); in kiic_get_node()
439 /* We only have one child, the I2C bus, which needs our own node. */ in kiic_get_node()
441 return sc->sc_node; in kiic_get_node()