2 * TI TPS68470 PMIC operation region driver
4 * Copyright (C) 2017 Intel Corporation. All rights reserved.
6 * Author: Rajmohan Mani <rajmohan.mani@intel.com>
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.
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.
17 * Based on drivers/acpi/pmic/intel_pmic* drivers
20 #include <linux/acpi.h>
21 #include <linux/mfd/tps68470.h>
22 #include <linux/init.h>
23 #include <linux/platform_device.h>
24 #include <linux/regmap.h>
26 struct tps68470_pmic_table
{
27 u32 address
; /* operation region address */
28 u32 reg
; /* corresponding register */
29 u32 bitmask
; /* bit mask for power, clock */
32 #define TI_PMIC_POWER_OPREGION_ID 0xB0
33 #define TI_PMIC_VR_VAL_OPREGION_ID 0xB1
34 #define TI_PMIC_CLOCK_OPREGION_ID 0xB2
35 #define TI_PMIC_CLKFREQ_OPREGION_ID 0xB3
37 struct tps68470_pmic_opregion
{
39 struct regmap
*regmap
;
42 #define S_IO_I2C_EN (BIT(0) | BIT(1))
44 static const struct tps68470_pmic_table power_table
[] = {
47 .reg
= TPS68470_REG_S_I2C_CTL
,
48 .bitmask
= S_IO_I2C_EN
,
53 .reg
= TPS68470_REG_VCMCTL
,
59 .reg
= TPS68470_REG_VAUX1CTL
,
65 .reg
= TPS68470_REG_VAUX2CTL
,
71 .reg
= TPS68470_REG_VACTL
,
77 .reg
= TPS68470_REG_VDCTL
,
83 /* Table to set voltage regulator value */
84 static const struct tps68470_pmic_table vr_val_table
[] = {
87 .reg
= TPS68470_REG_VSIOVAL
,
88 .bitmask
= TPS68470_VSIOVAL_IOVOLT_MASK
,
89 /* TPS68470_REG_VSIOVAL */
93 .reg
= TPS68470_REG_VIOVAL
,
94 .bitmask
= TPS68470_VIOVAL_IOVOLT_MASK
,
95 /* TPS68470_REG_VIOVAL */
99 .reg
= TPS68470_REG_VCMVAL
,
100 .bitmask
= TPS68470_VCMVAL_VCVOLT_MASK
,
101 /* TPS68470_REG_VCMVAL */
105 .reg
= TPS68470_REG_VAUX1VAL
,
106 .bitmask
= TPS68470_VAUX1VAL_AUX1VOLT_MASK
,
107 /* TPS68470_REG_VAUX1VAL */
111 .reg
= TPS68470_REG_VAUX2VAL
,
112 .bitmask
= TPS68470_VAUX2VAL_AUX2VOLT_MASK
,
113 /* TPS68470_REG_VAUX2VAL */
117 .reg
= TPS68470_REG_VAVAL
,
118 .bitmask
= TPS68470_VAVAL_AVOLT_MASK
,
119 /* TPS68470_REG_VAVAL */
123 .reg
= TPS68470_REG_VDVAL
,
124 .bitmask
= TPS68470_VDVAL_DVOLT_MASK
,
125 /* TPS68470_REG_VDVAL */
129 /* Table to configure clock frequency */
130 static const struct tps68470_pmic_table clk_freq_table
[] = {
133 .reg
= TPS68470_REG_POSTDIV2
,
134 .bitmask
= BIT(0) | BIT(1),
135 /* TPS68470_REG_POSTDIV2 */
139 .reg
= TPS68470_REG_BOOSTDIV
,
141 /* TPS68470_REG_BOOSTDIV */
145 .reg
= TPS68470_REG_BUCKDIV
,
147 /* TPS68470_REG_BUCKDIV */
151 .reg
= TPS68470_REG_PLLSWR
,
153 /* TPS68470_REG_PLLSWR */
157 .reg
= TPS68470_REG_XTALDIV
,
159 /* TPS68470_REG_XTALDIV */
163 .reg
= TPS68470_REG_PLLDIV
,
165 /* TPS68470_REG_PLLDIV */
169 .reg
= TPS68470_REG_POSTDIV
,
171 /* TPS68470_REG_POSTDIV */
175 /* Table to configure and enable clocks */
176 static const struct tps68470_pmic_table clk_table
[] = {
179 .reg
= TPS68470_REG_PLLCTL
,
181 /* TPS68470_REG_PLLCTL */
185 .reg
= TPS68470_REG_PLLCTL2
,
187 /* TPS68470_REG_PLLCTL2 */
191 .reg
= TPS68470_REG_CLKCFG1
,
192 .bitmask
= TPS68470_CLKCFG1_MODE_A_MASK
|
193 TPS68470_CLKCFG1_MODE_B_MASK
,
194 /* TPS68470_REG_CLKCFG1 */
198 .reg
= TPS68470_REG_CLKCFG2
,
199 .bitmask
= TPS68470_CLKCFG1_MODE_A_MASK
|
200 TPS68470_CLKCFG1_MODE_B_MASK
,
201 /* TPS68470_REG_CLKCFG2 */
205 static int pmic_get_reg_bit(u64 address
,
206 const struct tps68470_pmic_table
*table
,
207 const unsigned int table_size
, int *reg
,
216 if (!reg
|| !bitmask
)
220 *bitmask
= table
[i
].bitmask
;
225 static int tps68470_pmic_get_power(struct regmap
*regmap
, int reg
,
226 int bitmask
, u64
*value
)
230 if (regmap_read(regmap
, reg
, &data
))
233 *value
= (data
& bitmask
) ? 1 : 0;
237 static int tps68470_pmic_get_vr_val(struct regmap
*regmap
, int reg
,
238 int bitmask
, u64
*value
)
242 if (regmap_read(regmap
, reg
, &data
))
245 *value
= data
& bitmask
;
249 static int tps68470_pmic_get_clk(struct regmap
*regmap
, int reg
,
250 int bitmask
, u64
*value
)
254 if (regmap_read(regmap
, reg
, &data
))
257 *value
= (data
& bitmask
) ? 1 : 0;
261 static int tps68470_pmic_get_clk_freq(struct regmap
*regmap
, int reg
,
262 int bitmask
, u64
*value
)
266 if (regmap_read(regmap
, reg
, &data
))
269 *value
= data
& bitmask
;
273 static int ti_tps68470_regmap_update_bits(struct regmap
*regmap
, int reg
,
274 int bitmask
, u64 value
)
276 return regmap_update_bits(regmap
, reg
, bitmask
, value
);
279 static acpi_status
tps68470_pmic_common_handler(u32 function
,
280 acpi_physical_address address
,
281 u32 bits
, u64
*value
,
282 void *region_context
,
283 int (*get
)(struct regmap
*,
285 int (*update
)(struct regmap
*,
287 const struct tps68470_pmic_table
*tbl
,
288 unsigned int tbl_size
)
290 struct tps68470_pmic_opregion
*opregion
= region_context
;
291 struct regmap
*regmap
= opregion
->regmap
;
292 int reg
, ret
, bitmask
;
295 return AE_BAD_PARAMETER
;
297 ret
= pmic_get_reg_bit(address
, tbl
, tbl_size
, ®
, &bitmask
);
299 return AE_BAD_PARAMETER
;
301 if (function
== ACPI_WRITE
&& *value
> bitmask
)
302 return AE_BAD_PARAMETER
;
304 mutex_lock(&opregion
->lock
);
306 ret
= (function
== ACPI_READ
) ?
307 get(regmap
, reg
, bitmask
, value
) :
308 update(regmap
, reg
, bitmask
, *value
);
310 mutex_unlock(&opregion
->lock
);
312 return ret
? AE_ERROR
: AE_OK
;
315 static acpi_status
tps68470_pmic_cfreq_handler(u32 function
,
316 acpi_physical_address address
,
317 u32 bits
, u64
*value
,
318 void *handler_context
,
319 void *region_context
)
321 return tps68470_pmic_common_handler(function
, address
, bits
, value
,
323 tps68470_pmic_get_clk_freq
,
324 ti_tps68470_regmap_update_bits
,
326 ARRAY_SIZE(clk_freq_table
));
329 static acpi_status
tps68470_pmic_clk_handler(u32 function
,
330 acpi_physical_address address
, u32 bits
,
331 u64
*value
, void *handler_context
,
332 void *region_context
)
334 return tps68470_pmic_common_handler(function
, address
, bits
, value
,
336 tps68470_pmic_get_clk
,
337 ti_tps68470_regmap_update_bits
,
339 ARRAY_SIZE(clk_table
));
342 static acpi_status
tps68470_pmic_vrval_handler(u32 function
,
343 acpi_physical_address address
,
344 u32 bits
, u64
*value
,
345 void *handler_context
,
346 void *region_context
)
348 return tps68470_pmic_common_handler(function
, address
, bits
, value
,
350 tps68470_pmic_get_vr_val
,
351 ti_tps68470_regmap_update_bits
,
353 ARRAY_SIZE(vr_val_table
));
356 static acpi_status
tps68470_pmic_pwr_handler(u32 function
,
357 acpi_physical_address address
,
358 u32 bits
, u64
*value
,
359 void *handler_context
,
360 void *region_context
)
363 return AE_BAD_PARAMETER
;
365 /* set/clear for bit 0, bits 0 and 1 together */
366 if (function
== ACPI_WRITE
&&
367 !(*value
== 0 || *value
== 1 || *value
== 3)) {
368 return AE_BAD_PARAMETER
;
371 return tps68470_pmic_common_handler(function
, address
, bits
, value
,
373 tps68470_pmic_get_power
,
374 ti_tps68470_regmap_update_bits
,
376 ARRAY_SIZE(power_table
));
379 static int tps68470_pmic_opregion_probe(struct platform_device
*pdev
)
381 struct regmap
*tps68470_regmap
= dev_get_drvdata(pdev
->dev
.parent
);
382 acpi_handle handle
= ACPI_HANDLE(pdev
->dev
.parent
);
383 struct device
*dev
= &pdev
->dev
;
384 struct tps68470_pmic_opregion
*opregion
;
387 if (!dev
|| !tps68470_regmap
) {
388 dev_warn(dev
, "dev or regmap is NULL\n");
393 dev_warn(dev
, "acpi handle is NULL\n");
397 opregion
= devm_kzalloc(dev
, sizeof(*opregion
), GFP_KERNEL
);
401 mutex_init(&opregion
->lock
);
402 opregion
->regmap
= tps68470_regmap
;
404 status
= acpi_install_address_space_handler(handle
,
405 TI_PMIC_POWER_OPREGION_ID
,
406 tps68470_pmic_pwr_handler
,
408 if (ACPI_FAILURE(status
))
409 goto out_mutex_destroy
;
411 status
= acpi_install_address_space_handler(handle
,
412 TI_PMIC_VR_VAL_OPREGION_ID
,
413 tps68470_pmic_vrval_handler
,
415 if (ACPI_FAILURE(status
))
416 goto out_remove_power_handler
;
418 status
= acpi_install_address_space_handler(handle
,
419 TI_PMIC_CLOCK_OPREGION_ID
,
420 tps68470_pmic_clk_handler
,
422 if (ACPI_FAILURE(status
))
423 goto out_remove_vr_val_handler
;
425 status
= acpi_install_address_space_handler(handle
,
426 TI_PMIC_CLKFREQ_OPREGION_ID
,
427 tps68470_pmic_cfreq_handler
,
429 if (ACPI_FAILURE(status
))
430 goto out_remove_clk_handler
;
434 out_remove_clk_handler
:
435 acpi_remove_address_space_handler(handle
, TI_PMIC_CLOCK_OPREGION_ID
,
436 tps68470_pmic_clk_handler
);
437 out_remove_vr_val_handler
:
438 acpi_remove_address_space_handler(handle
, TI_PMIC_VR_VAL_OPREGION_ID
,
439 tps68470_pmic_vrval_handler
);
440 out_remove_power_handler
:
441 acpi_remove_address_space_handler(handle
, TI_PMIC_POWER_OPREGION_ID
,
442 tps68470_pmic_pwr_handler
);
444 mutex_destroy(&opregion
->lock
);
448 static struct platform_driver tps68470_pmic_opregion_driver
= {
449 .probe
= tps68470_pmic_opregion_probe
,
451 .name
= "tps68470_pmic_opregion",
455 builtin_platform_driver(tps68470_pmic_opregion_driver
)