diff options
-rw-r--r-- | drivers/gpio/gpio-74x164.c | 68 |
1 files changed, 61 insertions, 7 deletions
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c index 2e31bd35769a..ed3e55161bdc 100644 --- a/drivers/gpio/gpio-74x164.c +++ b/drivers/gpio/gpio-74x164.c | |||
@@ -14,14 +14,18 @@ | |||
14 | #include <linux/spi/spi.h> | 14 | #include <linux/spi/spi.h> |
15 | #include <linux/spi/74x164.h> | 15 | #include <linux/spi/74x164.h> |
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/of_gpio.h> | ||
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
18 | #include <linux/module.h> | 19 | #include <linux/module.h> |
19 | 20 | ||
21 | #define GEN_74X164_NUMBER_GPIOS 8 | ||
22 | |||
20 | struct gen_74x164_chip { | 23 | struct gen_74x164_chip { |
21 | struct spi_device *spi; | 24 | struct spi_device *spi; |
25 | u8 *buffer; | ||
22 | struct gpio_chip gpio_chip; | 26 | struct gpio_chip gpio_chip; |
23 | struct mutex lock; | 27 | struct mutex lock; |
24 | u8 port_config; | 28 | u32 registers; |
25 | }; | 29 | }; |
26 | 30 | ||
27 | static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc) | 31 | static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc) |
@@ -31,17 +35,47 @@ static struct gen_74x164_chip *gpio_to_74x164_chip(struct gpio_chip *gc) | |||
31 | 35 | ||
32 | static int __gen_74x164_write_config(struct gen_74x164_chip *chip) | 36 | static int __gen_74x164_write_config(struct gen_74x164_chip *chip) |
33 | { | 37 | { |
34 | return spi_write(chip->spi, | 38 | struct spi_message message; |
35 | &chip->port_config, sizeof(chip->port_config)); | 39 | struct spi_transfer *msg_buf; |
40 | int i, ret = 0; | ||
41 | |||
42 | msg_buf = kzalloc(chip->registers * sizeof(struct spi_transfer), | ||
43 | GFP_KERNEL); | ||
44 | if (!msg_buf) | ||
45 | return -ENOMEM; | ||
46 | |||
47 | spi_message_init(&message); | ||
48 | |||
49 | /* | ||
50 | * Since the registers are chained, every byte sent will make | ||
51 | * the previous byte shift to the next register in the | ||
52 | * chain. Thus, the first byte send will end up in the last | ||
53 | * register at the end of the transfer. So, to have a logical | ||
54 | * numbering, send the bytes in reverse order so that the last | ||
55 | * byte of the buffer will end up in the last register. | ||
56 | */ | ||
57 | for (i = chip->registers - 1; i >= 0; i--) { | ||
58 | msg_buf[i].tx_buf = chip->buffer +i; | ||
59 | msg_buf[i].len = sizeof(u8); | ||
60 | spi_message_add_tail(msg_buf + i, &message); | ||
61 | } | ||
62 | |||
63 | ret = spi_sync(chip->spi, &message); | ||
64 | |||
65 | kfree(msg_buf); | ||
66 | |||
67 | return ret; | ||
36 | } | 68 | } |
37 | 69 | ||
38 | static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) | 70 | static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset) |
39 | { | 71 | { |
40 | struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc); | 72 | struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc); |
73 | u8 bank = offset / 8; | ||
74 | u8 pin = offset % 8; | ||
41 | int ret; | 75 | int ret; |
42 | 76 | ||
43 | mutex_lock(&chip->lock); | 77 | mutex_lock(&chip->lock); |
44 | ret = (chip->port_config >> offset) & 0x1; | 78 | ret = (chip->buffer[bank] >> pin) & 0x1; |
45 | mutex_unlock(&chip->lock); | 79 | mutex_unlock(&chip->lock); |
46 | 80 | ||
47 | return ret; | 81 | return ret; |
@@ -51,12 +85,14 @@ static void gen_74x164_set_value(struct gpio_chip *gc, | |||
51 | unsigned offset, int val) | 85 | unsigned offset, int val) |
52 | { | 86 | { |
53 | struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc); | 87 | struct gen_74x164_chip *chip = gpio_to_74x164_chip(gc); |
88 | u8 bank = offset / 8; | ||
89 | u8 pin = offset % 8; | ||
54 | 90 | ||
55 | mutex_lock(&chip->lock); | 91 | mutex_lock(&chip->lock); |
56 | if (val) | 92 | if (val) |
57 | chip->port_config |= (1 << offset); | 93 | chip->buffer[bank] |= (1 << pin); |
58 | else | 94 | else |
59 | chip->port_config &= ~(1 << offset); | 95 | chip->buffer[bank] &= ~(1 << pin); |
60 | 96 | ||
61 | __gen_74x164_write_config(chip); | 97 | __gen_74x164_write_config(chip); |
62 | mutex_unlock(&chip->lock); | 98 | mutex_unlock(&chip->lock); |
@@ -75,6 +111,11 @@ static int __devinit gen_74x164_probe(struct spi_device *spi) | |||
75 | struct gen_74x164_chip_platform_data *pdata; | 111 | struct gen_74x164_chip_platform_data *pdata; |
76 | int ret; | 112 | int ret; |
77 | 113 | ||
114 | if (!spi->dev.of_node) { | ||
115 | dev_err(&spi->dev, "No device tree data available.\n"); | ||
116 | return -EINVAL; | ||
117 | } | ||
118 | |||
78 | /* | 119 | /* |
79 | * bits_per_word cannot be configured in platform data | 120 | * bits_per_word cannot be configured in platform data |
80 | */ | 121 | */ |
@@ -104,7 +145,20 @@ static int __devinit gen_74x164_probe(struct spi_device *spi) | |||
104 | chip->gpio_chip.direction_output = gen_74x164_direction_output; | 145 | chip->gpio_chip.direction_output = gen_74x164_direction_output; |
105 | chip->gpio_chip.get = gen_74x164_get_value; | 146 | chip->gpio_chip.get = gen_74x164_get_value; |
106 | chip->gpio_chip.set = gen_74x164_set_value; | 147 | chip->gpio_chip.set = gen_74x164_set_value; |
107 | chip->gpio_chip.ngpio = 8; | 148 | |
149 | if (of_property_read_u32(spi->dev.of_node, "registers-number", &chip->registers)) { | ||
150 | dev_err(&spi->dev, "Missing registers-number property in the DT.\n"); | ||
151 | ret = -EINVAL; | ||
152 | goto exit_destroy; | ||
153 | } | ||
154 | |||
155 | chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers; | ||
156 | chip->buffer = devm_kzalloc(&spi->dev, chip->gpio_chip.ngpio, GFP_KERNEL); | ||
157 | if (!chip->buffer) { | ||
158 | ret = -ENOMEM; | ||
159 | goto exit_destroy; | ||
160 | } | ||
161 | |||
108 | chip->gpio_chip.can_sleep = 1; | 162 | chip->gpio_chip.can_sleep = 1; |
109 | chip->gpio_chip.dev = &spi->dev; | 163 | chip->gpio_chip.dev = &spi->dev; |
110 | chip->gpio_chip.owner = THIS_MODULE; | 164 | chip->gpio_chip.owner = THIS_MODULE; |