1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2009 Nokia Corporation
5 *
6 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/interrupt.h>
25#include <linux/irq.h>
26#include <linux/module.h>
27#include <linux/slab.h>
28#include <linux/swab.h>
29#include <linux/crc7.h>
30#include <linux/spi/spi.h>
31#include <linux/wl12xx.h>
32#include <linux/platform_device.h>
33
34#include "wlcore.h"
35#include "wl12xx_80211.h"
36#include "io.h"
37
38#define WSPI_CMD_READ                 0x40000000
39#define WSPI_CMD_WRITE                0x00000000
40#define WSPI_CMD_FIXED                0x20000000
41#define WSPI_CMD_BYTE_LENGTH          0x1FFE0000
42#define WSPI_CMD_BYTE_LENGTH_OFFSET   17
43#define WSPI_CMD_BYTE_ADDR            0x0001FFFF
44
45#define WSPI_INIT_CMD_CRC_LEN       5
46
47#define WSPI_INIT_CMD_START         0x00
48#define WSPI_INIT_CMD_TX            0x40
49/* the extra bypass bit is sampled by the TNET as '1' */
50#define WSPI_INIT_CMD_BYPASS_BIT    0x80
51#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
52#define WSPI_INIT_CMD_EN_FIXEDBUSY  0x80
53#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
54#define WSPI_INIT_CMD_IOD           0x40
55#define WSPI_INIT_CMD_IP            0x20
56#define WSPI_INIT_CMD_CS            0x10
57#define WSPI_INIT_CMD_WS            0x08
58#define WSPI_INIT_CMD_WSPI          0x01
59#define WSPI_INIT_CMD_END           0x01
60
61#define WSPI_INIT_CMD_LEN           8
62
63#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
64		((WL1271_BUSY_WORD_LEN - 4) / sizeof(u32))
65#define HW_ACCESS_WSPI_INIT_CMD_MASK  0
66
67/* HW limitation: maximum possible chunk size is 4095 bytes */
68#define WSPI_MAX_CHUNK_SIZE    4092
69
70/*
71 * only support SPI for 12xx - this code should be reworked when 18xx
72 * support is introduced
73 */
74#define SPI_AGGR_BUFFER_SIZE (4 * PAGE_SIZE)
75
76/* Maximum number of SPI write chunks */
77#define WSPI_MAX_NUM_OF_CHUNKS \
78	((SPI_AGGR_BUFFER_SIZE / WSPI_MAX_CHUNK_SIZE) + 1)
79
80
81struct wl12xx_spi_glue {
82	struct device *dev;
83	struct platform_device *core;
84};
85
86static void wl12xx_spi_reset(struct device *child)
87{
88	struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
89	u8 *cmd;
90	struct spi_transfer t;
91	struct spi_message m;
92
93	cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
94	if (!cmd) {
95		dev_err(child->parent,
96			"could not allocate cmd for spi reset\n");
97		return;
98	}
99
100	memset(&t, 0, sizeof(t));
101	spi_message_init(&m);
102
103	memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
104
105	t.tx_buf = cmd;
106	t.len = WSPI_INIT_CMD_LEN;
107	spi_message_add_tail(&t, &m);
108
109	spi_sync(to_spi_device(glue->dev), &m);
110
111	kfree(cmd);
112}
113
114static void wl12xx_spi_init(struct device *child)
115{
116	struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
117	struct spi_transfer t;
118	struct spi_message m;
119	u8 *cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
120
121	if (!cmd) {
122		dev_err(child->parent,
123			"could not allocate cmd for spi init\n");
124		return;
125	}
126
127	memset(&t, 0, sizeof(t));
128	spi_message_init(&m);
129
130	/*
131	 * Set WSPI_INIT_COMMAND
132	 * the data is being send from the MSB to LSB
133	 */
134	cmd[0] = 0xff;
135	cmd[1] = 0xff;
136	cmd[2] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
137	cmd[3] = 0;
138	cmd[4] = 0;
139	cmd[5] = HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
140	cmd[5] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
141
142	cmd[6] = WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
143		| WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
144
145	if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
146		cmd[6] |= WSPI_INIT_CMD_DIS_FIXEDBUSY;
147	else
148		cmd[6] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
149
150	cmd[7] = crc7_be(0, cmd+2, WSPI_INIT_CMD_CRC_LEN) | WSPI_INIT_CMD_END;
151	/*
152	 * The above is the logical order; it must actually be stored
153	 * in the buffer byte-swapped.
154	 */
155	__swab32s((u32 *)cmd);
156	__swab32s((u32 *)cmd+1);
157
158	t.tx_buf = cmd;
159	t.len = WSPI_INIT_CMD_LEN;
160	spi_message_add_tail(&t, &m);
161
162	spi_sync(to_spi_device(glue->dev), &m);
163	kfree(cmd);
164}
165
166#define WL1271_BUSY_WORD_TIMEOUT 1000
167
168static int wl12xx_spi_read_busy(struct device *child)
169{
170	struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
171	struct wl1271 *wl = dev_get_drvdata(child);
172	struct spi_transfer t[1];
173	struct spi_message m;
174	u32 *busy_buf;
175	int num_busy_bytes = 0;
176
177	/*
178	 * Read further busy words from SPI until a non-busy word is
179	 * encountered, then read the data itself into the buffer.
180	 */
181
182	num_busy_bytes = WL1271_BUSY_WORD_TIMEOUT;
183	busy_buf = wl->buffer_busyword;
184	while (num_busy_bytes) {
185		num_busy_bytes--;
186		spi_message_init(&m);
187		memset(t, 0, sizeof(t));
188		t[0].rx_buf = busy_buf;
189		t[0].len = sizeof(u32);
190		t[0].cs_change = true;
191		spi_message_add_tail(&t[0], &m);
192		spi_sync(to_spi_device(glue->dev), &m);
193
194		if (*busy_buf & 0x1)
195			return 0;
196	}
197
198	/* The SPI bus is unresponsive, the read failed. */
199	dev_err(child->parent, "SPI read busy-word timeout!\n");
200	return -ETIMEDOUT;
201}
202
203static int __must_check wl12xx_spi_raw_read(struct device *child, int addr,
204					    void *buf, size_t len, bool fixed)
205{
206	struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
207	struct wl1271 *wl = dev_get_drvdata(child);
208	struct spi_transfer t[2];
209	struct spi_message m;
210	u32 *busy_buf;
211	u32 *cmd;
212	u32 chunk_len;
213
214	while (len > 0) {
215		chunk_len = min_t(size_t, WSPI_MAX_CHUNK_SIZE, len);
216
217		cmd = &wl->buffer_cmd;
218		busy_buf = wl->buffer_busyword;
219
220		*cmd = 0;
221		*cmd |= WSPI_CMD_READ;
222		*cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
223			WSPI_CMD_BYTE_LENGTH;
224		*cmd |= addr & WSPI_CMD_BYTE_ADDR;
225
226		if (fixed)
227			*cmd |= WSPI_CMD_FIXED;
228
229		spi_message_init(&m);
230		memset(t, 0, sizeof(t));
231
232		t[0].tx_buf = cmd;
233		t[0].len = 4;
234		t[0].cs_change = true;
235		spi_message_add_tail(&t[0], &m);
236
237		/* Busy and non busy words read */
238		t[1].rx_buf = busy_buf;
239		t[1].len = WL1271_BUSY_WORD_LEN;
240		t[1].cs_change = true;
241		spi_message_add_tail(&t[1], &m);
242
243		spi_sync(to_spi_device(glue->dev), &m);
244
245		if (!(busy_buf[WL1271_BUSY_WORD_CNT - 1] & 0x1) &&
246		    wl12xx_spi_read_busy(child)) {
247			memset(buf, 0, chunk_len);
248			return 0;
249		}
250
251		spi_message_init(&m);
252		memset(t, 0, sizeof(t));
253
254		t[0].rx_buf = buf;
255		t[0].len = chunk_len;
256		t[0].cs_change = true;
257		spi_message_add_tail(&t[0], &m);
258
259		spi_sync(to_spi_device(glue->dev), &m);
260
261		if (!fixed)
262			addr += chunk_len;
263		buf += chunk_len;
264		len -= chunk_len;
265	}
266
267	return 0;
268}
269
270static int __must_check wl12xx_spi_raw_write(struct device *child, int addr,
271					     void *buf, size_t len, bool fixed)
272{
273	struct wl12xx_spi_glue *glue = dev_get_drvdata(child->parent);
274	/* SPI write buffers - 2 for each chunk */
275	struct spi_transfer t[2 * WSPI_MAX_NUM_OF_CHUNKS];
276	struct spi_message m;
277	u32 commands[WSPI_MAX_NUM_OF_CHUNKS]; /* 1 command per chunk */
278	u32 *cmd;
279	u32 chunk_len;
280	int i;
281
282	WARN_ON(len > SPI_AGGR_BUFFER_SIZE);
283
284	spi_message_init(&m);
285	memset(t, 0, sizeof(t));
286
287	cmd = &commands[0];
288	i = 0;
289	while (len > 0) {
290		chunk_len = min_t(size_t, WSPI_MAX_CHUNK_SIZE, len);
291
292		*cmd = 0;
293		*cmd |= WSPI_CMD_WRITE;
294		*cmd |= (chunk_len << WSPI_CMD_BYTE_LENGTH_OFFSET) &
295			WSPI_CMD_BYTE_LENGTH;
296		*cmd |= addr & WSPI_CMD_BYTE_ADDR;
297
298		if (fixed)
299			*cmd |= WSPI_CMD_FIXED;
300
301		t[i].tx_buf = cmd;
302		t[i].len = sizeof(*cmd);
303		spi_message_add_tail(&t[i++], &m);
304
305		t[i].tx_buf = buf;
306		t[i].len = chunk_len;
307		spi_message_add_tail(&t[i++], &m);
308
309		if (!fixed)
310			addr += chunk_len;
311		buf += chunk_len;
312		len -= chunk_len;
313		cmd++;
314	}
315
316	spi_sync(to_spi_device(glue->dev), &m);
317
318	return 0;
319}
320
321static struct wl1271_if_operations spi_ops = {
322	.read		= wl12xx_spi_raw_read,
323	.write		= wl12xx_spi_raw_write,
324	.reset		= wl12xx_spi_reset,
325	.init		= wl12xx_spi_init,
326	.set_block_size = NULL,
327};
328
329static int wl1271_probe(struct spi_device *spi)
330{
331	struct wl12xx_spi_glue *glue;
332	struct wlcore_platdev_data pdev_data;
333	struct resource res[1];
334	int ret;
335
336	memset(&pdev_data, 0x00, sizeof(pdev_data));
337
338	/* TODO: add DT parsing when needed */
339
340	pdev_data.if_ops = &spi_ops;
341
342	glue = devm_kzalloc(&spi->dev, sizeof(*glue), GFP_KERNEL);
343	if (!glue) {
344		dev_err(&spi->dev, "can't allocate glue\n");
345		return -ENOMEM;
346	}
347
348	glue->dev = &spi->dev;
349
350	spi_set_drvdata(spi, glue);
351
352	/* This is the only SPI value that we need to set here, the rest
353	 * comes from the board-peripherals file */
354	spi->bits_per_word = 32;
355
356	ret = spi_setup(spi);
357	if (ret < 0) {
358		dev_err(glue->dev, "spi_setup failed\n");
359		return ret;
360	}
361
362	glue->core = platform_device_alloc("wl12xx", PLATFORM_DEVID_AUTO);
363	if (!glue->core) {
364		dev_err(glue->dev, "can't allocate platform_device\n");
365		return -ENOMEM;
366	}
367
368	glue->core->dev.parent = &spi->dev;
369
370	memset(res, 0x00, sizeof(res));
371
372	res[0].start = spi->irq;
373	res[0].flags = IORESOURCE_IRQ;
374	res[0].name = "irq";
375
376	ret = platform_device_add_resources(glue->core, res, ARRAY_SIZE(res));
377	if (ret) {
378		dev_err(glue->dev, "can't add resources\n");
379		goto out_dev_put;
380	}
381
382	ret = platform_device_add_data(glue->core, &pdev_data,
383				       sizeof(pdev_data));
384	if (ret) {
385		dev_err(glue->dev, "can't add platform data\n");
386		goto out_dev_put;
387	}
388
389	ret = platform_device_add(glue->core);
390	if (ret) {
391		dev_err(glue->dev, "can't register platform device\n");
392		goto out_dev_put;
393	}
394
395	return 0;
396
397out_dev_put:
398	platform_device_put(glue->core);
399	return ret;
400}
401
402static int wl1271_remove(struct spi_device *spi)
403{
404	struct wl12xx_spi_glue *glue = spi_get_drvdata(spi);
405
406	platform_device_unregister(glue->core);
407
408	return 0;
409}
410
411
412static struct spi_driver wl1271_spi_driver = {
413	.driver = {
414		.name		= "wl1271_spi",
415		.owner		= THIS_MODULE,
416	},
417
418	.probe		= wl1271_probe,
419	.remove		= wl1271_remove,
420};
421
422module_spi_driver(wl1271_spi_driver);
423MODULE_LICENSE("GPL");
424MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
425MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
426MODULE_ALIAS("spi:wl1271");
427