Added new driver rx51_battery which export twlmadc battery values to sysfs
authorPali Rohár <pali.rohar@gmail.com>
Wed, 12 Sep 2012 12:04:27 +0000 (14:04 +0200)
committerPali Rohár <pali.rohar@gmail.com>
Wed, 12 Sep 2012 12:04:27 +0000 (14:04 +0200)
kernel-power-2.6.28/debian/patches/rx51_battery.patch [new file with mode: 0644]
kernel-power-2.6.28/debian/patches/rx51_battery_board.patch [new file with mode: 0644]
kernel-power-2.6.28/debian/patches/rx51_battery_kconfig.patch [new file with mode: 0644]
kernel-power-2.6.28/debian/patches/series

diff --git a/kernel-power-2.6.28/debian/patches/rx51_battery.patch b/kernel-power-2.6.28/debian/patches/rx51_battery.patch
new file mode 100644 (file)
index 0000000..8bbd7e5
--- /dev/null
@@ -0,0 +1,220 @@
+--- /dev/null
++++ kernel-power/drivers/power/rx51_battery.c
+@@ -0,0 +1,217 @@
++/*
++    rx51_battery.c - Nokia RX-51 battery driver
++    Copyright (C) 2012  Pali Rohár <pali.rohar@gmail.com>
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 2 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License along
++    with this program; if not, write to the Free Software Foundation, Inc.,
++    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++*/
++
++#include <linux/module.h>
++#include <linux/param.h>
++#include <linux/platform_device.h>
++#include <linux/power_supply.h>
++#include <linux/slab.h>
++#include <linux/i2c/twl4030-madc.h>
++
++struct rx51_device_info {
++      struct device *dev;
++      struct power_supply bat;
++};
++
++/* Read ADCIN channel value, code copied from maemo kernel */
++static int rx51_battery_read_adc(int channel)
++{
++      struct twl4030_madc_request req;
++
++      req.channels = (1 << channel);
++      req.do_avg = 1;
++      req.method = TWL4030_MADC_SW1;
++      req.func_cb = NULL;
++      req.type = TWL4030_MADC_WAIT;
++
++      if (twl4030_madc_conversion(&req) > 0)
++              return (u16)req.rbuf[channel];
++      else
++              return -ENODATA;
++}
++
++/* Read ADCIN channel 12 (voltage) and convert RAW value to micro voltage */
++/* This conversion formula was extracted from maemo program bsi-read */
++static int rx51_battery_read_voltage(struct rx51_device_info *di)
++{
++      int voltage = rx51_battery_read_adc(12);
++      if (voltage < 0)
++              return voltage;
++      return (((((2099203 - (1LL<<31)) * voltage * 6000) >> 32) -
++              ((voltage * 6000LL << 1) >> 32) + (voltage * 6000)) >> 9)*1000;
++}
++
++/* Conversation table based on experimental data */
++/* Usage: rx51_temp_table[rx51_temp_first - Celsius value] = lowest RAW value */
++static int rx51_temp_first = 48;
++static int rx51_temp_table[] = {
++       30,  31,  32,  33,  34,  35,  36,  38,  39,  40,  42,  43,  45,  47,
++       48,  50,  51,  53,  55,  57,  59,  61,  63,  66,  69,  72,  74,  76,
++       80,  83,  86,  90,  93,  96, 100, 105, 109, 114, 119, 124, 130, 136,
++      142, 148, 155, 161, 166, 177, 184, 193, 202, 213, 222, 230, 243, 255,
++      268, 280
++};
++
++/* Read ADCIN channel 0 (battery temp) and convert value to tenths of Celsius */
++/* Try to find lowest temperature value for raw value in table */
++static int rx51_battery_read_temperature(struct rx51_device_info *di)
++{
++      int min = 0;
++      int max = ARRAY_SIZE(rx51_temp_table)-1;
++      int temperature = rx51_battery_read_adc(0);
++
++      if (temperature < 0)
++              return temperature;
++      if (temperature < rx51_temp_table[min])
++              return rx51_temp_first-min+1;
++      if (temperature > rx51_temp_table[max])
++              return rx51_temp_first-max-1;
++
++      while (max-min > 1) {
++              int mid = (max+min)/2;
++              if (rx51_temp_table[mid] <= temperature)
++                      min = mid;
++              else if (rx51_temp_table[mid] > temperature)
++                      max = mid;
++              if (rx51_temp_table[mid] == temperature)
++                      break;
++      }
++
++      return (rx51_temp_first - min) * 100;
++}
++
++/* Read ADCIN channel 4 (BSI) and convert RAW value to micro Ah */
++/* This conversion formula was extracted from maemo program bsi-read */
++static int rx51_battery_read_capacity(struct rx51_device_info *di)
++{
++      int capacity = rx51_battery_read_adc(4);
++      if (capacity < 0)
++              return capacity;
++      return 1280 * (1200 * capacity)/(1024 - capacity);
++}
++
++/* Return power_supply property */
++static int rx51_battery_get_property(struct power_supply *psy,
++                                      enum power_supply_property psp,
++                                      union power_supply_propval *val)
++{
++      struct rx51_device_info *di = container_of((psy),
++                              struct rx51_device_info, bat);
++
++      switch (psp) {
++      case POWER_SUPPLY_PROP_TECHNOLOGY:
++              val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
++              break;
++      case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
++              val->intval = 4200000;
++              break;
++      case POWER_SUPPLY_PROP_PRESENT:
++              val->intval = rx51_battery_read_voltage(di) ? 1 : 0;
++              break;
++      case POWER_SUPPLY_PROP_VOLTAGE_NOW:
++              val->intval = rx51_battery_read_voltage(di);
++              break;
++      case POWER_SUPPLY_PROP_TEMP:
++              val->intval = rx51_battery_read_temperature(di);
++              break;
++      case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
++              val->intval = rx51_battery_read_capacity(di);
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      if (val->intval < 0)
++              return val->intval;
++
++      return 0;
++}
++
++static enum power_supply_property rx51_battery_props[] = {
++      POWER_SUPPLY_PROP_TECHNOLOGY,
++      POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
++      POWER_SUPPLY_PROP_PRESENT,
++      POWER_SUPPLY_PROP_VOLTAGE_NOW,
++      POWER_SUPPLY_PROP_TEMP,
++      POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
++};
++
++static int __devinit rx51_battery_probe(struct platform_device *pdev)
++{
++      struct rx51_device_info *di;
++      int ret;
++
++      di = kzalloc(sizeof(*di), GFP_KERNEL);
++      if (!di)
++              return -ENOMEM;
++
++      platform_set_drvdata(pdev, di);
++
++      di->bat.name = dev_name(&pdev->dev);
++      di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
++      di->bat.properties = rx51_battery_props;
++      di->bat.num_properties = ARRAY_SIZE(rx51_battery_props);
++      di->bat.get_property = rx51_battery_get_property;
++
++      ret = power_supply_register(di->dev, &di->bat);
++      if (ret) {
++              platform_set_drvdata(pdev, NULL);
++              kfree(di);
++              return ret;
++      }
++
++      return 0;
++}
++
++static int __devexit rx51_battery_remove(struct platform_device *pdev)
++{
++      struct rx51_device_info *di = platform_get_drvdata(pdev);
++
++      power_supply_unregister(&di->bat);
++      platform_set_drvdata(pdev, NULL);
++      kfree(di);
++
++      return 0;
++}
++
++static struct platform_driver rx51_battery_driver = {
++      .probe = rx51_battery_probe,
++      .remove = __devexit_p(rx51_battery_remove),
++      .driver = {
++              .name = "rx51-battery",
++              .owner = THIS_MODULE,
++      },
++};
++
++static int __init rx51_battery_init(void)
++{
++      return platform_driver_register(&rx51_battery_driver);
++}
++module_init(rx51_battery_init);
++
++static void __exit rx51_battery_exit(void)
++{
++      platform_driver_unregister(&rx51_battery_driver);
++}
++module_exit(rx51_battery_exit);
++
++MODULE_ALIAS("platform:rx51-battery");
++MODULE_AUTHOR("Pali Rohár <pali.rohar@gmail.com>");
++MODULE_DESCRIPTION("Nokia RX-51 battery driver");
++MODULE_LICENSE("GPL");
diff --git a/kernel-power-2.6.28/debian/patches/rx51_battery_board.patch b/kernel-power-2.6.28/debian/patches/rx51_battery_board.patch
new file mode 100644 (file)
index 0000000..906b812
--- /dev/null
@@ -0,0 +1,19 @@
+--- kernel-power/arch/arm/mach-omap2/board-rx51-peripherals.c.orig     2012-09-12 13:34:39.219423454 +0200
++++ kernel-power/arch/arm/mach-omap2/board-rx51-peripherals.c  2012-09-12 13:33:59.979424767 +0200
+@@ -267,10 +267,16 @@ static struct platform_device rx51_lirc_
+       },
+ };
++static struct platform_device rx51_battery = {
++      .name           = "rx51-battery",
++      .id             = -1,
++};
++
+ static struct platform_device *rx51_peripherals_devices[] = {
+       &rx51_smc91x_device,
+       &rx51_camera_button_device,
+       &rx51_lirc_device,
++      &rx51_battery,
+ };
+ static void __init rx51_init_smc91x(void)
diff --git a/kernel-power-2.6.28/debian/patches/rx51_battery_kconfig.patch b/kernel-power-2.6.28/debian/patches/rx51_battery_kconfig.patch
new file mode 100644 (file)
index 0000000..2219531
--- /dev/null
@@ -0,0 +1,20 @@
+--- kernel-power/drivers/power/Kconfig.orig    2012-09-12 13:56:16.891379993 +0200
++++ kernel-power/drivers/power/Kconfig 2012-09-12 13:59:44.455373042 +0200
+@@ -81,4 +81,10 @@ config CHARGER_BQ2415X
+       help
+         Say Y here to enable support for chargers with BQ2415X(I2C) chip.
++config BATTERY_RX51
++      tristate "Nokia RX-51 battery driver"
++      depends on TWL4030_MADC
++      help
++        Say Y here to enable support for battery information on Nokia RX-51.
++
+ endif # POWER_SUPPLY
+--- kernel-power/drivers/power/Makefile.orig   2012-09-12 13:56:21.735379832 +0200
++++ kernel-power/drivers/power/Makefile        2012-09-12 14:00:14.171372046 +0200
+@@ -26,3 +26,4 @@ obj-$(CONFIG_BATTERY_TOSA)   += tosa_batte
+ obj-$(CONFIG_BATTERY_WM97XX)  += wm97xx_battery.o
+ obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
+ obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
++obj-$(CONFIG_BATTERY_RX51)    += rx51_battery.o
index 9bf0798..ca9184c 100644 (file)
@@ -76,6 +76,9 @@ USB-fix-kernel-oops-with-g_ether-and-windows.diff
 bq2415x_charger.patch
 bq2415x_kconfig.patch
 bq2415x_rx51.patch
+rx51_battery.patch
+rx51_battery_board.patch
+rx51_battery_kconfig.patch
 rx51_add_secure_ppa_api.diff
 rx51_arm_errata_430973.diff
 clear_the_it_state_when_invoking_a_thumb_2_signal_handler.diff