diff --git a/target/linux/xburst/config-2.6.31 b/target/linux/xburst/config-2.6.31 index 7ab7f8afa..826551d69 100644 --- a/target/linux/xburst/config-2.6.31 +++ b/target/linux/xburst/config-2.6.31 @@ -15,6 +15,8 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_GENERIC is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BASE_SMALL=0 +# CONFIG_BATTERY_DS2760 is not set +CONFIG_BATTERY_JZ4740=y # CONFIG_BCM47XX is not set # CONFIG_BINARY_PRINTF is not set CONFIG_BITREVERSE=y @@ -160,6 +162,7 @@ CONFIG_IP_PNP_BOOTP=y CONFIG_IP_PNP_DHCP=y # CONFIG_IP_PNP_RARP is not set CONFIG_IRQ_CPU=y +CONFIG_JZ4740_ADC=y CONFIG_JZ4740_QI_LB60=y CONFIG_JZRISC=y CONFIG_JZSOC=y @@ -212,7 +215,6 @@ CONFIG_MIPS_MT_DISABLED=y # CONFIG_MIPS_MT_SMP is not set # CONFIG_MIPS_MT_SMTC is not set # CONFIG_MIPS_SIM is not set -# CONFIG_MISC_DEVICES is not set CONFIG_MMC=y CONFIG_MMC_BLOCK=y # CONFIG_MMC_BLOCK_BOUNCE is not set @@ -245,12 +247,15 @@ CONFIG_MTD_UBI_WL_THRESHOLD=4096 # CONFIG_PACKET_MMAP is not set CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_PCSPKR_PLATFORM=y +# CONFIG_PDA_POWER is not set CONFIG_PM=y # CONFIG_PMC_MSP is not set # CONFIG_PMC_YOSEMITE is not set # CONFIG_PM_DEBUG is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set CONFIG_PREEMPT=y # CONFIG_PREEMPT_NONE is not set # CONFIG_PROM_EMU is not set diff --git a/target/linux/xburst/files-2.6.31/arch/mips/jz4740/platform.c b/target/linux/xburst/files-2.6.31/arch/mips/jz4740/platform.c index 18fd6b756..4522cd372 100644 --- a/target/linux/xburst/files-2.6.31/arch/mips/jz4740/platform.c +++ b/target/linux/xburst/files-2.6.31/arch/mips/jz4740/platform.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include @@ -430,7 +430,27 @@ static struct platform_device jz_codec_device = { .resource = codec_resources, }; -static struct jz_batt_info jz_batt_gpio_platform_data = { +static struct resource adc_resources[] = { + [0] = { + .start = CPHYSADDR(SADC_BASE), + .end = CPHYSADDR(SADC_BASE) + 0x30, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = JZ_IRQ_SADC, + .end = JZ_IRQ_SADC, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device jz_adc_device = { + .name = "jz4740-adc", + .id = -1, + .num_resources = ARRAY_SIZE(adc_resources), + .resource = adc_resources, +}; + +static struct jz_batt_info jz_battery_platform_data = { .dc_dect_gpio = GPIO_DC_DETE_N, .usb_dect_gpio = GPIO_USB_DETE, .charg_stat_gpio = GPIO_CHARG_STAT_N, @@ -440,11 +460,12 @@ static struct jz_batt_info jz_batt_gpio_platform_data = { .batt_tech = POWER_SUPPLY_TECHNOLOGY_LIPO, }; -static struct platform_device batt_gpio_device = { - .name = "batt_gpio", +static struct platform_device jz_battery_device = { + .name = "jz4740-battery", .id = -1, .dev = { - .platform_data = &jz_batt_gpio_platform_data, + .platform_data = &jz_battery_platform_data, + .parent = &jz_adc_device.dev }, }; @@ -461,7 +482,8 @@ static struct platform_device *jz_platform_devices[] __initdata = { &jz_i2s_device, &jz_codec_device, &jz_rtc_device, - &batt_gpio_device, + &jz_adc_device, + &jz_battery_device, }; static int __init jz_platform_init(void) diff --git a/target/linux/xburst/files-2.6.31/drivers/power/jz_battery.c b/target/linux/xburst/files-2.6.31/drivers/power/jz4740-battery.c old mode 100755 new mode 100644 similarity index 71% rename from target/linux/xburst/files-2.6.31/drivers/power/jz_battery.c rename to target/linux/xburst/files-2.6.31/drivers/power/jz4740-battery.c index 2d74d75a9..de1f4e2d8 --- a/target/linux/xburst/files-2.6.31/drivers/power/jz_battery.c +++ b/target/linux/xburst/files-2.6.31/drivers/power/jz4740-battery.c @@ -1,6 +1,4 @@ /* - * linux/drivers/power/jz_battery - * * Battery measurement code for Ingenic JZ SOC. * * based on tosa_battery.c @@ -20,33 +18,35 @@ #include #include #include -#include +#include -#include +#include +#include -struct workqueue_struct *monitor_wqueue; -struct delayed_work bat_work; -struct mutex work_lock; +/*struct jz_battery {*/ + static int bat_status = POWER_SUPPLY_STATUS_DISCHARGING; + static struct jz_batt_info *pdata = 0; -static int bat_status = POWER_SUPPLY_STATUS_DISCHARGING; -static struct jz_batt_info *pdata = 0; + struct mutex work_lock; + + struct workqueue_struct *monitor_wqueue; + struct delayed_work bat_work; +/*};*/ -extern unsigned int jz_read_battery(void); /********************************************************************* * Power *********************************************************************/ static int jz_get_power_prop(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) + enum power_supply_property psp, + union power_supply_propval *val) { + int gpio = (psy->type == POWER_SUPPLY_TYPE_MAINS) ? pdata->dc_dect_gpio : + pdata->usb_dect_gpio; switch (psp) { case POWER_SUPPLY_PROP_ONLINE: - if (psy->type == POWER_SUPPLY_TYPE_MAINS) - val->intval = !gpio_get_value(pdata->dc_dect_gpio); - else - val->intval = !!gpio_get_value(pdata->usb_dect_gpio); + val->intval = !gpio_get_value(gpio); break; default: return -EINVAL; @@ -80,33 +80,40 @@ static struct power_supply jz_usb = { * Battery properties *********************************************************************/ -static unsigned long jz_read_bat(struct power_supply *bat_ps) +static long jz_read_bat(struct power_supply *bat_ps) { - unsigned long val; - if (CFG_PBAT_DIV == 1) - val = (((unsigned long long)jz_read_battery() * 7500000L) >> 12) + 33000L; + enum jz_adc_battery_scale scale; + if (pdata->max_voltag > 2500000) + scale = JZ_ADC_BATTERY_SCALE_7V5; else - val = ((unsigned long long)jz_read_battery() * CFG_PBAT_DIV * 2500000L) >> 12; - dev_dbg(bat_ps->dev, "%s: raw_batter_vol = %d uV\n",__func__,val); - return val; + scale = JZ_ADC_BATTERY_SCALE_2V5; + + return jz4740_adc_read_battery_voltage(bat_ps->dev->parent->parent, scale); } static int jz_bat_get_capacity(struct power_supply *bat_ps) { int ret; - ret = (jz_read_bat(bat_ps) - pdata->min_voltag) * 100 + + ret = jz_read_bat(bat_ps); + + if (ret < 0) + return ret; + + ret = (ret - pdata->min_voltag) * 100 / (pdata->max_voltag - pdata->min_voltag); - if (ret > 100) { - dev_warn(bat_ps->dev, "%s: capacity=%d which exceeds 100," - "set to 100\n", __func__, ret); + + if (ret > 100) ret = 100; - } + else if (ret < 0) + ret = 0; + return ret; } static int jz_bat_get_property(struct power_supply *bat_ps, - enum power_supply_property psp, - union power_supply_propval *val) + enum power_supply_property psp, + union power_supply_propval *val) { switch (psp) { case POWER_SUPPLY_PROP_STATUS: @@ -116,7 +123,7 @@ static int jz_bat_get_property(struct power_supply *bat_ps, val->intval = pdata->batt_tech; break; case POWER_SUPPLY_PROP_HEALTH: - if(jz_read_bat(bat_ps) < JZ_BAT_MIN_VOLTAGE) { + if(jz_read_bat(bat_ps) < pdata->min_voltag) { dev_dbg(bat_ps->dev, "%s: battery is dead," "voltage too low!\n", __func__); val->intval = POWER_SUPPLY_HEALTH_DEAD; @@ -128,11 +135,13 @@ static int jz_bat_get_property(struct power_supply *bat_ps, break; case POWER_SUPPLY_PROP_CAPACITY: val->intval = jz_bat_get_capacity(bat_ps); - dev_dbg(bat_ps->dev, "%s: battery_capacity = %d\%\n", + dev_dbg(bat_ps->dev, "%s: battery_capacity = %d\n", __func__, val->intval); break; case POWER_SUPPLY_PROP_VOLTAGE_NOW: val->intval = jz_read_bat(bat_ps); + if (val->intval < 0) + return val->intval; break; case POWER_SUPPLY_PROP_VOLTAGE_MAX: case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: @@ -153,7 +162,7 @@ static int jz_bat_get_property(struct power_supply *bat_ps, static void jz_bat_external_power_changed(struct power_supply *bat_ps) { cancel_delayed_work(&bat_work); - queue_delayed_work(monitor_wqueue, &bat_work, HZ/10); + queue_delayed_work(monitor_wqueue, &bat_work, HZ / 8); } static char *status_text[] = { @@ -170,7 +179,7 @@ static void jz_bat_update(struct power_supply *bat_ps) unsigned long batt_vol = jz_read_bat(bat_ps); mutex_lock(&work_lock); - if(!gpio_get_value(pdata->charg_stat_pgio)) + if(!gpio_get_value(pdata->charg_stat_gpio)) bat_status = POWER_SUPPLY_STATUS_CHARGING; else bat_status = POWER_SUPPLY_STATUS_NOT_CHARGING; @@ -179,7 +188,7 @@ static void jz_bat_update(struct power_supply *bat_ps) __func__, status_text[bat_status]); if ((old_status != bat_status) || - (old_batt_vol - batt_vol > 50000)) { + (old_batt_vol - batt_vol > 50000)) { dev_dbg(bat_ps->dev, "%s %s -> %s\n", bat_ps->name, status_text[old_status], @@ -243,7 +252,7 @@ static int jz_bat_resume(struct platform_device *dev) #define jz_bat_resume NULL #endif -static int __devinit jz_bat_probe(struct platform_device *dev) +static int __devinit jz_bat_probe(struct platform_device *pdev) { int ret = 0; @@ -251,23 +260,23 @@ static int __devinit jz_bat_probe(struct platform_device *dev) mutex_init(&work_lock); INIT_DELAYED_WORK(&bat_work, jz_bat_work); - if (!dev->dev->platform_data) { - dev_error(&dev->dev, "Please set battery info\n"); + if (!pdev->dev.platform_data) { + dev_err(&pdev->dev, "Please set battery info\n"); return -EINVAL; } - pdata = dev->dev->platform_data; + pdata = pdev->dev.platform_data; if (gpio_is_valid(pdata->dc_dect_gpio)) { ret = gpio_request(pdata->dc_dect_gpio, "AC/DC DECT"); if (ret) { - dev_err(dev->dev, "ac/dc dect gpio request failed.\n"); + dev_err(&pdev->dev, "ac/dc dect gpio request failed.\n"); goto err_dc_gpio_request; } ret = gpio_direction_input(pdata->dc_dect_gpio); if (ret) { - dev_err(dev->dev, "ac/dc dect gpio direction failed.\n"); + dev_err(&pdev->dev, "ac/dc dect gpio direction failed.\n"); goto err_dc_gpio_direction; } @@ -276,13 +285,13 @@ static int __devinit jz_bat_probe(struct platform_device *dev) if (gpio_is_valid(pdata->usb_dect_gpio)) { ret = gpio_request(pdata->usb_dect_gpio, "USB DECT"); if (ret) { - dev_err(dev->dev, "usb dect gpio request failed.\n"); + dev_err(&pdev->dev, "usb dect gpio request failed.\n"); goto err_usb_gpio_request; } ret = gpio_direction_input(pdata->usb_dect_gpio); if (ret) { - dev_err(dev->dev, "usb dect gpio set direction failed.\n"); + dev_err(&pdev->dev, "usb dect gpio set direction failed.\n"); goto err_usb_gpio_direction; } @@ -293,34 +302,34 @@ static int __devinit jz_bat_probe(struct platform_device *dev) if (gpio_is_valid(pdata->charg_stat_gpio)) { ret = gpio_request(pdata->charg_stat_gpio, "CHARG STAT"); if (ret) { - dev_err(dev->dev, "charger state gpio request failed.\n"); + dev_err(&pdev->dev, "charger state gpio request failed.\n"); goto err_charg_gpio_request; } - ret = gpio_direction_input(pdata->charg_stat_pgio); + ret = gpio_direction_input(pdata->charg_stat_gpio); if (ret) { - dev_err(dev->dev, "charger state gpio set direction failed.\n"); + dev_err(&pdev->dev, "charger state gpio set direction failed.\n"); goto err_charg_gpio_direction; } } - ret = power_supply_register(&dev->dev, &jz_ac); + ret = power_supply_register(&pdev->dev, &jz_ac); if (ret) { - dev_err(dev->dev, "power supply ac/dc register failed.\n"); + dev_err(&pdev->dev, "power supply ac/dc register failed.\n"); goto err_power_register_ac; } - - ret = power_supply_register(&dev->dev, &jz_usb); + + ret = power_supply_register(&pdev->dev, &jz_usb); if (ret) { - dev_err(dev->dev, "power supply usb register failed.\n"); + dev_err(&pdev->dev, "power supply usb register failed.\n"); goto err_power_register_usb; } - ret = power_supply_register(&dev->dev, &bat_ps); + ret = power_supply_register(&pdev->dev, &bat_ps); if (ret) { - dev_err(dev->dev, "power supply battery register failed.\n"); + dev_err(&pdev->dev, "power supply battery register failed.\n"); goto err_power_register_bat; } - + if (!ret) { monitor_wqueue = create_singlethread_workqueue("jz_battery"); if (!monitor_wqueue) { @@ -337,57 +346,58 @@ err_power_register_usb: power_supply_unregister(&jz_ac); err_power_register_ac: err_charg_gpio_direction: - gpio_free(pdata->charg_stat_pgio); + gpio_free(pdata->charg_stat_gpio); err_charg_gpio_request: err_usb_gpio_direction: gpio_free(pdata->usb_dect_gpio); err_usb_gpio_request: err_dc_gpio_direction: gpio_free(pdata->dc_dect_gpio); -err_err_dc_gpio_request: +err_dc_gpio_request: return ret; } static int __devexit jz_bat_remove(struct platform_device *dev) { if (pdata) { - if (gpio_is_valid(pdata->dc_dct_gpio)) - gpio_free(pdata->dc_dect_gpio); - if (gpio_is_valid(pdata->usb_dect_gpio)) - gpio_free(pdata->usb_dect_pgio); - if (gpio_is_valid(pdata->charg_stat_gpio)) - gpio_free(pdata->charg_stat_gpio); + if (gpio_is_valid(pdata->dc_dect_gpio)) + gpio_free(pdata->dc_dect_gpio); + if (gpio_is_valid(pdata->usb_dect_gpio)) + gpio_free(pdata->usb_dect_gpio); + if (gpio_is_valid(pdata->charg_stat_gpio)) + gpio_free(pdata->charg_stat_gpio); } power_supply_unregister(&bat_ps); power_supply_unregister(&jz_ac); power_supply_unregister(&jz_usb); + return 0; } static struct platform_driver jz_bat_driver = { - .driver.name = "jz-battery", - .driver.owner = THIS_MODULE, .probe = jz_bat_probe, .remove = __devexit_p(jz_bat_remove), .suspend = jz_bat_suspend, .resume = jz_bat_resume, + .driver = { + .name = "jz4740-battery", + .owner = THIS_MODULE, + }, }; static int __init jz_bat_init(void) { - platform_device_register_simple("jz-battery", 0, NULL, 0); return platform_driver_register(&jz_bat_driver); } +module_init(jz_bat_init); static void __exit jz_bat_exit(void) { platform_driver_unregister(&jz_bat_driver); } - -module_init(jz_bat_init); module_exit(jz_bat_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Marek Vasut "); -MODULE_DESCRIPTION("Palm T|X battery driver"); +MODULE_AUTHOR("Jiejing Zhang "); +MODULE_DESCRIPTION("JZ4720/JZ4740 SoC battery driver"); diff --git a/target/linux/xburst/files-2.6.31/include/linux/jz4740_batt.h b/target/linux/xburst/files-2.6.31/include/linux/power/jz4740-battery.h similarity index 89% rename from target/linux/xburst/files-2.6.31/include/linux/jz4740_batt.h rename to target/linux/xburst/files-2.6.31/include/linux/power/jz4740-battery.h index f801aed32..2bcd77283 100644 --- a/target/linux/xburst/files-2.6.31/include/linux/jz4740_batt.h +++ b/target/linux/xburst/files-2.6.31/include/linux/power/jz4740-battery.h @@ -12,8 +12,8 @@ * */ -#ifndef JZ4740_BATT_H -#define JZ4740_BATT_H +#ifndef __JZ4740_BATTERY_H +#define __JZ4740_BATTERY_H struct jz_batt_info { int dc_dect_gpio; /* GPIO port of DC charger detection */ @@ -22,6 +22,7 @@ struct jz_batt_info { int min_voltag; /* Mininal battery voltage in uV */ int max_voltag; /* Maximum battery voltage in uV */ - int batt_tech; /* Battery technoledge */ -}; + int batt_tech; /* Battery technology */ +}; + #endif diff --git a/target/linux/xburst/patches-2.6.31/100-battery.patch b/target/linux/xburst/patches-2.6.31/100-battery.patch index bbf5fb3eb..dfb59c931 100644 --- a/target/linux/xburst/patches-2.6.31/100-battery.patch +++ b/target/linux/xburst/patches-2.6.31/100-battery.patch @@ -2,14 +2,20 @@ diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index bdbc4f7..3942136 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig -@@ -103,4 +103,9 @@ config CHARGER_PCF50633 +@@ -103,4 +103,15 @@ config CHARGER_PCF50633 help Say Y to include support for NXP PCF50633 Main Battery Charger. -+config BATTERY_JZ -+ tristate "JZ battery" ++config BATTERY_JZ4740 ++ tristate "Ingenic JZ4720/JZ4740 battery" ++ depends on SOC_JZ4740 ++ depends on JZ4740_ADC + help -+ Say Y to enable support for the battery in JZ SOC. ++ Say Y to enable support for the battery on Ingenic JZ4720/JZ4740 based ++ boards. ++ ++ This driver can be build as a module. If so, the module will be ++ called jz4740-battery. + endif # POWER_SUPPLY diff --git a/drivers/power/Makefile b/drivers/power/Makefile @@ -20,4 +26,4 @@ index 380d17c..4eebbf5 100644 obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o -+obj-$(CONFIG_BATTERY_JZ) += jz_battery.o ++obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o