xref: /linux/drivers/mfd/wm831x-spi.c (revision d524dac9279b6a41ffdf7ff7958c577f2e387db6)
1 /*
2  * wm831x-spi.c  --  SPI access for Wolfson WM831x PMICs
3  *
4  * Copyright 2009,2010 Wolfson Microelectronics PLC.
5  *
6  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7  *
8  *  This program is free software; you can redistribute  it and/or modify it
9  *  under  the terms of  the GNU General  Public License as published by the
10  *  Free Software Foundation;  either version 2 of the  License, or (at your
11  *  option) any later version.
12  *
13  */
14 
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/spi/spi.h>
18 
19 #include <linux/mfd/wm831x/core.h>
20 
21 static int wm831x_spi_read_device(struct wm831x *wm831x, unsigned short reg,
22 				  int bytes, void *dest)
23 {
24 	u16 tx_val;
25 	u16 *d = dest;
26 	int r, ret;
27 
28 	/* Go register at a time */
29 	for (r = reg; r < reg + (bytes / 2); r++) {
30 		tx_val = r | 0x8000;
31 
32 		ret = spi_write_then_read(wm831x->control_data,
33 					  (u8 *)&tx_val, 2, (u8 *)d, 2);
34 		if (ret != 0)
35 			return ret;
36 
37 		*d = be16_to_cpu(*d);
38 
39 		d++;
40 	}
41 
42 	return 0;
43 }
44 
45 static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
46 				   int bytes, void *src)
47 {
48 	struct spi_device *spi = wm831x->control_data;
49 	u16 *s = src;
50 	u16 data[2];
51 	int ret, r;
52 
53 	/* Go register at a time */
54 	for (r = reg; r < reg + (bytes / 2); r++) {
55 		data[0] = r;
56 		data[1] = *s++;
57 
58 		ret = spi_write(spi, (char *)&data, sizeof(data));
59 		if (ret != 0)
60 			return ret;
61 	}
62 
63 	return 0;
64 }
65 
66 static int __devinit wm831x_spi_probe(struct spi_device *spi)
67 {
68 	struct wm831x *wm831x;
69 	enum wm831x_parent type;
70 
71 	/* Currently SPI support for ID tables is unmerged, we're faking it */
72 	if (strcmp(spi->modalias, "wm8310") == 0)
73 		type = WM8310;
74 	else if (strcmp(spi->modalias, "wm8311") == 0)
75 		type = WM8311;
76 	else if (strcmp(spi->modalias, "wm8312") == 0)
77 		type = WM8312;
78 	else if (strcmp(spi->modalias, "wm8320") == 0)
79 		type = WM8320;
80 	else if (strcmp(spi->modalias, "wm8321") == 0)
81 		type = WM8321;
82 	else if (strcmp(spi->modalias, "wm8325") == 0)
83 		type = WM8325;
84 	else if (strcmp(spi->modalias, "wm8326") == 0)
85 		type = WM8326;
86 	else {
87 		dev_err(&spi->dev, "Unknown device type\n");
88 		return -EINVAL;
89 	}
90 
91 	wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
92 	if (wm831x == NULL)
93 		return -ENOMEM;
94 
95 	spi->bits_per_word = 16;
96 	spi->mode = SPI_MODE_0;
97 
98 	dev_set_drvdata(&spi->dev, wm831x);
99 	wm831x->dev = &spi->dev;
100 	wm831x->control_data = spi;
101 	wm831x->read_dev = wm831x_spi_read_device;
102 	wm831x->write_dev = wm831x_spi_write_device;
103 
104 	return wm831x_device_init(wm831x, type, spi->irq);
105 }
106 
107 static int __devexit wm831x_spi_remove(struct spi_device *spi)
108 {
109 	struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
110 
111 	wm831x_device_exit(wm831x);
112 
113 	return 0;
114 }
115 
116 static int wm831x_spi_suspend(struct spi_device *spi, pm_message_t m)
117 {
118 	struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
119 
120 	return wm831x_device_suspend(wm831x);
121 }
122 
123 static struct spi_driver wm8310_spi_driver = {
124 	.driver = {
125 		.name	= "wm8310",
126 		.bus	= &spi_bus_type,
127 		.owner	= THIS_MODULE,
128 	},
129 	.probe		= wm831x_spi_probe,
130 	.remove		= __devexit_p(wm831x_spi_remove),
131 	.suspend	= wm831x_spi_suspend,
132 };
133 
134 static struct spi_driver wm8311_spi_driver = {
135 	.driver = {
136 		.name	= "wm8311",
137 		.bus	= &spi_bus_type,
138 		.owner	= THIS_MODULE,
139 	},
140 	.probe		= wm831x_spi_probe,
141 	.remove		= __devexit_p(wm831x_spi_remove),
142 	.suspend	= wm831x_spi_suspend,
143 };
144 
145 static struct spi_driver wm8312_spi_driver = {
146 	.driver = {
147 		.name	= "wm8312",
148 		.bus	= &spi_bus_type,
149 		.owner	= THIS_MODULE,
150 	},
151 	.probe		= wm831x_spi_probe,
152 	.remove		= __devexit_p(wm831x_spi_remove),
153 	.suspend	= wm831x_spi_suspend,
154 };
155 
156 static struct spi_driver wm8320_spi_driver = {
157 	.driver = {
158 		.name	= "wm8320",
159 		.bus	= &spi_bus_type,
160 		.owner	= THIS_MODULE,
161 	},
162 	.probe		= wm831x_spi_probe,
163 	.remove		= __devexit_p(wm831x_spi_remove),
164 	.suspend	= wm831x_spi_suspend,
165 };
166 
167 static struct spi_driver wm8321_spi_driver = {
168 	.driver = {
169 		.name	= "wm8321",
170 		.bus	= &spi_bus_type,
171 		.owner	= THIS_MODULE,
172 	},
173 	.probe		= wm831x_spi_probe,
174 	.remove		= __devexit_p(wm831x_spi_remove),
175 	.suspend	= wm831x_spi_suspend,
176 };
177 
178 static struct spi_driver wm8325_spi_driver = {
179 	.driver = {
180 		.name	= "wm8325",
181 		.bus	= &spi_bus_type,
182 		.owner	= THIS_MODULE,
183 	},
184 	.probe		= wm831x_spi_probe,
185 	.remove		= __devexit_p(wm831x_spi_remove),
186 	.suspend	= wm831x_spi_suspend,
187 };
188 
189 static struct spi_driver wm8326_spi_driver = {
190 	.driver = {
191 		.name	= "wm8326",
192 		.bus	= &spi_bus_type,
193 		.owner	= THIS_MODULE,
194 	},
195 	.probe		= wm831x_spi_probe,
196 	.remove		= __devexit_p(wm831x_spi_remove),
197 	.suspend	= wm831x_spi_suspend,
198 };
199 
200 static int __init wm831x_spi_init(void)
201 {
202 	int ret;
203 
204 	ret = spi_register_driver(&wm8310_spi_driver);
205 	if (ret != 0)
206 		pr_err("Failed to register WM8310 SPI driver: %d\n", ret);
207 
208 	ret = spi_register_driver(&wm8311_spi_driver);
209 	if (ret != 0)
210 		pr_err("Failed to register WM8311 SPI driver: %d\n", ret);
211 
212 	ret = spi_register_driver(&wm8312_spi_driver);
213 	if (ret != 0)
214 		pr_err("Failed to register WM8312 SPI driver: %d\n", ret);
215 
216 	ret = spi_register_driver(&wm8320_spi_driver);
217 	if (ret != 0)
218 		pr_err("Failed to register WM8320 SPI driver: %d\n", ret);
219 
220 	ret = spi_register_driver(&wm8321_spi_driver);
221 	if (ret != 0)
222 		pr_err("Failed to register WM8321 SPI driver: %d\n", ret);
223 
224 	ret = spi_register_driver(&wm8325_spi_driver);
225 	if (ret != 0)
226 		pr_err("Failed to register WM8325 SPI driver: %d\n", ret);
227 
228 	ret = spi_register_driver(&wm8326_spi_driver);
229 	if (ret != 0)
230 		pr_err("Failed to register WM8326 SPI driver: %d\n", ret);
231 
232 	return 0;
233 }
234 subsys_initcall(wm831x_spi_init);
235 
236 static void __exit wm831x_spi_exit(void)
237 {
238 	spi_unregister_driver(&wm8326_spi_driver);
239 	spi_unregister_driver(&wm8325_spi_driver);
240 	spi_unregister_driver(&wm8321_spi_driver);
241 	spi_unregister_driver(&wm8320_spi_driver);
242 	spi_unregister_driver(&wm8312_spi_driver);
243 	spi_unregister_driver(&wm8311_spi_driver);
244 	spi_unregister_driver(&wm8310_spi_driver);
245 }
246 module_exit(wm831x_spi_exit);
247 
248 MODULE_DESCRIPTION("SPI support for WM831x/2x AudioPlus PMICs");
249 MODULE_LICENSE("GPL");
250 MODULE_AUTHOR("Mark Brown");
251