xref: /openbmc/linux/drivers/net/wireless/ti/wl1251/sdio.c (revision aaa746ad)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * wl12xx SDIO routines
4  *
5  * Copyright (C) 2005 Texas Instruments Incorporated
6  * Copyright (C) 2008 Google Inc
7  * Copyright (C) 2009 Bob Copeland (me@bobcopeland.com)
8  */
9 #include <linux/interrupt.h>
10 #include <linux/module.h>
11 #include <linux/mod_devicetable.h>
12 #include <linux/mmc/sdio_func.h>
13 #include <linux/mmc/sdio_ids.h>
14 #include <linux/platform_device.h>
15 #include <linux/irq.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/of.h>
18 #include <linux/of_irq.h>
19 
20 #include "wl1251.h"
21 
22 struct wl1251_sdio {
23 	struct sdio_func *func;
24 	u32 elp_val;
25 };
26 
27 static struct sdio_func *wl_to_func(struct wl1251 *wl)
28 {
29 	struct wl1251_sdio *wl_sdio = wl->if_priv;
30 	return wl_sdio->func;
31 }
32 
33 static void wl1251_sdio_interrupt(struct sdio_func *func)
34 {
35 	struct wl1251 *wl = sdio_get_drvdata(func);
36 
37 	wl1251_debug(DEBUG_IRQ, "IRQ");
38 
39 	/* FIXME should be synchronous for sdio */
40 	ieee80211_queue_work(wl->hw, &wl->irq_work);
41 }
42 
43 static const struct sdio_device_id wl1251_devices[] = {
44 	{ SDIO_DEVICE(SDIO_VENDOR_ID_TI_WL1251, SDIO_DEVICE_ID_TI_WL1251) },
45 	{}
46 };
47 MODULE_DEVICE_TABLE(sdio, wl1251_devices);
48 
49 
50 static void wl1251_sdio_read(struct wl1251 *wl, int addr,
51 			     void *buf, size_t len)
52 {
53 	int ret;
54 	struct sdio_func *func = wl_to_func(wl);
55 
56 	sdio_claim_host(func);
57 	ret = sdio_memcpy_fromio(func, buf, addr, len);
58 	if (ret)
59 		wl1251_error("sdio read failed (%d)", ret);
60 	sdio_release_host(func);
61 }
62 
63 static void wl1251_sdio_write(struct wl1251 *wl, int addr,
64 			      void *buf, size_t len)
65 {
66 	int ret;
67 	struct sdio_func *func = wl_to_func(wl);
68 
69 	sdio_claim_host(func);
70 	ret = sdio_memcpy_toio(func, addr, buf, len);
71 	if (ret)
72 		wl1251_error("sdio write failed (%d)", ret);
73 	sdio_release_host(func);
74 }
75 
76 static void wl1251_sdio_read_elp(struct wl1251 *wl, int addr, u32 *val)
77 {
78 	int ret = 0;
79 	struct wl1251_sdio *wl_sdio = wl->if_priv;
80 	struct sdio_func *func = wl_sdio->func;
81 
82 	/*
83 	 * The hardware only supports RAW (read after write) access for
84 	 * reading, regular sdio_readb won't work here (it interprets
85 	 * the unused bits of CMD52 as write data even if we send read
86 	 * request).
87 	 */
88 	sdio_claim_host(func);
89 	*val = sdio_writeb_readb(func, wl_sdio->elp_val, addr, &ret);
90 	sdio_release_host(func);
91 
92 	if (ret)
93 		wl1251_error("sdio_readb failed (%d)", ret);
94 }
95 
96 static void wl1251_sdio_write_elp(struct wl1251 *wl, int addr, u32 val)
97 {
98 	int ret = 0;
99 	struct wl1251_sdio *wl_sdio = wl->if_priv;
100 	struct sdio_func *func = wl_sdio->func;
101 
102 	sdio_claim_host(func);
103 	sdio_writeb(func, val, addr, &ret);
104 	sdio_release_host(func);
105 
106 	if (ret)
107 		wl1251_error("sdio_writeb failed (%d)", ret);
108 	else
109 		wl_sdio->elp_val = val;
110 }
111 
112 static void wl1251_sdio_reset(struct wl1251 *wl)
113 {
114 }
115 
116 static void wl1251_sdio_enable_irq(struct wl1251 *wl)
117 {
118 	struct sdio_func *func = wl_to_func(wl);
119 
120 	sdio_claim_host(func);
121 	sdio_claim_irq(func, wl1251_sdio_interrupt);
122 	sdio_release_host(func);
123 }
124 
125 static void wl1251_sdio_disable_irq(struct wl1251 *wl)
126 {
127 	struct sdio_func *func = wl_to_func(wl);
128 
129 	sdio_claim_host(func);
130 	sdio_release_irq(func);
131 	sdio_release_host(func);
132 }
133 
134 /* Interrupts when using dedicated WLAN_IRQ pin */
135 static irqreturn_t wl1251_line_irq(int irq, void *cookie)
136 {
137 	struct wl1251 *wl = cookie;
138 
139 	ieee80211_queue_work(wl->hw, &wl->irq_work);
140 
141 	return IRQ_HANDLED;
142 }
143 
144 static void wl1251_enable_line_irq(struct wl1251 *wl)
145 {
146 	return enable_irq(wl->irq);
147 }
148 
149 static void wl1251_disable_line_irq(struct wl1251 *wl)
150 {
151 	return disable_irq(wl->irq);
152 }
153 
154 static int wl1251_sdio_set_power(struct wl1251 *wl, bool enable)
155 {
156 	struct sdio_func *func = wl_to_func(wl);
157 	int ret;
158 
159 	if (enable) {
160 		ret = pm_runtime_get_sync(&func->dev);
161 		if (ret < 0) {
162 			pm_runtime_put_sync(&func->dev);
163 			goto out;
164 		}
165 
166 		sdio_claim_host(func);
167 		sdio_enable_func(func);
168 		sdio_release_host(func);
169 	} else {
170 		sdio_claim_host(func);
171 		sdio_disable_func(func);
172 		sdio_release_host(func);
173 
174 		ret = pm_runtime_put_sync(&func->dev);
175 		if (ret < 0)
176 			goto out;
177 	}
178 
179 out:
180 	return ret;
181 }
182 
183 static struct wl1251_if_operations wl1251_sdio_ops = {
184 	.read = wl1251_sdio_read,
185 	.write = wl1251_sdio_write,
186 	.write_elp = wl1251_sdio_write_elp,
187 	.read_elp = wl1251_sdio_read_elp,
188 	.reset = wl1251_sdio_reset,
189 	.power = wl1251_sdio_set_power,
190 };
191 
192 static int wl1251_sdio_probe(struct sdio_func *func,
193 			     const struct sdio_device_id *id)
194 {
195 	int ret;
196 	struct wl1251 *wl;
197 	struct ieee80211_hw *hw;
198 	struct wl1251_sdio *wl_sdio;
199 	struct device_node *np = func->dev.of_node;
200 
201 	hw = wl1251_alloc_hw();
202 	if (IS_ERR(hw))
203 		return PTR_ERR(hw);
204 
205 	wl = hw->priv;
206 
207 	wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL);
208 	if (wl_sdio == NULL) {
209 		ret = -ENOMEM;
210 		goto out_free_hw;
211 	}
212 
213 	sdio_claim_host(func);
214 	ret = sdio_enable_func(func);
215 	if (ret)
216 		goto release;
217 
218 	sdio_set_block_size(func, 512);
219 	sdio_release_host(func);
220 
221 	SET_IEEE80211_DEV(hw, &func->dev);
222 	wl_sdio->func = func;
223 	wl->if_priv = wl_sdio;
224 	wl->if_ops = &wl1251_sdio_ops;
225 
226 	if (np) {
227 		wl->use_eeprom = of_property_read_bool(np, "ti,wl1251-has-eeprom");
228 		wl->irq = of_irq_get(np, 0);
229 		if (wl->irq == -EPROBE_DEFER) {
230 			ret = -EPROBE_DEFER;
231 			goto disable;
232 		}
233 	}
234 
235 	if (wl->irq) {
236 		irq_set_status_flags(wl->irq, IRQ_NOAUTOEN);
237 		ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl);
238 		if (ret < 0) {
239 			wl1251_error("request_irq() failed: %d", ret);
240 			goto disable;
241 		}
242 
243 		irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
244 
245 		wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
246 		wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq;
247 
248 		wl1251_info("using dedicated interrupt line");
249 	} else {
250 		wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq;
251 		wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq;
252 
253 		wl1251_info("using SDIO interrupt");
254 	}
255 
256 	ret = wl1251_init_ieee80211(wl);
257 	if (ret)
258 		goto out_free_irq;
259 
260 	sdio_set_drvdata(func, wl);
261 
262 	/* Tell PM core that we don't need the card to be powered now */
263 	pm_runtime_put_noidle(&func->dev);
264 
265 	return ret;
266 
267 out_free_irq:
268 	if (wl->irq)
269 		free_irq(wl->irq, wl);
270 disable:
271 	sdio_claim_host(func);
272 	sdio_disable_func(func);
273 release:
274 	sdio_release_host(func);
275 	kfree(wl_sdio);
276 out_free_hw:
277 	wl1251_free_hw(wl);
278 	return ret;
279 }
280 
281 static void wl1251_sdio_remove(struct sdio_func *func)
282 {
283 	struct wl1251 *wl = sdio_get_drvdata(func);
284 	struct wl1251_sdio *wl_sdio = wl->if_priv;
285 
286 	/* Undo decrement done above in wl1251_probe */
287 	pm_runtime_get_noresume(&func->dev);
288 
289 	if (wl->irq)
290 		free_irq(wl->irq, wl);
291 	wl1251_free_hw(wl);
292 	kfree(wl_sdio);
293 
294 	sdio_claim_host(func);
295 	sdio_release_irq(func);
296 	sdio_disable_func(func);
297 	sdio_release_host(func);
298 }
299 
300 static int wl1251_suspend(struct device *dev)
301 {
302 	/*
303 	 * Tell MMC/SDIO core it's OK to power down the card
304 	 * (if it isn't already), but not to remove it completely.
305 	 */
306 	return 0;
307 }
308 
309 static int wl1251_resume(struct device *dev)
310 {
311 	return 0;
312 }
313 
314 static const struct dev_pm_ops wl1251_sdio_pm_ops = {
315 	.suspend        = wl1251_suspend,
316 	.resume         = wl1251_resume,
317 };
318 
319 static struct sdio_driver wl1251_sdio_driver = {
320 	.name		= "wl1251_sdio",
321 	.id_table	= wl1251_devices,
322 	.probe		= wl1251_sdio_probe,
323 	.remove		= wl1251_sdio_remove,
324 	.drv.pm		= &wl1251_sdio_pm_ops,
325 };
326 
327 static int __init wl1251_sdio_init(void)
328 {
329 	int err;
330 
331 	err = sdio_register_driver(&wl1251_sdio_driver);
332 	if (err)
333 		wl1251_error("failed to register sdio driver: %d", err);
334 	return err;
335 }
336 
337 static void __exit wl1251_sdio_exit(void)
338 {
339 	sdio_unregister_driver(&wl1251_sdio_driver);
340 	wl1251_notice("unloaded");
341 }
342 
343 module_init(wl1251_sdio_init);
344 module_exit(wl1251_sdio_exit);
345 
346 MODULE_LICENSE("GPL");
347 MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>");
348