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