1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2023 Axis Communications AB
5 * Driver for Texas Instruments TPS6287x PMIC.
6 * Datasheet: https://www.ti.com/lit/ds/symlink/tps62873.pdf
10 #include <linux/i2c.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/module.h>
13 #include <linux/regmap.h>
14 #include <linux/regulator/of_regulator.h>
15 #include <linux/regulator/machine.h>
16 #include <linux/regulator/driver.h>
17 #include <linux/bitfield.h>
18 #include <linux/linear_range.h>
20 #define TPS6287X_VSET 0x00
21 #define TPS6287X_CTRL1 0x01
22 #define TPS6287X_CTRL1_VRAMP GENMASK(1, 0)
23 #define TPS6287X_CTRL1_FPWMEN BIT(4)
24 #define TPS6287X_CTRL1_SWEN BIT(5)
25 #define TPS6287X_CTRL2 0x02
26 #define TPS6287X_CTRL2_VRANGE GENMASK(3, 2)
27 #define TPS6287X_CTRL3 0x03
28 #define TPS6287X_STATUS 0x04
30 static const struct regmap_config tps6287x_regmap_config
= {
33 .max_register
= TPS6287X_STATUS
,
36 static const struct linear_range tps6287x_voltage_ranges
[] = {
37 LINEAR_RANGE(400000, 0, 0xFF, 1250),
38 LINEAR_RANGE(400000, 0, 0xFF, 2500),
39 LINEAR_RANGE(400000, 0, 0xFF, 5000),
40 LINEAR_RANGE(800000, 0, 0xFF, 10000),
43 static const unsigned int tps6287x_voltage_range_sel
[] = {
47 static const unsigned int tps6287x_ramp_table
[] = {
48 10000, 5000, 1250, 500
51 static int tps6287x_set_mode(struct regulator_dev
*rdev
, unsigned int mode
)
56 case REGULATOR_MODE_NORMAL
:
59 case REGULATOR_MODE_FAST
:
60 val
= TPS6287X_CTRL1_FPWMEN
;
66 return regmap_update_bits(rdev
->regmap
, TPS6287X_CTRL1
,
67 TPS6287X_CTRL1_FPWMEN
, val
);
70 static unsigned int tps6287x_get_mode(struct regulator_dev
*rdev
)
75 ret
= regmap_read(rdev
->regmap
, TPS6287X_CTRL1
, &val
);
79 return (val
& TPS6287X_CTRL1_FPWMEN
) ? REGULATOR_MODE_FAST
:
80 REGULATOR_MODE_NORMAL
;
83 static unsigned int tps6287x_of_map_mode(unsigned int mode
)
86 case REGULATOR_MODE_NORMAL
:
87 case REGULATOR_MODE_FAST
:
90 return REGULATOR_MODE_INVALID
;
94 static const struct regulator_ops tps6287x_regulator_ops
= {
95 .enable
= regulator_enable_regmap
,
96 .disable
= regulator_disable_regmap
,
97 .set_mode
= tps6287x_set_mode
,
98 .get_mode
= tps6287x_get_mode
,
99 .is_enabled
= regulator_is_enabled_regmap
,
100 .get_voltage_sel
= regulator_get_voltage_sel_pickable_regmap
,
101 .set_voltage_sel
= regulator_set_voltage_sel_pickable_regmap
,
102 .list_voltage
= regulator_list_voltage_pickable_linear_range
,
103 .set_ramp_delay
= regulator_set_ramp_delay_regmap
,
106 static const struct regulator_desc tps6287x_reg
= {
108 .owner
= THIS_MODULE
,
109 .ops
= &tps6287x_regulator_ops
,
110 .of_map_mode
= tps6287x_of_map_mode
,
111 .type
= REGULATOR_VOLTAGE
,
112 .enable_reg
= TPS6287X_CTRL1
,
113 .enable_mask
= TPS6287X_CTRL1_SWEN
,
114 .vsel_reg
= TPS6287X_VSET
,
116 .vsel_range_reg
= TPS6287X_CTRL2
,
117 .vsel_range_mask
= TPS6287X_CTRL2_VRANGE
,
118 .range_applied_by_vsel
= true,
119 .ramp_reg
= TPS6287X_CTRL1
,
120 .ramp_mask
= TPS6287X_CTRL1_VRAMP
,
121 .ramp_delay_table
= tps6287x_ramp_table
,
122 .n_ramp_values
= ARRAY_SIZE(tps6287x_ramp_table
),
123 .n_voltages
= 256 * ARRAY_SIZE(tps6287x_voltage_ranges
),
124 .linear_ranges
= tps6287x_voltage_ranges
,
125 .n_linear_ranges
= ARRAY_SIZE(tps6287x_voltage_ranges
),
126 .linear_range_selectors_bitfield
= tps6287x_voltage_range_sel
,
129 static int tps6287x_i2c_probe(struct i2c_client
*i2c
)
131 struct device
*dev
= &i2c
->dev
;
132 struct regulator_config config
= {};
133 struct regulator_dev
*rdev
;
135 config
.regmap
= devm_regmap_init_i2c(i2c
, &tps6287x_regmap_config
);
136 if (IS_ERR(config
.regmap
)) {
137 dev_err(dev
, "Failed to init i2c\n");
138 return PTR_ERR(config
.regmap
);
142 config
.of_node
= dev
->of_node
;
143 config
.init_data
= of_get_regulator_init_data(dev
, dev
->of_node
,
146 rdev
= devm_regulator_register(dev
, &tps6287x_reg
, &config
);
148 dev_err(dev
, "Failed to register regulator\n");
149 return PTR_ERR(rdev
);
152 dev_dbg(dev
, "Probed regulator\n");
157 static const struct of_device_id tps6287x_dt_ids
[] = {
158 { .compatible
= "ti,tps62870", },
159 { .compatible
= "ti,tps62871", },
160 { .compatible
= "ti,tps62872", },
161 { .compatible
= "ti,tps62873", },
165 MODULE_DEVICE_TABLE(of
, tps6287x_dt_ids
);
167 static const struct i2c_device_id tps6287x_i2c_id
[] = {
175 MODULE_DEVICE_TABLE(i2c
, tps6287x_i2c_id
);
177 static struct i2c_driver tps6287x_regulator_driver
= {
180 .of_match_table
= tps6287x_dt_ids
,
182 .probe
= tps6287x_i2c_probe
,
183 .id_table
= tps6287x_i2c_id
,
186 module_i2c_driver(tps6287x_regulator_driver
);
188 MODULE_AUTHOR("MÃ¥rten Lindahl <marten.lindahl@axis.com>");
189 MODULE_DESCRIPTION("Regulator driver for TI TPS6287X PMIC");
190 MODULE_LICENSE("GPL");