diff options
Diffstat (limited to 'drivers/i2c')
| -rw-r--r-- | drivers/i2c/algos/i2c-algo-bit.c | 31 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-i801.c | 1 | ||||
| -rw-r--r-- | drivers/i2c/busses/i2c-nforce2.c | 2 | ||||
| -rw-r--r-- | drivers/i2c/i2c-core.c | 29 | ||||
| -rw-r--r-- | drivers/i2c/muxes/Kconfig | 12 | ||||
| -rw-r--r-- | drivers/i2c/muxes/Makefile | 1 | ||||
| -rw-r--r-- | drivers/i2c/muxes/gpio-i2cmux.c | 184 |
7 files changed, 230 insertions, 30 deletions
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index a39e6cff86e7..38319a69bd0a 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c | |||
| @@ -600,12 +600,14 @@ static const struct i2c_algorithm i2c_bit_algo = { | |||
| 600 | /* | 600 | /* |
| 601 | * registering functions to load algorithms at runtime | 601 | * registering functions to load algorithms at runtime |
| 602 | */ | 602 | */ |
| 603 | static int i2c_bit_prepare_bus(struct i2c_adapter *adap) | 603 | static int __i2c_bit_add_bus(struct i2c_adapter *adap, |
| 604 | int (*add_adapter)(struct i2c_adapter *)) | ||
| 604 | { | 605 | { |
| 605 | struct i2c_algo_bit_data *bit_adap = adap->algo_data; | 606 | struct i2c_algo_bit_data *bit_adap = adap->algo_data; |
| 607 | int ret; | ||
| 606 | 608 | ||
| 607 | if (bit_test) { | 609 | if (bit_test) { |
| 608 | int ret = test_bus(bit_adap, adap->name); | 610 | ret = test_bus(bit_adap, adap->name); |
| 609 | if (ret < 0) | 611 | if (ret < 0) |
| 610 | return -ENODEV; | 612 | return -ENODEV; |
| 611 | } | 613 | } |
| @@ -614,30 +616,27 @@ static int i2c_bit_prepare_bus(struct i2c_adapter *adap) | |||
| 614 | adap->algo = &i2c_bit_algo; | 616 | adap->algo = &i2c_bit_algo; |
| 615 | adap->retries = 3; | 617 | adap->retries = 3; |
| 616 | 618 | ||
| 619 | ret = add_adapter(adap); | ||
| 620 | if (ret < 0) | ||
| 621 | return ret; | ||
| 622 | |||
| 623 | /* Complain if SCL can't be read */ | ||
| 624 | if (bit_adap->getscl == NULL) { | ||
| 625 | dev_warn(&adap->dev, "Not I2C compliant: can't read SCL\n"); | ||
| 626 | dev_warn(&adap->dev, "Bus may be unreliable\n"); | ||
| 627 | } | ||
| 617 | return 0; | 628 | return 0; |
| 618 | } | 629 | } |
| 619 | 630 | ||
| 620 | int i2c_bit_add_bus(struct i2c_adapter *adap) | 631 | int i2c_bit_add_bus(struct i2c_adapter *adap) |
| 621 | { | 632 | { |
| 622 | int err; | 633 | return __i2c_bit_add_bus(adap, i2c_add_adapter); |
| 623 | |||
| 624 | err = i2c_bit_prepare_bus(adap); | ||
| 625 | if (err) | ||
| 626 | return err; | ||
| 627 | |||
| 628 | return i2c_add_adapter(adap); | ||
| 629 | } | 634 | } |
| 630 | EXPORT_SYMBOL(i2c_bit_add_bus); | 635 | EXPORT_SYMBOL(i2c_bit_add_bus); |
| 631 | 636 | ||
| 632 | int i2c_bit_add_numbered_bus(struct i2c_adapter *adap) | 637 | int i2c_bit_add_numbered_bus(struct i2c_adapter *adap) |
| 633 | { | 638 | { |
| 634 | int err; | 639 | return __i2c_bit_add_bus(adap, i2c_add_numbered_adapter); |
| 635 | |||
| 636 | err = i2c_bit_prepare_bus(adap); | ||
| 637 | if (err) | ||
| 638 | return err; | ||
| 639 | |||
| 640 | return i2c_add_numbered_adapter(adap); | ||
| 641 | } | 640 | } |
| 642 | EXPORT_SYMBOL(i2c_bit_add_numbered_bus); | 641 | EXPORT_SYMBOL(i2c_bit_add_numbered_bus); |
| 643 | 642 | ||
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 02835ce7ff4b..7979aef7ee7b 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
| @@ -72,6 +72,7 @@ | |||
| 72 | #include <linux/acpi.h> | 72 | #include <linux/acpi.h> |
| 73 | #include <linux/io.h> | 73 | #include <linux/io.h> |
| 74 | #include <linux/dmi.h> | 74 | #include <linux/dmi.h> |
| 75 | #include <linux/slab.h> | ||
| 75 | 76 | ||
| 76 | /* I801 SMBus address offsets */ | 77 | /* I801 SMBus address offsets */ |
| 77 | #define SMBHSTSTS(p) (0 + (p)->smba) | 78 | #define SMBHSTSTS(p) (0 + (p)->smba) |
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index a605a5029cfe..ff1e127dfea8 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c | |||
| @@ -432,7 +432,7 @@ static int __devinit nforce2_probe(struct pci_dev *dev, const struct pci_device_ | |||
| 432 | 432 | ||
| 433 | static void __devexit nforce2_remove(struct pci_dev *dev) | 433 | static void __devexit nforce2_remove(struct pci_dev *dev) |
| 434 | { | 434 | { |
| 435 | struct nforce2_smbus *smbuses = (void*) pci_get_drvdata(dev); | 435 | struct nforce2_smbus *smbuses = pci_get_drvdata(dev); |
| 436 | 436 | ||
| 437 | nforce2_set_reference(NULL); | 437 | nforce2_set_reference(NULL); |
| 438 | if (smbuses[0].base) { | 438 | if (smbuses[0].base) { |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 6b4cc567645b..c7db6980e3a3 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -1362,7 +1362,7 @@ EXPORT_SYMBOL(i2c_transfer); | |||
| 1362 | * | 1362 | * |
| 1363 | * Returns negative errno, or else the number of bytes written. | 1363 | * Returns negative errno, or else the number of bytes written. |
| 1364 | */ | 1364 | */ |
| 1365 | int i2c_master_send(struct i2c_client *client, const char *buf, int count) | 1365 | int i2c_master_send(const struct i2c_client *client, const char *buf, int count) |
| 1366 | { | 1366 | { |
| 1367 | int ret; | 1367 | int ret; |
| 1368 | struct i2c_adapter *adap = client->adapter; | 1368 | struct i2c_adapter *adap = client->adapter; |
| @@ -1389,7 +1389,7 @@ EXPORT_SYMBOL(i2c_master_send); | |||
| 1389 | * | 1389 | * |
| 1390 | * Returns negative errno, or else the number of bytes read. | 1390 | * Returns negative errno, or else the number of bytes read. |
| 1391 | */ | 1391 | */ |
| 1392 | int i2c_master_recv(struct i2c_client *client, char *buf, int count) | 1392 | int i2c_master_recv(const struct i2c_client *client, char *buf, int count) |
| 1393 | { | 1393 | { |
| 1394 | struct i2c_adapter *adap = client->adapter; | 1394 | struct i2c_adapter *adap = client->adapter; |
| 1395 | struct i2c_msg msg; | 1395 | struct i2c_msg msg; |
| @@ -1679,7 +1679,7 @@ static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg) | |||
| 1679 | * This executes the SMBus "receive byte" protocol, returning negative errno | 1679 | * This executes the SMBus "receive byte" protocol, returning negative errno |
| 1680 | * else the byte received from the device. | 1680 | * else the byte received from the device. |
| 1681 | */ | 1681 | */ |
| 1682 | s32 i2c_smbus_read_byte(struct i2c_client *client) | 1682 | s32 i2c_smbus_read_byte(const struct i2c_client *client) |
| 1683 | { | 1683 | { |
| 1684 | union i2c_smbus_data data; | 1684 | union i2c_smbus_data data; |
| 1685 | int status; | 1685 | int status; |
| @@ -1699,7 +1699,7 @@ EXPORT_SYMBOL(i2c_smbus_read_byte); | |||
| 1699 | * This executes the SMBus "send byte" protocol, returning negative errno | 1699 | * This executes the SMBus "send byte" protocol, returning negative errno |
| 1700 | * else zero on success. | 1700 | * else zero on success. |
| 1701 | */ | 1701 | */ |
| 1702 | s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value) | 1702 | s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value) |
| 1703 | { | 1703 | { |
| 1704 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | 1704 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, |
| 1705 | I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); | 1705 | I2C_SMBUS_WRITE, value, I2C_SMBUS_BYTE, NULL); |
| @@ -1714,7 +1714,7 @@ EXPORT_SYMBOL(i2c_smbus_write_byte); | |||
| 1714 | * This executes the SMBus "read byte" protocol, returning negative errno | 1714 | * This executes the SMBus "read byte" protocol, returning negative errno |
| 1715 | * else a data byte received from the device. | 1715 | * else a data byte received from the device. |
| 1716 | */ | 1716 | */ |
| 1717 | s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command) | 1717 | s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command) |
| 1718 | { | 1718 | { |
| 1719 | union i2c_smbus_data data; | 1719 | union i2c_smbus_data data; |
| 1720 | int status; | 1720 | int status; |
| @@ -1735,7 +1735,8 @@ EXPORT_SYMBOL(i2c_smbus_read_byte_data); | |||
| 1735 | * This executes the SMBus "write byte" protocol, returning negative errno | 1735 | * This executes the SMBus "write byte" protocol, returning negative errno |
| 1736 | * else zero on success. | 1736 | * else zero on success. |
| 1737 | */ | 1737 | */ |
| 1738 | s32 i2c_smbus_write_byte_data(struct i2c_client *client, u8 command, u8 value) | 1738 | s32 i2c_smbus_write_byte_data(const struct i2c_client *client, u8 command, |
| 1739 | u8 value) | ||
| 1739 | { | 1740 | { |
| 1740 | union i2c_smbus_data data; | 1741 | union i2c_smbus_data data; |
| 1741 | data.byte = value; | 1742 | data.byte = value; |
| @@ -1753,7 +1754,7 @@ EXPORT_SYMBOL(i2c_smbus_write_byte_data); | |||
| 1753 | * This executes the SMBus "read word" protocol, returning negative errno | 1754 | * This executes the SMBus "read word" protocol, returning negative errno |
| 1754 | * else a 16-bit unsigned "word" received from the device. | 1755 | * else a 16-bit unsigned "word" received from the device. |
| 1755 | */ | 1756 | */ |
| 1756 | s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command) | 1757 | s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command) |
| 1757 | { | 1758 | { |
| 1758 | union i2c_smbus_data data; | 1759 | union i2c_smbus_data data; |
| 1759 | int status; | 1760 | int status; |
| @@ -1774,7 +1775,8 @@ EXPORT_SYMBOL(i2c_smbus_read_word_data); | |||
| 1774 | * This executes the SMBus "write word" protocol, returning negative errno | 1775 | * This executes the SMBus "write word" protocol, returning negative errno |
| 1775 | * else zero on success. | 1776 | * else zero on success. |
| 1776 | */ | 1777 | */ |
| 1777 | s32 i2c_smbus_write_word_data(struct i2c_client *client, u8 command, u16 value) | 1778 | s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, |
| 1779 | u16 value) | ||
| 1778 | { | 1780 | { |
| 1779 | union i2c_smbus_data data; | 1781 | union i2c_smbus_data data; |
| 1780 | data.word = value; | 1782 | data.word = value; |
| @@ -1793,7 +1795,8 @@ EXPORT_SYMBOL(i2c_smbus_write_word_data); | |||
| 1793 | * This executes the SMBus "process call" protocol, returning negative errno | 1795 | * This executes the SMBus "process call" protocol, returning negative errno |
| 1794 | * else a 16-bit unsigned "word" received from the device. | 1796 | * else a 16-bit unsigned "word" received from the device. |
| 1795 | */ | 1797 | */ |
| 1796 | s32 i2c_smbus_process_call(struct i2c_client *client, u8 command, u16 value) | 1798 | s32 i2c_smbus_process_call(const struct i2c_client *client, u8 command, |
| 1799 | u16 value) | ||
| 1797 | { | 1800 | { |
| 1798 | union i2c_smbus_data data; | 1801 | union i2c_smbus_data data; |
| 1799 | int status; | 1802 | int status; |
| @@ -1821,7 +1824,7 @@ EXPORT_SYMBOL(i2c_smbus_process_call); | |||
| 1821 | * support this; its emulation through I2C messaging relies on a specific | 1824 | * support this; its emulation through I2C messaging relies on a specific |
| 1822 | * mechanism (I2C_M_RECV_LEN) which may not be implemented. | 1825 | * mechanism (I2C_M_RECV_LEN) which may not be implemented. |
| 1823 | */ | 1826 | */ |
| 1824 | s32 i2c_smbus_read_block_data(struct i2c_client *client, u8 command, | 1827 | s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, |
| 1825 | u8 *values) | 1828 | u8 *values) |
| 1826 | { | 1829 | { |
| 1827 | union i2c_smbus_data data; | 1830 | union i2c_smbus_data data; |
| @@ -1848,7 +1851,7 @@ EXPORT_SYMBOL(i2c_smbus_read_block_data); | |||
| 1848 | * This executes the SMBus "block write" protocol, returning negative errno | 1851 | * This executes the SMBus "block write" protocol, returning negative errno |
| 1849 | * else zero on success. | 1852 | * else zero on success. |
| 1850 | */ | 1853 | */ |
| 1851 | s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, | 1854 | s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command, |
| 1852 | u8 length, const u8 *values) | 1855 | u8 length, const u8 *values) |
| 1853 | { | 1856 | { |
| 1854 | union i2c_smbus_data data; | 1857 | union i2c_smbus_data data; |
| @@ -1864,7 +1867,7 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command, | |||
| 1864 | EXPORT_SYMBOL(i2c_smbus_write_block_data); | 1867 | EXPORT_SYMBOL(i2c_smbus_write_block_data); |
| 1865 | 1868 | ||
| 1866 | /* Returns the number of read bytes */ | 1869 | /* Returns the number of read bytes */ |
| 1867 | s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, | 1870 | s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client, u8 command, |
| 1868 | u8 length, u8 *values) | 1871 | u8 length, u8 *values) |
| 1869 | { | 1872 | { |
| 1870 | union i2c_smbus_data data; | 1873 | union i2c_smbus_data data; |
| @@ -1884,7 +1887,7 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, | |||
| 1884 | } | 1887 | } |
| 1885 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); | 1888 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); |
| 1886 | 1889 | ||
| 1887 | s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, | 1890 | s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command, |
| 1888 | u8 length, const u8 *values) | 1891 | u8 length, const u8 *values) |
| 1889 | { | 1892 | { |
| 1890 | union i2c_smbus_data data; | 1893 | union i2c_smbus_data data; |
diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig index 4d91d80bfd23..90b7a0163899 100644 --- a/drivers/i2c/muxes/Kconfig +++ b/drivers/i2c/muxes/Kconfig | |||
| @@ -5,6 +5,18 @@ | |||
| 5 | menu "Multiplexer I2C Chip support" | 5 | menu "Multiplexer I2C Chip support" |
| 6 | depends on I2C_MUX | 6 | depends on I2C_MUX |
| 7 | 7 | ||
| 8 | config I2C_MUX_GPIO | ||
| 9 | tristate "GPIO-based I2C multiplexer" | ||
| 10 | depends on GENERIC_GPIO | ||
| 11 | help | ||
| 12 | If you say yes to this option, support will be included for a | ||
| 13 | GPIO based I2C multiplexer. This driver provides access to | ||
| 14 | I2C busses connected through a MUX, which is controlled | ||
| 15 | through GPIO pins. | ||
| 16 | |||
| 17 | This driver can also be built as a module. If so, the module | ||
| 18 | will be called gpio-i2cmux. | ||
| 19 | |||
| 8 | config I2C_MUX_PCA9541 | 20 | config I2C_MUX_PCA9541 |
| 9 | tristate "NXP PCA9541 I2C Master Selector" | 21 | tristate "NXP PCA9541 I2C Master Selector" |
| 10 | depends on EXPERIMENTAL | 22 | depends on EXPERIMENTAL |
diff --git a/drivers/i2c/muxes/Makefile b/drivers/i2c/muxes/Makefile index d743806d9b42..4640436ea61f 100644 --- a/drivers/i2c/muxes/Makefile +++ b/drivers/i2c/muxes/Makefile | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Makefile for multiplexer I2C chip drivers. | 2 | # Makefile for multiplexer I2C chip drivers. |
| 3 | 3 | ||
| 4 | obj-$(CONFIG_I2C_MUX_GPIO) += gpio-i2cmux.o | ||
| 4 | obj-$(CONFIG_I2C_MUX_PCA9541) += pca9541.o | 5 | obj-$(CONFIG_I2C_MUX_PCA9541) += pca9541.o |
| 5 | obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o | 6 | obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o |
| 6 | 7 | ||
diff --git a/drivers/i2c/muxes/gpio-i2cmux.c b/drivers/i2c/muxes/gpio-i2cmux.c new file mode 100644 index 000000000000..7b6ce624cd6e --- /dev/null +++ b/drivers/i2c/muxes/gpio-i2cmux.c | |||
| @@ -0,0 +1,184 @@ | |||
| 1 | /* | ||
| 2 | * I2C multiplexer using GPIO API | ||
| 3 | * | ||
| 4 | * Peter Korsgaard <peter.korsgaard@barco.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/i2c.h> | ||
| 12 | #include <linux/i2c-mux.h> | ||
| 13 | #include <linux/gpio-i2cmux.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | #include <linux/gpio.h> | ||
| 19 | |||
| 20 | struct gpiomux { | ||
| 21 | struct i2c_adapter *parent; | ||
| 22 | struct i2c_adapter **adap; /* child busses */ | ||
| 23 | struct gpio_i2cmux_platform_data data; | ||
| 24 | }; | ||
| 25 | |||
| 26 | static void gpiomux_set(const struct gpiomux *mux, unsigned val) | ||
| 27 | { | ||
| 28 | int i; | ||
| 29 | |||
| 30 | for (i = 0; i < mux->data.n_gpios; i++) | ||
| 31 | gpio_set_value(mux->data.gpios[i], val & (1 << i)); | ||
| 32 | } | ||
| 33 | |||
| 34 | static int gpiomux_select(struct i2c_adapter *adap, void *data, u32 chan) | ||
| 35 | { | ||
| 36 | struct gpiomux *mux = data; | ||
| 37 | |||
| 38 | gpiomux_set(mux, mux->data.values[chan]); | ||
| 39 | |||
| 40 | return 0; | ||
| 41 | } | ||
| 42 | |||
| 43 | static int gpiomux_deselect(struct i2c_adapter *adap, void *data, u32 chan) | ||
| 44 | { | ||
| 45 | struct gpiomux *mux = data; | ||
| 46 | |||
| 47 | gpiomux_set(mux, mux->data.idle); | ||
| 48 | |||
| 49 | return 0; | ||
| 50 | } | ||
| 51 | |||
| 52 | static int __devinit gpiomux_probe(struct platform_device *pdev) | ||
| 53 | { | ||
| 54 | struct gpiomux *mux; | ||
| 55 | struct gpio_i2cmux_platform_data *pdata; | ||
| 56 | struct i2c_adapter *parent; | ||
| 57 | int (*deselect) (struct i2c_adapter *, void *, u32); | ||
| 58 | unsigned initial_state; | ||
| 59 | int i, ret; | ||
| 60 | |||
| 61 | pdata = pdev->dev.platform_data; | ||
| 62 | if (!pdata) { | ||
| 63 | dev_err(&pdev->dev, "Missing platform data\n"); | ||
| 64 | return -ENODEV; | ||
| 65 | } | ||
| 66 | |||
| 67 | parent = i2c_get_adapter(pdata->parent); | ||
| 68 | if (!parent) { | ||
| 69 | dev_err(&pdev->dev, "Parent adapter (%d) not found\n", | ||
| 70 | pdata->parent); | ||
| 71 | return -ENODEV; | ||
| 72 | } | ||
| 73 | |||
| 74 | mux = kzalloc(sizeof(*mux), GFP_KERNEL); | ||
| 75 | if (!mux) { | ||
| 76 | ret = -ENOMEM; | ||
| 77 | goto alloc_failed; | ||
| 78 | } | ||
| 79 | |||
| 80 | mux->parent = parent; | ||
| 81 | mux->data = *pdata; | ||
| 82 | mux->adap = kzalloc(sizeof(struct i2c_adapter *) * pdata->n_values, | ||
| 83 | GFP_KERNEL); | ||
| 84 | if (!mux->adap) { | ||
| 85 | ret = -ENOMEM; | ||
| 86 | goto alloc_failed2; | ||
| 87 | } | ||
| 88 | |||
| 89 | if (pdata->idle != GPIO_I2CMUX_NO_IDLE) { | ||
| 90 | initial_state = pdata->idle; | ||
| 91 | deselect = gpiomux_deselect; | ||
| 92 | } else { | ||
| 93 | initial_state = pdata->values[0]; | ||
| 94 | deselect = NULL; | ||
| 95 | } | ||
| 96 | |||
| 97 | for (i = 0; i < pdata->n_gpios; i++) { | ||
| 98 | ret = gpio_request(pdata->gpios[i], "gpio-i2cmux"); | ||
| 99 | if (ret) | ||
| 100 | goto err_request_gpio; | ||
| 101 | gpio_direction_output(pdata->gpios[i], | ||
| 102 | initial_state & (1 << i)); | ||
| 103 | } | ||
| 104 | |||
| 105 | for (i = 0; i < pdata->n_values; i++) { | ||
| 106 | u32 nr = pdata->base_nr ? (pdata->base_nr + i) : 0; | ||
| 107 | |||
| 108 | mux->adap[i] = i2c_add_mux_adapter(parent, mux, nr, i, | ||
| 109 | gpiomux_select, deselect); | ||
| 110 | if (!mux->adap[i]) { | ||
| 111 | ret = -ENODEV; | ||
| 112 | dev_err(&pdev->dev, "Failed to add adapter %d\n", i); | ||
| 113 | goto add_adapter_failed; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 117 | dev_info(&pdev->dev, "%d port mux on %s adapter\n", | ||
| 118 | pdata->n_values, parent->name); | ||
| 119 | |||
| 120 | platform_set_drvdata(pdev, mux); | ||
| 121 | |||
| 122 | return 0; | ||
| 123 | |||
| 124 | add_adapter_failed: | ||
| 125 | for (; i > 0; i--) | ||
| 126 | i2c_del_mux_adapter(mux->adap[i - 1]); | ||
| 127 | i = pdata->n_gpios; | ||
| 128 | err_request_gpio: | ||
| 129 | for (; i > 0; i--) | ||
| 130 | gpio_free(pdata->gpios[i - 1]); | ||
| 131 | kfree(mux->adap); | ||
| 132 | alloc_failed2: | ||
| 133 | kfree(mux); | ||
| 134 | alloc_failed: | ||
| 135 | i2c_put_adapter(parent); | ||
| 136 | |||
| 137 | return ret; | ||
| 138 | } | ||
| 139 | |||
| 140 | static int __devexit gpiomux_remove(struct platform_device *pdev) | ||
| 141 | { | ||
| 142 | struct gpiomux *mux = platform_get_drvdata(pdev); | ||
| 143 | int i; | ||
| 144 | |||
| 145 | for (i = 0; i < mux->data.n_values; i++) | ||
| 146 | i2c_del_mux_adapter(mux->adap[i]); | ||
| 147 | |||
| 148 | for (i = 0; i < mux->data.n_gpios; i++) | ||
| 149 | gpio_free(mux->data.gpios[i]); | ||
| 150 | |||
| 151 | platform_set_drvdata(pdev, NULL); | ||
| 152 | i2c_put_adapter(mux->parent); | ||
| 153 | kfree(mux->adap); | ||
| 154 | kfree(mux); | ||
| 155 | |||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | static struct platform_driver gpiomux_driver = { | ||
| 160 | .probe = gpiomux_probe, | ||
| 161 | .remove = __devexit_p(gpiomux_remove), | ||
| 162 | .driver = { | ||
| 163 | .owner = THIS_MODULE, | ||
| 164 | .name = "gpio-i2cmux", | ||
| 165 | }, | ||
| 166 | }; | ||
| 167 | |||
| 168 | static int __init gpiomux_init(void) | ||
| 169 | { | ||
| 170 | return platform_driver_register(&gpiomux_driver); | ||
| 171 | } | ||
| 172 | |||
| 173 | static void __exit gpiomux_exit(void) | ||
| 174 | { | ||
| 175 | platform_driver_unregister(&gpiomux_driver); | ||
| 176 | } | ||
| 177 | |||
| 178 | module_init(gpiomux_init); | ||
| 179 | module_exit(gpiomux_exit); | ||
| 180 | |||
| 181 | MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver"); | ||
| 182 | MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>"); | ||
| 183 | MODULE_LICENSE("GPL"); | ||
| 184 | MODULE_ALIAS("platform:gpio-i2cmux"); | ||
