1 /* SPDX-License-Identifier: BSD-3-Clause or GPL-2.0-only */
2
3 #include <delay.h>
4 #include <types.h>
5 #include <console/console.h>
6 #include <device/i2c_simple.h>
7 #include "tps65090.h"
8
9 /* TPS65090 register addresses */
10 enum {
11 REG_CG_CTRL0 = 4,
12 REG_CG_STATUS1 = 0xa,
13 };
14
15 enum {
16 CG_CTRL0_ENC_MASK = 0x01,
17
18 MAX_FET_NUM = 7,
19 MAX_CTRL_READ_TRIES = 5,
20
21 /* TPS65090 FET_CTRL register values */
22 FET_CTRL_TOFET = 1 << 7, /* Timeout, startup, overload */
23 FET_CTRL_PGFET = 1 << 4, /* Power good for FET status */
24 FET_CTRL_WAIT = 3 << 2, /* Overcurrent timeout max */
25 FET_CTRL_ADENFET = 1 << 1, /* Enable output auto discharge */
26 FET_CTRL_ENFET = 1 << 0, /* Enable FET */
27 };
28
tps65090_i2c_write(unsigned int bus,unsigned int reg_addr,unsigned char value)29 static int tps65090_i2c_write(unsigned int bus,
30 unsigned int reg_addr, unsigned char value)
31 {
32 int ret;
33
34 ret = i2c_writeb(bus, TPS65090_I2C_ADDR, reg_addr, value);
35 printk(BIOS_DEBUG, "%s: reg=%#x, value=%#x, ret=%d\n",
36 __func__, reg_addr, value, ret);
37 return ret;
38 }
39
tps65090_i2c_read(unsigned int bus,unsigned int reg_addr,unsigned char * value)40 static int tps65090_i2c_read(unsigned int bus,
41 unsigned int reg_addr, unsigned char *value)
42 {
43 int ret;
44
45 printk(BIOS_DEBUG, "%s: reg=%#x, ", __func__, reg_addr);
46 ret = i2c_readb(bus, TPS65090_I2C_ADDR, reg_addr, value);
47 if (ret)
48 printk(BIOS_DEBUG, "fail, ret=%d\n", ret);
49 else
50 printk(BIOS_DEBUG, "value=%#x, ret=%d\n", *value, ret);
51 return ret;
52 }
53
54 /**
55 * Set the power state for a FET
56 *
57 * @param bus
58 * @param fet_id Fet number to set (1..MAX_FET_NUM)
59 * @param set 1 to power on FET, 0 to power off
60 * @return FET_ERR_COMMS if we got a comms error, FET_ERR_NOT_READY if the
61 * FET failed to change state. If all is ok, returns 0.
62 */
tps65090_fet_set(unsigned int bus,enum fet_id fet_id,int set)63 static int tps65090_fet_set(unsigned int bus, enum fet_id fet_id, int set)
64 {
65 int retry, value;
66 uint8_t reg;
67
68 value = FET_CTRL_ADENFET | FET_CTRL_WAIT;
69 if (set)
70 value |= FET_CTRL_ENFET;
71
72 if (tps65090_i2c_write(bus, fet_id, value))
73 return FET_ERR_COMMS;
74 /* Try reading until we get a result */
75 for (retry = 0; retry < MAX_CTRL_READ_TRIES; retry++) {
76 if (tps65090_i2c_read(bus, fet_id, ®))
77 return FET_ERR_COMMS;
78
79 /* Check that the fet went into the expected state */
80 if (!!(reg & FET_CTRL_PGFET) == set)
81 return 0;
82
83 /* If we got a timeout, there is no point in waiting longer */
84 if (reg & FET_CTRL_TOFET)
85 break;
86
87 udelay(1000);
88 }
89
90 printk(BIOS_DEBUG, "FET %d: Power good should have set to %d but "
91 "reg=%#02x\n", fet_id, set, reg);
92 return FET_ERR_NOT_READY;
93 }
94
tps65090_fet_enable(unsigned int bus,enum fet_id fet_id)95 int tps65090_fet_enable(unsigned int bus, enum fet_id fet_id)
96 {
97 int loops;
98 int ret = 0;
99
100 for (loops = 0; loops < 100; loops++) {
101 ret = tps65090_fet_set(bus, fet_id, 1);
102 if (!ret)
103 break;
104
105 /* Turn it off and try again until we time out */
106 tps65090_fet_set(bus, fet_id, 0);
107 udelay(1000);
108 }
109
110 if (ret) {
111 printk(BIOS_DEBUG, "%s: FET%d failed to power on\n",
112 __func__, fet_id);
113 } else if (loops) {
114 printk(BIOS_DEBUG, "%s: FET%d powered on\n",
115 __func__, fet_id);
116 }
117 /*
118 * Unfortunately, there are some conditions where the power
119 * good bit will be 0, but the fet still comes up. One such
120 * case occurs with the lcd backlight. We'll just return 0 here
121 * and assume that the fet will eventually come up.
122 */
123 if (ret == FET_ERR_NOT_READY)
124 ret = 0;
125
126 return ret;
127 }
128
tps65090_fet_disable(unsigned int bus,enum fet_id fet_id)129 int tps65090_fet_disable(unsigned int bus, enum fet_id fet_id)
130 {
131 return tps65090_fet_set(bus, fet_id, 0);
132 }
133
tps65090_fet_is_enabled(unsigned int bus,enum fet_id fet_id)134 int tps65090_fet_is_enabled(unsigned int bus, enum fet_id fet_id)
135 {
136 unsigned char reg;
137 int ret;
138
139 ret = tps65090_i2c_read(bus, fet_id, ®);
140 if (ret) {
141 printk(BIOS_DEBUG, "fail to read FET%u_CTRL", fet_id);
142 return -2;
143 }
144
145 return reg & FET_CTRL_ENFET;
146 }
147
tps65090_is_charging(unsigned int bus)148 int tps65090_is_charging(unsigned int bus)
149 {
150 unsigned char val;
151 int ret;
152
153 ret = tps65090_i2c_read(bus, REG_CG_CTRL0, &val);
154 if (ret)
155 return ret;
156 return val & CG_CTRL0_ENC_MASK ? 1 : 0;
157 }
158
tps65090_set_charge_enable(unsigned int bus,int enable)159 int tps65090_set_charge_enable(unsigned int bus, int enable)
160 {
161 unsigned char val;
162 int ret;
163
164 ret = tps65090_i2c_read(bus, REG_CG_CTRL0, &val);
165 if (!ret) {
166 if (enable)
167 val |= CG_CTRL0_ENC_MASK;
168 else
169 val &= ~CG_CTRL0_ENC_MASK;
170 ret = tps65090_i2c_write(bus, REG_CG_CTRL0, val);
171 }
172 if (ret) {
173 printk(BIOS_DEBUG, "%s: Failed to enable\n", __func__);
174 return ret;
175 }
176 return 0;
177 }
178
tps65090_get_status(unsigned int bus)179 int tps65090_get_status(unsigned int bus)
180 {
181 unsigned char val;
182 int ret;
183
184 ret = tps65090_i2c_read(bus, REG_CG_STATUS1, &val);
185 if (ret)
186 return ret;
187 return val;
188 }
189