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