coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
tps65090.c
Go to the documentation of this file.
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 {
13 };
14 
15 enum {
17 
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 
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 
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  */
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 
69  if (set)
71 
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, &reg))
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 
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 */
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 
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 
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, &reg);
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 
148 int tps65090_is_charging(unsigned int bus)
149 {
150  unsigned char val;
151  int ret;
152 
154  if (ret)
155  return ret;
156  return val & CG_CTRL0_ENC_MASK ? 1 : 0;
157 }
158 
159 int tps65090_set_charge_enable(unsigned int bus, int enable)
160 {
161  unsigned char val;
162  int ret;
163 
165  if (!ret) {
166  if (enable)
168  else
171  }
172  if (ret) {
173  printk(BIOS_DEBUG, "%s: Failed to enable\n", __func__);
174  return ret;
175  }
176  return 0;
177 }
178 
179 int tps65090_get_status(unsigned int bus)
180 {
181  unsigned char val;
182  int ret;
183 
185  if (ret)
186  return ret;
187  return val;
188 }
pte_t value
Definition: mmu.c:91
#define retry(attempts, condition,...)
Definition: helpers.h:126
#define printk(level,...)
Definition: stdlib.h:16
static int i2c_writeb(unsigned int bus, uint8_t slave, uint8_t reg, uint8_t data)
Write a byte with one segment in one frame.
Definition: i2c_simple.h:131
static int i2c_readb(unsigned int bus, uint8_t slave, uint8_t reg, uint8_t *data)
Read a byte with two segments in one frame.
Definition: i2c_simple.h:109
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
unsigned char uint8_t
Definition: stdint.h:8
Definition: device.h:76
u8 val
Definition: sys.c:300
int tps65090_set_charge_enable(unsigned int bus, int enable)
Enable / disable the battery charger.
Definition: tps65090.c:159
static int tps65090_i2c_write(unsigned int bus, unsigned int reg_addr, unsigned char value)
Definition: tps65090.c:29
@ REG_CG_STATUS1
Definition: tps65090.c:12
@ REG_CG_CTRL0
Definition: tps65090.c:11
int tps65090_fet_disable(unsigned int bus, enum fet_id fet_id)
Disable FET.
Definition: tps65090.c:129
int tps65090_fet_enable(unsigned int bus, enum fet_id fet_id)
Enable FET.
Definition: tps65090.c:95
int tps65090_is_charging(unsigned int bus)
Check whether we have enabled battery charging.
Definition: tps65090.c:148
static int tps65090_fet_set(unsigned int bus, enum fet_id fet_id, int set)
Set the power state for a FET.
Definition: tps65090.c:63
@ MAX_CTRL_READ_TRIES
Definition: tps65090.c:19
@ CG_CTRL0_ENC_MASK
Definition: tps65090.c:16
@ FET_CTRL_TOFET
Definition: tps65090.c:22
@ FET_CTRL_PGFET
Definition: tps65090.c:23
@ FET_CTRL_ADENFET
Definition: tps65090.c:25
@ FET_CTRL_ENFET
Definition: tps65090.c:26
@ FET_CTRL_WAIT
Definition: tps65090.c:24
@ MAX_FET_NUM
Definition: tps65090.c:18
int tps65090_get_status(unsigned int bus)
Return the value of the status register.
Definition: tps65090.c:179
static int tps65090_i2c_read(unsigned int bus, unsigned int reg_addr, unsigned char *value)
Definition: tps65090.c:40
int tps65090_fet_is_enabled(unsigned int bus, enum fet_id fet_id)
Is FET enabled?
Definition: tps65090.c:134
fet_id
Definition: tps65090.h:10
#define TPS65090_I2C_ADDR
Definition: tps65090.h:7
@ FET_ERR_NOT_READY
Definition: tps65090.h:31
@ FET_ERR_COMMS
Definition: tps65090.h:30
void udelay(uint32_t us)
Definition: udelay.c:15