]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/iio/adc/ad7606_par.c
43a554ce753da23a0cb1e15202210d4282b4858c
[karo-tx-linux.git] / drivers / staging / iio / adc / ad7606_par.c
1 /*
2  * AD7606 Parallel Interface ADC driver
3  *
4  * Copyright 2011 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2.
7  */
8
9 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/types.h>
12 #include <linux/err.h>
13 #include <linux/io.h>
14
15 #include "ad7606.h"
16
17 static int ad7606_par16_read_block(struct device *dev,
18                                  int count, void *buf)
19 {
20         struct platform_device *pdev = to_platform_device(dev);
21         struct ad7606_state *st = platform_get_drvdata(pdev);
22
23         insw((unsigned long) st->base_address, buf, count);
24
25         return 0;
26 }
27
28 static const struct ad7606_bus_ops ad7606_par16_bops = {
29         .read_block     = ad7606_par16_read_block,
30 };
31
32 static int ad7606_par8_read_block(struct device *dev,
33                                  int count, void *buf)
34 {
35         struct platform_device *pdev = to_platform_device(dev);
36         struct ad7606_state *st = platform_get_drvdata(pdev);
37
38         insb((unsigned long) st->base_address, buf, count * 2);
39
40         return 0;
41 }
42
43 static const struct ad7606_bus_ops ad7606_par8_bops = {
44         .read_block     = ad7606_par8_read_block,
45 };
46
47 static int __devinit ad7606_par_probe(struct platform_device *pdev)
48 {
49         struct resource *res;
50         struct ad7606_state *st;
51         void __iomem *addr;
52         resource_size_t remap_size;
53         int ret, irq;
54
55         irq = platform_get_irq(pdev, 0);
56         if (irq < 0) {
57                 dev_err(&pdev->dev, "no irq\n");
58                 return -ENODEV;
59         }
60
61         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
62         if (!res)
63                 return -ENODEV;
64
65         remap_size = resource_size(res);
66
67         /* Request the regions */
68         if (!request_mem_region(res->start, remap_size, "iio-ad7606")) {
69                 ret = -EBUSY;
70                 goto out1;
71         }
72         addr = ioremap(res->start, remap_size);
73         if (!addr) {
74                 ret = -ENOMEM;
75                 goto out1;
76         }
77
78         st = ad7606_probe(&pdev->dev, irq, addr,
79                           platform_get_device_id(pdev)->driver_data,
80                           remap_size > 1 ? &ad7606_par16_bops :
81                           &ad7606_par8_bops);
82
83         if (IS_ERR(st))  {
84                 ret = PTR_ERR(st);
85                 goto out2;
86         }
87
88         platform_set_drvdata(pdev, st);
89
90         return 0;
91
92 out2:
93         iounmap(addr);
94 out1:
95         release_mem_region(res->start, remap_size);
96
97         return ret;
98 }
99
100 static int __devexit ad7606_par_remove(struct platform_device *pdev)
101 {
102         struct ad7606_state *st = platform_get_drvdata(pdev);
103         struct resource *res;
104
105         ad7606_remove(st);
106
107         iounmap(st->base_address);
108         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
109         release_mem_region(res->start, resource_size(res));
110
111         platform_set_drvdata(pdev, NULL);
112
113         return 0;
114 }
115
116 #ifdef CONFIG_PM
117 static int ad7606_par_suspend(struct device *dev)
118 {
119         struct ad7606_state *st = dev_get_drvdata(dev);
120
121         ad7606_suspend(st);
122
123         return 0;
124 }
125
126 static int ad7606_par_resume(struct device *dev)
127 {
128         struct ad7606_state *st = dev_get_drvdata(dev);
129
130         ad7606_resume(st);
131
132         return 0;
133 }
134
135 static const struct dev_pm_ops ad7606_pm_ops = {
136         .suspend = ad7606_par_suspend,
137         .resume  = ad7606_par_resume,
138 };
139 #define AD7606_PAR_PM_OPS (&ad7606_pm_ops)
140
141 #else
142 #define AD7606_PAR_PM_OPS NULL
143 #endif  /* CONFIG_PM */
144
145 static struct platform_device_id ad7606_driver_ids[] = {
146         {
147                 .name           = "ad7606-8",
148                 .driver_data    = ID_AD7606_8,
149         }, {
150                 .name           = "ad7606-6",
151                 .driver_data    = ID_AD7606_6,
152         }, {
153                 .name           = "ad7606-4",
154                 .driver_data    = ID_AD7606_4,
155         },
156         { }
157 };
158
159 MODULE_DEVICE_TABLE(platform, ad7606_driver_ids);
160
161 static struct platform_driver ad7606_driver = {
162         .probe = ad7606_par_probe,
163         .remove = __devexit_p(ad7606_par_remove),
164         .id_table = ad7606_driver_ids,
165         .driver = {
166                 .name    = "ad7606",
167                 .owner  = THIS_MODULE,
168                 .pm    = AD7606_PAR_PM_OPS,
169         },
170 };
171
172 static int __init ad7606_init(void)
173 {
174         return platform_driver_register(&ad7606_driver);
175 }
176
177 static void __exit ad7606_cleanup(void)
178 {
179         platform_driver_unregister(&ad7606_driver);
180 }
181
182 module_init(ad7606_init);
183 module_exit(ad7606_cleanup);
184
185 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
186 MODULE_DESCRIPTION("Analog Devices AD7606 ADC");
187 MODULE_LICENSE("GPL v2");
188 MODULE_ALIAS("platform:ad7606_par");