2 * MCP23S08 SPI/GPIO gpio expander driver
5 #include <linux/kernel.h>
6 #include <linux/device.h>
7 #include <linux/mutex.h>
8 #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
20 #define MCP_TYPE_008 2
21 #define MCP_TYPE_017 3
23 /* Registers are all 8 bits wide.
25 * The mcp23s17 has twice as many bits, and can be configured to work
26 * with either 16 bit registers or with two adjacent 8 bit banks.
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
);
57 /* lock protects the cached values */
60 struct gpio_chip chip
;
62 const struct mcp23s08_ops
*ops
;
63 void *data
; /* ops specific data */
66 /* A given spi_device can represent up to eight mcp23sxx chips
67 * sharing the same chipselect but using different addresses
68 * (e.g. chips #0 and #3 might be populated, but not #1 or $2).
69 * Driver data holds all the per-chip data.
71 struct mcp23s08_driver_data
{
73 struct mcp23s08
*mcp
[8];
74 struct mcp23s08 chip
[];
77 /*----------------------------------------------------------------------*/
81 static int mcp23008_read(struct mcp23s08
*mcp
, unsigned reg
)
83 return i2c_smbus_read_byte_data(mcp
->data
, reg
);
86 static int mcp23008_write(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
)
88 return i2c_smbus_write_byte_data(mcp
->data
, reg
, val
);
92 mcp23008_read_regs(struct mcp23s08
*mcp
, unsigned reg
, u16
*vals
, unsigned n
)
95 int ret
= mcp23008_read(mcp
, reg
++);
104 static int mcp23017_read(struct mcp23s08
*mcp
, unsigned reg
)
106 return i2c_smbus_read_word_data(mcp
->data
, reg
<< 1);
109 static int mcp23017_write(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
)
111 return i2c_smbus_write_word_data(mcp
->data
, reg
<< 1, val
);
115 mcp23017_read_regs(struct mcp23s08
*mcp
, unsigned reg
, u16
*vals
, unsigned n
)
118 int ret
= mcp23017_read(mcp
, reg
++);
127 static const struct mcp23s08_ops mcp23008_ops
= {
128 .read
= mcp23008_read
,
129 .write
= mcp23008_write
,
130 .read_regs
= mcp23008_read_regs
,
133 static const struct mcp23s08_ops mcp23017_ops
= {
134 .read
= mcp23017_read
,
135 .write
= mcp23017_write
,
136 .read_regs
= mcp23017_read_regs
,
139 #endif /* CONFIG_I2C */
141 /*----------------------------------------------------------------------*/
143 #ifdef CONFIG_SPI_MASTER
145 static int mcp23s08_read(struct mcp23s08
*mcp
, unsigned reg
)
150 tx
[0] = mcp
->addr
| 0x01;
152 status
= spi_write_then_read(mcp
->data
, tx
, sizeof tx
, rx
, sizeof rx
);
153 return (status
< 0) ? status
: rx
[0];
156 static int mcp23s08_write(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
)
163 return spi_write_then_read(mcp
->data
, tx
, sizeof tx
, NULL
, 0);
167 mcp23s08_read_regs(struct mcp23s08
*mcp
, unsigned reg
, u16
*vals
, unsigned n
)
172 if ((n
+ reg
) > sizeof mcp
->cache
)
174 tx
[0] = mcp
->addr
| 0x01;
178 status
= spi_write_then_read(mcp
->data
, tx
, sizeof tx
, tmp
, n
);
181 vals
[n
] = tmp
[n
]; /* expand to 16bit */
186 static int mcp23s17_read(struct mcp23s08
*mcp
, unsigned reg
)
191 tx
[0] = mcp
->addr
| 0x01;
193 status
= spi_write_then_read(mcp
->data
, tx
, sizeof tx
, rx
, sizeof rx
);
194 return (status
< 0) ? status
: (rx
[0] | (rx
[1] << 8));
197 static int mcp23s17_write(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
)
205 return spi_write_then_read(mcp
->data
, tx
, sizeof tx
, NULL
, 0);
209 mcp23s17_read_regs(struct mcp23s08
*mcp
, unsigned reg
, u16
*vals
, unsigned n
)
214 if ((n
+ reg
) > sizeof mcp
->cache
)
216 tx
[0] = mcp
->addr
| 0x01;
219 status
= spi_write_then_read(mcp
->data
, tx
, sizeof tx
,
223 vals
[n
] = __le16_to_cpu((__le16
)vals
[n
]);
229 static const struct mcp23s08_ops mcp23s08_ops
= {
230 .read
= mcp23s08_read
,
231 .write
= mcp23s08_write
,
232 .read_regs
= mcp23s08_read_regs
,
235 static const struct mcp23s08_ops mcp23s17_ops
= {
236 .read
= mcp23s17_read
,
237 .write
= mcp23s17_write
,
238 .read_regs
= mcp23s17_read_regs
,
241 #endif /* CONFIG_SPI_MASTER */
243 /*----------------------------------------------------------------------*/
245 static int mcp23s08_direction_input(struct gpio_chip
*chip
, unsigned offset
)
247 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
250 mutex_lock(&mcp
->lock
);
251 mcp
->cache
[MCP_IODIR
] |= (1 << offset
);
252 status
= mcp
->ops
->write(mcp
, MCP_IODIR
, mcp
->cache
[MCP_IODIR
]);
253 mutex_unlock(&mcp
->lock
);
257 static int mcp23s08_get(struct gpio_chip
*chip
, unsigned offset
)
259 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
262 mutex_lock(&mcp
->lock
);
264 /* REVISIT reading this clears any IRQ ... */
265 status
= mcp
->ops
->read(mcp
, MCP_GPIO
);
269 mcp
->cache
[MCP_GPIO
] = status
;
270 status
= !!(status
& (1 << offset
));
272 mutex_unlock(&mcp
->lock
);
276 static int __mcp23s08_set(struct mcp23s08
*mcp
, unsigned mask
, int value
)
278 unsigned olat
= mcp
->cache
[MCP_OLAT
];
284 mcp
->cache
[MCP_OLAT
] = olat
;
285 return mcp
->ops
->write(mcp
, MCP_OLAT
, olat
);
288 static void mcp23s08_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
290 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
291 unsigned mask
= 1 << offset
;
293 mutex_lock(&mcp
->lock
);
294 __mcp23s08_set(mcp
, mask
, value
);
295 mutex_unlock(&mcp
->lock
);
299 mcp23s08_direction_output(struct gpio_chip
*chip
, unsigned offset
, int value
)
301 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
302 unsigned mask
= 1 << offset
;
305 mutex_lock(&mcp
->lock
);
306 status
= __mcp23s08_set(mcp
, mask
, value
);
308 mcp
->cache
[MCP_IODIR
] &= ~mask
;
309 status
= mcp
->ops
->write(mcp
, MCP_IODIR
, mcp
->cache
[MCP_IODIR
]);
311 mutex_unlock(&mcp
->lock
);
315 /*----------------------------------------------------------------------*/
317 #ifdef CONFIG_DEBUG_FS
319 #include <linux/seq_file.h>
322 * This shows more info than the generic gpio dump code:
323 * pullups, deglitching, open drain drive.
325 static void mcp23s08_dbg_show(struct seq_file
*s
, struct gpio_chip
*chip
)
327 struct mcp23s08
*mcp
;
332 mcp
= container_of(chip
, struct mcp23s08
, chip
);
334 /* NOTE: we only handle one bank for now ... */
335 bank
= '0' + ((mcp
->addr
>> 1) & 0x7);
337 mutex_lock(&mcp
->lock
);
338 t
= mcp
->ops
->read_regs(mcp
, 0, mcp
->cache
, ARRAY_SIZE(mcp
->cache
));
340 seq_printf(s
, " I/O ERROR %d\n", t
);
344 for (t
= 0, mask
= 1; t
< chip
->ngpio
; t
++, mask
<<= 1) {
347 label
= gpiochip_is_requested(chip
, t
);
351 seq_printf(s
, " gpio-%-3d P%c.%d (%-12s) %s %s %s",
352 chip
->base
+ t
, bank
, t
, label
,
353 (mcp
->cache
[MCP_IODIR
] & mask
) ? "in " : "out",
354 (mcp
->cache
[MCP_GPIO
] & mask
) ? "hi" : "lo",
355 (mcp
->cache
[MCP_GPPU
] & mask
) ? " " : "up");
356 /* NOTE: ignoring the irq-related registers */
360 mutex_unlock(&mcp
->lock
);
364 #define mcp23s08_dbg_show NULL
367 /*----------------------------------------------------------------------*/
369 static int mcp23s08_probe_one(struct mcp23s08
*mcp
, struct device
*dev
,
370 void *data
, unsigned addr
,
371 unsigned type
, unsigned base
, unsigned pullups
)
375 mutex_init(&mcp
->lock
);
380 mcp
->chip
.direction_input
= mcp23s08_direction_input
;
381 mcp
->chip
.get
= mcp23s08_get
;
382 mcp
->chip
.direction_output
= mcp23s08_direction_output
;
383 mcp
->chip
.set
= mcp23s08_set
;
384 mcp
->chip
.dbg_show
= mcp23s08_dbg_show
;
387 #ifdef CONFIG_SPI_MASTER
389 mcp
->ops
= &mcp23s08_ops
;
391 mcp
->chip
.label
= "mcp23s08";
395 mcp
->ops
= &mcp23s17_ops
;
396 mcp
->chip
.ngpio
= 16;
397 mcp
->chip
.label
= "mcp23s17";
399 #endif /* CONFIG_SPI_MASTER */
403 mcp
->ops
= &mcp23008_ops
;
405 mcp
->chip
.label
= "mcp23008";
409 mcp
->ops
= &mcp23017_ops
;
410 mcp
->chip
.ngpio
= 16;
411 mcp
->chip
.label
= "mcp23017";
413 #endif /* CONFIG_I2C */
416 dev_err(dev
, "invalid device type (%d)\n", type
);
420 mcp
->chip
.base
= base
;
421 mcp
->chip
.can_sleep
= 1;
423 mcp
->chip
.owner
= THIS_MODULE
;
425 /* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
426 * and MCP_IOCON.HAEN = 1, so we work with all chips.
428 status
= mcp
->ops
->read(mcp
, MCP_IOCON
);
431 if ((status
& IOCON_SEQOP
) || !(status
& IOCON_HAEN
)) {
432 /* mcp23s17 has IOCON twice, make sure they are in sync */
433 status
&= ~(IOCON_SEQOP
| (IOCON_SEQOP
<< 8));
434 status
|= IOCON_HAEN
| (IOCON_HAEN
<< 8);
435 status
= mcp
->ops
->write(mcp
, MCP_IOCON
, status
);
440 /* configure ~100K pullups */
441 status
= mcp
->ops
->write(mcp
, MCP_GPPU
, pullups
);
445 status
= mcp
->ops
->read_regs(mcp
, 0, mcp
->cache
, ARRAY_SIZE(mcp
->cache
));
449 /* disable inverter on input */
450 if (mcp
->cache
[MCP_IPOL
] != 0) {
451 mcp
->cache
[MCP_IPOL
] = 0;
452 status
= mcp
->ops
->write(mcp
, MCP_IPOL
, 0);
458 if (mcp
->cache
[MCP_GPINTEN
] != 0) {
459 mcp
->cache
[MCP_GPINTEN
] = 0;
460 status
= mcp
->ops
->write(mcp
, MCP_GPINTEN
, 0);
465 status
= gpiochip_add(&mcp
->chip
);
468 dev_dbg(dev
, "can't setup chip %d, --> %d\n",
473 /*----------------------------------------------------------------------*/
477 static int __devinit
mcp230xx_probe(struct i2c_client
*client
,
478 const struct i2c_device_id
*id
)
480 struct mcp23s08_platform_data
*pdata
;
481 struct mcp23s08
*mcp
;
484 pdata
= client
->dev
.platform_data
;
485 if (!pdata
|| !gpio_is_valid(pdata
->base
)) {
486 dev_dbg(&client
->dev
, "invalid or missing platform data\n");
490 mcp
= kzalloc(sizeof *mcp
, GFP_KERNEL
);
494 status
= mcp23s08_probe_one(mcp
, &client
->dev
, client
, client
->addr
,
495 id
->driver_data
, pdata
->base
,
496 pdata
->chip
[0].pullups
);
500 i2c_set_clientdata(client
, mcp
);
510 static int __devexit
mcp230xx_remove(struct i2c_client
*client
)
512 struct mcp23s08
*mcp
= i2c_get_clientdata(client
);
515 status
= gpiochip_remove(&mcp
->chip
);
522 static const struct i2c_device_id mcp230xx_id
[] = {
523 { "mcp23008", MCP_TYPE_008
},
524 { "mcp23017", MCP_TYPE_017
},
527 MODULE_DEVICE_TABLE(i2c
, mcp230xx_id
);
529 static struct i2c_driver mcp230xx_driver
= {
532 .owner
= THIS_MODULE
,
534 .probe
= mcp230xx_probe
,
535 .remove
= __devexit_p(mcp230xx_remove
),
536 .id_table
= mcp230xx_id
,
539 static int __init
mcp23s08_i2c_init(void)
541 return i2c_add_driver(&mcp230xx_driver
);
544 static void mcp23s08_i2c_exit(void)
546 i2c_del_driver(&mcp230xx_driver
);
551 static int __init
mcp23s08_i2c_init(void) { return 0; }
552 static void mcp23s08_i2c_exit(void) { }
554 #endif /* CONFIG_I2C */
556 /*----------------------------------------------------------------------*/
558 #ifdef CONFIG_SPI_MASTER
560 static int mcp23s08_probe(struct spi_device
*spi
)
562 struct mcp23s08_platform_data
*pdata
;
565 struct mcp23s08_driver_data
*data
;
569 type
= spi_get_device_id(spi
)->driver_data
;
571 pdata
= spi
->dev
.platform_data
;
572 if (!pdata
|| !gpio_is_valid(pdata
->base
)) {
573 dev_dbg(&spi
->dev
, "invalid or missing platform data\n");
577 for (addr
= 0; addr
< ARRAY_SIZE(pdata
->chip
); addr
++) {
578 if (!pdata
->chip
[addr
].is_present
)
581 if ((type
== MCP_TYPE_S08
) && (addr
> 3)) {
583 "mcp23s08 only supports address 0..3\n");
590 data
= kzalloc(sizeof *data
+ chips
* sizeof(struct mcp23s08
),
594 spi_set_drvdata(spi
, data
);
597 for (addr
= 0; addr
< ARRAY_SIZE(pdata
->chip
); addr
++) {
598 if (!pdata
->chip
[addr
].is_present
)
601 data
->mcp
[addr
] = &data
->chip
[chips
];
602 status
= mcp23s08_probe_one(data
->mcp
[addr
], &spi
->dev
, spi
,
603 0x40 | (addr
<< 1), type
, base
,
604 pdata
->chip
[addr
].pullups
);
608 base
+= (type
== MCP_TYPE_S17
) ? 16 : 8;
610 data
->ngpio
= base
- pdata
->base
;
612 /* NOTE: these chips have a relatively sane IRQ framework, with
613 * per-signal masking and level/edge triggering. It's not yet
620 for (addr
= 0; addr
< ARRAY_SIZE(data
->mcp
); addr
++) {
623 if (!data
->mcp
[addr
])
625 tmp
= gpiochip_remove(&data
->mcp
[addr
]->chip
);
627 dev_err(&spi
->dev
, "%s --> %d\n", "remove", tmp
);
633 static int mcp23s08_remove(struct spi_device
*spi
)
635 struct mcp23s08_driver_data
*data
= spi_get_drvdata(spi
);
639 for (addr
= 0; addr
< ARRAY_SIZE(data
->mcp
); addr
++) {
642 if (!data
->mcp
[addr
])
645 tmp
= gpiochip_remove(&data
->mcp
[addr
]->chip
);
647 dev_err(&spi
->dev
, "%s --> %d\n", "remove", tmp
);
656 static const struct spi_device_id mcp23s08_ids
[] = {
657 { "mcp23s08", MCP_TYPE_S08
},
658 { "mcp23s17", MCP_TYPE_S17
},
661 MODULE_DEVICE_TABLE(spi
, mcp23s08_ids
);
663 static struct spi_driver mcp23s08_driver
= {
664 .probe
= mcp23s08_probe
,
665 .remove
= mcp23s08_remove
,
666 .id_table
= mcp23s08_ids
,
669 .owner
= THIS_MODULE
,
673 static int __init
mcp23s08_spi_init(void)
675 return spi_register_driver(&mcp23s08_driver
);
678 static void mcp23s08_spi_exit(void)
680 spi_unregister_driver(&mcp23s08_driver
);
685 static int __init
mcp23s08_spi_init(void) { return 0; }
686 static void mcp23s08_spi_exit(void) { }
688 #endif /* CONFIG_SPI_MASTER */
690 /*----------------------------------------------------------------------*/
692 static int __init
mcp23s08_init(void)
696 ret
= mcp23s08_spi_init();
700 ret
= mcp23s08_i2c_init();
711 /* register after spi/i2c postcore initcall and before
712 * subsys initcalls that may rely on these GPIOs
714 subsys_initcall(mcp23s08_init
);
716 static void __exit
mcp23s08_exit(void)
721 module_exit(mcp23s08_exit
);
723 MODULE_LICENSE("GPL");