tps68470_pmic.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. /*
  2. * TI TPS68470 PMIC operation region driver
  3. *
  4. * Copyright (C) 2017 Intel Corporation. All rights reserved.
  5. *
  6. * Author: Rajmohan Mani <rajmohan.mani@intel.com>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License version
  10. * 2 as published by the Free Software Foundation.
  11. *
  12. * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  13. * kind, whether express or implied; without even the implied warranty
  14. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * Based on drivers/acpi/pmic/intel_pmic* drivers
  18. */
  19. #include <linux/acpi.h>
  20. #include <linux/mfd/tps68470.h>
  21. #include <linux/init.h>
  22. #include <linux/platform_device.h>
  23. #include <linux/regmap.h>
  24. struct tps68470_pmic_table {
  25. u32 address; /* operation region address */
  26. u32 reg; /* corresponding register */
  27. u32 bitmask; /* bit mask for power, clock */
  28. };
  29. #define TI_PMIC_POWER_OPREGION_ID 0xB0
  30. #define TI_PMIC_VR_VAL_OPREGION_ID 0xB1
  31. #define TI_PMIC_CLOCK_OPREGION_ID 0xB2
  32. #define TI_PMIC_CLKFREQ_OPREGION_ID 0xB3
  33. struct tps68470_pmic_opregion {
  34. struct mutex lock;
  35. struct regmap *regmap;
  36. };
  37. #define S_IO_I2C_EN (BIT(0) | BIT(1))
  38. static const struct tps68470_pmic_table power_table[] = {
  39. {
  40. .address = 0x00,
  41. .reg = TPS68470_REG_S_I2C_CTL,
  42. .bitmask = S_IO_I2C_EN,
  43. /* S_I2C_CTL */
  44. },
  45. {
  46. .address = 0x04,
  47. .reg = TPS68470_REG_VCMCTL,
  48. .bitmask = BIT(0),
  49. /* VCMCTL */
  50. },
  51. {
  52. .address = 0x08,
  53. .reg = TPS68470_REG_VAUX1CTL,
  54. .bitmask = BIT(0),
  55. /* VAUX1_CTL */
  56. },
  57. {
  58. .address = 0x0C,
  59. .reg = TPS68470_REG_VAUX2CTL,
  60. .bitmask = BIT(0),
  61. /* VAUX2CTL */
  62. },
  63. {
  64. .address = 0x10,
  65. .reg = TPS68470_REG_VACTL,
  66. .bitmask = BIT(0),
  67. /* VACTL */
  68. },
  69. {
  70. .address = 0x14,
  71. .reg = TPS68470_REG_VDCTL,
  72. .bitmask = BIT(0),
  73. /* VDCTL */
  74. },
  75. };
  76. /* Table to set voltage regulator value */
  77. static const struct tps68470_pmic_table vr_val_table[] = {
  78. {
  79. .address = 0x00,
  80. .reg = TPS68470_REG_VSIOVAL,
  81. .bitmask = TPS68470_VSIOVAL_IOVOLT_MASK,
  82. /* TPS68470_REG_VSIOVAL */
  83. },
  84. {
  85. .address = 0x04,
  86. .reg = TPS68470_REG_VIOVAL,
  87. .bitmask = TPS68470_VIOVAL_IOVOLT_MASK,
  88. /* TPS68470_REG_VIOVAL */
  89. },
  90. {
  91. .address = 0x08,
  92. .reg = TPS68470_REG_VCMVAL,
  93. .bitmask = TPS68470_VCMVAL_VCVOLT_MASK,
  94. /* TPS68470_REG_VCMVAL */
  95. },
  96. {
  97. .address = 0x0C,
  98. .reg = TPS68470_REG_VAUX1VAL,
  99. .bitmask = TPS68470_VAUX1VAL_AUX1VOLT_MASK,
  100. /* TPS68470_REG_VAUX1VAL */
  101. },
  102. {
  103. .address = 0x10,
  104. .reg = TPS68470_REG_VAUX2VAL,
  105. .bitmask = TPS68470_VAUX2VAL_AUX2VOLT_MASK,
  106. /* TPS68470_REG_VAUX2VAL */
  107. },
  108. {
  109. .address = 0x14,
  110. .reg = TPS68470_REG_VAVAL,
  111. .bitmask = TPS68470_VAVAL_AVOLT_MASK,
  112. /* TPS68470_REG_VAVAL */
  113. },
  114. {
  115. .address = 0x18,
  116. .reg = TPS68470_REG_VDVAL,
  117. .bitmask = TPS68470_VDVAL_DVOLT_MASK,
  118. /* TPS68470_REG_VDVAL */
  119. },
  120. };
  121. /* Table to configure clock frequency */
  122. static const struct tps68470_pmic_table clk_freq_table[] = {
  123. {
  124. .address = 0x00,
  125. .reg = TPS68470_REG_POSTDIV2,
  126. .bitmask = BIT(0) | BIT(1),
  127. /* TPS68470_REG_POSTDIV2 */
  128. },
  129. {
  130. .address = 0x04,
  131. .reg = TPS68470_REG_BOOSTDIV,
  132. .bitmask = 0x1F,
  133. /* TPS68470_REG_BOOSTDIV */
  134. },
  135. {
  136. .address = 0x08,
  137. .reg = TPS68470_REG_BUCKDIV,
  138. .bitmask = 0x0F,
  139. /* TPS68470_REG_BUCKDIV */
  140. },
  141. {
  142. .address = 0x0C,
  143. .reg = TPS68470_REG_PLLSWR,
  144. .bitmask = 0x13,
  145. /* TPS68470_REG_PLLSWR */
  146. },
  147. {
  148. .address = 0x10,
  149. .reg = TPS68470_REG_XTALDIV,
  150. .bitmask = 0xFF,
  151. /* TPS68470_REG_XTALDIV */
  152. },
  153. {
  154. .address = 0x14,
  155. .reg = TPS68470_REG_PLLDIV,
  156. .bitmask = 0xFF,
  157. /* TPS68470_REG_PLLDIV */
  158. },
  159. {
  160. .address = 0x18,
  161. .reg = TPS68470_REG_POSTDIV,
  162. .bitmask = 0x83,
  163. /* TPS68470_REG_POSTDIV */
  164. },
  165. };
  166. /* Table to configure and enable clocks */
  167. static const struct tps68470_pmic_table clk_table[] = {
  168. {
  169. .address = 0x00,
  170. .reg = TPS68470_REG_PLLCTL,
  171. .bitmask = 0xF5,
  172. /* TPS68470_REG_PLLCTL */
  173. },
  174. {
  175. .address = 0x04,
  176. .reg = TPS68470_REG_PLLCTL2,
  177. .bitmask = BIT(0),
  178. /* TPS68470_REG_PLLCTL2 */
  179. },
  180. {
  181. .address = 0x08,
  182. .reg = TPS68470_REG_CLKCFG1,
  183. .bitmask = TPS68470_CLKCFG1_MODE_A_MASK |
  184. TPS68470_CLKCFG1_MODE_B_MASK,
  185. /* TPS68470_REG_CLKCFG1 */
  186. },
  187. {
  188. .address = 0x0C,
  189. .reg = TPS68470_REG_CLKCFG2,
  190. .bitmask = TPS68470_CLKCFG1_MODE_A_MASK |
  191. TPS68470_CLKCFG1_MODE_B_MASK,
  192. /* TPS68470_REG_CLKCFG2 */
  193. },
  194. };
  195. static int pmic_get_reg_bit(u64 address,
  196. const struct tps68470_pmic_table *table,
  197. const unsigned int table_size, int *reg,
  198. int *bitmask)
  199. {
  200. u64 i;
  201. i = address / 4;
  202. if (i >= table_size)
  203. return -ENOENT;
  204. if (!reg || !bitmask)
  205. return -EINVAL;
  206. *reg = table[i].reg;
  207. *bitmask = table[i].bitmask;
  208. return 0;
  209. }
  210. static int tps68470_pmic_get_power(struct regmap *regmap, int reg,
  211. int bitmask, u64 *value)
  212. {
  213. unsigned int data;
  214. if (regmap_read(regmap, reg, &data))
  215. return -EIO;
  216. *value = (data & bitmask) ? 1 : 0;
  217. return 0;
  218. }
  219. static int tps68470_pmic_get_vr_val(struct regmap *regmap, int reg,
  220. int bitmask, u64 *value)
  221. {
  222. unsigned int data;
  223. if (regmap_read(regmap, reg, &data))
  224. return -EIO;
  225. *value = data & bitmask;
  226. return 0;
  227. }
  228. static int tps68470_pmic_get_clk(struct regmap *regmap, int reg,
  229. int bitmask, u64 *value)
  230. {
  231. unsigned int data;
  232. if (regmap_read(regmap, reg, &data))
  233. return -EIO;
  234. *value = (data & bitmask) ? 1 : 0;
  235. return 0;
  236. }
  237. static int tps68470_pmic_get_clk_freq(struct regmap *regmap, int reg,
  238. int bitmask, u64 *value)
  239. {
  240. unsigned int data;
  241. if (regmap_read(regmap, reg, &data))
  242. return -EIO;
  243. *value = data & bitmask;
  244. return 0;
  245. }
  246. static int ti_tps68470_regmap_update_bits(struct regmap *regmap, int reg,
  247. int bitmask, u64 value)
  248. {
  249. return regmap_update_bits(regmap, reg, bitmask, value);
  250. }
  251. static acpi_status tps68470_pmic_common_handler(u32 function,
  252. acpi_physical_address address,
  253. u32 bits, u64 *value,
  254. void *region_context,
  255. int (*get)(struct regmap *,
  256. int, int, u64 *),
  257. int (*update)(struct regmap *,
  258. int, int, u64),
  259. const struct tps68470_pmic_table *tbl,
  260. unsigned int tbl_size)
  261. {
  262. struct tps68470_pmic_opregion *opregion = region_context;
  263. struct regmap *regmap = opregion->regmap;
  264. int reg, ret, bitmask;
  265. if (bits != 32)
  266. return AE_BAD_PARAMETER;
  267. ret = pmic_get_reg_bit(address, tbl, tbl_size, &reg, &bitmask);
  268. if (ret < 0)
  269. return AE_BAD_PARAMETER;
  270. if (function == ACPI_WRITE && *value > bitmask)
  271. return AE_BAD_PARAMETER;
  272. mutex_lock(&opregion->lock);
  273. ret = (function == ACPI_READ) ?
  274. get(regmap, reg, bitmask, value) :
  275. update(regmap, reg, bitmask, *value);
  276. mutex_unlock(&opregion->lock);
  277. return ret ? AE_ERROR : AE_OK;
  278. }
  279. static acpi_status tps68470_pmic_cfreq_handler(u32 function,
  280. acpi_physical_address address,
  281. u32 bits, u64 *value,
  282. void *handler_context,
  283. void *region_context)
  284. {
  285. return tps68470_pmic_common_handler(function, address, bits, value,
  286. region_context,
  287. tps68470_pmic_get_clk_freq,
  288. ti_tps68470_regmap_update_bits,
  289. clk_freq_table,
  290. ARRAY_SIZE(clk_freq_table));
  291. }
  292. static acpi_status tps68470_pmic_clk_handler(u32 function,
  293. acpi_physical_address address, u32 bits,
  294. u64 *value, void *handler_context,
  295. void *region_context)
  296. {
  297. return tps68470_pmic_common_handler(function, address, bits, value,
  298. region_context,
  299. tps68470_pmic_get_clk,
  300. ti_tps68470_regmap_update_bits,
  301. clk_table,
  302. ARRAY_SIZE(clk_table));
  303. }
  304. static acpi_status tps68470_pmic_vrval_handler(u32 function,
  305. acpi_physical_address address,
  306. u32 bits, u64 *value,
  307. void *handler_context,
  308. void *region_context)
  309. {
  310. return tps68470_pmic_common_handler(function, address, bits, value,
  311. region_context,
  312. tps68470_pmic_get_vr_val,
  313. ti_tps68470_regmap_update_bits,
  314. vr_val_table,
  315. ARRAY_SIZE(vr_val_table));
  316. }
  317. static acpi_status tps68470_pmic_pwr_handler(u32 function,
  318. acpi_physical_address address,
  319. u32 bits, u64 *value,
  320. void *handler_context,
  321. void *region_context)
  322. {
  323. if (bits != 32)
  324. return AE_BAD_PARAMETER;
  325. /* set/clear for bit 0, bits 0 and 1 together */
  326. if (function == ACPI_WRITE &&
  327. !(*value == 0 || *value == 1 || *value == 3)) {
  328. return AE_BAD_PARAMETER;
  329. }
  330. return tps68470_pmic_common_handler(function, address, bits, value,
  331. region_context,
  332. tps68470_pmic_get_power,
  333. ti_tps68470_regmap_update_bits,
  334. power_table,
  335. ARRAY_SIZE(power_table));
  336. }
  337. static int tps68470_pmic_opregion_probe(struct platform_device *pdev)
  338. {
  339. struct regmap *tps68470_regmap = dev_get_drvdata(pdev->dev.parent);
  340. acpi_handle handle = ACPI_HANDLE(pdev->dev.parent);
  341. struct device *dev = &pdev->dev;
  342. struct tps68470_pmic_opregion *opregion;
  343. acpi_status status;
  344. if (!dev || !tps68470_regmap) {
  345. dev_warn(dev, "dev or regmap is NULL\n");
  346. return -EINVAL;
  347. }
  348. if (!handle) {
  349. dev_warn(dev, "acpi handle is NULL\n");
  350. return -ENODEV;
  351. }
  352. opregion = devm_kzalloc(dev, sizeof(*opregion), GFP_KERNEL);
  353. if (!opregion)
  354. return -ENOMEM;
  355. mutex_init(&opregion->lock);
  356. opregion->regmap = tps68470_regmap;
  357. status = acpi_install_address_space_handler(handle,
  358. TI_PMIC_POWER_OPREGION_ID,
  359. tps68470_pmic_pwr_handler,
  360. NULL, opregion);
  361. if (ACPI_FAILURE(status))
  362. goto out_mutex_destroy;
  363. status = acpi_install_address_space_handler(handle,
  364. TI_PMIC_VR_VAL_OPREGION_ID,
  365. tps68470_pmic_vrval_handler,
  366. NULL, opregion);
  367. if (ACPI_FAILURE(status))
  368. goto out_remove_power_handler;
  369. status = acpi_install_address_space_handler(handle,
  370. TI_PMIC_CLOCK_OPREGION_ID,
  371. tps68470_pmic_clk_handler,
  372. NULL, opregion);
  373. if (ACPI_FAILURE(status))
  374. goto out_remove_vr_val_handler;
  375. status = acpi_install_address_space_handler(handle,
  376. TI_PMIC_CLKFREQ_OPREGION_ID,
  377. tps68470_pmic_cfreq_handler,
  378. NULL, opregion);
  379. if (ACPI_FAILURE(status))
  380. goto out_remove_clk_handler;
  381. return 0;
  382. out_remove_clk_handler:
  383. acpi_remove_address_space_handler(handle, TI_PMIC_CLOCK_OPREGION_ID,
  384. tps68470_pmic_clk_handler);
  385. out_remove_vr_val_handler:
  386. acpi_remove_address_space_handler(handle, TI_PMIC_VR_VAL_OPREGION_ID,
  387. tps68470_pmic_vrval_handler);
  388. out_remove_power_handler:
  389. acpi_remove_address_space_handler(handle, TI_PMIC_POWER_OPREGION_ID,
  390. tps68470_pmic_pwr_handler);
  391. out_mutex_destroy:
  392. mutex_destroy(&opregion->lock);
  393. return -ENODEV;
  394. }
  395. static struct platform_driver tps68470_pmic_opregion_driver = {
  396. .probe = tps68470_pmic_opregion_probe,
  397. .driver = {
  398. .name = "tps68470_pmic_opregion",
  399. },
  400. };
  401. builtin_platform_driver(tps68470_pmic_opregion_driver)