intel_pmic_chtwc.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * Intel CHT Whiskey Cove PMIC operation region driver
  3. * Copyright (C) 2017 Hans de Goede <hdegoede@redhat.com>
  4. *
  5. * Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
  6. * Copyright (C) 2013-2015 Intel Corporation. All rights reserved.
  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 in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. */
  17. #include <linux/acpi.h>
  18. #include <linux/init.h>
  19. #include <linux/mfd/intel_soc_pmic.h>
  20. #include <linux/platform_device.h>
  21. #include <linux/regmap.h>
  22. #include "intel_pmic.h"
  23. #define CHT_WC_V1P05A_CTRL 0x6e3b
  24. #define CHT_WC_V1P15_CTRL 0x6e3c
  25. #define CHT_WC_V1P05A_VSEL 0x6e3d
  26. #define CHT_WC_V1P15_VSEL 0x6e3e
  27. #define CHT_WC_V1P8A_CTRL 0x6e56
  28. #define CHT_WC_V1P8SX_CTRL 0x6e57
  29. #define CHT_WC_VDDQ_CTRL 0x6e58
  30. #define CHT_WC_V1P2A_CTRL 0x6e59
  31. #define CHT_WC_V1P2SX_CTRL 0x6e5a
  32. #define CHT_WC_V1P8A_VSEL 0x6e5b
  33. #define CHT_WC_VDDQ_VSEL 0x6e5c
  34. #define CHT_WC_V2P8SX_CTRL 0x6e5d
  35. #define CHT_WC_V3P3A_CTRL 0x6e5e
  36. #define CHT_WC_V3P3SD_CTRL 0x6e5f
  37. #define CHT_WC_VSDIO_CTRL 0x6e67
  38. #define CHT_WC_V3P3A_VSEL 0x6e68
  39. #define CHT_WC_VPROG1A_CTRL 0x6e90
  40. #define CHT_WC_VPROG1B_CTRL 0x6e91
  41. #define CHT_WC_VPROG1F_CTRL 0x6e95
  42. #define CHT_WC_VPROG2D_CTRL 0x6e99
  43. #define CHT_WC_VPROG3A_CTRL 0x6e9a
  44. #define CHT_WC_VPROG3B_CTRL 0x6e9b
  45. #define CHT_WC_VPROG4A_CTRL 0x6e9c
  46. #define CHT_WC_VPROG4B_CTRL 0x6e9d
  47. #define CHT_WC_VPROG4C_CTRL 0x6e9e
  48. #define CHT_WC_VPROG4D_CTRL 0x6e9f
  49. #define CHT_WC_VPROG5A_CTRL 0x6ea0
  50. #define CHT_WC_VPROG5B_CTRL 0x6ea1
  51. #define CHT_WC_VPROG6A_CTRL 0x6ea2
  52. #define CHT_WC_VPROG6B_CTRL 0x6ea3
  53. #define CHT_WC_VPROG1A_VSEL 0x6ec0
  54. #define CHT_WC_VPROG1B_VSEL 0x6ec1
  55. #define CHT_WC_V1P8SX_VSEL 0x6ec2
  56. #define CHT_WC_V1P2SX_VSEL 0x6ec3
  57. #define CHT_WC_V1P2A_VSEL 0x6ec4
  58. #define CHT_WC_VPROG1F_VSEL 0x6ec5
  59. #define CHT_WC_VSDIO_VSEL 0x6ec6
  60. #define CHT_WC_V2P8SX_VSEL 0x6ec7
  61. #define CHT_WC_V3P3SD_VSEL 0x6ec8
  62. #define CHT_WC_VPROG2D_VSEL 0x6ec9
  63. #define CHT_WC_VPROG3A_VSEL 0x6eca
  64. #define CHT_WC_VPROG3B_VSEL 0x6ecb
  65. #define CHT_WC_VPROG4A_VSEL 0x6ecc
  66. #define CHT_WC_VPROG4B_VSEL 0x6ecd
  67. #define CHT_WC_VPROG4C_VSEL 0x6ece
  68. #define CHT_WC_VPROG4D_VSEL 0x6ecf
  69. #define CHT_WC_VPROG5A_VSEL 0x6ed0
  70. #define CHT_WC_VPROG5B_VSEL 0x6ed1
  71. #define CHT_WC_VPROG6A_VSEL 0x6ed2
  72. #define CHT_WC_VPROG6B_VSEL 0x6ed3
  73. /*
  74. * Regulator support is based on the non upstream patch:
  75. * "regulator: whiskey_cove: implements Whiskey Cove pmic VRF support"
  76. * https://github.com/intel-aero/meta-intel-aero/blob/master/recipes-kernel/linux/linux-yocto/0019-regulator-whiskey_cove-implements-WhiskeyCove-pmic-V.patch
  77. */
  78. static struct pmic_table power_table[] = {
  79. {
  80. .address = 0x0,
  81. .reg = CHT_WC_V1P8A_CTRL,
  82. .bit = 0x01,
  83. }, /* V18A */
  84. {
  85. .address = 0x04,
  86. .reg = CHT_WC_V1P8SX_CTRL,
  87. .bit = 0x07,
  88. }, /* V18X */
  89. {
  90. .address = 0x08,
  91. .reg = CHT_WC_VDDQ_CTRL,
  92. .bit = 0x01,
  93. }, /* VDDQ */
  94. {
  95. .address = 0x0c,
  96. .reg = CHT_WC_V1P2A_CTRL,
  97. .bit = 0x07,
  98. }, /* V12A */
  99. {
  100. .address = 0x10,
  101. .reg = CHT_WC_V1P2SX_CTRL,
  102. .bit = 0x07,
  103. }, /* V12X */
  104. {
  105. .address = 0x14,
  106. .reg = CHT_WC_V2P8SX_CTRL,
  107. .bit = 0x07,
  108. }, /* V28X */
  109. {
  110. .address = 0x18,
  111. .reg = CHT_WC_V3P3A_CTRL,
  112. .bit = 0x01,
  113. }, /* V33A */
  114. {
  115. .address = 0x1c,
  116. .reg = CHT_WC_V3P3SD_CTRL,
  117. .bit = 0x07,
  118. }, /* V3SD */
  119. {
  120. .address = 0x20,
  121. .reg = CHT_WC_VSDIO_CTRL,
  122. .bit = 0x07,
  123. }, /* VSD */
  124. /* {
  125. .address = 0x24,
  126. .reg = ??,
  127. .bit = ??,
  128. }, ** VSW2 */
  129. /* {
  130. .address = 0x28,
  131. .reg = ??,
  132. .bit = ??,
  133. }, ** VSW1 */
  134. /* {
  135. .address = 0x2c,
  136. .reg = ??,
  137. .bit = ??,
  138. }, ** VUPY */
  139. /* {
  140. .address = 0x30,
  141. .reg = ??,
  142. .bit = ??,
  143. }, ** VRSO */
  144. {
  145. .address = 0x34,
  146. .reg = CHT_WC_VPROG1A_CTRL,
  147. .bit = 0x07,
  148. }, /* VP1A */
  149. {
  150. .address = 0x38,
  151. .reg = CHT_WC_VPROG1B_CTRL,
  152. .bit = 0x07,
  153. }, /* VP1B */
  154. {
  155. .address = 0x3c,
  156. .reg = CHT_WC_VPROG1F_CTRL,
  157. .bit = 0x07,
  158. }, /* VP1F */
  159. {
  160. .address = 0x40,
  161. .reg = CHT_WC_VPROG2D_CTRL,
  162. .bit = 0x07,
  163. }, /* VP2D */
  164. {
  165. .address = 0x44,
  166. .reg = CHT_WC_VPROG3A_CTRL,
  167. .bit = 0x07,
  168. }, /* VP3A */
  169. {
  170. .address = 0x48,
  171. .reg = CHT_WC_VPROG3B_CTRL,
  172. .bit = 0x07,
  173. }, /* VP3B */
  174. {
  175. .address = 0x4c,
  176. .reg = CHT_WC_VPROG4A_CTRL,
  177. .bit = 0x07,
  178. }, /* VP4A */
  179. {
  180. .address = 0x50,
  181. .reg = CHT_WC_VPROG4B_CTRL,
  182. .bit = 0x07,
  183. }, /* VP4B */
  184. {
  185. .address = 0x54,
  186. .reg = CHT_WC_VPROG4C_CTRL,
  187. .bit = 0x07,
  188. }, /* VP4C */
  189. {
  190. .address = 0x58,
  191. .reg = CHT_WC_VPROG4D_CTRL,
  192. .bit = 0x07,
  193. }, /* VP4D */
  194. {
  195. .address = 0x5c,
  196. .reg = CHT_WC_VPROG5A_CTRL,
  197. .bit = 0x07,
  198. }, /* VP5A */
  199. {
  200. .address = 0x60,
  201. .reg = CHT_WC_VPROG5B_CTRL,
  202. .bit = 0x07,
  203. }, /* VP5B */
  204. {
  205. .address = 0x64,
  206. .reg = CHT_WC_VPROG6A_CTRL,
  207. .bit = 0x07,
  208. }, /* VP6A */
  209. {
  210. .address = 0x68,
  211. .reg = CHT_WC_VPROG6B_CTRL,
  212. .bit = 0x07,
  213. }, /* VP6B */
  214. /* {
  215. .address = 0x6c,
  216. .reg = ??,
  217. .bit = ??,
  218. } ** VP7A */
  219. };
  220. static int intel_cht_wc_pmic_get_power(struct regmap *regmap, int reg,
  221. int bit, u64 *value)
  222. {
  223. int data;
  224. if (regmap_read(regmap, reg, &data))
  225. return -EIO;
  226. *value = (data & bit) ? 1 : 0;
  227. return 0;
  228. }
  229. static int intel_cht_wc_pmic_update_power(struct regmap *regmap, int reg,
  230. int bitmask, bool on)
  231. {
  232. return regmap_update_bits(regmap, reg, bitmask, on ? 1 : 0);
  233. }
  234. /*
  235. * The thermal table and ops are empty, we do not support the Thermal opregion
  236. * (DPTF) due to lacking documentation.
  237. */
  238. static struct intel_pmic_opregion_data intel_cht_wc_pmic_opregion_data = {
  239. .get_power = intel_cht_wc_pmic_get_power,
  240. .update_power = intel_cht_wc_pmic_update_power,
  241. .power_table = power_table,
  242. .power_table_count = ARRAY_SIZE(power_table),
  243. };
  244. static int intel_cht_wc_pmic_opregion_probe(struct platform_device *pdev)
  245. {
  246. struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
  247. return intel_pmic_install_opregion_handler(&pdev->dev,
  248. ACPI_HANDLE(pdev->dev.parent),
  249. pmic->regmap,
  250. &intel_cht_wc_pmic_opregion_data);
  251. }
  252. static const struct platform_device_id cht_wc_opregion_id_table[] = {
  253. { .name = "cht_wcove_region" },
  254. {},
  255. };
  256. static struct platform_driver intel_cht_wc_pmic_opregion_driver = {
  257. .probe = intel_cht_wc_pmic_opregion_probe,
  258. .driver = {
  259. .name = "cht_whiskey_cove_pmic",
  260. },
  261. .id_table = cht_wc_opregion_id_table,
  262. };
  263. builtin_platform_driver(intel_cht_wc_pmic_opregion_driver);