intel_pmic_bytcrc.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Intel Bay Trail Crystal Cove PMIC operation region driver
  4. *
  5. * Copyright (C) 2014 Intel Corporation. All rights reserved.
  6. */
  7. #include <linux/acpi.h>
  8. #include <linux/init.h>
  9. #include <linux/mfd/intel_soc_pmic.h>
  10. #include <linux/platform_device.h>
  11. #include <linux/regmap.h>
  12. #include "intel_pmic.h"
  13. #define PWR_SOURCE_SELECT BIT(1)
  14. #define PMIC_A0LOCK_REG 0xc5
  15. static struct pmic_table power_table[] = {
  16. /* {
  17. .address = 0x00,
  18. .reg = ??,
  19. .bit = ??,
  20. }, ** VSYS */
  21. {
  22. .address = 0x04,
  23. .reg = 0x63,
  24. .bit = 0x00,
  25. }, /* SYSX -> VSYS_SX */
  26. {
  27. .address = 0x08,
  28. .reg = 0x62,
  29. .bit = 0x00,
  30. }, /* SYSU -> VSYS_U */
  31. {
  32. .address = 0x0c,
  33. .reg = 0x64,
  34. .bit = 0x00,
  35. }, /* SYSS -> VSYS_S */
  36. {
  37. .address = 0x10,
  38. .reg = 0x6a,
  39. .bit = 0x00,
  40. }, /* V50S -> V5P0S */
  41. {
  42. .address = 0x14,
  43. .reg = 0x6b,
  44. .bit = 0x00,
  45. }, /* HOST -> VHOST, USB2/3 host */
  46. {
  47. .address = 0x18,
  48. .reg = 0x6c,
  49. .bit = 0x00,
  50. }, /* VBUS -> VBUS, USB2/3 OTG */
  51. {
  52. .address = 0x1c,
  53. .reg = 0x6d,
  54. .bit = 0x00,
  55. }, /* HDMI -> VHDMI */
  56. /* {
  57. .address = 0x20,
  58. .reg = ??,
  59. .bit = ??,
  60. }, ** S285 */
  61. {
  62. .address = 0x24,
  63. .reg = 0x66,
  64. .bit = 0x00,
  65. }, /* X285 -> V2P85SX, camera */
  66. /* {
  67. .address = 0x28,
  68. .reg = ??,
  69. .bit = ??,
  70. }, ** V33A */
  71. {
  72. .address = 0x2c,
  73. .reg = 0x69,
  74. .bit = 0x00,
  75. }, /* V33S -> V3P3S, display/ssd/audio */
  76. {
  77. .address = 0x30,
  78. .reg = 0x68,
  79. .bit = 0x00,
  80. }, /* V33U -> V3P3U, SDIO wifi&bt */
  81. /* {
  82. .address = 0x34 .. 0x40,
  83. .reg = ??,
  84. .bit = ??,
  85. }, ** V33I, V18A, REFQ, V12A */
  86. {
  87. .address = 0x44,
  88. .reg = 0x5c,
  89. .bit = 0x00,
  90. }, /* V18S -> V1P8S, SOC/USB PHY/SIM */
  91. {
  92. .address = 0x48,
  93. .reg = 0x5d,
  94. .bit = 0x00,
  95. }, /* V18X -> V1P8SX, eMMC/camara/audio */
  96. {
  97. .address = 0x4c,
  98. .reg = 0x5b,
  99. .bit = 0x00,
  100. }, /* V18U -> V1P8U, LPDDR */
  101. {
  102. .address = 0x50,
  103. .reg = 0x61,
  104. .bit = 0x00,
  105. }, /* V12X -> V1P2SX, SOC SFR */
  106. {
  107. .address = 0x54,
  108. .reg = 0x60,
  109. .bit = 0x00,
  110. }, /* V12S -> V1P2S, MIPI */
  111. /* {
  112. .address = 0x58,
  113. .reg = ??,
  114. .bit = ??,
  115. }, ** V10A */
  116. {
  117. .address = 0x5c,
  118. .reg = 0x56,
  119. .bit = 0x00,
  120. }, /* V10S -> V1P0S, SOC GFX */
  121. {
  122. .address = 0x60,
  123. .reg = 0x57,
  124. .bit = 0x00,
  125. }, /* V10X -> V1P0SX, SOC display/DDR IO/PCIe */
  126. {
  127. .address = 0x64,
  128. .reg = 0x59,
  129. .bit = 0x00,
  130. }, /* V105 -> V1P05S, L2 SRAM */
  131. };
  132. static struct pmic_table thermal_table[] = {
  133. {
  134. .address = 0x00,
  135. .reg = 0x75
  136. },
  137. {
  138. .address = 0x04,
  139. .reg = 0x95
  140. },
  141. {
  142. .address = 0x08,
  143. .reg = 0x97
  144. },
  145. {
  146. .address = 0x0c,
  147. .reg = 0x77
  148. },
  149. {
  150. .address = 0x10,
  151. .reg = 0x9a
  152. },
  153. {
  154. .address = 0x14,
  155. .reg = 0x9c
  156. },
  157. {
  158. .address = 0x18,
  159. .reg = 0x79
  160. },
  161. {
  162. .address = 0x1c,
  163. .reg = 0x9f
  164. },
  165. {
  166. .address = 0x20,
  167. .reg = 0xa1
  168. },
  169. {
  170. .address = 0x48,
  171. .reg = 0x94
  172. },
  173. {
  174. .address = 0x4c,
  175. .reg = 0x99
  176. },
  177. {
  178. .address = 0x50,
  179. .reg = 0x9e
  180. },
  181. };
  182. static int intel_crc_pmic_get_power(struct regmap *regmap, int reg,
  183. int bit, u64 *value)
  184. {
  185. int data;
  186. if (regmap_read(regmap, reg, &data))
  187. return -EIO;
  188. *value = (data & PWR_SOURCE_SELECT) && (data & BIT(bit)) ? 1 : 0;
  189. return 0;
  190. }
  191. static int intel_crc_pmic_update_power(struct regmap *regmap, int reg,
  192. int bit, bool on)
  193. {
  194. int data;
  195. if (regmap_read(regmap, reg, &data))
  196. return -EIO;
  197. if (on) {
  198. data |= PWR_SOURCE_SELECT | BIT(bit);
  199. } else {
  200. data &= ~BIT(bit);
  201. data |= PWR_SOURCE_SELECT;
  202. }
  203. if (regmap_write(regmap, reg, data))
  204. return -EIO;
  205. return 0;
  206. }
  207. static int intel_crc_pmic_get_raw_temp(struct regmap *regmap, int reg)
  208. {
  209. int temp_l, temp_h;
  210. /*
  211. * Raw temperature value is 10bits: 8bits in reg
  212. * and 2bits in reg-1: bit0,1
  213. */
  214. if (regmap_read(regmap, reg, &temp_l) ||
  215. regmap_read(regmap, reg - 1, &temp_h))
  216. return -EIO;
  217. return temp_l | (temp_h & 0x3) << 8;
  218. }
  219. static int intel_crc_pmic_update_aux(struct regmap *regmap, int reg, int raw)
  220. {
  221. return regmap_write(regmap, reg, raw) ||
  222. regmap_update_bits(regmap, reg - 1, 0x3, raw >> 8) ? -EIO : 0;
  223. }
  224. static int intel_crc_pmic_get_policy(struct regmap *regmap,
  225. int reg, int bit, u64 *value)
  226. {
  227. int pen;
  228. if (regmap_read(regmap, reg, &pen))
  229. return -EIO;
  230. *value = pen >> 7;
  231. return 0;
  232. }
  233. static int intel_crc_pmic_update_policy(struct regmap *regmap,
  234. int reg, int bit, int enable)
  235. {
  236. int alert0;
  237. /* Update to policy enable bit requires unlocking a0lock */
  238. if (regmap_read(regmap, PMIC_A0LOCK_REG, &alert0))
  239. return -EIO;
  240. if (regmap_update_bits(regmap, PMIC_A0LOCK_REG, 0x01, 0))
  241. return -EIO;
  242. if (regmap_update_bits(regmap, reg, 0x80, enable << 7))
  243. return -EIO;
  244. /* restore alert0 */
  245. if (regmap_write(regmap, PMIC_A0LOCK_REG, alert0))
  246. return -EIO;
  247. return 0;
  248. }
  249. static const struct intel_pmic_opregion_data intel_crc_pmic_opregion_data = {
  250. .get_power = intel_crc_pmic_get_power,
  251. .update_power = intel_crc_pmic_update_power,
  252. .get_raw_temp = intel_crc_pmic_get_raw_temp,
  253. .update_aux = intel_crc_pmic_update_aux,
  254. .get_policy = intel_crc_pmic_get_policy,
  255. .update_policy = intel_crc_pmic_update_policy,
  256. .lpat_raw_to_temp = acpi_lpat_raw_to_temp,
  257. .power_table = power_table,
  258. .power_table_count= ARRAY_SIZE(power_table),
  259. .thermal_table = thermal_table,
  260. .thermal_table_count = ARRAY_SIZE(thermal_table),
  261. };
  262. static int intel_crc_pmic_opregion_probe(struct platform_device *pdev)
  263. {
  264. struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
  265. return intel_pmic_install_opregion_handler(&pdev->dev,
  266. ACPI_HANDLE(pdev->dev.parent), pmic->regmap,
  267. &intel_crc_pmic_opregion_data);
  268. }
  269. static struct platform_driver intel_crc_pmic_opregion_driver = {
  270. .probe = intel_crc_pmic_opregion_probe,
  271. .driver = {
  272. .name = "byt_crystal_cove_pmic",
  273. },
  274. };
  275. builtin_platform_driver(intel_crc_pmic_opregion_driver);