summaryrefslogtreecommitdiff
path: root/recipes/linux/linux-omap-pm-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-3.patch
blob: 2247056177a70106d00d6e1236f5f40c727910af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
--- a/drivers/power/twl4030_bci_battery.c	2010-01-16 13:48:46.745838675 -0800
+++ b/drivers/power/twl4030_bci_battery.c	2010-01-16 13:41:47.317595764 -0800
@@ -598,11 +598,31 @@
 static int twl4030battery_voltage(void)
 {
 	int volt = read_bci_val(T2_BATTERY_VOLT);
-
 	return (volt * VOLT_STEP_SIZE) / VOLT_PSR_R;
 }
 
 /*
+ * Get latest battery voltage (using MADC)
+ *
+ * When the BCI is not charging, the BCI voltage registers are not
+ * updated and are 'frozen' but the data can be read through the
+ * MADC.
+ */
+static int twl4030battery_voltage_madc(void)
+{
+	struct twl4030_madc_request req;
+
+	req.channels = (1 << 12);
+	req.do_avg = 0;
+	req.method = TWL4030_MADC_SW1;
+	req.active = 0;
+	req.func_cb = NULL;
+	twl4030_madc_conversion(&req);
+
+	return (((int) req.rbuf[12]) * VOLT_STEP_SIZE) / VOLT_PSR_R;
+}
+
+/*
  * Return the battery current
  * Or < 0 on failure.
  */
@@ -840,21 +860,21 @@
 
 static void twl4030_bci_battery_read_status(struct twl4030_bci_device_info *di)
 {
-	di->temp_C = twl4030battery_temperature(di);
-	di->voltage_uV = twl4030battery_voltage();
-	di->current_uA = twl4030battery_current();
+	if(di->charge_status != POWER_SUPPLY_STATUS_DISCHARGING) {
+		di->temp_C = twl4030battery_temperature(di);
+		di->voltage_uV = twl4030battery_voltage();
+		di->current_uA = twl4030battery_current();
+	}
 }
 
 static void
 twl4030_bci_battery_update_status(struct twl4030_bci_device_info *di)
 {
-	twl4030_bci_battery_read_status(di);
-	di->charge_status = POWER_SUPPLY_STATUS_UNKNOWN;
-
 	if (power_supply_am_i_supplied(&di->bat))
 		di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
 	else
 		di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
+	twl4030_bci_battery_read_status(di);
 }
 
 static void twl4030_bci_battery_work(struct work_struct *work)
@@ -960,7 +980,15 @@
 
 	return count;
 }
+
+static ssize_t
+show_voltage(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%d\n", twl4030battery_voltage_madc());
+}
+
 static DEVICE_ATTR(charge_current, S_IRUGO | S_IWUGO, show_charge_current, set_charge_current);
+static DEVICE_ATTR(voltage_now_madc, S_IRUGO, show_voltage, NULL);
 
 static int twl4030_bk_bci_battery_get_property(struct power_supply *psy,
 					enum power_supply_property psp,
@@ -998,10 +1026,23 @@
 
 	switch (psp) {
 	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
-		val->intval = di->voltage_uV;
+	{
+		/* Get latest data from MADC -- not done periodically by
+		   worker as this is more expensive, so only do it when we
+		   are actually asked for the data... */
+		if(di->charge_status == POWER_SUPPLY_STATUS_DISCHARGING)
+			val->intval = twl4030battery_voltage_madc();
+		else
+			val->intval = di->voltage_uV;
+
 		break;
+	}
 	case POWER_SUPPLY_PROP_CURRENT_NOW:
-		val->intval = di->current_uA;
+		/* FIXME: Get from MADC */
+		if(di->charge_status == POWER_SUPPLY_STATUS_DISCHARGING)
+			val->intval = 0;
+		else
+			val->intval = di->current_uA;
 		break;
 	case POWER_SUPPLY_PROP_TEMP:
 		val->intval = di->temp_C;
@@ -1016,6 +1057,12 @@
 			val->intval = 0;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
+		/* Get latest data from MADC -- not done periodically by
+		   worker as this is more expensive, so only do it when we
+		   are actually asked for the data... */
+		if(di->charge_status == POWER_SUPPLY_STATUS_DISCHARGING)
+			di->voltage_uV = twl4030battery_voltage_madc();
+
 		/*
 		 * need to get the correct percentage value per the
 		 * battery characteristics. Approx values for now.
@@ -1145,6 +1192,7 @@
 		}
 	}
 
+	ret = device_create_file(di->bat.dev, &dev_attr_voltage_now_madc);
 	ret = device_create_file(di->bat.dev, &dev_attr_charge_current);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to create sysfs entries\n");