summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/input/keyboard/wmt_saradc.c
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/drivers/input/keyboard/wmt_saradc.c')
-rwxr-xr-xANDROID_3.4.5/drivers/input/keyboard/wmt_saradc.c718
1 files changed, 718 insertions, 0 deletions
diff --git a/ANDROID_3.4.5/drivers/input/keyboard/wmt_saradc.c b/ANDROID_3.4.5/drivers/input/keyboard/wmt_saradc.c
new file mode 100755
index 00000000..132f0ae0
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/keyboard/wmt_saradc.c
@@ -0,0 +1,718 @@
+/*++
+linux/drivers/input/keyboard/wmt_kpad.c
+
+Some descriptions of such software. Copyright (c) 2008 WonderMedia Technologies, Inc.
+
+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, see <http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/errno.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/wmt_saradc.h>
+#include <linux/suspend.h>
+
+
+/* #define COUNTTIMER */
+#ifdef COUNTTIMER
+unsigned int start_time;
+#endif
+
+/* Debug macros */
+#if 0
+#define DPRINTK(fmt, args...) printk(KERN_ALERT "[%s]: " fmt, __func__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+/* the shortest response time is 20 ms, original timeout (HZ/100)*100 */
+#define wmt_saradc_timeout ((HZ/100)*2)
+#define WMT_SARADC_FUNCTION_NUM 6
+#define SAMETIMES 2
+unsigned int HW_Hz;
+unsigned int SW_timeout;
+unsigned int INT_timeout;
+
+enum adc_func {
+ FUNC_KPAD,
+ FUNC_BAT,
+ FUNC_NONE,
+};
+unsigned int func = FUNC_NONE;
+
+/* SARADC battery */
+unsigned int BatteryCODE;
+static unsigned int bat_interval = 3;
+static struct delayed_work bat_work;
+
+static unsigned int wmt_saradc_codes[WMT_SARADC_FUNCTION_NUM] = {
+ [0] = KEY_VOLUMEUP,
+ [1] = KEY_VOLUMEDOWN,
+ [2] = KEY_BACK,
+ [3] = KEY_MENU,
+ [4] = KEY_HOME,
+ [5] = KEY_RESERVED,
+};
+
+/*high resolution timer */
+static struct hrtimer wmt_saradc_hrtimer;
+static struct input_dev *saradc_dev;
+
+static struct wmt_saradc_s saradc = {
+ .ref = 0,
+ .res = NULL,
+ .regs = NULL,
+ .irq = 0,
+};
+
+int count_sample_rate(unsigned APB_clock, int Hz)
+{
+ int temp_slot;
+ /* the Hz that we want */
+ temp_slot = APB_clock/(4096 * Hz); /* (APB clock/32)/ (128 * HZ)*/
+ return temp_slot;
+}
+
+static int saradc_sample_rate(unsigned ADC_clock, int Hz)
+{
+ int temp_slot;
+ /* the Hz that we want */
+ temp_slot = ADC_clock/(128 * Hz); /* ADC clock/ (128 * HZ)*/
+ return temp_slot;
+}
+
+int saradc_event_table(unsigned int eventcode)
+{
+ DPRINTK("eventcode = %d\n", eventcode);
+ if (eventcode >= 39 && eventcode <= 42)
+ return 0;
+ else if (eventcode >= 63 && eventcode <= 64)
+ return 1;
+ else if (eventcode >= 84 && eventcode <= 85)
+ return 2;
+ else if (eventcode >= 18 && eventcode <= 20)
+ return 3;
+ else if (eventcode == 0)
+ return 4;
+ else if (eventcode >= 29 && eventcode <= 31)
+ return 5;
+ else if (eventcode == 127)
+ return 5;
+ else
+ return 5;
+}
+
+static void wmt_saradc_hw_init(void)
+{
+ unsigned int auto_temp_slot;
+ //unsigned int APB_clk;
+ unsigned int ADC_clk;
+ DPRINTK("Start\n");
+
+ /*
+ * Turn on saradc clocks.
+ */
+ auto_pll_divisor(DEV_ADC, CLK_ENABLE, 0, 0);
+
+ /* Set the ADC clock to 4.8 MHz */
+ auto_pll_divisor(DEV_ADC, SET_DIV, 1, 4800);
+
+ /* Turn on SARADC controll power */
+ saradc.regs->Ctr0 &= ~PD;
+
+ /* Enable SARADC digital clock */
+ saradc.regs->Ctr0 |= DigClkEn;
+
+ /* Simply clean all previous saradc status. */
+ saradc.regs->Ctr0 |= (ClrIntADC | ClrIntTOut);
+ saradc.regs->Ctr1 |= ClrIntValDet;
+
+ if (((saradc.regs->Ctr2 & EndcIntStatus) == EndcIntStatus) ||
+ ((saradc.regs->Ctr2 & TOutStatus) == TOutStatus) ||
+ ((saradc.regs->Ctr2 & ValDetIntStatus) == ValDetIntStatus))
+ printk(KERN_ERR "[saradc] clear status failed! status = %x\n", saradc.regs->Ctr2);
+
+ /*Set Timeout Value*/
+ saradc.regs->Ctr0 &= 0xffff0000;
+ saradc.regs->Ctr0 |= TOutDly(0xffff);
+
+ /* get APB clock & count sample rate*/
+ ADC_clk = auto_pll_divisor(DEV_ADC, GET_FREQ, 0, 0);
+ DPRINTK("[%s] ADC_clk = %d\n", __func__, ADC_clk);
+ /* sample rate: 500 Hz , 1 ms/sample */
+ auto_temp_slot = saradc_sample_rate(ADC_clk, 500);
+#if 0
+ /* get APB clock & count sample rate*/
+ APB_clk = auto_pll_divisor(DEV_APB, GET_FREQ, 0, 0);
+ /* sample rate: 1000 Hz , 1 ms/sample */
+ auto_temp_slot = count_sample_rate(APB_clk, HW_Hz);
+ DPRINTK("[%s] APB_clk = %d\n", __func__, APB_clk);
+#endif
+ /*Set Sample Rate*/
+ saradc.regs->Ctr1 &= 0x0000ffff;
+ saradc.regs->Ctr1 |= (auto_temp_slot << 16);
+ DPRINTK("[%s] auto_temp_slot = %x ctr1: %x\n", __func__, auto_temp_slot, saradc.regs->Ctr1);
+ /* Set saradc as auto mode */
+ saradc.regs->Ctr0 |= AutoMode;
+
+ msleep(200);
+
+ /* Enable value changing interrupt and Buffer data valid */
+ saradc.regs->Ctr1 |= (ValDetIntEn | BufRd);
+ /* saradc.regs->Ctr0 |= TOutEn; */
+
+ DPRINTK("End\n");
+}
+
+enum hrtimer_restart wmt_saradc_timeout_hrtimer(struct hrtimer *timer)
+{
+ unsigned int SARCODE = 0xffff;
+ static unsigned int OLDCODE = 0xffff;
+ static int time, same;
+ static bool saradc_flag = 1; /* 0: report event state, 1: get SARCODE value state */
+ int new_event = -1;
+ static int pre_event = -1, button_press;
+ ktime_t ktime;
+ /* count timeout value */
+#ifdef COUNTTIMER
+ unsigned int end_time;
+ end_time = wmt_read_oscr();
+ printk(KERN_ERR "time = %d\n", (end_time - start_time)/3);
+#endif
+ ktime = ktime_set(0, SW_timeout * 1000);
+
+ DPRINTK("[%s] Start\n", __func__);
+ while ((saradc.regs->Ctr2 & EndcIntStatus) == 0)
+ ;
+ SARCODE = SARCode(saradc.regs->Ctr1);
+
+ if (saradc_flag && time < 10) {
+ if ((SARCODE/4 - OLDCODE/4) <= 1 || (SARCODE/4 - OLDCODE/4) >= -1) {
+ same++;
+ DPRINTK("time:%d SARCODE=%u SARCODE/4=%u, OLDCODE=%u, OLDCODE/4=%u, same=%d\n",
+ time, SARCODE, SARCODE/4, OLDCODE, OLDCODE/4, same);
+ if (same == SAMETIMES)
+ saradc_flag = 0; /* get the new event */
+ } else
+ same = 0;
+
+ DPRINTK("time:%d SARCODE=%u SARCODE/4=%u, OLDCODE=%u, OLDCODE/4=%u, same=%d\n",
+ time, SARCODE, SARCODE/4, OLDCODE, OLDCODE/4, same);
+ OLDCODE = SARCODE;
+ time++;
+
+ /* don't call timer when 10th get SARCODE or enough same time */
+ if (time < 10 && same != SAMETIMES) {
+ hrtimer_start(&wmt_saradc_hrtimer, ktime, HRTIMER_MODE_REL);
+ /* count timer from callback function to callback function */
+#ifdef COUNTTIMER
+ start_time = wmt_read_oscr();
+#endif
+ }
+ /* if not get stable SARCODE value in 10 times, report SARACODE is NONE event */
+ if (time == 10 && same != SAMETIMES) {
+ SARCODE = 508;
+ DPRINTK("time %d SARCODE %u", time, SARCODE);
+ }
+ }
+ if (time == 10 || saradc_flag == 0)
+ time = 0;
+
+ /* disable BufRd */
+ saradc.regs->Ctr1 &= ~BufRd;
+
+ new_event = saradc_event_table(SARCODE/4);
+
+ if (SARCODE == 0xffff) {
+ printk(KERN_ERR "Auto mode witn INT test fail\n");
+ /*Disable interrupt*/
+ saradc.regs->Ctr1 &= ~ValDetIntEn;
+ /* Clean all previous saradc status. */
+ saradc.regs->Ctr0 |= (ClrIntTOut | ClrIntADC);
+ saradc.regs->Ctr1 |= ClrIntValDet;
+ } else {
+ /*DPRINTK("Buf_rdata = %u Buf_rdata/4 = %u\n", data, data/4);*/
+ DPRINTK("SARCODE = %u SARCODE/4 = %u\n", SARCODE, SARCODE/4);
+ /*Disable interrupt*/
+ saradc.regs->Ctr1 &= ~ValDetIntEn;
+ /* Clean all previous saradc status. */
+ saradc.regs->Ctr0 |= (ClrIntTOut | ClrIntADC);
+ saradc.regs->Ctr1 |= ClrIntValDet;
+ }
+
+ if (saradc_flag == 0) {
+ /* switch other button means release button*/
+ if ((pre_event != new_event) && (SARCODE/4 != 127)) {
+ button_press = 0;
+ DPRINTK("Different event, pre_event = %d, new_event = %d\n", pre_event, new_event);
+ DPRINTK("WMT_ROW1_KEY_NUM release key = %d, event=%d\n", SARCODE/4, pre_event);
+ input_report_key(saradc_dev, wmt_saradc_codes[pre_event], 0); /* key is release*/
+ input_sync(saradc_dev);
+ }
+
+ if (SARCODE/4 == 127 || SARCODE/4 == 126) { /*Active Low*/
+ DPRINTK("WMT_ROW1_KEY_NUM release key = %d, event=%d\n", SARCODE/4, pre_event);
+ input_report_key(saradc_dev, wmt_saradc_codes[pre_event], 0); /* key is release*/
+ input_sync(saradc_dev);
+ button_press = 0;
+ } else {
+ if (button_press == 0) {
+ DPRINTK("new event = %d\n", new_event);
+ input_report_key(saradc_dev, wmt_saradc_codes[new_event], 1);/* key is press*/
+ input_sync(saradc_dev);
+ DPRINTK("saradc code = %d\n", wmt_saradc_codes[new_event]);
+ button_press = 1;
+ }
+ DPRINTK("WMT_ROW1_KEY_NUM keep press key = %d, event=%d\n", SARCODE/4, new_event);
+ }
+ pre_event = new_event;
+ saradc_flag = 1; /* report new event to Android, get new SARCODE */
+ same = 0;
+ }
+ saradc.regs->Ctr1 |= ValDetIntEn;
+ DPRINTK("[%s] End\n", __func__);
+ return HRTIMER_NORESTART; /* avoid to timer restart */
+}
+
+static irqreturn_t
+saradc_interrupt(int irq, void *dev_id)
+{
+ ktime_t ktime;
+ ktime = ktime_set(0, INT_timeout * 1000); /* ms */
+ DPRINTK("[%s] Start\n", __func__);
+ DPRINTK("status = %x\n", saradc.regs->Ctr2);
+ /* Disable interrupt */
+ /* disable_irq_nosync(saradc.irq);*/
+ saradc.regs->Ctr1 &= ~ValDetIntEn;
+
+ saradc.regs->Ctr1 |= BufRd;
+ /*
+ * Get saradc interrupt status and clean interrput source.
+ */
+
+ /* if (((saradc.regs->Ctr1 & ValDetIntEn) == ValDetIntEn) && */
+ if ((saradc.regs->Ctr2 & ValDetIntStatus) == ValDetIntStatus) {
+ /* clear value chaning interrupt */
+ saradc.regs->Ctr1 |= ClrIntValDet;
+ /* start hrtimer */
+ hrtimer_start(&wmt_saradc_hrtimer, ktime, HRTIMER_MODE_REL);
+
+ /* count timer from interrupt to callback function */
+#ifdef COUNTTIMER
+ start_time = wmt_read_oscr();
+#endif
+ }
+
+ if ((saradc.regs->Ctr2 & ValDetIntStatus) == ValDetIntStatus)
+ printk(KERN_ERR "[saradc] status clear failed!\n");
+
+
+ /* Enable interrupt */
+ /* saradc.regs->Ctr1 |= ValDetIntEn; // enable INT in wmt_saradc_timeout_timer*/
+ DPRINTK("[%s] End\n", __func__);
+ return IRQ_HANDLED;
+}
+
+
+static unsigned int saradc_read(void)
+{
+ int i;
+ int min=0xfff,max=0;
+ int total=0,val;
+
+ for(i=0; i < 7; i++){
+ while ((saradc.regs->Ctr2 & EndcIntStatus) == 0);
+
+ val = SARCode(saradc.regs->Ctr1);
+ //printk("%d--",val);
+
+ if(max < val) max = val;
+ if(min > val) min = val;
+ total +=val;
+ }
+ //printk("value %d\n",(total-max-min)/5);
+ return (total-max-min)/5;
+
+}
+
+/* Read SARADC BATTRTY CODE */
+unsigned int ReadBattery(void)
+{
+ return BatteryCODE;
+}
+EXPORT_SYMBOL_GPL(ReadBattery);
+
+/* Update SARCODE BATTERY CODE */
+static void WriteBattery(unsigned int value)
+{
+ BatteryCODE = value;
+}
+static void saradc_bat_handler(struct work_struct *work)
+{
+ unsigned int sarcode = 0xffff;
+
+ DPRINTK("Start\n");
+ /* disable value change interrupt */
+ saradc.regs->Ctr1 &= ~ValDetIntEn;
+ /* Switch to BATTERY channel and clear INT status */
+ saradc.regs->Ctr0 |= (AdcChSel | ClrIntADC | ClrIntTOut);
+ saradc.regs->Ctr1 |= (ClrIntValDet);
+ msleep(20);
+ //printk("bat:\n");
+ sarcode = saradc_read();
+ WriteBattery(sarcode/4);
+ DPRINTK("sarcode = %d\n", sarcode);
+ /* Switch to ADC channel */
+ saradc.regs->Ctr0 &= ~AdcChSel;
+ /* too early to clear status will cause interrupts */
+ msleep(5);
+ /* Switch to BATTERY channel and clear INT status */
+ saradc.regs->Ctr0 |= (ClrIntADC | ClrIntTOut);
+ saradc.regs->Ctr1 |= (ClrIntValDet);
+
+ /* enable value change interrupt */
+ saradc.regs->Ctr1 |= ValDetIntEn;
+
+ schedule_delayed_work(&bat_work, bat_interval*HZ);
+ DPRINTK("End\n\n\n");
+ return ;
+}
+
+static int saradc_open(struct input_dev *dev)
+{
+ int ret = 0;
+ unsigned int i;
+ DPRINTK("Start saradc.ref = %d\n", saradc.ref);
+
+ if (saradc.ref++) {
+ /* Return success, but not initialize again. */
+ DPRINTK("End 1 saradc.ref=%d\n", saradc.ref);
+ return 0;
+ }
+
+ if (func != FUNC_KPAD)
+ goto bat_init;
+
+ ret = request_irq(saradc.irq, saradc_interrupt, IRQF_DISABLED, "saradc", dev);
+
+ if (ret) {
+ printk(KERN_ERR "%s: Can't allocate irq %d\n", __func__, IRQ_TSC);
+ saradc.ref--;
+ free_irq(saradc.irq, dev);
+ goto saradc_open_out;
+ }
+
+ /* Init hr timer */
+ hrtimer_init(&wmt_saradc_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ wmt_saradc_hrtimer.function = &wmt_saradc_timeout_hrtimer;
+
+ /* Register an input event device. */
+ dev->name = "saradc",
+ dev->phys = "saradc",
+
+ /*
+ * Let kpad to implement key repeat.
+ */
+
+ set_bit(EV_KEY, dev->evbit);
+
+ for (i = 0; i < WMT_SARADC_FUNCTION_NUM; i++)
+ set_bit(wmt_saradc_codes[i], dev->keybit);
+
+
+ dev->keycode = wmt_saradc_codes;
+ dev->keycodesize = sizeof(unsigned int);
+ dev->keycodemax = WMT_SARADC_FUNCTION_NUM;
+
+ /*
+ * For better view of /proc/bus/input/devices
+ */
+ dev->id.bustype = 0;
+ dev->id.vendor = 0;
+ dev->id.product = 0;
+ dev->id.version = 0;
+
+ input_register_device(dev);
+
+bat_init:
+ if (func == FUNC_BAT) {
+ INIT_DELAYED_WORK(&bat_work,saradc_bat_handler);
+ schedule_delayed_work(&bat_work, HZ);
+ }
+
+ wmt_saradc_hw_init();
+
+ DPRINTK("End2\n");
+saradc_open_out:
+ DPRINTK("End3\n");
+ return ret;
+}
+
+static void saradc_close(struct input_dev *dev)
+{
+ DPRINTK("Start\n");
+ if (--saradc.ref) {
+ DPRINTK("End1\n");
+ return;
+ }
+
+ /* Free interrupt resource */
+ free_irq(saradc.irq, dev);
+
+ /*Disable clock*/
+ auto_pll_divisor(DEV_ADC, CLK_DISABLE, 0, 0);
+
+ /* Unregister input device driver */
+ input_unregister_device(dev);
+ DPRINTK("End2\n");
+}
+
+static int wmt_saradc_probe(struct platform_device *pdev)
+{
+ unsigned long base;
+ int ret = 0;
+ DPRINTK("Start\n");
+ saradc_dev = input_allocate_device();
+ if (saradc_dev == NULL) {
+ DPRINTK("End 1\n");
+ return -1;
+ }
+ /*
+ * Simply check resources parameters.
+ */
+ if (pdev->num_resources < 2 || pdev->num_resources > 3) {
+ ret = -ENODEV;
+ goto saradc_probe_out;
+ }
+
+ base = pdev->resource[0].start;
+
+ saradc.irq = pdev->resource[1].start;
+
+ saradc.regs = (struct saradc_regs_s *)ADC_BASE_ADDR;
+
+ if (!saradc.regs) {
+ ret = -ENOMEM;
+ goto saradc_probe_out;
+ }
+
+ saradc_dev->open = saradc_open,
+ saradc_dev->close = saradc_close,
+
+ saradc_open(saradc_dev);
+ DPRINTK("End2\n");
+saradc_probe_out:
+
+#ifndef CONFIG_SKIP_DRIVER_MSG
+ printk(KERN_INFO "WMT saradc driver initialized: %s\n",
+ (ret == 0) ? "ok" : "failed");
+#endif
+ DPRINTK("End3\n");
+ return ret;
+}
+
+static int wmt_saradc_remove(struct platform_device *pdev)
+{
+ DPRINTK("Start\n");
+ saradc_close(saradc_dev);
+
+ /*
+ * Free allocated resource
+ */
+ /*kfree(kpad.res);
+ kpad.res = NULL;
+
+ if (kpad.regs) {
+ iounmap(kpad.regs);
+ kpad.regs = NULL;
+ }*/
+
+ saradc.ref = 0;
+ saradc.irq = 0;
+
+ DPRINTK("End\n");
+ return 0;
+}
+
+static int wmt_saradc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ DPRINTK("Start\n");
+
+ switch (state.event) {
+ case PM_EVENT_SUSPEND:
+ /*Disable clock*/
+ auto_pll_divisor(DEV_ADC, CLK_DISABLE, 0, 0);
+ break;
+ case PM_EVENT_FREEZE:
+ case PM_EVENT_PRETHAW:
+
+ default:
+ break;
+ }
+
+ DPRINTK("End2\n");
+ return 0;
+}
+
+static int wmt_saradc_resume(struct platform_device *pdev)
+{
+ DPRINTK("Start\n");
+ wmt_saradc_hw_init();
+ DPRINTK("End\n");
+ return 0;
+}
+
+static struct platform_driver wmt_saradc_driver = {
+ .driver.name = "wmt-saradc",
+ .probe = &wmt_saradc_probe,
+ .remove = &wmt_saradc_remove,
+ .suspend = &wmt_saradc_suspend,
+ .resume = &wmt_saradc_resume
+};
+
+static struct resource wmt_saradc_resources[] = {
+ [0] = {
+ .start = ADC_BASE_ADDR,
+ .end = (ADC_BASE_ADDR + 0xFFFF),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TSC,
+ .end = IRQ_TSC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device wmt_saradc_device = {
+ .name = "wmt-saradc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(wmt_saradc_resources),
+ .resource = wmt_saradc_resources,
+};
+
+static int __init saradc_init(void)
+{
+ int ret;
+ int retval;
+ unsigned char buf[80];
+ int varlen = 80;
+ char *varname1 = "wmt.keypad.param";
+ char *varname2 = "wmt.battery.param";
+ char *p;
+ int temp = 0, enable_saradc = 0, function_sel = 0;
+
+ DPRINTK(KERN_ALERT "Start\n");
+ /*read keypad enable*/
+ retval = wmt_getsyspara(varname1, buf, &varlen);
+ if (retval == 0) {
+ sscanf(buf, "%X:%d:%d:%d", &temp, &HW_Hz, &INT_timeout, &SW_timeout);
+ enable_saradc = temp & 0xf;
+ function_sel = (temp >> 4) & 0xf;
+ printk(KERN_ALERT "wmt.keypad.param = %x:%d:%d:%d, enable = %x, function = %x\n",
+ temp, HW_Hz, INT_timeout, SW_timeout, enable_saradc, function_sel);
+
+ if (enable_saradc != 1 || function_sel != 1) {
+ printk(KERN_ALERT "Disable SARADC as keypad function!!\n");
+ goto bat;
+ } else if (enable_saradc == 1 && function_sel == 1)
+ printk(KERN_ALERT "HW_HZ = %d, INT_time = %d, SW_timeout = %d\n",
+ HW_Hz, INT_timeout, SW_timeout);
+ if ((HW_Hz == 0) || (INT_timeout == 0) || (SW_timeout == 0)) {
+ HW_Hz = 1000; /* 1000 Hz */
+ INT_timeout = 20000; /* 20 ms */
+ SW_timeout = 1000; /* 1 ms */
+ printk(KERN_ALERT "wmt.keypad.param isn't correct. Set the default value\n");
+ printk(KERN_ALERT "Default HW_HZ = %d, INT_time = %d, SW_timeout = %d\n",
+ HW_Hz, INT_timeout, SW_timeout);
+ }
+ func = FUNC_KPAD;
+ } else {
+ printk(KERN_ALERT "##Warning: \"wmt.keypad.param\" not find\n");
+ printk(KERN_ALERT "Default wmt.keypad.param = %x\n", temp);
+ //return -ENODEV;
+ }
+
+bat:
+ if (func != FUNC_KPAD) {
+ memset(buf, 0x00,sizeof(buf));
+ /* read battery enable, dev name and */
+ retval = wmt_getsyspara(varname2, buf, &varlen);
+ if (retval == 0) {
+ p = buf;
+ if(!strncmp(p,"saradc", 6)){
+ p = strchr(p,':');
+ if(p){
+ p++;
+ sscanf(p,"%d",&bat_interval);
+ }
+ printk("Bat ADC sample period = %ds\n", bat_interval);
+ func = FUNC_BAT;
+ }
+ }
+ }
+
+ if (func == FUNC_NONE) {
+ printk("SARADC not enable\n");
+ return -ENODEV;
+ }
+
+/* check saradc can switch freq.
+#ifdef CONFIG_CPU_FREQ
+ ret = cpufreq_register_notifier(&kpad_clock_nblock, \
+ CPUFREQ_TRANSITION_NOTIFIER);
+
+ if (ret) {
+ printk(KERN_ERR "Unable to register CPU frequency " \
+ "change notifier (%d)\n", ret);
+ }
+#endif
+*/
+ ret = platform_device_register(&wmt_saradc_device);
+ if (ret != 0) {
+ DPRINTK("End1 ret = %x\n", ret);
+ return -ENODEV;
+ }
+
+ ret = platform_driver_register(&wmt_saradc_driver);
+ DPRINTK("End2 ret = %x\n", ret);
+ return ret;
+}
+
+static void __exit saradc_exit(void)
+{
+ DPRINTK("Start\n");
+ platform_driver_unregister(&wmt_saradc_driver);
+ platform_device_unregister(&wmt_saradc_device);
+ DPRINTK("End\n");
+}
+
+module_init(saradc_init);
+module_exit(saradc_exit);
+
+MODULE_AUTHOR("WonderMedia Technologies, Inc.");
+MODULE_DESCRIPTION("WMT [generic saradc] driver");
+MODULE_LICENSE("GPL");