]> git.sur5r.net Git - u-boot/blob - drivers/power/twl6030.c
6bf1a33286400e85f25dafd4161e6ca69c2be572
[u-boot] / drivers / power / twl6030.c
1 /*
2  * (C) Copyright 2010
3  * Texas Instruments, <www.ti.com>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7 #include <config.h>
8 #ifdef CONFIG_TWL6030_POWER
9
10 #include <twl6030.h>
11
12 static struct twl6030_data *twl;
13
14 static struct twl6030_data twl6030_info = {
15         .chip_type      = chip_TWL6030,
16         .adc_rbase      = GPCH0_LSB,
17         .adc_ctrl       = CTRL_P2,
18         .adc_enable     = CTRL_P2_SP2,
19         .vbat_mult      = TWL6030_VBAT_MULT,
20         .vbat_shift     = TWL6030_VBAT_SHIFT,
21 };
22
23 static int twl6030_gpadc_read_channel(u8 channel_no)
24 {
25         u8 lsb = 0;
26         u8 msb = 0;
27         int ret = 0;
28
29         ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
30                                   twl->adc_rbase + channel_no * 2, &lsb);
31         if (ret)
32                 return ret;
33
34         ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
35                                   twl->adc_rbase + 1 + channel_no * 2, &msb);
36         if (ret)
37                 return ret;
38
39         return (msb << 8) | lsb;
40 }
41
42 static int twl6030_gpadc_sw2_trigger(void)
43 {
44         u8 val;
45         int ret = 0;
46
47         ret = twl6030_i2c_write_u8(TWL6030_CHIP_ADC,
48                                    twl->adc_ctrl, twl->adc_enable);
49         if (ret)
50                 return ret;
51
52         /* Waiting until the SW1 conversion ends*/
53         val =  CTRL_P2_BUSY;
54
55         while (!((val & CTRL_P2_EOCP2) && (!(val & CTRL_P2_BUSY)))) {
56                 ret = twl6030_i2c_read_u8(TWL6030_CHIP_ADC,
57                                           twl->adc_ctrl, &val);
58                 if (ret)
59                         return ret;
60                 udelay(1000);
61         }
62
63         return 0;
64 }
65
66 void twl6030_stop_usb_charging(void)
67 {
68         twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CONTROLLER_CTRL1, 0);
69
70         return;
71 }
72
73 void twl6030_start_usb_charging(void)
74 {
75         twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
76                              CHARGERUSB_VICHRG, CHARGERUSB_VICHRG_1500);
77         twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
78                              CHARGERUSB_CINLIMIT, CHARGERUSB_CIN_LIMIT_NONE);
79         twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
80                              CONTROLLER_INT_MASK, MBAT_TEMP);
81         twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
82                              CHARGERUSB_INT_MASK, MASK_MCHARGERUSB_THMREG);
83         twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
84                              CHARGERUSB_VOREG, CHARGERUSB_VOREG_4P0);
85         twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
86                              CHARGERUSB_CTRL2, CHARGERUSB_CTRL2_VITERM_400);
87         twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, CHARGERUSB_CTRL1, TERM);
88         /* Enable USB charging */
89         twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER,
90                              CONTROLLER_CTRL1, CONTROLLER_CTRL1_EN_CHARGER);
91         return;
92 }
93
94 int twl6030_get_battery_current(void)
95 {
96         int battery_current = 0;
97         u8 msb = 0;
98         u8 lsb = 0;
99
100         twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_11, &msb);
101         twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, FG_REG_10, &lsb);
102         battery_current = ((msb << 8) | lsb);
103
104         /* convert 10 bit signed number to 16 bit signed number */
105         if (battery_current >= 0x2000)
106                 battery_current = (battery_current - 0x4000);
107
108         battery_current = battery_current * 3000 / 4096;
109         printf("Battery Current: %d mA\n", battery_current);
110
111         return battery_current;
112 }
113
114 int twl6030_get_battery_voltage(void)
115 {
116         int battery_volt = 0;
117         int ret = 0;
118
119         /* Start GPADC SW conversion */
120         ret = twl6030_gpadc_sw2_trigger();
121         if (ret) {
122                 printf("Failed to convert battery voltage\n");
123                 return ret;
124         }
125
126         /* measure Vbat voltage */
127         battery_volt = twl6030_gpadc_read_channel(7);
128         if (battery_volt < 0) {
129                 printf("Failed to read battery voltage\n");
130                 return ret;
131         }
132         battery_volt = (battery_volt * twl->vbat_mult) >> twl->vbat_shift;
133         printf("Battery Voltage: %d mV\n", battery_volt);
134
135         return battery_volt;
136 }
137
138 void twl6030_init_battery_charging(void)
139 {
140         u8 stat1 = 0;
141         int battery_volt = 0;
142         int ret = 0;
143
144         twl = &twl6030_info;
145
146         /* Enable VBAT measurement */
147         twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC1, VBAT_MEAS);
148
149         /* Enable GPADC module */
150         ret = twl6030_i2c_write_u8(TWL6030_CHIP_CHARGER, TOGGLE1, FGS | GPADCS);
151         if (ret) {
152                 printf("Failed to enable GPADC\n");
153                 return;
154         }
155
156         battery_volt = twl6030_get_battery_voltage();
157         if (battery_volt < 0)
158                 return;
159
160         if (battery_volt < 3000)
161                 printf("Main battery voltage too low!\n");
162
163         /* Check for the presence of USB charger */
164         twl6030_i2c_read_u8(TWL6030_CHIP_CHARGER, CONTROLLER_STAT1, &stat1);
165
166         /* check for battery presence indirectly via Fuel gauge */
167         if ((stat1 & VBUS_DET) && (battery_volt < 3300))
168                 twl6030_start_usb_charging();
169
170         return;
171 }
172
173 void twl6030_power_mmc_init()
174 {
175         /* set voltage to 3.0 and turnon for APP */
176         twl6030_i2c_write_u8(TWL6030_CHIP_PM, VMMC_CFG_VOLTATE, 0x15);
177         twl6030_i2c_write_u8(TWL6030_CHIP_PM, VMMC_CFG_STATE, 0x21);
178 }
179
180 void twl6030_usb_device_settings()
181 {
182         u8 data = 0;
183
184         /* Select APP Group and set state to ON */
185         twl6030_i2c_write_u8(TWL6030_CHIP_PM, VUSB_CFG_STATE, 0x21);
186
187         twl6030_i2c_read_u8(TWL6030_CHIP_PM, MISC2, &data);
188         data |= 0x10;
189
190         /* Select the input supply for VBUS regulator */
191         twl6030_i2c_write_u8(TWL6030_CHIP_PM, MISC2, data);
192 }
193 #endif