From 035e3ba750e10e8bb63b59e3fd138dcbe584b33e Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E5=BC=A0=E6=99=B4?= Date: Thu, 3 May 2012 13:50:32 +0800 Subject: [PATCH] rk30:sdk:Support wm8326 adc for low battery detection --- arch/arm/mach-rk30/board-rk30-sdk-wm8326.c | 26 +++++++++++++++++++ drivers/mfd/wm831x-core.c | 29 ++++++++++++++++++++++ drivers/power/Kconfig | 4 +++ 3 files changed, 59 insertions(+) diff --git a/arch/arm/mach-rk30/board-rk30-sdk-wm8326.c b/arch/arm/mach-rk30/board-rk30-sdk-wm8326.c index b7babb99f2a6..92e2480af09c 100755 --- a/arch/arm/mach-rk30/board-rk30-sdk-wm8326.c +++ b/arch/arm/mach-rk30/board-rk30-sdk-wm8326.c @@ -140,6 +140,27 @@ static int wm831x_mask_interrupt(struct wm831x *Wm831x) /*****************************************************************/ } +#ifdef CONFIG_WM8326_VBAT_LOW_DETECTION +static int wm831x_low_power_detection(struct wm831x *wm831x) +{ + wm831x_reg_write(wm831x,WM831X_AUXADC_CONTROL,0x803f); //open adc + wm831x_reg_write(wm831x,WM831X_AUXADC_CONTROL,0xd03f); + wm831x_reg_write(wm831x,WM831X_AUXADC_SOURCE,0x0001); + + wm831x_reg_write(wm831x,WM831X_COMPARATOR_CONTROL,0x0001); + wm831x_reg_write(wm831x,WM831X_COMPARATOR_1,0x2910); //set the low power is 3.4v + + wm831x_reg_write(wm831x,WM831X_INTERRUPT_STATUS_1_MASK,0x99ee); + wm831x_set_bits(wm831x,WM831X_SYSTEM_INTERRUPTS_MASK,0x0100,0x0000); + if (wm831x_reg_read(wm831x,WM831X_AUXADC_DATA)< 0x1900){ + printk("The vbat is too low.\n"); + wm831x_device_shutdown(wm831x); + } + return 0; +} +#endif + + int wm831x_post_init(struct wm831x *Wm831x) { struct regulator *dcdc; @@ -258,6 +279,11 @@ int wm831x_post_init(struct wm831x *Wm831x) udelay(100); wm831x_mask_interrupt(Wm831x); + + #ifdef CONFIG_WM8326_VBAT_LOW_DETECTION + wm831x_low_power_detection(Wm831x); + #endif + printk("wm831x_post_init end"); return 0; } diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index bb5016ad104e..4fc2b755a6e2 100755 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c @@ -28,6 +28,8 @@ #include #include +#include + /* Current settings - values are 2*2^(reg_val/4) microamps. These are * exported since they are used by multiple drivers. @@ -421,6 +423,15 @@ out: } EXPORT_SYMBOL_GPL(wm831x_auxadc_read); +#ifdef CONFIG_WM8326_VBAT_LOW_DETECTION +static irqreturn_t wm831x_vbatlo_irq(int irq, void *irq_data) +{ + rk28_send_wakeup_key(); + + return IRQ_HANDLED; +} +#endif + static irqreturn_t wm831x_auxadc_irq(int irq, void *irq_data) { struct wm831x *wm831x = irq_data; @@ -1617,14 +1628,32 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) if (ret != 0) goto err; + switch (parent) { + #ifdef CONFIG_WM8326_VBAT_LOW_DETECTION + case WM8326: + if (wm831x->irq_base) { + ret = request_threaded_irq(wm831x->irq_base + + WM831X_IRQ_AUXADC_DCOMP1, + NULL, wm831x_vbatlo_irq, IRQF_TRIGGER_RISING, + "dcomp1", wm831x); + } + if (ret < 0) + dev_err(wm831x->dev, "dcomp1 IRQ request failed: %d\n", + ret); + break; + #endif + + default: if (wm831x->irq_base) { ret = request_threaded_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, NULL, wm831x_auxadc_irq, 0, "auxadc", wm831x); + } if (ret < 0) dev_err(wm831x->dev, "AUXADC IRQ request failed: %d\n", ret); + } /* The core device is up, instantiate the subdevices. */ diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index a543004b34e1..caacf8bd6473 100755 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -325,4 +325,8 @@ config BATTERY_RK30_VOL3V8 config POWER_ON_CHARGER_DISPLAY bool "Support charger display" +config WM8326_VBAT_LOW_DETECTION + tristate "Support for WM8326 battery voltage detection." + default n + endif # POWER_SUPPLY -- 2.34.1