gpio-mcp23s08.c 18 KB

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