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