xref: /OK3568_Linux_fs/kernel/drivers/regulator/tps549b22-regulator.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright (c) 2017-2018 Rockchip Electronics Co. Ltd.
3*4882a593Smuzhiyun  * Author: XiaoDong Huang <derrick.huang@rock-chips.com>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * This program is free software; you can redistribute it and/or modify
6*4882a593Smuzhiyun  * it under the terms of the GNU General Public License as published by
7*4882a593Smuzhiyun  * the Free Software Foundation; either version 2 of the License, or
8*4882a593Smuzhiyun  * (at your option) any later version.
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * This program is distributed in the hope that it will be useful,
11*4882a593Smuzhiyun  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*4882a593Smuzhiyun  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*4882a593Smuzhiyun  * GNU General Public License for more details.
14*4882a593Smuzhiyun  */
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include <linux/bug.h>
17*4882a593Smuzhiyun #include <linux/debugfs.h>
18*4882a593Smuzhiyun #include <linux/delay.h>
19*4882a593Smuzhiyun #include <linux/err.h>
20*4882a593Smuzhiyun #include <linux/i2c.h>
21*4882a593Smuzhiyun #include <linux/kernel.h>
22*4882a593Smuzhiyun #include <linux/mutex.h>
23*4882a593Smuzhiyun #include <linux/module.h>
24*4882a593Smuzhiyun #include <linux/of.h>
25*4882a593Smuzhiyun #include <linux/of_device.h>
26*4882a593Smuzhiyun #include <linux/regulator/of_regulator.h>
27*4882a593Smuzhiyun #include <linux/regulator/driver.h>
28*4882a593Smuzhiyun #include <linux/regulator/machine.h>
29*4882a593Smuzhiyun #include <linux/regulator/driver.h>
30*4882a593Smuzhiyun #include <linux/regmap.h>
31*4882a593Smuzhiyun #include <linux/types.h>
32*4882a593Smuzhiyun #include <linux/uaccess.h>
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun #define TPS549b22_REG_OPERATION		0x01
35*4882a593Smuzhiyun #define TPS549b22_REG_ON_OFF_CFG	0x02
36*4882a593Smuzhiyun #define TPS549b22_REG_WRITE_PROTECT	0x10
37*4882a593Smuzhiyun #define TPS549b22_REG_COMMAND		0x21
38*4882a593Smuzhiyun #define TPS549b22_REG_MRG_H		0x25
39*4882a593Smuzhiyun #define TPS549b22_REG_MRG_L		0x26
40*4882a593Smuzhiyun #define TPS549b22_REG_ST_BYTE		0x78
41*4882a593Smuzhiyun #define TPS549b22_REG_MFR_SPC_44	0xfc
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #define TPS549b22_ID			0x0200
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun #define VOL_MSK				0x3ff
46*4882a593Smuzhiyun #define VOL_OFF_MSK			0x40
47*4882a593Smuzhiyun #define OPERATION_ON_MSK		0x80
48*4882a593Smuzhiyun #define OPERATION_MRG_MSK		0x3c
49*4882a593Smuzhiyun #define ON_OFF_CFG_OPT_MSK		0x0c
50*4882a593Smuzhiyun #define VOL_MIN_IDX			0x133
51*4882a593Smuzhiyun #define VOL_MAX_IDX			0x266
52*4882a593Smuzhiyun #define VOL_STEP_DEF			2500
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define VOL2REG(vol_sel, vol_step) \
55*4882a593Smuzhiyun 		((vol_sel) / (vol_step) & VOL_MSK)
56*4882a593Smuzhiyun #define REG2VOL(val, vol_step) \
57*4882a593Smuzhiyun 		((vol_step) * ((val) & VOL_MSK))
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun #define TPS549b22_NUM_REGULATORS	1
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun struct tps549b22 {
62*4882a593Smuzhiyun 	struct device *dev;
63*4882a593Smuzhiyun 	struct i2c_client *i2c;
64*4882a593Smuzhiyun 	int num_regulators;
65*4882a593Smuzhiyun 	struct regulator_dev **rdev;
66*4882a593Smuzhiyun 	struct regmap *regmap_8bits;
67*4882a593Smuzhiyun 	struct regmap *regmap_16bits;
68*4882a593Smuzhiyun 	int vol_step;
69*4882a593Smuzhiyun };
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun struct tps549b22_board {
72*4882a593Smuzhiyun 	struct regulator_init_data
73*4882a593Smuzhiyun 		*tps549b22_init_data[TPS549b22_NUM_REGULATORS];
74*4882a593Smuzhiyun 	struct device_node *of_node[TPS549b22_NUM_REGULATORS];
75*4882a593Smuzhiyun };
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun struct tps549b22_regulator_subdev {
78*4882a593Smuzhiyun 	int id;
79*4882a593Smuzhiyun 	struct regulator_init_data *initdata;
80*4882a593Smuzhiyun 	struct device_node *reg_node;
81*4882a593Smuzhiyun };
82*4882a593Smuzhiyun 
tps549b22_dcdc_list_voltage(struct regulator_dev * rdev,unsigned int index)83*4882a593Smuzhiyun static int tps549b22_dcdc_list_voltage(struct regulator_dev *rdev,
84*4882a593Smuzhiyun 				       unsigned int index)
85*4882a593Smuzhiyun {
86*4882a593Smuzhiyun 	struct tps549b22 *tps549b22 = rdev_get_drvdata(rdev);
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	if (index + VOL_MIN_IDX > VOL_MAX_IDX)
89*4882a593Smuzhiyun 		return -EINVAL;
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun 	return REG2VOL(index + VOL_MIN_IDX, tps549b22->vol_step);
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun 
tps549b22_reg_init(struct tps549b22 * tps549b22)94*4882a593Smuzhiyun static int tps549b22_reg_init(struct tps549b22 *tps549b22)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun 	if (regmap_update_bits(tps549b22->regmap_8bits,
97*4882a593Smuzhiyun 			       TPS549b22_REG_OPERATION,
98*4882a593Smuzhiyun 			       OPERATION_ON_MSK,
99*4882a593Smuzhiyun 			       0x80) == 0)
100*4882a593Smuzhiyun 		return regmap_update_bits(tps549b22->regmap_8bits,
101*4882a593Smuzhiyun 					  TPS549b22_REG_ON_OFF_CFG,
102*4882a593Smuzhiyun 					  ON_OFF_CFG_OPT_MSK,
103*4882a593Smuzhiyun 					  0x0c);
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun 	dev_err(tps549b22->dev, "regulator init err\n");
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun 	return -1;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun 
tps549b22dcdc_is_enabled(struct regulator_dev * rdev)110*4882a593Smuzhiyun static int tps549b22dcdc_is_enabled(struct regulator_dev *rdev)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun 	struct tps549b22 *tps549b22 = rdev_get_drvdata(rdev);
113*4882a593Smuzhiyun 	int err;
114*4882a593Smuzhiyun 	u32 val;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	err = regmap_read(tps549b22->regmap_8bits, TPS549b22_REG_ST_BYTE, &val);
117*4882a593Smuzhiyun 	if (err)
118*4882a593Smuzhiyun 		return 0;
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun 	return !(val & VOL_OFF_MSK);
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun 
tps549b22dcdc_enable(struct regulator_dev * rdev)123*4882a593Smuzhiyun static int tps549b22dcdc_enable(struct regulator_dev *rdev)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	struct tps549b22 *tps549b22 = rdev_get_drvdata(rdev);
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	return regmap_update_bits(tps549b22->regmap_8bits,
128*4882a593Smuzhiyun 				  TPS549b22_REG_OPERATION,
129*4882a593Smuzhiyun 				  OPERATION_ON_MSK,
130*4882a593Smuzhiyun 				  0x80);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
tps549b22dcdc_disable(struct regulator_dev * rdev)133*4882a593Smuzhiyun static int tps549b22dcdc_disable(struct regulator_dev *rdev)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun 	struct tps549b22 *tps549b22 = rdev_get_drvdata(rdev);
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	return regmap_update_bits(tps549b22->regmap_8bits,
138*4882a593Smuzhiyun 				  TPS549b22_REG_OPERATION,
139*4882a593Smuzhiyun 				  OPERATION_ON_MSK,
140*4882a593Smuzhiyun 				  0);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
tps549b22dcdc_get_voltage(struct regulator_dev * rdev)143*4882a593Smuzhiyun static int tps549b22dcdc_get_voltage(struct regulator_dev *rdev)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	struct tps549b22 *tps549b22 = rdev_get_drvdata(rdev);
146*4882a593Smuzhiyun 	int err;
147*4882a593Smuzhiyun 	u32 val = 0;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	err = regmap_read(tps549b22->regmap_16bits,
150*4882a593Smuzhiyun 			  TPS549b22_REG_COMMAND,
151*4882a593Smuzhiyun 			  &val);
152*4882a593Smuzhiyun 	if (!err)
153*4882a593Smuzhiyun 		return REG2VOL(val, tps549b22->vol_step);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	return -1;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun 
tps549b22dcdc_set_voltage(struct regulator_dev * rdev,int min_uV,int max_uV,unsigned int * selector)158*4882a593Smuzhiyun static int tps549b22dcdc_set_voltage(struct regulator_dev *rdev,
159*4882a593Smuzhiyun 				     int min_uV,
160*4882a593Smuzhiyun 				     int max_uV,
161*4882a593Smuzhiyun 				     unsigned int *selector)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	struct tps549b22 *tps549b22 = rdev_get_drvdata(rdev);
164*4882a593Smuzhiyun 	int val;
165*4882a593Smuzhiyun 	int err;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	if (min_uV < REG2VOL(VOL_MIN_IDX, tps549b22->vol_step) ||
168*4882a593Smuzhiyun 	    min_uV > REG2VOL(VOL_MAX_IDX, tps549b22->vol_step)) {
169*4882a593Smuzhiyun 		dev_warn(rdev_get_dev(rdev),
170*4882a593Smuzhiyun 			 "this voltage is out of limit! voltage set is %d mv\n",
171*4882a593Smuzhiyun 			 REG2VOL(min_uV, tps549b22->vol_step));
172*4882a593Smuzhiyun 		return -EINVAL;
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	for (val = VOL_MIN_IDX; val <= VOL_MAX_IDX; val++)
176*4882a593Smuzhiyun 		if (REG2VOL(val, tps549b22->vol_step) >= min_uV)
177*4882a593Smuzhiyun 			break;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	if (REG2VOL(val, tps549b22->vol_step) > max_uV)
180*4882a593Smuzhiyun 		dev_warn(rdev_get_dev(rdev),
181*4882a593Smuzhiyun 			 "this voltage is not support! voltage set is %d mv\n",
182*4882a593Smuzhiyun 			 REG2VOL(val, tps549b22->vol_step));
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	err = regmap_update_bits(tps549b22->regmap_16bits,
185*4882a593Smuzhiyun 				 TPS549b22_REG_COMMAND,
186*4882a593Smuzhiyun 				 VOL_MSK,
187*4882a593Smuzhiyun 				 val);
188*4882a593Smuzhiyun 	if (err)
189*4882a593Smuzhiyun 		dev_err(rdev_get_dev(rdev),
190*4882a593Smuzhiyun 			"set voltage is error! voltage set is %d mv\n",
191*4882a593Smuzhiyun 			REG2VOL(val, tps549b22->vol_step));
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	return err;
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun static struct regulator_ops tps549b22dcdc_ops = {
197*4882a593Smuzhiyun 	.set_voltage = tps549b22dcdc_set_voltage,
198*4882a593Smuzhiyun 	.get_voltage = tps549b22dcdc_get_voltage,
199*4882a593Smuzhiyun 	.is_enabled = tps549b22dcdc_is_enabled,
200*4882a593Smuzhiyun 	.enable = tps549b22dcdc_enable,
201*4882a593Smuzhiyun 	.disable = tps549b22dcdc_disable,
202*4882a593Smuzhiyun 	.list_voltage = tps549b22_dcdc_list_voltage,
203*4882a593Smuzhiyun };
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun static struct regulator_desc regulators[] = {
206*4882a593Smuzhiyun 	{
207*4882a593Smuzhiyun 		.name = "tps549b22_DCDC1",
208*4882a593Smuzhiyun 		.id = 0,
209*4882a593Smuzhiyun 		.ops = &tps549b22dcdc_ops,
210*4882a593Smuzhiyun 		.n_voltages = VOL_MAX_IDX - VOL_MIN_IDX + 1,
211*4882a593Smuzhiyun 		.type = REGULATOR_VOLTAGE,
212*4882a593Smuzhiyun 		.owner = THIS_MODULE,
213*4882a593Smuzhiyun 	},
214*4882a593Smuzhiyun };
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun static struct of_regulator_match tps549b22_reg_matches[] = {
217*4882a593Smuzhiyun 	{ .name = "tps549b22_dcdc1", .driver_data = (void *)0},
218*4882a593Smuzhiyun };
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun static struct tps549b22_board *
tps549b22_parse_dt(struct tps549b22 * tps549b22)221*4882a593Smuzhiyun tps549b22_parse_dt(struct tps549b22 *tps549b22)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	struct tps549b22_board *pdata;
224*4882a593Smuzhiyun 	struct device_node *regs;
225*4882a593Smuzhiyun 	struct device_node *tps549b22_np;
226*4882a593Smuzhiyun 	int count;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 	tps549b22_np = of_node_get(tps549b22->dev->of_node);
229*4882a593Smuzhiyun 	if (!tps549b22_np) {
230*4882a593Smuzhiyun 		pr_err("could not find pmic sub-node\n");
231*4882a593Smuzhiyun 		goto err;
232*4882a593Smuzhiyun 	}
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 	regs = of_get_child_by_name(tps549b22_np, "regulators");
235*4882a593Smuzhiyun 	if (!regs)
236*4882a593Smuzhiyun 		goto err;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	count = of_regulator_match(tps549b22->dev,
239*4882a593Smuzhiyun 				   regs,
240*4882a593Smuzhiyun 				   tps549b22_reg_matches,
241*4882a593Smuzhiyun 				   TPS549b22_NUM_REGULATORS);
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	if (of_property_read_u32(tps549b22_reg_matches[0].of_node,
244*4882a593Smuzhiyun 				 "voltage-step",
245*4882a593Smuzhiyun 				 &tps549b22->vol_step))
246*4882a593Smuzhiyun 		tps549b22->vol_step = VOL_STEP_DEF;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	dev_info(tps549b22->dev, "voltage-step: %duV\n", tps549b22->vol_step);
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	of_node_put(regs);
251*4882a593Smuzhiyun 	of_node_put(tps549b22_np);
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun 	if (count <= 0)
254*4882a593Smuzhiyun 		goto err;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	pdata = devm_kzalloc(tps549b22->dev, sizeof(*pdata), GFP_KERNEL);
257*4882a593Smuzhiyun 	if (!pdata)
258*4882a593Smuzhiyun 		goto err;
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	pdata->tps549b22_init_data[0] = tps549b22_reg_matches[0].init_data;
261*4882a593Smuzhiyun 	pdata->of_node[0] = tps549b22_reg_matches[0].of_node;
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	return pdata;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun err:
266*4882a593Smuzhiyun 	return NULL;
267*4882a593Smuzhiyun }
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun static const struct of_device_id tps549b22_of_match[] = {
270*4882a593Smuzhiyun 	{.compatible = "ti,tps549b22"},
271*4882a593Smuzhiyun 	{ },
272*4882a593Smuzhiyun };
273*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, tps549b22_of_match);
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun static const struct regmap_config tps549b22_8bits_regmap_config = {
276*4882a593Smuzhiyun 	.reg_bits = 8,
277*4882a593Smuzhiyun 	.val_bits = 8,
278*4882a593Smuzhiyun 	.max_register = TPS549b22_REG_MFR_SPC_44 + 1,
279*4882a593Smuzhiyun 	.cache_type = REGCACHE_NONE,
280*4882a593Smuzhiyun };
281*4882a593Smuzhiyun 
282*4882a593Smuzhiyun static const struct regmap_config tps549b22_16bits_regmap_config = {
283*4882a593Smuzhiyun 	.reg_bits = 8,
284*4882a593Smuzhiyun 	.val_bits = 16,
285*4882a593Smuzhiyun 	.max_register = TPS549b22_REG_MFR_SPC_44 + 1,
286*4882a593Smuzhiyun 	.cache_type = REGCACHE_NONE,
287*4882a593Smuzhiyun 	.val_format_endian = REGMAP_ENDIAN_LITTLE,
288*4882a593Smuzhiyun };
289*4882a593Smuzhiyun 
tps549b22_i2c_probe(struct i2c_client * i2c,const struct i2c_device_id * id)290*4882a593Smuzhiyun static int tps549b22_i2c_probe(struct i2c_client *i2c,
291*4882a593Smuzhiyun 			       const struct i2c_device_id *id)
292*4882a593Smuzhiyun {
293*4882a593Smuzhiyun 	struct tps549b22 *tps549b22;
294*4882a593Smuzhiyun 	struct tps549b22_board *pdev = NULL;
295*4882a593Smuzhiyun 	const struct of_device_id *match;
296*4882a593Smuzhiyun 	struct regulator_config config = { };
297*4882a593Smuzhiyun 	struct regulator_dev *rdev;
298*4882a593Smuzhiyun 	struct regulator_init_data *reg_data;
299*4882a593Smuzhiyun 	int ret;
300*4882a593Smuzhiyun 	u32 val;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	if (i2c->dev.of_node) {
303*4882a593Smuzhiyun 		match = of_match_device(tps549b22_of_match, &i2c->dev);
304*4882a593Smuzhiyun 		if (!match) {
305*4882a593Smuzhiyun 			pr_err("Failed to find matching dt id\n");
306*4882a593Smuzhiyun 			return -EINVAL;
307*4882a593Smuzhiyun 		}
308*4882a593Smuzhiyun 	}
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 	tps549b22 = devm_kzalloc(&i2c->dev,
311*4882a593Smuzhiyun 				 sizeof(struct tps549b22),
312*4882a593Smuzhiyun 				 GFP_KERNEL);
313*4882a593Smuzhiyun 	if (!tps549b22) {
314*4882a593Smuzhiyun 		ret = -ENOMEM;
315*4882a593Smuzhiyun 		goto err;
316*4882a593Smuzhiyun 	}
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	tps549b22->regmap_8bits =
319*4882a593Smuzhiyun 		devm_regmap_init_i2c(i2c, &tps549b22_8bits_regmap_config);
320*4882a593Smuzhiyun 	if (IS_ERR(tps549b22->regmap_8bits)) {
321*4882a593Smuzhiyun 		dev_err(&i2c->dev, "8 bits regmap initialization failed\n");
322*4882a593Smuzhiyun 		return PTR_ERR(tps549b22->regmap_8bits);
323*4882a593Smuzhiyun 	}
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 	tps549b22->regmap_16bits =
326*4882a593Smuzhiyun 		devm_regmap_init_i2c(i2c, &tps549b22_16bits_regmap_config);
327*4882a593Smuzhiyun 	if (IS_ERR(tps549b22->regmap_16bits)) {
328*4882a593Smuzhiyun 		dev_err(&i2c->dev, "16 bits regmap initialization failed\n");
329*4882a593Smuzhiyun 		return PTR_ERR(tps549b22->regmap_16bits);
330*4882a593Smuzhiyun 	}
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	tps549b22->i2c = i2c;
333*4882a593Smuzhiyun 	tps549b22->dev = &i2c->dev;
334*4882a593Smuzhiyun 	i2c_set_clientdata(i2c, tps549b22);
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	ret = regmap_read(tps549b22->regmap_16bits,
337*4882a593Smuzhiyun 			  TPS549b22_REG_MFR_SPC_44,
338*4882a593Smuzhiyun 			  &val);
339*4882a593Smuzhiyun 	if (!ret) {
340*4882a593Smuzhiyun 		if (val != TPS549b22_ID)
341*4882a593Smuzhiyun 			dev_warn(tps549b22->dev,
342*4882a593Smuzhiyun 				 "The device is not tps549b22 0x%x\n",
343*4882a593Smuzhiyun 				 val);
344*4882a593Smuzhiyun 	} else {
345*4882a593Smuzhiyun 		dev_err(tps549b22->dev,
346*4882a593Smuzhiyun 			"Tps549b22_reg_read err, ret = %d\n",
347*4882a593Smuzhiyun 			ret);
348*4882a593Smuzhiyun 		return -EINVAL;
349*4882a593Smuzhiyun 	}
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	tps549b22_reg_init(tps549b22);
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	if (tps549b22->dev->of_node)
354*4882a593Smuzhiyun 		pdev = tps549b22_parse_dt(tps549b22);
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	if (pdev) {
357*4882a593Smuzhiyun 		tps549b22->num_regulators = TPS549b22_NUM_REGULATORS;
358*4882a593Smuzhiyun 		tps549b22->rdev =
359*4882a593Smuzhiyun 			devm_kmalloc_array(tps549b22->dev,
360*4882a593Smuzhiyun 					   TPS549b22_NUM_REGULATORS,
361*4882a593Smuzhiyun 					   sizeof(struct regulator_dev *),
362*4882a593Smuzhiyun 					   GFP_KERNEL);
363*4882a593Smuzhiyun 		if (!tps549b22->rdev)
364*4882a593Smuzhiyun 			return -ENOMEM;
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 		/* Instantiate the regulators */
367*4882a593Smuzhiyun 		reg_data = pdev->tps549b22_init_data[0];
368*4882a593Smuzhiyun 		config.dev = tps549b22->dev;
369*4882a593Smuzhiyun 		config.driver_data = tps549b22;
370*4882a593Smuzhiyun 		if (tps549b22->dev->of_node)
371*4882a593Smuzhiyun 			config.of_node = pdev->of_node[0];
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 		config.init_data = reg_data;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 		rdev = devm_regulator_register(tps549b22->dev,
376*4882a593Smuzhiyun 					       &regulators[0],
377*4882a593Smuzhiyun 					       &config);
378*4882a593Smuzhiyun 		if (IS_ERR(rdev)) {
379*4882a593Smuzhiyun 			pr_err("failed to register regulator\n");
380*4882a593Smuzhiyun 			goto err;
381*4882a593Smuzhiyun 		}
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 		tps549b22->rdev[0] = rdev;
384*4882a593Smuzhiyun 	}
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun 	return 0;
387*4882a593Smuzhiyun err:
388*4882a593Smuzhiyun 	return ret;
389*4882a593Smuzhiyun }
390*4882a593Smuzhiyun 
tps549b22_i2c_remove(struct i2c_client * i2c)391*4882a593Smuzhiyun static int tps549b22_i2c_remove(struct i2c_client *i2c)
392*4882a593Smuzhiyun {
393*4882a593Smuzhiyun 	i2c_set_clientdata(i2c, NULL);
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun 	return 0;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun 
398*4882a593Smuzhiyun static const struct i2c_device_id tps549b22_i2c_id[] = {
399*4882a593Smuzhiyun 	{"tps549b22", 0},
400*4882a593Smuzhiyun 	{ }
401*4882a593Smuzhiyun };
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, tps549b22_i2c_id);
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun static struct i2c_driver tps549b22_i2c_driver = {
406*4882a593Smuzhiyun 	.driver = {
407*4882a593Smuzhiyun 		.name = "tps549b22",
408*4882a593Smuzhiyun 		.of_match_table = of_match_ptr(tps549b22_of_match),
409*4882a593Smuzhiyun 	},
410*4882a593Smuzhiyun 	.probe = tps549b22_i2c_probe,
411*4882a593Smuzhiyun 	.remove = tps549b22_i2c_remove,
412*4882a593Smuzhiyun 	.id_table = tps549b22_i2c_id,
413*4882a593Smuzhiyun };
414*4882a593Smuzhiyun 
tps549b22_module_init(void)415*4882a593Smuzhiyun static int __init tps549b22_module_init(void)
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun 	int ret;
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	ret = i2c_add_driver(&tps549b22_i2c_driver);
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	if (ret != 0)
422*4882a593Smuzhiyun 		pr_err("Failed to register I2C driver: %d\n", ret);
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun 	return ret;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun subsys_initcall_sync(tps549b22_module_init);
427*4882a593Smuzhiyun 
tps549b22_module_exit(void)428*4882a593Smuzhiyun static void __exit tps549b22_module_exit(void)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun 	i2c_del_driver(&tps549b22_i2c_driver);
431*4882a593Smuzhiyun }
432*4882a593Smuzhiyun module_exit(tps549b22_module_exit);
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun MODULE_LICENSE("GPL");
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun MODULE_AUTHOR("derrick.huang@rock-chips.com");
437*4882a593Smuzhiyun MODULE_DESCRIPTION("   tps549b22 dcdc driver");
438