xref: /openbmc/linux/drivers/regulator/ad5398.c (revision 32ced09d)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Voltage and current regulation for AD5398 and AD5821
4  *
5  * Copyright 2010 Analog Devices Inc.
6  *
7  * Enter bugs at http://blackfin.uclinux.org/
8  */
9 
10 #include <linux/module.h>
11 #include <linux/err.h>
12 #include <linux/i2c.h>
13 #include <linux/slab.h>
14 #include <linux/platform_device.h>
15 #include <linux/regulator/driver.h>
16 #include <linux/regulator/machine.h>
17 
18 #define AD5398_CURRENT_EN_MASK	0x8000
19 
20 struct ad5398_chip_info {
21 	struct i2c_client *client;
22 	int min_uA;
23 	int max_uA;
24 	unsigned int current_level;
25 	unsigned int current_mask;
26 	unsigned int current_offset;
27 	struct regulator_dev *rdev;
28 };
29 
30 static int ad5398_calc_current(struct ad5398_chip_info *chip,
31 	unsigned selector)
32 {
33 	unsigned range_uA = chip->max_uA - chip->min_uA;
34 
35 	return chip->min_uA + (selector * range_uA / chip->current_level);
36 }
37 
38 static int ad5398_read_reg(struct i2c_client *client, unsigned short *data)
39 {
40 	unsigned short val;
41 	int ret;
42 
43 	ret = i2c_master_recv(client, (char *)&val, 2);
44 	if (ret < 0) {
45 		dev_err(&client->dev, "I2C read error\n");
46 		return ret;
47 	}
48 	*data = be16_to_cpu(val);
49 
50 	return ret;
51 }
52 
53 static int ad5398_write_reg(struct i2c_client *client, const unsigned short data)
54 {
55 	unsigned short val;
56 	int ret;
57 
58 	val = cpu_to_be16(data);
59 	ret = i2c_master_send(client, (char *)&val, 2);
60 	if (ret != 2) {
61 		dev_err(&client->dev, "I2C write error\n");
62 		return ret < 0 ? ret : -EIO;
63 	}
64 
65 	return 0;
66 }
67 
68 static int ad5398_get_current_limit(struct regulator_dev *rdev)
69 {
70 	struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
71 	struct i2c_client *client = chip->client;
72 	unsigned short data;
73 	int ret;
74 
75 	ret = ad5398_read_reg(client, &data);
76 	if (ret < 0)
77 		return ret;
78 
79 	ret = (data & chip->current_mask) >> chip->current_offset;
80 
81 	return ad5398_calc_current(chip, ret);
82 }
83 
84 static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)
85 {
86 	struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
87 	struct i2c_client *client = chip->client;
88 	unsigned range_uA = chip->max_uA - chip->min_uA;
89 	unsigned selector;
90 	unsigned short data;
91 	int ret;
92 
93 	if (min_uA < chip->min_uA)
94 		min_uA = chip->min_uA;
95 	if (max_uA > chip->max_uA)
96 		max_uA = chip->max_uA;
97 
98 	if (min_uA > chip->max_uA || max_uA < chip->min_uA)
99 		return -EINVAL;
100 
101 	selector = DIV_ROUND_UP((min_uA - chip->min_uA) * chip->current_level,
102 				range_uA);
103 	if (ad5398_calc_current(chip, selector) > max_uA)
104 		return -EINVAL;
105 
106 	dev_dbg(&client->dev, "changing current %duA\n",
107 		ad5398_calc_current(chip, selector));
108 
109 	/* read chip enable bit */
110 	ret = ad5398_read_reg(client, &data);
111 	if (ret < 0)
112 		return ret;
113 
114 	/* prepare register data */
115 	selector = (selector << chip->current_offset) & chip->current_mask;
116 	data = (unsigned short)selector | (data & AD5398_CURRENT_EN_MASK);
117 
118 	/* write the new current value back as well as enable bit */
119 	ret = ad5398_write_reg(client, data);
120 
121 	return ret;
122 }
123 
124 static int ad5398_is_enabled(struct regulator_dev *rdev)
125 {
126 	struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
127 	struct i2c_client *client = chip->client;
128 	unsigned short data;
129 	int ret;
130 
131 	ret = ad5398_read_reg(client, &data);
132 	if (ret < 0)
133 		return ret;
134 
135 	if (data & AD5398_CURRENT_EN_MASK)
136 		return 1;
137 	else
138 		return 0;
139 }
140 
141 static int ad5398_enable(struct regulator_dev *rdev)
142 {
143 	struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
144 	struct i2c_client *client = chip->client;
145 	unsigned short data;
146 	int ret;
147 
148 	ret = ad5398_read_reg(client, &data);
149 	if (ret < 0)
150 		return ret;
151 
152 	if (data & AD5398_CURRENT_EN_MASK)
153 		return 0;
154 
155 	data |= AD5398_CURRENT_EN_MASK;
156 
157 	ret = ad5398_write_reg(client, data);
158 
159 	return ret;
160 }
161 
162 static int ad5398_disable(struct regulator_dev *rdev)
163 {
164 	struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
165 	struct i2c_client *client = chip->client;
166 	unsigned short data;
167 	int ret;
168 
169 	ret = ad5398_read_reg(client, &data);
170 	if (ret < 0)
171 		return ret;
172 
173 	if (!(data & AD5398_CURRENT_EN_MASK))
174 		return 0;
175 
176 	data &= ~AD5398_CURRENT_EN_MASK;
177 
178 	ret = ad5398_write_reg(client, data);
179 
180 	return ret;
181 }
182 
183 static const struct regulator_ops ad5398_ops = {
184 	.get_current_limit = ad5398_get_current_limit,
185 	.set_current_limit = ad5398_set_current_limit,
186 	.enable = ad5398_enable,
187 	.disable = ad5398_disable,
188 	.is_enabled = ad5398_is_enabled,
189 };
190 
191 static const struct regulator_desc ad5398_reg = {
192 	.name = "isink",
193 	.id = 0,
194 	.ops = &ad5398_ops,
195 	.type = REGULATOR_CURRENT,
196 	.owner = THIS_MODULE,
197 };
198 
199 struct ad5398_current_data_format {
200 	int current_bits;
201 	int current_offset;
202 	int min_uA;
203 	int max_uA;
204 };
205 
206 static const struct ad5398_current_data_format df_10_4_120 = {10, 4, 0, 120000};
207 
208 static const struct i2c_device_id ad5398_id[] = {
209 	{ "ad5398", (kernel_ulong_t)&df_10_4_120 },
210 	{ "ad5821", (kernel_ulong_t)&df_10_4_120 },
211 	{ }
212 };
213 MODULE_DEVICE_TABLE(i2c, ad5398_id);
214 
215 static int ad5398_probe(struct i2c_client *client,
216 				const struct i2c_device_id *id)
217 {
218 	struct regulator_init_data *init_data = dev_get_platdata(&client->dev);
219 	struct regulator_config config = { };
220 	struct ad5398_chip_info *chip;
221 	const struct ad5398_current_data_format *df =
222 			(struct ad5398_current_data_format *)id->driver_data;
223 
224 	if (!init_data)
225 		return -EINVAL;
226 
227 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
228 	if (!chip)
229 		return -ENOMEM;
230 
231 	config.dev = &client->dev;
232 	config.init_data = init_data;
233 	config.driver_data = chip;
234 
235 	chip->client = client;
236 
237 	chip->min_uA = df->min_uA;
238 	chip->max_uA = df->max_uA;
239 	chip->current_level = 1 << df->current_bits;
240 	chip->current_offset = df->current_offset;
241 	chip->current_mask = (chip->current_level - 1) << chip->current_offset;
242 
243 	chip->rdev = devm_regulator_register(&client->dev, &ad5398_reg,
244 					     &config);
245 	if (IS_ERR(chip->rdev)) {
246 		dev_err(&client->dev, "failed to register %s %s\n",
247 			id->name, ad5398_reg.name);
248 		return PTR_ERR(chip->rdev);
249 	}
250 
251 	i2c_set_clientdata(client, chip);
252 	dev_dbg(&client->dev, "%s regulator driver is registered.\n", id->name);
253 	return 0;
254 }
255 
256 static struct i2c_driver ad5398_driver = {
257 	.probe = ad5398_probe,
258 	.driver		= {
259 		.name	= "ad5398",
260 	},
261 	.id_table	= ad5398_id,
262 };
263 
264 static int __init ad5398_init(void)
265 {
266 	return i2c_add_driver(&ad5398_driver);
267 }
268 subsys_initcall(ad5398_init);
269 
270 static void __exit ad5398_exit(void)
271 {
272 	i2c_del_driver(&ad5398_driver);
273 }
274 module_exit(ad5398_exit);
275 
276 MODULE_DESCRIPTION("AD5398 and AD5821 current regulator driver");
277 MODULE_AUTHOR("Sonic Zhang");
278 MODULE_LICENSE("GPL");
279