2 * mcp23s08.c - SPI gpio expander driver
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 #include <asm/byteorder.h>
16 * MCP types supported by driver
18 #define MCP_TYPE_S08 0
19 #define MCP_TYPE_S17 1
21 /* Registers are all 8 bits wide.
23 * The mcp23s17 has twice as many bits, and can be configured to work
24 * with either 16 bit registers or with two adjacent 8 bit banks.
26 * Also, there are I2C versions of both chips.
28 #define MCP_IODIR 0x00 /* init/reset: all ones */
30 #define MCP_GPINTEN 0x02
31 #define MCP_DEFVAL 0x03
32 #define MCP_INTCON 0x04
33 #define MCP_IOCON 0x05
34 # define IOCON_SEQOP (1 << 5)
35 # define IOCON_HAEN (1 << 3)
36 # define IOCON_ODR (1 << 2)
37 # define IOCON_INTPOL (1 << 1)
40 #define MCP_INTCAP 0x08
47 int (*read
)(struct mcp23s08
*mcp
, unsigned reg
);
48 int (*write
)(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
);
49 int (*read_regs
)(struct mcp23s08
*mcp
, unsigned reg
,
50 u16
*vals
, unsigned n
);
54 struct spi_device
*spi
;
58 /* lock protects the cached values */
61 struct gpio_chip chip
;
63 struct work_struct work
;
65 const struct mcp23s08_ops
*ops
;
68 /* A given spi_device can represent up to eight mcp23sxx chips
69 * sharing the same chipselect but using different addresses
70 * (e.g. chips #0 and #3 might be populated, but not #1 or $2).
71 * Driver data holds all the per-chip data.
73 struct mcp23s08_driver_data
{
75 struct mcp23s08
*mcp
[8];
76 struct mcp23s08 chip
[];
79 static int mcp23s08_read(struct mcp23s08
*mcp
, unsigned reg
)
84 tx
[0] = mcp
->addr
| 0x01;
86 status
= spi_write_then_read(mcp
->spi
, tx
, sizeof tx
, rx
, sizeof rx
);
87 return (status
< 0) ? status
: rx
[0];
90 static int mcp23s08_write(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
)
97 return spi_write_then_read(mcp
->spi
, tx
, sizeof tx
, NULL
, 0);
101 mcp23s08_read_regs(struct mcp23s08
*mcp
, unsigned reg
, u16
*vals
, unsigned n
)
106 if ((n
+ reg
) > sizeof mcp
->cache
)
108 tx
[0] = mcp
->addr
| 0x01;
112 status
= spi_write_then_read(mcp
->spi
, tx
, sizeof tx
, tmp
, n
);
115 vals
[n
] = tmp
[n
]; /* expand to 16bit */
120 static int mcp23s17_read(struct mcp23s08
*mcp
, unsigned reg
)
125 tx
[0] = mcp
->addr
| 0x01;
127 status
= spi_write_then_read(mcp
->spi
, tx
, sizeof tx
, rx
, sizeof rx
);
128 return (status
< 0) ? status
: (rx
[0] | (rx
[1] << 8));
131 static int mcp23s17_write(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
)
139 return spi_write_then_read(mcp
->spi
, tx
, sizeof tx
, NULL
, 0);
143 mcp23s17_read_regs(struct mcp23s08
*mcp
, unsigned reg
, u16
*vals
, unsigned n
)
148 if ((n
+ reg
) > sizeof mcp
->cache
)
150 tx
[0] = mcp
->addr
| 0x01;
153 status
= spi_write_then_read(mcp
->spi
, tx
, sizeof tx
,
157 vals
[n
] = __le16_to_cpu((__le16
)vals
[n
]);
163 static const struct mcp23s08_ops mcp23s08_ops
= {
164 .read
= mcp23s08_read
,
165 .write
= mcp23s08_write
,
166 .read_regs
= mcp23s08_read_regs
,
169 static const struct mcp23s08_ops mcp23s17_ops
= {
170 .read
= mcp23s17_read
,
171 .write
= mcp23s17_write
,
172 .read_regs
= mcp23s17_read_regs
,
176 /*----------------------------------------------------------------------*/
178 static int mcp23s08_direction_input(struct gpio_chip
*chip
, unsigned offset
)
180 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
183 mutex_lock(&mcp
->lock
);
184 mcp
->cache
[MCP_IODIR
] |= (1 << offset
);
185 status
= mcp
->ops
->write(mcp
, MCP_IODIR
, mcp
->cache
[MCP_IODIR
]);
186 mutex_unlock(&mcp
->lock
);
190 static int mcp23s08_get(struct gpio_chip
*chip
, unsigned offset
)
192 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
195 mutex_lock(&mcp
->lock
);
197 /* REVISIT reading this clears any IRQ ... */
198 status
= mcp
->ops
->read(mcp
, MCP_GPIO
);
202 mcp
->cache
[MCP_GPIO
] = status
;
203 status
= !!(status
& (1 << offset
));
205 mutex_unlock(&mcp
->lock
);
209 static int __mcp23s08_set(struct mcp23s08
*mcp
, unsigned mask
, int value
)
211 unsigned olat
= mcp
->cache
[MCP_OLAT
];
217 mcp
->cache
[MCP_OLAT
] = olat
;
218 return mcp
->ops
->write(mcp
, MCP_OLAT
, olat
);
221 static void mcp23s08_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
223 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
224 unsigned mask
= 1 << offset
;
226 mutex_lock(&mcp
->lock
);
227 __mcp23s08_set(mcp
, mask
, value
);
228 mutex_unlock(&mcp
->lock
);
232 mcp23s08_direction_output(struct gpio_chip
*chip
, unsigned offset
, int value
)
234 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
235 unsigned mask
= 1 << offset
;
238 mutex_lock(&mcp
->lock
);
239 status
= __mcp23s08_set(mcp
, mask
, value
);
241 mcp
->cache
[MCP_IODIR
] &= ~mask
;
242 status
= mcp
->ops
->write(mcp
, MCP_IODIR
, mcp
->cache
[MCP_IODIR
]);
244 mutex_unlock(&mcp
->lock
);
248 /*----------------------------------------------------------------------*/
250 #ifdef CONFIG_DEBUG_FS
252 #include <linux/seq_file.h>
255 * This shows more info than the generic gpio dump code:
256 * pullups, deglitching, open drain drive.
258 static void mcp23s08_dbg_show(struct seq_file
*s
, struct gpio_chip
*chip
)
260 struct mcp23s08
*mcp
;
265 mcp
= container_of(chip
, struct mcp23s08
, chip
);
267 /* NOTE: we only handle one bank for now ... */
268 bank
= '0' + ((mcp
->addr
>> 1) & 0x7);
270 mutex_lock(&mcp
->lock
);
271 t
= mcp
->ops
->read_regs(mcp
, 0, mcp
->cache
, ARRAY_SIZE(mcp
->cache
));
273 seq_printf(s
, " I/O ERROR %d\n", t
);
277 for (t
= 0, mask
= 1; t
< chip
->ngpio
; t
++, mask
<<= 1) {
280 label
= gpiochip_is_requested(chip
, t
);
284 seq_printf(s
, " gpio-%-3d P%c.%d (%-12s) %s %s %s",
285 chip
->base
+ t
, bank
, t
, label
,
286 (mcp
->cache
[MCP_IODIR
] & mask
) ? "in " : "out",
287 (mcp
->cache
[MCP_GPIO
] & mask
) ? "hi" : "lo",
288 (mcp
->cache
[MCP_GPPU
] & mask
) ? " " : "up");
289 /* NOTE: ignoring the irq-related registers */
293 mutex_unlock(&mcp
->lock
);
297 #define mcp23s08_dbg_show NULL
300 /*----------------------------------------------------------------------*/
302 static int mcp23s08_probe_one(struct spi_device
*spi
, unsigned addr
,
303 unsigned type
, unsigned base
, unsigned pullups
)
305 struct mcp23s08_driver_data
*data
= spi_get_drvdata(spi
);
306 struct mcp23s08
*mcp
= data
->mcp
[addr
];
309 mutex_init(&mcp
->lock
);
312 mcp
->addr
= 0x40 | (addr
<< 1);
314 mcp
->chip
.direction_input
= mcp23s08_direction_input
;
315 mcp
->chip
.get
= mcp23s08_get
;
316 mcp
->chip
.direction_output
= mcp23s08_direction_output
;
317 mcp
->chip
.set
= mcp23s08_set
;
318 mcp
->chip
.dbg_show
= mcp23s08_dbg_show
;
320 if (type
== MCP_TYPE_S17
) {
321 mcp
->ops
= &mcp23s17_ops
;
322 mcp
->chip
.ngpio
= 16;
323 mcp
->chip
.label
= "mcp23s17";
325 mcp
->ops
= &mcp23s08_ops
;
327 mcp
->chip
.label
= "mcp23s08";
329 mcp
->chip
.base
= base
;
330 mcp
->chip
.can_sleep
= 1;
331 mcp
->chip
.dev
= &spi
->dev
;
332 mcp
->chip
.owner
= THIS_MODULE
;
334 /* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
335 * and MCP_IOCON.HAEN = 1, so we work with all chips.
337 status
= mcp
->ops
->read(mcp
, MCP_IOCON
);
340 if ((status
& IOCON_SEQOP
) || !(status
& IOCON_HAEN
)) {
341 /* mcp23s17 has IOCON twice, make sure they are in sync */
342 status
&= ~(IOCON_SEQOP
| (IOCON_SEQOP
<< 8));
343 status
|= IOCON_HAEN
| (IOCON_HAEN
<< 8);
344 status
= mcp
->ops
->write(mcp
, MCP_IOCON
, status
);
349 /* configure ~100K pullups */
350 status
= mcp
->ops
->write(mcp
, MCP_GPPU
, pullups
);
354 status
= mcp
->ops
->read_regs(mcp
, 0, mcp
->cache
, ARRAY_SIZE(mcp
->cache
));
358 /* disable inverter on input */
359 if (mcp
->cache
[MCP_IPOL
] != 0) {
360 mcp
->cache
[MCP_IPOL
] = 0;
361 status
= mcp
->ops
->write(mcp
, MCP_IPOL
, 0);
367 if (mcp
->cache
[MCP_GPINTEN
] != 0) {
368 mcp
->cache
[MCP_GPINTEN
] = 0;
369 status
= mcp
->ops
->write(mcp
, MCP_GPINTEN
, 0);
374 status
= gpiochip_add(&mcp
->chip
);
377 dev_dbg(&spi
->dev
, "can't setup chip %d, --> %d\n",
382 static int mcp23s08_probe(struct spi_device
*spi
)
384 struct mcp23s08_platform_data
*pdata
;
387 struct mcp23s08_driver_data
*data
;
391 type
= spi_get_device_id(spi
)->driver_data
;
393 pdata
= spi
->dev
.platform_data
;
394 if (!pdata
|| !gpio_is_valid(pdata
->base
)) {
395 dev_dbg(&spi
->dev
, "invalid or missing platform data\n");
399 for (addr
= 0; addr
< ARRAY_SIZE(pdata
->chip
); addr
++) {
400 if (!pdata
->chip
[addr
].is_present
)
403 if ((type
== MCP_TYPE_S08
) && (addr
> 3)) {
405 "mcp23s08 only supports address 0..3\n");
412 data
= kzalloc(sizeof *data
+ chips
* sizeof(struct mcp23s08
),
416 spi_set_drvdata(spi
, data
);
419 for (addr
= 0; addr
< ARRAY_SIZE(pdata
->chip
); addr
++) {
420 if (!pdata
->chip
[addr
].is_present
)
423 data
->mcp
[addr
] = &data
->chip
[chips
];
424 status
= mcp23s08_probe_one(spi
, addr
, type
, base
,
425 pdata
->chip
[addr
].pullups
);
429 base
+= (type
== MCP_TYPE_S17
) ? 16 : 8;
431 data
->ngpio
= base
- pdata
->base
;
433 /* NOTE: these chips have a relatively sane IRQ framework, with
434 * per-signal masking and level/edge triggering. It's not yet
439 status
= pdata
->setup(spi
,
440 pdata
->base
, data
->ngpio
,
443 dev_dbg(&spi
->dev
, "setup --> %d\n", status
);
449 for (addr
= 0; addr
< ARRAY_SIZE(data
->mcp
); addr
++) {
452 if (!data
->mcp
[addr
])
454 tmp
= gpiochip_remove(&data
->mcp
[addr
]->chip
);
456 dev_err(&spi
->dev
, "%s --> %d\n", "remove", tmp
);
462 static int mcp23s08_remove(struct spi_device
*spi
)
464 struct mcp23s08_driver_data
*data
= spi_get_drvdata(spi
);
465 struct mcp23s08_platform_data
*pdata
= spi
->dev
.platform_data
;
469 if (pdata
->teardown
) {
470 status
= pdata
->teardown(spi
,
471 pdata
->base
, data
->ngpio
,
474 dev_err(&spi
->dev
, "%s --> %d\n", "teardown", status
);
479 for (addr
= 0; addr
< ARRAY_SIZE(data
->mcp
); addr
++) {
482 if (!data
->mcp
[addr
])
485 tmp
= gpiochip_remove(&data
->mcp
[addr
]->chip
);
487 dev_err(&spi
->dev
, "%s --> %d\n", "remove", tmp
);
496 static const struct spi_device_id mcp23s08_ids
[] = {
497 { "mcp23s08", MCP_TYPE_S08
},
498 { "mcp23s17", MCP_TYPE_S17
},
501 MODULE_DEVICE_TABLE(spi
, mcp23s08_ids
);
503 static struct spi_driver mcp23s08_driver
= {
504 .probe
= mcp23s08_probe
,
505 .remove
= mcp23s08_remove
,
506 .id_table
= mcp23s08_ids
,
509 .owner
= THIS_MODULE
,
513 /*----------------------------------------------------------------------*/
515 static int __init
mcp23s08_init(void)
517 return spi_register_driver(&mcp23s08_driver
);
519 /* register after spi postcore initcall and before
520 * subsys initcalls that may rely on these GPIOs
522 subsys_initcall(mcp23s08_init
);
524 static void __exit
mcp23s08_exit(void)
526 spi_unregister_driver(&mcp23s08_driver
);
528 module_exit(mcp23s08_exit
);
530 MODULE_LICENSE("GPL");