1 // SPDX-License-Identifier: GPL-2.0
3 // SY8827N regulator driver
5 // Copyright (C) 2020 Synaptics Incorporated
7 // Author: Jisheng Zhang <jszhang@kernel.org>
9 #include <linux/gpio/consumer.h>
10 #include <linux/module.h>
11 #include <linux/i2c.h>
12 #include <linux/of_device.h>
13 #include <linux/regmap.h>
14 #include <linux/regulator/driver.h>
15 #include <linux/regulator/of_regulator.h>
17 #define SY8827N_VSEL0 0
18 #define SY8827N_BUCK_EN (1 << 7)
19 #define SY8827N_MODE (1 << 6)
20 #define SY8827N_VSEL1 1
21 #define SY8827N_CTRL 2
23 #define SY8827N_NVOLTAGES 64
24 #define SY8827N_VSELMIN 600000
25 #define SY8827N_VSELSTEP 12500
27 struct sy8827n_device_info
{
29 struct regulator_desc desc
;
30 struct regulator_init_data
*regulator
;
31 struct gpio_desc
*en_gpio
;
32 unsigned int vsel_reg
;
35 static int sy8827n_set_mode(struct regulator_dev
*rdev
, unsigned int mode
)
37 struct sy8827n_device_info
*di
= rdev_get_drvdata(rdev
);
40 case REGULATOR_MODE_FAST
:
41 regmap_update_bits(rdev
->regmap
, di
->vsel_reg
,
42 SY8827N_MODE
, SY8827N_MODE
);
44 case REGULATOR_MODE_NORMAL
:
45 regmap_update_bits(rdev
->regmap
, di
->vsel_reg
,
54 static unsigned int sy8827n_get_mode(struct regulator_dev
*rdev
)
56 struct sy8827n_device_info
*di
= rdev_get_drvdata(rdev
);
60 ret
= regmap_read(rdev
->regmap
, di
->vsel_reg
, &val
);
63 if (val
& SY8827N_MODE
)
64 return REGULATOR_MODE_FAST
;
66 return REGULATOR_MODE_NORMAL
;
69 static const struct regulator_ops sy8827n_regulator_ops
= {
70 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
71 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
72 .set_voltage_time_sel
= regulator_set_voltage_time_sel
,
73 .map_voltage
= regulator_map_voltage_linear
,
74 .list_voltage
= regulator_list_voltage_linear
,
75 .enable
= regulator_enable_regmap
,
76 .disable
= regulator_disable_regmap
,
77 .is_enabled
= regulator_is_enabled_regmap
,
78 .set_mode
= sy8827n_set_mode
,
79 .get_mode
= sy8827n_get_mode
,
82 static int sy8827n_regulator_register(struct sy8827n_device_info
*di
,
83 struct regulator_config
*config
)
85 struct regulator_desc
*rdesc
= &di
->desc
;
86 struct regulator_dev
*rdev
;
88 rdesc
->name
= "sy8827n-reg";
89 rdesc
->supply_name
= "vin";
90 rdesc
->ops
= &sy8827n_regulator_ops
;
91 rdesc
->type
= REGULATOR_VOLTAGE
;
92 rdesc
->n_voltages
= SY8827N_NVOLTAGES
;
93 rdesc
->enable_reg
= di
->vsel_reg
;
94 rdesc
->enable_mask
= SY8827N_BUCK_EN
;
95 rdesc
->min_uV
= SY8827N_VSELMIN
;
96 rdesc
->uV_step
= SY8827N_VSELSTEP
;
97 rdesc
->vsel_reg
= di
->vsel_reg
;
98 rdesc
->vsel_mask
= rdesc
->n_voltages
- 1;
99 rdesc
->owner
= THIS_MODULE
;
101 rdev
= devm_regulator_register(di
->dev
, &di
->desc
, config
);
102 return PTR_ERR_OR_ZERO(rdev
);
105 static const struct regmap_config sy8827n_regmap_config
= {
110 static int sy8827n_i2c_probe(struct i2c_client
*client
)
112 struct device
*dev
= &client
->dev
;
113 struct device_node
*np
= dev
->of_node
;
114 struct sy8827n_device_info
*di
;
115 struct regulator_config config
= { };
116 struct regmap
*regmap
;
119 di
= devm_kzalloc(dev
, sizeof(struct sy8827n_device_info
), GFP_KERNEL
);
123 di
->regulator
= of_get_regulator_init_data(dev
, np
, &di
->desc
);
124 if (!di
->regulator
) {
125 dev_err(dev
, "Platform data not found!\n");
129 di
->en_gpio
= devm_gpiod_get_optional(dev
, "enable", GPIOD_OUT_HIGH
);
130 if (IS_ERR(di
->en_gpio
))
131 return PTR_ERR(di
->en_gpio
);
133 if (of_property_read_bool(np
, "silergy,vsel-state-high"))
134 di
->vsel_reg
= SY8827N_VSEL1
;
136 di
->vsel_reg
= SY8827N_VSEL0
;
140 regmap
= devm_regmap_init_i2c(client
, &sy8827n_regmap_config
);
141 if (IS_ERR(regmap
)) {
142 dev_err(dev
, "Failed to allocate regmap!\n");
143 return PTR_ERR(regmap
);
145 i2c_set_clientdata(client
, di
);
147 config
.dev
= di
->dev
;
148 config
.init_data
= di
->regulator
;
149 config
.regmap
= regmap
;
150 config
.driver_data
= di
;
153 ret
= sy8827n_regulator_register(di
, &config
);
155 dev_err(dev
, "Failed to register regulator!\n");
160 static const struct of_device_id sy8827n_dt_ids
[] = {
162 .compatible
= "silergy,sy8827n",
166 MODULE_DEVICE_TABLE(of
, sy8827n_dt_ids
);
169 static const struct i2c_device_id sy8827n_id
[] = {
173 MODULE_DEVICE_TABLE(i2c
, sy8827n_id
);
175 static struct i2c_driver sy8827n_regulator_driver
= {
177 .name
= "sy8827n-regulator",
178 .of_match_table
= of_match_ptr(sy8827n_dt_ids
),
180 .probe_new
= sy8827n_i2c_probe
,
181 .id_table
= sy8827n_id
,
183 module_i2c_driver(sy8827n_regulator_driver
);
185 MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>");
186 MODULE_DESCRIPTION("SY8827N regulator driver");
187 MODULE_LICENSE("GPL v2");