Lines Matching refs:mcp
60 int (*read)(struct mcp23s08 *mcp, unsigned reg);
61 int (*write)(struct mcp23s08 *mcp, unsigned reg, unsigned val);
62 int (*read_regs)(struct mcp23s08 *mcp, unsigned reg,
93 struct mcp23s08 *mcp[8]; member
106 static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg) in mcp23008_read() argument
108 return i2c_smbus_read_byte_data(mcp->data, reg); in mcp23008_read()
111 static int mcp23008_write(struct mcp23s08 *mcp, unsigned reg, unsigned val) in mcp23008_write() argument
113 return i2c_smbus_write_byte_data(mcp->data, reg, val); in mcp23008_write()
117 mcp23008_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n) in mcp23008_read_regs() argument
120 int ret = mcp23008_read(mcp, reg++); in mcp23008_read_regs()
129 static int mcp23017_read(struct mcp23s08 *mcp, unsigned reg) in mcp23017_read() argument
131 return i2c_smbus_read_word_data(mcp->data, reg << 1); in mcp23017_read()
134 static int mcp23017_write(struct mcp23s08 *mcp, unsigned reg, unsigned val) in mcp23017_write() argument
136 return i2c_smbus_write_word_data(mcp->data, reg << 1, val); in mcp23017_write()
140 mcp23017_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n) in mcp23017_read_regs() argument
143 int ret = mcp23017_read(mcp, reg++); in mcp23017_read_regs()
170 static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg) in mcp23s08_read() argument
175 tx[0] = mcp->addr | 0x01; in mcp23s08_read()
177 status = spi_write_then_read(mcp->data, tx, sizeof(tx), rx, sizeof(rx)); in mcp23s08_read()
181 static int mcp23s08_write(struct mcp23s08 *mcp, unsigned reg, unsigned val) in mcp23s08_write() argument
185 tx[0] = mcp->addr; in mcp23s08_write()
188 return spi_write_then_read(mcp->data, tx, sizeof(tx), NULL, 0); in mcp23s08_write()
192 mcp23s08_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n) in mcp23s08_read_regs() argument
197 if ((n + reg) > sizeof(mcp->cache)) in mcp23s08_read_regs()
199 tx[0] = mcp->addr | 0x01; in mcp23s08_read_regs()
203 status = spi_write_then_read(mcp->data, tx, sizeof(tx), tmp, n); in mcp23s08_read_regs()
211 static int mcp23s17_read(struct mcp23s08 *mcp, unsigned reg) in mcp23s17_read() argument
216 tx[0] = mcp->addr | 0x01; in mcp23s17_read()
218 status = spi_write_then_read(mcp->data, tx, sizeof(tx), rx, sizeof(rx)); in mcp23s17_read()
222 static int mcp23s17_write(struct mcp23s08 *mcp, unsigned reg, unsigned val) in mcp23s17_write() argument
226 tx[0] = mcp->addr; in mcp23s17_write()
230 return spi_write_then_read(mcp->data, tx, sizeof(tx), NULL, 0); in mcp23s17_write()
234 mcp23s17_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n) in mcp23s17_read_regs() argument
239 if ((n + reg) > sizeof(mcp->cache)) in mcp23s17_read_regs()
241 tx[0] = mcp->addr | 0x01; in mcp23s17_read_regs()
244 status = spi_write_then_read(mcp->data, tx, sizeof(tx), in mcp23s17_read_regs()
272 struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip); in mcp23s08_direction_input() local
275 mutex_lock(&mcp->lock); in mcp23s08_direction_input()
276 mcp->cache[MCP_IODIR] |= (1 << offset); in mcp23s08_direction_input()
277 status = mcp->ops->write(mcp, MCP_IODIR, mcp->cache[MCP_IODIR]); in mcp23s08_direction_input()
278 mutex_unlock(&mcp->lock); in mcp23s08_direction_input()
284 struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip); in mcp23s08_get() local
287 mutex_lock(&mcp->lock); in mcp23s08_get()
290 status = mcp->ops->read(mcp, MCP_GPIO); in mcp23s08_get()
294 mcp->cache[MCP_GPIO] = status; in mcp23s08_get()
297 mutex_unlock(&mcp->lock); in mcp23s08_get()
301 static int __mcp23s08_set(struct mcp23s08 *mcp, unsigned mask, int value) in __mcp23s08_set() argument
303 unsigned olat = mcp->cache[MCP_OLAT]; in __mcp23s08_set()
309 mcp->cache[MCP_OLAT] = olat; in __mcp23s08_set()
310 return mcp->ops->write(mcp, MCP_OLAT, olat); in __mcp23s08_set()
315 struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip); in mcp23s08_set() local
318 mutex_lock(&mcp->lock); in mcp23s08_set()
319 __mcp23s08_set(mcp, mask, value); in mcp23s08_set()
320 mutex_unlock(&mcp->lock); in mcp23s08_set()
326 struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip); in mcp23s08_direction_output() local
330 mutex_lock(&mcp->lock); in mcp23s08_direction_output()
331 status = __mcp23s08_set(mcp, mask, value); in mcp23s08_direction_output()
333 mcp->cache[MCP_IODIR] &= ~mask; in mcp23s08_direction_output()
334 status = mcp->ops->write(mcp, MCP_IODIR, mcp->cache[MCP_IODIR]); in mcp23s08_direction_output()
336 mutex_unlock(&mcp->lock); in mcp23s08_direction_output()
343 struct mcp23s08 *mcp = data; in mcp23s08_irq() local
347 mutex_lock(&mcp->lock); in mcp23s08_irq()
348 intf = mcp->ops->read(mcp, MCP_INTF); in mcp23s08_irq()
350 mutex_unlock(&mcp->lock); in mcp23s08_irq()
354 mcp->cache[MCP_INTF] = intf; in mcp23s08_irq()
356 intcap = mcp->ops->read(mcp, MCP_INTCAP); in mcp23s08_irq()
358 mutex_unlock(&mcp->lock); in mcp23s08_irq()
362 mcp->cache[MCP_INTCAP] = intcap; in mcp23s08_irq()
363 mutex_unlock(&mcp->lock); in mcp23s08_irq()
366 for (i = 0; i < mcp->chip.ngpio; i++) { in mcp23s08_irq()
367 if ((BIT(i) & mcp->cache[MCP_INTF]) && in mcp23s08_irq()
368 ((BIT(i) & intcap & mcp->irq_rise) || in mcp23s08_irq()
369 (mcp->irq_fall & ~intcap & BIT(i)))) { in mcp23s08_irq()
370 child_irq = irq_find_mapping(mcp->irq_domain, i); in mcp23s08_irq()
380 struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip); in mcp23s08_gpio_to_irq() local
382 return irq_find_mapping(mcp->irq_domain, offset); in mcp23s08_gpio_to_irq()
387 struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); in mcp23s08_irq_mask() local
390 mcp->cache[MCP_GPINTEN] &= ~BIT(pos); in mcp23s08_irq_mask()
395 struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); in mcp23s08_irq_unmask() local
398 mcp->cache[MCP_GPINTEN] |= BIT(pos); in mcp23s08_irq_unmask()
403 struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); in mcp23s08_irq_set_type() local
408 mcp->cache[MCP_INTCON] &= ~BIT(pos); in mcp23s08_irq_set_type()
409 mcp->irq_rise |= BIT(pos); in mcp23s08_irq_set_type()
410 mcp->irq_fall |= BIT(pos); in mcp23s08_irq_set_type()
412 mcp->cache[MCP_INTCON] &= ~BIT(pos); in mcp23s08_irq_set_type()
413 mcp->irq_rise |= BIT(pos); in mcp23s08_irq_set_type()
414 mcp->irq_fall &= ~BIT(pos); in mcp23s08_irq_set_type()
416 mcp->cache[MCP_INTCON] &= ~BIT(pos); in mcp23s08_irq_set_type()
417 mcp->irq_rise &= ~BIT(pos); in mcp23s08_irq_set_type()
418 mcp->irq_fall |= BIT(pos); in mcp23s08_irq_set_type()
427 struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); in mcp23s08_irq_bus_lock() local
429 mutex_lock(&mcp->irq_lock); in mcp23s08_irq_bus_lock()
434 struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); in mcp23s08_irq_bus_unlock() local
436 mutex_lock(&mcp->lock); in mcp23s08_irq_bus_unlock()
437 mcp->ops->write(mcp, MCP_GPINTEN, mcp->cache[MCP_GPINTEN]); in mcp23s08_irq_bus_unlock()
438 mcp->ops->write(mcp, MCP_DEFVAL, mcp->cache[MCP_DEFVAL]); in mcp23s08_irq_bus_unlock()
439 mcp->ops->write(mcp, MCP_INTCON, mcp->cache[MCP_INTCON]); in mcp23s08_irq_bus_unlock()
440 mutex_unlock(&mcp->lock); in mcp23s08_irq_bus_unlock()
441 mutex_unlock(&mcp->irq_lock); in mcp23s08_irq_bus_unlock()
446 struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); in mcp23s08_irq_reqres() local
448 if (gpiochip_lock_as_irq(&mcp->chip, data->hwirq)) { in mcp23s08_irq_reqres()
449 dev_err(mcp->chip.dev, in mcp23s08_irq_reqres()
460 struct mcp23s08 *mcp = irq_data_get_irq_chip_data(data); in mcp23s08_irq_relres() local
462 gpiochip_unlock_as_irq(&mcp->chip, data->hwirq); in mcp23s08_irq_relres()
476 static int mcp23s08_irq_setup(struct mcp23s08 *mcp) in mcp23s08_irq_setup() argument
478 struct gpio_chip *chip = &mcp->chip; in mcp23s08_irq_setup()
482 mutex_init(&mcp->irq_lock); in mcp23s08_irq_setup()
484 mcp->irq_domain = irq_domain_add_linear(chip->dev->of_node, chip->ngpio, in mcp23s08_irq_setup()
485 &irq_domain_simple_ops, mcp); in mcp23s08_irq_setup()
486 if (!mcp->irq_domain) in mcp23s08_irq_setup()
489 if (mcp->irq_active_high) in mcp23s08_irq_setup()
494 err = devm_request_threaded_irq(chip->dev, mcp->irq, NULL, mcp23s08_irq, in mcp23s08_irq_setup()
495 irqflags, dev_name(chip->dev), mcp); in mcp23s08_irq_setup()
498 mcp->irq, err); in mcp23s08_irq_setup()
504 for (j = 0; j < mcp->chip.ngpio; j++) { in mcp23s08_irq_setup()
505 irq = irq_create_mapping(mcp->irq_domain, j); in mcp23s08_irq_setup()
507 irq_set_chip_data(irq, mcp); in mcp23s08_irq_setup()
519 static void mcp23s08_irq_teardown(struct mcp23s08 *mcp) in mcp23s08_irq_teardown() argument
523 for (i = 0; i < mcp->chip.ngpio; i++) { in mcp23s08_irq_teardown()
524 irq = irq_find_mapping(mcp->irq_domain, i); in mcp23s08_irq_teardown()
529 irq_domain_remove(mcp->irq_domain); in mcp23s08_irq_teardown()
544 struct mcp23s08 *mcp; in mcp23s08_dbg_show() local
549 mcp = container_of(chip, struct mcp23s08, chip); in mcp23s08_dbg_show()
552 bank = '0' + ((mcp->addr >> 1) & 0x7); in mcp23s08_dbg_show()
554 mutex_lock(&mcp->lock); in mcp23s08_dbg_show()
555 t = mcp->ops->read_regs(mcp, 0, mcp->cache, ARRAY_SIZE(mcp->cache)); in mcp23s08_dbg_show()
570 (mcp->cache[MCP_IODIR] & mask) ? "in " : "out", in mcp23s08_dbg_show()
571 (mcp->cache[MCP_GPIO] & mask) ? "hi" : "lo", in mcp23s08_dbg_show()
572 (mcp->cache[MCP_GPPU] & mask) ? "up" : " "); in mcp23s08_dbg_show()
577 mutex_unlock(&mcp->lock); in mcp23s08_dbg_show()
586 static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev, in mcp23s08_probe_one() argument
593 mutex_init(&mcp->lock); in mcp23s08_probe_one()
595 mcp->data = data; in mcp23s08_probe_one()
596 mcp->addr = addr; in mcp23s08_probe_one()
597 mcp->irq_active_high = false; in mcp23s08_probe_one()
599 mcp->chip.direction_input = mcp23s08_direction_input; in mcp23s08_probe_one()
600 mcp->chip.get = mcp23s08_get; in mcp23s08_probe_one()
601 mcp->chip.direction_output = mcp23s08_direction_output; in mcp23s08_probe_one()
602 mcp->chip.set = mcp23s08_set; in mcp23s08_probe_one()
603 mcp->chip.dbg_show = mcp23s08_dbg_show; in mcp23s08_probe_one()
605 mcp->chip.of_gpio_n_cells = 2; in mcp23s08_probe_one()
606 mcp->chip.of_node = dev->of_node; in mcp23s08_probe_one()
612 mcp->ops = &mcp23s08_ops; in mcp23s08_probe_one()
613 mcp->chip.ngpio = 8; in mcp23s08_probe_one()
614 mcp->chip.label = "mcp23s08"; in mcp23s08_probe_one()
618 mcp->ops = &mcp23s17_ops; in mcp23s08_probe_one()
619 mcp->chip.ngpio = 16; in mcp23s08_probe_one()
620 mcp->chip.label = "mcp23s17"; in mcp23s08_probe_one()
626 mcp->ops = &mcp23008_ops; in mcp23s08_probe_one()
627 mcp->chip.ngpio = 8; in mcp23s08_probe_one()
628 mcp->chip.label = "mcp23008"; in mcp23s08_probe_one()
632 mcp->ops = &mcp23017_ops; in mcp23s08_probe_one()
633 mcp->chip.ngpio = 16; in mcp23s08_probe_one()
634 mcp->chip.label = "mcp23017"; in mcp23s08_probe_one()
643 mcp->chip.base = pdata->base; in mcp23s08_probe_one()
644 mcp->chip.can_sleep = true; in mcp23s08_probe_one()
645 mcp->chip.dev = dev; in mcp23s08_probe_one()
646 mcp->chip.owner = THIS_MODULE; in mcp23s08_probe_one()
652 status = mcp->ops->read(mcp, MCP_IOCON); in mcp23s08_probe_one()
656 mcp->irq_controller = pdata->irq_controller; in mcp23s08_probe_one()
657 if (mcp->irq && mcp->irq_controller) { in mcp23s08_probe_one()
658 mcp->irq_active_high = in mcp23s08_probe_one()
659 of_property_read_bool(mcp->chip.dev->of_node, in mcp23s08_probe_one()
667 mcp->irq_active_high) { in mcp23s08_probe_one()
671 if (mcp->irq_active_high) in mcp23s08_probe_one()
679 status = mcp->ops->write(mcp, MCP_IOCON, status); in mcp23s08_probe_one()
685 status = mcp->ops->write(mcp, MCP_GPPU, pdata->chip[cs].pullups); in mcp23s08_probe_one()
689 status = mcp->ops->read_regs(mcp, 0, mcp->cache, ARRAY_SIZE(mcp->cache)); in mcp23s08_probe_one()
694 if (mcp->cache[MCP_IPOL] != 0) { in mcp23s08_probe_one()
695 mcp->cache[MCP_IPOL] = 0; in mcp23s08_probe_one()
696 status = mcp->ops->write(mcp, MCP_IPOL, 0); in mcp23s08_probe_one()
702 if (mcp->cache[MCP_GPINTEN] != 0) { in mcp23s08_probe_one()
703 mcp->cache[MCP_GPINTEN] = 0; in mcp23s08_probe_one()
704 status = mcp->ops->write(mcp, MCP_GPINTEN, 0); in mcp23s08_probe_one()
709 status = gpiochip_add(&mcp->chip); in mcp23s08_probe_one()
713 if (mcp->irq && mcp->irq_controller) { in mcp23s08_probe_one()
714 status = mcp23s08_irq_setup(mcp); in mcp23s08_probe_one()
716 mcp23s08_irq_teardown(mcp); in mcp23s08_probe_one()
786 struct mcp23s08 *mcp; in mcp230xx_probe() local
812 mcp = kzalloc(sizeof(*mcp), GFP_KERNEL); in mcp230xx_probe()
813 if (!mcp) in mcp230xx_probe()
816 mcp->irq = client->irq; in mcp230xx_probe()
817 status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr, in mcp230xx_probe()
822 i2c_set_clientdata(client, mcp); in mcp230xx_probe()
827 kfree(mcp); in mcp230xx_probe()
834 struct mcp23s08 *mcp = i2c_get_clientdata(client); in mcp230xx_remove() local
836 if (client->irq && mcp->irq_controller) in mcp230xx_remove()
837 mcp23s08_irq_teardown(mcp); in mcp230xx_remove()
839 gpiochip_remove(&mcp->chip); in mcp230xx_remove()
840 kfree(mcp); in mcp230xx_remove()
966 data->mcp[addr] = &data->chip[chips]; in mcp23s08_probe()
967 data->mcp[addr]->irq = spi->irq; in mcp23s08_probe()
968 status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi, in mcp23s08_probe()
988 for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) { in mcp23s08_probe()
990 if (!data->mcp[addr]) in mcp23s08_probe()
992 gpiochip_remove(&data->mcp[addr]->chip); in mcp23s08_probe()
1002 for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) { in mcp23s08_remove()
1004 if (!data->mcp[addr]) in mcp23s08_remove()
1007 if (spi->irq && data->mcp[addr]->irq_controller) in mcp23s08_remove()
1008 mcp23s08_irq_teardown(data->mcp[addr]); in mcp23s08_remove()
1009 gpiochip_remove(&data->mcp[addr]->chip); in mcp23s08_remove()