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 */
tps65217_reg_read(uchar src_reg,uchar * src_val)19 int tps65217_reg_read(uchar src_reg, uchar *src_val)
20 {
21 #if !CONFIG_IS_ENABLED(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 */
tps65217_reg_write(uchar prot_level,uchar dest_reg,uchar dest_val,uchar mask)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 #if !CONFIG_IS_ENABLED(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 #if !CONFIG_IS_ENABLED(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 #if !CONFIG_IS_ENABLED(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 #if !CONFIG_IS_ENABLED(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 #if !CONFIG_IS_ENABLED(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 */
tps65217_voltage_update(uchar dc_cntrl_reg,uchar volt_sel)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
power_tps65217_init(unsigned char bus)138 int power_tps65217_init(unsigned char bus)
139 {
140 #if CONFIG_IS_ENABLED(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 }
151