wm831x-core.c 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940
  1. /*
  2. * wm831x-core.c -- Device access for Wolfson WM831x PMICs
  3. *
  4. * Copyright 2009 Wolfson Microelectronics PLC.
  5. *
  6. * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. *
  13. */
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/bcd.h>
  17. #include <linux/delay.h>
  18. #include <linux/mfd/core.h>
  19. #include <linux/slab.h>
  20. #include <linux/err.h>
  21. #include <linux/mfd/wm831x/core.h>
  22. #include <linux/mfd/wm831x/pdata.h>
  23. #include <linux/mfd/wm831x/irq.h>
  24. #include <linux/mfd/wm831x/auxadc.h>
  25. #include <linux/mfd/wm831x/otp.h>
  26. #include <linux/mfd/wm831x/pmu.h>
  27. #include <linux/mfd/wm831x/regulator.h>
  28. /* Current settings - values are 2*2^(reg_val/4) microamps. These are
  29. * exported since they are used by multiple drivers.
  30. */
  31. int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
  32. 2,
  33. 2,
  34. 3,
  35. 3,
  36. 4,
  37. 5,
  38. 6,
  39. 7,
  40. 8,
  41. 10,
  42. 11,
  43. 13,
  44. 16,
  45. 19,
  46. 23,
  47. 27,
  48. 32,
  49. 38,
  50. 45,
  51. 54,
  52. 64,
  53. 76,
  54. 91,
  55. 108,
  56. 128,
  57. 152,
  58. 181,
  59. 215,
  60. 256,
  61. 304,
  62. 362,
  63. 431,
  64. 512,
  65. 609,
  66. 724,
  67. 861,
  68. 1024,
  69. 1218,
  70. 1448,
  71. 1722,
  72. 2048,
  73. 2435,
  74. 2896,
  75. 3444,
  76. 4096,
  77. 4871,
  78. 5793,
  79. 6889,
  80. 8192,
  81. 9742,
  82. 11585,
  83. 13777,
  84. 16384,
  85. 19484,
  86. 23170,
  87. 27554,
  88. };
  89. EXPORT_SYMBOL_GPL(wm831x_isinkv_values);
  90. static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
  91. {
  92. if (!wm831x->locked)
  93. return 0;
  94. switch (reg) {
  95. case WM831X_WATCHDOG:
  96. case WM831X_DC4_CONTROL:
  97. case WM831X_ON_PIN_CONTROL:
  98. case WM831X_BACKUP_CHARGER_CONTROL:
  99. case WM831X_CHARGER_CONTROL_1:
  100. case WM831X_CHARGER_CONTROL_2:
  101. return 1;
  102. default:
  103. return 0;
  104. }
  105. }
  106. /**
  107. * wm831x_reg_unlock: Unlock user keyed registers
  108. *
  109. * The WM831x has a user key preventing writes to particularly
  110. * critical registers. This function locks those registers,
  111. * allowing writes to them.
  112. */
  113. void wm831x_reg_lock(struct wm831x *wm831x)
  114. {
  115. int ret;
  116. ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
  117. if (ret == 0) {
  118. dev_vdbg(wm831x->dev, "Registers locked\n");
  119. mutex_lock(&wm831x->io_lock);
  120. WARN_ON(wm831x->locked);
  121. wm831x->locked = 1;
  122. mutex_unlock(&wm831x->io_lock);
  123. } else {
  124. dev_err(wm831x->dev, "Failed to lock registers: %d\n", ret);
  125. }
  126. }
  127. EXPORT_SYMBOL_GPL(wm831x_reg_lock);
  128. /**
  129. * wm831x_reg_unlock: Unlock user keyed registers
  130. *
  131. * The WM831x has a user key preventing writes to particularly
  132. * critical registers. This function locks those registers,
  133. * preventing spurious writes.
  134. */
  135. int wm831x_reg_unlock(struct wm831x *wm831x)
  136. {
  137. int ret;
  138. /* 0x9716 is the value required to unlock the registers */
  139. ret = wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0x9716);
  140. if (ret == 0) {
  141. dev_vdbg(wm831x->dev, "Registers unlocked\n");
  142. mutex_lock(&wm831x->io_lock);
  143. WARN_ON(!wm831x->locked);
  144. wm831x->locked = 0;
  145. mutex_unlock(&wm831x->io_lock);
  146. }
  147. return ret;
  148. }
  149. EXPORT_SYMBOL_GPL(wm831x_reg_unlock);
  150. static bool wm831x_reg_readable(struct device *dev, unsigned int reg)
  151. {
  152. switch (reg) {
  153. case WM831X_RESET_ID:
  154. case WM831X_REVISION:
  155. case WM831X_PARENT_ID:
  156. case WM831X_SYSVDD_CONTROL:
  157. case WM831X_THERMAL_MONITORING:
  158. case WM831X_POWER_STATE:
  159. case WM831X_WATCHDOG:
  160. case WM831X_ON_PIN_CONTROL:
  161. case WM831X_RESET_CONTROL:
  162. case WM831X_CONTROL_INTERFACE:
  163. case WM831X_SECURITY_KEY:
  164. case WM831X_SOFTWARE_SCRATCH:
  165. case WM831X_OTP_CONTROL:
  166. case WM831X_GPIO_LEVEL:
  167. case WM831X_SYSTEM_STATUS:
  168. case WM831X_ON_SOURCE:
  169. case WM831X_OFF_SOURCE:
  170. case WM831X_SYSTEM_INTERRUPTS:
  171. case WM831X_INTERRUPT_STATUS_1:
  172. case WM831X_INTERRUPT_STATUS_2:
  173. case WM831X_INTERRUPT_STATUS_3:
  174. case WM831X_INTERRUPT_STATUS_4:
  175. case WM831X_INTERRUPT_STATUS_5:
  176. case WM831X_IRQ_CONFIG:
  177. case WM831X_SYSTEM_INTERRUPTS_MASK:
  178. case WM831X_INTERRUPT_STATUS_1_MASK:
  179. case WM831X_INTERRUPT_STATUS_2_MASK:
  180. case WM831X_INTERRUPT_STATUS_3_MASK:
  181. case WM831X_INTERRUPT_STATUS_4_MASK:
  182. case WM831X_INTERRUPT_STATUS_5_MASK:
  183. case WM831X_RTC_WRITE_COUNTER:
  184. case WM831X_RTC_TIME_1:
  185. case WM831X_RTC_TIME_2:
  186. case WM831X_RTC_ALARM_1:
  187. case WM831X_RTC_ALARM_2:
  188. case WM831X_RTC_CONTROL:
  189. case WM831X_RTC_TRIM:
  190. case WM831X_TOUCH_CONTROL_1:
  191. case WM831X_TOUCH_CONTROL_2:
  192. case WM831X_TOUCH_DATA_X:
  193. case WM831X_TOUCH_DATA_Y:
  194. case WM831X_TOUCH_DATA_Z:
  195. case WM831X_AUXADC_DATA:
  196. case WM831X_AUXADC_CONTROL:
  197. case WM831X_AUXADC_SOURCE:
  198. case WM831X_COMPARATOR_CONTROL:
  199. case WM831X_COMPARATOR_1:
  200. case WM831X_COMPARATOR_2:
  201. case WM831X_COMPARATOR_3:
  202. case WM831X_COMPARATOR_4:
  203. case WM831X_GPIO1_CONTROL:
  204. case WM831X_GPIO2_CONTROL:
  205. case WM831X_GPIO3_CONTROL:
  206. case WM831X_GPIO4_CONTROL:
  207. case WM831X_GPIO5_CONTROL:
  208. case WM831X_GPIO6_CONTROL:
  209. case WM831X_GPIO7_CONTROL:
  210. case WM831X_GPIO8_CONTROL:
  211. case WM831X_GPIO9_CONTROL:
  212. case WM831X_GPIO10_CONTROL:
  213. case WM831X_GPIO11_CONTROL:
  214. case WM831X_GPIO12_CONTROL:
  215. case WM831X_GPIO13_CONTROL:
  216. case WM831X_GPIO14_CONTROL:
  217. case WM831X_GPIO15_CONTROL:
  218. case WM831X_GPIO16_CONTROL:
  219. case WM831X_CHARGER_CONTROL_1:
  220. case WM831X_CHARGER_CONTROL_2:
  221. case WM831X_CHARGER_STATUS:
  222. case WM831X_BACKUP_CHARGER_CONTROL:
  223. case WM831X_STATUS_LED_1:
  224. case WM831X_STATUS_LED_2:
  225. case WM831X_CURRENT_SINK_1:
  226. case WM831X_CURRENT_SINK_2:
  227. case WM831X_DCDC_ENABLE:
  228. case WM831X_LDO_ENABLE:
  229. case WM831X_DCDC_STATUS:
  230. case WM831X_LDO_STATUS:
  231. case WM831X_DCDC_UV_STATUS:
  232. case WM831X_LDO_UV_STATUS:
  233. case WM831X_DC1_CONTROL_1:
  234. case WM831X_DC1_CONTROL_2:
  235. case WM831X_DC1_ON_CONFIG:
  236. case WM831X_DC1_SLEEP_CONTROL:
  237. case WM831X_DC1_DVS_CONTROL:
  238. case WM831X_DC2_CONTROL_1:
  239. case WM831X_DC2_CONTROL_2:
  240. case WM831X_DC2_ON_CONFIG:
  241. case WM831X_DC2_SLEEP_CONTROL:
  242. case WM831X_DC2_DVS_CONTROL:
  243. case WM831X_DC3_CONTROL_1:
  244. case WM831X_DC3_CONTROL_2:
  245. case WM831X_DC3_ON_CONFIG:
  246. case WM831X_DC3_SLEEP_CONTROL:
  247. case WM831X_DC4_CONTROL:
  248. case WM831X_DC4_SLEEP_CONTROL:
  249. case WM831X_EPE1_CONTROL:
  250. case WM831X_EPE2_CONTROL:
  251. case WM831X_LDO1_CONTROL:
  252. case WM831X_LDO1_ON_CONTROL:
  253. case WM831X_LDO1_SLEEP_CONTROL:
  254. case WM831X_LDO2_CONTROL:
  255. case WM831X_LDO2_ON_CONTROL:
  256. case WM831X_LDO2_SLEEP_CONTROL:
  257. case WM831X_LDO3_CONTROL:
  258. case WM831X_LDO3_ON_CONTROL:
  259. case WM831X_LDO3_SLEEP_CONTROL:
  260. case WM831X_LDO4_CONTROL:
  261. case WM831X_LDO4_ON_CONTROL:
  262. case WM831X_LDO4_SLEEP_CONTROL:
  263. case WM831X_LDO5_CONTROL:
  264. case WM831X_LDO5_ON_CONTROL:
  265. case WM831X_LDO5_SLEEP_CONTROL:
  266. case WM831X_LDO6_CONTROL:
  267. case WM831X_LDO6_ON_CONTROL:
  268. case WM831X_LDO6_SLEEP_CONTROL:
  269. case WM831X_LDO7_CONTROL:
  270. case WM831X_LDO7_ON_CONTROL:
  271. case WM831X_LDO7_SLEEP_CONTROL:
  272. case WM831X_LDO8_CONTROL:
  273. case WM831X_LDO8_ON_CONTROL:
  274. case WM831X_LDO8_SLEEP_CONTROL:
  275. case WM831X_LDO9_CONTROL:
  276. case WM831X_LDO9_ON_CONTROL:
  277. case WM831X_LDO9_SLEEP_CONTROL:
  278. case WM831X_LDO10_CONTROL:
  279. case WM831X_LDO10_ON_CONTROL:
  280. case WM831X_LDO10_SLEEP_CONTROL:
  281. case WM831X_LDO11_ON_CONTROL:
  282. case WM831X_LDO11_SLEEP_CONTROL:
  283. case WM831X_POWER_GOOD_SOURCE_1:
  284. case WM831X_POWER_GOOD_SOURCE_2:
  285. case WM831X_CLOCK_CONTROL_1:
  286. case WM831X_CLOCK_CONTROL_2:
  287. case WM831X_FLL_CONTROL_1:
  288. case WM831X_FLL_CONTROL_2:
  289. case WM831X_FLL_CONTROL_3:
  290. case WM831X_FLL_CONTROL_4:
  291. case WM831X_FLL_CONTROL_5:
  292. case WM831X_UNIQUE_ID_1:
  293. case WM831X_UNIQUE_ID_2:
  294. case WM831X_UNIQUE_ID_3:
  295. case WM831X_UNIQUE_ID_4:
  296. case WM831X_UNIQUE_ID_5:
  297. case WM831X_UNIQUE_ID_6:
  298. case WM831X_UNIQUE_ID_7:
  299. case WM831X_UNIQUE_ID_8:
  300. case WM831X_FACTORY_OTP_ID:
  301. case WM831X_FACTORY_OTP_1:
  302. case WM831X_FACTORY_OTP_2:
  303. case WM831X_FACTORY_OTP_3:
  304. case WM831X_FACTORY_OTP_4:
  305. case WM831X_FACTORY_OTP_5:
  306. case WM831X_CUSTOMER_OTP_ID:
  307. case WM831X_DC1_OTP_CONTROL:
  308. case WM831X_DC2_OTP_CONTROL:
  309. case WM831X_DC3_OTP_CONTROL:
  310. case WM831X_LDO1_2_OTP_CONTROL:
  311. case WM831X_LDO3_4_OTP_CONTROL:
  312. case WM831X_LDO5_6_OTP_CONTROL:
  313. case WM831X_LDO7_8_OTP_CONTROL:
  314. case WM831X_LDO9_10_OTP_CONTROL:
  315. case WM831X_LDO11_EPE_CONTROL:
  316. case WM831X_GPIO1_OTP_CONTROL:
  317. case WM831X_GPIO2_OTP_CONTROL:
  318. case WM831X_GPIO3_OTP_CONTROL:
  319. case WM831X_GPIO4_OTP_CONTROL:
  320. case WM831X_GPIO5_OTP_CONTROL:
  321. case WM831X_GPIO6_OTP_CONTROL:
  322. case WM831X_DBE_CHECK_DATA:
  323. return true;
  324. default:
  325. return false;
  326. }
  327. }
  328. static bool wm831x_reg_writeable(struct device *dev, unsigned int reg)
  329. {
  330. struct wm831x *wm831x = dev_get_drvdata(dev);
  331. if (wm831x_reg_locked(wm831x, reg))
  332. return false;
  333. switch (reg) {
  334. case WM831X_SYSVDD_CONTROL:
  335. case WM831X_THERMAL_MONITORING:
  336. case WM831X_POWER_STATE:
  337. case WM831X_WATCHDOG:
  338. case WM831X_ON_PIN_CONTROL:
  339. case WM831X_RESET_CONTROL:
  340. case WM831X_CONTROL_INTERFACE:
  341. case WM831X_SECURITY_KEY:
  342. case WM831X_SOFTWARE_SCRATCH:
  343. case WM831X_OTP_CONTROL:
  344. case WM831X_GPIO_LEVEL:
  345. case WM831X_INTERRUPT_STATUS_1:
  346. case WM831X_INTERRUPT_STATUS_2:
  347. case WM831X_INTERRUPT_STATUS_3:
  348. case WM831X_INTERRUPT_STATUS_4:
  349. case WM831X_INTERRUPT_STATUS_5:
  350. case WM831X_IRQ_CONFIG:
  351. case WM831X_SYSTEM_INTERRUPTS_MASK:
  352. case WM831X_INTERRUPT_STATUS_1_MASK:
  353. case WM831X_INTERRUPT_STATUS_2_MASK:
  354. case WM831X_INTERRUPT_STATUS_3_MASK:
  355. case WM831X_INTERRUPT_STATUS_4_MASK:
  356. case WM831X_INTERRUPT_STATUS_5_MASK:
  357. case WM831X_RTC_TIME_1:
  358. case WM831X_RTC_TIME_2:
  359. case WM831X_RTC_ALARM_1:
  360. case WM831X_RTC_ALARM_2:
  361. case WM831X_RTC_CONTROL:
  362. case WM831X_RTC_TRIM:
  363. case WM831X_TOUCH_CONTROL_1:
  364. case WM831X_TOUCH_CONTROL_2:
  365. case WM831X_AUXADC_CONTROL:
  366. case WM831X_AUXADC_SOURCE:
  367. case WM831X_COMPARATOR_CONTROL:
  368. case WM831X_COMPARATOR_1:
  369. case WM831X_COMPARATOR_2:
  370. case WM831X_COMPARATOR_3:
  371. case WM831X_COMPARATOR_4:
  372. case WM831X_GPIO1_CONTROL:
  373. case WM831X_GPIO2_CONTROL:
  374. case WM831X_GPIO3_CONTROL:
  375. case WM831X_GPIO4_CONTROL:
  376. case WM831X_GPIO5_CONTROL:
  377. case WM831X_GPIO6_CONTROL:
  378. case WM831X_GPIO7_CONTROL:
  379. case WM831X_GPIO8_CONTROL:
  380. case WM831X_GPIO9_CONTROL:
  381. case WM831X_GPIO10_CONTROL:
  382. case WM831X_GPIO11_CONTROL:
  383. case WM831X_GPIO12_CONTROL:
  384. case WM831X_GPIO13_CONTROL:
  385. case WM831X_GPIO14_CONTROL:
  386. case WM831X_GPIO15_CONTROL:
  387. case WM831X_GPIO16_CONTROL:
  388. case WM831X_CHARGER_CONTROL_1:
  389. case WM831X_CHARGER_CONTROL_2:
  390. case WM831X_CHARGER_STATUS:
  391. case WM831X_BACKUP_CHARGER_CONTROL:
  392. case WM831X_STATUS_LED_1:
  393. case WM831X_STATUS_LED_2:
  394. case WM831X_CURRENT_SINK_1:
  395. case WM831X_CURRENT_SINK_2:
  396. case WM831X_DCDC_ENABLE:
  397. case WM831X_LDO_ENABLE:
  398. case WM831X_DC1_CONTROL_1:
  399. case WM831X_DC1_CONTROL_2:
  400. case WM831X_DC1_ON_CONFIG:
  401. case WM831X_DC1_SLEEP_CONTROL:
  402. case WM831X_DC1_DVS_CONTROL:
  403. case WM831X_DC2_CONTROL_1:
  404. case WM831X_DC2_CONTROL_2:
  405. case WM831X_DC2_ON_CONFIG:
  406. case WM831X_DC2_SLEEP_CONTROL:
  407. case WM831X_DC2_DVS_CONTROL:
  408. case WM831X_DC3_CONTROL_1:
  409. case WM831X_DC3_CONTROL_2:
  410. case WM831X_DC3_ON_CONFIG:
  411. case WM831X_DC3_SLEEP_CONTROL:
  412. case WM831X_DC4_CONTROL:
  413. case WM831X_DC4_SLEEP_CONTROL:
  414. case WM831X_EPE1_CONTROL:
  415. case WM831X_EPE2_CONTROL:
  416. case WM831X_LDO1_CONTROL:
  417. case WM831X_LDO1_ON_CONTROL:
  418. case WM831X_LDO1_SLEEP_CONTROL:
  419. case WM831X_LDO2_CONTROL:
  420. case WM831X_LDO2_ON_CONTROL:
  421. case WM831X_LDO2_SLEEP_CONTROL:
  422. case WM831X_LDO3_CONTROL:
  423. case WM831X_LDO3_ON_CONTROL:
  424. case WM831X_LDO3_SLEEP_CONTROL:
  425. case WM831X_LDO4_CONTROL:
  426. case WM831X_LDO4_ON_CONTROL:
  427. case WM831X_LDO4_SLEEP_CONTROL:
  428. case WM831X_LDO5_CONTROL:
  429. case WM831X_LDO5_ON_CONTROL:
  430. case WM831X_LDO5_SLEEP_CONTROL:
  431. case WM831X_LDO6_CONTROL:
  432. case WM831X_LDO6_ON_CONTROL:
  433. case WM831X_LDO6_SLEEP_CONTROL:
  434. case WM831X_LDO7_CONTROL:
  435. case WM831X_LDO7_ON_CONTROL:
  436. case WM831X_LDO7_SLEEP_CONTROL:
  437. case WM831X_LDO8_CONTROL:
  438. case WM831X_LDO8_ON_CONTROL:
  439. case WM831X_LDO8_SLEEP_CONTROL:
  440. case WM831X_LDO9_CONTROL:
  441. case WM831X_LDO9_ON_CONTROL:
  442. case WM831X_LDO9_SLEEP_CONTROL:
  443. case WM831X_LDO10_CONTROL:
  444. case WM831X_LDO10_ON_CONTROL:
  445. case WM831X_LDO10_SLEEP_CONTROL:
  446. case WM831X_LDO11_ON_CONTROL:
  447. case WM831X_LDO11_SLEEP_CONTROL:
  448. case WM831X_POWER_GOOD_SOURCE_1:
  449. case WM831X_POWER_GOOD_SOURCE_2:
  450. case WM831X_CLOCK_CONTROL_1:
  451. case WM831X_CLOCK_CONTROL_2:
  452. case WM831X_FLL_CONTROL_1:
  453. case WM831X_FLL_CONTROL_2:
  454. case WM831X_FLL_CONTROL_3:
  455. case WM831X_FLL_CONTROL_4:
  456. case WM831X_FLL_CONTROL_5:
  457. return true;
  458. default:
  459. return false;
  460. }
  461. }
  462. static bool wm831x_reg_volatile(struct device *dev, unsigned int reg)
  463. {
  464. switch (reg) {
  465. case WM831X_SYSTEM_STATUS:
  466. case WM831X_ON_SOURCE:
  467. case WM831X_OFF_SOURCE:
  468. case WM831X_GPIO_LEVEL:
  469. case WM831X_SYSTEM_INTERRUPTS:
  470. case WM831X_INTERRUPT_STATUS_1:
  471. case WM831X_INTERRUPT_STATUS_2:
  472. case WM831X_INTERRUPT_STATUS_3:
  473. case WM831X_INTERRUPT_STATUS_4:
  474. case WM831X_INTERRUPT_STATUS_5:
  475. case WM831X_RTC_TIME_1:
  476. case WM831X_RTC_TIME_2:
  477. case WM831X_TOUCH_DATA_X:
  478. case WM831X_TOUCH_DATA_Y:
  479. case WM831X_TOUCH_DATA_Z:
  480. case WM831X_AUXADC_DATA:
  481. case WM831X_CHARGER_STATUS:
  482. case WM831X_DCDC_STATUS:
  483. case WM831X_LDO_STATUS:
  484. case WM831X_DCDC_UV_STATUS:
  485. case WM831X_LDO_UV_STATUS:
  486. return true;
  487. default:
  488. return false;
  489. }
  490. }
  491. /**
  492. * wm831x_reg_read: Read a single WM831x register.
  493. *
  494. * @wm831x: Device to read from.
  495. * @reg: Register to read.
  496. */
  497. int wm831x_reg_read(struct wm831x *wm831x, unsigned short reg)
  498. {
  499. unsigned int val;
  500. int ret;
  501. ret = regmap_read(wm831x->regmap, reg, &val);
  502. if (ret < 0)
  503. return ret;
  504. else
  505. return val;
  506. }
  507. EXPORT_SYMBOL_GPL(wm831x_reg_read);
  508. /**
  509. * wm831x_bulk_read: Read multiple WM831x registers
  510. *
  511. * @wm831x: Device to read from
  512. * @reg: First register
  513. * @count: Number of registers
  514. * @buf: Buffer to fill.
  515. */
  516. int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
  517. int count, u16 *buf)
  518. {
  519. return regmap_bulk_read(wm831x->regmap, reg, buf, count);
  520. }
  521. EXPORT_SYMBOL_GPL(wm831x_bulk_read);
  522. static int wm831x_write(struct wm831x *wm831x, unsigned short reg,
  523. int bytes, void *src)
  524. {
  525. u16 *buf = src;
  526. int i, ret;
  527. BUG_ON(bytes % 2);
  528. BUG_ON(bytes <= 0);
  529. for (i = 0; i < bytes / 2; i++) {
  530. if (wm831x_reg_locked(wm831x, reg))
  531. return -EPERM;
  532. dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n",
  533. buf[i], reg + i, reg + i);
  534. ret = regmap_write(wm831x->regmap, reg + i, buf[i]);
  535. }
  536. return 0;
  537. }
  538. /**
  539. * wm831x_reg_write: Write a single WM831x register.
  540. *
  541. * @wm831x: Device to write to.
  542. * @reg: Register to write to.
  543. * @val: Value to write.
  544. */
  545. int wm831x_reg_write(struct wm831x *wm831x, unsigned short reg,
  546. unsigned short val)
  547. {
  548. int ret;
  549. mutex_lock(&wm831x->io_lock);
  550. ret = wm831x_write(wm831x, reg, 2, &val);
  551. mutex_unlock(&wm831x->io_lock);
  552. return ret;
  553. }
  554. EXPORT_SYMBOL_GPL(wm831x_reg_write);
  555. /**
  556. * wm831x_set_bits: Set the value of a bitfield in a WM831x register
  557. *
  558. * @wm831x: Device to write to.
  559. * @reg: Register to write to.
  560. * @mask: Mask of bits to set.
  561. * @val: Value to set (unshifted)
  562. */
  563. int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
  564. unsigned short mask, unsigned short val)
  565. {
  566. int ret;
  567. mutex_lock(&wm831x->io_lock);
  568. if (!wm831x_reg_locked(wm831x, reg))
  569. ret = regmap_update_bits(wm831x->regmap, reg, mask, val);
  570. else
  571. ret = -EPERM;
  572. mutex_unlock(&wm831x->io_lock);
  573. return ret;
  574. }
  575. EXPORT_SYMBOL_GPL(wm831x_set_bits);
  576. static struct resource wm831x_dcdc1_resources[] = {
  577. {
  578. .start = WM831X_DC1_CONTROL_1,
  579. .end = WM831X_DC1_DVS_CONTROL,
  580. .flags = IORESOURCE_IO,
  581. },
  582. {
  583. .name = "UV",
  584. .start = WM831X_IRQ_UV_DC1,
  585. .end = WM831X_IRQ_UV_DC1,
  586. .flags = IORESOURCE_IRQ,
  587. },
  588. {
  589. .name = "HC",
  590. .start = WM831X_IRQ_HC_DC1,
  591. .end = WM831X_IRQ_HC_DC1,
  592. .flags = IORESOURCE_IRQ,
  593. },
  594. };
  595. static struct resource wm831x_dcdc2_resources[] = {
  596. {
  597. .start = WM831X_DC2_CONTROL_1,
  598. .end = WM831X_DC2_DVS_CONTROL,
  599. .flags = IORESOURCE_IO,
  600. },
  601. {
  602. .name = "UV",
  603. .start = WM831X_IRQ_UV_DC2,
  604. .end = WM831X_IRQ_UV_DC2,
  605. .flags = IORESOURCE_IRQ,
  606. },
  607. {
  608. .name = "HC",
  609. .start = WM831X_IRQ_HC_DC2,
  610. .end = WM831X_IRQ_HC_DC2,
  611. .flags = IORESOURCE_IRQ,
  612. },
  613. };
  614. static struct resource wm831x_dcdc3_resources[] = {
  615. {
  616. .start = WM831X_DC3_CONTROL_1,
  617. .end = WM831X_DC3_SLEEP_CONTROL,
  618. .flags = IORESOURCE_IO,
  619. },
  620. {
  621. .name = "UV",
  622. .start = WM831X_IRQ_UV_DC3,
  623. .end = WM831X_IRQ_UV_DC3,
  624. .flags = IORESOURCE_IRQ,
  625. },
  626. };
  627. static struct resource wm831x_dcdc4_resources[] = {
  628. {
  629. .start = WM831X_DC4_CONTROL,
  630. .end = WM831X_DC4_SLEEP_CONTROL,
  631. .flags = IORESOURCE_IO,
  632. },
  633. {
  634. .name = "UV",
  635. .start = WM831X_IRQ_UV_DC4,
  636. .end = WM831X_IRQ_UV_DC4,
  637. .flags = IORESOURCE_IRQ,
  638. },
  639. };
  640. static struct resource wm8320_dcdc4_buck_resources[] = {
  641. {
  642. .start = WM831X_DC4_CONTROL,
  643. .end = WM832X_DC4_SLEEP_CONTROL,
  644. .flags = IORESOURCE_IO,
  645. },
  646. {
  647. .name = "UV",
  648. .start = WM831X_IRQ_UV_DC4,
  649. .end = WM831X_IRQ_UV_DC4,
  650. .flags = IORESOURCE_IRQ,
  651. },
  652. };
  653. static struct resource wm831x_gpio_resources[] = {
  654. {
  655. .start = WM831X_IRQ_GPIO_1,
  656. .end = WM831X_IRQ_GPIO_16,
  657. .flags = IORESOURCE_IRQ,
  658. },
  659. };
  660. static struct resource wm831x_isink1_resources[] = {
  661. {
  662. .start = WM831X_CURRENT_SINK_1,
  663. .end = WM831X_CURRENT_SINK_1,
  664. .flags = IORESOURCE_IO,
  665. },
  666. {
  667. .start = WM831X_IRQ_CS1,
  668. .end = WM831X_IRQ_CS1,
  669. .flags = IORESOURCE_IRQ,
  670. },
  671. };
  672. static struct resource wm831x_isink2_resources[] = {
  673. {
  674. .start = WM831X_CURRENT_SINK_2,
  675. .end = WM831X_CURRENT_SINK_2,
  676. .flags = IORESOURCE_IO,
  677. },
  678. {
  679. .start = WM831X_IRQ_CS2,
  680. .end = WM831X_IRQ_CS2,
  681. .flags = IORESOURCE_IRQ,
  682. },
  683. };
  684. static struct resource wm831x_ldo1_resources[] = {
  685. {
  686. .start = WM831X_LDO1_CONTROL,
  687. .end = WM831X_LDO1_SLEEP_CONTROL,
  688. .flags = IORESOURCE_IO,
  689. },
  690. {
  691. .name = "UV",
  692. .start = WM831X_IRQ_UV_LDO1,
  693. .end = WM831X_IRQ_UV_LDO1,
  694. .flags = IORESOURCE_IRQ,
  695. },
  696. };
  697. static struct resource wm831x_ldo2_resources[] = {
  698. {
  699. .start = WM831X_LDO2_CONTROL,
  700. .end = WM831X_LDO2_SLEEP_CONTROL,
  701. .flags = IORESOURCE_IO,
  702. },
  703. {
  704. .name = "UV",
  705. .start = WM831X_IRQ_UV_LDO2,
  706. .end = WM831X_IRQ_UV_LDO2,
  707. .flags = IORESOURCE_IRQ,
  708. },
  709. };
  710. static struct resource wm831x_ldo3_resources[] = {
  711. {
  712. .start = WM831X_LDO3_CONTROL,
  713. .end = WM831X_LDO3_SLEEP_CONTROL,
  714. .flags = IORESOURCE_IO,
  715. },
  716. {
  717. .name = "UV",
  718. .start = WM831X_IRQ_UV_LDO3,
  719. .end = WM831X_IRQ_UV_LDO3,
  720. .flags = IORESOURCE_IRQ,
  721. },
  722. };
  723. static struct resource wm831x_ldo4_resources[] = {
  724. {
  725. .start = WM831X_LDO4_CONTROL,
  726. .end = WM831X_LDO4_SLEEP_CONTROL,
  727. .flags = IORESOURCE_IO,
  728. },
  729. {
  730. .name = "UV",
  731. .start = WM831X_IRQ_UV_LDO4,
  732. .end = WM831X_IRQ_UV_LDO4,
  733. .flags = IORESOURCE_IRQ,
  734. },
  735. };
  736. static struct resource wm831x_ldo5_resources[] = {
  737. {
  738. .start = WM831X_LDO5_CONTROL,
  739. .end = WM831X_LDO5_SLEEP_CONTROL,
  740. .flags = IORESOURCE_IO,
  741. },
  742. {
  743. .name = "UV",
  744. .start = WM831X_IRQ_UV_LDO5,
  745. .end = WM831X_IRQ_UV_LDO5,
  746. .flags = IORESOURCE_IRQ,
  747. },
  748. };
  749. static struct resource wm831x_ldo6_resources[] = {
  750. {
  751. .start = WM831X_LDO6_CONTROL,
  752. .end = WM831X_LDO6_SLEEP_CONTROL,
  753. .flags = IORESOURCE_IO,
  754. },
  755. {
  756. .name = "UV",
  757. .start = WM831X_IRQ_UV_LDO6,
  758. .end = WM831X_IRQ_UV_LDO6,
  759. .flags = IORESOURCE_IRQ,
  760. },
  761. };
  762. static struct resource wm831x_ldo7_resources[] = {
  763. {
  764. .start = WM831X_LDO7_CONTROL,
  765. .end = WM831X_LDO7_SLEEP_CONTROL,
  766. .flags = IORESOURCE_IO,
  767. },
  768. {
  769. .name = "UV",
  770. .start = WM831X_IRQ_UV_LDO7,
  771. .end = WM831X_IRQ_UV_LDO7,
  772. .flags = IORESOURCE_IRQ,
  773. },
  774. };
  775. static struct resource wm831x_ldo8_resources[] = {
  776. {
  777. .start = WM831X_LDO8_CONTROL,
  778. .end = WM831X_LDO8_SLEEP_CONTROL,
  779. .flags = IORESOURCE_IO,
  780. },
  781. {
  782. .name = "UV",
  783. .start = WM831X_IRQ_UV_LDO8,
  784. .end = WM831X_IRQ_UV_LDO8,
  785. .flags = IORESOURCE_IRQ,
  786. },
  787. };
  788. static struct resource wm831x_ldo9_resources[] = {
  789. {
  790. .start = WM831X_LDO9_CONTROL,
  791. .end = WM831X_LDO9_SLEEP_CONTROL,
  792. .flags = IORESOURCE_IO,
  793. },
  794. {
  795. .name = "UV",
  796. .start = WM831X_IRQ_UV_LDO9,
  797. .end = WM831X_IRQ_UV_LDO9,
  798. .flags = IORESOURCE_IRQ,
  799. },
  800. };
  801. static struct resource wm831x_ldo10_resources[] = {
  802. {
  803. .start = WM831X_LDO10_CONTROL,
  804. .end = WM831X_LDO10_SLEEP_CONTROL,
  805. .flags = IORESOURCE_IO,
  806. },
  807. {
  808. .name = "UV",
  809. .start = WM831X_IRQ_UV_LDO10,
  810. .end = WM831X_IRQ_UV_LDO10,
  811. .flags = IORESOURCE_IRQ,
  812. },
  813. };
  814. static struct resource wm831x_ldo11_resources[] = {
  815. {
  816. .start = WM831X_LDO11_ON_CONTROL,
  817. .end = WM831X_LDO11_SLEEP_CONTROL,
  818. .flags = IORESOURCE_IO,
  819. },
  820. };
  821. static struct resource wm831x_on_resources[] = {
  822. {
  823. .start = WM831X_IRQ_ON,
  824. .end = WM831X_IRQ_ON,
  825. .flags = IORESOURCE_IRQ,
  826. },
  827. };
  828. static struct resource wm831x_power_resources[] = {
  829. {
  830. .name = "SYSLO",
  831. .start = WM831X_IRQ_PPM_SYSLO,
  832. .end = WM831X_IRQ_PPM_SYSLO,
  833. .flags = IORESOURCE_IRQ,
  834. },
  835. {
  836. .name = "PWR SRC",
  837. .start = WM831X_IRQ_PPM_PWR_SRC,
  838. .end = WM831X_IRQ_PPM_PWR_SRC,
  839. .flags = IORESOURCE_IRQ,
  840. },
  841. {
  842. .name = "USB CURR",
  843. .start = WM831X_IRQ_PPM_USB_CURR,
  844. .end = WM831X_IRQ_PPM_USB_CURR,
  845. .flags = IORESOURCE_IRQ,
  846. },
  847. {
  848. .name = "BATT HOT",
  849. .start = WM831X_IRQ_CHG_BATT_HOT,
  850. .end = WM831X_IRQ_CHG_BATT_HOT,
  851. .flags = IORESOURCE_IRQ,
  852. },
  853. {
  854. .name = "BATT COLD",
  855. .start = WM831X_IRQ_CHG_BATT_COLD,
  856. .end = WM831X_IRQ_CHG_BATT_COLD,
  857. .flags = IORESOURCE_IRQ,
  858. },
  859. {
  860. .name = "BATT FAIL",
  861. .start = WM831X_IRQ_CHG_BATT_FAIL,
  862. .end = WM831X_IRQ_CHG_BATT_FAIL,
  863. .flags = IORESOURCE_IRQ,
  864. },
  865. {
  866. .name = "OV",
  867. .start = WM831X_IRQ_CHG_OV,
  868. .end = WM831X_IRQ_CHG_OV,
  869. .flags = IORESOURCE_IRQ,
  870. },
  871. {
  872. .name = "END",
  873. .start = WM831X_IRQ_CHG_END,
  874. .end = WM831X_IRQ_CHG_END,
  875. .flags = IORESOURCE_IRQ,
  876. },
  877. {
  878. .name = "TO",
  879. .start = WM831X_IRQ_CHG_TO,
  880. .end = WM831X_IRQ_CHG_TO,
  881. .flags = IORESOURCE_IRQ,
  882. },
  883. {
  884. .name = "MODE",
  885. .start = WM831X_IRQ_CHG_MODE,
  886. .end = WM831X_IRQ_CHG_MODE,
  887. .flags = IORESOURCE_IRQ,
  888. },
  889. {
  890. .name = "START",
  891. .start = WM831X_IRQ_CHG_START,
  892. .end = WM831X_IRQ_CHG_START,
  893. .flags = IORESOURCE_IRQ,
  894. },
  895. };
  896. static struct resource wm831x_rtc_resources[] = {
  897. {
  898. .name = "PER",
  899. .start = WM831X_IRQ_RTC_PER,
  900. .end = WM831X_IRQ_RTC_PER,
  901. .flags = IORESOURCE_IRQ,
  902. },
  903. {
  904. .name = "ALM",
  905. .start = WM831X_IRQ_RTC_ALM,
  906. .end = WM831X_IRQ_RTC_ALM,
  907. .flags = IORESOURCE_IRQ,
  908. },
  909. };
  910. static struct resource wm831x_status1_resources[] = {
  911. {
  912. .start = WM831X_STATUS_LED_1,
  913. .end = WM831X_STATUS_LED_1,
  914. .flags = IORESOURCE_IO,
  915. },
  916. };
  917. static struct resource wm831x_status2_resources[] = {
  918. {
  919. .start = WM831X_STATUS_LED_2,
  920. .end = WM831X_STATUS_LED_2,
  921. .flags = IORESOURCE_IO,
  922. },
  923. };
  924. static struct resource wm831x_touch_resources[] = {
  925. {
  926. .name = "TCHPD",
  927. .start = WM831X_IRQ_TCHPD,
  928. .end = WM831X_IRQ_TCHPD,
  929. .flags = IORESOURCE_IRQ,
  930. },
  931. {
  932. .name = "TCHDATA",
  933. .start = WM831X_IRQ_TCHDATA,
  934. .end = WM831X_IRQ_TCHDATA,
  935. .flags = IORESOURCE_IRQ,
  936. },
  937. };
  938. static struct resource wm831x_wdt_resources[] = {
  939. {
  940. .start = WM831X_IRQ_WDOG_TO,
  941. .end = WM831X_IRQ_WDOG_TO,
  942. .flags = IORESOURCE_IRQ,
  943. },
  944. };
  945. static struct mfd_cell wm8310_devs[] = {
  946. {
  947. .name = "wm831x-backup",
  948. },
  949. {
  950. .name = "wm831x-buckv",
  951. .id = 1,
  952. .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
  953. .resources = wm831x_dcdc1_resources,
  954. },
  955. {
  956. .name = "wm831x-buckv",
  957. .id = 2,
  958. .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
  959. .resources = wm831x_dcdc2_resources,
  960. },
  961. {
  962. .name = "wm831x-buckp",
  963. .id = 3,
  964. .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
  965. .resources = wm831x_dcdc3_resources,
  966. },
  967. {
  968. .name = "wm831x-boostp",
  969. .id = 4,
  970. .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
  971. .resources = wm831x_dcdc4_resources,
  972. },
  973. {
  974. .name = "wm831x-clk",
  975. },
  976. {
  977. .name = "wm831x-epe",
  978. .id = 1,
  979. },
  980. {
  981. .name = "wm831x-epe",
  982. .id = 2,
  983. },
  984. {
  985. .name = "wm831x-gpio",
  986. .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
  987. .resources = wm831x_gpio_resources,
  988. },
  989. {
  990. .name = "wm831x-hwmon",
  991. },
  992. {
  993. .name = "wm831x-isink",
  994. .id = 1,
  995. .num_resources = ARRAY_SIZE(wm831x_isink1_resources),
  996. .resources = wm831x_isink1_resources,
  997. },
  998. {
  999. .name = "wm831x-isink",
  1000. .id = 2,
  1001. .num_resources = ARRAY_SIZE(wm831x_isink2_resources),
  1002. .resources = wm831x_isink2_resources,
  1003. },
  1004. {
  1005. .name = "wm831x-ldo",
  1006. .id = 1,
  1007. .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
  1008. .resources = wm831x_ldo1_resources,
  1009. },
  1010. {
  1011. .name = "wm831x-ldo",
  1012. .id = 2,
  1013. .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
  1014. .resources = wm831x_ldo2_resources,
  1015. },
  1016. {
  1017. .name = "wm831x-ldo",
  1018. .id = 3,
  1019. .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
  1020. .resources = wm831x_ldo3_resources,
  1021. },
  1022. {
  1023. .name = "wm831x-ldo",
  1024. .id = 4,
  1025. .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
  1026. .resources = wm831x_ldo4_resources,
  1027. },
  1028. {
  1029. .name = "wm831x-ldo",
  1030. .id = 5,
  1031. .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
  1032. .resources = wm831x_ldo5_resources,
  1033. },
  1034. {
  1035. .name = "wm831x-ldo",
  1036. .id = 6,
  1037. .num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
  1038. .resources = wm831x_ldo6_resources,
  1039. },
  1040. {
  1041. .name = "wm831x-aldo",
  1042. .id = 7,
  1043. .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
  1044. .resources = wm831x_ldo7_resources,
  1045. },
  1046. {
  1047. .name = "wm831x-aldo",
  1048. .id = 8,
  1049. .num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
  1050. .resources = wm831x_ldo8_resources,
  1051. },
  1052. {
  1053. .name = "wm831x-aldo",
  1054. .id = 9,
  1055. .num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
  1056. .resources = wm831x_ldo9_resources,
  1057. },
  1058. {
  1059. .name = "wm831x-aldo",
  1060. .id = 10,
  1061. .num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
  1062. .resources = wm831x_ldo10_resources,
  1063. },
  1064. {
  1065. .name = "wm831x-alive-ldo",
  1066. .id = 11,
  1067. .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
  1068. .resources = wm831x_ldo11_resources,
  1069. },
  1070. {
  1071. .name = "wm831x-on",
  1072. .num_resources = ARRAY_SIZE(wm831x_on_resources),
  1073. .resources = wm831x_on_resources,
  1074. },
  1075. {
  1076. .name = "wm831x-power",
  1077. .num_resources = ARRAY_SIZE(wm831x_power_resources),
  1078. .resources = wm831x_power_resources,
  1079. },
  1080. {
  1081. .name = "wm831x-status",
  1082. .id = 1,
  1083. .num_resources = ARRAY_SIZE(wm831x_status1_resources),
  1084. .resources = wm831x_status1_resources,
  1085. },
  1086. {
  1087. .name = "wm831x-status",
  1088. .id = 2,
  1089. .num_resources = ARRAY_SIZE(wm831x_status2_resources),
  1090. .resources = wm831x_status2_resources,
  1091. },
  1092. {
  1093. .name = "wm831x-watchdog",
  1094. .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
  1095. .resources = wm831x_wdt_resources,
  1096. },
  1097. };
  1098. static struct mfd_cell wm8311_devs[] = {
  1099. {
  1100. .name = "wm831x-backup",
  1101. },
  1102. {
  1103. .name = "wm831x-buckv",
  1104. .id = 1,
  1105. .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
  1106. .resources = wm831x_dcdc1_resources,
  1107. },
  1108. {
  1109. .name = "wm831x-buckv",
  1110. .id = 2,
  1111. .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
  1112. .resources = wm831x_dcdc2_resources,
  1113. },
  1114. {
  1115. .name = "wm831x-buckp",
  1116. .id = 3,
  1117. .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
  1118. .resources = wm831x_dcdc3_resources,
  1119. },
  1120. {
  1121. .name = "wm831x-boostp",
  1122. .id = 4,
  1123. .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
  1124. .resources = wm831x_dcdc4_resources,
  1125. },
  1126. {
  1127. .name = "wm831x-clk",
  1128. },
  1129. {
  1130. .name = "wm831x-epe",
  1131. .id = 1,
  1132. },
  1133. {
  1134. .name = "wm831x-epe",
  1135. .id = 2,
  1136. },
  1137. {
  1138. .name = "wm831x-gpio",
  1139. .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
  1140. .resources = wm831x_gpio_resources,
  1141. },
  1142. {
  1143. .name = "wm831x-hwmon",
  1144. },
  1145. {
  1146. .name = "wm831x-isink",
  1147. .id = 1,
  1148. .num_resources = ARRAY_SIZE(wm831x_isink1_resources),
  1149. .resources = wm831x_isink1_resources,
  1150. },
  1151. {
  1152. .name = "wm831x-isink",
  1153. .id = 2,
  1154. .num_resources = ARRAY_SIZE(wm831x_isink2_resources),
  1155. .resources = wm831x_isink2_resources,
  1156. },
  1157. {
  1158. .name = "wm831x-ldo",
  1159. .id = 1,
  1160. .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
  1161. .resources = wm831x_ldo1_resources,
  1162. },
  1163. {
  1164. .name = "wm831x-ldo",
  1165. .id = 2,
  1166. .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
  1167. .resources = wm831x_ldo2_resources,
  1168. },
  1169. {
  1170. .name = "wm831x-ldo",
  1171. .id = 3,
  1172. .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
  1173. .resources = wm831x_ldo3_resources,
  1174. },
  1175. {
  1176. .name = "wm831x-ldo",
  1177. .id = 4,
  1178. .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
  1179. .resources = wm831x_ldo4_resources,
  1180. },
  1181. {
  1182. .name = "wm831x-ldo",
  1183. .id = 5,
  1184. .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
  1185. .resources = wm831x_ldo5_resources,
  1186. },
  1187. {
  1188. .name = "wm831x-aldo",
  1189. .id = 7,
  1190. .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
  1191. .resources = wm831x_ldo7_resources,
  1192. },
  1193. {
  1194. .name = "wm831x-alive-ldo",
  1195. .id = 11,
  1196. .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
  1197. .resources = wm831x_ldo11_resources,
  1198. },
  1199. {
  1200. .name = "wm831x-on",
  1201. .num_resources = ARRAY_SIZE(wm831x_on_resources),
  1202. .resources = wm831x_on_resources,
  1203. },
  1204. {
  1205. .name = "wm831x-power",
  1206. .num_resources = ARRAY_SIZE(wm831x_power_resources),
  1207. .resources = wm831x_power_resources,
  1208. },
  1209. {
  1210. .name = "wm831x-status",
  1211. .id = 1,
  1212. .num_resources = ARRAY_SIZE(wm831x_status1_resources),
  1213. .resources = wm831x_status1_resources,
  1214. },
  1215. {
  1216. .name = "wm831x-status",
  1217. .id = 2,
  1218. .num_resources = ARRAY_SIZE(wm831x_status2_resources),
  1219. .resources = wm831x_status2_resources,
  1220. },
  1221. {
  1222. .name = "wm831x-watchdog",
  1223. .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
  1224. .resources = wm831x_wdt_resources,
  1225. },
  1226. };
  1227. static struct mfd_cell wm8312_devs[] = {
  1228. {
  1229. .name = "wm831x-backup",
  1230. },
  1231. {
  1232. .name = "wm831x-buckv",
  1233. .id = 1,
  1234. .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
  1235. .resources = wm831x_dcdc1_resources,
  1236. },
  1237. {
  1238. .name = "wm831x-buckv",
  1239. .id = 2,
  1240. .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
  1241. .resources = wm831x_dcdc2_resources,
  1242. },
  1243. {
  1244. .name = "wm831x-buckp",
  1245. .id = 3,
  1246. .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
  1247. .resources = wm831x_dcdc3_resources,
  1248. },
  1249. {
  1250. .name = "wm831x-boostp",
  1251. .id = 4,
  1252. .num_resources = ARRAY_SIZE(wm831x_dcdc4_resources),
  1253. .resources = wm831x_dcdc4_resources,
  1254. },
  1255. {
  1256. .name = "wm831x-clk",
  1257. },
  1258. {
  1259. .name = "wm831x-epe",
  1260. .id = 1,
  1261. },
  1262. {
  1263. .name = "wm831x-epe",
  1264. .id = 2,
  1265. },
  1266. {
  1267. .name = "wm831x-gpio",
  1268. .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
  1269. .resources = wm831x_gpio_resources,
  1270. },
  1271. {
  1272. .name = "wm831x-hwmon",
  1273. },
  1274. {
  1275. .name = "wm831x-isink",
  1276. .id = 1,
  1277. .num_resources = ARRAY_SIZE(wm831x_isink1_resources),
  1278. .resources = wm831x_isink1_resources,
  1279. },
  1280. {
  1281. .name = "wm831x-isink",
  1282. .id = 2,
  1283. .num_resources = ARRAY_SIZE(wm831x_isink2_resources),
  1284. .resources = wm831x_isink2_resources,
  1285. },
  1286. {
  1287. .name = "wm831x-ldo",
  1288. .id = 1,
  1289. .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
  1290. .resources = wm831x_ldo1_resources,
  1291. },
  1292. {
  1293. .name = "wm831x-ldo",
  1294. .id = 2,
  1295. .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
  1296. .resources = wm831x_ldo2_resources,
  1297. },
  1298. {
  1299. .name = "wm831x-ldo",
  1300. .id = 3,
  1301. .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
  1302. .resources = wm831x_ldo3_resources,
  1303. },
  1304. {
  1305. .name = "wm831x-ldo",
  1306. .id = 4,
  1307. .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
  1308. .resources = wm831x_ldo4_resources,
  1309. },
  1310. {
  1311. .name = "wm831x-ldo",
  1312. .id = 5,
  1313. .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
  1314. .resources = wm831x_ldo5_resources,
  1315. },
  1316. {
  1317. .name = "wm831x-ldo",
  1318. .id = 6,
  1319. .num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
  1320. .resources = wm831x_ldo6_resources,
  1321. },
  1322. {
  1323. .name = "wm831x-aldo",
  1324. .id = 7,
  1325. .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
  1326. .resources = wm831x_ldo7_resources,
  1327. },
  1328. {
  1329. .name = "wm831x-aldo",
  1330. .id = 8,
  1331. .num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
  1332. .resources = wm831x_ldo8_resources,
  1333. },
  1334. {
  1335. .name = "wm831x-aldo",
  1336. .id = 9,
  1337. .num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
  1338. .resources = wm831x_ldo9_resources,
  1339. },
  1340. {
  1341. .name = "wm831x-aldo",
  1342. .id = 10,
  1343. .num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
  1344. .resources = wm831x_ldo10_resources,
  1345. },
  1346. {
  1347. .name = "wm831x-alive-ldo",
  1348. .id = 11,
  1349. .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
  1350. .resources = wm831x_ldo11_resources,
  1351. },
  1352. {
  1353. .name = "wm831x-on",
  1354. .num_resources = ARRAY_SIZE(wm831x_on_resources),
  1355. .resources = wm831x_on_resources,
  1356. },
  1357. {
  1358. .name = "wm831x-power",
  1359. .num_resources = ARRAY_SIZE(wm831x_power_resources),
  1360. .resources = wm831x_power_resources,
  1361. },
  1362. {
  1363. .name = "wm831x-status",
  1364. .id = 1,
  1365. .num_resources = ARRAY_SIZE(wm831x_status1_resources),
  1366. .resources = wm831x_status1_resources,
  1367. },
  1368. {
  1369. .name = "wm831x-status",
  1370. .id = 2,
  1371. .num_resources = ARRAY_SIZE(wm831x_status2_resources),
  1372. .resources = wm831x_status2_resources,
  1373. },
  1374. {
  1375. .name = "wm831x-watchdog",
  1376. .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
  1377. .resources = wm831x_wdt_resources,
  1378. },
  1379. };
  1380. static struct mfd_cell wm8320_devs[] = {
  1381. {
  1382. .name = "wm831x-backup",
  1383. },
  1384. {
  1385. .name = "wm831x-buckv",
  1386. .id = 1,
  1387. .num_resources = ARRAY_SIZE(wm831x_dcdc1_resources),
  1388. .resources = wm831x_dcdc1_resources,
  1389. },
  1390. {
  1391. .name = "wm831x-buckv",
  1392. .id = 2,
  1393. .num_resources = ARRAY_SIZE(wm831x_dcdc2_resources),
  1394. .resources = wm831x_dcdc2_resources,
  1395. },
  1396. {
  1397. .name = "wm831x-buckp",
  1398. .id = 3,
  1399. .num_resources = ARRAY_SIZE(wm831x_dcdc3_resources),
  1400. .resources = wm831x_dcdc3_resources,
  1401. },
  1402. {
  1403. .name = "wm831x-buckp",
  1404. .id = 4,
  1405. .num_resources = ARRAY_SIZE(wm8320_dcdc4_buck_resources),
  1406. .resources = wm8320_dcdc4_buck_resources,
  1407. },
  1408. {
  1409. .name = "wm831x-clk",
  1410. },
  1411. {
  1412. .name = "wm831x-gpio",
  1413. .num_resources = ARRAY_SIZE(wm831x_gpio_resources),
  1414. .resources = wm831x_gpio_resources,
  1415. },
  1416. {
  1417. .name = "wm831x-hwmon",
  1418. },
  1419. {
  1420. .name = "wm831x-ldo",
  1421. .id = 1,
  1422. .num_resources = ARRAY_SIZE(wm831x_ldo1_resources),
  1423. .resources = wm831x_ldo1_resources,
  1424. },
  1425. {
  1426. .name = "wm831x-ldo",
  1427. .id = 2,
  1428. .num_resources = ARRAY_SIZE(wm831x_ldo2_resources),
  1429. .resources = wm831x_ldo2_resources,
  1430. },
  1431. {
  1432. .name = "wm831x-ldo",
  1433. .id = 3,
  1434. .num_resources = ARRAY_SIZE(wm831x_ldo3_resources),
  1435. .resources = wm831x_ldo3_resources,
  1436. },
  1437. {
  1438. .name = "wm831x-ldo",
  1439. .id = 4,
  1440. .num_resources = ARRAY_SIZE(wm831x_ldo4_resources),
  1441. .resources = wm831x_ldo4_resources,
  1442. },
  1443. {
  1444. .name = "wm831x-ldo",
  1445. .id = 5,
  1446. .num_resources = ARRAY_SIZE(wm831x_ldo5_resources),
  1447. .resources = wm831x_ldo5_resources,
  1448. },
  1449. {
  1450. .name = "wm831x-ldo",
  1451. .id = 6,
  1452. .num_resources = ARRAY_SIZE(wm831x_ldo6_resources),
  1453. .resources = wm831x_ldo6_resources,
  1454. },
  1455. {
  1456. .name = "wm831x-aldo",
  1457. .id = 7,
  1458. .num_resources = ARRAY_SIZE(wm831x_ldo7_resources),
  1459. .resources = wm831x_ldo7_resources,
  1460. },
  1461. {
  1462. .name = "wm831x-aldo",
  1463. .id = 8,
  1464. .num_resources = ARRAY_SIZE(wm831x_ldo8_resources),
  1465. .resources = wm831x_ldo8_resources,
  1466. },
  1467. {
  1468. .name = "wm831x-aldo",
  1469. .id = 9,
  1470. .num_resources = ARRAY_SIZE(wm831x_ldo9_resources),
  1471. .resources = wm831x_ldo9_resources,
  1472. },
  1473. {
  1474. .name = "wm831x-aldo",
  1475. .id = 10,
  1476. .num_resources = ARRAY_SIZE(wm831x_ldo10_resources),
  1477. .resources = wm831x_ldo10_resources,
  1478. },
  1479. {
  1480. .name = "wm831x-alive-ldo",
  1481. .id = 11,
  1482. .num_resources = ARRAY_SIZE(wm831x_ldo11_resources),
  1483. .resources = wm831x_ldo11_resources,
  1484. },
  1485. {
  1486. .name = "wm831x-on",
  1487. .num_resources = ARRAY_SIZE(wm831x_on_resources),
  1488. .resources = wm831x_on_resources,
  1489. },
  1490. {
  1491. .name = "wm831x-status",
  1492. .id = 1,
  1493. .num_resources = ARRAY_SIZE(wm831x_status1_resources),
  1494. .resources = wm831x_status1_resources,
  1495. },
  1496. {
  1497. .name = "wm831x-status",
  1498. .id = 2,
  1499. .num_resources = ARRAY_SIZE(wm831x_status2_resources),
  1500. .resources = wm831x_status2_resources,
  1501. },
  1502. {
  1503. .name = "wm831x-watchdog",
  1504. .num_resources = ARRAY_SIZE(wm831x_wdt_resources),
  1505. .resources = wm831x_wdt_resources,
  1506. },
  1507. };
  1508. static struct mfd_cell touch_devs[] = {
  1509. {
  1510. .name = "wm831x-touch",
  1511. .num_resources = ARRAY_SIZE(wm831x_touch_resources),
  1512. .resources = wm831x_touch_resources,
  1513. },
  1514. };
  1515. static struct mfd_cell rtc_devs[] = {
  1516. {
  1517. .name = "wm831x-rtc",
  1518. .num_resources = ARRAY_SIZE(wm831x_rtc_resources),
  1519. .resources = wm831x_rtc_resources,
  1520. },
  1521. };
  1522. static struct mfd_cell backlight_devs[] = {
  1523. {
  1524. .name = "wm831x-backlight",
  1525. },
  1526. };
  1527. struct regmap_config wm831x_regmap_config = {
  1528. .reg_bits = 16,
  1529. .val_bits = 16,
  1530. .cache_type = REGCACHE_RBTREE,
  1531. .max_register = WM831X_DBE_CHECK_DATA,
  1532. .readable_reg = wm831x_reg_readable,
  1533. .writeable_reg = wm831x_reg_writeable,
  1534. .volatile_reg = wm831x_reg_volatile,
  1535. };
  1536. EXPORT_SYMBOL_GPL(wm831x_regmap_config);
  1537. /*
  1538. * Instantiate the generic non-control parts of the device.
  1539. */
  1540. int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
  1541. {
  1542. struct wm831x_pdata *pdata = wm831x->dev->platform_data;
  1543. int rev, wm831x_num;
  1544. enum wm831x_parent parent;
  1545. int ret, i;
  1546. mutex_init(&wm831x->io_lock);
  1547. mutex_init(&wm831x->key_lock);
  1548. dev_set_drvdata(wm831x->dev, wm831x);
  1549. wm831x->soft_shutdown = pdata->soft_shutdown;
  1550. ret = wm831x_reg_read(wm831x, WM831X_PARENT_ID);
  1551. if (ret < 0) {
  1552. dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret);
  1553. goto err_regmap;
  1554. }
  1555. switch (ret) {
  1556. case 0x6204:
  1557. case 0x6246:
  1558. break;
  1559. default:
  1560. dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret);
  1561. ret = -EINVAL;
  1562. goto err_regmap;
  1563. }
  1564. ret = wm831x_reg_read(wm831x, WM831X_REVISION);
  1565. if (ret < 0) {
  1566. dev_err(wm831x->dev, "Failed to read revision: %d\n", ret);
  1567. goto err_regmap;
  1568. }
  1569. rev = (ret & WM831X_PARENT_REV_MASK) >> WM831X_PARENT_REV_SHIFT;
  1570. ret = wm831x_reg_read(wm831x, WM831X_RESET_ID);
  1571. if (ret < 0) {
  1572. dev_err(wm831x->dev, "Failed to read device ID: %d\n", ret);
  1573. goto err_regmap;
  1574. }
  1575. /* Some engineering samples do not have the ID set, rely on
  1576. * the device being registered correctly.
  1577. */
  1578. if (ret == 0) {
  1579. dev_info(wm831x->dev, "Device is an engineering sample\n");
  1580. ret = id;
  1581. }
  1582. switch (ret) {
  1583. case WM8310:
  1584. parent = WM8310;
  1585. wm831x->num_gpio = 16;
  1586. wm831x->charger_irq_wake = 1;
  1587. if (rev > 0) {
  1588. wm831x->has_gpio_ena = 1;
  1589. wm831x->has_cs_sts = 1;
  1590. }
  1591. dev_info(wm831x->dev, "WM8310 revision %c\n", 'A' + rev);
  1592. break;
  1593. case WM8311:
  1594. parent = WM8311;
  1595. wm831x->num_gpio = 16;
  1596. wm831x->charger_irq_wake = 1;
  1597. if (rev > 0) {
  1598. wm831x->has_gpio_ena = 1;
  1599. wm831x->has_cs_sts = 1;
  1600. }
  1601. dev_info(wm831x->dev, "WM8311 revision %c\n", 'A' + rev);
  1602. break;
  1603. case WM8312:
  1604. parent = WM8312;
  1605. wm831x->num_gpio = 16;
  1606. wm831x->charger_irq_wake = 1;
  1607. if (rev > 0) {
  1608. wm831x->has_gpio_ena = 1;
  1609. wm831x->has_cs_sts = 1;
  1610. }
  1611. dev_info(wm831x->dev, "WM8312 revision %c\n", 'A' + rev);
  1612. break;
  1613. case WM8320:
  1614. parent = WM8320;
  1615. wm831x->num_gpio = 12;
  1616. dev_info(wm831x->dev, "WM8320 revision %c\n", 'A' + rev);
  1617. break;
  1618. case WM8321:
  1619. parent = WM8321;
  1620. wm831x->num_gpio = 12;
  1621. dev_info(wm831x->dev, "WM8321 revision %c\n", 'A' + rev);
  1622. break;
  1623. case WM8325:
  1624. parent = WM8325;
  1625. wm831x->num_gpio = 12;
  1626. dev_info(wm831x->dev, "WM8325 revision %c\n", 'A' + rev);
  1627. break;
  1628. case WM8326:
  1629. parent = WM8326;
  1630. wm831x->num_gpio = 12;
  1631. dev_info(wm831x->dev, "WM8326 revision %c\n", 'A' + rev);
  1632. break;
  1633. default:
  1634. dev_err(wm831x->dev, "Unknown WM831x device %04x\n", ret);
  1635. ret = -EINVAL;
  1636. goto err_regmap;
  1637. }
  1638. /* This will need revisiting in future but is OK for all
  1639. * current parts.
  1640. */
  1641. if (parent != id)
  1642. dev_warn(wm831x->dev, "Device was registered as a WM%lx\n",
  1643. id);
  1644. /* Bootstrap the user key */
  1645. ret = wm831x_reg_read(wm831x, WM831X_SECURITY_KEY);
  1646. if (ret < 0) {
  1647. dev_err(wm831x->dev, "Failed to read security key: %d\n", ret);
  1648. goto err_regmap;
  1649. }
  1650. if (ret != 0) {
  1651. dev_warn(wm831x->dev, "Security key had non-zero value %x\n",
  1652. ret);
  1653. wm831x_reg_write(wm831x, WM831X_SECURITY_KEY, 0);
  1654. }
  1655. wm831x->locked = 1;
  1656. if (pdata && pdata->pre_init) {
  1657. ret = pdata->pre_init(wm831x);
  1658. if (ret != 0) {
  1659. dev_err(wm831x->dev, "pre_init() failed: %d\n", ret);
  1660. goto err_regmap;
  1661. }
  1662. }
  1663. if (pdata) {
  1664. for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
  1665. if (!pdata->gpio_defaults[i])
  1666. continue;
  1667. wm831x_reg_write(wm831x,
  1668. WM831X_GPIO1_CONTROL + i,
  1669. pdata->gpio_defaults[i] & 0xffff);
  1670. }
  1671. }
  1672. /* Multiply by 10 as we have many subdevices of the same type */
  1673. if (pdata && pdata->wm831x_num)
  1674. wm831x_num = pdata->wm831x_num * 10;
  1675. else
  1676. wm831x_num = -1;
  1677. ret = wm831x_irq_init(wm831x, irq);
  1678. if (ret != 0)
  1679. goto err_regmap;
  1680. wm831x_auxadc_init(wm831x);
  1681. /* The core device is up, instantiate the subdevices. */
  1682. switch (parent) {
  1683. case WM8310:
  1684. ret = mfd_add_devices(wm831x->dev, wm831x_num,
  1685. wm8310_devs, ARRAY_SIZE(wm8310_devs),
  1686. NULL, wm831x->irq_base);
  1687. break;
  1688. case WM8311:
  1689. ret = mfd_add_devices(wm831x->dev, wm831x_num,
  1690. wm8311_devs, ARRAY_SIZE(wm8311_devs),
  1691. NULL, wm831x->irq_base);
  1692. if (!pdata || !pdata->disable_touch)
  1693. mfd_add_devices(wm831x->dev, wm831x_num,
  1694. touch_devs, ARRAY_SIZE(touch_devs),
  1695. NULL, wm831x->irq_base);
  1696. break;
  1697. case WM8312:
  1698. ret = mfd_add_devices(wm831x->dev, wm831x_num,
  1699. wm8312_devs, ARRAY_SIZE(wm8312_devs),
  1700. NULL, wm831x->irq_base);
  1701. if (!pdata || !pdata->disable_touch)
  1702. mfd_add_devices(wm831x->dev, wm831x_num,
  1703. touch_devs, ARRAY_SIZE(touch_devs),
  1704. NULL, wm831x->irq_base);
  1705. break;
  1706. case WM8320:
  1707. case WM8321:
  1708. case WM8325:
  1709. case WM8326:
  1710. ret = mfd_add_devices(wm831x->dev, wm831x_num,
  1711. wm8320_devs, ARRAY_SIZE(wm8320_devs),
  1712. NULL, wm831x->irq_base);
  1713. break;
  1714. default:
  1715. /* If this happens the bus probe function is buggy */
  1716. BUG();
  1717. }
  1718. if (ret != 0) {
  1719. dev_err(wm831x->dev, "Failed to add children\n");
  1720. goto err_irq;
  1721. }
  1722. /* The RTC can only be used if the 32.768kHz crystal is
  1723. * enabled; this can't be controlled by software at runtime.
  1724. */
  1725. ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
  1726. if (ret < 0) {
  1727. dev_err(wm831x->dev, "Failed to read clock status: %d\n", ret);
  1728. goto err_irq;
  1729. }
  1730. if (ret & WM831X_XTAL_ENA) {
  1731. ret = mfd_add_devices(wm831x->dev, wm831x_num,
  1732. rtc_devs, ARRAY_SIZE(rtc_devs),
  1733. NULL, wm831x->irq_base);
  1734. if (ret != 0) {
  1735. dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret);
  1736. goto err_irq;
  1737. }
  1738. } else {
  1739. dev_info(wm831x->dev, "32.768kHz clock disabled, no RTC\n");
  1740. }
  1741. if (pdata && pdata->backlight) {
  1742. /* Treat errors as non-critical */
  1743. ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs,
  1744. ARRAY_SIZE(backlight_devs), NULL,
  1745. wm831x->irq_base);
  1746. if (ret < 0)
  1747. dev_err(wm831x->dev, "Failed to add backlight: %d\n",
  1748. ret);
  1749. }
  1750. wm831x_otp_init(wm831x);
  1751. if (pdata && pdata->post_init) {
  1752. ret = pdata->post_init(wm831x);
  1753. if (ret != 0) {
  1754. dev_err(wm831x->dev, "post_init() failed: %d\n", ret);
  1755. goto err_irq;
  1756. }
  1757. }
  1758. return 0;
  1759. err_irq:
  1760. wm831x_irq_exit(wm831x);
  1761. err_regmap:
  1762. mfd_remove_devices(wm831x->dev);
  1763. regmap_exit(wm831x->regmap);
  1764. kfree(wm831x);
  1765. return ret;
  1766. }
  1767. void wm831x_device_exit(struct wm831x *wm831x)
  1768. {
  1769. wm831x_otp_exit(wm831x);
  1770. mfd_remove_devices(wm831x->dev);
  1771. if (wm831x->irq_base)
  1772. free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
  1773. wm831x_irq_exit(wm831x);
  1774. regmap_exit(wm831x->regmap);
  1775. kfree(wm831x);
  1776. }
  1777. int wm831x_device_suspend(struct wm831x *wm831x)
  1778. {
  1779. int reg, mask;
  1780. /* If the charger IRQs are a wake source then make sure we ack
  1781. * them even if they're not actively being used (eg, no power
  1782. * driver or no IRQ line wired up) then acknowledge the
  1783. * interrupts otherwise suspend won't last very long.
  1784. */
  1785. if (wm831x->charger_irq_wake) {
  1786. reg = wm831x_reg_read(wm831x, WM831X_INTERRUPT_STATUS_2_MASK);
  1787. mask = WM831X_CHG_BATT_HOT_EINT |
  1788. WM831X_CHG_BATT_COLD_EINT |
  1789. WM831X_CHG_BATT_FAIL_EINT |
  1790. WM831X_CHG_OV_EINT | WM831X_CHG_END_EINT |
  1791. WM831X_CHG_TO_EINT | WM831X_CHG_MODE_EINT |
  1792. WM831X_CHG_START_EINT;
  1793. /* If any of the interrupts are masked read the statuses */
  1794. if (reg & mask)
  1795. reg = wm831x_reg_read(wm831x,
  1796. WM831X_INTERRUPT_STATUS_2);
  1797. if (reg & mask) {
  1798. dev_info(wm831x->dev,
  1799. "Acknowledging masked charger IRQs: %x\n",
  1800. reg & mask);
  1801. wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_2,
  1802. reg & mask);
  1803. }
  1804. }
  1805. return 0;
  1806. }
  1807. void wm831x_device_shutdown(struct wm831x *wm831x)
  1808. {
  1809. if (wm831x->soft_shutdown) {
  1810. dev_info(wm831x->dev, "Initiating shutdown...\n");
  1811. wm831x_set_bits(wm831x, WM831X_POWER_STATE, WM831X_CHIP_ON, 0);
  1812. }
  1813. }
  1814. EXPORT_SYMBOL_GPL(wm831x_device_shutdown);
  1815. MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC");
  1816. MODULE_LICENSE("GPL");
  1817. MODULE_AUTHOR("Mark Brown");