mc13783-core.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. /*
  2. * Copyright 2009 Pengutronix
  3. * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
  4. *
  5. * loosely based on an earlier driver that has
  6. * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it under
  9. * the terms of the GNU General Public License version 2 as published by the
  10. * Free Software Foundation.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/spi/spi.h>
  14. #include <linux/mfd/core.h>
  15. #include <linux/mfd/mc13783-private.h>
  16. #define MC13783_IRQSTAT0 0
  17. #define MC13783_IRQSTAT0_ADCDONEI (1 << 0)
  18. #define MC13783_IRQSTAT0_ADCBISDONEI (1 << 1)
  19. #define MC13783_IRQSTAT0_TSI (1 << 2)
  20. #define MC13783_IRQSTAT0_WHIGHI (1 << 3)
  21. #define MC13783_IRQSTAT0_WLOWI (1 << 4)
  22. #define MC13783_IRQSTAT0_CHGDETI (1 << 6)
  23. #define MC13783_IRQSTAT0_CHGOVI (1 << 7)
  24. #define MC13783_IRQSTAT0_CHGREVI (1 << 8)
  25. #define MC13783_IRQSTAT0_CHGSHORTI (1 << 9)
  26. #define MC13783_IRQSTAT0_CCCVI (1 << 10)
  27. #define MC13783_IRQSTAT0_CHGCURRI (1 << 11)
  28. #define MC13783_IRQSTAT0_BPONI (1 << 12)
  29. #define MC13783_IRQSTAT0_LOBATLI (1 << 13)
  30. #define MC13783_IRQSTAT0_LOBATHI (1 << 14)
  31. #define MC13783_IRQSTAT0_UDPI (1 << 15)
  32. #define MC13783_IRQSTAT0_USBI (1 << 16)
  33. #define MC13783_IRQSTAT0_IDI (1 << 19)
  34. #define MC13783_IRQSTAT0_SE1I (1 << 21)
  35. #define MC13783_IRQSTAT0_CKDETI (1 << 22)
  36. #define MC13783_IRQSTAT0_UDMI (1 << 23)
  37. #define MC13783_IRQMASK0 1
  38. #define MC13783_IRQMASK0_ADCDONEM MC13783_IRQSTAT0_ADCDONEI
  39. #define MC13783_IRQMASK0_ADCBISDONEM MC13783_IRQSTAT0_ADCBISDONEI
  40. #define MC13783_IRQMASK0_TSM MC13783_IRQSTAT0_TSI
  41. #define MC13783_IRQMASK0_WHIGHM MC13783_IRQSTAT0_WHIGHI
  42. #define MC13783_IRQMASK0_WLOWM MC13783_IRQSTAT0_WLOWI
  43. #define MC13783_IRQMASK0_CHGDETM MC13783_IRQSTAT0_CHGDETI
  44. #define MC13783_IRQMASK0_CHGOVM MC13783_IRQSTAT0_CHGOVI
  45. #define MC13783_IRQMASK0_CHGREVM MC13783_IRQSTAT0_CHGREVI
  46. #define MC13783_IRQMASK0_CHGSHORTM MC13783_IRQSTAT0_CHGSHORTI
  47. #define MC13783_IRQMASK0_CCCVM MC13783_IRQSTAT0_CCCVI
  48. #define MC13783_IRQMASK0_CHGCURRM MC13783_IRQSTAT0_CHGCURRI
  49. #define MC13783_IRQMASK0_BPONM MC13783_IRQSTAT0_BPONI
  50. #define MC13783_IRQMASK0_LOBATLM MC13783_IRQSTAT0_LOBATLI
  51. #define MC13783_IRQMASK0_LOBATHM MC13783_IRQSTAT0_LOBATHI
  52. #define MC13783_IRQMASK0_UDPM MC13783_IRQSTAT0_UDPI
  53. #define MC13783_IRQMASK0_USBM MC13783_IRQSTAT0_USBI
  54. #define MC13783_IRQMASK0_IDM MC13783_IRQSTAT0_IDI
  55. #define MC13783_IRQMASK0_SE1M MC13783_IRQSTAT0_SE1I
  56. #define MC13783_IRQMASK0_CKDETM MC13783_IRQSTAT0_CKDETI
  57. #define MC13783_IRQMASK0_UDMM MC13783_IRQSTAT0_UDMI
  58. #define MC13783_IRQSTAT1 3
  59. #define MC13783_IRQSTAT1_1HZI (1 << 0)
  60. #define MC13783_IRQSTAT1_TODAI (1 << 1)
  61. #define MC13783_IRQSTAT1_ONOFD1I (1 << 3)
  62. #define MC13783_IRQSTAT1_ONOFD2I (1 << 4)
  63. #define MC13783_IRQSTAT1_ONOFD3I (1 << 5)
  64. #define MC13783_IRQSTAT1_SYSRSTI (1 << 6)
  65. #define MC13783_IRQSTAT1_RTCRSTI (1 << 7)
  66. #define MC13783_IRQSTAT1_PCI (1 << 8)
  67. #define MC13783_IRQSTAT1_WARMI (1 << 9)
  68. #define MC13783_IRQSTAT1_MEMHLDI (1 << 10)
  69. #define MC13783_IRQSTAT1_PWRRDYI (1 << 11)
  70. #define MC13783_IRQSTAT1_THWARNLI (1 << 12)
  71. #define MC13783_IRQSTAT1_THWARNHI (1 << 13)
  72. #define MC13783_IRQSTAT1_CLKI (1 << 14)
  73. #define MC13783_IRQSTAT1_SEMAFI (1 << 15)
  74. #define MC13783_IRQSTAT1_MC2BI (1 << 17)
  75. #define MC13783_IRQSTAT1_HSDETI (1 << 18)
  76. #define MC13783_IRQSTAT1_HSLI (1 << 19)
  77. #define MC13783_IRQSTAT1_ALSPTHI (1 << 20)
  78. #define MC13783_IRQSTAT1_AHSSHORTI (1 << 21)
  79. #define MC13783_IRQMASK1 4
  80. #define MC13783_IRQMASK1_1HZM MC13783_IRQSTAT1_1HZI
  81. #define MC13783_IRQMASK1_TODAM MC13783_IRQSTAT1_TODAI
  82. #define MC13783_IRQMASK1_ONOFD1M MC13783_IRQSTAT1_ONOFD1I
  83. #define MC13783_IRQMASK1_ONOFD2M MC13783_IRQSTAT1_ONOFD2I
  84. #define MC13783_IRQMASK1_ONOFD3M MC13783_IRQSTAT1_ONOFD3I
  85. #define MC13783_IRQMASK1_SYSRSTM MC13783_IRQSTAT1_SYSRSTI
  86. #define MC13783_IRQMASK1_RTCRSTM MC13783_IRQSTAT1_RTCRSTI
  87. #define MC13783_IRQMASK1_PCM MC13783_IRQSTAT1_PCI
  88. #define MC13783_IRQMASK1_WARMM MC13783_IRQSTAT1_WARMI
  89. #define MC13783_IRQMASK1_MEMHLDM MC13783_IRQSTAT1_MEMHLDI
  90. #define MC13783_IRQMASK1_PWRRDYM MC13783_IRQSTAT1_PWRRDYI
  91. #define MC13783_IRQMASK1_THWARNLM MC13783_IRQSTAT1_THWARNLI
  92. #define MC13783_IRQMASK1_THWARNHM MC13783_IRQSTAT1_THWARNHI
  93. #define MC13783_IRQMASK1_CLKM MC13783_IRQSTAT1_CLKI
  94. #define MC13783_IRQMASK1_SEMAFM MC13783_IRQSTAT1_SEMAFI
  95. #define MC13783_IRQMASK1_MC2BM MC13783_IRQSTAT1_MC2BI
  96. #define MC13783_IRQMASK1_HSDETM MC13783_IRQSTAT1_HSDETI
  97. #define MC13783_IRQMASK1_HSLM MC13783_IRQSTAT1_HSLI
  98. #define MC13783_IRQMASK1_ALSPTHM MC13783_IRQSTAT1_ALSPTHI
  99. #define MC13783_IRQMASK1_AHSSHORTM MC13783_IRQSTAT1_AHSSHORTI
  100. #define MC13783_ADC1 44
  101. #define MC13783_ADC1_ADEN (1 << 0)
  102. #define MC13783_ADC1_RAND (1 << 1)
  103. #define MC13783_ADC1_ADSEL (1 << 3)
  104. #define MC13783_ADC1_ASC (1 << 20)
  105. #define MC13783_ADC1_ADTRIGIGN (1 << 21)
  106. #define MC13783_NUMREGS 0x3f
  107. void mc13783_lock(struct mc13783 *mc13783)
  108. {
  109. if (!mutex_trylock(&mc13783->lock)) {
  110. dev_dbg(&mc13783->spidev->dev, "wait for %s from %pf\n",
  111. __func__, __builtin_return_address(0));
  112. mutex_lock(&mc13783->lock);
  113. }
  114. dev_dbg(&mc13783->spidev->dev, "%s from %pf\n",
  115. __func__, __builtin_return_address(0));
  116. }
  117. EXPORT_SYMBOL(mc13783_lock);
  118. void mc13783_unlock(struct mc13783 *mc13783)
  119. {
  120. dev_dbg(&mc13783->spidev->dev, "%s from %pf\n",
  121. __func__, __builtin_return_address(0));
  122. mutex_unlock(&mc13783->lock);
  123. }
  124. EXPORT_SYMBOL(mc13783_unlock);
  125. #define MC13783_REGOFFSET_SHIFT 25
  126. int mc13783_reg_read(struct mc13783 *mc13783, unsigned int offset, u32 *val)
  127. {
  128. struct spi_transfer t;
  129. struct spi_message m;
  130. int ret;
  131. BUG_ON(!mutex_is_locked(&mc13783->lock));
  132. if (offset > MC13783_NUMREGS)
  133. return -EINVAL;
  134. *val = offset << MC13783_REGOFFSET_SHIFT;
  135. memset(&t, 0, sizeof(t));
  136. t.tx_buf = val;
  137. t.rx_buf = val;
  138. t.len = sizeof(u32);
  139. spi_message_init(&m);
  140. spi_message_add_tail(&t, &m);
  141. ret = spi_sync(mc13783->spidev, &m);
  142. /* error in message.status implies error return from spi_sync */
  143. BUG_ON(!ret && m.status);
  144. if (ret)
  145. return ret;
  146. *val &= 0xffffff;
  147. dev_vdbg(&mc13783->spidev->dev, "[0x%02x] -> 0x%06x\n", offset, *val);
  148. return 0;
  149. }
  150. EXPORT_SYMBOL(mc13783_reg_read);
  151. int mc13783_reg_write(struct mc13783 *mc13783, unsigned int offset, u32 val)
  152. {
  153. u32 buf;
  154. struct spi_transfer t;
  155. struct spi_message m;
  156. int ret;
  157. BUG_ON(!mutex_is_locked(&mc13783->lock));
  158. dev_vdbg(&mc13783->spidev->dev, "[0x%02x] <- 0x%06x\n", offset, val);
  159. if (offset > MC13783_NUMREGS || val > 0xffffff)
  160. return -EINVAL;
  161. buf = 1 << 31 | offset << MC13783_REGOFFSET_SHIFT | val;
  162. memset(&t, 0, sizeof(t));
  163. t.tx_buf = &buf;
  164. t.rx_buf = &buf;
  165. t.len = sizeof(u32);
  166. spi_message_init(&m);
  167. spi_message_add_tail(&t, &m);
  168. ret = spi_sync(mc13783->spidev, &m);
  169. BUG_ON(!ret && m.status);
  170. if (ret)
  171. return ret;
  172. return 0;
  173. }
  174. EXPORT_SYMBOL(mc13783_reg_write);
  175. int mc13783_reg_rmw(struct mc13783 *mc13783, unsigned int offset,
  176. u32 mask, u32 val)
  177. {
  178. int ret;
  179. u32 valread;
  180. BUG_ON(val & ~mask);
  181. ret = mc13783_reg_read(mc13783, offset, &valread);
  182. if (ret)
  183. return ret;
  184. valread = (valread & ~mask) | val;
  185. return mc13783_reg_write(mc13783, offset, valread);
  186. }
  187. EXPORT_SYMBOL(mc13783_reg_rmw);
  188. int mc13783_mask(struct mc13783 *mc13783, int irq)
  189. {
  190. int ret;
  191. unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
  192. u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
  193. u32 mask;
  194. if (irq < 0 || irq >= MC13783_NUM_IRQ)
  195. return -EINVAL;
  196. ret = mc13783_reg_read(mc13783, offmask, &mask);
  197. if (ret)
  198. return ret;
  199. if (mask & irqbit)
  200. /* already masked */
  201. return 0;
  202. return mc13783_reg_write(mc13783, offmask, mask | irqbit);
  203. }
  204. EXPORT_SYMBOL(mc13783_mask);
  205. int mc13783_unmask(struct mc13783 *mc13783, int irq)
  206. {
  207. int ret;
  208. unsigned int offmask = irq < 24 ? MC13783_IRQMASK0 : MC13783_IRQMASK1;
  209. u32 irqbit = 1 << (irq < 24 ? irq : irq - 24);
  210. u32 mask;
  211. if (irq < 0 || irq >= MC13783_NUM_IRQ)
  212. return -EINVAL;
  213. ret = mc13783_reg_read(mc13783, offmask, &mask);
  214. if (ret)
  215. return ret;
  216. if (!(mask & irqbit))
  217. /* already unmasked */
  218. return 0;
  219. return mc13783_reg_write(mc13783, offmask, mask & ~irqbit);
  220. }
  221. EXPORT_SYMBOL(mc13783_unmask);
  222. int mc13783_irq_request_nounmask(struct mc13783 *mc13783, int irq,
  223. irq_handler_t handler, const char *name, void *dev)
  224. {
  225. BUG_ON(!mutex_is_locked(&mc13783->lock));
  226. BUG_ON(!handler);
  227. if (irq < 0 || irq >= MC13783_NUM_IRQ)
  228. return -EINVAL;
  229. if (mc13783->irqhandler[irq])
  230. return -EBUSY;
  231. mc13783->irqhandler[irq] = handler;
  232. mc13783->irqdata[irq] = dev;
  233. return 0;
  234. }
  235. EXPORT_SYMBOL(mc13783_irq_request_nounmask);
  236. int mc13783_irq_request(struct mc13783 *mc13783, int irq,
  237. irq_handler_t handler, const char *name, void *dev)
  238. {
  239. int ret;
  240. ret = mc13783_irq_request_nounmask(mc13783, irq, handler, name, dev);
  241. if (ret)
  242. return ret;
  243. ret = mc13783_unmask(mc13783, irq);
  244. if (ret) {
  245. mc13783->irqhandler[irq] = NULL;
  246. mc13783->irqdata[irq] = NULL;
  247. return ret;
  248. }
  249. return 0;
  250. }
  251. EXPORT_SYMBOL(mc13783_irq_request);
  252. int mc13783_irq_free(struct mc13783 *mc13783, int irq, void *dev)
  253. {
  254. int ret;
  255. BUG_ON(!mutex_is_locked(&mc13783->lock));
  256. if (irq < 0 || irq >= MC13783_NUM_IRQ || !mc13783->irqhandler[irq] ||
  257. mc13783->irqdata[irq] != dev)
  258. return -EINVAL;
  259. ret = mc13783_mask(mc13783, irq);
  260. if (ret)
  261. return ret;
  262. mc13783->irqhandler[irq] = NULL;
  263. mc13783->irqdata[irq] = NULL;
  264. return 0;
  265. }
  266. EXPORT_SYMBOL(mc13783_irq_free);
  267. static inline irqreturn_t mc13783_irqhandler(struct mc13783 *mc13783, int irq)
  268. {
  269. return mc13783->irqhandler[irq](irq, mc13783->irqdata[irq]);
  270. }
  271. int mc13783_ackirq(struct mc13783 *mc13783, int irq)
  272. {
  273. unsigned int offstat = irq < 24 ? MC13783_IRQSTAT0 : MC13783_IRQSTAT1;
  274. unsigned int val = 1 << (irq < 24 ? irq : irq - 24);
  275. BUG_ON(irq < 0 || irq >= MC13783_NUM_IRQ);
  276. return mc13783_reg_write(mc13783, offstat, val);
  277. }
  278. EXPORT_SYMBOL(mc13783_ackirq);
  279. /*
  280. * returns: number of handled irqs or negative error
  281. * locking: holds mc13783->lock
  282. */
  283. static int mc13783_irq_handle(struct mc13783 *mc13783,
  284. unsigned int offstat, unsigned int offmask, int baseirq)
  285. {
  286. u32 stat, mask;
  287. int ret = mc13783_reg_read(mc13783, offstat, &stat);
  288. int num_handled = 0;
  289. if (ret)
  290. return ret;
  291. ret = mc13783_reg_read(mc13783, offmask, &mask);
  292. if (ret)
  293. return ret;
  294. while (stat & ~mask) {
  295. int irq = __ffs(stat & ~mask);
  296. stat &= ~(1 << irq);
  297. if (likely(mc13783->irqhandler[baseirq + irq])) {
  298. irqreturn_t handled;
  299. handled = mc13783_irqhandler(mc13783, baseirq + irq);
  300. if (handled == IRQ_HANDLED)
  301. num_handled++;
  302. } else {
  303. dev_err(&mc13783->spidev->dev,
  304. "BUG: irq %u but no handler\n",
  305. baseirq + irq);
  306. mask |= 1 << irq;
  307. ret = mc13783_reg_write(mc13783, offmask, mask);
  308. }
  309. }
  310. return num_handled;
  311. }
  312. static irqreturn_t mc13783_irq_thread(int irq, void *data)
  313. {
  314. struct mc13783 *mc13783 = data;
  315. irqreturn_t ret;
  316. int handled = 0;
  317. mc13783_lock(mc13783);
  318. ret = mc13783_irq_handle(mc13783, MC13783_IRQSTAT0,
  319. MC13783_IRQMASK0, MC13783_IRQ_ADCDONE);
  320. if (ret > 0)
  321. handled = 1;
  322. ret = mc13783_irq_handle(mc13783, MC13783_IRQSTAT1,
  323. MC13783_IRQMASK1, MC13783_IRQ_1HZ);
  324. if (ret > 0)
  325. handled = 1;
  326. mc13783_unlock(mc13783);
  327. return IRQ_RETVAL(handled);
  328. }
  329. #define MC13783_ADC1_CHAN0_SHIFT 5
  330. #define MC13783_ADC1_CHAN1_SHIFT 8
  331. struct mc13783_adcdone_data {
  332. struct mc13783 *mc13783;
  333. struct completion done;
  334. };
  335. static irqreturn_t mc13783_handler_adcdone(int irq, void *data)
  336. {
  337. struct mc13783_adcdone_data *adcdone_data = data;
  338. mc13783_ackirq(adcdone_data->mc13783, irq);
  339. complete_all(&adcdone_data->done);
  340. return IRQ_HANDLED;
  341. }
  342. #define MC13783_ADC_WORKING (1 << 16)
  343. int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
  344. unsigned int channel, unsigned int *sample)
  345. {
  346. u32 adc0, adc1, old_adc0;
  347. int i, ret;
  348. struct mc13783_adcdone_data adcdone_data = {
  349. .mc13783 = mc13783,
  350. };
  351. init_completion(&adcdone_data.done);
  352. dev_dbg(&mc13783->spidev->dev, "%s\n", __func__);
  353. mc13783_lock(mc13783);
  354. if (mc13783->flags & MC13783_ADC_WORKING) {
  355. ret = -EBUSY;
  356. goto out;
  357. }
  358. mc13783->flags |= MC13783_ADC_WORKING;
  359. mc13783_reg_read(mc13783, MC13783_ADC0, &old_adc0);
  360. adc0 = MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2;
  361. adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN | MC13783_ADC1_ASC;
  362. if (channel > 7)
  363. adc1 |= MC13783_ADC1_ADSEL;
  364. switch (mode) {
  365. case MC13783_ADC_MODE_TS:
  366. adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_TSMOD0 |
  367. MC13783_ADC0_TSMOD1;
  368. adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
  369. break;
  370. case MC13783_ADC_MODE_SINGLE_CHAN:
  371. adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
  372. adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT;
  373. adc1 |= MC13783_ADC1_RAND;
  374. break;
  375. case MC13783_ADC_MODE_MULT_CHAN:
  376. adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK;
  377. adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT;
  378. break;
  379. default:
  380. mc13783_unlock(mc13783);
  381. return -EINVAL;
  382. }
  383. dev_dbg(&mc13783->spidev->dev, "%s: request irq\n", __func__);
  384. mc13783_irq_request(mc13783, MC13783_IRQ_ADCDONE,
  385. mc13783_handler_adcdone, __func__, &adcdone_data);
  386. mc13783_ackirq(mc13783, MC13783_IRQ_ADCDONE);
  387. mc13783_reg_write(mc13783, MC13783_REG_ADC_0, adc0);
  388. mc13783_reg_write(mc13783, MC13783_REG_ADC_1, adc1);
  389. mc13783_unlock(mc13783);
  390. ret = wait_for_completion_interruptible_timeout(&adcdone_data.done, HZ);
  391. if (!ret)
  392. ret = -ETIMEDOUT;
  393. mc13783_lock(mc13783);
  394. mc13783_irq_free(mc13783, MC13783_IRQ_ADCDONE, &adcdone_data);
  395. if (ret > 0)
  396. for (i = 0; i < 4; ++i) {
  397. ret = mc13783_reg_read(mc13783,
  398. MC13783_REG_ADC_2, &sample[i]);
  399. if (ret)
  400. break;
  401. }
  402. if (mode == MC13783_ADC_MODE_TS)
  403. /* restore TSMOD */
  404. mc13783_reg_write(mc13783, MC13783_REG_ADC_0, old_adc0);
  405. mc13783->flags &= ~MC13783_ADC_WORKING;
  406. out:
  407. mc13783_unlock(mc13783);
  408. return ret;
  409. }
  410. EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion);
  411. static int mc13783_add_subdevice_pdata(struct mc13783 *mc13783,
  412. const char *name, void *pdata, size_t pdata_size)
  413. {
  414. struct mfd_cell cell = {
  415. .name = name,
  416. .platform_data = pdata,
  417. .data_size = pdata_size,
  418. };
  419. return mfd_add_devices(&mc13783->spidev->dev, -1, &cell, 1, NULL, 0);
  420. }
  421. static int mc13783_add_subdevice(struct mc13783 *mc13783, const char *name)
  422. {
  423. return mc13783_add_subdevice_pdata(mc13783, name, NULL, 0);
  424. }
  425. static int mc13783_check_revision(struct mc13783 *mc13783)
  426. {
  427. u32 rev_id, rev1, rev2, finid, icid;
  428. mc13783_reg_read(mc13783, MC13783_REG_REVISION, &rev_id);
  429. rev1 = (rev_id & 0x018) >> 3;
  430. rev2 = (rev_id & 0x007);
  431. icid = (rev_id & 0x01C0) >> 6;
  432. finid = (rev_id & 0x01E00) >> 9;
  433. /* Ver 0.2 is actually 3.2a. Report as 3.2 */
  434. if ((rev1 == 0) && (rev2 == 2))
  435. rev1 = 3;
  436. if (rev1 == 0 || icid != 2) {
  437. dev_err(&mc13783->spidev->dev, "No MC13783 detected.\n");
  438. return -ENODEV;
  439. }
  440. dev_info(&mc13783->spidev->dev,
  441. "MC13783 Rev %d.%d FinVer %x detected\n",
  442. rev1, rev2, finid);
  443. return 0;
  444. }
  445. static int mc13783_probe(struct spi_device *spi)
  446. {
  447. struct mc13783 *mc13783;
  448. struct mc13783_platform_data *pdata = dev_get_platdata(&spi->dev);
  449. int ret;
  450. mc13783 = kzalloc(sizeof(*mc13783), GFP_KERNEL);
  451. if (!mc13783)
  452. return -ENOMEM;
  453. dev_set_drvdata(&spi->dev, mc13783);
  454. spi->mode = SPI_MODE_0 | SPI_CS_HIGH;
  455. spi->bits_per_word = 32;
  456. spi_setup(spi);
  457. mc13783->spidev = spi;
  458. mutex_init(&mc13783->lock);
  459. mc13783_lock(mc13783);
  460. ret = mc13783_check_revision(mc13783);
  461. if (ret)
  462. goto err_revision;
  463. /* mask all irqs */
  464. ret = mc13783_reg_write(mc13783, MC13783_IRQMASK0, 0x00ffffff);
  465. if (ret)
  466. goto err_mask;
  467. ret = mc13783_reg_write(mc13783, MC13783_IRQMASK1, 0x00ffffff);
  468. if (ret)
  469. goto err_mask;
  470. ret = request_threaded_irq(spi->irq, NULL, mc13783_irq_thread,
  471. IRQF_ONESHOT | IRQF_TRIGGER_HIGH, "mc13783", mc13783);
  472. if (ret) {
  473. err_mask:
  474. err_revision:
  475. mutex_unlock(&mc13783->lock);
  476. dev_set_drvdata(&spi->dev, NULL);
  477. kfree(mc13783);
  478. return ret;
  479. }
  480. /* This should go away (BEGIN) */
  481. if (pdata) {
  482. mc13783->flags = pdata->flags;
  483. mc13783->regulators = pdata->regulators;
  484. mc13783->num_regulators = pdata->num_regulators;
  485. }
  486. /* This should go away (END) */
  487. if (pdata->flags & MC13783_USE_ADC)
  488. mc13783_add_subdevice(mc13783, "mc13783-adc");
  489. if (pdata->flags & MC13783_USE_CODEC)
  490. mc13783_add_subdevice(mc13783, "mc13783-codec");
  491. if (pdata->flags & MC13783_USE_REGULATOR) {
  492. struct mc13783_regulator_platform_data regulator_pdata = {
  493. .num_regulators = pdata->num_regulators,
  494. .regulators = pdata->regulators,
  495. };
  496. mc13783_add_subdevice_pdata(mc13783, "mc13783-regulator",
  497. &regulator_pdata, sizeof(regulator_pdata));
  498. }
  499. if (pdata->flags & MC13783_USE_RTC)
  500. mc13783_add_subdevice(mc13783, "mc13783-rtc");
  501. if (pdata->flags & MC13783_USE_TOUCHSCREEN)
  502. mc13783_add_subdevice(mc13783, "mc13783-ts");
  503. mc13783_unlock(mc13783);
  504. return 0;
  505. }
  506. static int __devexit mc13783_remove(struct spi_device *spi)
  507. {
  508. struct mc13783 *mc13783 = dev_get_drvdata(&spi->dev);
  509. free_irq(mc13783->spidev->irq, mc13783);
  510. mfd_remove_devices(&spi->dev);
  511. return 0;
  512. }
  513. static struct spi_driver mc13783_driver = {
  514. .driver = {
  515. .name = "mc13783",
  516. .bus = &spi_bus_type,
  517. .owner = THIS_MODULE,
  518. },
  519. .probe = mc13783_probe,
  520. .remove = __devexit_p(mc13783_remove),
  521. };
  522. static int __init mc13783_init(void)
  523. {
  524. return spi_register_driver(&mc13783_driver);
  525. }
  526. subsys_initcall(mc13783_init);
  527. static void __exit mc13783_exit(void)
  528. {
  529. spi_unregister_driver(&mc13783_driver);
  530. }
  531. module_exit(mc13783_exit);
  532. MODULE_DESCRIPTION("Core driver for Freescale MC13783 PMIC");
  533. MODULE_AUTHOR("Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>");
  534. MODULE_LICENSE("GPL v2");