Commit e952805d2d2e706aed182723e5ab3ec0b1f91de3

Authored by Wolfram Sang
Committed by Linus Torvalds
1 parent 5a98c04d78

gpio: add driver for MAX7300 I2C GPIO extender

Add the MAX7300-I2C variant of the MAX7301-SPI version.  Both chips share
the same core logic, so the generic part of the in-kernel SPI-driver is
refactored into a generic part.  The I2C and SPI specific funtions are
then wrapped into seperate drivers picking up the generic part.

Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Cc: Juergen Beisert <j.beisert@pengutronix.de>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Jean Delvare <khali@linux-fr.org>
Cc: Anton Vorontsov <avorontsov@ru.mvista.com>
Cc: Randy Dunlap <randy.dunlap@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 6 changed files with 404 additions and 260 deletions Side-by-side Diff

drivers/gpio/Kconfig
... ... @@ -65,6 +65,9 @@
65 65  
66 66 # put expanders in the right section, in alphabetical order
67 67  
  68 +config GPIO_MAX730X
  69 + tristate
  70 +
68 71 comment "Memory mapped GPIO expanders:"
69 72  
70 73 config GPIO_PL061
... ... @@ -87,6 +90,13 @@
87 90  
88 91 comment "I2C GPIO expanders:"
89 92  
  93 +config GPIO_MAX7300
  94 + tristate "Maxim MAX7300 GPIO expander"
  95 + depends on I2C
  96 + select GPIO_MAX730X
  97 + help
  98 + GPIO driver for Maxim MAX7301 I2C-based GPIO expander.
  99 +
90 100 config GPIO_MAX732X
91 101 tristate "MAX7319, MAX7320-7327 I2C Port Expanders"
92 102 depends on I2C
93 103  
... ... @@ -226,8 +236,9 @@
226 236 config GPIO_MAX7301
227 237 tristate "Maxim MAX7301 GPIO expander"
228 238 depends on SPI_MASTER
  239 + select GPIO_MAX730X
229 240 help
230   - gpio driver for Maxim MAX7301 SPI GPIO expander.
  241 + GPIO driver for Maxim MAX7301 SPI-based GPIO expander.
231 242  
232 243 config GPIO_MCP23S08
233 244 tristate "Microchip MCP23S08 I/O expander"
drivers/gpio/Makefile
... ... @@ -7,6 +7,8 @@
7 7 obj-$(CONFIG_GPIO_ADP5520) += adp5520-gpio.o
8 8 obj-$(CONFIG_GPIO_ADP5588) += adp5588-gpio.o
9 9 obj-$(CONFIG_GPIO_LANGWELL) += langwell_gpio.o
  10 +obj-$(CONFIG_GPIO_MAX730X) += max730x.o
  11 +obj-$(CONFIG_GPIO_MAX7300) += max7300.o
10 12 obj-$(CONFIG_GPIO_MAX7301) += max7301.o
11 13 obj-$(CONFIG_GPIO_MAX732X) += max732x.o
12 14 obj-$(CONFIG_GPIO_MC33880) += mc33880.o
drivers/gpio/max7300.c
  1 +/*
  2 + * drivers/gpio/max7300.c
  3 + *
  4 + * Copyright (C) 2009 Wolfram Sang, Pengutronix
  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 + * Check max730x.c for further details.
  11 + */
  12 +
  13 +#include <linux/module.h>
  14 +#include <linux/init.h>
  15 +#include <linux/platform_device.h>
  16 +#include <linux/mutex.h>
  17 +#include <linux/i2c.h>
  18 +#include <linux/spi/max7301.h>
  19 +
  20 +static int max7300_i2c_write(struct device *dev, unsigned int reg,
  21 + unsigned int val)
  22 +{
  23 + struct i2c_client *client = to_i2c_client(dev);
  24 +
  25 + return i2c_smbus_write_byte_data(client, reg, val);
  26 +}
  27 +
  28 +static int max7300_i2c_read(struct device *dev, unsigned int reg)
  29 +{
  30 + struct i2c_client *client = to_i2c_client(dev);
  31 +
  32 + return i2c_smbus_read_byte_data(client, reg);
  33 +}
  34 +
  35 +static int __devinit max7300_probe(struct i2c_client *client,
  36 + const struct i2c_device_id *id)
  37 +{
  38 + struct max7301 *ts;
  39 + int ret;
  40 +
  41 + if (!i2c_check_functionality(client->adapter,
  42 + I2C_FUNC_SMBUS_BYTE_DATA))
  43 + return -EIO;
  44 +
  45 + ts = kzalloc(sizeof(struct max7301), GFP_KERNEL);
  46 + if (!ts)
  47 + return -ENOMEM;
  48 +
  49 + ts->read = max7300_i2c_read;
  50 + ts->write = max7300_i2c_write;
  51 + ts->dev = &client->dev;
  52 +
  53 + ret = __max730x_probe(ts);
  54 + if (ret)
  55 + kfree(ts);
  56 + return ret;
  57 +}
  58 +
  59 +static int __devexit max7300_remove(struct i2c_client *client)
  60 +{
  61 + return __max730x_remove(&client->dev);
  62 +}
  63 +
  64 +static const struct i2c_device_id max7300_id[] = {
  65 + { "max7300", 0 },
  66 + { }
  67 +};
  68 +MODULE_DEVICE_TABLE(i2c, max7300_id);
  69 +
  70 +static struct i2c_driver max7300_driver = {
  71 + .driver = {
  72 + .name = "max7300",
  73 + .owner = THIS_MODULE,
  74 + },
  75 + .probe = max7300_probe,
  76 + .remove = __devexit_p(max7300_remove),
  77 + .id_table = max7300_id,
  78 +};
  79 +
  80 +static int __init max7300_init(void)
  81 +{
  82 + return i2c_add_driver(&max7300_driver);
  83 +}
  84 +subsys_initcall(max7300_init);
  85 +
  86 +static void __exit max7300_exit(void)
  87 +{
  88 + i2c_del_driver(&max7300_driver);
  89 +}
  90 +module_exit(max7300_exit);
  91 +
  92 +MODULE_AUTHOR("Wolfram Sang");
  93 +MODULE_LICENSE("GPL v2");
  94 +MODULE_DESCRIPTION("MAX7300 GPIO-Expander");
drivers/gpio/max7301.c
1   -/**
  1 +/*
2 2 * drivers/gpio/max7301.c
3 3 *
4 4 * Copyright (C) 2006 Juergen Beisert, Pengutronix
5 5 * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
  6 + * Copyright (C) 2009 Wolfram Sang, Pengutronix
6 7 *
7 8 * This program is free software; you can redistribute it and/or modify
8 9 * it under the terms of the GNU General Public License version 2 as
9 10 * published by the Free Software Foundation.
10 11 *
11   - * The Maxim's MAX7301 device is an SPI driven GPIO expander. There are
12   - * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more
13   - * details
14   - * Note:
15   - * - DIN must be stable at the rising edge of clock.
16   - * - when writing:
17   - * - always clock in 16 clocks at once
18   - * - at DIN: D15 first, D0 last
19   - * - D0..D7 = databyte, D8..D14 = commandbyte
20   - * - D15 = low -> write command
21   - * - when reading
22   - * - always clock in 16 clocks at once
23   - * - at DIN: D15 first, D0 last
24   - * - D0..D7 = dummy, D8..D14 = register address
25   - * - D15 = high -> read command
26   - * - raise CS and assert it again
27   - * - always clock in 16 clocks at once
28   - * - at DOUT: D15 first, D0 last
29   - * - D0..D7 contains the data from the first cycle
30   - *
31   - * The driver exports a standard gpiochip interface
  12 + * Check max730x.c for further details.
32 13 */
33 14  
  15 +#include <linux/module.h>
34 16 #include <linux/init.h>
35 17 #include <linux/platform_device.h>
36 18 #include <linux/mutex.h>
37 19 #include <linux/spi/spi.h>
38 20 #include <linux/spi/max7301.h>
39   -#include <linux/gpio.h>
40 21  
41   -#define DRIVER_NAME "max7301"
42   -
43   -/*
44   - * Pin configurations, see MAX7301 datasheet page 6
45   - */
46   -#define PIN_CONFIG_MASK 0x03
47   -#define PIN_CONFIG_IN_PULLUP 0x03
48   -#define PIN_CONFIG_IN_WO_PULLUP 0x02
49   -#define PIN_CONFIG_OUT 0x01
50   -
51   -#define PIN_NUMBER 28
52   -
53   -
54   -/*
55   - * Some registers must be read back to modify.
56   - * To save time we cache them here in memory
57   - */
58   -struct max7301 {
59   - struct mutex lock;
60   - u8 port_config[8]; /* field 0 is unused */
61   - u32 out_level; /* cached output levels */
62   - struct gpio_chip chip;
63   - struct spi_device *spi;
64   -};
65   -
66   -/**
67   - * max7301_write - Write a new register content
68   - * @spi: The SPI device
69   - * @reg: Register offset
70   - * @val: Value to write
71   - *
72   - * A write to the MAX7301 means one message with one transfer
73   - *
74   - * Returns 0 if successful or a negative value on error
75   - */
76   -static int max7301_write(struct spi_device *spi, unsigned int reg, unsigned int val)
  22 +/* A write to the MAX7301 means one message with one transfer */
  23 +static int max7301_spi_write(struct device *dev, unsigned int reg,
  24 + unsigned int val)
77 25 {
  26 + struct spi_device *spi = to_spi_device(dev);
78 27 u16 word = ((reg & 0x7F) << 8) | (val & 0xFF);
  28 +
79 29 return spi_write(spi, (const u8 *)&word, sizeof(word));
80 30 }
81 31  
82   -/**
83   - * max7301_read - Read back register content
84   - * @spi: The SPI device
85   - * @reg: Register offset
86   - *
87   - * A read from the MAX7301 means two transfers; here, one message each
88   - *
89   - * Returns positive 8 bit value from device if successful or a
90   - * negative value on error
91   - */
92   -static int max7301_read(struct spi_device *spi, unsigned int reg)
  32 +/* A read from the MAX7301 means two transfers; here, one message each */
  33 +
  34 +static int max7301_spi_read(struct device *dev, unsigned int reg)
93 35 {
94 36 int ret;
95 37 u16 word;
  38 + struct spi_device *spi = to_spi_device(dev);
96 39  
97 40 word = 0x8000 | (reg << 8);
98 41 ret = spi_write(spi, (const u8 *)&word, sizeof(word));
99 42  
100 43  
101 44  
... ... @@ -108,125 +51,13 @@
108 51 return word & 0xff;
109 52 }
110 53  
111   -static int max7301_direction_input(struct gpio_chip *chip, unsigned offset)
112   -{
113   - struct max7301 *ts = container_of(chip, struct max7301, chip);
114   - u8 *config;
115   - int ret;
116   -
117   - /* First 4 pins are unused in the controller */
118   - offset += 4;
119   -
120   - config = &ts->port_config[offset >> 2];
121   -
122   - mutex_lock(&ts->lock);
123   -
124   - /* Standard GPIO API doesn't support pull-ups, has to be extended.
125   - * Hard-coding no pollup for now. */
126   - *config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
127   -
128   - ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
129   -
130   - mutex_unlock(&ts->lock);
131   -
132   - return ret;
133   -}
134   -
135   -static int __max7301_set(struct max7301 *ts, unsigned offset, int value)
136   -{
137   - if (value) {
138   - ts->out_level |= 1 << offset;
139   - return max7301_write(ts->spi, 0x20 + offset, 0x01);
140   - } else {
141   - ts->out_level &= ~(1 << offset);
142   - return max7301_write(ts->spi, 0x20 + offset, 0x00);
143   - }
144   -}
145   -
146   -static int max7301_direction_output(struct gpio_chip *chip, unsigned offset,
147   - int value)
148   -{
149   - struct max7301 *ts = container_of(chip, struct max7301, chip);
150   - u8 *config;
151   - int ret;
152   -
153   - /* First 4 pins are unused in the controller */
154   - offset += 4;
155   -
156   - config = &ts->port_config[offset >> 2];
157   -
158   - mutex_lock(&ts->lock);
159   -
160   - *config = (*config & ~(3 << (offset & 3))) | (1 << (offset & 3));
161   -
162   - ret = __max7301_set(ts, offset, value);
163   -
164   - if (!ret)
165   - ret = max7301_write(ts->spi, 0x08 + (offset >> 2), *config);
166   -
167   - mutex_unlock(&ts->lock);
168   -
169   - return ret;
170   -}
171   -
172   -static int max7301_get(struct gpio_chip *chip, unsigned offset)
173   -{
174   - struct max7301 *ts = container_of(chip, struct max7301, chip);
175   - int config, level = -EINVAL;
176   -
177   - /* First 4 pins are unused in the controller */
178   - offset += 4;
179   -
180   - mutex_lock(&ts->lock);
181   -
182   - config = (ts->port_config[offset >> 2] >> ((offset & 3) * 2)) & 3;
183   -
184   - switch (config) {
185   - case 1:
186   - /* Output: return cached level */
187   - level = !!(ts->out_level & (1 << offset));
188   - break;
189   - case 2:
190   - case 3:
191   - /* Input: read out */
192   - level = max7301_read(ts->spi, 0x20 + offset) & 0x01;
193   - }
194   - mutex_unlock(&ts->lock);
195   -
196   - return level;
197   -}
198   -
199   -static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
200   -{
201   - struct max7301 *ts = container_of(chip, struct max7301, chip);
202   -
203   - /* First 4 pins are unused in the controller */
204   - offset += 4;
205   -
206   - mutex_lock(&ts->lock);
207   -
208   - __max7301_set(ts, offset, value);
209   -
210   - mutex_unlock(&ts->lock);
211   -}
212   -
213 54 static int __devinit max7301_probe(struct spi_device *spi)
214 55 {
215 56 struct max7301 *ts;
216   - struct max7301_platform_data *pdata;
217   - int i, ret;
  57 + int ret;
218 58  
219   - pdata = spi->dev.platform_data;
220   - if (!pdata || !pdata->base) {
221   - dev_dbg(&spi->dev, "incorrect or missing platform data\n");
222   - return -EINVAL;
223   - }
224   -
225   - /*
226   - * bits_per_word cannot be configured in platform data
227   - */
  59 + /* bits_per_word cannot be configured in platform data */
228 60 spi->bits_per_word = 16;
229   -
230 61 ret = spi_setup(spi);
231 62 if (ret < 0)
232 63 return ret;
233 64  
234 65  
235 66  
236 67  
237 68  
238 69  
239 70  
... ... @@ -235,90 +66,35 @@
235 66 if (!ts)
236 67 return -ENOMEM;
237 68  
238   - mutex_init(&ts->lock);
  69 + ts->read = max7301_spi_read;
  70 + ts->write = max7301_spi_write;
  71 + ts->dev = &spi->dev;
239 72  
240   - dev_set_drvdata(&spi->dev, ts);
241   -
242   - /* Power up the chip and disable IRQ output */
243   - max7301_write(spi, 0x04, 0x01);
244   -
245   - ts->spi = spi;
246   -
247   - ts->chip.label = DRIVER_NAME,
248   -
249   - ts->chip.direction_input = max7301_direction_input;
250   - ts->chip.get = max7301_get;
251   - ts->chip.direction_output = max7301_direction_output;
252   - ts->chip.set = max7301_set;
253   -
254   - ts->chip.base = pdata->base;
255   - ts->chip.ngpio = PIN_NUMBER;
256   - ts->chip.can_sleep = 1;
257   - ts->chip.dev = &spi->dev;
258   - ts->chip.owner = THIS_MODULE;
259   -
260   - /*
261   - * tristate all pins in hardware and cache the
262   - * register values for later use.
263   - */
264   - for (i = 1; i < 8; i++) {
265   - int j;
266   - /* 0xAA means input with internal pullup disabled */
267   - max7301_write(spi, 0x08 + i, 0xAA);
268   - ts->port_config[i] = 0xAA;
269   - for (j = 0; j < 4; j++) {
270   - int offset = (i - 1) * 4 + j;
271   - ret = max7301_direction_input(&ts->chip, offset);
272   - if (ret)
273   - goto exit_destroy;
274   - }
275   - }
276   -
277   - ret = gpiochip_add(&ts->chip);
  73 + ret = __max730x_probe(ts);
278 74 if (ret)
279   - goto exit_destroy;
280   -
  75 + kfree(ts);
281 76 return ret;
282   -
283   -exit_destroy:
284   - dev_set_drvdata(&spi->dev, NULL);
285   - mutex_destroy(&ts->lock);
286   - kfree(ts);
287   - return ret;
288 77 }
289 78  
290 79 static int __devexit max7301_remove(struct spi_device *spi)
291 80 {
292   - struct max7301 *ts;
293   - int ret;
294   -
295   - ts = dev_get_drvdata(&spi->dev);
296   - if (ts == NULL)
297   - return -ENODEV;
298   -
299   - dev_set_drvdata(&spi->dev, NULL);
300   -
301   - /* Power down the chip and disable IRQ output */
302   - max7301_write(spi, 0x04, 0x00);
303   -
304   - ret = gpiochip_remove(&ts->chip);
305   - if (!ret) {
306   - mutex_destroy(&ts->lock);
307   - kfree(ts);
308   - } else
309   - dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
310   - ret);
311   -
312   - return ret;
  81 + return __max730x_remove(&spi->dev);
313 82 }
314 83  
  84 +static const struct spi_device_id max7301_id[] = {
  85 + { "max7301", 0 },
  86 + { }
  87 +};
  88 +MODULE_DEVICE_TABLE(spi, max7301_id);
  89 +
315 90 static struct spi_driver max7301_driver = {
316 91 .driver = {
317   - .name = DRIVER_NAME,
318   - .owner = THIS_MODULE,
  92 + .name = "max7301",
  93 + .owner = THIS_MODULE,
319 94 },
320   - .probe = max7301_probe,
321   - .remove = __devexit_p(max7301_remove),
  95 + .probe = max7301_probe,
  96 + .remove = __devexit_p(max7301_remove),
  97 + .id_table = max7301_id,
322 98 };
323 99  
324 100 static int __init max7301_init(void)
325 101  
... ... @@ -336,8 +112,7 @@
336 112 }
337 113 module_exit(max7301_exit);
338 114  
339   -MODULE_AUTHOR("Juergen Beisert");
  115 +MODULE_AUTHOR("Juergen Beisert, Wolfram Sang");
340 116 MODULE_LICENSE("GPL v2");
341   -MODULE_DESCRIPTION("MAX7301 SPI based GPIO-Expander");
342   -MODULE_ALIAS("spi:" DRIVER_NAME);
  117 +MODULE_DESCRIPTION("MAX7301 GPIO-Expander");
drivers/gpio/max730x.c
  1 +/**
  2 + * drivers/gpio/max7301.c
  3 + *
  4 + * Copyright (C) 2006 Juergen Beisert, Pengutronix
  5 + * Copyright (C) 2008 Guennadi Liakhovetski, Pengutronix
  6 + * Copyright (C) 2009 Wolfram Sang, Pengutronix
  7 + *
  8 + * This program is free software; you can redistribute it and/or modify
  9 + * it under the terms of the GNU General Public License version 2 as
  10 + * published by the Free Software Foundation.
  11 + *
  12 + * The Maxim MAX7300/1 device is an I2C/SPI driven GPIO expander. There are
  13 + * 28 GPIOs. 8 of them can trigger an interrupt. See datasheet for more
  14 + * details
  15 + * Note:
  16 + * - DIN must be stable at the rising edge of clock.
  17 + * - when writing:
  18 + * - always clock in 16 clocks at once
  19 + * - at DIN: D15 first, D0 last
  20 + * - D0..D7 = databyte, D8..D14 = commandbyte
  21 + * - D15 = low -> write command
  22 + * - when reading
  23 + * - always clock in 16 clocks at once
  24 + * - at DIN: D15 first, D0 last
  25 + * - D0..D7 = dummy, D8..D14 = register address
  26 + * - D15 = high -> read command
  27 + * - raise CS and assert it again
  28 + * - always clock in 16 clocks at once
  29 + * - at DOUT: D15 first, D0 last
  30 + * - D0..D7 contains the data from the first cycle
  31 + *
  32 + * The driver exports a standard gpiochip interface
  33 + */
  34 +
  35 +#include <linux/module.h>
  36 +#include <linux/init.h>
  37 +#include <linux/platform_device.h>
  38 +#include <linux/mutex.h>
  39 +#include <linux/spi/max7301.h>
  40 +#include <linux/gpio.h>
  41 +
  42 +/*
  43 + * Pin configurations, see MAX7301 datasheet page 6
  44 + */
  45 +#define PIN_CONFIG_MASK 0x03
  46 +#define PIN_CONFIG_IN_PULLUP 0x03
  47 +#define PIN_CONFIG_IN_WO_PULLUP 0x02
  48 +#define PIN_CONFIG_OUT 0x01
  49 +
  50 +#define PIN_NUMBER 28
  51 +
  52 +static int max7301_direction_input(struct gpio_chip *chip, unsigned offset)
  53 +{
  54 + struct max7301 *ts = container_of(chip, struct max7301, chip);
  55 + u8 *config;
  56 + u8 offset_bits;
  57 + int ret;
  58 +
  59 + /* First 4 pins are unused in the controller */
  60 + offset += 4;
  61 + offset_bits = (offset & 3) << 1;
  62 +
  63 + config = &ts->port_config[offset >> 2];
  64 +
  65 + mutex_lock(&ts->lock);
  66 +
  67 + /* Standard GPIO API doesn't support pull-ups, has to be extended.
  68 + * Hard-coding no pollup for now. */
  69 + *config = (*config & ~(PIN_CONFIG_MASK << offset_bits))
  70 + | (PIN_CONFIG_IN_WO_PULLUP << offset_bits);
  71 +
  72 + ret = ts->write(ts->dev, 0x08 + (offset >> 2), *config);
  73 +
  74 + mutex_unlock(&ts->lock);
  75 +
  76 + return ret;
  77 +}
  78 +
  79 +static int __max7301_set(struct max7301 *ts, unsigned offset, int value)
  80 +{
  81 + if (value) {
  82 + ts->out_level |= 1 << offset;
  83 + return ts->write(ts->dev, 0x20 + offset, 0x01);
  84 + } else {
  85 + ts->out_level &= ~(1 << offset);
  86 + return ts->write(ts->dev, 0x20 + offset, 0x00);
  87 + }
  88 +}
  89 +
  90 +static int max7301_direction_output(struct gpio_chip *chip, unsigned offset,
  91 + int value)
  92 +{
  93 + struct max7301 *ts = container_of(chip, struct max7301, chip);
  94 + u8 *config;
  95 + u8 offset_bits;
  96 + int ret;
  97 +
  98 + /* First 4 pins are unused in the controller */
  99 + offset += 4;
  100 + offset_bits = (offset & 3) << 1;
  101 +
  102 + config = &ts->port_config[offset >> 2];
  103 +
  104 + mutex_lock(&ts->lock);
  105 +
  106 + *config = (*config & ~(PIN_CONFIG_MASK << offset_bits))
  107 + | (PIN_CONFIG_OUT << offset_bits);
  108 +
  109 + ret = __max7301_set(ts, offset, value);
  110 +
  111 + if (!ret)
  112 + ret = ts->write(ts->dev, 0x08 + (offset >> 2), *config);
  113 +
  114 + mutex_unlock(&ts->lock);
  115 +
  116 + return ret;
  117 +}
  118 +
  119 +static int max7301_get(struct gpio_chip *chip, unsigned offset)
  120 +{
  121 + struct max7301 *ts = container_of(chip, struct max7301, chip);
  122 + int config, level = -EINVAL;
  123 +
  124 + /* First 4 pins are unused in the controller */
  125 + offset += 4;
  126 +
  127 + mutex_lock(&ts->lock);
  128 +
  129 + config = (ts->port_config[offset >> 2] >> ((offset & 3) << 1))
  130 + & PIN_CONFIG_MASK;
  131 +
  132 + switch (config) {
  133 + case PIN_CONFIG_OUT:
  134 + /* Output: return cached level */
  135 + level = !!(ts->out_level & (1 << offset));
  136 + break;
  137 + case PIN_CONFIG_IN_WO_PULLUP:
  138 + case PIN_CONFIG_IN_PULLUP:
  139 + /* Input: read out */
  140 + level = ts->read(ts->dev, 0x20 + offset) & 0x01;
  141 + }
  142 + mutex_unlock(&ts->lock);
  143 +
  144 + return level;
  145 +}
  146 +
  147 +static void max7301_set(struct gpio_chip *chip, unsigned offset, int value)
  148 +{
  149 + struct max7301 *ts = container_of(chip, struct max7301, chip);
  150 +
  151 + /* First 4 pins are unused in the controller */
  152 + offset += 4;
  153 +
  154 + mutex_lock(&ts->lock);
  155 +
  156 + __max7301_set(ts, offset, value);
  157 +
  158 + mutex_unlock(&ts->lock);
  159 +}
  160 +
  161 +int __devinit __max730x_probe(struct max7301 *ts)
  162 +{
  163 + struct device *dev = ts->dev;
  164 + struct max7301_platform_data *pdata;
  165 + int i, ret;
  166 +
  167 + pdata = dev->platform_data;
  168 + if (!pdata || !pdata->base) {
  169 + dev_err(dev, "incorrect or missing platform data\n");
  170 + return -EINVAL;
  171 + }
  172 +
  173 + mutex_init(&ts->lock);
  174 + dev_set_drvdata(dev, ts);
  175 +
  176 + /* Power up the chip and disable IRQ output */
  177 + ts->write(dev, 0x04, 0x01);
  178 +
  179 + ts->chip.label = dev->driver->name;
  180 +
  181 + ts->chip.direction_input = max7301_direction_input;
  182 + ts->chip.get = max7301_get;
  183 + ts->chip.direction_output = max7301_direction_output;
  184 + ts->chip.set = max7301_set;
  185 +
  186 + ts->chip.base = pdata->base;
  187 + ts->chip.ngpio = PIN_NUMBER;
  188 + ts->chip.can_sleep = 1;
  189 + ts->chip.dev = dev;
  190 + ts->chip.owner = THIS_MODULE;
  191 +
  192 + /*
  193 + * tristate all pins in hardware and cache the
  194 + * register values for later use.
  195 + */
  196 + for (i = 1; i < 8; i++) {
  197 + int j;
  198 + /* 0xAA means input with internal pullup disabled */
  199 + ts->write(dev, 0x08 + i, 0xAA);
  200 + ts->port_config[i] = 0xAA;
  201 + for (j = 0; j < 4; j++) {
  202 + int offset = (i - 1) * 4 + j;
  203 + ret = max7301_direction_input(&ts->chip, offset);
  204 + if (ret)
  205 + goto exit_destroy;
  206 + }
  207 + }
  208 +
  209 + ret = gpiochip_add(&ts->chip);
  210 + if (ret)
  211 + goto exit_destroy;
  212 +
  213 + return ret;
  214 +
  215 +exit_destroy:
  216 + dev_set_drvdata(dev, NULL);
  217 + mutex_destroy(&ts->lock);
  218 + return ret;
  219 +}
  220 +EXPORT_SYMBOL_GPL(__max730x_probe);
  221 +
  222 +int __devexit __max730x_remove(struct device *dev)
  223 +{
  224 + struct max7301 *ts = dev_get_drvdata(dev);
  225 + int ret;
  226 +
  227 + if (ts == NULL)
  228 + return -ENODEV;
  229 +
  230 + dev_set_drvdata(dev, NULL);
  231 +
  232 + /* Power down the chip and disable IRQ output */
  233 + ts->write(dev, 0x04, 0x00);
  234 +
  235 + ret = gpiochip_remove(&ts->chip);
  236 + if (!ret) {
  237 + mutex_destroy(&ts->lock);
  238 + kfree(ts);
  239 + } else
  240 + dev_err(dev, "Failed to remove GPIO controller: %d\n", ret);
  241 +
  242 + return ret;
  243 +}
  244 +EXPORT_SYMBOL_GPL(__max730x_remove);
include/linux/spi/max7301.h
1 1 #ifndef LINUX_SPI_MAX7301_H
2 2 #define LINUX_SPI_MAX7301_H
3 3  
  4 +#include <linux/gpio.h>
  5 +
  6 +/*
  7 + * Some registers must be read back to modify.
  8 + * To save time we cache them here in memory
  9 + */
  10 +struct max7301 {
  11 + struct mutex lock;
  12 + u8 port_config[8]; /* field 0 is unused */
  13 + u32 out_level; /* cached output levels */
  14 + struct gpio_chip chip;
  15 + struct device *dev;
  16 + int (*write)(struct device *dev, unsigned int reg, unsigned int val);
  17 + int (*read)(struct device *dev, unsigned int reg);
  18 +};
  19 +
4 20 struct max7301_platform_data {
5 21 /* number assigned to the first GPIO */
6 22 unsigned base;
7 23 };
8 24  
  25 +extern int __max730x_remove(struct device *dev);
  26 +extern int __max730x_probe(struct max7301 *ts);
9 27 #endif