Merge branch 'master' of git://git.denx.de/u-boot-i2c
[platform/kernel/u-boot.git] / drivers / power / pmic / pmic_tps65217.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2011-2013
4  * Texas Instruments, <www.ti.com>
5  */
6
7 #include <common.h>
8 #include <i2c.h>
9 #include <power/tps65217.h>
10
11 struct udevice *tps65217_dev __attribute__((section(".data"))) = NULL;
12
13 /**
14  * tps65217_reg_read() - Generic function that can read a TPS65217 register
15  * @src_reg:             Source register address
16  * @src_val:             Address of destination variable
17  * @return:              0 for success, not 0 on failure.
18  */
19 int tps65217_reg_read(uchar src_reg, uchar *src_val)
20 {
21 #ifndef CONFIG_DM_I2C
22         return i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1);
23 #else
24         return dm_i2c_read(tps65217_dev, src_reg,  src_val, 1);
25 #endif
26 }
27
28 /**
29  *  tps65217_reg_write() - Generic function that can write a TPS65217 PMIC
30  *                         register or bit field regardless of protection
31  *                         level.
32  *
33  *  @prot_level:           Register password protection.  Use
34  *                         TPS65217_PROT_LEVEL_NONE,
35  *                         TPS65217_PROT_LEVEL_1 or TPS65217_PROT_LEVEL_2
36  *  @dest_reg:             Register address to write.
37  *  @dest_val:             Value to write.
38  *  @mask:                 Bit mask (8 bits) to be applied.  Function will only
39  *                         change bits that are set in the bit mask.
40  *
41  *  @return:               0 for success, not 0 on failure, as per the i2c API
42  */
43 int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
44                        uchar mask)
45 {
46         uchar read_val;
47         uchar xor_reg;
48         int ret;
49
50         /*
51          * If we are affecting only a bit field, read dest_reg and apply the
52          * mask
53          */
54         if (mask != TPS65217_MASK_ALL_BITS) {
55 #ifndef CONFIG_DM_I2C
56                 ret = i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1);
57 #else
58                 ret = dm_i2c_read(tps65217_dev, dest_reg, &read_val, 1);
59 #endif
60                 if (ret)
61                         return ret;
62
63                 read_val &= (~mask);
64                 read_val |= (dest_val & mask);
65                 dest_val = read_val;
66         }
67
68         if (prot_level > 0) {
69                 xor_reg = dest_reg ^ TPS65217_PASSWORD_UNLOCK;
70 #ifndef CONFIG_DM_I2C
71                 ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
72                                 &xor_reg, 1);
73 #else
74                 ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
75                                    &xor_reg, 1);
76 #endif
77                 if (ret)
78                         return ret;
79         }
80 #ifndef CONFIG_DM_I2C
81         ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
82 #else
83         ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
84 #endif
85         if (ret)
86                 return ret;
87
88         if (prot_level == TPS65217_PROT_LEVEL_2) {
89 #ifndef CONFIG_DM_I2C
90                 ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
91                                 &xor_reg, 1);
92 #else
93                 ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
94                                    &xor_reg, 1);
95 #endif
96                 if (ret)
97                         return ret;
98
99 #ifndef CONFIG_DM_I2C
100                 ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
101 #else
102                 ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
103 #endif
104                 if (ret)
105                         return ret;
106         }
107
108         return 0;
109 }
110
111 /**
112  * tps65217_voltage_update() - Function to change a voltage level, as this
113  *                             is a multi-step process.
114  * @dc_cntrl_reg:              DC voltage control register to change.
115  * @volt_sel:                  New value for the voltage register
116  * @return:                    0 for success, not 0 on failure.
117  */
118 int tps65217_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
119 {
120         if ((dc_cntrl_reg != TPS65217_DEFDCDC1) &&
121             (dc_cntrl_reg != TPS65217_DEFDCDC2) &&
122             (dc_cntrl_reg != TPS65217_DEFDCDC3))
123                 return 1;
124
125         /* set voltage level */
126         if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, dc_cntrl_reg, volt_sel,
127                                TPS65217_MASK_ALL_BITS))
128                 return 1;
129
130         /* set GO bit to initiate voltage transition */
131         if (tps65217_reg_write(TPS65217_PROT_LEVEL_2, TPS65217_DEFSLEW,
132                                TPS65217_DCDC_GO, TPS65217_DCDC_GO))
133                 return 1;
134
135         return 0;
136 }
137
138 int power_tps65217_init(unsigned char bus)
139 {
140 #ifdef CONFIG_DM_I2C
141         struct udevice *dev = NULL;
142         int rc;
143
144         rc = i2c_get_chip_for_busnum(bus, TPS65217_CHIP_PM, 1, &dev);
145         if (rc)
146                 return rc;
147         tps65217_dev = dev;
148 #endif
149         return 0;
150 }