wm831x-core.c 42 KB

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