int adc_sync_read(struct adc_client *client)
{
struct adc_request *req = NULL;
- int err, tmo;
+ int err, tmo, tail;
if(client == NULL) {
printk(KERN_ERR "client point is NULL");
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);
return err;
}
tmo = wait_for_completion_timeout(&req->completion,msecs_to_jiffies(100));
- if(tmo == 0)
+ 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;
+ }
return client->result;
}
EXPORT_SYMBOL(adc_sync_read);
req->callback = client->callback;
req->callback_param = client->callback_param;
req->client = client;
+ req->status = ASYNC_READ;
return adc_enqueue_request(client->adc, req);
}
trigger_next_adc_job_if_any(adc);
req->callback(adc->cur, req->callback_param, res);
- kfree(req);
+ if(req->status == ASYNC_READ) {
+ kfree(req);
+ req = NULL;
+ }
}
EXPORT_SYMBOL(adc_core_irq_handle);
.read = rk29_adc_read,\r
};\r
#ifdef ADC_TEST\r
+struct adc_test_data {\r
+ struct adc_client *client;\r
+ struct timer_list timer;\r
+ struct work_struct timer_work;\r
+};\r
static void callback(struct adc_client *client, void *param, int result)\r
{\r
dev_info(client->adc->dev, "[chn%d] async_read = %d\n", client->chn, result);\r
return;\r
}\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
+static void adc_timer_work(struct work_struct *work)\r
+{ \r
+ int sync_read = 0;\r
+ struct adc_test_data *test = container_of(work, struct adc_test_data,\r
+ 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
+}\r
+\r
static int rk29_adc_test(void)\r
{\r
- int sync_read = 0, i, j = 10;\r
- struct adc_client *client =NULL;\r
-\r
- while(j--)\r
- {\r
- client = adc_register(i, callback, NULL);\r
- adc_async_read(client);\r
- mdelay(1000);\r
- sync_read = adc_sync_read(client);\r
- dev_info(client->adc->dev, "[chn%d] sync_read = %d\n", client->chn, sync_read);\r
- adc_unregister(client);\r
- mdelay(1000);\r
- i++;\r
- if(i >= 4)\r
- i = 0;\r
- }\r
- adc_unregister(client);\r
+ struct adc_test_data *test = NULL;\r
+\r
+ test = kzalloc(sizeof(struct adc_test_data), GFP_KERNEL);\r
+ \r
+ test->client = adc_register(0, 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
+ add_timer(&test->timer);\r
+ \r
return 0;\r
+\r
}\r
#endif\r
\r
}\r
platform_set_drvdata(pdev, dev);\r
dev_info(&pdev->dev, "rk29 adc: driver initialized\n");\r
-#ifdef ADC_TEST \r
- rk29_adc_test();\r
-#endif\r
return 0;\r
// err_iomap:\r
// iounmap(dev->regs);\r
MODULE_DESCRIPTION("Driver for ADC");\r
MODULE_AUTHOR("kfx, kfx@rock-chips.com");\r
MODULE_LICENSE("GPL");\r
+static int __init adc_test_init(void)\r
+{\r
+#ifdef ADC_TEST \r
+ rk29_adc_test();\r
+#endif\r
+ return 0;\r
\r
+}\r
+module_init(adc_test_init);\r