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

Archive Download this file



interactive