1 /* drivers/adc/chips/rk29_adc.c
\r
3 * This program is free software; you can redistribute it and/or modify
\r
4 * it under the terms of the GNU General Public License as published by
\r
5 * the Free Software Foundation; either version 2 of the License.
\r
7 #include <linux/adc.h>
\r
9 #include "../adc_priv.h"
\r
10 #include "rk29_adc.h"
\r
14 struct rk29_adc_device {
\r
18 struct resource *ioarea;
\r
19 struct adc_host *adc;
\r
21 static void rk29_adc_start(struct adc_host *adc)
\r
23 struct rk29_adc_device *dev = adc_priv(adc);
\r
26 writel(0, dev->regs + ADC_CTRL);
\r
27 writel(ADC_CTRL_POWER_UP|ADC_CTRL_CH(chn), dev->regs + ADC_CTRL);
\r
28 udelay(SAMPLE_RATE);
\r
30 writel(readl(dev->regs + ADC_CTRL)|ADC_CTRL_IRQ_ENABLE|ADC_CTRL_START,
\r
31 dev->regs + ADC_CTRL);
\r
34 static void rk29_adc_stop(struct adc_host *adc)
\r
36 struct rk29_adc_device *dev = adc_priv(adc);
\r
38 writel(0, dev->regs + ADC_CTRL);
\r
40 static int rk29_adc_read(struct adc_host *adc)
\r
42 struct rk29_adc_device *dev = adc_priv(adc);
\r
44 udelay(SAMPLE_RATE);
\r
45 return readl(dev->regs + ADC_DATA) & ADC_DATA_MASK;
\r
47 static irqreturn_t rk29_adc_irq(int irq, void *data)
\r
49 struct rk29_adc_device *dev = data;
\r
50 adc_core_irq_handle(dev->adc);
\r
53 static const struct adc_ops rk29_adc_ops = {
\r
54 .start = rk29_adc_start,
\r
55 .stop = rk29_adc_stop,
\r
56 .read = rk29_adc_read,
\r
59 struct adc_test_data {
\r
60 struct adc_client *client;
\r
61 struct timer_list timer;
\r
62 struct work_struct timer_work;
\r
64 static void callback(struct adc_client *client, void *param, int result)
\r
66 dev_info(client->adc->dev, "[chn%d] async_read = %d\n", client->chn, result);
\r
69 static void adc_timer(unsigned long data)
\r
71 //int sync_read = 0;
\r
72 struct adc_test_data *test=(struct adc_test_data *)data;
\r
74 //sync_read = adc_sync_read(test->client);
\r
75 //dev_info(test->client->adc->dev, "[chn%d] sync_read = %d\n", 0, sync_read);
\r
76 schedule_work(&test->timer_work);
\r
77 add_timer(&test->timer);
\r
79 static void adc_timer_work(struct work_struct *work)
\r
82 struct adc_test_data *test = container_of(work, struct adc_test_data,
\r
84 adc_async_read(test->client);
\r
85 sync_read = adc_sync_read(test->client);
\r
86 dev_info(test->client->adc->dev, "[chn%d] sync_read = %d\n", 0, sync_read);
\r
89 static int rk29_adc_test(void)
\r
91 struct adc_test_data *test = NULL;
\r
93 test = kzalloc(sizeof(struct adc_test_data), GFP_KERNEL);
\r
95 test->client = adc_register(0, callback, NULL);
\r
96 INIT_WORK(&test->timer_work, adc_timer_work);
\r
97 setup_timer(&test->timer, adc_timer, (unsigned long)test);
\r
98 test->timer.expires = jiffies + 100;
\r
99 add_timer(&test->timer);
\r
106 static int rk29_adc_probe(struct platform_device *pdev)
\r
108 struct adc_platform_data *pdata = pdev->dev.platform_data;
\r
109 struct adc_host *adc = NULL;
\r
110 struct rk29_adc_device *dev;
\r
111 struct resource *res;
\r
117 adc = adc_alloc_host(&pdev->dev, sizeof(struct rk29_adc_device), SARADC_CHN_MASK);
\r
120 adc->ops = &rk29_adc_ops;
\r
121 adc->pdata = pdata;
\r
122 dev = adc_priv(adc);
\r
124 dev->irq = platform_get_irq(pdev, 0);
\r
125 if (dev->irq <= 0) {
\r
126 dev_err(&pdev->dev, "failed to get adc irq\n");
\r
131 ret = request_threaded_irq(dev->irq, NULL, rk29_adc_irq, IRQF_ONESHOT, pdev->name, dev);
\r
133 dev_err(&pdev->dev, "failed to attach adc irq\n");
\r
136 dev->clk = clk_get(&pdev->dev, "saradc");
\r
137 if (IS_ERR(dev->clk)) {
\r
138 dev_err(&pdev->dev, "failed to get adc clock\n");
\r
139 ret = PTR_ERR(dev->clk);
\r
143 ret = clk_set_rate(dev->clk, ADC_CLK_RATE * 1000 * 1000);
\r
145 dev_err(&pdev->dev, "failed to set adc clk\n");
\r
148 clk_enable(dev->clk);
\r
150 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
\r
152 dev_err(&pdev->dev, "cannot find IO resource\n");
\r
156 dev->ioarea = request_mem_region(res->start, (res->end - res->start) + 1,
\r
158 if(dev->ioarea == NULL) {
\r
159 dev_err(&pdev->dev, "cannot request IO\n");
\r
163 dev->regs = ioremap(res->start, (res->end - res->start) + 1);
\r
165 dev_err(&pdev->dev, "cannot map IO\n");
\r
170 platform_set_drvdata(pdev, dev);
\r
171 dev_info(&pdev->dev, "rk29 adc: driver initialized\n");
\r
175 release_resource(dev->ioarea);
\r
176 kfree(dev->ioarea);
\r
177 clk_disable(dev->clk);
\r
183 free_irq(dev->irq, dev);
\r
186 adc_free_host(dev->adc);
\r
190 static int rk29_adc_remove(struct platform_device *pdev)
\r
192 struct rk29_adc_device *dev = platform_get_drvdata(pdev);
\r
194 iounmap(dev->regs);
\r
195 release_resource(dev->ioarea);
\r
196 kfree(dev->ioarea);
\r
197 free_irq(dev->irq, dev);
\r
198 clk_disable(dev->clk);
\r
200 adc_free_host(dev->adc);
\r
206 static int rk29_adc_suspend(struct platform_device *pdev, pm_message_t state)
\r
208 struct rk29_adc_device *dev = platform_get_drvdata(pdev);
\r
210 dev->adc->is_suspended = 1;
\r
214 static int rk29_adc_resume(struct platform_device *pdev)
\r
216 struct rk29_adc_device *dev = platform_get_drvdata(pdev);
\r
218 dev->adc->is_suspended = 0;
\r
223 #define rk29_adc_suspend NULL
\r
224 #define rk29_adc_resume NULL
\r
227 static struct platform_driver rk29_adc_driver = {
\r
229 .name = "rk29-adc",
\r
230 .owner = THIS_MODULE,
\r
232 .probe = rk29_adc_probe,
\r
233 .remove = __devexit_p(rk29_adc_remove),
\r
234 .suspend = rk29_adc_suspend,
\r
235 .resume = rk29_adc_resume,
\r
238 static int __init rk29_adc_init(void)
\r
240 return platform_driver_register(&rk29_adc_driver);
\r
242 subsys_initcall(rk29_adc_init);
\r
244 static void __exit rk29_adc_exit(void)
\r
246 platform_driver_unregister(&rk29_adc_driver);
\r
248 module_exit(rk29_adc_exit);
\r
250 MODULE_DESCRIPTION("Driver for ADC");
\r
251 MODULE_AUTHOR("kfx, kfx@rock-chips.com");
\r
252 MODULE_LICENSE("GPL");
\r
253 static int __init adc_test_init(void)
\r
261 module_init(adc_test_init);
\r