blob: bfeb34b428ac3fa144235bbdd6fbc852d0d43434 [file] [log] [blame]
Steve Sakomanf8f7c952010-07-15 12:53:42 -07001/*
2 * (C) Copyright 2010
3 * Texas Instruments, <www.ti.com>
4 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Steve Sakomanf8f7c952010-07-15 12:53:42 -07006 */
7#include <config.h>
Steve Sakomanf8f7c952010-07-15 12:53:42 -07008
9#include <twl6030.h>
10
Oleg Kosheliev8cce7a92013-10-08 15:49:55 +030011static struct twl6030_data *twl;
12
13static struct twl6030_data twl6030_info = {
14 .chip_type = chip_TWL6030,
15 .adc_rbase = GPCH0_LSB,
16 .adc_ctrl = CTRL_P2,
17 .adc_enable = CTRL_P2_SP2,
18 .vbat_mult = TWL6030_VBAT_MULT,
19 .vbat_shift = TWL6030_VBAT_SHIFT,
20};
21
Oleg Kosheliev5c05da72013-10-08 15:49:56 +030022static struct twl6030_data twl6032_info = {
23 .chip_type = chip_TWL6032,
24 .adc_rbase = TWL6032_GPCH0_LSB,
25 .adc_ctrl = TWL6032_CTRL_P1,
26 .adc_enable = CTRL_P1_SP1,
27 .vbat_mult = TWL6032_VBAT_MULT,
28 .vbat_shift = TWL6032_VBAT_SHIFT,
29};
30
Balaji T K13c3c502010-11-25 16:22:04 +053031static int twl6030_gpadc_read_channel(u8 channel_no)
32{
33 u8 lsb = 0;
34 u8 msb = 0;
35 int ret = 0;
36
Nishanth Menon9deff3c2013-03-26 05:20:51 +000037 ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
Oleg Kosheliev8cce7a92013-10-08 15:49:55 +030038 twl->adc_rbase + channel_no * 2, &lsb);
Balaji T K13c3c502010-11-25 16:22:04 +053039 if (ret)
40 return ret;
41
Nishanth Menon9deff3c2013-03-26 05:20:51 +000042 ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
Oleg Kosheliev8cce7a92013-10-08 15:49:55 +030043 twl->adc_rbase + 1 + channel_no * 2, &msb);
Balaji T K13c3c502010-11-25 16:22:04 +053044 if (ret)
45 return ret;
46
47 return (msb << 8) | lsb;
48}
49
50static int twl6030_gpadc_sw2_trigger(void)
51{
52 u8 val;
53 int ret = 0;
54
Oleg Kosheliev8cce7a92013-10-08 15:49:55 +030055 ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
56 twl->adc_ctrl, twl->adc_enable);
Balaji T K13c3c502010-11-25 16:22:04 +053057 if (ret)
58 return ret;
59
60 /* Waiting until the SW1 conversion ends*/
61 val = CTRL_P2_BUSY;
62
63 while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) {
Oleg Kosheliev8cce7a92013-10-08 15:49:55 +030064 ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
65 twl->adc_ctrl, &val);
Balaji T K13c3c502010-11-25 16:22:04 +053066 if (ret)
67 return ret;
68 udelay(1000);
69 }
70
71 return 0;
72}
73
74void twl6030_stop_usb_charging(void)
75{
Nishanth Menon9deff3c2013-03-26 05:20:51 +000076 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1, 0);
Balaji T K13c3c502010-11-25 16:22:04 +053077
78 return;
79}
80
Steve Sakomanf8f7c952010-07-15 12:53:42 -070081void twl6030_start_usb_charging(void)
82{
Nishanth Menon9deff3c2013-03-26 05:20:51 +000083 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
84 CHARGERUSB_VICHRG, CHARGERUSB_VICHRG_1500);
85 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
86 CHARGERUSB_CINLIMIT, CHARGERUSB_CIN_LIMIT_NONE);
87 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
88 CONTROLLER_INT_MASK, MBAT_TEMP);
89 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
90 CHARGERUSB_INT_MASK, MASK_MCHARGERUSB_THMREG);
91 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
92 CHARGERUSB_VOREG, CHARGERUSB_VOREG_4P0);
93 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
94 CHARGERUSB_CTRL2, CHARGERUSB_CTRL2_VITERM_400);
95 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL1, TERM);
Steve Sakomanf8f7c952010-07-15 12:53:42 -070096 /* Enable USB charging */
Nishanth Menon9deff3c2013-03-26 05:20:51 +000097 twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
98 CONTROLLER_CTRL1, CONTROLLER_CTRL1_EN_CHARGER);
Steve Sakomanf8f7c952010-07-15 12:53:42 -070099 return;
100}
101
Balaji T K13c3c502010-11-25 16:22:04 +0530102int twl6030_get_battery_current(void)
103{
104 int battery_current = 0;
105 u8 msb = 0;
106 u8 lsb = 0;
107
Nishanth Menon9deff3c2013-03-26 05:20:51 +0000108 twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_11, &msb);
109 twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_10, &lsb);
Balaji T K13c3c502010-11-25 16:22:04 +0530110 battery_current = ((msb << 8) | lsb);
111
112 /* convert 10 bit signed number to 16 bit signed number */
113 if (battery_current >= 0x2000)
114 battery_current = (battery_current - 0x4000);
115
116 battery_current = battery_current * 3000 / 4096;
117 printf("Battery Current: %d mA\n", battery_current);
118
119 return battery_current;
120}
121
122int twl6030_get_battery_voltage(void)
123{
124 int battery_volt = 0;
125 int ret = 0;
Oleg Kosheliev5c05da72013-10-08 15:49:56 +0300126 u8 vbatch;
127
128 if (twl->chip_type == chip_TWL6030) {
129 vbatch = TWL6030_GPADC_VBAT_CHNL;
130 } else {
131 ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
132 TWL6032_GPSELECT_ISB,
133 TWL6032_GPADC_VBAT_CHNL);
134 if (ret)
135 return ret;
136 vbatch = 0;
137 }
Balaji T K13c3c502010-11-25 16:22:04 +0530138
139 /* Start GPADC SW conversion */
140 ret = twl6030_gpadc_sw2_trigger();
141 if (ret) {
142 printf("Failed to convert battery voltage\n");
143 return ret;
144 }
145
146 /* measure Vbat voltage */
Oleg Kosheliev5c05da72013-10-08 15:49:56 +0300147 battery_volt = twl6030_gpadc_read_channel(vbatch);
Balaji T K13c3c502010-11-25 16:22:04 +0530148 if (battery_volt < 0) {
149 printf("Failed to read battery voltage\n");
150 return ret;
151 }
Oleg Kosheliev8cce7a92013-10-08 15:49:55 +0300152 battery_volt = (battery_volt * twl->vbat_mult) >> twl->vbat_shift;
Balaji T K13c3c502010-11-25 16:22:04 +0530153 printf("Battery Voltage: %d mV\n", battery_volt);
154
155 return battery_volt;
156}
157
Steve Sakomanf8f7c952010-07-15 12:53:42 -0700158void twl6030_init_battery_charging(void)
159{
Oleg Kosheliev5c05da72013-10-08 15:49:56 +0300160 u8 val = 0;
Balaji T K13c3c502010-11-25 16:22:04 +0530161 int battery_volt = 0;
162 int ret = 0;
163
Oleg Kosheliev5c05da72013-10-08 15:49:56 +0300164 ret = twl6030_i2c_read_u8(TWL6030_CHIP_USB, USB_PRODUCT_ID_LSB, &val);
165 if (ret) {
166 puts("twl6030_init_battery_charging(): could not determine chip!\n");
167 return;
168 }
169 if (val == 0x30) {
170 twl = &twl6030_info;
171 } else if (val == 0x32) {
172 twl = &twl6032_info;
173 } else {
174 puts("twl6030_init_battery_charging(): unsupported chip type\n");
175 return;
176 }
Oleg Kosheliev8cce7a92013-10-08 15:49:55 +0300177
Balaji T K13c3c502010-11-25 16:22:04 +0530178 /* Enable VBAT measurement */
Oleg Kosheliev5c05da72013-10-08 15:49:56 +0300179 if (twl->chip_type == chip_TWL6030) {
180 twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC1, VBAT_MEAS);
181 twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
182 TWL6030_GPADC_CTRL,
183 GPADC_CTRL_SCALER_DIV4);
184 } else {
185 twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
186 TWL6032_GPADC_CTRL2,
187 GPADC_CTRL2_CH18_SCALER_EN);
188 }
Balaji T K13c3c502010-11-25 16:22:04 +0530189
190 /* Enable GPADC module */
Nishanth Menon9deff3c2013-03-26 05:20:51 +0000191 ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TOGGLE1, FGS | GPADCS);
Balaji T K13c3c502010-11-25 16:22:04 +0530192 if (ret) {
193 printf("Failed to enable GPADC\n");
194 return;
195 }
196
197 battery_volt = twl6030_get_battery_voltage();
198 if (battery_volt < 0)
199 return;
200
201 if (battery_volt < 3000)
202 printf("Main battery voltage too low!\n");
203
204 /* Check for the presence of USB charger */
Oleg Kosheliev5c05da72013-10-08 15:49:56 +0300205 twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, CONTROLLER_STAT1, &val);
Balaji T K13c3c502010-11-25 16:22:04 +0530206
207 /* check for battery presence indirectly via Fuel gauge */
Oleg Kosheliev5c05da72013-10-08 15:49:56 +0300208 if ((val & VBUS_DET) && (battery_volt < 3300))
Balaji T K13c3c502010-11-25 16:22:04 +0530209 twl6030_start_usb_charging();
210
Steve Sakomanf8f7c952010-07-15 12:53:42 -0700211 return;
212}
213
Paul Kocialkowskib6497482016-02-27 19:18:51 +0100214void twl6030_power_mmc_init(int dev_index)
Balaji T Kf843d332011-09-08 06:34:57 +0000215{
Paul Kocialkowski1db349f2016-02-27 19:18:50 +0100216 u8 value = 0;
217
Paul Kocialkowskib6497482016-02-27 19:18:51 +0100218 if (dev_index == 0) {
219 /* 3.0V voltage output for VMMC */
220 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VMMC_CFG_VOLTAGE,
221 TWL6030_CFG_VOLTAGE_30);
Paul Kocialkowskib8421a72016-02-27 19:18:49 +0100222
Paul Kocialkowskib6497482016-02-27 19:18:51 +0100223 /* Enable P1 output for VMMC */
224 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VMMC_CFG_STATE,
225 TWL6030_CFG_STATE_P1 | TWL6030_CFG_STATE_ON);
Paul Kocialkowski1db349f2016-02-27 19:18:50 +0100226
Paul Kocialkowskib6497482016-02-27 19:18:51 +0100227 twl6030_i2c_read_u8(TWL6030_CHIP_PM, TWL6030_PH_STS_BOOT, &value);
228 } else if (dev_index == 1) {
229 /* BOOT2 indicates 1.8V/2.8V VAUX1 for eMMC */
230 if (value & TWL6030_PH_STS_BOOT2) {
231 /* 1.8V voltage output for VAUX1 */
232 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VAUX1_CFG_VOLTAGE,
233 TWL6030_CFG_VOLTAGE_18);
234 } else {
235 /* 2.8V voltage output for VAUX1 */
236 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VAUX1_CFG_VOLTAGE,
237 TWL6030_CFG_VOLTAGE_28);
238 }
Paul Kocialkowski1db349f2016-02-27 19:18:50 +0100239
Paul Kocialkowskib6497482016-02-27 19:18:51 +0100240 /* Enable P1 output for VAUX */
241 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VAUX1_CFG_STATE,
242 TWL6030_CFG_STATE_P1 | TWL6030_CFG_STATE_ON);
Paul Kocialkowski1db349f2016-02-27 19:18:50 +0100243 }
Balaji T Kf843d332011-09-08 06:34:57 +0000244}
245
Steve Sakomanf8f7c952010-07-15 12:53:42 -0700246void twl6030_usb_device_settings()
247{
Paul Kocialkowskib8421a72016-02-27 19:18:49 +0100248 u8 value = 0;
Steve Sakomanf8f7c952010-07-15 12:53:42 -0700249
Paul Kocialkowski3f3b12b2016-02-27 19:19:03 +0100250 /* 3.3V voltage output for VUSB */
251 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VUSB_CFG_VOLTAGE,
252 TWL6030_CFG_VOLTAGE_33);
253
Paul Kocialkowskib8421a72016-02-27 19:18:49 +0100254 /* Enable P1 output for VUSB */
255 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_VUSB_CFG_STATE,
256 TWL6030_CFG_STATE_P1 | TWL6030_CFG_STATE_ON);
Steve Sakomanf8f7c952010-07-15 12:53:42 -0700257
Paul Kocialkowskib8421a72016-02-27 19:18:49 +0100258 /* Select the input supply for VUSB regulator */
259 twl6030_i2c_read_u8(TWL6030_CHIP_PM, TWL6030_MISC2, &value);
260 value |= TWL6030_MISC2_VUSB_IN_VSYS;
Paul Kocialkowskie1545d92016-02-27 19:19:04 +0100261 value &= ~TWL6030_MISC2_VUSB_IN_PMID;
Paul Kocialkowskib8421a72016-02-27 19:18:49 +0100262 twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_MISC2, value);
Steve Sakomanf8f7c952010-07-15 12:53:42 -0700263}