1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
4 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
5 * Copyright (c) 2024 Linaro Limited
8 #include <linux/array_size.h>
9 #include <linux/bits.h>
10 #include <linux/device.h>
11 #include <linux/math.h>
12 #include <linux/module.h>
14 #include <linux/platform_device.h>
15 #include <linux/regmap.h>
16 #include <linux/regulator/driver.h>
18 #include <asm/byteorder.h>
20 #define DEFAULT_VOLTAGE_STEPPER_RATE 38400
22 #define LDO_STEPPER_CTL_REG 0x3b
23 #define STEP_RATE_MASK GENMASK(1, 0)
25 #define LDO_VSET_LB_REG 0x40
27 #define LDO_ENABLE_REG 0x46
28 #define ENABLE_BIT BIT(7)
30 struct pm8008_regulator
{
31 struct regmap
*regmap
;
32 struct regulator_desc desc
;
36 struct pm8008_regulator_data
{
38 const char *supply_name
;
41 const struct linear_range
*voltage_range
;
44 static const struct linear_range nldo_ranges
[] = {
45 REGULATOR_LINEAR_RANGE(528000, 0, 122, 8000),
48 static const struct linear_range pldo_ranges
[] = {
49 REGULATOR_LINEAR_RANGE(1504000, 0, 237, 8000),
52 static const struct pm8008_regulator_data pm8008_reg_data
[] = {
53 { "ldo1", "vdd-l1-l2", 0x4000, 225000, nldo_ranges
, },
54 { "ldo2", "vdd-l1-l2", 0x4100, 225000, nldo_ranges
, },
55 { "ldo3", "vdd-l3-l4", 0x4200, 300000, pldo_ranges
, },
56 { "ldo4", "vdd-l3-l4", 0x4300, 300000, pldo_ranges
, },
57 { "ldo5", "vdd-l5", 0x4400, 200000, pldo_ranges
, },
58 { "ldo6", "vdd-l6", 0x4500, 200000, pldo_ranges
, },
59 { "ldo7", "vdd-l7", 0x4600, 200000, pldo_ranges
, },
62 static int pm8008_regulator_set_voltage_sel(struct regulator_dev
*rdev
, unsigned int sel
)
64 struct pm8008_regulator
*preg
= rdev_get_drvdata(rdev
);
69 ret
= regulator_list_voltage_linear_range(rdev
, sel
);
73 mV
= DIV_ROUND_UP(ret
, 1000);
75 val
= cpu_to_le16(mV
);
77 ret
= regmap_bulk_write(preg
->regmap
, preg
->base
+ LDO_VSET_LB_REG
,
85 static int pm8008_regulator_get_voltage_sel(struct regulator_dev
*rdev
)
87 struct pm8008_regulator
*preg
= rdev_get_drvdata(rdev
);
92 ret
= regmap_bulk_read(preg
->regmap
, preg
->base
+ LDO_VSET_LB_REG
,
97 uV
= le16_to_cpu(val
) * 1000;
99 return (uV
- preg
->desc
.min_uV
) / preg
->desc
.uV_step
;
102 static const struct regulator_ops pm8008_regulator_ops
= {
103 .list_voltage
= regulator_list_voltage_linear
,
104 .set_voltage_sel
= pm8008_regulator_set_voltage_sel
,
105 .get_voltage_sel
= pm8008_regulator_get_voltage_sel
,
106 .enable
= regulator_enable_regmap
,
107 .disable
= regulator_disable_regmap
,
108 .is_enabled
= regulator_is_enabled_regmap
,
111 static int pm8008_regulator_probe(struct platform_device
*pdev
)
113 const struct pm8008_regulator_data
*data
;
114 struct regulator_config config
= {};
115 struct device
*dev
= &pdev
->dev
;
116 struct pm8008_regulator
*preg
;
117 struct regulator_desc
*desc
;
118 struct regulator_dev
*rdev
;
119 struct regmap
*regmap
;
123 regmap
= dev_get_regmap(dev
->parent
, "secondary");
127 for (i
= 0; i
< ARRAY_SIZE(pm8008_reg_data
); i
++) {
128 data
= &pm8008_reg_data
[i
];
130 preg
= devm_kzalloc(dev
, sizeof(*preg
), GFP_KERNEL
);
134 preg
->regmap
= regmap
;
135 preg
->base
= data
->base
;
139 desc
->name
= data
->name
;
140 desc
->supply_name
= data
->supply_name
;
141 desc
->of_match
= data
->name
;
142 desc
->regulators_node
= of_match_ptr("regulators");
143 desc
->ops
= &pm8008_regulator_ops
;
144 desc
->type
= REGULATOR_VOLTAGE
;
145 desc
->owner
= THIS_MODULE
;
147 desc
->linear_ranges
= data
->voltage_range
;
148 desc
->n_linear_ranges
= 1;
149 desc
->uV_step
= desc
->linear_ranges
[0].step
;
150 desc
->min_uV
= desc
->linear_ranges
[0].min
;
151 desc
->n_voltages
= linear_range_values_in_range(&desc
->linear_ranges
[0]);
153 ret
= regmap_read(regmap
, preg
->base
+ LDO_STEPPER_CTL_REG
, &val
);
155 dev_err(dev
, "failed to read step rate: %d\n", ret
);
158 val
&= STEP_RATE_MASK
;
159 desc
->ramp_delay
= DEFAULT_VOLTAGE_STEPPER_RATE
>> val
;
161 desc
->min_dropout_uV
= data
->min_dropout_uV
;
163 desc
->enable_reg
= preg
->base
+ LDO_ENABLE_REG
;
164 desc
->enable_mask
= ENABLE_BIT
;
166 config
.dev
= dev
->parent
;
167 config
.driver_data
= preg
;
168 config
.regmap
= regmap
;
170 rdev
= devm_regulator_register(dev
, desc
, &config
);
173 dev_err(dev
, "failed to register regulator %s: %d\n",
182 static const struct platform_device_id pm8008_regulator_id_table
[] = {
183 { "pm8008-regulator" },
186 MODULE_DEVICE_TABLE(platform
, pm8008_regulator_id_table
);
188 static struct platform_driver pm8008_regulator_driver
= {
190 .name
= "qcom-pm8008-regulator",
192 .probe
= pm8008_regulator_probe
,
193 .id_table
= pm8008_regulator_id_table
,
195 module_platform_driver(pm8008_regulator_driver
);
197 MODULE_DESCRIPTION("Qualcomm PM8008 PMIC regulator driver");
198 MODULE_LICENSE("GPL");