rk30&rk29: update adc drivers
authorkfx <kfx@rock-chips.com>
Tue, 27 Mar 2012 07:06:36 +0000 (15:06 +0800)
committerkfx <kfx@rock-chips.com>
Tue, 27 Mar 2012 07:06:36 +0000 (15:06 +0800)
drivers/adc/adc_priv.h [new file with mode: 0755]
drivers/adc/core.c
drivers/adc/plat/rk28_adc.c
drivers/adc/plat/rk28_adc.h
drivers/adc/plat/rk29_adc.c
drivers/adc/plat/rk29_adc.h
drivers/adc/plat/rk30_adc.c
drivers/adc/plat/rk30_adc.h
include/linux/adc.h

diff --git a/drivers/adc/adc_priv.h b/drivers/adc/adc_priv.h
new file mode 100755 (executable)
index 0000000..6ac01d5
--- /dev/null
@@ -0,0 +1,67 @@
+/* include/linux/adc.h\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License version 2 as\r
+ * published by the Free Software Foundation.\r
+ *\r
+*/\r
+\r
+#ifndef __ASM_ADC_PRIV_H\r
+#define __ASM_ADC_PRIV_H\r
+\r
+#include <linux/kernel.h>\r
+#include <linux/module.h>\r
+#include <linux/init.h>\r
+#include <linux/device.h>\r
+#include <linux/delay.h>\r
+#include <linux/slab.h>\r
+#include <linux/time.h>\r
+#include <linux/err.h>\r
+#include <linux/io.h>\r
+#include <linux/clk.h>\r
+#include <linux/interrupt.h>\r
+#include <mach/board.h>\r
+\r
+#define ADC_READ_TMO    100 // ms\r
+\r
+#define adc_writel                 writel_relaxed\r
+#define adc_readl                  readl_relaxed\r
+\r
+enum read_type{\r
+        ADC_SYNC_READ,\r
+        ADC_ASYNC_READ,\r
+};\r
+\r
+struct adc_request {\r
+        struct list_head entry;\r
+        struct adc_client *client;\r
+};\r
+struct adc_ops {\r
+       void (*start)(struct adc_host *);\r
+       void (*stop)(struct adc_host *);\r
+       int (*read)(struct adc_host *);\r
+};\r
+struct adc_host {\r
+        struct list_head entry;\r
+        struct list_head request_head;\r
+        unsigned int is_suspended;\r
+        enum host_chn_mask mask;\r
+        struct device *dev;\r
+        struct adc_client *cur;\r
+        spinlock_t lock;\r
+        unsigned int client_count;\r
+       const struct adc_ops *ops;\r
+        unsigned long priv[0];\r
+};\r
+\r
+static inline void *adc_priv(struct adc_host *adc)\r
+{\r
+       return adc->priv;\r
+}\r
+       \r
+struct adc_host *adc_alloc_host(struct device *dev, int extra, enum host_chn_mask mask);\r
+void adc_free_host(struct adc_host *adc);\r
+void adc_core_irq_handle(struct adc_host *adc);\r
+\r
+#endif\r
+\r
index e4bfb238af70c9a2a719201a361051332b389696..0c439b987bc54c291ca246840c36db29ce864e01 100755 (executable)
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License.
 */
-
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/completion.h>
-#include <linux/delay.h>
-#include <linux/err.h>
 #include <linux/adc.h>
-#include <linux/slab.h>
-
+#include "adc_priv.h"
 
-static struct adc_host *g_adc = NULL;
+struct list_head adc_host_head;
 
-struct adc_host *adc_alloc_host(int extra, struct device *dev)
+struct adc_host *adc_alloc_host(struct device *dev, int extra, enum host_chn_mask mask)
 {
        struct adc_host *adc;
        
        adc = kzalloc(sizeof(struct adc_host) + extra, GFP_KERNEL);
        if (!adc)
                return NULL;
+        adc->mask = mask;
        adc->dev = dev;
-       g_adc = adc;
+        spin_lock_init(&adc->lock);
+        INIT_LIST_HEAD(&adc->request_head);
+
+        list_add_tail(&adc->entry, &adc_host_head);
+
        return adc;
 }
-EXPORT_SYMBOL(adc_alloc_host);
+
 void adc_free_host(struct adc_host *adc)
 {
+        list_del(&adc->entry);
        kfree(adc);
        adc = NULL;
        return;
 }
-EXPORT_SYMBOL(adc_free_host);
-
 
 struct adc_client *adc_register(int chn,
                                void (*callback)(struct adc_client *, void *, int), 
                                void *callback_param)
-{
-       struct adc_client *client;
-       if(!g_adc)
-       {
-               printk(KERN_ERR "adc host has not initialized\n");
-               return NULL;
-       }
-       if(chn >= MAX_ADC_CHN)
-       {
-               dev_err(g_adc->dev, "channel[%d] is greater than the maximum[%d]\n", chn, MAX_ADC_CHN);
-               return NULL;
-       }
-       client = kzalloc(sizeof(struct adc_client), GFP_KERNEL);
-       if(!client)
-       {
-               dev_err(g_adc->dev, "no memory for adc client\n");
-               return NULL;
-       }
-       client->callback = callback;
-       client->callback_param = callback_param;
-       client->chn = chn;
-
-       client->adc = g_adc;
 
-       return client;
+{
+        struct adc_client *client = NULL;
+        struct adc_host *adc = NULL;
+
+        list_for_each_entry(adc, &adc_host_head, entry) {
+                if((chn == 0 && adc->mask == SARADC_CHN_MASK) ||
+                (chn & adc->mask)){
+                       client = kzalloc(sizeof(struct adc_client), GFP_KERNEL);
+                        if(!client)
+                                return NULL;
+                       client->callback = callback;
+                       client->callback_param = callback_param;
+                       client->chn = chn;
+                       client->adc = adc;
+                        client->index = adc->client_count;
+                        init_waitqueue_head(&client->wait);
+                        adc->client_count++;
+
+                        return client;
+                }
+        }
+        dev_err(adc->dev, "chn(%d) is not support\n", chn);
+        return NULL;
 }
-EXPORT_SYMBOL(adc_register);
 
 void adc_unregister(struct adc_client *client)
 {
+        struct adc_host *adc = client->adc;
+
+        adc->client_count--;
        kfree(client);
        client = NULL;
        return;
 }
-EXPORT_SYMBOL(adc_unregister);
-
 
-static void trigger_next_adc_job_if_any(struct adc_host *adc)
+static inline void trigger_next_adc_job_if_any(struct adc_host *adc)
 {
-       int head = adc->queue_head;
+        struct adc_request *req = NULL;
+
+        if(list_empty(&adc->request_head))
+                return;
+
+        req = list_first_entry(&adc->request_head, struct adc_request, entry);
 
-       if (!adc->queue[head])
-               return;
-       adc->cur = adc->queue[head]->client;
+        if(req == NULL)
+                return;
+        list_del(&req->entry);
+       adc->cur = req->client;
+       kfree(req);
        adc->ops->start(adc);
        return;
 }
-
-static int
-adc_enqueue_request(struct adc_host *adc, struct adc_request *req)
+static int adc_request_add(struct adc_host *adc, struct adc_client *client)
 {
-       int head, tail;
-       unsigned long flags;
-       
-       spin_lock_irqsave(&adc->lock, flags);
-       head = adc->queue_head;
-       tail = adc->queue_tail;
+        struct adc_request *req = NULL;
 
-       if (adc->queue[tail]) {
-               spin_unlock_irqrestore(&adc->lock,flags);
-               dev_err(adc->dev, "ADC queue is full, dropping request\n");
-               return -EBUSY;
-       }
+        list_for_each_entry(req, &adc->request_head, entry) {
+                if(req->client->index == client->index)
+                        return 0;
+        }
+        req = kzalloc(sizeof(struct adc_request), GFP_KERNEL);
 
-       adc->queue[tail] = req;
-       if (head == tail)
-               trigger_next_adc_job_if_any(adc);
-       adc->queue_tail = (tail + 1) & (MAX_ADC_FIFO_DEPTH - 1);
+        if(!req)
+                return -ENOMEM;
+        req->client = client;
+        list_add_tail(&req->entry, &adc->request_head);
 
-       spin_unlock_irqrestore(&adc->lock,flags);
+        trigger_next_adc_job_if_any(adc);
 
-       return 0;
+        return 0;
 }
-
 static void
 adc_sync_read_callback(struct adc_client *client, void *param, int result)
 {
-       struct adc_request *req = param;
+        client->result = result;
+}
+void adc_core_irq_handle(struct adc_host *adc)
+{
+        int result = adc->ops->read(adc);
 
-       client->result = result;
-       complete(&req->completion);
+        adc->ops->stop(adc);
+        adc->cur->callback(adc->cur, adc->cur->callback_param, result);
+        adc_sync_read_callback(adc->cur, NULL, result);
+        adc->cur->is_finished = 1;
+        wake_up(&adc->cur->wait);
+
+        trigger_next_adc_job_if_any(adc);
 }
 
-int adc_sync_read(struct adc_client *client)
+int adc_host_read(struct adc_client *client, enum read_type type)
 {
-       struct adc_request *req = NULL;
-       int err, tmo, tail;
+        int tmo;
+       unsigned long flags;
+        struct adc_host *adc = NULL;
 
        if(client == NULL) {
-               printk(KERN_ERR "client point is NULL");
+               printk(KERN_ERR "client is NULL");
                return -EINVAL;
        }
-       if(client->adc->is_suspended == 1) {
-               dev_dbg(client->adc->dev, "system enter sleep\n");
-               return -1;
-       }
-       req = kzalloc(sizeof(*req), GFP_ATOMIC);
-       if (!req){
-               dev_err(client->adc->dev, "no memory for adc request\n");
-               return -ENOMEM;
-       }
-       req->chn = client->chn;
-       req->callback =  adc_sync_read_callback;
-       req->callback_param = req;
-       req->client = client;
-       req->status = SYNC_READ;
-
-       init_completion(&req->completion);
-       err = adc_enqueue_request(client->adc, req);
-       if (err)
-       {
-               dev_err(client->adc->dev, "fail to enqueue request\n");
-               kfree(req);
-               return err;
-       }
-       tmo = wait_for_completion_timeout(&req->completion,msecs_to_jiffies(100));
-       kfree(req);
-       req = NULL;
-       if(tmo == 0) {
-               tail = (client->adc->queue_tail - 1) & (MAX_ADC_FIFO_DEPTH - 1);
-               client->adc->queue[tail] = NULL;
-               client->adc->queue_tail = tail;
-               return -ETIMEDOUT;
+        adc = client->adc;
+       if(adc->is_suspended == 1) {
+               dev_dbg(adc->dev, "system enter sleep\n");
+               return -EIO;
        }
-       return client->result;
+
+       spin_lock_irqsave(&adc->lock, flags);
+        adc_request_add(adc, client);
+        client->is_finished = 0;
+       spin_unlock_irqrestore(&adc->lock, flags);
+
+        if(type == ADC_ASYNC_READ)
+                return 0;
+
+        tmo = wait_event_timeout(client->wait, ( client->is_finished == 1 ), msecs_to_jiffies(ADC_READ_TMO));
+        if(tmo <= 0) {
+                adc->ops->stop(adc);
+                dev_dbg(adc->dev, "get adc value timeout\n");
+                return -ETIMEDOUT;
+        } 
+
+        return client->result;
+}
+
+int adc_sync_read(struct adc_client *client)
+{
+        return adc_host_read(client, ADC_SYNC_READ);
 }
-EXPORT_SYMBOL(adc_sync_read);
 
 int adc_async_read(struct adc_client *client)
 {
-       int ret = 0;
-       struct adc_request *req = NULL;
-       
-       if(client == NULL) {
-               printk(KERN_ERR "client point is NULL");
-               return -EINVAL;
-       }
-       if(client->adc->is_suspended == 1) {
-               dev_dbg(client->adc->dev, "system enter sleep\n");
-               return -1;
-       }
-       req = kzalloc(sizeof(*req), GFP_ATOMIC);
-       if (!req) {
-               dev_err(client->adc->dev, "no memory for adc request\n");
-               return -ENOMEM;
-       }
-       req->chn = client->chn;
-       req->callback = client->callback;
-       req->callback_param = client->callback_param;
-       req->client = client;
-       req->status = ASYNC_READ;
+        return adc_host_read(client, ADC_ASYNC_READ);
+}
 
-       ret = adc_enqueue_request(client->adc, req);
-       if(ret < 0)
-               kfree(req);
 
-       return ret;
+static int __init adc_core_init(void)
+{
+        INIT_LIST_HEAD(&adc_host_head);
+        return 0;
 }
-EXPORT_SYMBOL(adc_async_read);
+subsys_initcall(adc_core_init);
 
-void adc_core_irq_handle(struct adc_host *adc)
+static void __exit adc_core_exit(void)
 {
-       struct adc_request *req;
-       int head, res;
-       spin_lock(&adc->lock);
-       head = adc->queue_head;
-
-       req = adc->queue[head];
-       if (WARN_ON(!req)) {
-               spin_unlock(&adc->lock);
-               dev_err(adc->dev, "adc irq: ADC queue empty!\n");
-               return;
-       }
-       adc->queue[head] = NULL;
-       adc->queue_head = (head + 1) & (MAX_ADC_FIFO_DEPTH - 1);
-       
-       res = adc->ops->read(adc);
-       adc->ops->stop(adc);
-       trigger_next_adc_job_if_any(adc);
-
-       req->callback(adc->cur, req->callback_param, res);
-       if(req->status == ASYNC_READ) {
-               kfree(req);
-               req = NULL;
-       }
-       spin_unlock(&adc->lock);
+        return;
 }
-EXPORT_SYMBOL(adc_core_irq_handle);
+module_exit(adc_core_exit);  
 
 
index e17f01179e17c16fe6cd85a806da100334820245..e5ac7a35c1a3b3ed3780e81e446ac300a69a29c3 100755 (executable)
@@ -4,19 +4,9 @@
  * it under the terms of the GNU General Public License as published by\r
  * the Free Software Foundation; either version 2 of the License.\r
 */\r
-#include <linux/kernel.h>\r
-#include <linux/module.h>\r
-#include <linux/init.h>\r
-#include <linux/device.h>\r
-#include <linux/platform_device.h>\r
-#include <linux/err.h>\r
-#include <linux/clk.h>\r
-#include <linux/interrupt.h>\r
-#include <linux/io.h>\r
 #include <linux/adc.h>\r
-#include <linux/delay.h>\r
-\r
 \r
+#include "../adc_priv.h"\r
 #include "rk28_adc.h"\r
 \r
 //#define ADC_TEST\r
@@ -91,12 +81,9 @@ static int rk28_adc_probe(struct platform_device *pdev)
        struct resource *res;\r
        int ret;\r
 \r
-       adc = adc_alloc_host(sizeof(struct rk28_adc_device), &pdev->dev);\r
+       adc = adc_alloc_host(&pdev->dev, sizeof(struct rk28_adc_device), SARADC_CHN_MASK);\r
        if (!adc)\r
                return -ENOMEM;\r
-       mutex_init(&adc->queue_mutex);\r
-       adc->dev = &pdev->dev;\r
-       adc->is_suspended = 0;\r
        adc->ops = &rk28_adc_ops;\r
        dev = adc_priv(adc);\r
        dev->adc = adc;\r
@@ -151,8 +138,6 @@ static int rk28_adc_probe(struct platform_device *pdev)
        rk28_adc_test();\r
 #endif\r
        return 0;\r
-// err_iomap:\r
-//     iounmap(dev->regs);\r
 \r
  err_ioarea:\r
        release_resource(dev->ioarea);\r
index ccd8daf062b9d96f808ae4f88edf451319abce03..9de0f796f81bba3e83cb11688f2c8ea80e09273a 100755 (executable)
@@ -16,7 +16,7 @@
 #define ADC_STAS_BUSY          (1<<0)
 
 #define ADC_CTRL                       0x08
-#define ADC_CTRL_CH(ch)                ((ch)<<0)
+#define ADC_CTRL_CH(ch)                (ch >> SARADC_CHN_SHIFT)
 #define ADC_CTRL_POWER_UP      (1<<3)
 #define ADC_CTRL_START         (1<<4)
 #define ADC_CTRL_IRQ_ENABLE    (1<<5)
index 1b52850715beae98679c73463ceab7a32f1403be..db45d1b8d6b4d3f753b61e312d3a88c641a9b535 100755 (executable)
@@ -4,20 +4,9 @@
  * it under the terms of the GNU General Public License as published by\r
  * the Free Software Foundation; either version 2 of the License.\r
 */\r
-#include <linux/kernel.h>\r
-#include <linux/module.h>\r
-#include <linux/init.h>\r
-#include <linux/device.h>\r
-#include <linux/platform_device.h>\r
-#include <linux/err.h>\r
-#include <linux/clk.h>\r
-#include <linux/interrupt.h>\r
-#include <linux/io.h>\r
 #include <linux/adc.h>\r
-#include <linux/delay.h>\r
-#include <linux/slab.h>\r
-\r
 \r
+#include "../adc_priv.h"\r
 #include "rk29_adc.h"\r
 \r
 //#define ADC_TEST\r
@@ -121,12 +110,9 @@ static int rk29_adc_probe(struct platform_device *pdev)
        struct resource *res;\r
        int ret;\r
 \r
-       adc = adc_alloc_host(sizeof(struct rk29_adc_device), &pdev->dev);\r
+       adc = adc_alloc_host(&pdev->dev, sizeof(struct rk29_adc_device), SARADC_CHN_MASK);\r
        if (!adc)\r
                return -ENOMEM;\r
-       spin_lock_init(&adc->lock);\r
-       adc->dev = &pdev->dev;\r
-       adc->is_suspended = 0;\r
        adc->ops = &rk29_adc_ops;\r
        dev = adc_priv(adc);\r
        dev->adc = adc;\r
@@ -178,8 +164,6 @@ static int rk29_adc_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, dev);\r
        dev_info(&pdev->dev, "rk29 adc: driver initialized\n");\r
        return 0;\r
-// err_iomap:\r
-//     iounmap(dev->regs);\r
 \r
  err_ioarea:\r
        release_resource(dev->ioarea);\r
index 7164c087644b187dfe39d38b818370379fb2327b..94825da2d0887402b792306cf9ff3d0d8541a3de 100755 (executable)
@@ -16,7 +16,7 @@
 #define ADC_STAS_BUSY          (1<<0)
 
 #define ADC_CTRL                       0x08
-#define ADC_CTRL_CH(ch)                (0x07 - ((ch)<<0))
+#define ADC_CTRL_CH(ch)                (0x07 - ((ch >> SARADC_CHN_SHIFT)<<0))
 #define ADC_CTRL_POWER_UP      (1<<3)
 #define ADC_CTRL_START         (1<<4)
 #define ADC_CTRL_IRQ_ENABLE    (1<<5)
index fbc81f3e1ad1e404de46a782b099a56eebfdda48..d4dd046de847b17f1f4d09f13782b6799ff35ee8 100755 (executable)
@@ -4,26 +4,15 @@
  * it under the terms of the GNU General Public License as published by\r
  * the Free Software Foundation; either version 2 of the License.\r
 */\r
-#include <linux/kernel.h>\r
-#include <linux/module.h>\r
-#include <linux/init.h>\r
-#include <linux/device.h>\r
-#include <linux/platform_device.h>\r
-#include <linux/err.h>\r
-#include <linux/clk.h>\r
-#include <linux/interrupt.h>\r
-#include <linux/io.h>\r
 #include <linux/adc.h>\r
-#include <linux/delay.h>\r
-#include <linux/slab.h>\r
-\r
 \r
+#include "../adc_priv.h"\r
 #include "rk30_adc.h"\r
 \r
 //#define ADC_TEST\r
 \r
 struct rk30_adc_device {\r
-       int                                     irq;\r
+       int                      irq;\r
        void __iomem            *regs;\r
        struct clk *            clk;\r
        struct resource         *ioarea;\r
@@ -34,9 +23,9 @@ static void rk30_adc_start(struct adc_host *adc)
        struct rk30_adc_device *dev  = adc_priv(adc);\r
        int chn = adc->cur->chn;\r
 \r
-       writel(0, dev->regs + ADC_CTRL);\r
-        writel(0x08, dev->regs + ADC_DELAY_PU_SOC);\r
-       writel(ADC_CTRL_POWER_UP|ADC_CTRL_CH(chn)|ADC_CTRL_IRQ_ENABLE, dev->regs + ADC_CTRL);\r
+       adc_writel(0, dev->regs + ADC_CTRL);\r
+        adc_writel(0x08, dev->regs + ADC_DELAY_PU_SOC);\r
+       adc_writel(ADC_CTRL_POWER_UP|ADC_CTRL_CH(chn)|ADC_CTRL_IRQ_ENABLE, dev->regs + ADC_CTRL);\r
 \r
        return;\r
 }\r
@@ -44,13 +33,13 @@ static void rk30_adc_stop(struct adc_host *adc)
 {\r
        struct rk30_adc_device *dev  = adc_priv(adc);\r
        \r
-       writel(0, dev->regs + ADC_CTRL);\r
+       adc_writel(0, dev->regs + ADC_CTRL);\r
 }\r
 static int rk30_adc_read(struct adc_host *adc)\r
 {\r
        struct rk30_adc_device *dev  = adc_priv(adc);\r
 \r
-       return readl(dev->regs + ADC_DATA) & ADC_DATA_MASK;\r
+       return adc_readl(dev->regs + ADC_DATA) & ADC_DATA_MASK;\r
 }\r
 static irqreturn_t rk30_adc_irq(int irq, void *data)\r
 {\r
@@ -77,11 +66,8 @@ static void callback(struct adc_client *client, void *param, int result)
 }\r
 static void adc_timer(unsigned long data)\r
 {\r
-       //int sync_read = 0;\r
         struct adc_test_data *test=(struct adc_test_data *)data;\r
        \r
-       //sync_read = adc_sync_read(test->client);\r
-       //dev_info(test->client->adc->dev, "[chn%d] sync_read = %d\n", 0, sync_read);\r
        schedule_work(&test->timer_work);\r
        add_timer(&test->timer);\r
 }\r
@@ -92,7 +78,7 @@ static void adc_timer_work(struct work_struct *work)
                                                timer_work);\r
        adc_async_read(test->client);\r
        sync_read = adc_sync_read(test->client);\r
-       dev_info(test->client->adc->dev, "[chn%d] sync_read = %d\n", 0, sync_read);\r
+       dev_info(test->client->adc->dev, "[chn%d] sync_read = %d\n", test->client->chn, sync_read);\r
 }\r
 \r
 static int rk30_adc_test(void)\r
@@ -101,10 +87,10 @@ static int rk30_adc_test(void)
 \r
        test = kzalloc(sizeof(struct adc_test_data), GFP_KERNEL);\r
        \r
-       test->client = adc_register(0, callback, NULL);\r
+       test->client = adc_register(1, callback, NULL);\r
        INIT_WORK(&test->timer_work, adc_timer_work);\r
        setup_timer(&test->timer, adc_timer, (unsigned long)test);\r
-       test->timer.expires  = jiffies + 100;\r
+       test->timer.expires  = jiffies + 1;\r
        add_timer(&test->timer);\r
        \r
        return 0;\r
@@ -119,12 +105,9 @@ static int rk30_adc_probe(struct platform_device *pdev)
        struct resource *res;\r
        int ret;\r
 \r
-       adc = adc_alloc_host(sizeof(struct rk30_adc_device), &pdev->dev);\r
+       adc = adc_alloc_host(&pdev->dev, sizeof(struct rk30_adc_device), SARADC_CHN_MASK);\r
        if (!adc)\r
                return -ENOMEM;\r
-       spin_lock_init(&adc->lock);\r
-       adc->dev = &pdev->dev;\r
-       adc->is_suspended = 0;\r
        adc->ops = &rk30_adc_ops;\r
        dev = adc_priv(adc);\r
        dev->adc = adc;\r
@@ -176,8 +159,6 @@ static int rk30_adc_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, dev);\r
        dev_info(&pdev->dev, "rk30 adc: driver initialized\n");\r
        return 0;\r
-// err_iomap:\r
-//     iounmap(dev->regs);\r
 \r
  err_ioarea:\r
        release_resource(dev->ioarea);\r
index 8160f49046cbd152264320699cced16436dd718e..e9961275b99362e8a80fed7ec917cfbc5c1fd3e8 100755 (executable)
@@ -17,7 +17,7 @@
 
 #define ADC_CTRL                       0x08
 #define ADC_DELAY_PU_SOC               0x0c
-#define ADC_CTRL_CH(ch)                (ch) //(0x07 - ((ch)<<0))
+#define ADC_CTRL_CH(ch)                (ch >> SARADC_CHN_SHIFT) //(0x07 - ((ch)<<0))
 #define ADC_CTRL_POWER_UP      (1<<3)
 #define ADC_CTRL_IRQ_ENABLE    (1<<5)
 #define ADC_CTRL_IRQ_STATUS    (1<<6)
index 22c781fbd3054cf9e6438756e6ca8edf7954d7c2..1b61b47106ab5f50353ff9b91d4bd4ed0ba6213a 100755 (executable)
@@ -9,69 +9,40 @@
 #ifndef __ASM_ADC_CORE_H\r
 #define __ASM_ADC_CORE_H\r
 \r
-#define MAX_ADC_CHN 4\r
-#define MAX_ADC_FIFO_DEPTH 8\r
+#include <linux/list.h>\r
+#include <linux/wait.h>\r
 \r
+enum host_chn_shift{\r
+        SARADC_CHN_SHIFT = 0,\r
+        CUSTOM_CHN_SHIFT = 28\r
+};\r
 \r
-struct adc_client {\r
-       int chn;\r
-       int time;\r
-       int result;\r
-       void (*callback)(struct adc_client *, void *, int);\r
-       void *callback_param;\r
-\r
-       struct adc_host *adc;\r
+enum host_chn_mask{\r
+        SARADC_CHN_MASK = 0x0000000f,  // saradc: 0 -- 15\r
+        CUSTOM_CHN_MASK = 0xf0000000,\r
 };\r
 \r
-struct adc_request {\r
-       int result;\r
-       int chn;\r
+struct adc_host;\r
+struct adc_client {\r
+        unsigned int index;\r
+        unsigned int chn;\r
+        unsigned int is_finished;\r
+        int result;\r
+       struct adc_host *adc;\r
+        struct list_head list;\r
+        wait_queue_head_t      wait;\r
        void (*callback)(struct adc_client *, void *, int);\r
        void *callback_param;\r
-       struct adc_client *client;\r
-       /* Used in case of sync requests */\r
-       struct completion completion;\r
-#define ASYNC_READ 0\r
-#define SYNC_READ 1\r
-       int status;\r
-};\r
-struct adc_host;\r
-struct adc_ops {\r
-       void (*start)(struct adc_host *);\r
-       void (*stop)(struct adc_host *);\r
-       int (*read)(struct adc_host *);\r
-};\r
-       \r
-       \r
-struct adc_host {\r
-       struct device *dev;\r
-       int is_suspended;\r
-       struct adc_request *queue[MAX_ADC_FIFO_DEPTH];\r
-       int queue_head;\r
-       int queue_tail;\r
-       spinlock_t                      lock;\r
-       struct adc_client *cur;\r
-       const struct adc_ops *ops;\r
-       unsigned long           private[0];\r
 };\r
-static inline void *adc_priv(struct adc_host *adc)\r
-{\r
-       return (void *)adc->private;\r
-}\r
-       \r
-extern struct adc_host *adc_alloc_host(int extra, struct device *dev);\r
-extern void adc_free_host(struct adc_host *adc);\r
-extern void adc_core_irq_handle(struct adc_host *adc);\r
-\r
 \r
 #ifdef CONFIG_ADC\r
-extern struct adc_client *adc_register(int chn,\r
+struct adc_client *adc_register(int chn,\r
                                void (*callback)(struct adc_client *, void *, int), \r
                                void *callback_param);\r
-extern void adc_unregister(struct adc_client *client);\r
+void adc_unregister(struct adc_client *client);\r
 \r
-extern int adc_sync_read(struct adc_client *client);\r
-extern int adc_async_read(struct adc_client *client);\r
+int adc_sync_read(struct adc_client *client);\r
+int adc_async_read(struct adc_client *client);\r
 #else\r
 static inline struct adc_client *adc_register(int chn,\r
                                void (*callback)(struct adc_client *, void *, int),\r
@@ -80,8 +51,8 @@ static inline struct adc_client *adc_register(int chn,
        return NULL;\r
 }\r
 static inline void adc_unregister(struct adc_client *client) {}\r
-static inline int adc_sync_read(struct adc_client *client) { return -EINVAL; }\r
-static inline int adc_async_read(struct adc_client *client) { return -EINVAL; }\r
+static inline int adc_sync_read(struct adc_client *client) { return -1; }\r
+static inline int adc_async_read(struct adc_client *client) { return -1; }\r
 #endif\r
 \r
 #endif\r