• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * MCP23S08 SPI/GPIO gpio expander driver
3  */
4 
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>
15 #include <linux/of.h>
16 #include <linux/of_device.h>
17 
18 /**
19  * MCP types supported by driver
20  */
21 #define MCP_TYPE_S08	0
22 #define MCP_TYPE_S17	1
23 #define MCP_TYPE_008	2
24 #define MCP_TYPE_017	3
25 
26 /* Registers are all 8 bits wide.
27  *
28  * The mcp23s17 has twice as many bits, and can be configured to work
29  * with either 16 bit registers or with two adjacent 8 bit banks.
30  */
31 #define MCP_IODIR	0x00		/* init/reset:  all ones */
32 #define MCP_IPOL	0x01
33 #define MCP_GPINTEN	0x02
34 #define MCP_DEFVAL	0x03
35 #define MCP_INTCON	0x04
36 #define MCP_IOCON	0x05
37 #	define IOCON_SEQOP	(1 << 5)
38 #	define IOCON_HAEN	(1 << 3)
39 #	define IOCON_ODR	(1 << 2)
40 #	define IOCON_INTPOL	(1 << 1)
41 #define MCP_GPPU	0x06
42 #define MCP_INTF	0x07
43 #define MCP_INTCAP	0x08
44 #define MCP_GPIO	0x09
45 #define MCP_OLAT	0x0a
46 
47 struct mcp23s08;
48 
49 struct mcp23s08_ops {
50 	int	(*read)(struct mcp23s08 *mcp, unsigned reg);
51 	int	(*write)(struct mcp23s08 *mcp, unsigned reg, unsigned val);
52 	int	(*read_regs)(struct mcp23s08 *mcp, unsigned reg,
53 			     u16 *vals, unsigned n);
54 };
55 
56 struct mcp23s08 {
57 	u8			addr;
58 
59 	u16			cache[11];
60 	/* lock protects the cached values */
61 	struct mutex		lock;
62 
63 	struct gpio_chip	chip;
64 
65 	const struct mcp23s08_ops	*ops;
66 	void			*data; /* ops specific data */
67 };
68 
69 /* A given spi_device can represent up to eight mcp23sxx chips
70  * sharing the same chipselect but using different addresses
71  * (e.g. chips #0 and #3 might be populated, but not #1 or $2).
72  * Driver data holds all the per-chip data.
73  */
74 struct mcp23s08_driver_data {
75 	unsigned		ngpio;
76 	struct mcp23s08		*mcp[8];
77 	struct mcp23s08		chip[];
78 };
79 
80 /*----------------------------------------------------------------------*/
81 
82 #if IS_ENABLED(CONFIG_I2C)
83 
mcp23008_read(struct mcp23s08 * mcp,unsigned reg)84 static int mcp23008_read(struct mcp23s08 *mcp, unsigned reg)
85 {
86 	return i2c_smbus_read_byte_data(mcp->data, reg);
87 }
88 
mcp23008_write(struct mcp23s08 * mcp,unsigned reg,unsigned val)89 static int mcp23008_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
90 {
91 	return i2c_smbus_write_byte_data(mcp->data, reg, val);
92 }
93 
94 static int
mcp23008_read_regs(struct mcp23s08 * mcp,unsigned reg,u16 * vals,unsigned n)95 mcp23008_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
96 {
97 	while (n--) {
98 		int ret = mcp23008_read(mcp, reg++);
99 		if (ret < 0)
100 			return ret;
101 		*vals++ = ret;
102 	}
103 
104 	return 0;
105 }
106 
mcp23017_read(struct mcp23s08 * mcp,unsigned reg)107 static int mcp23017_read(struct mcp23s08 *mcp, unsigned reg)
108 {
109 	return i2c_smbus_read_word_data(mcp->data, reg << 1);
110 }
111 
mcp23017_write(struct mcp23s08 * mcp,unsigned reg,unsigned val)112 static int mcp23017_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
113 {
114 	return i2c_smbus_write_word_data(mcp->data, reg << 1, val);
115 }
116 
117 static int
mcp23017_read_regs(struct mcp23s08 * mcp,unsigned reg,u16 * vals,unsigned n)118 mcp23017_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
119 {
120 	while (n--) {
121 		int ret = mcp23017_read(mcp, reg++);
122 		if (ret < 0)
123 			return ret;
124 		*vals++ = ret;
125 	}
126 
127 	return 0;
128 }
129 
130 static const struct mcp23s08_ops mcp23008_ops = {
131 	.read		= mcp23008_read,
132 	.write		= mcp23008_write,
133 	.read_regs	= mcp23008_read_regs,
134 };
135 
136 static const struct mcp23s08_ops mcp23017_ops = {
137 	.read		= mcp23017_read,
138 	.write		= mcp23017_write,
139 	.read_regs	= mcp23017_read_regs,
140 };
141 
142 #endif /* CONFIG_I2C */
143 
144 /*----------------------------------------------------------------------*/
145 
146 #ifdef CONFIG_SPI_MASTER
147 
mcp23s08_read(struct mcp23s08 * mcp,unsigned reg)148 static int mcp23s08_read(struct mcp23s08 *mcp, unsigned reg)
149 {
150 	u8	tx[2], rx[1];
151 	int	status;
152 
153 	tx[0] = mcp->addr | 0x01;
154 	tx[1] = reg;
155 	status = spi_write_then_read(mcp->data, tx, sizeof tx, rx, sizeof rx);
156 	return (status < 0) ? status : rx[0];
157 }
158 
mcp23s08_write(struct mcp23s08 * mcp,unsigned reg,unsigned val)159 static int mcp23s08_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
160 {
161 	u8	tx[3];
162 
163 	tx[0] = mcp->addr;
164 	tx[1] = reg;
165 	tx[2] = val;
166 	return spi_write_then_read(mcp->data, tx, sizeof tx, NULL, 0);
167 }
168 
169 static int
mcp23s08_read_regs(struct mcp23s08 * mcp,unsigned reg,u16 * vals,unsigned n)170 mcp23s08_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
171 {
172 	u8	tx[2], *tmp;
173 	int	status;
174 
175 	if ((n + reg) > sizeof mcp->cache)
176 		return -EINVAL;
177 	tx[0] = mcp->addr | 0x01;
178 	tx[1] = reg;
179 
180 	tmp = (u8 *)vals;
181 	status = spi_write_then_read(mcp->data, tx, sizeof tx, tmp, n);
182 	if (status >= 0) {
183 		while (n--)
184 			vals[n] = tmp[n]; /* expand to 16bit */
185 	}
186 	return status;
187 }
188 
mcp23s17_read(struct mcp23s08 * mcp,unsigned reg)189 static int mcp23s17_read(struct mcp23s08 *mcp, unsigned reg)
190 {
191 	u8	tx[2], rx[2];
192 	int	status;
193 
194 	tx[0] = mcp->addr | 0x01;
195 	tx[1] = reg << 1;
196 	status = spi_write_then_read(mcp->data, tx, sizeof tx, rx, sizeof rx);
197 	return (status < 0) ? status : (rx[0] | (rx[1] << 8));
198 }
199 
mcp23s17_write(struct mcp23s08 * mcp,unsigned reg,unsigned val)200 static int mcp23s17_write(struct mcp23s08 *mcp, unsigned reg, unsigned val)
201 {
202 	u8	tx[4];
203 
204 	tx[0] = mcp->addr;
205 	tx[1] = reg << 1;
206 	tx[2] = val;
207 	tx[3] = val >> 8;
208 	return spi_write_then_read(mcp->data, tx, sizeof tx, NULL, 0);
209 }
210 
211 static int
mcp23s17_read_regs(struct mcp23s08 * mcp,unsigned reg,u16 * vals,unsigned n)212 mcp23s17_read_regs(struct mcp23s08 *mcp, unsigned reg, u16 *vals, unsigned n)
213 {
214 	u8	tx[2];
215 	int	status;
216 
217 	if ((n + reg) > sizeof mcp->cache)
218 		return -EINVAL;
219 	tx[0] = mcp->addr | 0x01;
220 	tx[1] = reg << 1;
221 
222 	status = spi_write_then_read(mcp->data, tx, sizeof tx,
223 				     (u8 *)vals, n * 2);
224 	if (status >= 0) {
225 		while (n--)
226 			vals[n] = __le16_to_cpu((__le16)vals[n]);
227 	}
228 
229 	return status;
230 }
231 
232 static const struct mcp23s08_ops mcp23s08_ops = {
233 	.read		= mcp23s08_read,
234 	.write		= mcp23s08_write,
235 	.read_regs	= mcp23s08_read_regs,
236 };
237 
238 static const struct mcp23s08_ops mcp23s17_ops = {
239 	.read		= mcp23s17_read,
240 	.write		= mcp23s17_write,
241 	.read_regs	= mcp23s17_read_regs,
242 };
243 
244 #endif /* CONFIG_SPI_MASTER */
245 
246 /*----------------------------------------------------------------------*/
247 
mcp23s08_direction_input(struct gpio_chip * chip,unsigned offset)248 static int mcp23s08_direction_input(struct gpio_chip *chip, unsigned offset)
249 {
250 	struct mcp23s08	*mcp = container_of(chip, struct mcp23s08, chip);
251 	int status;
252 
253 	mutex_lock(&mcp->lock);
254 	mcp->cache[MCP_IODIR] |= (1 << offset);
255 	status = mcp->ops->write(mcp, MCP_IODIR, mcp->cache[MCP_IODIR]);
256 	mutex_unlock(&mcp->lock);
257 	return status;
258 }
259 
mcp23s08_get(struct gpio_chip * chip,unsigned offset)260 static int mcp23s08_get(struct gpio_chip *chip, unsigned offset)
261 {
262 	struct mcp23s08	*mcp = container_of(chip, struct mcp23s08, chip);
263 	int status;
264 
265 	mutex_lock(&mcp->lock);
266 
267 	/* REVISIT reading this clears any IRQ ... */
268 	status = mcp->ops->read(mcp, MCP_GPIO);
269 	if (status < 0)
270 		status = 0;
271 	else {
272 		mcp->cache[MCP_GPIO] = status;
273 		status = !!(status & (1 << offset));
274 	}
275 	mutex_unlock(&mcp->lock);
276 	return status;
277 }
278 
__mcp23s08_set(struct mcp23s08 * mcp,unsigned mask,int value)279 static int __mcp23s08_set(struct mcp23s08 *mcp, unsigned mask, int value)
280 {
281 	unsigned olat = mcp->cache[MCP_OLAT];
282 
283 	if (value)
284 		olat |= mask;
285 	else
286 		olat &= ~mask;
287 	mcp->cache[MCP_OLAT] = olat;
288 	return mcp->ops->write(mcp, MCP_OLAT, olat);
289 }
290 
mcp23s08_set(struct gpio_chip * chip,unsigned offset,int value)291 static void mcp23s08_set(struct gpio_chip *chip, unsigned offset, int value)
292 {
293 	struct mcp23s08	*mcp = container_of(chip, struct mcp23s08, chip);
294 	unsigned mask = 1 << offset;
295 
296 	mutex_lock(&mcp->lock);
297 	__mcp23s08_set(mcp, mask, value);
298 	mutex_unlock(&mcp->lock);
299 }
300 
301 static int
mcp23s08_direction_output(struct gpio_chip * chip,unsigned offset,int value)302 mcp23s08_direction_output(struct gpio_chip *chip, unsigned offset, int value)
303 {
304 	struct mcp23s08	*mcp = container_of(chip, struct mcp23s08, chip);
305 	unsigned mask = 1 << offset;
306 	int status;
307 
308 	mutex_lock(&mcp->lock);
309 	status = __mcp23s08_set(mcp, mask, value);
310 	if (status == 0) {
311 		mcp->cache[MCP_IODIR] &= ~mask;
312 		status = mcp->ops->write(mcp, MCP_IODIR, mcp->cache[MCP_IODIR]);
313 	}
314 	mutex_unlock(&mcp->lock);
315 	return status;
316 }
317 
318 /*----------------------------------------------------------------------*/
319 
320 #ifdef CONFIG_DEBUG_FS
321 
322 #include <linux/seq_file.h>
323 
324 /*
325  * This shows more info than the generic gpio dump code:
326  * pullups, deglitching, open drain drive.
327  */
mcp23s08_dbg_show(struct seq_file * s,struct gpio_chip * chip)328 static void mcp23s08_dbg_show(struct seq_file *s, struct gpio_chip *chip)
329 {
330 	struct mcp23s08	*mcp;
331 	char		bank;
332 	int		t;
333 	unsigned	mask;
334 
335 	mcp = container_of(chip, struct mcp23s08, chip);
336 
337 	/* NOTE: we only handle one bank for now ... */
338 	bank = '0' + ((mcp->addr >> 1) & 0x7);
339 
340 	mutex_lock(&mcp->lock);
341 	t = mcp->ops->read_regs(mcp, 0, mcp->cache, ARRAY_SIZE(mcp->cache));
342 	if (t < 0) {
343 		seq_printf(s, " I/O ERROR %d\n", t);
344 		goto done;
345 	}
346 
347 	for (t = 0, mask = 1; t < chip->ngpio; t++, mask <<= 1) {
348 		const char	*label;
349 
350 		label = gpiochip_is_requested(chip, t);
351 		if (!label)
352 			continue;
353 
354 		seq_printf(s, " gpio-%-3d P%c.%d (%-12s) %s %s %s",
355 			chip->base + t, bank, t, label,
356 			(mcp->cache[MCP_IODIR] & mask) ? "in " : "out",
357 			(mcp->cache[MCP_GPIO] & mask) ? "hi" : "lo",
358 			(mcp->cache[MCP_GPPU] & mask) ? "up" : "  ");
359 		/* NOTE:  ignoring the irq-related registers */
360 		seq_printf(s, "\n");
361 	}
362 done:
363 	mutex_unlock(&mcp->lock);
364 }
365 
366 #else
367 #define mcp23s08_dbg_show	NULL
368 #endif
369 
370 /*----------------------------------------------------------------------*/
371 
mcp23s08_probe_one(struct mcp23s08 * mcp,struct device * dev,void * data,unsigned addr,unsigned type,unsigned base,unsigned pullups)372 static int mcp23s08_probe_one(struct mcp23s08 *mcp, struct device *dev,
373 			      void *data, unsigned addr,
374 			      unsigned type, unsigned base, unsigned pullups)
375 {
376 	int status;
377 
378 	mutex_init(&mcp->lock);
379 
380 	mcp->data = data;
381 	mcp->addr = addr;
382 
383 	mcp->chip.direction_input = mcp23s08_direction_input;
384 	mcp->chip.get = mcp23s08_get;
385 	mcp->chip.direction_output = mcp23s08_direction_output;
386 	mcp->chip.set = mcp23s08_set;
387 	mcp->chip.dbg_show = mcp23s08_dbg_show;
388 #ifdef CONFIG_OF
389 	mcp->chip.of_gpio_n_cells = 2;
390 	mcp->chip.of_node = dev->of_node;
391 #endif
392 
393 	switch (type) {
394 #ifdef CONFIG_SPI_MASTER
395 	case MCP_TYPE_S08:
396 		mcp->ops = &mcp23s08_ops;
397 		mcp->chip.ngpio = 8;
398 		mcp->chip.label = "mcp23s08";
399 		break;
400 
401 	case MCP_TYPE_S17:
402 		mcp->ops = &mcp23s17_ops;
403 		mcp->chip.ngpio = 16;
404 		mcp->chip.label = "mcp23s17";
405 		break;
406 #endif /* CONFIG_SPI_MASTER */
407 
408 #if IS_ENABLED(CONFIG_I2C)
409 	case MCP_TYPE_008:
410 		mcp->ops = &mcp23008_ops;
411 		mcp->chip.ngpio = 8;
412 		mcp->chip.label = "mcp23008";
413 		break;
414 
415 	case MCP_TYPE_017:
416 		mcp->ops = &mcp23017_ops;
417 		mcp->chip.ngpio = 16;
418 		mcp->chip.label = "mcp23017";
419 		break;
420 #endif /* CONFIG_I2C */
421 
422 	default:
423 		dev_err(dev, "invalid device type (%d)\n", type);
424 		return -EINVAL;
425 	}
426 
427 	mcp->chip.base = base;
428 	mcp->chip.can_sleep = 1;
429 	mcp->chip.dev = dev;
430 	mcp->chip.owner = THIS_MODULE;
431 
432 	/* verify MCP_IOCON.SEQOP = 0, so sequential reads work,
433 	 * and MCP_IOCON.HAEN = 1, so we work with all chips.
434 	 */
435 	status = mcp->ops->read(mcp, MCP_IOCON);
436 	if (status < 0)
437 		goto fail;
438 	if ((status & IOCON_SEQOP) || !(status & IOCON_HAEN)) {
439 		/* mcp23s17 has IOCON twice, make sure they are in sync */
440 		status &= ~(IOCON_SEQOP | (IOCON_SEQOP << 8));
441 		status |= IOCON_HAEN | (IOCON_HAEN << 8);
442 		status = mcp->ops->write(mcp, MCP_IOCON, status);
443 		if (status < 0)
444 			goto fail;
445 	}
446 
447 	/* configure ~100K pullups */
448 	status = mcp->ops->write(mcp, MCP_GPPU, pullups);
449 	if (status < 0)
450 		goto fail;
451 
452 	status = mcp->ops->read_regs(mcp, 0, mcp->cache, ARRAY_SIZE(mcp->cache));
453 	if (status < 0)
454 		goto fail;
455 
456 	/* disable inverter on input */
457 	if (mcp->cache[MCP_IPOL] != 0) {
458 		mcp->cache[MCP_IPOL] = 0;
459 		status = mcp->ops->write(mcp, MCP_IPOL, 0);
460 		if (status < 0)
461 			goto fail;
462 	}
463 
464 	/* disable irqs */
465 	if (mcp->cache[MCP_GPINTEN] != 0) {
466 		mcp->cache[MCP_GPINTEN] = 0;
467 		status = mcp->ops->write(mcp, MCP_GPINTEN, 0);
468 		if (status < 0)
469 			goto fail;
470 	}
471 
472 	status = gpiochip_add(&mcp->chip);
473 fail:
474 	if (status < 0)
475 		dev_dbg(dev, "can't setup chip %d, --> %d\n",
476 			addr, status);
477 	return status;
478 }
479 
480 /*----------------------------------------------------------------------*/
481 
482 #ifdef CONFIG_OF
483 #ifdef CONFIG_SPI_MASTER
484 static struct of_device_id mcp23s08_spi_of_match[] = {
485 	{
486 		.compatible = "mcp,mcp23s08", .data = (void *) MCP_TYPE_S08,
487 	},
488 	{
489 		.compatible = "mcp,mcp23s17", .data = (void *) MCP_TYPE_S17,
490 	},
491 	{ },
492 };
493 MODULE_DEVICE_TABLE(of, mcp23s08_spi_of_match);
494 #endif
495 
496 #if IS_ENABLED(CONFIG_I2C)
497 static struct of_device_id mcp23s08_i2c_of_match[] = {
498 	{
499 		.compatible = "mcp,mcp23008", .data = (void *) MCP_TYPE_008,
500 	},
501 	{
502 		.compatible = "mcp,mcp23017", .data = (void *) MCP_TYPE_017,
503 	},
504 	{ },
505 };
506 MODULE_DEVICE_TABLE(of, mcp23s08_i2c_of_match);
507 #endif
508 #endif /* CONFIG_OF */
509 
510 
511 #if IS_ENABLED(CONFIG_I2C)
512 
mcp230xx_probe(struct i2c_client * client,const struct i2c_device_id * id)513 static int mcp230xx_probe(struct i2c_client *client,
514 				    const struct i2c_device_id *id)
515 {
516 	struct mcp23s08_platform_data *pdata;
517 	struct mcp23s08 *mcp;
518 	int status, base, pullups;
519 	const struct of_device_id *match;
520 
521 	match = of_match_device(of_match_ptr(mcp23s08_i2c_of_match),
522 					&client->dev);
523 	if (match) {
524 		base = -1;
525 		pullups = 0;
526 	} else {
527 		pdata = client->dev.platform_data;
528 		if (!pdata || !gpio_is_valid(pdata->base)) {
529 			dev_dbg(&client->dev,
530 					"invalid or missing platform data\n");
531 			return -EINVAL;
532 		}
533 		base = pdata->base;
534 		pullups = pdata->chip[0].pullups;
535 	}
536 
537 	mcp = kzalloc(sizeof *mcp, GFP_KERNEL);
538 	if (!mcp)
539 		return -ENOMEM;
540 
541 	status = mcp23s08_probe_one(mcp, &client->dev, client, client->addr,
542 				    id->driver_data, base, pullups);
543 	if (status)
544 		goto fail;
545 
546 	i2c_set_clientdata(client, mcp);
547 
548 	return 0;
549 
550 fail:
551 	kfree(mcp);
552 
553 	return status;
554 }
555 
mcp230xx_remove(struct i2c_client * client)556 static int mcp230xx_remove(struct i2c_client *client)
557 {
558 	struct mcp23s08 *mcp = i2c_get_clientdata(client);
559 	int status;
560 
561 	status = gpiochip_remove(&mcp->chip);
562 	if (status == 0)
563 		kfree(mcp);
564 
565 	return status;
566 }
567 
568 static const struct i2c_device_id mcp230xx_id[] = {
569 	{ "mcp23008", MCP_TYPE_008 },
570 	{ "mcp23017", MCP_TYPE_017 },
571 	{ },
572 };
573 MODULE_DEVICE_TABLE(i2c, mcp230xx_id);
574 
575 static struct i2c_driver mcp230xx_driver = {
576 	.driver = {
577 		.name	= "mcp230xx",
578 		.owner	= THIS_MODULE,
579 		.of_match_table = of_match_ptr(mcp23s08_i2c_of_match),
580 	},
581 	.probe		= mcp230xx_probe,
582 	.remove		= mcp230xx_remove,
583 	.id_table	= mcp230xx_id,
584 };
585 
mcp23s08_i2c_init(void)586 static int __init mcp23s08_i2c_init(void)
587 {
588 	return i2c_add_driver(&mcp230xx_driver);
589 }
590 
mcp23s08_i2c_exit(void)591 static void mcp23s08_i2c_exit(void)
592 {
593 	i2c_del_driver(&mcp230xx_driver);
594 }
595 
596 #else
597 
mcp23s08_i2c_init(void)598 static int __init mcp23s08_i2c_init(void) { return 0; }
mcp23s08_i2c_exit(void)599 static void mcp23s08_i2c_exit(void) { }
600 
601 #endif /* CONFIG_I2C */
602 
603 /*----------------------------------------------------------------------*/
604 
605 #ifdef CONFIG_SPI_MASTER
606 
mcp23s08_probe(struct spi_device * spi)607 static int mcp23s08_probe(struct spi_device *spi)
608 {
609 	struct mcp23s08_platform_data	*pdata;
610 	unsigned			addr;
611 	unsigned			chips = 0;
612 	struct mcp23s08_driver_data	*data;
613 	int				status, type;
614 	unsigned			base = -1,
615 					ngpio = 0,
616 					pullups[ARRAY_SIZE(pdata->chip)];
617 	const struct			of_device_id *match;
618 	u32				spi_present_mask = 0;
619 
620 	match = of_match_device(of_match_ptr(mcp23s08_spi_of_match), &spi->dev);
621 	if (match) {
622 		type = (int)match->data;
623 		status = of_property_read_u32(spi->dev.of_node,
624 				"mcp,spi-present-mask", &spi_present_mask);
625 		if (status) {
626 			dev_err(&spi->dev, "DT has no spi-present-mask\n");
627 			return -ENODEV;
628 		}
629 		if ((spi_present_mask <= 0) || (spi_present_mask >= 256)) {
630 			dev_err(&spi->dev, "invalid spi-present-mask\n");
631 			return -ENODEV;
632 		}
633 
634 		for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++)
635 			pullups[addr] = 0;
636 	} else {
637 		type = spi_get_device_id(spi)->driver_data;
638 		pdata = spi->dev.platform_data;
639 		if (!pdata || !gpio_is_valid(pdata->base)) {
640 			dev_dbg(&spi->dev,
641 					"invalid or missing platform data\n");
642 			return -EINVAL;
643 		}
644 
645 		for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
646 			if (!pdata->chip[addr].is_present)
647 				continue;
648 			chips++;
649 			if ((type == MCP_TYPE_S08) && (addr > 3)) {
650 				dev_err(&spi->dev,
651 					"mcp23s08 only supports address 0..3\n");
652 				return -EINVAL;
653 			}
654 			spi_present_mask |= 1 << addr;
655 			pullups[addr] = pdata->chip[addr].pullups;
656 		}
657 
658 		if (!chips)
659 			return -ENODEV;
660 
661 		base = pdata->base;
662 	}
663 
664 	data = kzalloc(sizeof *data + chips * sizeof(struct mcp23s08),
665 			GFP_KERNEL);
666 	if (!data)
667 		return -ENOMEM;
668 	spi_set_drvdata(spi, data);
669 
670 	for (addr = 0; addr < ARRAY_SIZE(pdata->chip); addr++) {
671 		if (!(spi_present_mask & (1 << addr)))
672 			continue;
673 		chips--;
674 		data->mcp[addr] = &data->chip[chips];
675 		status = mcp23s08_probe_one(data->mcp[addr], &spi->dev, spi,
676 					    0x40 | (addr << 1), type, base,
677 					    pullups[addr]);
678 		if (status < 0)
679 			goto fail;
680 
681 		if (base != -1)
682 			base += (type == MCP_TYPE_S17) ? 16 : 8;
683 		ngpio += (type == MCP_TYPE_S17) ? 16 : 8;
684 	}
685 	data->ngpio = ngpio;
686 
687 	/* NOTE:  these chips have a relatively sane IRQ framework, with
688 	 * per-signal masking and level/edge triggering.  It's not yet
689 	 * handled here...
690 	 */
691 
692 	return 0;
693 
694 fail:
695 	for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) {
696 		int tmp;
697 
698 		if (!data->mcp[addr])
699 			continue;
700 		tmp = gpiochip_remove(&data->mcp[addr]->chip);
701 		if (tmp < 0)
702 			dev_err(&spi->dev, "%s --> %d\n", "remove", tmp);
703 	}
704 	kfree(data);
705 	return status;
706 }
707 
mcp23s08_remove(struct spi_device * spi)708 static int mcp23s08_remove(struct spi_device *spi)
709 {
710 	struct mcp23s08_driver_data	*data = spi_get_drvdata(spi);
711 	unsigned			addr;
712 	int				status = 0;
713 
714 	for (addr = 0; addr < ARRAY_SIZE(data->mcp); addr++) {
715 		int tmp;
716 
717 		if (!data->mcp[addr])
718 			continue;
719 
720 		tmp = gpiochip_remove(&data->mcp[addr]->chip);
721 		if (tmp < 0) {
722 			dev_err(&spi->dev, "%s --> %d\n", "remove", tmp);
723 			status = tmp;
724 		}
725 	}
726 	if (status == 0)
727 		kfree(data);
728 	return status;
729 }
730 
731 static const struct spi_device_id mcp23s08_ids[] = {
732 	{ "mcp23s08", MCP_TYPE_S08 },
733 	{ "mcp23s17", MCP_TYPE_S17 },
734 	{ },
735 };
736 MODULE_DEVICE_TABLE(spi, mcp23s08_ids);
737 
738 static struct spi_driver mcp23s08_driver = {
739 	.probe		= mcp23s08_probe,
740 	.remove		= mcp23s08_remove,
741 	.id_table	= mcp23s08_ids,
742 	.driver = {
743 		.name	= "mcp23s08",
744 		.owner	= THIS_MODULE,
745 		.of_match_table = of_match_ptr(mcp23s08_spi_of_match),
746 	},
747 };
748 
mcp23s08_spi_init(void)749 static int __init mcp23s08_spi_init(void)
750 {
751 	return spi_register_driver(&mcp23s08_driver);
752 }
753 
mcp23s08_spi_exit(void)754 static void mcp23s08_spi_exit(void)
755 {
756 	spi_unregister_driver(&mcp23s08_driver);
757 }
758 
759 #else
760 
mcp23s08_spi_init(void)761 static int __init mcp23s08_spi_init(void) { return 0; }
mcp23s08_spi_exit(void)762 static void mcp23s08_spi_exit(void) { }
763 
764 #endif /* CONFIG_SPI_MASTER */
765 
766 /*----------------------------------------------------------------------*/
767 
mcp23s08_init(void)768 static int __init mcp23s08_init(void)
769 {
770 	int ret;
771 
772 	ret = mcp23s08_spi_init();
773 	if (ret)
774 		goto spi_fail;
775 
776 	ret = mcp23s08_i2c_init();
777 	if (ret)
778 		goto i2c_fail;
779 
780 	return 0;
781 
782  i2c_fail:
783 	mcp23s08_spi_exit();
784  spi_fail:
785 	return ret;
786 }
787 /* register after spi/i2c postcore initcall and before
788  * subsys initcalls that may rely on these GPIOs
789  */
790 subsys_initcall(mcp23s08_init);
791 
mcp23s08_exit(void)792 static void __exit mcp23s08_exit(void)
793 {
794 	mcp23s08_spi_exit();
795 	mcp23s08_i2c_exit();
796 }
797 module_exit(mcp23s08_exit);
798 
799 MODULE_LICENSE("GPL");
800