Root/target/linux/generic/patches-3.7/862-gpio_spi_driver.patch

1THIS CODE IS DEPRECATED.
2
3Please use the new mainline SPI-GPIO driver, as of 2.6.29.
4
5--mb
6
7
8
9---
10 drivers/spi/Kconfig | 9 +
11 drivers/spi/Makefile | 1
12 drivers/spi/spi_gpio_old.c | 251 +++++++++++++++++++++++++++++++++++++++
13 include/linux/spi/spi_gpio_old.h | 73 +++++++++++
14 4 files changed, 334 insertions(+)
15
16--- /dev/null
17+++ b/include/linux/spi/spi_gpio_old.h
18@@ -0,0 +1,73 @@
19+/*
20+ * spi_gpio interface to platform code
21+ *
22+ * Copyright (c) 2008 Piotr Skamruk
23+ * Copyright (c) 2008 Michael Buesch
24+ *
25+ * This program is free software; you can redistribute it and/or modify
26+ * it under the terms of the GNU General Public License version 2 as
27+ * published by the Free Software Foundation.
28+ */
29+#ifndef _LINUX_SPI_SPI_GPIO
30+#define _LINUX_SPI_SPI_GPIO
31+
32+#include <linux/types.h>
33+#include <linux/spi/spi.h>
34+
35+
36+/**
37+ * struct spi_gpio_platform_data - Data definitions for a SPI-GPIO device.
38+ *
39+ * This structure holds information about a GPIO-based SPI device.
40+ *
41+ * @pin_clk: The GPIO pin number of the CLOCK pin.
42+ *
43+ * @pin_miso: The GPIO pin number of the MISO pin.
44+ *
45+ * @pin_mosi: The GPIO pin number of the MOSI pin.
46+ *
47+ * @pin_cs: The GPIO pin number of the CHIPSELECT pin.
48+ *
49+ * @cs_activelow: If true, the chip is selected when the CS line is low.
50+ *
51+ * @no_spi_delay: If true, no delay is done in the lowlevel bitbanging.
52+ * Note that doing no delay is not standards compliant,
53+ * but it might be needed to speed up transfers on some
54+ * slow embedded machines.
55+ *
56+ * @boardinfo_setup: This callback is called after the
57+ * SPI master device was registered, but before the
58+ * device is registered.
59+ * @boardinfo_setup_data: Data argument passed to boardinfo_setup().
60+ */
61+struct spi_gpio_platform_data {
62+ unsigned int pin_clk;
63+ unsigned int pin_miso;
64+ unsigned int pin_mosi;
65+ unsigned int pin_cs;
66+ bool cs_activelow;
67+ bool no_spi_delay;
68+ int (*boardinfo_setup)(struct spi_board_info *bi,
69+ struct spi_master *master,
70+ void *data);
71+ void *boardinfo_setup_data;
72+};
73+
74+/**
75+ * SPI_GPIO_PLATDEV_NAME - The platform device name string.
76+ *
77+ * The name string that has to be used for platform_device_alloc
78+ * when allocating a spi-gpio device.
79+ */
80+#define SPI_GPIO_PLATDEV_NAME "spi-gpio"
81+
82+/**
83+ * spi_gpio_next_id - Get another platform device ID number.
84+ *
85+ * This returns the next platform device ID number that has to be used
86+ * for platform_device_alloc. The ID is opaque and should not be used for
87+ * anything else.
88+ */
89+int spi_gpio_next_id(void);
90+
91+#endif /* _LINUX_SPI_SPI_GPIO */
92--- /dev/null
93+++ b/drivers/spi/spi_gpio_old.c
94@@ -0,0 +1,251 @@
95+/*
96+ * Bitbanging SPI bus driver using GPIO API
97+ *
98+ * Copyright (c) 2008 Piotr Skamruk
99+ * Copyright (c) 2008 Michael Buesch
100+ *
101+ * based on spi_s3c2410_gpio.c
102+ * Copyright (c) 2006 Ben Dooks
103+ * Copyright (c) 2006 Simtec Electronics
104+ * and on i2c-gpio.c
105+ * Copyright (C) 2007 Atmel Corporation
106+ *
107+ * This program is free software; you can redistribute it and/or modify
108+ * it under the terms of the GNU General Public License version 2 as
109+ * published by the Free Software Foundation.
110+ */
111+
112+#include <linux/kernel.h>
113+#include <linux/init.h>
114+#include <linux/delay.h>
115+#include <linux/spinlock.h>
116+#include <linux/workqueue.h>
117+#include <linux/module.h>
118+#include <linux/platform_device.h>
119+#include <linux/spi/spi.h>
120+#include <linux/spi/spi_bitbang.h>
121+#include <linux/spi/spi_gpio_old.h>
122+#include <linux/gpio.h>
123+#include <asm/atomic.h>
124+
125+
126+struct spi_gpio {
127+ struct spi_bitbang bitbang;
128+ struct spi_gpio_platform_data *info;
129+ struct platform_device *pdev;
130+ struct spi_board_info bi;
131+};
132+
133+
134+static inline struct spi_gpio *spidev_to_sg(struct spi_device *dev)
135+{
136+ return dev->controller_data;
137+}
138+
139+static inline void setsck(struct spi_device *dev, int val)
140+{
141+ struct spi_gpio *sp = spidev_to_sg(dev);
142+ gpio_set_value(sp->info->pin_clk, val ? 1 : 0);
143+}
144+
145+static inline void setmosi(struct spi_device *dev, int val)
146+{
147+ struct spi_gpio *sp = spidev_to_sg(dev);
148+ gpio_set_value(sp->info->pin_mosi, val ? 1 : 0);
149+}
150+
151+static inline u32 getmiso(struct spi_device *dev)
152+{
153+ struct spi_gpio *sp = spidev_to_sg(dev);
154+ return gpio_get_value(sp->info->pin_miso) ? 1 : 0;
155+}
156+
157+static inline void do_spidelay(struct spi_device *dev, unsigned nsecs)
158+{
159+ struct spi_gpio *sp = spidev_to_sg(dev);
160+
161+ if (!sp->info->no_spi_delay)
162+ ndelay(nsecs);
163+}
164+
165+#define spidelay(nsecs) do { \
166+ /* Steal the spi_device pointer from our caller. \
167+ * The bitbang-API should probably get fixed here... */ \
168+ do_spidelay(spi, nsecs); \
169+ } while (0)
170+
171+#define EXPAND_BITBANG_TXRX
172+#include "spi-bitbang-txrx.h"
173+
174+static u32 spi_gpio_txrx_mode0(struct spi_device *spi,
175+ unsigned nsecs, u32 word, u8 bits)
176+{
177+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
178+}
179+
180+static u32 spi_gpio_txrx_mode1(struct spi_device *spi,
181+ unsigned nsecs, u32 word, u8 bits)
182+{
183+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
184+}
185+
186+static u32 spi_gpio_txrx_mode2(struct spi_device *spi,
187+ unsigned nsecs, u32 word, u8 bits)
188+{
189+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
190+}
191+
192+static u32 spi_gpio_txrx_mode3(struct spi_device *spi,
193+ unsigned nsecs, u32 word, u8 bits)
194+{
195+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
196+}
197+
198+static void spi_gpio_chipselect(struct spi_device *dev, int on)
199+{
200+ struct spi_gpio *sp = spidev_to_sg(dev);
201+
202+ if (sp->info->cs_activelow)
203+ on = !on;
204+ gpio_set_value(sp->info->pin_cs, on ? 1 : 0);
205+}
206+
207+static int spi_gpio_probe(struct platform_device *pdev)
208+{
209+ struct spi_master *master;
210+ struct spi_gpio_platform_data *pdata;
211+ struct spi_gpio *sp;
212+ struct spi_device *spidev;
213+ int err;
214+
215+ pdata = pdev->dev.platform_data;
216+ if (!pdata)
217+ return -ENXIO;
218+
219+ err = -ENOMEM;
220+ master = spi_alloc_master(&pdev->dev, sizeof(struct spi_gpio));
221+ if (!master)
222+ goto err_alloc_master;
223+
224+ sp = spi_master_get_devdata(master);
225+ platform_set_drvdata(pdev, sp);
226+ sp->info = pdata;
227+
228+ err = gpio_request(pdata->pin_clk, "spi_clock");
229+ if (err)
230+ goto err_request_clk;
231+ err = gpio_request(pdata->pin_mosi, "spi_mosi");
232+ if (err)
233+ goto err_request_mosi;
234+ err = gpio_request(pdata->pin_miso, "spi_miso");
235+ if (err)
236+ goto err_request_miso;
237+ err = gpio_request(pdata->pin_cs, "spi_cs");
238+ if (err)
239+ goto err_request_cs;
240+
241+ sp->bitbang.master = spi_master_get(master);
242+ sp->bitbang.master->bus_num = -1;
243+ sp->bitbang.master->num_chipselect = 1;
244+ sp->bitbang.chipselect = spi_gpio_chipselect;
245+ sp->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_mode0;
246+ sp->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_mode1;
247+ sp->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_mode2;
248+ sp->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_mode3;
249+
250+ gpio_direction_output(pdata->pin_clk, 0);
251+ gpio_direction_output(pdata->pin_mosi, 0);
252+ gpio_direction_output(pdata->pin_cs,
253+ pdata->cs_activelow ? 1 : 0);
254+ gpio_direction_input(pdata->pin_miso);
255+
256+ err = spi_bitbang_start(&sp->bitbang);
257+ if (err)
258+ goto err_no_bitbang;
259+ err = pdata->boardinfo_setup(&sp->bi, master,
260+ pdata->boardinfo_setup_data);
261+ if (err)
262+ goto err_bi_setup;
263+ sp->bi.controller_data = sp;
264+ spidev = spi_new_device(master, &sp->bi);
265+ if (!spidev)
266+ goto err_new_dev;
267+
268+ return 0;
269+
270+err_new_dev:
271+err_bi_setup:
272+ spi_bitbang_stop(&sp->bitbang);
273+err_no_bitbang:
274+ spi_master_put(sp->bitbang.master);
275+ gpio_free(pdata->pin_cs);
276+err_request_cs:
277+ gpio_free(pdata->pin_miso);
278+err_request_miso:
279+ gpio_free(pdata->pin_mosi);
280+err_request_mosi:
281+ gpio_free(pdata->pin_clk);
282+err_request_clk:
283+ kfree(master);
284+
285+err_alloc_master:
286+ return err;
287+}
288+
289+static int __devexit spi_gpio_remove(struct platform_device *pdev)
290+{
291+ struct spi_gpio *sp;
292+ struct spi_gpio_platform_data *pdata;
293+
294+ pdata = pdev->dev.platform_data;
295+ sp = platform_get_drvdata(pdev);
296+
297+ gpio_free(pdata->pin_clk);
298+ gpio_free(pdata->pin_mosi);
299+ gpio_free(pdata->pin_miso);
300+ gpio_free(pdata->pin_cs);
301+ spi_bitbang_stop(&sp->bitbang);
302+ spi_master_put(sp->bitbang.master);
303+
304+ return 0;
305+}
306+
307+static struct platform_driver spi_gpio_driver = {
308+ .driver = {
309+ .name = SPI_GPIO_PLATDEV_NAME,
310+ .owner = THIS_MODULE,
311+ },
312+ .probe = spi_gpio_probe,
313+ .remove = __devexit_p(spi_gpio_remove),
314+};
315+
316+int spi_gpio_next_id(void)
317+{
318+ static atomic_t counter = ATOMIC_INIT(-1);
319+
320+ return atomic_inc_return(&counter);
321+}
322+EXPORT_SYMBOL(spi_gpio_next_id);
323+
324+static int __init spi_gpio_init(void)
325+{
326+ int err;
327+
328+ err = platform_driver_register(&spi_gpio_driver);
329+ if (err)
330+ printk(KERN_ERR "spi-gpio: register failed: %d\n", err);
331+
332+ return err;
333+}
334+module_init(spi_gpio_init);
335+
336+static void __exit spi_gpio_exit(void)
337+{
338+ platform_driver_unregister(&spi_gpio_driver);
339+}
340+module_exit(spi_gpio_exit);
341+
342+MODULE_AUTHOR("Piot Skamruk <piotr.skamruk at gmail.com>");
343+MODULE_AUTHOR("Michael Buesch");
344+MODULE_DESCRIPTION("Platform independent GPIO bitbanging SPI driver");
345+MODULE_LICENSE("GPL v2");
346--- a/drivers/spi/Kconfig
347+++ b/drivers/spi/Kconfig
348@@ -170,6 +170,15 @@ config SPI_GPIO
349       GPIO operations, you should be able to leverage that for better
350       speed with a custom version of this driver; see the source code.
351 
352+config SPI_GPIO_OLD
353+ tristate "Old GPIO API based bitbanging SPI controller (DEPRECATED)"
354+ depends on SPI_MASTER && GENERIC_GPIO
355+ select SPI_BITBANG
356+ help
357+ This code is deprecated. Please use the new mainline SPI-GPIO driver.
358+
359+ If unsure, say N.
360+
361 config SPI_IMX
362     tristate "Freescale i.MX SPI controllers"
363     depends on ARCH_MXC
364--- a/drivers/spi/Makefile
365+++ b/drivers/spi/Makefile
366@@ -31,6 +31,7 @@ obj-$(CONFIG_SPI_FSL_LIB) += spi-fsl-li
367 obj-$(CONFIG_SPI_FSL_ESPI) += spi-fsl-espi.o
368 obj-$(CONFIG_SPI_FSL_SPI) += spi-fsl-spi.o
369 obj-$(CONFIG_SPI_GPIO) += spi-gpio.o
370+obj-$(CONFIG_SPI_GPIO_OLD) += spi_gpio_old.o
371 obj-$(CONFIG_SPI_IMX) += spi-imx.o
372 obj-$(CONFIG_SPI_LM70_LLP) += spi-lm70llp.o
373 obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
374

Archive Download this file



interactive