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/module.h>
9 #include <linux/gpio.h>
10 #include <linux/i2c.h>
11 #include <linux/spi/spi.h>
12 #include <linux/spi/mcp23s08.h>
13 #include <linux/slab.h>
14 #include <asm/byteorder.h>
17 * MCP types supported by driver
19 #define MCP_TYPE_S08 0
20 #define MCP_TYPE_S17 1
21 #define MCP_TYPE_008 2
22 #define MCP_TYPE_017 3
24 /* Registers are all 8 bits wide.
26 * The mcp23s17 has twice as many bits, and can be configured to work
27 * with either 16 bit registers or with two adjacent 8 bit banks.
29 #define MCP_IODIR 0x00 /* init/reset: all ones */
31 #define MCP_GPINTEN 0x02
32 #define MCP_DEFVAL 0x03
33 #define MCP_INTCON 0x04
34 #define MCP_IOCON 0x05
35 # define IOCON_SEQOP (1 << 5)
36 # define IOCON_HAEN (1 << 3)
37 # define IOCON_ODR (1 << 2)
38 # define IOCON_INTPOL (1 << 1)
41 #define MCP_INTCAP 0x08
48 int (*read
)(struct mcp23s08
*mcp
, unsigned reg
);
49 int (*write
)(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
);
50 int (*read_regs
)(struct mcp23s08
*mcp
, unsigned reg
,
51 u16
*vals
, unsigned n
);
58 /* lock protects the cached values */
61 struct gpio_chip chip
;
63 const struct mcp23s08_ops
*ops
;
64 void *data
; /* ops specific data */
67 /* A given spi_device can represent up to eight mcp23sxx chips
68 * sharing the same chipselect but using different addresses
69 * (e.g. chips #0 and #3 might be populated, but not #1 or $2).
70 * Driver data holds all the per-chip data.
72 struct mcp23s08_driver_data
{
74 struct mcp23s08
*mcp
[8];
75 struct mcp23s08 chip
[];
78 /*----------------------------------------------------------------------*/
82 static int mcp23008_read(struct mcp23s08
*mcp
, unsigned reg
)
84 return i2c_smbus_read_byte_data(mcp
->data
, reg
);
87 static int mcp23008_write(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
)
89 return i2c_smbus_write_byte_data(mcp
->data
, reg
, val
);
93 mcp23008_read_regs(struct mcp23s08
*mcp
, unsigned reg
, u16
*vals
, unsigned n
)
96 int ret
= mcp23008_read(mcp
, reg
++);
105 static int mcp23017_read(struct mcp23s08
*mcp
, unsigned reg
)
107 return i2c_smbus_read_word_data(mcp
->data
, reg
<< 1);
110 static int mcp23017_write(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
)
112 return i2c_smbus_write_word_data(mcp
->data
, reg
<< 1, val
);
116 mcp23017_read_regs(struct mcp23s08
*mcp
, unsigned reg
, u16
*vals
, unsigned n
)
119 int ret
= mcp23017_read(mcp
, reg
++);
128 static const struct mcp23s08_ops mcp23008_ops
= {
129 .read
= mcp23008_read
,
130 .write
= mcp23008_write
,
131 .read_regs
= mcp23008_read_regs
,
134 static const struct mcp23s08_ops mcp23017_ops
= {
135 .read
= mcp23017_read
,
136 .write
= mcp23017_write
,
137 .read_regs
= mcp23017_read_regs
,
140 #endif /* CONFIG_I2C */
142 /*----------------------------------------------------------------------*/
144 #ifdef CONFIG_SPI_MASTER
146 static int mcp23s08_read(struct mcp23s08
*mcp
, unsigned reg
)
151 tx
[0] = mcp
->addr
| 0x01;
153 status
= spi_write_then_read(mcp
->data
, tx
, sizeof tx
, rx
, sizeof rx
);
154 return (status
< 0) ? status
: rx
[0];
157 static int mcp23s08_write(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
)
164 return spi_write_then_read(mcp
->data
, tx
, sizeof tx
, NULL
, 0);
168 mcp23s08_read_regs(struct mcp23s08
*mcp
, unsigned reg
, u16
*vals
, unsigned n
)
173 if ((n
+ reg
) > sizeof mcp
->cache
)
175 tx
[0] = mcp
->addr
| 0x01;
179 status
= spi_write_then_read(mcp
->data
, tx
, sizeof tx
, tmp
, n
);
182 vals
[n
] = tmp
[n
]; /* expand to 16bit */
187 static int mcp23s17_read(struct mcp23s08
*mcp
, unsigned reg
)
192 tx
[0] = mcp
->addr
| 0x01;
194 status
= spi_write_then_read(mcp
->data
, tx
, sizeof tx
, rx
, sizeof rx
);
195 return (status
< 0) ? status
: (rx
[0] | (rx
[1] << 8));
198 static int mcp23s17_write(struct mcp23s08
*mcp
, unsigned reg
, unsigned val
)
206 return spi_write_then_read(mcp
->data
, tx
, sizeof tx
, NULL
, 0);
210 mcp23s17_read_regs(struct mcp23s08
*mcp
, unsigned reg
, u16
*vals
, unsigned n
)
215 if ((n
+ reg
) > sizeof mcp
->cache
)
217 tx
[0] = mcp
->addr
| 0x01;
220 status
= spi_write_then_read(mcp
->data
, tx
, sizeof tx
,
224 vals
[n
] = __le16_to_cpu((__le16
)vals
[n
]);
230 static const struct mcp23s08_ops mcp23s08_ops
= {
231 .read
= mcp23s08_read
,
232 .write
= mcp23s08_write
,
233 .read_regs
= mcp23s08_read_regs
,
236 static const struct mcp23s08_ops mcp23s17_ops
= {
237 .read
= mcp23s17_read
,
238 .write
= mcp23s17_write
,
239 .read_regs
= mcp23s17_read_regs
,
242 #endif /* CONFIG_SPI_MASTER */
244 /*----------------------------------------------------------------------*/
246 static int mcp23s08_direction_input(struct gpio_chip
*chip
, unsigned offset
)
248 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
251 mutex_lock(&mcp
->lock
);
252 mcp
->cache
[MCP_IODIR
] |= (1 << offset
);
253 status
= mcp
->ops
->write(mcp
, MCP_IODIR
, mcp
->cache
[MCP_IODIR
]);
254 mutex_unlock(&mcp
->lock
);
258 static int mcp23s08_get(struct gpio_chip
*chip
, unsigned offset
)
260 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
263 mutex_lock(&mcp
->lock
);
265 /* REVISIT reading this clears any IRQ ... */
266 status
= mcp
->ops
->read(mcp
, MCP_GPIO
);
270 mcp
->cache
[MCP_GPIO
] = status
;
271 status
= !!(status
& (1 << offset
));
273 mutex_unlock(&mcp
->lock
);
277 static int __mcp23s08_set(struct mcp23s08
*mcp
, unsigned mask
, int value
)
279 unsigned olat
= mcp
->cache
[MCP_OLAT
];
285 mcp
->cache
[MCP_OLAT
] = olat
;
286 return mcp
->ops
->write(mcp
, MCP_OLAT
, olat
);
289 static void mcp23s08_set(struct gpio_chip
*chip
, unsigned offset
, int value
)
291 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
292 unsigned mask
= 1 << offset
;
294 mutex_lock(&mcp
->lock
);
295 __mcp23s08_set(mcp
, mask
, value
);
296 mutex_unlock(&mcp
->lock
);
300 mcp23s08_direction_output(struct gpio_chip
*chip
, unsigned offset
, int value
)
302 struct mcp23s08
*mcp
= container_of(chip
, struct mcp23s08
, chip
);
303 unsigned mask
= 1 << offset
;
306 mutex_lock(&mcp
->lock
);
307 status
= __mcp23s08_set(mcp
, mask
, value
);
309 mcp
->cache
[MCP_IODIR
] &= ~mask
;
310 status
= mcp
->ops
->write(mcp
, MCP_IODIR
, mcp
->cache
[MCP_IODIR
]);
312 mutex_unlock(&mcp
->lock
);
316 /*----------------------------------------------------------------------*/
318 #ifdef CONFIG_DEBUG_FS
320 #include <linux/seq_file.h>
323 * This shows more info than the generic gpio dump code:
324 * pullups, deglitching, open drain drive.
326 static void mcp23s08_dbg_show(struct seq_file
*s
, struct gpio_chip
*chip
)
328 struct mcp23s08
*mcp
;
333 mcp
= container_of(chip
, struct mcp23s08
, chip
);
335 /* NOTE: we only handle one bank for now ... */
336 bank
= '0' + ((mcp
->addr
>> 1) & 0x7);
338 mutex_lock(&mcp
->lock
);
339 t
= mcp
->ops
->read_regs(mcp
, 0, mcp
->cache
, ARRAY_SIZE(mcp
->cache
));
341 seq_printf(s
, " I/O ERROR %d\n", t
);
345 for (t
= 0, mask
= 1; t
< chip
->ngpio
; t
++, mask
<<= 1) {
348 label
= gpiochip_is_requested(chip
, t
);
352 seq_printf(s
, " gpio-%-3d P%c.%d (%-12s) %s %s %s",
353 chip
->base
+ t
, bank
, t
, label
,
354 (mcp
->cache
[MCP_IODIR
] & mask
) ? "in " : "out",
355 (mcp
->cache
[MCP_GPIO
] & mask
) ? "hi" : "lo",
356 (mcp
->cache
[MCP_GPPU
] & mask
) ? "up" : " ");
357 /* NOTE: ignoring the irq-related registers */
361 mutex_unlock(&mcp
->lock
);
365 #define mcp23s08_dbg_show NULL
368 /*----------------------------------------------------------------------*/
370 static int mcp23s08_probe_one(struct mcp23s08
*mcp
, struct device
*dev
,
371 void *data
, unsigned addr
,
372 unsigned type
, unsigned base
, unsigned pullups
)
376 mutex_init(&mcp
->lock
);
381 mcp
->chip
.direction_input
= mcp23s08_direction_input
;
382 mcp
->chip
.get
= mcp23s08_get
;
383 mcp
->chip
.direction_output
= mcp23s08_direction_output
;
384 mcp
->chip
.set
= mcp23s08_set
;
385 mcp
->chip
.dbg_show
= mcp23s08_dbg_show
;
388 #ifdef CONFIG_SPI_MASTER
390 mcp
->ops
= &mcp23s08_ops
;
392 mcp
->chip
.label
= "mcp23s08";
396 mcp
->ops
= &mcp23s17_ops
;
397 mcp
->chip
.ngpio
= 16;
398 mcp
->chip
.label
= "mcp23s17";
400 #endif /* CONFIG_SPI_MASTER */
404 mcp
->ops
= &mcp23008_ops
;
406 mcp
->chip
.label
= "mcp23008";
410 mcp
->ops
= &mcp23017_ops
;
411 mcp
->chip
.ngpio
= 16;
412 mcp
->chip
.label
= "mcp23017";
414 #endif /* CONFIG_I2C */
417 dev_err(dev
, "invalid device type (%d)\n", type
);
421 mcp
->chip
.base
= base
;
422 mcp
->chip
.can_sleep
= 1;
424 mcp
->chip
.owner
= THIS_MODULE
;
426 /* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
427 * and MCP_IOCON.HAEN = 1, so we work with all chips.
429 status
= mcp
->ops
->read(mcp
, MCP_IOCON
);
432 if ((status
& IOCON_SEQOP
) || !(status
& IOCON_HAEN
)) {
433 /* mcp23s17 has IOCON twice, make sure they are in sync */
434 status
&= ~(IOCON_SEQOP
| (IOCON_SEQOP
<< 8));
435 status
|= IOCON_HAEN
| (IOCON_HAEN
<< 8);
436 status
= mcp
->ops
->write(mcp
, MCP_IOCON
, status
);
441 /* configure ~100K pullups */
442 status
= mcp
->ops
->write(mcp
, MCP_GPPU
, pullups
);
446 status
= mcp
->ops
->read_regs(mcp
, 0, mcp
->cache
, ARRAY_SIZE(mcp
->cache
));
450 /* disable inverter on input */
451 if (mcp
->cache
[MCP_IPOL
] != 0) {
452 mcp
->cache
[MCP_IPOL
] = 0;
453 status
= mcp
->ops
->write(mcp
, MCP_IPOL
, 0);
459 if (mcp
->cache
[MCP_GPINTEN
] != 0) {
460 mcp
->cache
[MCP_GPINTEN
] = 0;
461 status
= mcp
->ops
->write(mcp
, MCP_GPINTEN
, 0);
466 status
= gpiochip_add(&mcp
->chip
);
469 dev_dbg(dev
, "can't setup chip %d, --> %d\n",
474 /*----------------------------------------------------------------------*/
478 static int __devinit
mcp230xx_probe(struct i2c_client
*client
,
479 const struct i2c_device_id
*id
)
481 struct mcp23s08_platform_data
*pdata
;
482 struct mcp23s08
*mcp
;
485 pdata
= client
->dev
.platform_data
;
486 if (!pdata
|| !gpio_is_valid(pdata
->base
)) {
487 dev_dbg(&client
->dev
, "invalid or missing platform data\n");
491 mcp
= kzalloc(sizeof *mcp
, GFP_KERNEL
);
495 status
= mcp23s08_probe_one(mcp
, &client
->dev
, client
, client
->addr
,
496 id
->driver_data
, pdata
->base
,
497 pdata
->chip
[0].pullups
);
501 i2c_set_clientdata(client
, mcp
);
511 static int __devexit
mcp230xx_remove(struct i2c_client
*client
)
513 struct mcp23s08
*mcp
= i2c_get_clientdata(client
);
516 status
= gpiochip_remove(&mcp
->chip
);
523 static const struct i2c_device_id mcp230xx_id
[] = {
524 { "mcp23008", MCP_TYPE_008
},
525 { "mcp23017", MCP_TYPE_017
},
528 MODULE_DEVICE_TABLE(i2c
, mcp230xx_id
);
530 static struct i2c_driver mcp230xx_driver
= {
533 .owner
= THIS_MODULE
,
535 .probe
= mcp230xx_probe
,
536 .remove
= __devexit_p(mcp230xx_remove
),
537 .id_table
= mcp230xx_id
,
540 static int __init
mcp23s08_i2c_init(void)
542 return i2c_add_driver(&mcp230xx_driver
);
545 static void mcp23s08_i2c_exit(void)
547 i2c_del_driver(&mcp230xx_driver
);
552 static int __init
mcp23s08_i2c_init(void) { return 0; }
553 static void mcp23s08_i2c_exit(void) { }
555 #endif /* CONFIG_I2C */
557 /*----------------------------------------------------------------------*/
559 #ifdef CONFIG_SPI_MASTER
561 static int mcp23s08_probe(struct spi_device
*spi
)
563 struct mcp23s08_platform_data
*pdata
;
566 struct mcp23s08_driver_data
*data
;
570 type
= spi_get_device_id(spi
)->driver_data
;
572 pdata
= spi
->dev
.platform_data
;
573 if (!pdata
|| !gpio_is_valid(pdata
->base
)) {
574 dev_dbg(&spi
->dev
, "invalid or missing platform data\n");
578 for (addr
= 0; addr
< ARRAY_SIZE(pdata
->chip
); addr
++) {
579 if (!pdata
->chip
[addr
].is_present
)
582 if ((type
== MCP_TYPE_S08
) && (addr
> 3)) {
584 "mcp23s08 only supports address 0..3\n");
591 data
= kzalloc(sizeof *data
+ chips
* sizeof(struct mcp23s08
),
595 spi_set_drvdata(spi
, data
);
598 for (addr
= 0; addr
< ARRAY_SIZE(pdata
->chip
); addr
++) {
599 if (!pdata
->chip
[addr
].is_present
)
602 data
->mcp
[addr
] = &data
->chip
[chips
];
603 status
= mcp23s08_probe_one(data
->mcp
[addr
], &spi
->dev
, spi
,
604 0x40 | (addr
<< 1), type
, base
,
605 pdata
->chip
[addr
].pullups
);
609 base
+= (type
== MCP_TYPE_S17
) ? 16 : 8;
611 data
->ngpio
= base
- pdata
->base
;
613 /* NOTE: these chips have a relatively sane IRQ framework, with
614 * per-signal masking and level/edge triggering. It's not yet
621 for (addr
= 0; addr
< ARRAY_SIZE(data
->mcp
); addr
++) {
624 if (!data
->mcp
[addr
])
626 tmp
= gpiochip_remove(&data
->mcp
[addr
]->chip
);
628 dev_err(&spi
->dev
, "%s --> %d\n", "remove", tmp
);
634 static int mcp23s08_remove(struct spi_device
*spi
)
636 struct mcp23s08_driver_data
*data
= spi_get_drvdata(spi
);
640 for (addr
= 0; addr
< ARRAY_SIZE(data
->mcp
); addr
++) {
643 if (!data
->mcp
[addr
])
646 tmp
= gpiochip_remove(&data
->mcp
[addr
]->chip
);
648 dev_err(&spi
->dev
, "%s --> %d\n", "remove", tmp
);
657 static const struct spi_device_id mcp23s08_ids
[] = {
658 { "mcp23s08", MCP_TYPE_S08
},
659 { "mcp23s17", MCP_TYPE_S17
},
662 MODULE_DEVICE_TABLE(spi
, mcp23s08_ids
);
664 static struct spi_driver mcp23s08_driver
= {
665 .probe
= mcp23s08_probe
,
666 .remove
= mcp23s08_remove
,
667 .id_table
= mcp23s08_ids
,
670 .owner
= THIS_MODULE
,
674 static int __init
mcp23s08_spi_init(void)
676 return spi_register_driver(&mcp23s08_driver
);
679 static void mcp23s08_spi_exit(void)
681 spi_unregister_driver(&mcp23s08_driver
);
686 static int __init
mcp23s08_spi_init(void) { return 0; }
687 static void mcp23s08_spi_exit(void) { }
689 #endif /* CONFIG_SPI_MASTER */
691 /*----------------------------------------------------------------------*/
693 static int __init
mcp23s08_init(void)
697 ret
= mcp23s08_spi_init();
701 ret
= mcp23s08_i2c_init();
712 /* register after spi/i2c postcore initcall and before
713 * subsys initcalls that may rely on these GPIOs
715 subsys_initcall(mcp23s08_init
);
717 static void __exit
mcp23s08_exit(void)
722 module_exit(mcp23s08_exit
);
724 MODULE_LICENSE("GPL");