1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Regulator driver for National Semiconductors LP3972 PMIC chip
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Based on lp3971.c
6*4882a593Smuzhiyun */
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun #include <linux/bug.h>
9*4882a593Smuzhiyun #include <linux/err.h>
10*4882a593Smuzhiyun #include <linux/i2c.h>
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <linux/kernel.h>
13*4882a593Smuzhiyun #include <linux/regulator/driver.h>
14*4882a593Smuzhiyun #include <linux/regulator/lp3972.h>
15*4882a593Smuzhiyun #include <linux/slab.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun struct lp3972 {
18*4882a593Smuzhiyun struct device *dev;
19*4882a593Smuzhiyun struct mutex io_lock;
20*4882a593Smuzhiyun struct i2c_client *i2c;
21*4882a593Smuzhiyun };
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun /* LP3972 Control Registers */
24*4882a593Smuzhiyun #define LP3972_SCR_REG 0x07
25*4882a593Smuzhiyun #define LP3972_OVER1_REG 0x10
26*4882a593Smuzhiyun #define LP3972_OVSR1_REG 0x11
27*4882a593Smuzhiyun #define LP3972_OVER2_REG 0x12
28*4882a593Smuzhiyun #define LP3972_OVSR2_REG 0x13
29*4882a593Smuzhiyun #define LP3972_VCC1_REG 0x20
30*4882a593Smuzhiyun #define LP3972_ADTV1_REG 0x23
31*4882a593Smuzhiyun #define LP3972_ADTV2_REG 0x24
32*4882a593Smuzhiyun #define LP3972_AVRC_REG 0x25
33*4882a593Smuzhiyun #define LP3972_CDTC1_REG 0x26
34*4882a593Smuzhiyun #define LP3972_CDTC2_REG 0x27
35*4882a593Smuzhiyun #define LP3972_SDTV1_REG 0x29
36*4882a593Smuzhiyun #define LP3972_SDTV2_REG 0x2A
37*4882a593Smuzhiyun #define LP3972_MDTV1_REG 0x32
38*4882a593Smuzhiyun #define LP3972_MDTV2_REG 0x33
39*4882a593Smuzhiyun #define LP3972_L2VCR_REG 0x39
40*4882a593Smuzhiyun #define LP3972_L34VCR_REG 0x3A
41*4882a593Smuzhiyun #define LP3972_SCR1_REG 0x80
42*4882a593Smuzhiyun #define LP3972_SCR2_REG 0x81
43*4882a593Smuzhiyun #define LP3972_OEN3_REG 0x82
44*4882a593Smuzhiyun #define LP3972_OSR3_REG 0x83
45*4882a593Smuzhiyun #define LP3972_LOER4_REG 0x84
46*4882a593Smuzhiyun #define LP3972_B2TV_REG 0x85
47*4882a593Smuzhiyun #define LP3972_B3TV_REG 0x86
48*4882a593Smuzhiyun #define LP3972_B32RC_REG 0x87
49*4882a593Smuzhiyun #define LP3972_ISRA_REG 0x88
50*4882a593Smuzhiyun #define LP3972_BCCR_REG 0x89
51*4882a593Smuzhiyun #define LP3972_II1RR_REG 0x8E
52*4882a593Smuzhiyun #define LP3972_II2RR_REG 0x8F
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun #define LP3972_SYS_CONTROL1_REG LP3972_SCR1_REG
55*4882a593Smuzhiyun /* System control register 1 initial value,
56*4882a593Smuzhiyun * bits 5, 6 and 7 are EPROM programmable */
57*4882a593Smuzhiyun #define SYS_CONTROL1_INIT_VAL 0x02
58*4882a593Smuzhiyun #define SYS_CONTROL1_INIT_MASK 0x1F
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun #define LP3972_VOL_CHANGE_REG LP3972_VCC1_REG
61*4882a593Smuzhiyun #define LP3972_VOL_CHANGE_FLAG_GO 0x01
62*4882a593Smuzhiyun #define LP3972_VOL_CHANGE_FLAG_MASK 0x03
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /* LDO output enable mask */
65*4882a593Smuzhiyun #define LP3972_OEN3_L1EN BIT(0)
66*4882a593Smuzhiyun #define LP3972_OVER2_LDO2_EN BIT(2)
67*4882a593Smuzhiyun #define LP3972_OVER2_LDO3_EN BIT(3)
68*4882a593Smuzhiyun #define LP3972_OVER2_LDO4_EN BIT(4)
69*4882a593Smuzhiyun #define LP3972_OVER1_S_EN BIT(2)
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun static const unsigned int ldo1_voltage_map[] = {
72*4882a593Smuzhiyun 1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000,
73*4882a593Smuzhiyun 1900000, 1925000, 1950000, 1975000, 2000000,
74*4882a593Smuzhiyun };
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun static const unsigned int ldo23_voltage_map[] = {
77*4882a593Smuzhiyun 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000,
78*4882a593Smuzhiyun 2600000, 2700000, 2800000, 2900000, 3000000, 3100000, 3200000, 3300000,
79*4882a593Smuzhiyun };
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun static const unsigned int ldo4_voltage_map[] = {
82*4882a593Smuzhiyun 1000000, 1050000, 1100000, 1150000, 1200000, 1250000, 1300000, 1350000,
83*4882a593Smuzhiyun 1400000, 1500000, 1800000, 1900000, 2500000, 2800000, 3000000, 3300000,
84*4882a593Smuzhiyun };
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun static const unsigned int ldo5_voltage_map[] = {
87*4882a593Smuzhiyun 0, 0, 0, 0, 0, 850000, 875000, 900000,
88*4882a593Smuzhiyun 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000,
89*4882a593Smuzhiyun 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000,
90*4882a593Smuzhiyun 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000,
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun static const unsigned int buck1_voltage_map[] = {
94*4882a593Smuzhiyun 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000,
95*4882a593Smuzhiyun 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000,
96*4882a593Smuzhiyun 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000,
97*4882a593Smuzhiyun 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000,
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun static const unsigned int buck23_voltage_map[] = {
101*4882a593Smuzhiyun 0, 800000, 850000, 900000, 950000, 1000000, 1050000, 1100000,
102*4882a593Smuzhiyun 1150000, 1200000, 1250000, 1300000, 1350000, 1400000, 1450000, 1500000,
103*4882a593Smuzhiyun 1550000, 1600000, 1650000, 1700000, 1800000, 1900000, 2500000, 2800000,
104*4882a593Smuzhiyun 3000000, 3300000,
105*4882a593Smuzhiyun };
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun static const int ldo_output_enable_mask[] = {
108*4882a593Smuzhiyun LP3972_OEN3_L1EN,
109*4882a593Smuzhiyun LP3972_OVER2_LDO2_EN,
110*4882a593Smuzhiyun LP3972_OVER2_LDO3_EN,
111*4882a593Smuzhiyun LP3972_OVER2_LDO4_EN,
112*4882a593Smuzhiyun LP3972_OVER1_S_EN,
113*4882a593Smuzhiyun };
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun static const int ldo_output_enable_addr[] = {
116*4882a593Smuzhiyun LP3972_OEN3_REG,
117*4882a593Smuzhiyun LP3972_OVER2_REG,
118*4882a593Smuzhiyun LP3972_OVER2_REG,
119*4882a593Smuzhiyun LP3972_OVER2_REG,
120*4882a593Smuzhiyun LP3972_OVER1_REG,
121*4882a593Smuzhiyun };
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun static const int ldo_vol_ctl_addr[] = {
124*4882a593Smuzhiyun LP3972_MDTV1_REG,
125*4882a593Smuzhiyun LP3972_L2VCR_REG,
126*4882a593Smuzhiyun LP3972_L34VCR_REG,
127*4882a593Smuzhiyun LP3972_L34VCR_REG,
128*4882a593Smuzhiyun LP3972_SDTV1_REG,
129*4882a593Smuzhiyun };
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun static const int buck_vol_enable_addr[] = {
132*4882a593Smuzhiyun LP3972_OVER1_REG,
133*4882a593Smuzhiyun LP3972_OEN3_REG,
134*4882a593Smuzhiyun LP3972_OEN3_REG,
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun static const int buck_base_addr[] = {
138*4882a593Smuzhiyun LP3972_ADTV1_REG,
139*4882a593Smuzhiyun LP3972_B2TV_REG,
140*4882a593Smuzhiyun LP3972_B3TV_REG,
141*4882a593Smuzhiyun };
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun #define LP3972_LDO_OUTPUT_ENABLE_MASK(x) (ldo_output_enable_mask[x])
144*4882a593Smuzhiyun #define LP3972_LDO_OUTPUT_ENABLE_REG(x) (ldo_output_enable_addr[x])
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun /* LDO voltage control registers shift:
147*4882a593Smuzhiyun LP3972_LDO1 -> 0, LP3972_LDO2 -> 4
148*4882a593Smuzhiyun LP3972_LDO3 -> 0, LP3972_LDO4 -> 4
149*4882a593Smuzhiyun LP3972_LDO5 -> 0
150*4882a593Smuzhiyun */
151*4882a593Smuzhiyun #define LP3972_LDO_VOL_CONTR_SHIFT(x) (((x) & 1) << 2)
152*4882a593Smuzhiyun #define LP3972_LDO_VOL_CONTR_REG(x) (ldo_vol_ctl_addr[x])
153*4882a593Smuzhiyun #define LP3972_LDO_VOL_CHANGE_SHIFT(x) ((x) ? 4 : 6)
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun #define LP3972_LDO_VOL_MASK(x) (((x) % 4) ? 0x0f : 0x1f)
156*4882a593Smuzhiyun #define LP3972_LDO_VOL_MIN_IDX(x) (((x) == 4) ? 0x05 : 0x00)
157*4882a593Smuzhiyun #define LP3972_LDO_VOL_MAX_IDX(x) ((x) ? (((x) == 4) ? 0x1f : 0x0f) : 0x0c)
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun #define LP3972_BUCK_VOL_ENABLE_REG(x) (buck_vol_enable_addr[x])
160*4882a593Smuzhiyun #define LP3972_BUCK_VOL1_REG(x) (buck_base_addr[x])
161*4882a593Smuzhiyun #define LP3972_BUCK_VOL_MASK 0x1f
162*4882a593Smuzhiyun
lp3972_i2c_read(struct i2c_client * i2c,char reg,int count,u16 * dest)163*4882a593Smuzhiyun static int lp3972_i2c_read(struct i2c_client *i2c, char reg, int count,
164*4882a593Smuzhiyun u16 *dest)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun int ret;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun if (count != 1)
169*4882a593Smuzhiyun return -EIO;
170*4882a593Smuzhiyun ret = i2c_smbus_read_byte_data(i2c, reg);
171*4882a593Smuzhiyun if (ret < 0)
172*4882a593Smuzhiyun return ret;
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun *dest = ret;
175*4882a593Smuzhiyun return 0;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
lp3972_i2c_write(struct i2c_client * i2c,char reg,int count,const u16 * src)178*4882a593Smuzhiyun static int lp3972_i2c_write(struct i2c_client *i2c, char reg, int count,
179*4882a593Smuzhiyun const u16 *src)
180*4882a593Smuzhiyun {
181*4882a593Smuzhiyun if (count != 1)
182*4882a593Smuzhiyun return -EIO;
183*4882a593Smuzhiyun return i2c_smbus_write_byte_data(i2c, reg, *src);
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun
lp3972_reg_read(struct lp3972 * lp3972,u8 reg)186*4882a593Smuzhiyun static u8 lp3972_reg_read(struct lp3972 *lp3972, u8 reg)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun u16 val = 0;
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun mutex_lock(&lp3972->io_lock);
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun lp3972_i2c_read(lp3972->i2c, reg, 1, &val);
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun dev_dbg(lp3972->dev, "reg read 0x%02x -> 0x%02x\n", (int)reg,
195*4882a593Smuzhiyun (unsigned)val & 0xff);
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun mutex_unlock(&lp3972->io_lock);
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun return val & 0xff;
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun
lp3972_set_bits(struct lp3972 * lp3972,u8 reg,u16 mask,u16 val)202*4882a593Smuzhiyun static int lp3972_set_bits(struct lp3972 *lp3972, u8 reg, u16 mask, u16 val)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun u16 tmp;
205*4882a593Smuzhiyun int ret;
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun mutex_lock(&lp3972->io_lock);
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun ret = lp3972_i2c_read(lp3972->i2c, reg, 1, &tmp);
210*4882a593Smuzhiyun if (ret == 0) {
211*4882a593Smuzhiyun tmp = (tmp & ~mask) | val;
212*4882a593Smuzhiyun ret = lp3972_i2c_write(lp3972->i2c, reg, 1, &tmp);
213*4882a593Smuzhiyun dev_dbg(lp3972->dev, "reg write 0x%02x -> 0x%02x\n", (int)reg,
214*4882a593Smuzhiyun (unsigned)val & 0xff);
215*4882a593Smuzhiyun }
216*4882a593Smuzhiyun mutex_unlock(&lp3972->io_lock);
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun return ret;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun
lp3972_ldo_is_enabled(struct regulator_dev * dev)221*4882a593Smuzhiyun static int lp3972_ldo_is_enabled(struct regulator_dev *dev)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun struct lp3972 *lp3972 = rdev_get_drvdata(dev);
224*4882a593Smuzhiyun int ldo = rdev_get_id(dev) - LP3972_LDO1;
225*4882a593Smuzhiyun u16 mask = LP3972_LDO_OUTPUT_ENABLE_MASK(ldo);
226*4882a593Smuzhiyun u16 val;
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun val = lp3972_reg_read(lp3972, LP3972_LDO_OUTPUT_ENABLE_REG(ldo));
229*4882a593Smuzhiyun return !!(val & mask);
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun
lp3972_ldo_enable(struct regulator_dev * dev)232*4882a593Smuzhiyun static int lp3972_ldo_enable(struct regulator_dev *dev)
233*4882a593Smuzhiyun {
234*4882a593Smuzhiyun struct lp3972 *lp3972 = rdev_get_drvdata(dev);
235*4882a593Smuzhiyun int ldo = rdev_get_id(dev) - LP3972_LDO1;
236*4882a593Smuzhiyun u16 mask = LP3972_LDO_OUTPUT_ENABLE_MASK(ldo);
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun return lp3972_set_bits(lp3972, LP3972_LDO_OUTPUT_ENABLE_REG(ldo),
239*4882a593Smuzhiyun mask, mask);
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
lp3972_ldo_disable(struct regulator_dev * dev)242*4882a593Smuzhiyun static int lp3972_ldo_disable(struct regulator_dev *dev)
243*4882a593Smuzhiyun {
244*4882a593Smuzhiyun struct lp3972 *lp3972 = rdev_get_drvdata(dev);
245*4882a593Smuzhiyun int ldo = rdev_get_id(dev) - LP3972_LDO1;
246*4882a593Smuzhiyun u16 mask = LP3972_LDO_OUTPUT_ENABLE_MASK(ldo);
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun return lp3972_set_bits(lp3972, LP3972_LDO_OUTPUT_ENABLE_REG(ldo),
249*4882a593Smuzhiyun mask, 0);
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun
lp3972_ldo_get_voltage_sel(struct regulator_dev * dev)252*4882a593Smuzhiyun static int lp3972_ldo_get_voltage_sel(struct regulator_dev *dev)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun struct lp3972 *lp3972 = rdev_get_drvdata(dev);
255*4882a593Smuzhiyun int ldo = rdev_get_id(dev) - LP3972_LDO1;
256*4882a593Smuzhiyun u16 mask = LP3972_LDO_VOL_MASK(ldo);
257*4882a593Smuzhiyun u16 val, reg;
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun reg = lp3972_reg_read(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo));
260*4882a593Smuzhiyun val = (reg >> LP3972_LDO_VOL_CONTR_SHIFT(ldo)) & mask;
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun return val;
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun
lp3972_ldo_set_voltage_sel(struct regulator_dev * dev,unsigned int selector)265*4882a593Smuzhiyun static int lp3972_ldo_set_voltage_sel(struct regulator_dev *dev,
266*4882a593Smuzhiyun unsigned int selector)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun struct lp3972 *lp3972 = rdev_get_drvdata(dev);
269*4882a593Smuzhiyun int ldo = rdev_get_id(dev) - LP3972_LDO1;
270*4882a593Smuzhiyun int shift, ret;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun shift = LP3972_LDO_VOL_CONTR_SHIFT(ldo);
273*4882a593Smuzhiyun ret = lp3972_set_bits(lp3972, LP3972_LDO_VOL_CONTR_REG(ldo),
274*4882a593Smuzhiyun LP3972_LDO_VOL_MASK(ldo) << shift, selector << shift);
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun if (ret)
277*4882a593Smuzhiyun return ret;
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun /*
280*4882a593Smuzhiyun * LDO1 and LDO5 support voltage control by either target voltage1
281*4882a593Smuzhiyun * or target voltage2 register.
282*4882a593Smuzhiyun * We use target voltage1 register for LDO1 and LDO5 in this driver.
283*4882a593Smuzhiyun * We need to update voltage change control register(0x20) to enable
284*4882a593Smuzhiyun * LDO1 and LDO5 to change to their programmed target values.
285*4882a593Smuzhiyun */
286*4882a593Smuzhiyun switch (ldo) {
287*4882a593Smuzhiyun case LP3972_LDO1:
288*4882a593Smuzhiyun case LP3972_LDO5:
289*4882a593Smuzhiyun shift = LP3972_LDO_VOL_CHANGE_SHIFT(ldo);
290*4882a593Smuzhiyun ret = lp3972_set_bits(lp3972, LP3972_VOL_CHANGE_REG,
291*4882a593Smuzhiyun LP3972_VOL_CHANGE_FLAG_MASK << shift,
292*4882a593Smuzhiyun LP3972_VOL_CHANGE_FLAG_GO << shift);
293*4882a593Smuzhiyun if (ret)
294*4882a593Smuzhiyun return ret;
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun ret = lp3972_set_bits(lp3972, LP3972_VOL_CHANGE_REG,
297*4882a593Smuzhiyun LP3972_VOL_CHANGE_FLAG_MASK << shift, 0);
298*4882a593Smuzhiyun break;
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun return ret;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun static const struct regulator_ops lp3972_ldo_ops = {
305*4882a593Smuzhiyun .list_voltage = regulator_list_voltage_table,
306*4882a593Smuzhiyun .map_voltage = regulator_map_voltage_ascend,
307*4882a593Smuzhiyun .is_enabled = lp3972_ldo_is_enabled,
308*4882a593Smuzhiyun .enable = lp3972_ldo_enable,
309*4882a593Smuzhiyun .disable = lp3972_ldo_disable,
310*4882a593Smuzhiyun .get_voltage_sel = lp3972_ldo_get_voltage_sel,
311*4882a593Smuzhiyun .set_voltage_sel = lp3972_ldo_set_voltage_sel,
312*4882a593Smuzhiyun };
313*4882a593Smuzhiyun
lp3972_dcdc_is_enabled(struct regulator_dev * dev)314*4882a593Smuzhiyun static int lp3972_dcdc_is_enabled(struct regulator_dev *dev)
315*4882a593Smuzhiyun {
316*4882a593Smuzhiyun struct lp3972 *lp3972 = rdev_get_drvdata(dev);
317*4882a593Smuzhiyun int buck = rdev_get_id(dev) - LP3972_DCDC1;
318*4882a593Smuzhiyun u16 mask = 1 << (buck * 2);
319*4882a593Smuzhiyun u16 val;
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun val = lp3972_reg_read(lp3972, LP3972_BUCK_VOL_ENABLE_REG(buck));
322*4882a593Smuzhiyun return !!(val & mask);
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
lp3972_dcdc_enable(struct regulator_dev * dev)325*4882a593Smuzhiyun static int lp3972_dcdc_enable(struct regulator_dev *dev)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun struct lp3972 *lp3972 = rdev_get_drvdata(dev);
328*4882a593Smuzhiyun int buck = rdev_get_id(dev) - LP3972_DCDC1;
329*4882a593Smuzhiyun u16 mask = 1 << (buck * 2);
330*4882a593Smuzhiyun u16 val;
331*4882a593Smuzhiyun
332*4882a593Smuzhiyun val = lp3972_set_bits(lp3972, LP3972_BUCK_VOL_ENABLE_REG(buck),
333*4882a593Smuzhiyun mask, mask);
334*4882a593Smuzhiyun return val;
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun
lp3972_dcdc_disable(struct regulator_dev * dev)337*4882a593Smuzhiyun static int lp3972_dcdc_disable(struct regulator_dev *dev)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun struct lp3972 *lp3972 = rdev_get_drvdata(dev);
340*4882a593Smuzhiyun int buck = rdev_get_id(dev) - LP3972_DCDC1;
341*4882a593Smuzhiyun u16 mask = 1 << (buck * 2);
342*4882a593Smuzhiyun u16 val;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun val = lp3972_set_bits(lp3972, LP3972_BUCK_VOL_ENABLE_REG(buck),
345*4882a593Smuzhiyun mask, 0);
346*4882a593Smuzhiyun return val;
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun
lp3972_dcdc_get_voltage_sel(struct regulator_dev * dev)349*4882a593Smuzhiyun static int lp3972_dcdc_get_voltage_sel(struct regulator_dev *dev)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun struct lp3972 *lp3972 = rdev_get_drvdata(dev);
352*4882a593Smuzhiyun int buck = rdev_get_id(dev) - LP3972_DCDC1;
353*4882a593Smuzhiyun u16 reg;
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun reg = lp3972_reg_read(lp3972, LP3972_BUCK_VOL1_REG(buck));
356*4882a593Smuzhiyun reg &= LP3972_BUCK_VOL_MASK;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun return reg;
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun
lp3972_dcdc_set_voltage_sel(struct regulator_dev * dev,unsigned int selector)361*4882a593Smuzhiyun static int lp3972_dcdc_set_voltage_sel(struct regulator_dev *dev,
362*4882a593Smuzhiyun unsigned int selector)
363*4882a593Smuzhiyun {
364*4882a593Smuzhiyun struct lp3972 *lp3972 = rdev_get_drvdata(dev);
365*4882a593Smuzhiyun int buck = rdev_get_id(dev) - LP3972_DCDC1;
366*4882a593Smuzhiyun int ret;
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun ret = lp3972_set_bits(lp3972, LP3972_BUCK_VOL1_REG(buck),
369*4882a593Smuzhiyun LP3972_BUCK_VOL_MASK, selector);
370*4882a593Smuzhiyun if (ret)
371*4882a593Smuzhiyun return ret;
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun if (buck != 0)
374*4882a593Smuzhiyun return ret;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun ret = lp3972_set_bits(lp3972, LP3972_VOL_CHANGE_REG,
377*4882a593Smuzhiyun LP3972_VOL_CHANGE_FLAG_MASK, LP3972_VOL_CHANGE_FLAG_GO);
378*4882a593Smuzhiyun if (ret)
379*4882a593Smuzhiyun return ret;
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun return lp3972_set_bits(lp3972, LP3972_VOL_CHANGE_REG,
382*4882a593Smuzhiyun LP3972_VOL_CHANGE_FLAG_MASK, 0);
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun static const struct regulator_ops lp3972_dcdc_ops = {
386*4882a593Smuzhiyun .list_voltage = regulator_list_voltage_table,
387*4882a593Smuzhiyun .map_voltage = regulator_map_voltage_ascend,
388*4882a593Smuzhiyun .is_enabled = lp3972_dcdc_is_enabled,
389*4882a593Smuzhiyun .enable = lp3972_dcdc_enable,
390*4882a593Smuzhiyun .disable = lp3972_dcdc_disable,
391*4882a593Smuzhiyun .get_voltage_sel = lp3972_dcdc_get_voltage_sel,
392*4882a593Smuzhiyun .set_voltage_sel = lp3972_dcdc_set_voltage_sel,
393*4882a593Smuzhiyun };
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun static const struct regulator_desc regulators[] = {
396*4882a593Smuzhiyun {
397*4882a593Smuzhiyun .name = "LDO1",
398*4882a593Smuzhiyun .id = LP3972_LDO1,
399*4882a593Smuzhiyun .ops = &lp3972_ldo_ops,
400*4882a593Smuzhiyun .n_voltages = ARRAY_SIZE(ldo1_voltage_map),
401*4882a593Smuzhiyun .volt_table = ldo1_voltage_map,
402*4882a593Smuzhiyun .type = REGULATOR_VOLTAGE,
403*4882a593Smuzhiyun .owner = THIS_MODULE,
404*4882a593Smuzhiyun },
405*4882a593Smuzhiyun {
406*4882a593Smuzhiyun .name = "LDO2",
407*4882a593Smuzhiyun .id = LP3972_LDO2,
408*4882a593Smuzhiyun .ops = &lp3972_ldo_ops,
409*4882a593Smuzhiyun .n_voltages = ARRAY_SIZE(ldo23_voltage_map),
410*4882a593Smuzhiyun .volt_table = ldo23_voltage_map,
411*4882a593Smuzhiyun .type = REGULATOR_VOLTAGE,
412*4882a593Smuzhiyun .owner = THIS_MODULE,
413*4882a593Smuzhiyun },
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun .name = "LDO3",
416*4882a593Smuzhiyun .id = LP3972_LDO3,
417*4882a593Smuzhiyun .ops = &lp3972_ldo_ops,
418*4882a593Smuzhiyun .n_voltages = ARRAY_SIZE(ldo23_voltage_map),
419*4882a593Smuzhiyun .volt_table = ldo23_voltage_map,
420*4882a593Smuzhiyun .type = REGULATOR_VOLTAGE,
421*4882a593Smuzhiyun .owner = THIS_MODULE,
422*4882a593Smuzhiyun },
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun .name = "LDO4",
425*4882a593Smuzhiyun .id = LP3972_LDO4,
426*4882a593Smuzhiyun .ops = &lp3972_ldo_ops,
427*4882a593Smuzhiyun .n_voltages = ARRAY_SIZE(ldo4_voltage_map),
428*4882a593Smuzhiyun .volt_table = ldo4_voltage_map,
429*4882a593Smuzhiyun .type = REGULATOR_VOLTAGE,
430*4882a593Smuzhiyun .owner = THIS_MODULE,
431*4882a593Smuzhiyun },
432*4882a593Smuzhiyun {
433*4882a593Smuzhiyun .name = "LDO5",
434*4882a593Smuzhiyun .id = LP3972_LDO5,
435*4882a593Smuzhiyun .ops = &lp3972_ldo_ops,
436*4882a593Smuzhiyun .n_voltages = ARRAY_SIZE(ldo5_voltage_map),
437*4882a593Smuzhiyun .volt_table = ldo5_voltage_map,
438*4882a593Smuzhiyun .type = REGULATOR_VOLTAGE,
439*4882a593Smuzhiyun .owner = THIS_MODULE,
440*4882a593Smuzhiyun },
441*4882a593Smuzhiyun {
442*4882a593Smuzhiyun .name = "DCDC1",
443*4882a593Smuzhiyun .id = LP3972_DCDC1,
444*4882a593Smuzhiyun .ops = &lp3972_dcdc_ops,
445*4882a593Smuzhiyun .n_voltages = ARRAY_SIZE(buck1_voltage_map),
446*4882a593Smuzhiyun .volt_table = buck1_voltage_map,
447*4882a593Smuzhiyun .type = REGULATOR_VOLTAGE,
448*4882a593Smuzhiyun .owner = THIS_MODULE,
449*4882a593Smuzhiyun },
450*4882a593Smuzhiyun {
451*4882a593Smuzhiyun .name = "DCDC2",
452*4882a593Smuzhiyun .id = LP3972_DCDC2,
453*4882a593Smuzhiyun .ops = &lp3972_dcdc_ops,
454*4882a593Smuzhiyun .n_voltages = ARRAY_SIZE(buck23_voltage_map),
455*4882a593Smuzhiyun .volt_table = buck23_voltage_map,
456*4882a593Smuzhiyun .type = REGULATOR_VOLTAGE,
457*4882a593Smuzhiyun .owner = THIS_MODULE,
458*4882a593Smuzhiyun },
459*4882a593Smuzhiyun {
460*4882a593Smuzhiyun .name = "DCDC3",
461*4882a593Smuzhiyun .id = LP3972_DCDC3,
462*4882a593Smuzhiyun .ops = &lp3972_dcdc_ops,
463*4882a593Smuzhiyun .n_voltages = ARRAY_SIZE(buck23_voltage_map),
464*4882a593Smuzhiyun .volt_table = buck23_voltage_map,
465*4882a593Smuzhiyun .type = REGULATOR_VOLTAGE,
466*4882a593Smuzhiyun .owner = THIS_MODULE,
467*4882a593Smuzhiyun },
468*4882a593Smuzhiyun };
469*4882a593Smuzhiyun
setup_regulators(struct lp3972 * lp3972,struct lp3972_platform_data * pdata)470*4882a593Smuzhiyun static int setup_regulators(struct lp3972 *lp3972,
471*4882a593Smuzhiyun struct lp3972_platform_data *pdata)
472*4882a593Smuzhiyun {
473*4882a593Smuzhiyun int i, err;
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun /* Instantiate the regulators */
476*4882a593Smuzhiyun for (i = 0; i < pdata->num_regulators; i++) {
477*4882a593Smuzhiyun struct lp3972_regulator_subdev *reg = &pdata->regulators[i];
478*4882a593Smuzhiyun struct regulator_config config = { };
479*4882a593Smuzhiyun struct regulator_dev *rdev;
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun config.dev = lp3972->dev;
482*4882a593Smuzhiyun config.init_data = reg->initdata;
483*4882a593Smuzhiyun config.driver_data = lp3972;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun rdev = devm_regulator_register(lp3972->dev,
486*4882a593Smuzhiyun ®ulators[reg->id], &config);
487*4882a593Smuzhiyun if (IS_ERR(rdev)) {
488*4882a593Smuzhiyun err = PTR_ERR(rdev);
489*4882a593Smuzhiyun dev_err(lp3972->dev, "regulator init failed: %d\n",
490*4882a593Smuzhiyun err);
491*4882a593Smuzhiyun return err;
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun return 0;
496*4882a593Smuzhiyun }
497*4882a593Smuzhiyun
lp3972_i2c_probe(struct i2c_client * i2c,const struct i2c_device_id * id)498*4882a593Smuzhiyun static int lp3972_i2c_probe(struct i2c_client *i2c,
499*4882a593Smuzhiyun const struct i2c_device_id *id)
500*4882a593Smuzhiyun {
501*4882a593Smuzhiyun struct lp3972 *lp3972;
502*4882a593Smuzhiyun struct lp3972_platform_data *pdata = dev_get_platdata(&i2c->dev);
503*4882a593Smuzhiyun int ret;
504*4882a593Smuzhiyun u16 val;
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun if (!pdata) {
507*4882a593Smuzhiyun dev_dbg(&i2c->dev, "No platform init data supplied\n");
508*4882a593Smuzhiyun return -ENODEV;
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun lp3972 = devm_kzalloc(&i2c->dev, sizeof(struct lp3972), GFP_KERNEL);
512*4882a593Smuzhiyun if (!lp3972)
513*4882a593Smuzhiyun return -ENOMEM;
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun lp3972->i2c = i2c;
516*4882a593Smuzhiyun lp3972->dev = &i2c->dev;
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun mutex_init(&lp3972->io_lock);
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun /* Detect LP3972 */
521*4882a593Smuzhiyun ret = lp3972_i2c_read(i2c, LP3972_SYS_CONTROL1_REG, 1, &val);
522*4882a593Smuzhiyun if (ret == 0 &&
523*4882a593Smuzhiyun (val & SYS_CONTROL1_INIT_MASK) != SYS_CONTROL1_INIT_VAL) {
524*4882a593Smuzhiyun ret = -ENODEV;
525*4882a593Smuzhiyun dev_err(&i2c->dev, "chip reported: val = 0x%x\n", val);
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun if (ret < 0) {
528*4882a593Smuzhiyun dev_err(&i2c->dev, "failed to detect device. ret = %d\n", ret);
529*4882a593Smuzhiyun return ret;
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun ret = setup_regulators(lp3972, pdata);
533*4882a593Smuzhiyun if (ret < 0)
534*4882a593Smuzhiyun return ret;
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun i2c_set_clientdata(i2c, lp3972);
537*4882a593Smuzhiyun return 0;
538*4882a593Smuzhiyun }
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun static const struct i2c_device_id lp3972_i2c_id[] = {
541*4882a593Smuzhiyun { "lp3972", 0 },
542*4882a593Smuzhiyun { }
543*4882a593Smuzhiyun };
544*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, lp3972_i2c_id);
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun static struct i2c_driver lp3972_i2c_driver = {
547*4882a593Smuzhiyun .driver = {
548*4882a593Smuzhiyun .name = "lp3972",
549*4882a593Smuzhiyun },
550*4882a593Smuzhiyun .probe = lp3972_i2c_probe,
551*4882a593Smuzhiyun .id_table = lp3972_i2c_id,
552*4882a593Smuzhiyun };
553*4882a593Smuzhiyun
lp3972_module_init(void)554*4882a593Smuzhiyun static int __init lp3972_module_init(void)
555*4882a593Smuzhiyun {
556*4882a593Smuzhiyun return i2c_add_driver(&lp3972_i2c_driver);
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun subsys_initcall(lp3972_module_init);
559*4882a593Smuzhiyun
lp3972_module_exit(void)560*4882a593Smuzhiyun static void __exit lp3972_module_exit(void)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun i2c_del_driver(&lp3972_i2c_driver);
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun module_exit(lp3972_module_exit);
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun MODULE_LICENSE("GPL");
567*4882a593Smuzhiyun MODULE_AUTHOR("Axel Lin <axel.lin@gmail.com>");
568*4882a593Smuzhiyun MODULE_DESCRIPTION("LP3972 PMIC driver");
569