GNU Linux-libre 4.19.286-gnu1
[releases.git] / drivers / acpi / pmic / tps68470_pmic.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * TI TPS68470 PMIC operation region driver
4  *
5  * Copyright (C) 2017 Intel Corporation. All rights reserved.
6  *
7  * Author: Rajmohan Mani <rajmohan.mani@intel.com>
8  *
9  * Based on drivers/acpi/pmic/intel_pmic* drivers
10  */
11
12 #include <linux/acpi.h>
13 #include <linux/mfd/tps68470.h>
14 #include <linux/init.h>
15 #include <linux/platform_device.h>
16 #include <linux/regmap.h>
17
18 struct tps68470_pmic_table {
19         u32 address;            /* operation region address */
20         u32 reg;                /* corresponding register */
21         u32 bitmask;            /* bit mask for power, clock */
22 };
23
24 #define TI_PMIC_POWER_OPREGION_ID               0xB0
25 #define TI_PMIC_VR_VAL_OPREGION_ID              0xB1
26 #define TI_PMIC_CLOCK_OPREGION_ID               0xB2
27 #define TI_PMIC_CLKFREQ_OPREGION_ID             0xB3
28
29 struct tps68470_pmic_opregion {
30         struct mutex lock;
31         struct regmap *regmap;
32 };
33
34 #define S_IO_I2C_EN     (BIT(0) | BIT(1))
35
36 static const struct tps68470_pmic_table power_table[] = {
37         {
38                 .address = 0x00,
39                 .reg = TPS68470_REG_S_I2C_CTL,
40                 .bitmask = S_IO_I2C_EN,
41                 /* S_I2C_CTL */
42         },
43         {
44                 .address = 0x04,
45                 .reg = TPS68470_REG_VCMCTL,
46                 .bitmask = BIT(0),
47                 /* VCMCTL */
48         },
49         {
50                 .address = 0x08,
51                 .reg = TPS68470_REG_VAUX1CTL,
52                 .bitmask = BIT(0),
53                 /* VAUX1_CTL */
54         },
55         {
56                 .address = 0x0C,
57                 .reg = TPS68470_REG_VAUX2CTL,
58                 .bitmask = BIT(0),
59                 /* VAUX2CTL */
60         },
61         {
62                 .address = 0x10,
63                 .reg = TPS68470_REG_VACTL,
64                 .bitmask = BIT(0),
65                 /* VACTL */
66         },
67         {
68                 .address = 0x14,
69                 .reg = TPS68470_REG_VDCTL,
70                 .bitmask = BIT(0),
71                 /* VDCTL */
72         },
73 };
74
75 /* Table to set voltage regulator value */
76 static const struct tps68470_pmic_table vr_val_table[] = {
77         {
78                 .address = 0x00,
79                 .reg = TPS68470_REG_VSIOVAL,
80                 .bitmask = TPS68470_VSIOVAL_IOVOLT_MASK,
81                 /* TPS68470_REG_VSIOVAL */
82         },
83         {
84                 .address = 0x04,
85                 .reg = TPS68470_REG_VIOVAL,
86                 .bitmask = TPS68470_VIOVAL_IOVOLT_MASK,
87                 /* TPS68470_REG_VIOVAL */
88         },
89         {
90                 .address = 0x08,
91                 .reg = TPS68470_REG_VCMVAL,
92                 .bitmask = TPS68470_VCMVAL_VCVOLT_MASK,
93                 /* TPS68470_REG_VCMVAL */
94         },
95         {
96                 .address = 0x0C,
97                 .reg = TPS68470_REG_VAUX1VAL,
98                 .bitmask = TPS68470_VAUX1VAL_AUX1VOLT_MASK,
99                 /* TPS68470_REG_VAUX1VAL */
100         },
101         {
102                 .address = 0x10,
103                 .reg = TPS68470_REG_VAUX2VAL,
104                 .bitmask = TPS68470_VAUX2VAL_AUX2VOLT_MASK,
105                 /* TPS68470_REG_VAUX2VAL */
106         },
107         {
108                 .address = 0x14,
109                 .reg = TPS68470_REG_VAVAL,
110                 .bitmask = TPS68470_VAVAL_AVOLT_MASK,
111                 /* TPS68470_REG_VAVAL */
112         },
113         {
114                 .address = 0x18,
115                 .reg = TPS68470_REG_VDVAL,
116                 .bitmask = TPS68470_VDVAL_DVOLT_MASK,
117                 /* TPS68470_REG_VDVAL */
118         },
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
167 /* Table to configure and enable clocks */
168 static const struct tps68470_pmic_table clk_table[] = {
169         {
170                 .address = 0x00,
171                 .reg = TPS68470_REG_PLLCTL,
172                 .bitmask = 0xF5,
173                 /* TPS68470_REG_PLLCTL */
174         },
175         {
176                 .address = 0x04,
177                 .reg = TPS68470_REG_PLLCTL2,
178                 .bitmask = BIT(0),
179                 /* TPS68470_REG_PLLCTL2 */
180         },
181         {
182                 .address = 0x08,
183                 .reg = TPS68470_REG_CLKCFG1,
184                 .bitmask = TPS68470_CLKCFG1_MODE_A_MASK |
185                         TPS68470_CLKCFG1_MODE_B_MASK,
186                 /* TPS68470_REG_CLKCFG1 */
187         },
188         {
189                 .address = 0x0C,
190                 .reg = TPS68470_REG_CLKCFG2,
191                 .bitmask = TPS68470_CLKCFG1_MODE_A_MASK |
192                         TPS68470_CLKCFG1_MODE_B_MASK,
193                 /* TPS68470_REG_CLKCFG2 */
194         },
195 };
196
197 static int pmic_get_reg_bit(u64 address,
198                             const struct tps68470_pmic_table *table,
199                             const unsigned int table_size, int *reg,
200                             int *bitmask)
201 {
202         u64 i;
203
204         i = address / 4;
205         if (i >= table_size)
206                 return -ENOENT;
207
208         if (!reg || !bitmask)
209                 return -EINVAL;
210
211         *reg = table[i].reg;
212         *bitmask = table[i].bitmask;
213
214         return 0;
215 }
216
217 static int tps68470_pmic_get_power(struct regmap *regmap, int reg,
218                                        int bitmask, u64 *value)
219 {
220         unsigned int data;
221
222         if (regmap_read(regmap, reg, &data))
223                 return -EIO;
224
225         *value = (data & bitmask) ? 1 : 0;
226         return 0;
227 }
228
229 static int tps68470_pmic_get_vr_val(struct regmap *regmap, int reg,
230                                        int bitmask, u64 *value)
231 {
232         unsigned int data;
233
234         if (regmap_read(regmap, reg, &data))
235                 return -EIO;
236
237         *value = data & bitmask;
238         return 0;
239 }
240
241 static int tps68470_pmic_get_clk(struct regmap *regmap, int reg,
242                                        int bitmask, u64 *value)
243 {
244         unsigned int data;
245
246         if (regmap_read(regmap, reg, &data))
247                 return -EIO;
248
249         *value = (data & bitmask) ? 1 : 0;
250         return 0;
251 }
252
253 static int tps68470_pmic_get_clk_freq(struct regmap *regmap, int reg,
254                                        int bitmask, u64 *value)
255 {
256         unsigned int data;
257
258         if (regmap_read(regmap, reg, &data))
259                 return -EIO;
260
261         *value = data & bitmask;
262         return 0;
263 }
264
265 static int ti_tps68470_regmap_update_bits(struct regmap *regmap, int reg,
266                                         int bitmask, u64 value)
267 {
268         return regmap_update_bits(regmap, reg, bitmask, value);
269 }
270
271 static acpi_status tps68470_pmic_common_handler(u32 function,
272                                           acpi_physical_address address,
273                                           u32 bits, u64 *value,
274                                           void *region_context,
275                                           int (*get)(struct regmap *,
276                                                      int, int, u64 *),
277                                           int (*update)(struct regmap *,
278                                                         int, int, u64),
279                                           const struct tps68470_pmic_table *tbl,
280                                           unsigned int tbl_size)
281 {
282         struct tps68470_pmic_opregion *opregion = region_context;
283         struct regmap *regmap = opregion->regmap;
284         int reg, ret, bitmask;
285
286         if (bits != 32)
287                 return AE_BAD_PARAMETER;
288
289         ret = pmic_get_reg_bit(address, tbl, tbl_size, &reg, &bitmask);
290         if (ret < 0)
291                 return AE_BAD_PARAMETER;
292
293         if (function == ACPI_WRITE && *value > bitmask)
294                 return AE_BAD_PARAMETER;
295
296         mutex_lock(&opregion->lock);
297
298         ret = (function == ACPI_READ) ?
299                 get(regmap, reg, bitmask, value) :
300                 update(regmap, reg, bitmask, *value);
301
302         mutex_unlock(&opregion->lock);
303
304         return ret ? AE_ERROR : AE_OK;
305 }
306
307 static acpi_status tps68470_pmic_cfreq_handler(u32 function,
308                                             acpi_physical_address address,
309                                             u32 bits, u64 *value,
310                                             void *handler_context,
311                                             void *region_context)
312 {
313         return tps68470_pmic_common_handler(function, address, bits, value,
314                                 region_context,
315                                 tps68470_pmic_get_clk_freq,
316                                 ti_tps68470_regmap_update_bits,
317                                 clk_freq_table,
318                                 ARRAY_SIZE(clk_freq_table));
319 }
320
321 static acpi_status tps68470_pmic_clk_handler(u32 function,
322                                        acpi_physical_address address, u32 bits,
323                                        u64 *value, void *handler_context,
324                                        void *region_context)
325 {
326         return tps68470_pmic_common_handler(function, address, bits, value,
327                                 region_context,
328                                 tps68470_pmic_get_clk,
329                                 ti_tps68470_regmap_update_bits,
330                                 clk_table,
331                                 ARRAY_SIZE(clk_table));
332 }
333
334 static acpi_status tps68470_pmic_vrval_handler(u32 function,
335                                           acpi_physical_address address,
336                                           u32 bits, u64 *value,
337                                           void *handler_context,
338                                           void *region_context)
339 {
340         return tps68470_pmic_common_handler(function, address, bits, value,
341                                 region_context,
342                                 tps68470_pmic_get_vr_val,
343                                 ti_tps68470_regmap_update_bits,
344                                 vr_val_table,
345                                 ARRAY_SIZE(vr_val_table));
346 }
347
348 static acpi_status tps68470_pmic_pwr_handler(u32 function,
349                                          acpi_physical_address address,
350                                          u32 bits, u64 *value,
351                                          void *handler_context,
352                                          void *region_context)
353 {
354         if (bits != 32)
355                 return AE_BAD_PARAMETER;
356
357         /* set/clear for bit 0, bits 0 and 1 together */
358         if (function == ACPI_WRITE &&
359             !(*value == 0 || *value == 1 || *value == 3)) {
360                 return AE_BAD_PARAMETER;
361         }
362
363         return tps68470_pmic_common_handler(function, address, bits, value,
364                                 region_context,
365                                 tps68470_pmic_get_power,
366                                 ti_tps68470_regmap_update_bits,
367                                 power_table,
368                                 ARRAY_SIZE(power_table));
369 }
370
371 static int tps68470_pmic_opregion_probe(struct platform_device *pdev)
372 {
373         struct regmap *tps68470_regmap = dev_get_drvdata(pdev->dev.parent);
374         acpi_handle handle = ACPI_HANDLE(pdev->dev.parent);
375         struct device *dev = &pdev->dev;
376         struct tps68470_pmic_opregion *opregion;
377         acpi_status status;
378
379         if (!dev || !tps68470_regmap) {
380                 dev_warn(dev, "dev or regmap is NULL\n");
381                 return -EINVAL;
382         }
383
384         if (!handle) {
385                 dev_warn(dev, "acpi handle is NULL\n");
386                 return -ENODEV;
387         }
388
389         opregion = devm_kzalloc(dev, sizeof(*opregion), GFP_KERNEL);
390         if (!opregion)
391                 return -ENOMEM;
392
393         mutex_init(&opregion->lock);
394         opregion->regmap = tps68470_regmap;
395
396         status = acpi_install_address_space_handler(handle,
397                                                     TI_PMIC_POWER_OPREGION_ID,
398                                                     tps68470_pmic_pwr_handler,
399                                                     NULL, opregion);
400         if (ACPI_FAILURE(status))
401                 goto out_mutex_destroy;
402
403         status = acpi_install_address_space_handler(handle,
404                                                     TI_PMIC_VR_VAL_OPREGION_ID,
405                                                     tps68470_pmic_vrval_handler,
406                                                     NULL, opregion);
407         if (ACPI_FAILURE(status))
408                 goto out_remove_power_handler;
409
410         status = acpi_install_address_space_handler(handle,
411                                                     TI_PMIC_CLOCK_OPREGION_ID,
412                                                     tps68470_pmic_clk_handler,
413                                                     NULL, opregion);
414         if (ACPI_FAILURE(status))
415                 goto out_remove_vr_val_handler;
416
417         status = acpi_install_address_space_handler(handle,
418                                                     TI_PMIC_CLKFREQ_OPREGION_ID,
419                                                     tps68470_pmic_cfreq_handler,
420                                                     NULL, opregion);
421         if (ACPI_FAILURE(status))
422                 goto out_remove_clk_handler;
423
424         return 0;
425
426 out_remove_clk_handler:
427         acpi_remove_address_space_handler(handle, TI_PMIC_CLOCK_OPREGION_ID,
428                                           tps68470_pmic_clk_handler);
429 out_remove_vr_val_handler:
430         acpi_remove_address_space_handler(handle, TI_PMIC_VR_VAL_OPREGION_ID,
431                                           tps68470_pmic_vrval_handler);
432 out_remove_power_handler:
433         acpi_remove_address_space_handler(handle, TI_PMIC_POWER_OPREGION_ID,
434                                           tps68470_pmic_pwr_handler);
435 out_mutex_destroy:
436         mutex_destroy(&opregion->lock);
437         return -ENODEV;
438 }
439
440 static struct platform_driver tps68470_pmic_opregion_driver = {
441         .probe = tps68470_pmic_opregion_probe,
442         .driver = {
443                 .name = "tps68470_pmic_opregion",
444         },
445 };
446
447 builtin_platform_driver(tps68470_pmic_opregion_driver)