From b81a719236bf7d8004a144405eeed8cc6b7b4f9e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Pali=20Roh=C3=A1r?= Date: Wed, 12 Sep 2012 14:04:27 +0200 Subject: [PATCH] Added new driver rx51_battery which export twlmadc battery values to sysfs --- .../debian/patches/rx51_battery.patch | 220 ++++++++++++++++++++ .../debian/patches/rx51_battery_board.patch | 19 ++ .../debian/patches/rx51_battery_kconfig.patch | 20 ++ kernel-power-2.6.28/debian/patches/series | 3 + 4 files changed, 262 insertions(+) create mode 100644 kernel-power-2.6.28/debian/patches/rx51_battery.patch create mode 100644 kernel-power-2.6.28/debian/patches/rx51_battery_board.patch create mode 100644 kernel-power-2.6.28/debian/patches/rx51_battery_kconfig.patch 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 index 0000000..8bbd7e5 --- /dev/null +++ b/kernel-power-2.6.28/debian/patches/rx51_battery.patch @@ -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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#include ++ ++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 "); ++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 index 0000000..906b812 --- /dev/null +++ b/kernel-power-2.6.28/debian/patches/rx51_battery_board.patch @@ -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 index 0000000..2219531 --- /dev/null +++ b/kernel-power-2.6.28/debian/patches/rx51_battery_kconfig.patch @@ -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 diff --git a/kernel-power-2.6.28/debian/patches/series b/kernel-power-2.6.28/debian/patches/series index 9bf0798..ca9184c 100644 --- a/kernel-power-2.6.28/debian/patches/series +++ b/kernel-power-2.6.28/debian/patches/series @@ -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 -- 1.7.9.5