From 00994ee99ee4744d9ca5bd8df1af3718acb66ecc Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michael=20B=C3=BCsch?= Date: Fri, 28 Jan 2011 22:45:37 +0000 Subject: [PATCH] n810bm: Implement more ADC basics SVN-Revision: 25222 --- .../900-n810-battery-management.patch | 243 +++++++++++++++--- 1 file changed, 211 insertions(+), 32 deletions(-) diff --git a/target/linux/omap24xx/patches-2.6.37/900-n810-battery-management.patch b/target/linux/omap24xx/patches-2.6.37/900-n810-battery-management.patch index ea33bfdb5e4..3f6262a357b 100644 --- a/target/linux/omap24xx/patches-2.6.37/900-n810-battery-management.patch +++ b/target/linux/omap24xx/patches-2.6.37/900-n810-battery-management.patch @@ -12,9 +12,9 @@ Index: linux-2.6.37/drivers/cbus/Kconfig =================================================================== ---- linux-2.6.37.orig/drivers/cbus/Kconfig 2011-01-28 18:14:27.901372343 +0100 -+++ linux-2.6.37/drivers/cbus/Kconfig 2011-01-28 18:14:27.952363634 +0100 -@@ -94,4 +94,16 @@ +--- linux-2.6.37.orig/drivers/cbus/Kconfig 2011-01-28 22:33:39.703215389 +0100 ++++ linux-2.6.37/drivers/cbus/Kconfig 2011-01-28 23:41:57.094298060 +0100 +@@ -94,4 +94,12 @@ to Retu/Vilma. Detection state and events are exposed through sysfs. @@ -24,17 +24,13 @@ Index: linux-2.6.37/drivers/cbus/Kconfig + ---help--- + Nokia n810 device battery management. + -+ WARNING: This driver is based on reverse engineered information. -+ It is possibly dangerous to use this software. -+ Use this software at your own risk! -+ + If unsure, say N. + endmenu Index: linux-2.6.37/drivers/cbus/Makefile =================================================================== ---- linux-2.6.37.orig/drivers/cbus/Makefile 2011-01-28 18:14:27.891374053 +0100 -+++ linux-2.6.37/drivers/cbus/Makefile 2011-01-28 18:14:27.952363634 +0100 +--- linux-2.6.37.orig/drivers/cbus/Makefile 2011-01-28 22:33:39.694216931 +0100 ++++ linux-2.6.37/drivers/cbus/Makefile 2011-01-28 22:33:39.754206648 +0100 @@ -12,3 +12,6 @@ obj-$(CONFIG_CBUS_TAHVO_USER) += tahvo-user.o obj-$(CONFIG_CBUS_RETU_USER) += retu-user.o @@ -45,16 +41,16 @@ Index: linux-2.6.37/drivers/cbus/Makefile Index: linux-2.6.37/drivers/cbus/n810bm_main.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.37/drivers/cbus/n810bm_main.c 2011-01-28 18:14:27.952363634 +0100 -@@ -0,0 +1,397 @@ ++++ linux-2.6.37/drivers/cbus/n810bm_main.c 2011-01-28 23:41:23.510064352 +0100 +@@ -0,0 +1,562 @@ +/* + * Nokia n810 battery management + * -+ * WARNING: This driver is based on reverse engineered information. ++ * WARNING: This driver is based on unconfirmed documentation. + * It is possibly dangerous to use this software. + * Use this software at your own risk! + * -+ * Copyright (c) 2010 Michael Buesch ++ * Copyright (c) 2010-2011 Michael Buesch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License @@ -84,10 +80,6 @@ Index: linux-2.6.37/drivers/cbus/n810bm_main.c +#define N810BM_MIN_VOLTAGE_THRES 3300 /* Absolute minimum voltage threshold */ + + -+/* Battery related retu ADC channels */ -+#define RETU_ADC_BSI 0x01 /* Battery Size Indicator */ -+#define RETU_ADC_BATTVOLT 0x08 /* Battery voltage measurement */ -+ +/* RETU_ADC_BSI + * The battery size indicator ADC measures the resistance between + * the battery BSI pin and ground. This is used to detect the battery @@ -222,6 +214,42 @@ Index: linux-2.6.37/drivers/cbus/n810bm_main.c + return value; +} + ++static int adc_sanity_check(struct n810bm *bm, unsigned int channel) ++{ ++ int value; ++ ++ value = retu_read_adc(channel); ++ if (value < 0) { ++ dev_err(&bm->pdev->dev, "Failed to read GND ADC channel %u", ++ channel); ++ return -EIO; ++ } ++ dev_info(&bm->pdev->dev, ++ "GND ADC channel %u sanity check got value: %d", ++ channel, value); ++ if (value > 5) { ++ n810bm_emergency(bm, "GND ADC sanity check failed"); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++static int n810bm_check_adc_sanity(struct n810bm *bm) ++{ ++ int err; ++ ++ /* Discard one conversion */ ++ retu_write(bm, RETU_REG_ADCSCR, 0); ++ retu_read_adc(RETU_ADC_GND2); ++ ++ err = adc_sanity_check(bm, RETU_ADC_GND2); ++ if (err) ++ return err; ++ ++ return 0; ++} ++ +/* Measure the battery voltage. Returns the value in mV (or negative value on error). */ +static int n810bm_measure_batt_voltage(struct n810bm *bm) +{ @@ -239,6 +267,51 @@ Index: linux-2.6.37/drivers/cbus/n810bm_main.c + return mv; +} + ++/* Measure the charger voltage. Returns the value in mV (or negative value on error). */ ++static int n810bm_measure_charger_voltage(struct n810bm *bm) ++{ ++ int adc; ++ unsigned int mv; ++ ++ adc = retu_adc_average(bm, RETU_ADC_CHGVOLT, 5); ++ if (adc < 0) ++ return adc; ++ //TODO convert to mV ++ mv = adc; ++ ++ return mv; ++} ++ ++/* Measure backup battery voltage. Returns the value in mV (or negative value on error). */ ++static int n810bm_measure_backup_batt_voltage(struct n810bm *bm) ++{ ++ int adc; ++ unsigned int mv; ++ ++ adc = retu_adc_average(bm, RETU_ADC_BKUPVOLT, 3); ++ if (adc < 0) ++ return adc; ++ //TODO convert to mV ++ mv = adc; ++ ++ return mv; ++} ++ ++/* Measure the battery temperature. Returns the value in K (or negative value on error). */ ++static int n810bm_measure_batt_temp(struct n810bm *bm) ++{ ++ int adc; ++ unsigned int k; ++ ++ adc = retu_adc_average(bm, RETU_ADC_BATTEMP, 3); ++ if (adc < 0) ++ return adc; ++ //TODO convert to K ++ k = adc; ++ ++ return k; ++} ++ +/* Read the battery capacity via BSI pin. */ +static enum n810bm_capacity n810bm_read_batt_capacity(struct n810bm *bm) +{ @@ -294,7 +367,7 @@ Index: linux-2.6.37/drivers/cbus/n810bm_main.c + +static void n810bm_adc_irq_handler(unsigned long data) +{ -+ struct n810bm *bm = (struct n810bm *)data; ++// struct n810bm *bm = (struct n810bm *)data; + + retu_ack_irq(RETU_INT_ADCS); + //TODO @@ -341,6 +414,69 @@ Index: linux-2.6.37/drivers/cbus/n810bm_main.c +} +static DEVICE_ATTR(batt_capacity, 0444, n810bm_attr_capacity_show, NULL); + ++static ssize_t n810bm_attr_battemp_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct n810bm *bm = platform_get_drvdata(pdev); ++ ssize_t count = 0; ++ int k, err = -ENODEV; ++ ++ spin_lock_irq(&bm->lock); ++ k = n810bm_measure_batt_temp(bm); ++ if (k >= 0) { ++ count = snprintf(buf, PAGE_SIZE, "%d\n", k); ++ err = 0; ++ } ++ spin_unlock_irq(&bm->lock); ++ ++ return err ? err : count; ++} ++static DEVICE_ATTR(batt_temp, 0444, n810bm_attr_battemp_show, NULL); ++ ++static ssize_t n810bm_attr_charger_voltage(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct n810bm *bm = platform_get_drvdata(pdev); ++ ssize_t count = 0; ++ int mv, err = -ENODEV; ++ ++ spin_lock_irq(&bm->lock); ++ mv = n810bm_measure_charger_voltage(bm); ++ if (mv >= 0) { ++ count = snprintf(buf, PAGE_SIZE, "%d\n", mv); ++ err = 0; ++ } ++ spin_unlock_irq(&bm->lock); ++ ++ return err ? err : count; ++} ++static DEVICE_ATTR(charger_voltage, 0444, n810bm_attr_charger_voltage, NULL); ++ ++static ssize_t n810bm_attr_backup_batt_voltage(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct n810bm *bm = platform_get_drvdata(pdev); ++ ssize_t count = 0; ++ int mv, err = -ENODEV; ++ ++ spin_lock_irq(&bm->lock); ++ mv = n810bm_measure_backup_batt_voltage(bm); ++ if (mv >= 0) { ++ count = snprintf(buf, PAGE_SIZE, "%d\n", mv); ++ err = 0; ++ } ++ spin_unlock_irq(&bm->lock); ++ ++ return err ? err : count; ++} ++static DEVICE_ATTR(backup_batt_voltage, 0444, n810bm_attr_backup_batt_voltage, NULL); ++ +static void n810bm_hw_exit(struct n810bm *bm) +{ + retu_write(bm, RETU_REG_ADCSCR, 0); @@ -348,17 +484,24 @@ Index: linux-2.6.37/drivers/cbus/n810bm_main.c + +static int n810bm_hw_init(struct n810bm *bm) +{ -+ retu_write(bm, RETU_REG_ADCSCR, 0); ++ int err; + ++ err = n810bm_check_adc_sanity(bm); ++ if (err) ++ goto error; + bm->capacity = n810bm_read_batt_capacity(bm); + if (bm->capacity == N810BM_CAP_UNKNOWN) { + dev_err(&bm->pdev->dev, "Unknown battery detected"); -+ return -ENODEV; ++ err = -ENODEV; ++ goto error; + } + dev_info(&bm->pdev->dev, "Detected %u mAh battery\n", + (unsigned int)bm->capacity); + + return 0; ++ ++error: ++ return err; +} + +static int __devinit n810bm_probe(struct platform_device *pdev) @@ -383,10 +526,19 @@ Index: linux-2.6.37/drivers/cbus/n810bm_main.c + err = device_create_file(&pdev->dev, &dev_attr_batt_capacity); + if (err) + goto err_rem_charge; ++ err = device_create_file(&pdev->dev, &dev_attr_batt_temp); ++ if (err) ++ goto err_rem_capa; ++ err = device_create_file(&pdev->dev, &dev_attr_charger_voltage); ++ if (err) ++ goto err_rem_temp; ++ err = device_create_file(&pdev->dev, &dev_attr_backup_batt_voltage); ++ if (err) ++ goto err_rem_chg; + err = retu_request_irq(RETU_INT_ADCS, n810bm_adc_irq_handler, + (unsigned long)bm, "n810bm"); + if (err) -+ goto err_rem_capa; ++ goto err_rem_bkup; + + mod_timer(&bm->check_timer, round_jiffies(jiffies + N810BM_CHECK_INTERVAL)); + @@ -394,6 +546,12 @@ Index: linux-2.6.37/drivers/cbus/n810bm_main.c + + return 0; + ++err_rem_bkup: ++ device_remove_file(&pdev->dev, &dev_attr_backup_batt_voltage); ++err_rem_chg: ++ device_remove_file(&pdev->dev, &dev_attr_charger_voltage); ++err_rem_temp: ++ device_remove_file(&pdev->dev, &dev_attr_batt_temp); +err_rem_capa: + device_remove_file(&pdev->dev, &dev_attr_batt_capacity); +err_rem_charge: @@ -412,6 +570,9 @@ Index: linux-2.6.37/drivers/cbus/n810bm_main.c + + retu_free_irq(RETU_INT_ADCS); + del_timer_sync(&bm->check_timer); ++ device_remove_file(&pdev->dev, &dev_attr_backup_batt_voltage); ++ device_remove_file(&pdev->dev, &dev_attr_charger_voltage); ++ device_remove_file(&pdev->dev, &dev_attr_batt_temp); + device_remove_file(&pdev->dev, &dev_attr_batt_capacity); + device_remove_file(&pdev->dev, &dev_attr_batt_charge); + n810bm_hw_exit(bm); @@ -446,8 +607,8 @@ Index: linux-2.6.37/drivers/cbus/n810bm_main.c +MODULE_AUTHOR("Michael Buesch"); Index: linux-2.6.37/drivers/cbus/retu.c =================================================================== ---- linux-2.6.37.orig/drivers/cbus/retu.c 2011-01-28 18:14:27.892373882 +0100 -+++ linux-2.6.37/drivers/cbus/retu.c 2011-01-28 18:14:27.952363634 +0100 +--- linux-2.6.37.orig/drivers/cbus/retu.c 2011-01-28 22:33:39.695216760 +0100 ++++ linux-2.6.37/drivers/cbus/retu.c 2011-01-28 22:33:39.754206648 +0100 @@ -85,10 +85,10 @@ * * This function writes a value to the specified register @@ -463,8 +624,8 @@ Index: linux-2.6.37/drivers/cbus/retu.c void retu_set_clear_reg_bits(int reg, u16 set, u16 clear) Index: linux-2.6.37/drivers/cbus/retu.h =================================================================== ---- linux-2.6.37.orig/drivers/cbus/retu.h 2011-01-28 18:14:27.892373882 +0100 -+++ linux-2.6.37/drivers/cbus/retu.h 2011-01-28 18:14:27.953363463 +0100 +--- linux-2.6.37.orig/drivers/cbus/retu.h 2011-01-28 22:33:39.695216760 +0100 ++++ linux-2.6.37/drivers/cbus/retu.h 2011-01-28 22:40:55.380584650 +0100 @@ -39,6 +39,7 @@ #define RETU_REG_CC2 0x0e /* Common control register 2 */ #define RETU_REG_CTRL_CLR 0x0f /* Regulator clear register */ @@ -473,9 +634,27 @@ Index: linux-2.6.37/drivers/cbus/retu.h #define RETU_REG_STATUS 0x16 /* Status register */ #define RETU_REG_WATCHDOG 0x17 /* Watchdog register */ #define RETU_REG_AUDTXR 0x18 /* Audio Codec Tx register */ -@@ -58,7 +59,7 @@ +@@ -57,8 +58,25 @@ + #define MAX_RETU_IRQ_HANDLERS 16 ++/* ADC channels */ ++#define RETU_ADC_GND 0x00 /* Ground */ ++#define RETU_ADC_BSI 0x01 /* Battery Size Indicator */ ++#define RETU_ADC_BATTEMP 0x02 /* Battery temperature */ ++#define RETU_ADC_CHGVOLT 0x03 /* Charger voltage */ ++#define RETU_ADC_HEADSET 0x04 /* Headset detection */ ++#define RETU_ADC_HOOKDET 0x05 /* Hook detection */ ++#define RETU_ADC_RFGP 0x06 /* RF GP */ ++#define RETU_ADC_WBTX 0x07 /* Wideband Tx detection */ ++#define RETU_ADC_BATTVOLT 0x08 /* Battery voltage measurement */ ++#define RETU_ADC_GND2 0x09 /* Ground */ ++#define RETU_ADC_LIGHTSENS 0x0A /* Light sensor */ ++#define RETU_ADC_LIGHTTEMP 0x0B /* Light sensor temperature */ ++#define RETU_ADC_BKUPVOLT 0x0C /* Backup battery voltage */ ++#define RETU_ADC_TEMP 0x0D /* RETU temperature */ ++ ++ int retu_read_reg(int reg); -void retu_write_reg(int reg, u16 val); +int retu_write_reg(int reg, u16 val); @@ -484,8 +663,8 @@ Index: linux-2.6.37/drivers/cbus/retu.h int retu_request_irq(int id, void *irq_handler, unsigned long arg, char *name); Index: linux-2.6.37/arch/arm/mach-omap2/board-n8x0.c =================================================================== ---- linux-2.6.37.orig/arch/arm/mach-omap2/board-n8x0.c 2011-01-28 18:14:27.876376613 +0100 -+++ linux-2.6.37/arch/arm/mach-omap2/board-n8x0.c 2011-01-28 18:14:27.953363463 +0100 +--- linux-2.6.37.orig/arch/arm/mach-omap2/board-n8x0.c 2011-01-28 22:33:39.679219500 +0100 ++++ linux-2.6.37/arch/arm/mach-omap2/board-n8x0.c 2011-01-28 22:33:39.754206648 +0100 @@ -907,6 +907,17 @@ ARRAY_SIZE(n8x0_gpio_switches)); } @@ -516,7 +695,7 @@ Index: linux-2.6.37/arch/arm/mach-omap2/board-n8x0.c Index: linux-2.6.37/drivers/cbus/lipocharge.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.37/drivers/cbus/lipocharge.c 2011-01-28 18:14:27.953363463 +0100 ++++ linux-2.6.37/drivers/cbus/lipocharge.c 2011-01-28 22:33:39.755206476 +0100 @@ -0,0 +1,63 @@ +/* + * Generic LIPO battery charger @@ -584,7 +763,7 @@ Index: linux-2.6.37/drivers/cbus/lipocharge.c Index: linux-2.6.37/drivers/cbus/lipocharge.h =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.37/drivers/cbus/lipocharge.h 2011-01-28 18:14:27.953363463 +0100 ++++ linux-2.6.37/drivers/cbus/lipocharge.h 2011-01-28 22:33:39.755206476 +0100 @@ -0,0 +1,50 @@ +#ifndef LIPOCHARGE_H_ +#define LIPOCHARGE_H_ @@ -638,8 +817,8 @@ Index: linux-2.6.37/drivers/cbus/lipocharge.h +#endif /* LIPOCHARGE_H_ */ Index: linux-2.6.37/drivers/cbus/tahvo.h =================================================================== ---- linux-2.6.37.orig/drivers/cbus/tahvo.h 2011-01-28 18:14:27.893373711 +0100 -+++ linux-2.6.37/drivers/cbus/tahvo.h 2011-01-28 18:14:27.953363463 +0100 +--- linux-2.6.37.orig/drivers/cbus/tahvo.h 2011-01-28 22:33:39.696216589 +0100 ++++ linux-2.6.37/drivers/cbus/tahvo.h 2011-01-28 22:33:39.755206476 +0100 @@ -30,8 +30,14 @@ #define TAHVO_REG_IDR 0x01 /* Interrupt ID */ #define TAHVO_REG_IDSR 0x02 /* Interrupt status */ -- 2.30.2