ARM: cpu topology: Add debugfs interface for cpu_power
[cmplus.git] / arch / arm / mach-omap2 / board-tuna-power.c
blob53a63389810d16a62f35f2e450fa2744d731d983
1 /* Power support for Samsung Tuna Board.
3 * Copyright (C) 2011 Google, Inc.
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/err.h>
16 #include <linux/i2c.h>
17 #include <linux/init.h>
18 #include <linux/kernel.h>
19 #include <linux/interrupt.h>
20 #include <linux/gpio.h>
21 #include <linux/max17040_battery.h>
22 #include <linux/moduleparam.h>
23 #include <linux/pda_power.h>
24 #include <linux/platform_device.h>
25 #include <linux/i2c/twl6030-madc.h>
26 #include <linux/delay.h>
28 #include <plat/cpu.h>
29 #include <plat/omap-pm.h>
31 #include "board-tuna.h"
32 #include "mux.h"
33 #include "pm.h"
35 /* These will be different on pre-lunchbox, lunchbox, and final */
36 #define GPIO_CHARGING_N 83
37 #define GPIO_TA_NCONNECTED 142
38 #define GPIO_CHARGE_N 13
39 #define GPIO_CHG_CUR_ADJ 102
40 #define GPIO_FUEL_ALERT 44
42 #define TPS62361_GPIO 7
43 #define ADC_NUM_SAMPLES 5
44 #define ADC_LIMIT_ERR_COUNT 5
45 #define ISET_ADC_CHANNEL 3
46 #define TEMP_ADC_CHANNEL 1
48 #define CHARGE_FULL_ADC 150
50 #define HIGH_BLOCK_TEMP_MAGURO 500
51 #define HIGH_RECOVER_TEMP_MAGURO 420
52 #define LOW_BLOCK_TEMP_MAGURO (-50)
53 #define LOW_RECOVER_TEMP_MAGURO 0
55 #define HIGH_BLOCK_TEMP_TORO 490
56 #define HIGH_RECOVER_TEMP_TORO 420
57 #define LOW_BLOCK_TEMP_TORO (-50)
58 #define LOW_RECOVER_TEMP_TORO 0
60 /**
61 ** temp_adc_table_data
62 ** @adc_value : thermistor adc value
63 ** @temperature : temperature(C) * 10
64 **/
65 struct temp_adc_table_data {
66 int adc_value;
67 int temperature;
70 static DEFINE_SPINLOCK(charge_en_lock);
71 static int charger_state;
72 static bool is_charging_mode;
74 static struct temp_adc_table_data temper_table_maguro[] = {
75 /* ADC, Temperature (C/10) */
76 { 75, 700 },
77 { 78, 690 },
78 { 82, 680 },
79 { 84, 670 },
80 { 87, 660 },
81 { 89, 650 },
82 { 92, 640 },
83 { 95, 630 },
84 { 99, 620 },
85 { 102, 610 },
86 { 105, 600 },
87 { 109, 590 },
88 { 113, 580 },
89 { 117, 570 },
90 { 121, 560 },
91 { 124, 550 },
92 { 127, 540 },
93 { 135, 530 },
94 { 139, 520 },
95 { 143, 510 },
96 { 147, 500 },
97 { 153, 490 },
98 { 158, 480 },
99 { 163, 470 },
100 { 169, 460 },
101 { 175, 450 },
102 { 181, 440 },
103 { 187, 430 },
104 { 193, 420 },
105 { 199, 410 },
106 { 205, 400 },
107 { 212, 390 },
108 { 218, 380 },
109 { 227, 370 },
110 { 233, 360 },
111 { 240, 350 },
112 { 249, 340 },
113 { 258, 330 },
114 { 267, 320 },
115 { 276, 310 },
116 { 285, 300 },
117 { 299, 290 },
118 { 308, 280 },
119 { 313, 270 },
120 { 322, 260 },
121 { 331, 250 },
122 { 342, 240 },
123 { 355, 230 },
124 { 363, 220 },
125 { 373, 210 },
126 { 383, 200 },
127 { 394, 190 },
128 { 407, 180 },
129 { 417, 170 },
130 { 427, 160 },
131 { 437, 150 },
132 { 450, 140 },
133 { 465, 130 },
134 { 475, 120 },
135 { 487, 110 },
136 { 500, 100 },
137 { 514, 90 },
138 { 526, 80 },
139 { 540, 70 },
140 { 552, 60 },
141 { 565, 50 },
142 { 577, 40 },
143 { 589, 30 },
144 { 603, 20 },
145 { 614, 10 },
146 { 628, 0 },
147 { 639, (-10) },
148 { 664, (-20) },
149 { 689, (-30) },
150 { 717, (-40) },
151 { 744, (-50) },
152 { 754, (-60) },
153 { 765, (-70) },
154 { 776, (-80) },
155 { 787, (-90) },
156 { 798, (-100) },
159 static struct temp_adc_table_data temper_table_toro[] = {
160 /* ADC, Temperature (C/10) */
161 { 70, 700 },
162 { 72, 690 },
163 { 75, 680 },
164 { 77, 670 },
165 { 80, 660 },
166 { 82, 650 },
167 { 85, 640 },
168 { 88, 630 },
169 { 91, 620 },
170 { 94, 610 },
171 { 97, 600 },
172 { 101, 590 },
173 { 104, 580 },
174 { 108, 570 },
175 { 111, 560 },
176 { 115, 550 },
177 { 119, 540 },
178 { 124, 530 },
179 { 129, 520 },
180 { 133, 510 },
181 { 137, 500 },
182 { 141, 490 },
183 { 146, 480 },
184 { 150, 470 },
185 { 155, 460 },
186 { 160, 450 },
187 { 166, 440 },
188 { 171, 430 },
189 { 177, 420 },
190 { 184, 410 },
191 { 190, 400 },
192 { 196, 390 },
193 { 203, 380 },
194 { 212, 370 },
195 { 219, 360 },
196 { 226, 350 },
197 { 234, 340 },
198 { 242, 330 },
199 { 250, 320 },
200 { 258, 310 },
201 { 266, 300 },
202 { 275, 290 },
203 { 284, 280 },
204 { 294, 270 },
205 { 303, 260 },
206 { 312, 250 },
207 { 322, 240 },
208 { 333, 230 },
209 { 344, 220 },
210 { 354, 210 },
211 { 364, 200 },
212 { 375, 190 },
213 { 387, 180 },
214 { 399, 170 },
215 { 410, 160 },
216 { 422, 150 },
217 { 431, 140 },
218 { 443, 130 },
219 { 456, 120 },
220 { 468, 110 },
221 { 480, 100 },
222 { 493, 90 },
223 { 506, 80 },
224 { 519, 70 },
225 { 532, 60 },
226 { 545, 50 },
227 { 558, 40 },
228 { 571, 30 },
229 { 582, 20 },
230 { 595, 10 },
231 { 608, 0 },
232 { 620, (-10) },
233 { 632, (-20) },
234 { 645, (-30) },
235 { 658, (-40) },
236 { 670, (-50) },
237 { 681, (-60) },
238 { 696, (-70) },
239 { 708, (-80) },
240 { 720, (-90) },
241 { 732, (-100) },
244 static struct temp_adc_table_data *temper_table = temper_table_maguro;
245 static int temper_table_size = ARRAY_SIZE(temper_table_maguro);
247 static bool enable_sr = true;
248 module_param(enable_sr, bool, S_IRUSR | S_IRGRP | S_IROTH);
250 static struct gpio charger_gpios[] = {
251 { .gpio = GPIO_CHARGING_N, .flags = GPIOF_IN, .label = "charging_n" },
252 { .gpio = GPIO_TA_NCONNECTED, .flags = GPIOF_IN, .label = "charger_n" },
253 { .gpio = GPIO_CHARGE_N, .flags = GPIOF_OUT_INIT_HIGH, .label = "charge_n" },
254 { .gpio = GPIO_CHG_CUR_ADJ, .flags = GPIOF_OUT_INIT_LOW, .label = "charge_cur_adj" },
257 static int twl6030_get_adc_data(int ch)
259 int adc_data;
260 int adc_max = -1;
261 int adc_min = 1 << 11;
262 int adc_total = 0;
263 int i, j;
265 for (i = 0; i < ADC_NUM_SAMPLES; i++) {
266 adc_data = twl6030_get_madc_conversion(ch);
267 if (adc_data == -EAGAIN) {
268 for (j = 0; j < ADC_LIMIT_ERR_COUNT; j++) {
269 msleep(20);
270 adc_data = twl6030_get_madc_conversion(ch);
271 if (adc_data > 0)
272 break;
274 if (j >= ADC_LIMIT_ERR_COUNT) {
275 pr_err("%s: Retry count exceeded[ch:%d]\n",
276 __func__, ch);
277 return adc_data;
279 } else if (adc_data < 0) {
280 pr_err("%s: Failed read adc value : %d [ch:%d]\n",
281 __func__, adc_data, ch);
282 return adc_data;
285 if (adc_data > adc_max)
286 adc_max = adc_data;
287 if (adc_data < adc_min)
288 adc_min = adc_data;
290 adc_total += adc_data;
292 return (adc_total - adc_max - adc_min) / (ADC_NUM_SAMPLES - 2);
295 static int iset_adc_value(void)
297 return twl6030_get_adc_data(ISET_ADC_CHANNEL);
300 static int temp_adc_value(void)
302 return twl6030_get_adc_data(TEMP_ADC_CHANNEL);
305 static bool check_charge_full(void)
307 int ret;
309 ret = iset_adc_value();
310 if (ret < 0) {
311 pr_err("%s: invalid iset adc value [%d]\n",
312 __func__, ret);
313 return false;
315 pr_debug("%s : iset adc value : %d\n", __func__, ret);
317 return ret < CHARGE_FULL_ADC;
320 static int get_bat_temp_by_adc(int *batt_temp)
322 int array_size = temper_table_size;
323 int temp_adc = temp_adc_value();
324 int mid;
325 int left_side = 0;
326 int right_side = array_size - 1;
327 int temp = 0;
329 if (temp_adc < 0) {
330 pr_err("%s : Invalid temperature adc value [%d]\n",
331 __func__, temp_adc);
332 return temp_adc;
335 while (left_side <= right_side) {
336 mid = (left_side + right_side) / 2;
337 if (mid == 0 || mid == array_size - 1 ||
338 (temper_table[mid].adc_value <= temp_adc &&
339 temper_table[mid+1].adc_value > temp_adc)) {
340 temp = temper_table[mid].temperature;
341 break;
342 } else if (temp_adc - temper_table[mid].adc_value > 0) {
343 left_side = mid + 1;
344 } else {
345 right_side = mid - 1;
349 pr_debug("%s: temp adc : %d, temp : %d\n", __func__, temp_adc, temp);
350 *batt_temp = temp;
351 return 0;
354 static int charger_init(struct device *dev)
356 return gpio_request_array(charger_gpios, ARRAY_SIZE(charger_gpios));
359 static void charger_exit(struct device *dev)
361 gpio_free_array(charger_gpios, ARRAY_SIZE(charger_gpios));
364 static void set_charge_en(int state)
366 gpio_set_value(GPIO_CHARGE_N, !state);
369 static void charger_set_charge(int state)
371 unsigned long flags;
373 spin_lock_irqsave(&charge_en_lock, flags);
374 gpio_set_value(GPIO_CHG_CUR_ADJ, !!(state & PDA_POWER_CHARGE_AC));
375 charger_state = state;
376 set_charge_en(state);
377 spin_unlock_irqrestore(&charge_en_lock, flags);
380 static void charger_set_only_charge(int state)
382 unsigned long flags;
384 spin_lock_irqsave(&charge_en_lock, flags);
385 if (charger_state)
386 set_charge_en(state);
387 spin_unlock_irqrestore(&charge_en_lock, flags);
388 /* CHG_ING_N level changed after set charge_en and 150ms */
389 msleep(150);
392 static int charger_is_online(void)
394 return !gpio_get_value(GPIO_TA_NCONNECTED);
397 static int charger_is_charging(void)
399 return !gpio_get_value(GPIO_CHARGING_N);
402 static char *tuna_charger_supplied_to[] = {
403 "battery",
406 static const __initdata struct pda_power_pdata charger_pdata = {
407 .init = charger_init,
408 .exit = charger_exit,
409 .set_charge = charger_set_charge,
410 .wait_for_status = 500,
411 .wait_for_charger = 500,
412 .supplied_to = tuna_charger_supplied_to,
413 .num_supplicants = ARRAY_SIZE(tuna_charger_supplied_to),
414 .use_otg_notifier = true,
417 static struct max17040_platform_data max17043_pdata = {
418 .charger_online = charger_is_online,
419 .charger_enable = charger_is_charging,
420 .allow_charging = charger_set_only_charge,
421 .skip_reset = true,
422 .min_capacity = 3,
423 .is_full_charge = check_charge_full,
424 .get_bat_temp = get_bat_temp_by_adc,
425 .high_block_temp = HIGH_BLOCK_TEMP_MAGURO,
426 .high_recover_temp = HIGH_RECOVER_TEMP_MAGURO,
427 .low_block_temp = LOW_BLOCK_TEMP_MAGURO,
428 .low_recover_temp = LOW_RECOVER_TEMP_MAGURO,
429 .fully_charged_vol = 4150000,
430 .recharge_vol = 4140000,
431 .limit_charging_time = 21600, /* 6 hours */
432 .limit_recharging_time = 5400, /* 90 min */
435 static const __initdata struct i2c_board_info max17043_i2c[] = {
437 I2C_BOARD_INFO("max17040", (0x6C >> 1)),
438 .platform_data = &max17043_pdata,
439 .irq = OMAP_GPIO_IRQ(GPIO_FUEL_ALERT),
443 static int __init tuna_charger_mode_setup(char *str)
445 if (!str) /* No mode string */
446 return 0;
448 is_charging_mode = !strcmp(str, "charger");
450 pr_debug("Charge mode string = \"%s\" charger mode = %d\n", str,
451 is_charging_mode);
453 return 1;
456 __setup("androidboot.mode=", tuna_charger_mode_setup);
458 void __init omap4_tuna_power_init(void)
460 struct platform_device *pdev;
461 int status;
463 /* Vsel0 = gpio, vsel1 = gnd */
464 status = omap_tps6236x_board_setup(true, TPS62361_GPIO, -1,
465 OMAP_PIN_OFF_OUTPUT_HIGH, -1);
466 if (status)
467 pr_err("TPS62361 initialization failed: %d\n", status);
469 * Some Tuna devices have a 4430 chip on a 4460 board, manually
470 * tweak the power tree to the 4460 style with the TPS regulator.
472 if (cpu_is_omap443x()) {
473 /* Disable 4430 mapping */
474 omap_twl_pmic_update("mpu", CHIP_IS_OMAP443X, 0x0);
475 omap_twl_pmic_update("core", CHIP_IS_OMAP443X, 0x0);
476 /* make 4460 map usable for 4430 */
477 omap_twl_pmic_update("core", CHIP_IS_OMAP446X, CHIP_IS_OMAP443X);
478 omap_tps6236x_update("mpu", CHIP_IS_OMAP446X, CHIP_IS_OMAP443X);
481 /* Update temperature data from board type */
482 if (omap4_tuna_get_type() == TUNA_TYPE_TORO) {
483 temper_table = temper_table_toro;
484 temper_table_size = ARRAY_SIZE(temper_table_toro);
486 max17043_pdata.high_block_temp = HIGH_BLOCK_TEMP_TORO;
487 max17043_pdata.high_recover_temp = HIGH_RECOVER_TEMP_TORO;
488 max17043_pdata.low_block_temp = LOW_BLOCK_TEMP_TORO;
489 max17043_pdata.low_recover_temp = LOW_RECOVER_TEMP_TORO;
492 /* Update oscillator information */
493 if (omap4_tuna_get_revision() <= 0x3) {
495 * until sample 4 (Toro and Maguro), we used KC2520B38:
496 * ST = 10ms
497 * Output Disable time = 100ns
498 * Output enable time = 5ms
499 * tstart = 10ms + 5ms = 15ms.
500 * tshut = 1us (rounded)
502 omap_pm_set_osc_lp_time(15000, 1);
503 } else {
505 * sample 5 onwards (Toro and Maguro), we use SQ200384:
506 * ST = 10ms
507 * Output Disable time = 100ns
508 * Output enable time = 10ms
509 * tstart = 10ms + 10ms = 20ms.
510 * tshut = 1us (rounded)
512 omap_pm_set_osc_lp_time(20000, 1);
515 omap_mux_init_gpio(charger_gpios[0].gpio, OMAP_PIN_INPUT);
516 omap_mux_init_gpio(charger_gpios[1].gpio, OMAP_PIN_INPUT);
517 omap_mux_init_gpio(charger_gpios[2].gpio, OMAP_PIN_OUTPUT);
518 omap_mux_init_gpio(charger_gpios[3].gpio, OMAP_PIN_OUTPUT);
519 omap_mux_init_gpio(GPIO_FUEL_ALERT, OMAP_PIN_INPUT);
521 pdev = platform_device_register_resndata(NULL, "pda-power", -1,
522 NULL, 0, &charger_pdata, sizeof(charger_pdata));
523 if (IS_ERR_OR_NULL(pdev))
524 pr_err("cannot register pda-power\n");
526 max17043_pdata.use_fuel_alert = !is_charging_mode;
527 i2c_register_board_info(4, max17043_i2c, ARRAY_SIZE(max17043_i2c));
529 if (enable_sr)
530 omap_enable_smartreflex_on_init();
532 omap_pm_enable_off_mode();