Lines Matching +full:pin +full:- +full:val

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
30 * Driver for PCF8574 / PCF8574A 8-bit I/O expander
31 * with quasi-bidirectional I/O.
87 pcf8574_read(struct pcf8574_softc *sc, uint8_t *val) in pcf8574_read() argument
92 msg.slave = sc->addr; in pcf8574_read()
95 msg.buf = val; in pcf8574_read()
97 error = iicbus_transfer_excl(sc->dev, &msg, 1, IIC_WAIT); in pcf8574_read()
102 pcf8574_write(struct pcf8574_softc *sc, uint8_t val) in pcf8574_write() argument
107 msg.slave = sc->addr; in pcf8574_write()
110 msg.buf = &val; in pcf8574_write()
112 error = iicbus_transfer_excl(sc->dev, &msg, 1, IIC_WAIT); in pcf8574_write()
121 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) in pcf8574_probe()
134 sc->dev = dev; in pcf8574_attach()
135 sc->addr = iicbus_get_addr(dev); in pcf8574_attach()
138 sc->output_mask = 0; in pcf8574_attach()
139 sc->output_state = 0xff; in pcf8574_attach()
144 sx_init(&sc->lock, "pcf8574"); in pcf8574_attach()
145 sc->busdev = gpiobus_attach_bus(dev); in pcf8574_attach()
146 if (sc->busdev == NULL) { in pcf8574_attach()
148 sx_destroy(&sc->lock); in pcf8574_attach()
161 if (sc->busdev != NULL) in pcf8574_detach()
162 gpiobus_detach_bus(sc->busdev); in pcf8574_detach()
164 sx_destroy(&sc->lock); in pcf8574_detach()
174 return (sc->busdev); in pcf8574_get_bus()
180 *maxpin = NUM_PINS - 1; in pcf8574_pin_max()
185 pcf8574_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) in pcf8574_pin_getcaps() argument
188 if (pin >= NUM_PINS) in pcf8574_pin_getcaps()
195 pcf8574_pin_getflags(device_t dev, uint32_t pin, uint32_t *pflags) in pcf8574_pin_getflags() argument
198 uint8_t val, stale; in pcf8574_pin_getflags() local
203 if (pin >= NUM_PINS) in pcf8574_pin_getflags()
206 sx_xlock(&sc->lock); in pcf8574_pin_getflags()
207 error = pcf8574_read(sc, &val); in pcf8574_pin_getflags()
211 sx_xunlock(&sc->lock); in pcf8574_pin_getflags()
220 stale = val & sc->output_mask & ~sc->output_state; in pcf8574_pin_getflags()
221 sc->output_mask &= ~stale; in pcf8574_pin_getflags()
222 sc->output_state |= stale; in pcf8574_pin_getflags()
224 if ((sc->output_mask & (1 << pin)) != 0) in pcf8574_pin_getflags()
228 sx_xunlock(&sc->lock); in pcf8574_pin_getflags()
234 pcf8574_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) in pcf8574_pin_setflags() argument
238 uint8_t val; in pcf8574_pin_setflags() local
243 if (pin >= NUM_PINS) in pcf8574_pin_setflags()
248 sx_xlock(&sc->lock); in pcf8574_pin_setflags()
250 sc->output_mask |= 1 << pin; in pcf8574_pin_setflags()
253 sc->output_mask &= ~(1 << pin); in pcf8574_pin_setflags()
254 sc->output_state |= 1 << pin; in pcf8574_pin_setflags()
262 val = sc->output_state | ~sc->output_mask; in pcf8574_pin_setflags()
263 error = pcf8574_write(sc, val); in pcf8574_pin_setflags()
268 sx_xunlock(&sc->lock); in pcf8574_pin_setflags()
274 pcf8574_pin_getname(device_t dev, uint32_t pin, char *name) in pcf8574_pin_getname() argument
277 if (pin >= NUM_PINS) in pcf8574_pin_getname()
279 snprintf(name, GPIOMAXNAME, "P%d", pin); in pcf8574_pin_getname()
284 pcf8574_pin_get(device_t dev, uint32_t pin, unsigned int *on) in pcf8574_pin_get() argument
287 uint8_t val; in pcf8574_pin_get() local
292 sx_xlock(&sc->lock); in pcf8574_pin_get()
293 if ((sc->output_mask & (1 << pin)) != 0) { in pcf8574_pin_get()
294 *on = (sc->output_state & (1 << pin)) != 0; in pcf8574_pin_get()
295 sx_xunlock(&sc->lock); in pcf8574_pin_get()
299 error = pcf8574_read(sc, &val); in pcf8574_pin_get()
302 sx_xunlock(&sc->lock); in pcf8574_pin_get()
305 sx_xunlock(&sc->lock); in pcf8574_pin_get()
307 *on = (val & (1 << pin)) != 0; in pcf8574_pin_get()
312 pcf8574_pin_set(device_t dev, uint32_t pin, unsigned int on) in pcf8574_pin_set() argument
315 uint8_t val; in pcf8574_pin_set() local
320 if (pin >= NUM_PINS) in pcf8574_pin_set()
323 sx_xlock(&sc->lock); in pcf8574_pin_set()
325 if ((sc->output_mask & (1 << pin)) == 0) { in pcf8574_pin_set()
326 sx_xunlock(&sc->lock); in pcf8574_pin_set()
332 * - set all outputs to their recorded state; in pcf8574_pin_set()
333 * - set all inputs to the high state; in pcf8574_pin_set()
334 * - apply the requested change. in pcf8574_pin_set()
336 val = sc->output_state | ~sc->output_mask; in pcf8574_pin_set()
337 val &= ~(1 << pin); in pcf8574_pin_set()
338 val |= (on != 0) << pin; in pcf8574_pin_set()
340 error = pcf8574_write(sc, val); in pcf8574_pin_set()
343 sx_xunlock(&sc->lock); in pcf8574_pin_set()
351 sc->output_state = val; in pcf8574_pin_set()
352 sx_xunlock(&sc->lock); in pcf8574_pin_set()
357 pcf8574_pin_toggle(device_t dev, uint32_t pin) in pcf8574_pin_toggle() argument
360 uint8_t val; in pcf8574_pin_toggle() local
365 if (pin >= NUM_PINS) in pcf8574_pin_toggle()
368 sx_xlock(&sc->lock); in pcf8574_pin_toggle()
370 if ((sc->output_mask & (1 << pin)) == 0) { in pcf8574_pin_toggle()
371 sx_xunlock(&sc->lock); in pcf8574_pin_toggle()
375 val = sc->output_state | ~sc->output_mask; in pcf8574_pin_toggle()
376 val ^= 1 << pin; in pcf8574_pin_toggle()
378 error = pcf8574_write(sc, val); in pcf8574_pin_toggle()
381 sx_xunlock(&sc->lock); in pcf8574_pin_toggle()
385 sc->output_state = val; in pcf8574_pin_toggle()
386 sx_xunlock(&sc->lock); in pcf8574_pin_toggle()