Merge branch 'fix/misc' into for-linus
[pandora-kernel.git] / drivers / gpio / mcp23s08.c
1 /*
2  * mcp23s08.c - SPI gpio expander driver
3  */
4
5 #include <linux/kernel.h>
6 #include <linux/device.h>
7 #include <linux/workqueue.h>
8 #include <linux/mutex.h>
9 #include <linux/gpio.h>
10 #include <linux/spi/spi.h>
11 #include <linux/spi/mcp23s08.h>
12 #include <linux/slab.h>
13
14
15 /* Registers are all 8 bits wide.
16  *
17  * The mcp23s17 has twice as many bits, and can be configured to work
18  * with either 16 bit registers or with two adjacent 8 bit banks.
19  *
20  * Also, there are I2C versions of both chips.
21  */
22 #define MCP_IODIR       0x00            /* init/reset:  all ones */
23 #define MCP_IPOL        0x01
24 #define MCP_GPINTEN     0x02
25 #define MCP_DEFVAL      0x03
26 #define MCP_INTCON      0x04
27 #define MCP_IOCON       0x05
28 #       define IOCON_SEQOP      (1 << 5)
29 #       define IOCON_HAEN       (1 << 3)
30 #       define IOCON_ODR        (1 << 2)
31 #       define IOCON_INTPOL     (1 << 1)
32 #define MCP_GPPU        0x06
33 #define MCP_INTF        0x07
34 #define MCP_INTCAP      0x08
35 #define MCP_GPIO        0x09
36 #define MCP_OLAT        0x0a
37
38 struct mcp23s08 {
39         struct spi_device       *spi;
40         u8                      addr;
41
42         u8                      cache[11];
43         /* lock protects the cached values */
44         struct mutex            lock;
45
46         struct gpio_chip        chip;
47
48         struct work_struct      work;
49 };
50
51 /* A given spi_device can represent up to four mcp23s08 chips
52  * sharing the same chipselect but using different addresses
53  * (e.g. chips #0 and #3 might be populated, but not #1 or $2).
54  * Driver data holds all the per-chip data.
55  */
56 struct mcp23s08_driver_data {
57         unsigned                ngpio;
58         struct mcp23s08         *mcp[4];
59         struct mcp23s08         chip[];
60 };
61
62 static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)
63 {
64         u8      tx[2], rx[1];
65         int     status;
66
67         tx[0] = mcp->addr | 0x01;
68         tx[1] = reg;
69         status = spi_write_then_read(mcp->spi, tx, sizeof tx, rx, sizeof rx);
70         return (status < 0) ? status : rx[0];
71 }
72
73 static int mcp23s08_write(struct mcp23s08 *mcp, unsigned reg, u8 val)
74 {
75         u8      tx[3];
76
77         tx[0] = mcp->addr;
78         tx[1] = reg;
79         tx[2] = val;
80         return spi_write_then_read(mcp->spi, tx, sizeof tx, NULL, 0);
81 }
82
83 static int
84 mcp23s08_read_regs(struct mcp23s08 *mcp, unsigned reg, u8 *vals, unsigned n)
85 {
86         u8      tx[2];
87
88         if ((n + reg) > sizeof mcp->cache)
89                 return -EINVAL;
90         tx[0] = mcp->addr | 0x01;
91         tx[1] = reg;
92         return spi_write_then_read(mcp->spi, tx, sizeof tx, vals, n);
93 }
94
95 /*----------------------------------------------------------------------*/
96
97 static int mcp23s08_direction_input(struct gpio_chip *chip, unsigned offset)
98 {
99         struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip);
100         int status;
101
102         mutex_lock(&mcp->lock);
103         mcp->cache[MCP_IODIR] |= (1 << offset);
104         status = mcp23s08_write(mcp, MCP_IODIR, mcp->cache[MCP_IODIR]);
105         mutex_unlock(&mcp->lock);
106         return status;
107 }
108
109 static int mcp23s08_get(struct gpio_chip *chip, unsigned offset)
110 {
111         struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip);
112         int status;
113
114         mutex_lock(&mcp->lock);
115
116         /* REVISIT reading this clears any IRQ ... */
117         status = mcp23s08_read(mcp, MCP_GPIO);
118         if (status < 0)
119                 status = 0;
120         else {
121                 mcp->cache[MCP_GPIO] = status;
122                 status = !!(status & (1 << offset));
123         }
124         mutex_unlock(&mcp->lock);
125         return status;
126 }
127
128 static int __mcp23s08_set(struct mcp23s08 *mcp, unsigned mask, int value)
129 {
130         u8 olat = mcp->cache[MCP_OLAT];
131
132         if (value)
133                 olat |= mask;
134         else
135                 olat &= ~mask;
136         mcp->cache[MCP_OLAT] = olat;
137         return mcp23s08_write(mcp, MCP_OLAT, olat);
138 }
139
140 static void mcp23s08_set(struct gpio_chip *chip, unsigned offset, int value)
141 {
142         struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip);
143         u8 mask = 1 << offset;
144
145         mutex_lock(&mcp->lock);
146         __mcp23s08_set(mcp, mask, value);
147         mutex_unlock(&mcp->lock);
148 }
149
150 static int
151 mcp23s08_direction_output(struct gpio_chip *chip, unsigned offset, int value)
152 {
153         struct mcp23s08 *mcp = container_of(chip, struct mcp23s08, chip);
154         u8 mask = 1 << offset;
155         int status;
156
157         mutex_lock(&mcp->lock);
158         status = __mcp23s08_set(mcp, mask, value);
159         if (status == 0) {
160                 mcp->cache[MCP_IODIR] &= ~mask;
161                 status = mcp23s08_write(mcp, MCP_IODIR, mcp->cache[MCP_IODIR]);
162         }
163         mutex_unlock(&mcp->lock);
164         return status;
165 }
166
167 /*----------------------------------------------------------------------*/
168
169 #ifdef CONFIG_DEBUG_FS
170
171 #include <linux/seq_file.h>
172
173 /*
174  * This shows more info than the generic gpio dump code:
175  * pullups, deglitching, open drain drive.
176  */
177 static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip)
178 {
179         struct mcp23s08 *mcp;
180         char            bank;
181         int             t;
182         unsigned        mask;
183
184         mcp = container_of(chip, struct mcp23s08, chip);
185
186         /* NOTE: we only handle one bank for now ... */
187         bank = '0' + ((mcp->addr >> 1) & 0x3);
188
189         mutex_lock(&mcp->lock);
190         t = mcp23s08_read_regs(mcp, 0, mcp->cache, sizeof mcp->cache);
191         if (t < 0) {
192                 seq_printf(s, " I/O ERROR %d\n", t);
193                 goto done;
194         }
195
196         for (t = 0, mask = 1; t < 8; t++, mask <<= 1) {
197                 const char      *label;
198
199                 label = gpiochip_is_requested(chip, t);
200                 if (!label)
201                         continue;
202
203                 seq_printf(s, " gpio-%-3d P%c.%d (%-12s) %s %s %s",
204                         chip->base + t, bank, t, label,
205                         (mcp->cache[MCP_IODIR] & mask) ? "in " : "out",
206                         (mcp->cache[MCP_GPIO] & mask) ? "hi" : "lo",
207                         (mcp->cache[MCP_GPPU] & mask) ? "  " : "up");
208                 /* NOTE:  ignoring the irq-related registers */
209                 seq_printf(s, "\n");
210         }
211 done:
212         mutex_unlock(&mcp->lock);
213 }
214
215 #else
216 #define mcp23s08_dbg_show       NULL
217 #endif
218
219 /*----------------------------------------------------------------------*/
220
221 static int mcp23s08_probe_one(struct spi_device *spi, unsigned addr,
222                 unsigned base, unsigned pullups)
223 {
224         struct mcp23s08_driver_data     *data = spi_get_drvdata(spi);
225         struct mcp23s08                 *mcp = data->mcp[addr];
226         int                             status;
227         int                             do_update = 0;
228
229         mutex_init(&mcp->lock);
230
231         mcp->spi = spi;
232         mcp->addr = 0x40 | (addr << 1);
233
234         mcp->chip.label = "mcp23s08",
235
236         mcp->chip.direction_input = mcp23s08_direction_input;
237         mcp->chip.get = mcp23s08_get;
238         mcp->chip.direction_output = mcp23s08_direction_output;
239         mcp->chip.set = mcp23s08_set;
240         mcp->chip.dbg_show = mcp23s08_dbg_show;
241
242         mcp->chip.base = base;
243         mcp->chip.ngpio = 8;
244         mcp->chip.can_sleep = 1;
245         mcp->chip.dev = &spi->dev;
246         mcp->chip.owner = THIS_MODULE;
247
248         /* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
249          * and MCP_IOCON.HAEN = 1, so we work with all chips.
250          */
251         status = mcp23s08_read(mcp, MCP_IOCON);
252         if (status < 0)
253                 goto fail;
254         if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN)) {
255                 status &= ~IOCON_SEQOP;
256                 status |= IOCON_HAEN;
257                 status = mcp23s08_write(mcp, MCP_IOCON, (u8) status);
258                 if (status < 0)
259                         goto fail;
260         }
261
262         /* configure ~100K pullups */
263         status = mcp23s08_write(mcp, MCP_GPPU, pullups);
264         if (status < 0)
265                 goto fail;
266
267         status = mcp23s08_read_regs(mcp, 0, mcp->cache, sizeof mcp->cache);
268         if (status < 0)
269                 goto fail;
270
271         /* disable inverter on input */
272         if (mcp->cache[MCP_IPOL] != 0) {
273                 mcp->cache[MCP_IPOL] = 0;
274                 do_update = 1;
275         }
276
277         /* disable irqs */
278         if (mcp->cache[MCP_GPINTEN] != 0) {
279                 mcp->cache[MCP_GPINTEN] = 0;
280                 do_update = 1;
281         }
282
283         if (do_update) {
284                 u8 tx[4];
285
286                 tx[0] = mcp->addr;
287                 tx[1] = MCP_IPOL;
288                 memcpy(&tx[2], &mcp->cache[MCP_IPOL], sizeof(tx) - 2);
289                 status = spi_write_then_read(mcp->spi, tx, sizeof tx, NULL, 0);
290                 if (status < 0)
291                         goto fail;
292         }
293
294         status = gpiochip_add(&mcp->chip);
295 fail:
296         if (status < 0)
297                 dev_dbg(&spi->dev, "can't setup chip %d, --> %d\n",
298                                 addr, status);
299         return status;
300 }
301
302 static int mcp23s08_probe(struct spi_device *spi)
303 {
304         struct mcp23s08_platform_data   *pdata;
305         unsigned                        addr;
306         unsigned                        chips = 0;
307         struct mcp23s08_driver_data     *data;
308         int                             status;
309         unsigned                        base;
310
311         pdata = spi->dev.platform_data;
312         if (!pdata || !gpio_is_valid(pdata->base)) {
313                 dev_dbg(&spi->dev, "invalid or missing platform data\n");
314                 return -EINVAL;
315         }
316
317         for (addr = 0; addr < 4; addr++) {
318                 if (!pdata->chip[addr].is_present)
319                         continue;
320                 chips++;
321         }
322         if (!chips)
323                 return -ENODEV;
324
325         data = kzalloc(sizeof *data + chips * sizeof(struct mcp23s08),
326                         GFP_KERNEL);
327         if (!data)
328                 return -ENOMEM;
329         spi_set_drvdata(spi, data);
330
331         base = pdata->base;
332         for (addr = 0; addr < 4; addr++) {
333                 if (!pdata->chip[addr].is_present)
334                         continue;
335                 chips--;
336                 data->mcp[addr] = &data->chip[chips];
337                 status = mcp23s08_probe_one(spi, addr, base,
338                                 pdata->chip[addr].pullups);
339                 if (status < 0)
340                         goto fail;
341                 base += 8;
342         }
343         data->ngpio = base - pdata->base;
344
345         /* NOTE:  these chips have a relatively sane IRQ framework, with
346          * per-signal masking and level/edge triggering.  It's not yet
347          * handled here...
348          */
349
350         if (pdata->setup) {
351                 status = pdata->setup(spi,
352                                 pdata->base, data->ngpio,
353                                 pdata->context);
354                 if (status < 0)
355                         dev_dbg(&spi->dev, "setup --> %d\n", status);
356         }
357
358         return 0;
359
360 fail:
361         for (addr = 0; addr < 4; addr++) {
362                 int tmp;
363
364                 if (!data->mcp[addr])
365                         continue;
366                 tmp = gpiochip_remove(&data->mcp[addr]->chip);
367                 if (tmp < 0)
368                         dev_err(&spi->dev, "%s --> %d\n", "remove", tmp);
369         }
370         kfree(data);
371         return status;
372 }
373
374 static int mcp23s08_remove(struct spi_device *spi)
375 {
376         struct mcp23s08_driver_data     *data = spi_get_drvdata(spi);
377         struct mcp23s08_platform_data   *pdata = spi->dev.platform_data;
378         unsigned                        addr;
379         int                             status = 0;
380
381         if (pdata->teardown) {
382                 status = pdata->teardown(spi,
383                                 pdata->base, data->ngpio,
384                                 pdata->context);
385                 if (status < 0) {
386                         dev_err(&spi->dev, "%s --> %d\n", "teardown", status);
387                         return status;
388                 }
389         }
390
391         for (addr = 0; addr < 4; addr++) {
392                 int tmp;
393
394                 if (!data->mcp[addr])
395                         continue;
396
397                 tmp = gpiochip_remove(&data->mcp[addr]->chip);
398                 if (tmp < 0) {
399                         dev_err(&spi->dev, "%s --> %d\n", "remove", tmp);
400                         status = tmp;
401                 }
402         }
403         if (status == 0)
404                 kfree(data);
405         return status;
406 }
407
408 static struct spi_driver mcp23s08_driver = {
409         .probe          = mcp23s08_probe,
410         .remove         = mcp23s08_remove,
411         .driver = {
412                 .name   = "mcp23s08",
413                 .owner  = THIS_MODULE,
414         },
415 };
416
417 /*----------------------------------------------------------------------*/
418
419 static int __init mcp23s08_init(void)
420 {
421         return spi_register_driver(&mcp23s08_driver);
422 }
423 /* register after spi postcore initcall and before
424  * subsys initcalls that may rely on these GPIOs
425  */
426 subsys_initcall(mcp23s08_init);
427
428 static void __exit mcp23s08_exit(void)
429 {
430         spi_unregister_driver(&mcp23s08_driver);
431 }
432 module_exit(mcp23s08_exit);
433
434 MODULE_LICENSE("GPL");
435 MODULE_ALIAS("spi:mcp23s08");