pm8038-core.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. /*
  2. * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #define pr_fmt(fmt) "%s: " fmt, __func__
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/slab.h>
  18. #include <linux/err.h>
  19. #include <linux/string.h>
  20. #include <linux/msm_ssbi.h>
  21. #include <linux/mfd/core.h>
  22. #include <linux/mfd/pm8xxx/pm8038.h>
  23. #include <linux/mfd/pm8xxx/pm8921.h>
  24. #include <linux/mfd/pm8xxx/core.h>
  25. #include <linux/mfd/pm8xxx/regulator.h>
  26. #define REG_HWREV 0x002 /* PMIC4 revision */
  27. #define REG_HWREV_2 0x0E8 /* PMIC4 revision 2 */
  28. #define REG_MPP_BASE 0x050
  29. #define REG_RTC_BASE 0x11D
  30. #define REG_IRQ_BASE 0x1BB
  31. #define REG_BATT_ALARM_THRESH 0x023
  32. #define REG_BATT_ALARM_CTRL1 0x024
  33. #define REG_BATT_ALARM_CTRL2 0x021
  34. #define REG_BATT_ALARM_PWM_CTRL 0x020
  35. #define REG_SPK_BASE 0x253
  36. #define REG_SPK_REGISTERS 6
  37. #define REG_TEMP_ALARM_CTRL 0x01B
  38. #define REG_TEMP_ALARM_PWM 0x09B
  39. #define PM8038_VERSION_MASK 0xFFF0
  40. #define PM8038_VERSION_VALUE 0x09F0
  41. #define PM8038_REVISION_MASK 0x000F
  42. #define REG_PM8038_PON_CNTRL_3 0x01D
  43. #define SINGLE_IRQ_RESOURCE(_name, _irq) \
  44. { \
  45. .name = _name, \
  46. .start = _irq, \
  47. .end = _irq, \
  48. .flags = IORESOURCE_IRQ, \
  49. }
  50. struct pm8038 {
  51. struct device *dev;
  52. struct pm_irq_chip *irq_chip;
  53. struct mfd_cell *mfd_regulators;
  54. struct pm8xxx_regulator_core_platform_data *regulator_cdata;
  55. u32 rev_registers;
  56. u8 restart_reason;
  57. };
  58. static int pm8038_readb(const struct device *dev, u16 addr, u8 *val)
  59. {
  60. const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
  61. const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
  62. return msm_ssbi_read(pmic->dev->parent, addr, val, 1);
  63. }
  64. static int pm8038_writeb(const struct device *dev, u16 addr, u8 val)
  65. {
  66. const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
  67. const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
  68. return msm_ssbi_write(pmic->dev->parent, addr, &val, 1);
  69. }
  70. static int pm8038_read_buf(const struct device *dev, u16 addr, u8 *buf,
  71. int cnt)
  72. {
  73. const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
  74. const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
  75. return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt);
  76. }
  77. static int pm8038_write_buf(const struct device *dev, u16 addr, u8 *buf,
  78. int cnt)
  79. {
  80. const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
  81. const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
  82. return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt);
  83. }
  84. static int pm8038_read_irq_stat(const struct device *dev, int irq)
  85. {
  86. const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
  87. const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
  88. return pm8xxx_get_irq_stat(pmic->irq_chip, irq);
  89. }
  90. static enum pm8xxx_version pm8038_get_version(const struct device *dev)
  91. {
  92. const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
  93. const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
  94. enum pm8xxx_version version = -ENODEV;
  95. if ((pmic->rev_registers & PM8038_VERSION_MASK) == PM8038_VERSION_VALUE)
  96. version = PM8XXX_VERSION_8038;
  97. return version;
  98. }
  99. static int pm8038_get_revision(const struct device *dev)
  100. {
  101. const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
  102. const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
  103. return pmic->rev_registers & PM8038_REVISION_MASK;
  104. }
  105. static u8 pm8038_restart_reason(const struct device *dev)
  106. {
  107. const struct pm8xxx_drvdata *pm8038_drvdata = dev_get_drvdata(dev);
  108. const struct pm8038 *pmic = pm8038_drvdata->pm_chip_data;
  109. return pmic->restart_reason;
  110. }
  111. static struct pm8xxx_drvdata pm8038_drvdata = {
  112. .pmic_readb = pm8038_readb,
  113. .pmic_writeb = pm8038_writeb,
  114. .pmic_read_buf = pm8038_read_buf,
  115. .pmic_write_buf = pm8038_write_buf,
  116. .pmic_read_irq_stat = pm8038_read_irq_stat,
  117. .pmic_get_version = pm8038_get_version,
  118. .pmic_get_revision = pm8038_get_revision,
  119. .pmic_restart_reason = pm8038_restart_reason,
  120. };
  121. static const struct resource gpio_cell_resources[] __devinitconst = {
  122. [0] = {
  123. .start = PM8038_IRQ_BLOCK_BIT(PM8038_GPIO_BLOCK_START, 0),
  124. .end = PM8038_IRQ_BLOCK_BIT(PM8038_GPIO_BLOCK_START, 0)
  125. + PM8038_NR_GPIOS - 1,
  126. .flags = IORESOURCE_IRQ,
  127. },
  128. };
  129. static struct mfd_cell gpio_cell __devinitdata = {
  130. .name = PM8XXX_GPIO_DEV_NAME,
  131. .id = -1,
  132. .resources = gpio_cell_resources,
  133. .num_resources = ARRAY_SIZE(gpio_cell_resources),
  134. };
  135. static const struct resource adc_cell_resources[] __devinitconst = {
  136. SINGLE_IRQ_RESOURCE(NULL, PM8038_ADC_EOC_USR_IRQ),
  137. SINGLE_IRQ_RESOURCE(NULL, PM8038_ADC_BATT_TEMP_WARM_IRQ),
  138. SINGLE_IRQ_RESOURCE(NULL, PM8038_ADC_BATT_TEMP_COLD_IRQ),
  139. };
  140. static struct mfd_cell adc_cell __devinitdata = {
  141. .name = PM8XXX_ADC_DEV_NAME,
  142. .id = -1,
  143. .resources = adc_cell_resources,
  144. .num_resources = ARRAY_SIZE(adc_cell_resources),
  145. };
  146. static const struct resource charger_cell_resources[] __devinitconst = {
  147. SINGLE_IRQ_RESOURCE("USBIN_VALID_IRQ", PM8921_USBIN_VALID_IRQ),
  148. SINGLE_IRQ_RESOURCE("USBIN_OV_IRQ", PM8921_USBIN_OV_IRQ),
  149. SINGLE_IRQ_RESOURCE("BATT_INSERTED_IRQ", PM8921_BATT_INSERTED_IRQ),
  150. SINGLE_IRQ_RESOURCE("VBATDET_LOW_IRQ", PM8921_VBATDET_LOW_IRQ),
  151. SINGLE_IRQ_RESOURCE("USBIN_UV_IRQ", PM8921_USBIN_UV_IRQ),
  152. SINGLE_IRQ_RESOURCE("VBAT_OV_IRQ", PM8921_VBAT_OV_IRQ),
  153. SINGLE_IRQ_RESOURCE("CHGWDOG_IRQ", PM8921_CHGWDOG_IRQ),
  154. SINGLE_IRQ_RESOURCE("VCP_IRQ", PM8921_VCP_IRQ),
  155. SINGLE_IRQ_RESOURCE("ATCDONE_IRQ", PM8921_ATCDONE_IRQ),
  156. SINGLE_IRQ_RESOURCE("ATCFAIL_IRQ", PM8921_ATCFAIL_IRQ),
  157. SINGLE_IRQ_RESOURCE("CHGDONE_IRQ", PM8921_CHGDONE_IRQ),
  158. SINGLE_IRQ_RESOURCE("CHGFAIL_IRQ", PM8921_CHGFAIL_IRQ),
  159. SINGLE_IRQ_RESOURCE("CHGSTATE_IRQ", PM8921_CHGSTATE_IRQ),
  160. SINGLE_IRQ_RESOURCE("LOOP_CHANGE_IRQ", PM8921_LOOP_CHANGE_IRQ),
  161. SINGLE_IRQ_RESOURCE("FASTCHG_IRQ", PM8921_FASTCHG_IRQ),
  162. SINGLE_IRQ_RESOURCE("TRKLCHG_IRQ", PM8921_TRKLCHG_IRQ),
  163. SINGLE_IRQ_RESOURCE("BATT_REMOVED_IRQ", PM8921_BATT_REMOVED_IRQ),
  164. SINGLE_IRQ_RESOURCE("BATTTEMP_HOT_IRQ", PM8921_BATTTEMP_HOT_IRQ),
  165. SINGLE_IRQ_RESOURCE("CHGHOT_IRQ", PM8921_CHGHOT_IRQ),
  166. SINGLE_IRQ_RESOURCE("BATTTEMP_COLD_IRQ", PM8921_BATTTEMP_COLD_IRQ),
  167. SINGLE_IRQ_RESOURCE("CHG_GONE_IRQ", PM8921_CHG_GONE_IRQ),
  168. SINGLE_IRQ_RESOURCE("BAT_TEMP_OK_IRQ", PM8921_BAT_TEMP_OK_IRQ),
  169. SINGLE_IRQ_RESOURCE("COARSE_DET_LOW_IRQ", PM8921_COARSE_DET_LOW_IRQ),
  170. SINGLE_IRQ_RESOURCE("VDD_LOOP_IRQ", PM8921_VDD_LOOP_IRQ),
  171. SINGLE_IRQ_RESOURCE("VREG_OV_IRQ", PM8921_VREG_OV_IRQ),
  172. SINGLE_IRQ_RESOURCE("VBATDET_IRQ", PM8921_VBATDET_IRQ),
  173. SINGLE_IRQ_RESOURCE("BATFET_IRQ", PM8921_BATFET_IRQ),
  174. SINGLE_IRQ_RESOURCE("PSI_IRQ", PM8921_PSI_IRQ),
  175. SINGLE_IRQ_RESOURCE("DCIN_VALID_IRQ", PM8921_DCIN_VALID_IRQ),
  176. SINGLE_IRQ_RESOURCE("DCIN_OV_IRQ", PM8921_DCIN_OV_IRQ),
  177. SINGLE_IRQ_RESOURCE("DCIN_UV_IRQ", PM8921_DCIN_UV_IRQ),
  178. };
  179. static const struct resource bms_cell_resources[] __devinitconst = {
  180. SINGLE_IRQ_RESOURCE("PM8921_BMS_SBI_WRITE_OK", PM8921_BMS_SBI_WRITE_OK),
  181. SINGLE_IRQ_RESOURCE("PM8921_BMS_CC_THR", PM8921_BMS_CC_THR),
  182. SINGLE_IRQ_RESOURCE("PM8921_BMS_VSENSE_THR", PM8921_BMS_VSENSE_THR),
  183. SINGLE_IRQ_RESOURCE("PM8921_BMS_VSENSE_FOR_R", PM8921_BMS_VSENSE_FOR_R),
  184. SINGLE_IRQ_RESOURCE("PM8921_BMS_OCV_FOR_R", PM8921_BMS_OCV_FOR_R),
  185. SINGLE_IRQ_RESOURCE("PM8921_BMS_GOOD_OCV", PM8921_BMS_GOOD_OCV),
  186. SINGLE_IRQ_RESOURCE("PM8921_BMS_VSENSE_AVG", PM8921_BMS_VSENSE_AVG),
  187. };
  188. static struct mfd_cell charger_cell __devinitdata = {
  189. .name = PM8921_CHARGER_DEV_NAME,
  190. .id = -1,
  191. .resources = charger_cell_resources,
  192. .num_resources = ARRAY_SIZE(charger_cell_resources),
  193. };
  194. static struct mfd_cell bms_cell __devinitdata = {
  195. .name = PM8921_BMS_DEV_NAME,
  196. .id = -1,
  197. .resources = bms_cell_resources,
  198. .num_resources = ARRAY_SIZE(bms_cell_resources),
  199. };
  200. static const struct resource mpp_cell_resources[] __devinitconst = {
  201. {
  202. .start = PM8038_IRQ_BLOCK_BIT(PM8038_MPP_BLOCK_START, 0),
  203. .end = PM8038_IRQ_BLOCK_BIT(PM8038_MPP_BLOCK_START, 0)
  204. + PM8038_NR_MPPS - 1,
  205. .flags = IORESOURCE_IRQ,
  206. },
  207. };
  208. static struct mfd_cell mpp_cell __devinitdata = {
  209. .name = PM8XXX_MPP_DEV_NAME,
  210. .id = 1,
  211. .resources = mpp_cell_resources,
  212. .num_resources = ARRAY_SIZE(mpp_cell_resources),
  213. };
  214. static const struct resource rtc_cell_resources[] __devinitconst = {
  215. [0] = SINGLE_IRQ_RESOURCE(NULL, PM8038_RTC_ALARM_IRQ),
  216. [1] = {
  217. .name = "pmic_rtc_base",
  218. .start = REG_RTC_BASE,
  219. .end = REG_RTC_BASE,
  220. .flags = IORESOURCE_IO,
  221. },
  222. };
  223. static struct mfd_cell rtc_cell __devinitdata = {
  224. .name = PM8XXX_RTC_DEV_NAME,
  225. .id = -1,
  226. .resources = rtc_cell_resources,
  227. .num_resources = ARRAY_SIZE(rtc_cell_resources),
  228. };
  229. static const struct resource resources_pwrkey[] __devinitconst = {
  230. SINGLE_IRQ_RESOURCE(NULL, PM8038_PWRKEY_REL_IRQ),
  231. SINGLE_IRQ_RESOURCE(NULL, PM8038_PWRKEY_PRESS_IRQ),
  232. };
  233. static struct mfd_cell pwrkey_cell __devinitdata = {
  234. .name = PM8XXX_PWRKEY_DEV_NAME,
  235. .id = -1,
  236. .num_resources = ARRAY_SIZE(resources_pwrkey),
  237. .resources = resources_pwrkey,
  238. };
  239. static struct mfd_cell pwm_cell __devinitdata = {
  240. .name = PM8XXX_PWM_DEV_NAME,
  241. .id = -1,
  242. };
  243. static struct mfd_cell misc_cell __devinitdata = {
  244. .name = PM8XXX_MISC_DEV_NAME,
  245. .id = -1,
  246. };
  247. static struct mfd_cell leds_cell __devinitdata = {
  248. .name = PM8XXX_LEDS_DEV_NAME,
  249. .id = -1,
  250. };
  251. static const struct resource resources_spk[] __devinitconst = {
  252. [0] = {
  253. .name = PM8XXX_SPK_DEV_NAME,
  254. .start = REG_SPK_BASE,
  255. .end = REG_SPK_BASE + REG_SPK_REGISTERS - 1,
  256. .flags = IORESOURCE_IO,
  257. },
  258. };
  259. static struct mfd_cell spk_cell __devinitdata = {
  260. .name = PM8XXX_SPK_DEV_NAME,
  261. .id = -1,
  262. .num_resources = ARRAY_SIZE(resources_spk),
  263. .resources = resources_spk,
  264. };
  265. static struct mfd_cell debugfs_cell __devinitdata = {
  266. .name = "pm8xxx-debug",
  267. .id = 0,
  268. .platform_data = "pm8038-dbg",
  269. .pdata_size = sizeof("pm8038-dbg"),
  270. };
  271. static const struct resource thermal_alarm_cell_resources[] __devinitconst = {
  272. SINGLE_IRQ_RESOURCE("pm8038_tempstat_irq", PM8038_TEMPSTAT_IRQ),
  273. SINGLE_IRQ_RESOURCE("pm8038_overtemp_irq", PM8038_OVERTEMP_IRQ),
  274. };
  275. static struct pm8xxx_tm_core_data thermal_alarm_cdata = {
  276. .adc_channel = CHANNEL_DIE_TEMP,
  277. .adc_type = PM8XXX_TM_ADC_PM8XXX_ADC,
  278. .reg_addr_temp_alarm_ctrl = REG_TEMP_ALARM_CTRL,
  279. .reg_addr_temp_alarm_pwm = REG_TEMP_ALARM_PWM,
  280. .tm_name = "pm8038_tz",
  281. .irq_name_temp_stat = "pm8038_tempstat_irq",
  282. .irq_name_over_temp = "pm8038_overtemp_irq",
  283. };
  284. static struct mfd_cell thermal_alarm_cell __devinitdata = {
  285. .name = PM8XXX_TM_DEV_NAME,
  286. .id = -1,
  287. .resources = thermal_alarm_cell_resources,
  288. .num_resources = ARRAY_SIZE(thermal_alarm_cell_resources),
  289. .platform_data = &thermal_alarm_cdata,
  290. .pdata_size = sizeof(struct pm8xxx_tm_core_data),
  291. };
  292. static const struct resource batt_alarm_cell_resources[] __devinitconst = {
  293. SINGLE_IRQ_RESOURCE("pm8921_batt_alarm_irq", PM8038_BATT_ALARM_IRQ),
  294. };
  295. static struct pm8xxx_batt_alarm_core_data batt_alarm_cdata = {
  296. .irq_name = "pm8921_batt_alarm_irq",
  297. .reg_addr_threshold = REG_BATT_ALARM_THRESH,
  298. .reg_addr_ctrl1 = REG_BATT_ALARM_CTRL1,
  299. .reg_addr_ctrl2 = REG_BATT_ALARM_CTRL2,
  300. .reg_addr_pwm_ctrl = REG_BATT_ALARM_PWM_CTRL,
  301. };
  302. static struct mfd_cell batt_alarm_cell __devinitdata = {
  303. .name = PM8XXX_BATT_ALARM_DEV_NAME,
  304. .id = -1,
  305. .resources = batt_alarm_cell_resources,
  306. .num_resources = ARRAY_SIZE(batt_alarm_cell_resources),
  307. .platform_data = &batt_alarm_cdata,
  308. .pdata_size = sizeof(struct pm8xxx_batt_alarm_core_data),
  309. };
  310. static const struct resource ccadc_cell_resources[] __devinitconst = {
  311. SINGLE_IRQ_RESOURCE("PM8921_BMS_CCADC_EOC", PM8921_BMS_CCADC_EOC),
  312. };
  313. static struct mfd_cell ccadc_cell __devinitdata = {
  314. .name = PM8XXX_CCADC_DEV_NAME,
  315. .id = -1,
  316. .resources = ccadc_cell_resources,
  317. .num_resources = ARRAY_SIZE(ccadc_cell_resources),
  318. };
  319. static struct mfd_cell vibrator_cell __devinitdata = {
  320. .name = PM8XXX_VIBRATOR_DEV_NAME,
  321. .id = -1,
  322. };
  323. static struct pm8xxx_vreg regulator_data[] = {
  324. /* name pc_name ctrl test hpm_min */
  325. NLDO1200("8038_l1", 0x0AE, 0x0AF, LDO_1200),
  326. NLDO("8038_l2", "8038_l2_pc", 0x0B0, 0x0B1, LDO_150),
  327. PLDO("8038_l3", "8038_l3_pc", 0x0B2, 0x0B3, LDO_50),
  328. PLDO("8038_l4", "8038_l4_pc", 0x0B4, 0x0B5, LDO_50),
  329. PLDO("8038_l5", "8038_l5_pc", 0x0B6, 0x0B7, LDO_600),
  330. PLDO("8038_l6", "8038_l6_pc", 0x0B8, 0x0B9, LDO_600),
  331. PLDO("8038_l7", "8038_l7_pc", 0x0BA, 0x0BB, LDO_600),
  332. PLDO("8038_l8", "8038_l8_pc", 0x0BC, 0x0BD, LDO_300),
  333. PLDO("8038_l9", "8038_l9_pc", 0x0BE, 0x0BF, LDO_300),
  334. PLDO("8038_l10", "8038_l10_pc", 0x0C0, 0x0C1, LDO_600),
  335. PLDO("8038_l11", "8038_l11_pc", 0x0C2, 0x0C3, LDO_600),
  336. NLDO("8038_l12", "8038_l12_pc", 0x0C4, 0x0C5, LDO_300),
  337. PLDO("8038_l14", "8038_l14_pc", 0x0C8, 0x0C9, LDO_50),
  338. PLDO("8038_l15", "8038_l15_pc", 0x0CA, 0x0CB, LDO_150),
  339. NLDO1200("8038_l16", 0x0CC, 0x0CD, LDO_1200),
  340. PLDO("8038_l17", "8038_l17_pc", 0x0CE, 0x0CF, LDO_150),
  341. PLDO("8038_l18", "8038_l18_pc", 0x0D0, 0x0D1, LDO_50),
  342. NLDO1200("8038_l19", 0x0D2, 0x0D3, LDO_1200),
  343. NLDO1200("8038_l20", 0x0D4, 0x0D5, LDO_1200),
  344. PLDO("8038_l21", "8038_l21_pc", 0x0D6, 0x0D7, LDO_150),
  345. PLDO("8038_l22", "8038_l22_pc", 0x0D8, 0x0D9, LDO_50),
  346. PLDO("8038_l23", "8038_l23_pc", 0x0DA, 0x0DB, LDO_50),
  347. NLDO1200("8038_l24", 0x0DC, 0x0DD, LDO_1200),
  348. NLDO("8038_l26", "8038_l26_pc", 0x0E0, 0x0E1, LDO_150),
  349. NLDO1200("8038_l27", 0x0E2, 0x0E3, LDO_1200),
  350. /* name pc_name ctrl test2 clk sleep hpm_min */
  351. SMPS("8038_s1", "8038_s1_pc", 0x1E0, 0x1E5, 0x009, 0x1E2, SMPS_1500),
  352. SMPS("8038_s2", "8038_s2_pc", 0x1D8, 0x1DD, 0x00A, 0x1DA, SMPS_1500),
  353. SMPS("8038_s3", "8038_s3_pc", 0x1D0, 0x1D5, 0x00B, 0x1D2, SMPS_1500),
  354. SMPS("8038_s4", "8038_s4_pc", 0x1E8, 0x1ED, 0x00C, 0x1EA, SMPS_1500),
  355. /* name ctrl fts_cnfg1 pfm pwr_cnfg hpm_min */
  356. FTSMPS("8038_s5", 0x025, 0x02E, 0x026, 0x032, SMPS_2000),
  357. FTSMPS("8038_s6", 0x036, 0x03F, 0x037, 0x043, SMPS_2000),
  358. /* name pc_name ctrl test */
  359. VS("8038_lvs1", "8038_lvs1_pc", 0x060, 0x061),
  360. VS("8038_lvs2", "8038_lvs2_pc", 0x062, 0x063),
  361. };
  362. #define MAX_NAME_COMPARISON_LEN 32
  363. static int __devinit match_regulator(
  364. struct pm8xxx_regulator_core_platform_data *core_data, const char *name)
  365. {
  366. int found = 0;
  367. int i;
  368. for (i = 0; i < ARRAY_SIZE(regulator_data); i++) {
  369. if (regulator_data[i].rdesc.name
  370. && strncmp(regulator_data[i].rdesc.name, name,
  371. MAX_NAME_COMPARISON_LEN) == 0) {
  372. core_data->is_pin_controlled = false;
  373. core_data->vreg = &regulator_data[i];
  374. found = 1;
  375. break;
  376. } else if (regulator_data[i].rdesc_pc.name
  377. && strncmp(regulator_data[i].rdesc_pc.name, name,
  378. MAX_NAME_COMPARISON_LEN) == 0) {
  379. core_data->is_pin_controlled = true;
  380. core_data->vreg = &regulator_data[i];
  381. found = 1;
  382. break;
  383. }
  384. }
  385. if (!found)
  386. pr_err("could not find a match for regulator: %s\n", name);
  387. return found;
  388. }
  389. static int __devinit
  390. pm8038_add_regulators(const struct pm8038_platform_data *pdata,
  391. struct pm8038 *pmic, int irq_base)
  392. {
  393. int ret = 0;
  394. struct mfd_cell *mfd_regulators;
  395. struct pm8xxx_regulator_core_platform_data *cdata;
  396. int i;
  397. /* Add one device for each regulator used by the board. */
  398. mfd_regulators = kzalloc(sizeof(struct mfd_cell)
  399. * (pdata->num_regulators), GFP_KERNEL);
  400. if (!mfd_regulators) {
  401. pr_err("Cannot allocate %d bytes for pm8038 regulator "
  402. "mfd cells\n", sizeof(struct mfd_cell)
  403. * (pdata->num_regulators));
  404. return -ENOMEM;
  405. }
  406. cdata = kzalloc(sizeof(struct pm8xxx_regulator_core_platform_data)
  407. * pdata->num_regulators, GFP_KERNEL);
  408. if (!cdata) {
  409. pr_err("Cannot allocate %d bytes for pm8038 regulator "
  410. "core data\n", pdata->num_regulators
  411. * sizeof(struct pm8xxx_regulator_core_platform_data));
  412. kfree(mfd_regulators);
  413. return -ENOMEM;
  414. }
  415. for (i = 0; i < ARRAY_SIZE(regulator_data); i++)
  416. mutex_init(&regulator_data[i].pc_lock);
  417. for (i = 0; i < pdata->num_regulators; i++) {
  418. if (!pdata->regulator_pdatas[i].init_data.constraints.name) {
  419. pr_err("name missing for regulator %d\n", i);
  420. ret = -EINVAL;
  421. goto bail;
  422. }
  423. if (!match_regulator(&cdata[i],
  424. pdata->regulator_pdatas[i].init_data.constraints.name)) {
  425. ret = -ENODEV;
  426. goto bail;
  427. }
  428. cdata[i].pdata = &(pdata->regulator_pdatas[i]);
  429. mfd_regulators[i].name = PM8XXX_REGULATOR_DEV_NAME;
  430. mfd_regulators[i].id = cdata[i].pdata->id;
  431. mfd_regulators[i].platform_data = &cdata[i];
  432. mfd_regulators[i].pdata_size =
  433. sizeof(struct pm8xxx_regulator_core_platform_data);
  434. }
  435. ret = mfd_add_devices(pmic->dev, 0, mfd_regulators,
  436. pdata->num_regulators, NULL, irq_base);
  437. if (ret)
  438. goto bail;
  439. pmic->mfd_regulators = mfd_regulators;
  440. pmic->regulator_cdata = cdata;
  441. return ret;
  442. bail:
  443. for (i = 0; i < ARRAY_SIZE(regulator_data); i++)
  444. mutex_destroy(&regulator_data[i].pc_lock);
  445. kfree(mfd_regulators);
  446. kfree(cdata);
  447. return ret;
  448. }
  449. static int __devinit
  450. pm8038_add_subdevices(const struct pm8038_platform_data *pdata,
  451. struct pm8038 *pmic)
  452. {
  453. int ret = 0, irq_base = 0;
  454. struct pm_irq_chip *irq_chip;
  455. if (pdata->irq_pdata) {
  456. pdata->irq_pdata->irq_cdata.nirqs = PM8038_NR_IRQS;
  457. pdata->irq_pdata->irq_cdata.base_addr = REG_IRQ_BASE;
  458. irq_base = pdata->irq_pdata->irq_base;
  459. irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata);
  460. if (IS_ERR(irq_chip)) {
  461. pr_err("Failed to init interrupts ret=%ld\n",
  462. PTR_ERR(irq_chip));
  463. return PTR_ERR(irq_chip);
  464. }
  465. pmic->irq_chip = irq_chip;
  466. }
  467. if (pdata->gpio_pdata) {
  468. pdata->gpio_pdata->gpio_cdata.ngpios = PM8038_NR_GPIOS;
  469. gpio_cell.platform_data = pdata->gpio_pdata;
  470. gpio_cell.pdata_size = sizeof(struct pm8xxx_gpio_platform_data);
  471. ret = mfd_add_devices(pmic->dev, 0, &gpio_cell, 1,
  472. NULL, irq_base);
  473. if (ret) {
  474. pr_err("Failed to add gpio subdevice ret=%d\n", ret);
  475. goto bail;
  476. }
  477. }
  478. if (pdata->mpp_pdata) {
  479. pdata->mpp_pdata->core_data.nmpps = PM8038_NR_MPPS;
  480. pdata->mpp_pdata->core_data.base_addr = REG_MPP_BASE;
  481. mpp_cell.platform_data = pdata->mpp_pdata;
  482. mpp_cell.pdata_size = sizeof(struct pm8xxx_mpp_platform_data);
  483. ret = mfd_add_devices(pmic->dev, 0, &mpp_cell, 1, NULL,
  484. irq_base);
  485. if (ret) {
  486. pr_err("Failed to add mpp subdevice ret=%d\n", ret);
  487. goto bail;
  488. }
  489. }
  490. if (pdata->rtc_pdata) {
  491. rtc_cell.platform_data = pdata->rtc_pdata;
  492. rtc_cell.pdata_size = sizeof(struct pm8xxx_rtc_platform_data);
  493. ret = mfd_add_devices(pmic->dev, 0, &rtc_cell, 1, NULL,
  494. irq_base);
  495. if (ret) {
  496. pr_err("Failed to add rtc subdevice ret=%d\n", ret);
  497. goto bail;
  498. }
  499. }
  500. if (pdata->pwrkey_pdata) {
  501. pwrkey_cell.platform_data = pdata->pwrkey_pdata;
  502. pwrkey_cell.pdata_size =
  503. sizeof(struct pm8xxx_pwrkey_platform_data);
  504. ret = mfd_add_devices(pmic->dev, 0, &pwrkey_cell, 1, NULL,
  505. irq_base);
  506. if (ret) {
  507. pr_err("Failed to add pwrkey subdevice ret=%d\n", ret);
  508. goto bail;
  509. }
  510. }
  511. ret = mfd_add_devices(pmic->dev, 0, &pwm_cell, 1, NULL, 0);
  512. if (ret) {
  513. pr_err("Failed to add pwm subdevice ret=%d\n", ret);
  514. goto bail;
  515. }
  516. if (pdata->misc_pdata) {
  517. misc_cell.platform_data = pdata->misc_pdata;
  518. misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data);
  519. ret = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL,
  520. irq_base);
  521. if (ret) {
  522. pr_err("Failed to add misc subdevice ret=%d\n", ret);
  523. goto bail;
  524. }
  525. }
  526. if (pdata->leds_pdata) {
  527. leds_cell.platform_data = pdata->leds_pdata;
  528. leds_cell.pdata_size = sizeof(struct pm8xxx_led_platform_data);
  529. ret = mfd_add_devices(pmic->dev, 0, &leds_cell, 1, NULL, 0);
  530. if (ret) {
  531. pr_err("Failed to add leds subdevice ret=%d\n", ret);
  532. goto bail;
  533. }
  534. }
  535. if (pdata->vibrator_pdata) {
  536. vibrator_cell.platform_data = pdata->vibrator_pdata;
  537. vibrator_cell.pdata_size =
  538. sizeof(struct pm8xxx_vibrator_platform_data);
  539. ret = mfd_add_devices(pmic->dev, 0, &vibrator_cell, 1, NULL, 0);
  540. if (ret) {
  541. pr_err("Failed to add vibrator ret=%d\n", ret);
  542. goto bail;
  543. }
  544. }
  545. if (pdata->spk_pdata) {
  546. spk_cell.platform_data = pdata->spk_pdata;
  547. spk_cell.pdata_size = sizeof(struct pm8xxx_spk_platform_data);
  548. ret = mfd_add_devices(pmic->dev, 0, &spk_cell, 1, NULL, 0);
  549. if (ret) {
  550. pr_err("Failed to add spk subdevice ret=%d\n", ret);
  551. goto bail;
  552. }
  553. }
  554. if (pdata->num_regulators > 0 && pdata->regulator_pdatas) {
  555. ret = pm8038_add_regulators(pdata, pmic, irq_base);
  556. if (ret) {
  557. pr_err("Failed to add regulator subdevices ret=%d\n",
  558. ret);
  559. goto bail;
  560. }
  561. }
  562. ret = mfd_add_devices(pmic->dev, 0, &debugfs_cell, 1, NULL, irq_base);
  563. if (ret) {
  564. pr_err("Failed to add debugfs subdevice ret=%d\n", ret);
  565. goto bail;
  566. }
  567. if (pdata->adc_pdata) {
  568. adc_cell.platform_data = pdata->adc_pdata;
  569. adc_cell.pdata_size =
  570. sizeof(struct pm8xxx_adc_platform_data);
  571. ret = mfd_add_devices(pmic->dev, 0, &adc_cell, 1, NULL,
  572. irq_base);
  573. if (ret) {
  574. pr_err("Failed to add adc subdevices ret=%d\n",
  575. ret);
  576. }
  577. }
  578. if (pdata->charger_pdata) {
  579. pdata->charger_pdata->charger_cdata.vbat_channel = CHANNEL_VBAT;
  580. pdata->charger_pdata->charger_cdata.batt_temp_channel
  581. = CHANNEL_BATT_THERM;
  582. pdata->charger_pdata->charger_cdata.batt_id_channel
  583. = CHANNEL_BATT_ID;
  584. charger_cell.platform_data = pdata->charger_pdata;
  585. charger_cell.pdata_size =
  586. sizeof(struct pm8921_charger_platform_data);
  587. ret = mfd_add_devices(pmic->dev, 0, &charger_cell, 1, NULL,
  588. irq_base);
  589. if (ret) {
  590. pr_err("Failed to add charger subdevice ret=%d\n", ret);
  591. goto bail;
  592. }
  593. }
  594. if (pdata->bms_pdata) {
  595. pdata->bms_pdata->bms_cdata.batt_temp_channel
  596. = CHANNEL_BATT_THERM;
  597. pdata->bms_pdata->bms_cdata.vbat_channel = CHANNEL_VBAT;
  598. pdata->bms_pdata->bms_cdata.ref625mv_channel = CHANNEL_625MV;
  599. pdata->bms_pdata->bms_cdata.ref1p25v_channel = CHANNEL_125V;
  600. pdata->bms_pdata->bms_cdata.batt_id_channel = CHANNEL_BATT_ID;
  601. bms_cell.platform_data = pdata->bms_pdata;
  602. bms_cell.pdata_size = sizeof(struct pm8921_bms_platform_data);
  603. ret = mfd_add_devices(pmic->dev, 0, &bms_cell, 1, NULL,
  604. irq_base);
  605. if (ret) {
  606. pr_err("Failed to add bms subdevice ret=%d\n", ret);
  607. goto bail;
  608. }
  609. }
  610. ret = mfd_add_devices(pmic->dev, 0, &thermal_alarm_cell, 1, NULL,
  611. irq_base);
  612. if (ret) {
  613. pr_err("Failed to add thermal alarm subdevice ret=%d\n", ret);
  614. goto bail;
  615. }
  616. ret = mfd_add_devices(pmic->dev, 0, &batt_alarm_cell, 1, NULL,
  617. irq_base);
  618. if (ret) {
  619. pr_err("Failed to add battery alarm subdevice ret=%d\n", ret);
  620. goto bail;
  621. }
  622. if (pdata->ccadc_pdata) {
  623. pdata->ccadc_pdata->ccadc_cdata.batt_temp_channel
  624. = CHANNEL_BATT_THERM;
  625. ccadc_cell.platform_data = pdata->ccadc_pdata;
  626. ccadc_cell.pdata_size =
  627. sizeof(struct pm8xxx_ccadc_platform_data);
  628. ret = mfd_add_devices(pmic->dev, 0, &ccadc_cell, 1, NULL,
  629. irq_base);
  630. if (ret) {
  631. pr_err("Failed to add ccadc subdevice ret=%d\n", ret);
  632. goto bail;
  633. }
  634. }
  635. return 0;
  636. bail:
  637. if (pmic->irq_chip) {
  638. pm8xxx_irq_exit(pmic->irq_chip);
  639. pmic->irq_chip = NULL;
  640. }
  641. return ret;
  642. }
  643. static const char * const pm8038_rev_names[] = {
  644. [PM8XXX_REVISION_8038_TEST] = "test",
  645. [PM8XXX_REVISION_8038_1p0] = "1.0",
  646. [PM8XXX_REVISION_8038_2p0] = "2.0",
  647. [PM8XXX_REVISION_8038_2p1] = "2.1",
  648. };
  649. static int __devinit pm8038_probe(struct platform_device *pdev)
  650. {
  651. const struct pm8038_platform_data *pdata = pdev->dev.platform_data;
  652. const char *revision_name = "unknown";
  653. struct pm8038 *pmic;
  654. enum pm8xxx_version version;
  655. int revision;
  656. int rc;
  657. u8 val;
  658. if (!pdata) {
  659. pr_err("missing platform data\n");
  660. return -EINVAL;
  661. }
  662. pmic = kzalloc(sizeof(struct pm8038), GFP_KERNEL);
  663. if (!pmic) {
  664. pr_err("Cannot alloc pm8038 struct\n");
  665. return -ENOMEM;
  666. }
  667. /* Read PMIC chip revision */
  668. rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val));
  669. if (rc) {
  670. pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
  671. goto err_read_rev;
  672. }
  673. pr_info("PMIC revision 1: PM8038 rev %02X\n", val);
  674. pmic->rev_registers = val;
  675. /* Read PMIC chip revision 2 */
  676. rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val));
  677. if (rc) {
  678. pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
  679. REG_HWREV_2, rc);
  680. goto err_read_rev;
  681. }
  682. pr_info("PMIC revision 2: PM8038 rev %02X\n", val);
  683. pmic->rev_registers |= val << BITS_PER_BYTE;
  684. pmic->dev = &pdev->dev;
  685. pm8038_drvdata.pm_chip_data = pmic;
  686. platform_set_drvdata(pdev, &pm8038_drvdata);
  687. /* Print out human readable version and revision names. */
  688. version = pm8xxx_get_version(pmic->dev);
  689. if (version == PM8XXX_VERSION_8038) {
  690. revision = pm8xxx_get_revision(pmic->dev);
  691. if (revision >= 0 && revision < ARRAY_SIZE(pm8038_rev_names))
  692. revision_name = pm8038_rev_names[revision];
  693. pr_info("PMIC version: PM8038 ver %s\n", revision_name);
  694. } else {
  695. WARN_ON(version != PM8XXX_VERSION_8038);
  696. }
  697. /* Log human readable restart reason */
  698. rc = msm_ssbi_read(pdev->dev.parent, REG_PM8038_PON_CNTRL_3, &val, 1);
  699. if (rc) {
  700. pr_err("Cannot read restart reason rc=%d\n", rc);
  701. goto err_read_rev;
  702. }
  703. val &= PM8XXX_RESTART_REASON_MASK;
  704. pr_info("PMIC Restart Reason: %s\n", pm8xxx_restart_reason_str[val]);
  705. pmic->restart_reason = val;
  706. rc = pm8038_add_subdevices(pdata, pmic);
  707. if (rc) {
  708. pr_err("Cannot add subdevices rc=%d\n", rc);
  709. goto err;
  710. }
  711. return 0;
  712. err:
  713. mfd_remove_devices(pmic->dev);
  714. platform_set_drvdata(pdev, NULL);
  715. kfree(pmic->mfd_regulators);
  716. kfree(pmic->regulator_cdata);
  717. err_read_rev:
  718. kfree(pmic);
  719. return rc;
  720. }
  721. static int __devexit pm8038_remove(struct platform_device *pdev)
  722. {
  723. struct pm8xxx_drvdata *drvdata;
  724. struct pm8038 *pmic = NULL;
  725. int i;
  726. drvdata = platform_get_drvdata(pdev);
  727. if (drvdata)
  728. pmic = drvdata->pm_chip_data;
  729. if (pmic) {
  730. if (pmic->dev)
  731. mfd_remove_devices(pmic->dev);
  732. if (pmic->irq_chip) {
  733. pm8xxx_irq_exit(pmic->irq_chip);
  734. pmic->irq_chip = NULL;
  735. }
  736. if (pmic->mfd_regulators) {
  737. for (i = 0; i < ARRAY_SIZE(regulator_data); i++)
  738. mutex_destroy(&regulator_data[i].pc_lock);
  739. }
  740. kfree(pmic->mfd_regulators);
  741. kfree(pmic->regulator_cdata);
  742. kfree(pmic);
  743. }
  744. platform_set_drvdata(pdev, NULL);
  745. return 0;
  746. }
  747. static struct platform_driver pm8038_driver = {
  748. .probe = pm8038_probe,
  749. .remove = __devexit_p(pm8038_remove),
  750. .driver = {
  751. .name = PM8038_CORE_DEV_NAME,
  752. .owner = THIS_MODULE,
  753. },
  754. };
  755. static int __init pm8038_init(void)
  756. {
  757. return platform_driver_register(&pm8038_driver);
  758. }
  759. postcore_initcall(pm8038_init);
  760. static void __exit pm8038_exit(void)
  761. {
  762. platform_driver_unregister(&pm8038_driver);
  763. }
  764. module_exit(pm8038_exit);
  765. MODULE_LICENSE("GPL v2");
  766. MODULE_DESCRIPTION("PMIC 8038 core driver");
  767. MODULE_VERSION("1.0");
  768. MODULE_ALIAS("platform:pm8038-core");