1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2560424e9SKalle Valo /*
3560424e9SKalle Valo * Mac80211 SPI driver for ST-Ericsson CW1200 device
4560424e9SKalle Valo *
5560424e9SKalle Valo * Copyright (c) 2011, Sagrad Inc.
6560424e9SKalle Valo * Author: Solomon Peachy <speachy@sagrad.com>
7560424e9SKalle Valo *
8560424e9SKalle Valo * Based on cw1200_sdio.c
9560424e9SKalle Valo * Copyright (c) 2010, ST-Ericsson
10560424e9SKalle Valo * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
11560424e9SKalle Valo */
12560424e9SKalle Valo
13560424e9SKalle Valo #include <linux/module.h>
14560424e9SKalle Valo #include <linux/gpio.h>
15560424e9SKalle Valo #include <linux/delay.h>
16560424e9SKalle Valo #include <linux/spinlock.h>
17560424e9SKalle Valo #include <linux/interrupt.h>
18560424e9SKalle Valo #include <net/mac80211.h>
19560424e9SKalle Valo
20560424e9SKalle Valo #include <linux/spi/spi.h>
21560424e9SKalle Valo #include <linux/device.h>
22560424e9SKalle Valo
23560424e9SKalle Valo #include "cw1200.h"
24560424e9SKalle Valo #include "hwbus.h"
25560424e9SKalle Valo #include <linux/platform_data/net-cw1200.h>
26560424e9SKalle Valo #include "hwio.h"
27560424e9SKalle Valo
28560424e9SKalle Valo MODULE_AUTHOR("Solomon Peachy <speachy@sagrad.com>");
29560424e9SKalle Valo MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SPI driver");
30560424e9SKalle Valo MODULE_LICENSE("GPL");
31560424e9SKalle Valo MODULE_ALIAS("spi:cw1200_wlan_spi");
32560424e9SKalle Valo
33560424e9SKalle Valo /* #define SPI_DEBUG */
34560424e9SKalle Valo
35560424e9SKalle Valo struct hwbus_priv {
36560424e9SKalle Valo struct spi_device *func;
37560424e9SKalle Valo struct cw1200_common *core;
38560424e9SKalle Valo const struct cw1200_platform_data_spi *pdata;
39560424e9SKalle Valo spinlock_t lock; /* Serialize all bus operations */
40560424e9SKalle Valo wait_queue_head_t wq;
41560424e9SKalle Valo int claimed;
42560424e9SKalle Valo };
43560424e9SKalle Valo
44560424e9SKalle Valo #define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2)
45560424e9SKalle Valo #define SET_WRITE 0x7FFF /* usage: and operation */
46560424e9SKalle Valo #define SET_READ 0x8000 /* usage: or operation */
47560424e9SKalle Valo
48560424e9SKalle Valo /* Notes on byte ordering:
49560424e9SKalle Valo LE: B0 B1 B2 B3
50560424e9SKalle Valo BE: B3 B2 B1 B0
51560424e9SKalle Valo
52560424e9SKalle Valo Hardware expects 32-bit data to be written as 16-bit BE words:
53560424e9SKalle Valo
54560424e9SKalle Valo B1 B0 B3 B2
55560424e9SKalle Valo */
56560424e9SKalle Valo
cw1200_spi_memcpy_fromio(struct hwbus_priv * self,unsigned int addr,void * dst,int count)57560424e9SKalle Valo static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
58560424e9SKalle Valo unsigned int addr,
59560424e9SKalle Valo void *dst, int count)
60560424e9SKalle Valo {
61560424e9SKalle Valo int ret, i;
62560424e9SKalle Valo u16 regaddr;
63560424e9SKalle Valo struct spi_message m;
64560424e9SKalle Valo
65560424e9SKalle Valo struct spi_transfer t_addr = {
66560424e9SKalle Valo .tx_buf = ®addr,
67560424e9SKalle Valo .len = sizeof(regaddr),
68560424e9SKalle Valo };
69560424e9SKalle Valo struct spi_transfer t_msg = {
70560424e9SKalle Valo .rx_buf = dst,
71560424e9SKalle Valo .len = count,
72560424e9SKalle Valo };
73560424e9SKalle Valo
74560424e9SKalle Valo regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
75560424e9SKalle Valo regaddr |= SET_READ;
76560424e9SKalle Valo regaddr |= (count>>1);
77560424e9SKalle Valo
78560424e9SKalle Valo #ifdef SPI_DEBUG
79560424e9SKalle Valo pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr, regaddr);
80560424e9SKalle Valo #endif
81560424e9SKalle Valo
82560424e9SKalle Valo /* Header is LE16 */
83560424e9SKalle Valo regaddr = cpu_to_le16(regaddr);
84560424e9SKalle Valo
85560424e9SKalle Valo /* We have to byteswap if the SPI bus is limited to 8b operation
86560424e9SKalle Valo or we are running on a Big Endian system
87560424e9SKalle Valo */
88560424e9SKalle Valo #if defined(__LITTLE_ENDIAN)
89560424e9SKalle Valo if (self->func->bits_per_word == 8)
90560424e9SKalle Valo #endif
91560424e9SKalle Valo regaddr = swab16(regaddr);
92560424e9SKalle Valo
93560424e9SKalle Valo spi_message_init(&m);
94560424e9SKalle Valo spi_message_add_tail(&t_addr, &m);
95560424e9SKalle Valo spi_message_add_tail(&t_msg, &m);
96560424e9SKalle Valo ret = spi_sync(self->func, &m);
97560424e9SKalle Valo
98560424e9SKalle Valo #ifdef SPI_DEBUG
99560424e9SKalle Valo pr_info("READ : ");
100560424e9SKalle Valo for (i = 0; i < t_addr.len; i++)
101560424e9SKalle Valo printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
102560424e9SKalle Valo printk(" : ");
103560424e9SKalle Valo for (i = 0; i < t_msg.len; i++)
104560424e9SKalle Valo printk("%02x ", ((u8 *)t_msg.rx_buf)[i]);
105560424e9SKalle Valo printk("\n");
106560424e9SKalle Valo #endif
107560424e9SKalle Valo
108560424e9SKalle Valo /* We have to byteswap if the SPI bus is limited to 8b operation
109560424e9SKalle Valo or we are running on a Big Endian system
110560424e9SKalle Valo */
111560424e9SKalle Valo #if defined(__LITTLE_ENDIAN)
112560424e9SKalle Valo if (self->func->bits_per_word == 8)
113560424e9SKalle Valo #endif
114560424e9SKalle Valo {
115560424e9SKalle Valo uint16_t *buf = (uint16_t *)dst;
116560424e9SKalle Valo for (i = 0; i < ((count + 1) >> 1); i++)
117560424e9SKalle Valo buf[i] = swab16(buf[i]);
118560424e9SKalle Valo }
119560424e9SKalle Valo
120560424e9SKalle Valo return ret;
121560424e9SKalle Valo }
122560424e9SKalle Valo
cw1200_spi_memcpy_toio(struct hwbus_priv * self,unsigned int addr,const void * src,int count)123560424e9SKalle Valo static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
124560424e9SKalle Valo unsigned int addr,
125560424e9SKalle Valo const void *src, int count)
126560424e9SKalle Valo {
127560424e9SKalle Valo int rval, i;
128560424e9SKalle Valo u16 regaddr;
129560424e9SKalle Valo struct spi_transfer t_addr = {
130560424e9SKalle Valo .tx_buf = ®addr,
131560424e9SKalle Valo .len = sizeof(regaddr),
132560424e9SKalle Valo };
133560424e9SKalle Valo struct spi_transfer t_msg = {
134560424e9SKalle Valo .tx_buf = src,
135560424e9SKalle Valo .len = count,
136560424e9SKalle Valo };
137560424e9SKalle Valo struct spi_message m;
138560424e9SKalle Valo
139560424e9SKalle Valo regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
140560424e9SKalle Valo regaddr &= SET_WRITE;
141560424e9SKalle Valo regaddr |= (count>>1);
142560424e9SKalle Valo
143560424e9SKalle Valo #ifdef SPI_DEBUG
144560424e9SKalle Valo pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr, regaddr);
145560424e9SKalle Valo #endif
146560424e9SKalle Valo
147560424e9SKalle Valo /* Header is LE16 */
148560424e9SKalle Valo regaddr = cpu_to_le16(regaddr);
149560424e9SKalle Valo
150560424e9SKalle Valo /* We have to byteswap if the SPI bus is limited to 8b operation
151560424e9SKalle Valo or we are running on a Big Endian system
152560424e9SKalle Valo */
153560424e9SKalle Valo #if defined(__LITTLE_ENDIAN)
154560424e9SKalle Valo if (self->func->bits_per_word == 8)
155560424e9SKalle Valo #endif
156560424e9SKalle Valo {
157560424e9SKalle Valo uint16_t *buf = (uint16_t *)src;
158560424e9SKalle Valo regaddr = swab16(regaddr);
159560424e9SKalle Valo for (i = 0; i < ((count + 1) >> 1); i++)
160560424e9SKalle Valo buf[i] = swab16(buf[i]);
161560424e9SKalle Valo }
162560424e9SKalle Valo
163560424e9SKalle Valo #ifdef SPI_DEBUG
164560424e9SKalle Valo pr_info("WRITE: ");
165560424e9SKalle Valo for (i = 0; i < t_addr.len; i++)
166560424e9SKalle Valo printk("%02x ", ((u8 *)t_addr.tx_buf)[i]);
167560424e9SKalle Valo printk(" : ");
168560424e9SKalle Valo for (i = 0; i < t_msg.len; i++)
169560424e9SKalle Valo printk("%02x ", ((u8 *)t_msg.tx_buf)[i]);
170560424e9SKalle Valo printk("\n");
171560424e9SKalle Valo #endif
172560424e9SKalle Valo
173560424e9SKalle Valo spi_message_init(&m);
174560424e9SKalle Valo spi_message_add_tail(&t_addr, &m);
175560424e9SKalle Valo spi_message_add_tail(&t_msg, &m);
176560424e9SKalle Valo rval = spi_sync(self->func, &m);
177560424e9SKalle Valo
178560424e9SKalle Valo #ifdef SPI_DEBUG
179560424e9SKalle Valo pr_info("WROTE: %d\n", m.actual_length);
180560424e9SKalle Valo #endif
181560424e9SKalle Valo
182560424e9SKalle Valo #if defined(__LITTLE_ENDIAN)
183560424e9SKalle Valo /* We have to byteswap if the SPI bus is limited to 8b operation */
184560424e9SKalle Valo if (self->func->bits_per_word == 8)
185560424e9SKalle Valo #endif
186560424e9SKalle Valo {
187560424e9SKalle Valo uint16_t *buf = (uint16_t *)src;
188560424e9SKalle Valo for (i = 0; i < ((count + 1) >> 1); i++)
189560424e9SKalle Valo buf[i] = swab16(buf[i]);
190560424e9SKalle Valo }
191560424e9SKalle Valo return rval;
192560424e9SKalle Valo }
193560424e9SKalle Valo
cw1200_spi_lock(struct hwbus_priv * self)194560424e9SKalle Valo static void cw1200_spi_lock(struct hwbus_priv *self)
195560424e9SKalle Valo {
196560424e9SKalle Valo unsigned long flags;
197560424e9SKalle Valo
198560424e9SKalle Valo DECLARE_WAITQUEUE(wait, current);
199560424e9SKalle Valo
200560424e9SKalle Valo might_sleep();
201560424e9SKalle Valo
202560424e9SKalle Valo add_wait_queue(&self->wq, &wait);
203560424e9SKalle Valo spin_lock_irqsave(&self->lock, flags);
204560424e9SKalle Valo while (1) {
205560424e9SKalle Valo set_current_state(TASK_UNINTERRUPTIBLE);
206560424e9SKalle Valo if (!self->claimed)
207560424e9SKalle Valo break;
208560424e9SKalle Valo spin_unlock_irqrestore(&self->lock, flags);
209560424e9SKalle Valo schedule();
210560424e9SKalle Valo spin_lock_irqsave(&self->lock, flags);
211560424e9SKalle Valo }
212560424e9SKalle Valo set_current_state(TASK_RUNNING);
213560424e9SKalle Valo self->claimed = 1;
214560424e9SKalle Valo spin_unlock_irqrestore(&self->lock, flags);
215560424e9SKalle Valo remove_wait_queue(&self->wq, &wait);
216560424e9SKalle Valo
217560424e9SKalle Valo return;
218560424e9SKalle Valo }
219560424e9SKalle Valo
cw1200_spi_unlock(struct hwbus_priv * self)220560424e9SKalle Valo static void cw1200_spi_unlock(struct hwbus_priv *self)
221560424e9SKalle Valo {
222560424e9SKalle Valo unsigned long flags;
223560424e9SKalle Valo
224560424e9SKalle Valo spin_lock_irqsave(&self->lock, flags);
225560424e9SKalle Valo self->claimed = 0;
226560424e9SKalle Valo spin_unlock_irqrestore(&self->lock, flags);
227560424e9SKalle Valo wake_up(&self->wq);
228560424e9SKalle Valo
229560424e9SKalle Valo return;
230560424e9SKalle Valo }
231560424e9SKalle Valo
cw1200_spi_irq_handler(int irq,void * dev_id)232560424e9SKalle Valo static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
233560424e9SKalle Valo {
234560424e9SKalle Valo struct hwbus_priv *self = dev_id;
235560424e9SKalle Valo
236560424e9SKalle Valo if (self->core) {
237560424e9SKalle Valo cw1200_spi_lock(self);
238560424e9SKalle Valo cw1200_irq_handler(self->core);
239560424e9SKalle Valo cw1200_spi_unlock(self);
240560424e9SKalle Valo return IRQ_HANDLED;
241560424e9SKalle Valo } else {
242560424e9SKalle Valo return IRQ_NONE;
243560424e9SKalle Valo }
244560424e9SKalle Valo }
245560424e9SKalle Valo
cw1200_spi_irq_subscribe(struct hwbus_priv * self)246560424e9SKalle Valo static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
247560424e9SKalle Valo {
248560424e9SKalle Valo int ret;
249560424e9SKalle Valo
250560424e9SKalle Valo pr_debug("SW IRQ subscribe\n");
251560424e9SKalle Valo
252560424e9SKalle Valo ret = request_threaded_irq(self->func->irq, NULL,
253560424e9SKalle Valo cw1200_spi_irq_handler,
254560424e9SKalle Valo IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
255560424e9SKalle Valo "cw1200_wlan_irq", self);
256560424e9SKalle Valo if (WARN_ON(ret < 0))
257560424e9SKalle Valo goto exit;
258560424e9SKalle Valo
259560424e9SKalle Valo ret = enable_irq_wake(self->func->irq);
260560424e9SKalle Valo if (WARN_ON(ret))
261560424e9SKalle Valo goto free_irq;
262560424e9SKalle Valo
263560424e9SKalle Valo return 0;
264560424e9SKalle Valo
265560424e9SKalle Valo free_irq:
266560424e9SKalle Valo free_irq(self->func->irq, self);
267560424e9SKalle Valo exit:
268560424e9SKalle Valo return ret;
269560424e9SKalle Valo }
270560424e9SKalle Valo
cw1200_spi_irq_unsubscribe(struct hwbus_priv * self)27180efb443SJason Yan static void cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
272560424e9SKalle Valo {
273560424e9SKalle Valo pr_debug("SW IRQ unsubscribe\n");
274560424e9SKalle Valo disable_irq_wake(self->func->irq);
275560424e9SKalle Valo free_irq(self->func->irq, self);
276560424e9SKalle Valo }
277560424e9SKalle Valo
cw1200_spi_off(const struct cw1200_platform_data_spi * pdata)278560424e9SKalle Valo static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
279560424e9SKalle Valo {
280560424e9SKalle Valo if (pdata->reset) {
281560424e9SKalle Valo gpio_set_value(pdata->reset, 0);
282560424e9SKalle Valo msleep(30); /* Min is 2 * CLK32K cycles */
283560424e9SKalle Valo gpio_free(pdata->reset);
284560424e9SKalle Valo }
285560424e9SKalle Valo
286560424e9SKalle Valo if (pdata->power_ctrl)
287560424e9SKalle Valo pdata->power_ctrl(pdata, false);
288560424e9SKalle Valo if (pdata->clk_ctrl)
289560424e9SKalle Valo pdata->clk_ctrl(pdata, false);
290560424e9SKalle Valo
291560424e9SKalle Valo return 0;
292560424e9SKalle Valo }
293560424e9SKalle Valo
cw1200_spi_on(const struct cw1200_platform_data_spi * pdata)294560424e9SKalle Valo static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata)
295560424e9SKalle Valo {
296560424e9SKalle Valo /* Ensure I/Os are pulled low */
297560424e9SKalle Valo if (pdata->reset) {
298560424e9SKalle Valo gpio_request(pdata->reset, "cw1200_wlan_reset");
299560424e9SKalle Valo gpio_direction_output(pdata->reset, 0);
300560424e9SKalle Valo }
301560424e9SKalle Valo if (pdata->powerup) {
302560424e9SKalle Valo gpio_request(pdata->powerup, "cw1200_wlan_powerup");
303560424e9SKalle Valo gpio_direction_output(pdata->powerup, 0);
304560424e9SKalle Valo }
305560424e9SKalle Valo if (pdata->reset || pdata->powerup)
306560424e9SKalle Valo msleep(10); /* Settle time? */
307560424e9SKalle Valo
308560424e9SKalle Valo /* Enable 3v3 and 1v8 to hardware */
309560424e9SKalle Valo if (pdata->power_ctrl) {
310560424e9SKalle Valo if (pdata->power_ctrl(pdata, true)) {
311560424e9SKalle Valo pr_err("power_ctrl() failed!\n");
312560424e9SKalle Valo return -1;
313560424e9SKalle Valo }
314560424e9SKalle Valo }
315560424e9SKalle Valo
316560424e9SKalle Valo /* Enable CLK32K */
317560424e9SKalle Valo if (pdata->clk_ctrl) {
318560424e9SKalle Valo if (pdata->clk_ctrl(pdata, true)) {
319560424e9SKalle Valo pr_err("clk_ctrl() failed!\n");
320560424e9SKalle Valo return -1;
321560424e9SKalle Valo }
322560424e9SKalle Valo msleep(10); /* Delay until clock is stable for 2 cycles */
323560424e9SKalle Valo }
324560424e9SKalle Valo
325560424e9SKalle Valo /* Enable POWERUP signal */
326560424e9SKalle Valo if (pdata->powerup) {
327560424e9SKalle Valo gpio_set_value(pdata->powerup, 1);
328560424e9SKalle Valo msleep(250); /* or more..? */
329560424e9SKalle Valo }
330560424e9SKalle Valo /* Enable RSTn signal */
331560424e9SKalle Valo if (pdata->reset) {
332560424e9SKalle Valo gpio_set_value(pdata->reset, 1);
333560424e9SKalle Valo msleep(50); /* Or more..? */
334560424e9SKalle Valo }
335560424e9SKalle Valo return 0;
336560424e9SKalle Valo }
337560424e9SKalle Valo
cw1200_spi_align_size(struct hwbus_priv * self,size_t size)338560424e9SKalle Valo static size_t cw1200_spi_align_size(struct hwbus_priv *self, size_t size)
339560424e9SKalle Valo {
340560424e9SKalle Valo return size & 1 ? size + 1 : size;
341560424e9SKalle Valo }
342560424e9SKalle Valo
cw1200_spi_pm(struct hwbus_priv * self,bool suspend)343560424e9SKalle Valo static int cw1200_spi_pm(struct hwbus_priv *self, bool suspend)
344560424e9SKalle Valo {
345560424e9SKalle Valo return irq_set_irq_wake(self->func->irq, suspend);
346560424e9SKalle Valo }
347560424e9SKalle Valo
3483ac27dd3SBhumika Goyal static const struct hwbus_ops cw1200_spi_hwbus_ops = {
349560424e9SKalle Valo .hwbus_memcpy_fromio = cw1200_spi_memcpy_fromio,
350560424e9SKalle Valo .hwbus_memcpy_toio = cw1200_spi_memcpy_toio,
351560424e9SKalle Valo .lock = cw1200_spi_lock,
352560424e9SKalle Valo .unlock = cw1200_spi_unlock,
353560424e9SKalle Valo .align_size = cw1200_spi_align_size,
354560424e9SKalle Valo .power_mgmt = cw1200_spi_pm,
355560424e9SKalle Valo };
356560424e9SKalle Valo
357560424e9SKalle Valo /* Probe Function to be called by SPI stack when device is discovered */
cw1200_spi_probe(struct spi_device * func)358560424e9SKalle Valo static int cw1200_spi_probe(struct spi_device *func)
359560424e9SKalle Valo {
360560424e9SKalle Valo const struct cw1200_platform_data_spi *plat_data =
361560424e9SKalle Valo dev_get_platdata(&func->dev);
362560424e9SKalle Valo struct hwbus_priv *self;
363560424e9SKalle Valo int status;
364560424e9SKalle Valo
365560424e9SKalle Valo /* Sanity check speed */
366560424e9SKalle Valo if (func->max_speed_hz > 52000000)
367560424e9SKalle Valo func->max_speed_hz = 52000000;
368560424e9SKalle Valo if (func->max_speed_hz < 1000000)
369560424e9SKalle Valo func->max_speed_hz = 1000000;
370560424e9SKalle Valo
371560424e9SKalle Valo /* Fix up transfer size */
372560424e9SKalle Valo if (plat_data->spi_bits_per_word)
373560424e9SKalle Valo func->bits_per_word = plat_data->spi_bits_per_word;
374560424e9SKalle Valo if (!func->bits_per_word)
375560424e9SKalle Valo func->bits_per_word = 16;
376560424e9SKalle Valo
377560424e9SKalle Valo /* And finally.. */
378560424e9SKalle Valo func->mode = SPI_MODE_0;
379560424e9SKalle Valo
380560424e9SKalle Valo pr_info("cw1200_wlan_spi: Probe called (CS %d M %d BPW %d CLK %d)\n",
381*25fd0550SAmit Kumar Mahapatra spi_get_chipselect(func, 0), func->mode, func->bits_per_word,
382560424e9SKalle Valo func->max_speed_hz);
383560424e9SKalle Valo
384560424e9SKalle Valo if (cw1200_spi_on(plat_data)) {
385560424e9SKalle Valo pr_err("spi_on() failed!\n");
386560424e9SKalle Valo return -1;
387560424e9SKalle Valo }
388560424e9SKalle Valo
389560424e9SKalle Valo if (spi_setup(func)) {
390560424e9SKalle Valo pr_err("spi_setup() failed!\n");
391560424e9SKalle Valo return -1;
392560424e9SKalle Valo }
393560424e9SKalle Valo
394560424e9SKalle Valo self = devm_kzalloc(&func->dev, sizeof(*self), GFP_KERNEL);
395560424e9SKalle Valo if (!self) {
396560424e9SKalle Valo pr_err("Can't allocate SPI hwbus_priv.");
397560424e9SKalle Valo return -ENOMEM;
398560424e9SKalle Valo }
399560424e9SKalle Valo
400560424e9SKalle Valo self->pdata = plat_data;
401560424e9SKalle Valo self->func = func;
402560424e9SKalle Valo spin_lock_init(&self->lock);
403560424e9SKalle Valo
404560424e9SKalle Valo spi_set_drvdata(func, self);
405560424e9SKalle Valo
406560424e9SKalle Valo init_waitqueue_head(&self->wq);
407560424e9SKalle Valo
408560424e9SKalle Valo status = cw1200_spi_irq_subscribe(self);
409560424e9SKalle Valo
410560424e9SKalle Valo status = cw1200_core_probe(&cw1200_spi_hwbus_ops,
411560424e9SKalle Valo self, &func->dev, &self->core,
412560424e9SKalle Valo self->pdata->ref_clk,
413560424e9SKalle Valo self->pdata->macaddr,
414560424e9SKalle Valo self->pdata->sdd_file,
415560424e9SKalle Valo self->pdata->have_5ghz);
416560424e9SKalle Valo
417560424e9SKalle Valo if (status) {
418560424e9SKalle Valo cw1200_spi_irq_unsubscribe(self);
419560424e9SKalle Valo cw1200_spi_off(plat_data);
420560424e9SKalle Valo }
421560424e9SKalle Valo
422560424e9SKalle Valo return status;
423560424e9SKalle Valo }
424560424e9SKalle Valo
425560424e9SKalle Valo /* Disconnect Function to be called by SPI stack when device is disconnected */
cw1200_spi_disconnect(struct spi_device * func)426a0386bbaSUwe Kleine-König static void cw1200_spi_disconnect(struct spi_device *func)
427560424e9SKalle Valo {
428560424e9SKalle Valo struct hwbus_priv *self = spi_get_drvdata(func);
429560424e9SKalle Valo
430560424e9SKalle Valo if (self) {
431560424e9SKalle Valo cw1200_spi_irq_unsubscribe(self);
432560424e9SKalle Valo if (self->core) {
433560424e9SKalle Valo cw1200_core_release(self->core);
434560424e9SKalle Valo self->core = NULL;
435560424e9SKalle Valo }
436560424e9SKalle Valo }
437560424e9SKalle Valo cw1200_spi_off(dev_get_platdata(&func->dev));
438560424e9SKalle Valo }
439560424e9SKalle Valo
cw1200_spi_suspend(struct device * dev)440836856e3SArnd Bergmann static int __maybe_unused cw1200_spi_suspend(struct device *dev)
441560424e9SKalle Valo {
442560424e9SKalle Valo struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev));
443560424e9SKalle Valo
444560424e9SKalle Valo if (!cw1200_can_suspend(self->core))
445560424e9SKalle Valo return -EAGAIN;
446560424e9SKalle Valo
447560424e9SKalle Valo /* XXX notify host that we have to keep CW1200 powered on? */
448560424e9SKalle Valo return 0;
449560424e9SKalle Valo }
450560424e9SKalle Valo
451560424e9SKalle Valo static SIMPLE_DEV_PM_OPS(cw1200_pm_ops, cw1200_spi_suspend, NULL);
452560424e9SKalle Valo
453560424e9SKalle Valo static struct spi_driver spi_driver = {
454560424e9SKalle Valo .probe = cw1200_spi_probe,
455560424e9SKalle Valo .remove = cw1200_spi_disconnect,
456560424e9SKalle Valo .driver = {
457560424e9SKalle Valo .name = "cw1200_wlan_spi",
458836856e3SArnd Bergmann .pm = IS_ENABLED(CONFIG_PM) ? &cw1200_pm_ops : NULL,
459560424e9SKalle Valo },
460560424e9SKalle Valo };
461560424e9SKalle Valo
462560424e9SKalle Valo module_spi_driver(spi_driver);
463