kernel: remove long obsolete gpio spi controller driver patch
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
		| @@ -43,22 +43,6 @@ endef | |||||||
| $(eval $(call KernelPackage,spi-bitbang)) | $(eval $(call KernelPackage,spi-bitbang)) | ||||||
|  |  | ||||||
|  |  | ||||||
| define KernelPackage/spi-gpio-old |  | ||||||
|   SUBMENU:=$(SPI_MENU) |  | ||||||
|   TITLE:=Old GPIO based bitbanging SPI controller (DEPRECATED) |  | ||||||
|   DEPENDS:=@GPIO_SUPPORT +kmod-spi-bitbang |  | ||||||
|   KCONFIG:=CONFIG_SPI_GPIO_OLD |  | ||||||
|   FILES:=$(LINUX_DIR)/drivers/spi/spi_gpio_old.ko |  | ||||||
|   AUTOLOAD:=$(call AutoProbe,spi_gpio_old) |  | ||||||
| endef |  | ||||||
|  |  | ||||||
| define KernelPackage/spi-gpio-old/description |  | ||||||
|  This package contains the GPIO based bitbanging SPI controller driver |  | ||||||
| endef |  | ||||||
|  |  | ||||||
| $(eval $(call KernelPackage,spi-gpio-old)) |  | ||||||
|  |  | ||||||
|  |  | ||||||
| define KernelPackage/spi-gpio | define KernelPackage/spi-gpio | ||||||
|   SUBMENU:=$(SPI_MENU) |   SUBMENU:=$(SPI_MENU) | ||||||
|   TITLE:=GPIO-based bitbanging SPI Master |   TITLE:=GPIO-based bitbanging SPI Master | ||||||
|   | |||||||
| @@ -3785,7 +3785,6 @@ CONFIG_SND_VERBOSE_PROCFS=y | |||||||
| # CONFIG_SPI_FSL_ESPI is not set | # CONFIG_SPI_FSL_ESPI is not set | ||||||
| # CONFIG_SPI_FSL_SPI is not set | # CONFIG_SPI_FSL_SPI is not set | ||||||
| # CONFIG_SPI_GPIO is not set | # CONFIG_SPI_GPIO is not set | ||||||
| # CONFIG_SPI_GPIO_OLD is not set |  | ||||||
| # CONFIG_SPI_LM70_LLP is not set | # CONFIG_SPI_LM70_LLP is not set | ||||||
| # CONFIG_SPI_MASTER is not set | # CONFIG_SPI_MASTER is not set | ||||||
| # CONFIG_SPI_MPC52xx is not set | # CONFIG_SPI_MPC52xx is not set | ||||||
|   | |||||||
| @@ -3939,7 +3939,6 @@ CONFIG_SND_VERBOSE_PROCFS=y | |||||||
| # CONFIG_SPI_FSL_ESPI is not set | # CONFIG_SPI_FSL_ESPI is not set | ||||||
| # CONFIG_SPI_FSL_SPI is not set | # CONFIG_SPI_FSL_SPI is not set | ||||||
| # CONFIG_SPI_GPIO is not set | # CONFIG_SPI_GPIO is not set | ||||||
| # CONFIG_SPI_GPIO_OLD is not set |  | ||||||
| # CONFIG_SPI_IMG_SPFI is not set | # CONFIG_SPI_IMG_SPFI is not set | ||||||
| # CONFIG_SPI_LM70_LLP is not set | # CONFIG_SPI_LM70_LLP is not set | ||||||
| # CONFIG_SPI_MASTER is not set | # CONFIG_SPI_MASTER is not set | ||||||
|   | |||||||
| @@ -3943,7 +3943,6 @@ CONFIG_SND_VERBOSE_PROCFS=y | |||||||
| # CONFIG_SPI_FSL_ESPI is not set | # CONFIG_SPI_FSL_ESPI is not set | ||||||
| # CONFIG_SPI_FSL_SPI is not set | # CONFIG_SPI_FSL_SPI is not set | ||||||
| # CONFIG_SPI_GPIO is not set | # CONFIG_SPI_GPIO is not set | ||||||
| # CONFIG_SPI_GPIO_OLD is not set |  | ||||||
| # CONFIG_SPI_IMG_SPFI is not set | # CONFIG_SPI_IMG_SPFI is not set | ||||||
| # CONFIG_SPI_LM70_LLP is not set | # CONFIG_SPI_LM70_LLP is not set | ||||||
| # CONFIG_SPI_MASTER is not set | # CONFIG_SPI_MASTER is not set | ||||||
|   | |||||||
| @@ -1,373 +0,0 @@ | |||||||
| THIS CODE IS DEPRECATED. |  | ||||||
|  |  | ||||||
| Please use the new mainline SPI-GPIO driver, as of 2.6.29. |  | ||||||
|  |  | ||||||
| --mb |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  drivers/spi/Kconfig              |    9 + |  | ||||||
|  drivers/spi/Makefile             |    1  |  | ||||||
|  drivers/spi/spi_gpio_old.c       |  251 +++++++++++++++++++++++++++++++++++++++ |  | ||||||
|  include/linux/spi/spi_gpio_old.h |   73 +++++++++++ |  | ||||||
|  4 files changed, 334 insertions(+) |  | ||||||
|  |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/include/linux/spi/spi_gpio_old.h |  | ||||||
| @@ -0,0 +1,73 @@ |  | ||||||
| +/* |  | ||||||
| + * spi_gpio interface to platform code |  | ||||||
| + * |  | ||||||
| + * Copyright (c) 2008 Piotr Skamruk |  | ||||||
| + * Copyright (c) 2008 Michael Buesch |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or modify |  | ||||||
| + * it under the terms of the GNU General Public License version 2 as |  | ||||||
| + * published by the Free Software Foundation. |  | ||||||
| + */ |  | ||||||
| +#ifndef _LINUX_SPI_SPI_GPIO |  | ||||||
| +#define _LINUX_SPI_SPI_GPIO |  | ||||||
| + |  | ||||||
| +#include <linux/types.h> |  | ||||||
| +#include <linux/spi/spi.h> |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
| + * struct spi_gpio_platform_data - Data definitions for a SPI-GPIO device. |  | ||||||
| + * |  | ||||||
| + * This structure holds information about a GPIO-based SPI device. |  | ||||||
| + * |  | ||||||
| + * @pin_clk: The GPIO pin number of the CLOCK pin. |  | ||||||
| + * |  | ||||||
| + * @pin_miso: The GPIO pin number of the MISO pin. |  | ||||||
| + * |  | ||||||
| + * @pin_mosi: The GPIO pin number of the MOSI pin. |  | ||||||
| + * |  | ||||||
| + * @pin_cs: The GPIO pin number of the CHIPSELECT pin. |  | ||||||
| + * |  | ||||||
| + * @cs_activelow: If true, the chip is selected when the CS line is low. |  | ||||||
| + * |  | ||||||
| + * @no_spi_delay: If true, no delay is done in the lowlevel bitbanging. |  | ||||||
| + *                Note that doing no delay is not standards compliant, |  | ||||||
| + *                but it might be needed to speed up transfers on some |  | ||||||
| + *                slow embedded machines. |  | ||||||
| + * |  | ||||||
| + * @boardinfo_setup: This callback is called after the |  | ||||||
| + *                   SPI master device was registered, but before the |  | ||||||
| + *                   device is registered. |  | ||||||
| + * @boardinfo_setup_data: Data argument passed to boardinfo_setup(). |  | ||||||
| + */ |  | ||||||
| +struct spi_gpio_platform_data { |  | ||||||
| +	unsigned int pin_clk; |  | ||||||
| +	unsigned int pin_miso; |  | ||||||
| +	unsigned int pin_mosi; |  | ||||||
| +	unsigned int pin_cs; |  | ||||||
| +	bool cs_activelow; |  | ||||||
| +	bool no_spi_delay; |  | ||||||
| +	int (*boardinfo_setup)(struct spi_board_info *bi, |  | ||||||
| +			       struct spi_master *master, |  | ||||||
| +			       void *data); |  | ||||||
| +	void *boardinfo_setup_data; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
| + * SPI_GPIO_PLATDEV_NAME - The platform device name string. |  | ||||||
| + * |  | ||||||
| + * The name string that has to be used for platform_device_alloc |  | ||||||
| + * when allocating a spi-gpio device. |  | ||||||
| + */ |  | ||||||
| +#define SPI_GPIO_PLATDEV_NAME	"spi-gpio" |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
| + * spi_gpio_next_id - Get another platform device ID number. |  | ||||||
| + * |  | ||||||
| + * This returns the next platform device ID number that has to be used |  | ||||||
| + * for platform_device_alloc. The ID is opaque and should not be used for |  | ||||||
| + * anything else. |  | ||||||
| + */ |  | ||||||
| +int spi_gpio_next_id(void); |  | ||||||
| + |  | ||||||
| +#endif /* _LINUX_SPI_SPI_GPIO */ |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/drivers/spi/spi_gpio_old.c |  | ||||||
| @@ -0,0 +1,251 @@ |  | ||||||
| +/* |  | ||||||
| + * Bitbanging SPI bus driver using GPIO API |  | ||||||
| + * |  | ||||||
| + * Copyright (c) 2008 Piotr Skamruk |  | ||||||
| + * Copyright (c) 2008 Michael Buesch |  | ||||||
| + * |  | ||||||
| + * based on spi_s3c2410_gpio.c |  | ||||||
| + *   Copyright (c) 2006 Ben Dooks |  | ||||||
| + *   Copyright (c) 2006 Simtec Electronics |  | ||||||
| + * and on i2c-gpio.c |  | ||||||
| + *   Copyright (C) 2007 Atmel Corporation |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or modify |  | ||||||
| + * it under the terms of the GNU General Public License version 2 as |  | ||||||
| + * published by the Free Software Foundation. |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +#include <linux/kernel.h> |  | ||||||
| +#include <linux/init.h> |  | ||||||
| +#include <linux/delay.h> |  | ||||||
| +#include <linux/spinlock.h> |  | ||||||
| +#include <linux/workqueue.h> |  | ||||||
| +#include <linux/module.h> |  | ||||||
| +#include <linux/platform_device.h> |  | ||||||
| +#include <linux/spi/spi.h> |  | ||||||
| +#include <linux/spi/spi_bitbang.h> |  | ||||||
| +#include <linux/spi/spi_gpio_old.h> |  | ||||||
| +#include <linux/gpio.h> |  | ||||||
| +#include <asm/atomic.h> |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +struct spi_gpio { |  | ||||||
| +	struct spi_bitbang bitbang; |  | ||||||
| +	struct spi_gpio_platform_data *info; |  | ||||||
| +	struct platform_device *pdev; |  | ||||||
| +	struct spi_board_info bi; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +static inline struct spi_gpio *spidev_to_sg(struct spi_device *dev) |  | ||||||
| +{ |  | ||||||
| +	return dev->controller_data; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void setsck(struct spi_device *dev, int val) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| +	gpio_set_value(sp->info->pin_clk, val ? 1 : 0); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void setmosi(struct spi_device *dev, int val) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| +	gpio_set_value(sp->info->pin_mosi, val ? 1 : 0); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline u32 getmiso(struct spi_device *dev) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| +	return gpio_get_value(sp->info->pin_miso) ? 1 : 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void do_spidelay(struct spi_device *dev, unsigned nsecs) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| + |  | ||||||
| +	if (!sp->info->no_spi_delay) |  | ||||||
| +		ndelay(nsecs); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +#define spidelay(nsecs) do {					\ |  | ||||||
| +	/* Steal the spi_device pointer from our caller.	\ |  | ||||||
| +	 * The bitbang-API should probably get fixed here... */	\ |  | ||||||
| +	do_spidelay(spi, nsecs);				\ |  | ||||||
| +  } while (0) |  | ||||||
| + |  | ||||||
| +#define EXPAND_BITBANG_TXRX |  | ||||||
| +#include "spi-bitbang-txrx.h" |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode0(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode1(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode2(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode3(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void spi_gpio_chipselect(struct spi_device *dev, int on) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| + |  | ||||||
| +	if (sp->info->cs_activelow) |  | ||||||
| +		on = !on; |  | ||||||
| +	gpio_set_value(sp->info->pin_cs, on ? 1 : 0); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int spi_gpio_probe(struct platform_device *pdev) |  | ||||||
| +{ |  | ||||||
| +	struct spi_master *master; |  | ||||||
| +	struct spi_gpio_platform_data *pdata; |  | ||||||
| +	struct spi_gpio *sp; |  | ||||||
| +	struct spi_device *spidev; |  | ||||||
| +	int err; |  | ||||||
| + |  | ||||||
| +	pdata = pdev->dev.platform_data; |  | ||||||
| +	if (!pdata) |  | ||||||
| +		return -ENXIO; |  | ||||||
| + |  | ||||||
| +	err = -ENOMEM; |  | ||||||
| +	master = spi_alloc_master(&pdev->dev, sizeof(struct spi_gpio)); |  | ||||||
| +	if (!master) |  | ||||||
| +		goto err_alloc_master; |  | ||||||
| + |  | ||||||
| +	sp = spi_master_get_devdata(master); |  | ||||||
| +	platform_set_drvdata(pdev, sp); |  | ||||||
| +	sp->info = pdata; |  | ||||||
| + |  | ||||||
| +	err = gpio_request(pdata->pin_clk, "spi_clock"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_clk; |  | ||||||
| +	err = gpio_request(pdata->pin_mosi, "spi_mosi"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_mosi; |  | ||||||
| +	err = gpio_request(pdata->pin_miso, "spi_miso"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_miso; |  | ||||||
| +	err = gpio_request(pdata->pin_cs, "spi_cs"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_cs; |  | ||||||
| + |  | ||||||
| +	sp->bitbang.master = spi_master_get(master); |  | ||||||
| +	sp->bitbang.master->bus_num = -1; |  | ||||||
| +	sp->bitbang.master->num_chipselect = 1; |  | ||||||
| +	sp->bitbang.chipselect = spi_gpio_chipselect; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_mode0; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_mode1; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_mode2; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_mode3; |  | ||||||
| + |  | ||||||
| +	gpio_direction_output(pdata->pin_clk, 0); |  | ||||||
| +	gpio_direction_output(pdata->pin_mosi, 0); |  | ||||||
| +	gpio_direction_output(pdata->pin_cs, |  | ||||||
| +			      pdata->cs_activelow ? 1 : 0); |  | ||||||
| +	gpio_direction_input(pdata->pin_miso); |  | ||||||
| + |  | ||||||
| +	err = spi_bitbang_start(&sp->bitbang); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_no_bitbang; |  | ||||||
| +	err = pdata->boardinfo_setup(&sp->bi, master, |  | ||||||
| +				     pdata->boardinfo_setup_data); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_bi_setup; |  | ||||||
| +	sp->bi.controller_data = sp; |  | ||||||
| +	spidev = spi_new_device(master, &sp->bi); |  | ||||||
| +	if (!spidev) |  | ||||||
| +		goto err_new_dev; |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| + |  | ||||||
| +err_new_dev: |  | ||||||
| +err_bi_setup: |  | ||||||
| +	spi_bitbang_stop(&sp->bitbang); |  | ||||||
| +err_no_bitbang: |  | ||||||
| +	spi_master_put(sp->bitbang.master); |  | ||||||
| +	gpio_free(pdata->pin_cs); |  | ||||||
| +err_request_cs: |  | ||||||
| +	gpio_free(pdata->pin_miso); |  | ||||||
| +err_request_miso: |  | ||||||
| +	gpio_free(pdata->pin_mosi); |  | ||||||
| +err_request_mosi: |  | ||||||
| +	gpio_free(pdata->pin_clk); |  | ||||||
| +err_request_clk: |  | ||||||
| +	kfree(master); |  | ||||||
| + |  | ||||||
| +err_alloc_master: |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int spi_gpio_remove(struct platform_device *pdev) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp; |  | ||||||
| +	struct spi_gpio_platform_data *pdata; |  | ||||||
| + |  | ||||||
| +	pdata = pdev->dev.platform_data; |  | ||||||
| +	sp = platform_get_drvdata(pdev); |  | ||||||
| + |  | ||||||
| +	gpio_free(pdata->pin_clk); |  | ||||||
| +	gpio_free(pdata->pin_mosi); |  | ||||||
| +	gpio_free(pdata->pin_miso); |  | ||||||
| +	gpio_free(pdata->pin_cs); |  | ||||||
| +	spi_bitbang_stop(&sp->bitbang); |  | ||||||
| +	spi_master_put(sp->bitbang.master); |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static struct platform_driver spi_gpio_driver = { |  | ||||||
| +	.driver		= { |  | ||||||
| +		.name	= SPI_GPIO_PLATDEV_NAME, |  | ||||||
| +		.owner	= THIS_MODULE, |  | ||||||
| +	}, |  | ||||||
| +	.probe		= spi_gpio_probe, |  | ||||||
| +	.remove		= spi_gpio_remove, |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +int spi_gpio_next_id(void) |  | ||||||
| +{ |  | ||||||
| +	static atomic_t counter = ATOMIC_INIT(-1); |  | ||||||
| + |  | ||||||
| +	return atomic_inc_return(&counter); |  | ||||||
| +} |  | ||||||
| +EXPORT_SYMBOL(spi_gpio_next_id); |  | ||||||
| + |  | ||||||
| +static int __init spi_gpio_init(void) |  | ||||||
| +{ |  | ||||||
| +	int err; |  | ||||||
| + |  | ||||||
| +	err = platform_driver_register(&spi_gpio_driver); |  | ||||||
| +	if (err) |  | ||||||
| +		printk(KERN_ERR "spi-gpio: register failed: %d\n", err); |  | ||||||
| + |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| +module_init(spi_gpio_init); |  | ||||||
| + |  | ||||||
| +static void __exit spi_gpio_exit(void) |  | ||||||
| +{ |  | ||||||
| +	platform_driver_unregister(&spi_gpio_driver); |  | ||||||
| +} |  | ||||||
| +module_exit(spi_gpio_exit); |  | ||||||
| + |  | ||||||
| +MODULE_AUTHOR("Piot Skamruk <piotr.skamruk at gmail.com>"); |  | ||||||
| +MODULE_AUTHOR("Michael Buesch"); |  | ||||||
| +MODULE_DESCRIPTION("Platform independent GPIO bitbanging SPI driver"); |  | ||||||
| +MODULE_LICENSE("GPL v2"); |  | ||||||
| --- a/drivers/spi/Kconfig |  | ||||||
| +++ b/drivers/spi/Kconfig |  | ||||||
| @@ -225,6 +225,15 @@ config SPI_GPIO |  | ||||||
|  	  GPIO operations, you should be able to leverage that for better |  | ||||||
|  	  speed with a custom version of this driver; see the source code. |  | ||||||
|   |  | ||||||
| +config SPI_GPIO_OLD |  | ||||||
| +	tristate "Old GPIO API based bitbanging SPI controller (DEPRECATED)" |  | ||||||
| +	depends on SPI_MASTER && GPIOLIB |  | ||||||
| +	select SPI_BITBANG |  | ||||||
| +	help |  | ||||||
| +	  This code is deprecated. Please use the new mainline SPI-GPIO driver. |  | ||||||
| + |  | ||||||
| +	  If unsure, say N. |  | ||||||
| + |  | ||||||
|  config SPI_IMX |  | ||||||
|  	tristate "Freescale i.MX SPI controllers" |  | ||||||
|  	depends on ARCH_MXC || COMPILE_TEST |  | ||||||
| --- a/drivers/spi/Makefile |  | ||||||
| +++ b/drivers/spi/Makefile |  | ||||||
| @@ -40,6 +40,7 @@ obj-$(CONFIG_SPI_FSL_LIB)		+= spi-fsl-li |  | ||||||
|  obj-$(CONFIG_SPI_FSL_ESPI)		+= spi-fsl-espi.o |  | ||||||
|  obj-$(CONFIG_SPI_FSL_SPI)		+= spi-fsl-spi.o |  | ||||||
|  obj-$(CONFIG_SPI_GPIO)			+= spi-gpio.o |  | ||||||
| +obj-$(CONFIG_SPI_GPIO_OLD)		+= spi_gpio_old.o |  | ||||||
|  obj-$(CONFIG_SPI_IMX)			+= spi-imx.o |  | ||||||
|  obj-$(CONFIG_SPI_LM70_LLP)		+= spi-lm70llp.o |  | ||||||
|  obj-$(CONFIG_SPI_MPC512x_PSC)		+= spi-mpc512x-psc.o |  | ||||||
| @@ -1,373 +0,0 @@ | |||||||
| THIS CODE IS DEPRECATED. |  | ||||||
|  |  | ||||||
| Please use the new mainline SPI-GPIO driver, as of 2.6.29. |  | ||||||
|  |  | ||||||
| --mb |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  drivers/spi/Kconfig              |    9 + |  | ||||||
|  drivers/spi/Makefile             |    1  |  | ||||||
|  drivers/spi/spi_gpio_old.c       |  251 +++++++++++++++++++++++++++++++++++++++ |  | ||||||
|  include/linux/spi/spi_gpio_old.h |   73 +++++++++++ |  | ||||||
|  4 files changed, 334 insertions(+) |  | ||||||
|  |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/include/linux/spi/spi_gpio_old.h |  | ||||||
| @@ -0,0 +1,73 @@ |  | ||||||
| +/* |  | ||||||
| + * spi_gpio interface to platform code |  | ||||||
| + * |  | ||||||
| + * Copyright (c) 2008 Piotr Skamruk |  | ||||||
| + * Copyright (c) 2008 Michael Buesch |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or modify |  | ||||||
| + * it under the terms of the GNU General Public License version 2 as |  | ||||||
| + * published by the Free Software Foundation. |  | ||||||
| + */ |  | ||||||
| +#ifndef _LINUX_SPI_SPI_GPIO |  | ||||||
| +#define _LINUX_SPI_SPI_GPIO |  | ||||||
| + |  | ||||||
| +#include <linux/types.h> |  | ||||||
| +#include <linux/spi/spi.h> |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
| + * struct spi_gpio_platform_data - Data definitions for a SPI-GPIO device. |  | ||||||
| + * |  | ||||||
| + * This structure holds information about a GPIO-based SPI device. |  | ||||||
| + * |  | ||||||
| + * @pin_clk: The GPIO pin number of the CLOCK pin. |  | ||||||
| + * |  | ||||||
| + * @pin_miso: The GPIO pin number of the MISO pin. |  | ||||||
| + * |  | ||||||
| + * @pin_mosi: The GPIO pin number of the MOSI pin. |  | ||||||
| + * |  | ||||||
| + * @pin_cs: The GPIO pin number of the CHIPSELECT pin. |  | ||||||
| + * |  | ||||||
| + * @cs_activelow: If true, the chip is selected when the CS line is low. |  | ||||||
| + * |  | ||||||
| + * @no_spi_delay: If true, no delay is done in the lowlevel bitbanging. |  | ||||||
| + *                Note that doing no delay is not standards compliant, |  | ||||||
| + *                but it might be needed to speed up transfers on some |  | ||||||
| + *                slow embedded machines. |  | ||||||
| + * |  | ||||||
| + * @boardinfo_setup: This callback is called after the |  | ||||||
| + *                   SPI master device was registered, but before the |  | ||||||
| + *                   device is registered. |  | ||||||
| + * @boardinfo_setup_data: Data argument passed to boardinfo_setup(). |  | ||||||
| + */ |  | ||||||
| +struct spi_gpio_platform_data { |  | ||||||
| +	unsigned int pin_clk; |  | ||||||
| +	unsigned int pin_miso; |  | ||||||
| +	unsigned int pin_mosi; |  | ||||||
| +	unsigned int pin_cs; |  | ||||||
| +	bool cs_activelow; |  | ||||||
| +	bool no_spi_delay; |  | ||||||
| +	int (*boardinfo_setup)(struct spi_board_info *bi, |  | ||||||
| +			       struct spi_master *master, |  | ||||||
| +			       void *data); |  | ||||||
| +	void *boardinfo_setup_data; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
| + * SPI_GPIO_PLATDEV_NAME - The platform device name string. |  | ||||||
| + * |  | ||||||
| + * The name string that has to be used for platform_device_alloc |  | ||||||
| + * when allocating a spi-gpio device. |  | ||||||
| + */ |  | ||||||
| +#define SPI_GPIO_PLATDEV_NAME	"spi-gpio" |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
| + * spi_gpio_next_id - Get another platform device ID number. |  | ||||||
| + * |  | ||||||
| + * This returns the next platform device ID number that has to be used |  | ||||||
| + * for platform_device_alloc. The ID is opaque and should not be used for |  | ||||||
| + * anything else. |  | ||||||
| + */ |  | ||||||
| +int spi_gpio_next_id(void); |  | ||||||
| + |  | ||||||
| +#endif /* _LINUX_SPI_SPI_GPIO */ |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/drivers/spi/spi_gpio_old.c |  | ||||||
| @@ -0,0 +1,251 @@ |  | ||||||
| +/* |  | ||||||
| + * Bitbanging SPI bus driver using GPIO API |  | ||||||
| + * |  | ||||||
| + * Copyright (c) 2008 Piotr Skamruk |  | ||||||
| + * Copyright (c) 2008 Michael Buesch |  | ||||||
| + * |  | ||||||
| + * based on spi_s3c2410_gpio.c |  | ||||||
| + *   Copyright (c) 2006 Ben Dooks |  | ||||||
| + *   Copyright (c) 2006 Simtec Electronics |  | ||||||
| + * and on i2c-gpio.c |  | ||||||
| + *   Copyright (C) 2007 Atmel Corporation |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or modify |  | ||||||
| + * it under the terms of the GNU General Public License version 2 as |  | ||||||
| + * published by the Free Software Foundation. |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +#include <linux/kernel.h> |  | ||||||
| +#include <linux/init.h> |  | ||||||
| +#include <linux/delay.h> |  | ||||||
| +#include <linux/spinlock.h> |  | ||||||
| +#include <linux/workqueue.h> |  | ||||||
| +#include <linux/module.h> |  | ||||||
| +#include <linux/platform_device.h> |  | ||||||
| +#include <linux/spi/spi.h> |  | ||||||
| +#include <linux/spi/spi_bitbang.h> |  | ||||||
| +#include <linux/spi/spi_gpio_old.h> |  | ||||||
| +#include <linux/gpio.h> |  | ||||||
| +#include <asm/atomic.h> |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +struct spi_gpio { |  | ||||||
| +	struct spi_bitbang bitbang; |  | ||||||
| +	struct spi_gpio_platform_data *info; |  | ||||||
| +	struct platform_device *pdev; |  | ||||||
| +	struct spi_board_info bi; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +static inline struct spi_gpio *spidev_to_sg(struct spi_device *dev) |  | ||||||
| +{ |  | ||||||
| +	return dev->controller_data; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void setsck(struct spi_device *dev, int val) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| +	gpio_set_value(sp->info->pin_clk, val ? 1 : 0); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void setmosi(struct spi_device *dev, int val) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| +	gpio_set_value(sp->info->pin_mosi, val ? 1 : 0); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline u32 getmiso(struct spi_device *dev) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| +	return gpio_get_value(sp->info->pin_miso) ? 1 : 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void do_spidelay(struct spi_device *dev, unsigned nsecs) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| + |  | ||||||
| +	if (!sp->info->no_spi_delay) |  | ||||||
| +		ndelay(nsecs); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +#define spidelay(nsecs) do {					\ |  | ||||||
| +	/* Steal the spi_device pointer from our caller.	\ |  | ||||||
| +	 * The bitbang-API should probably get fixed here... */	\ |  | ||||||
| +	do_spidelay(spi, nsecs);				\ |  | ||||||
| +  } while (0) |  | ||||||
| + |  | ||||||
| +#define EXPAND_BITBANG_TXRX |  | ||||||
| +#include "spi-bitbang-txrx.h" |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode0(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode1(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode2(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode3(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void spi_gpio_chipselect(struct spi_device *dev, int on) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| + |  | ||||||
| +	if (sp->info->cs_activelow) |  | ||||||
| +		on = !on; |  | ||||||
| +	gpio_set_value(sp->info->pin_cs, on ? 1 : 0); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int spi_gpio_probe(struct platform_device *pdev) |  | ||||||
| +{ |  | ||||||
| +	struct spi_master *master; |  | ||||||
| +	struct spi_gpio_platform_data *pdata; |  | ||||||
| +	struct spi_gpio *sp; |  | ||||||
| +	struct spi_device *spidev; |  | ||||||
| +	int err; |  | ||||||
| + |  | ||||||
| +	pdata = pdev->dev.platform_data; |  | ||||||
| +	if (!pdata) |  | ||||||
| +		return -ENXIO; |  | ||||||
| + |  | ||||||
| +	err = -ENOMEM; |  | ||||||
| +	master = spi_alloc_master(&pdev->dev, sizeof(struct spi_gpio)); |  | ||||||
| +	if (!master) |  | ||||||
| +		goto err_alloc_master; |  | ||||||
| + |  | ||||||
| +	sp = spi_master_get_devdata(master); |  | ||||||
| +	platform_set_drvdata(pdev, sp); |  | ||||||
| +	sp->info = pdata; |  | ||||||
| + |  | ||||||
| +	err = gpio_request(pdata->pin_clk, "spi_clock"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_clk; |  | ||||||
| +	err = gpio_request(pdata->pin_mosi, "spi_mosi"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_mosi; |  | ||||||
| +	err = gpio_request(pdata->pin_miso, "spi_miso"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_miso; |  | ||||||
| +	err = gpio_request(pdata->pin_cs, "spi_cs"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_cs; |  | ||||||
| + |  | ||||||
| +	sp->bitbang.master = spi_master_get(master); |  | ||||||
| +	sp->bitbang.master->bus_num = -1; |  | ||||||
| +	sp->bitbang.master->num_chipselect = 1; |  | ||||||
| +	sp->bitbang.chipselect = spi_gpio_chipselect; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_mode0; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_mode1; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_mode2; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_mode3; |  | ||||||
| + |  | ||||||
| +	gpio_direction_output(pdata->pin_clk, 0); |  | ||||||
| +	gpio_direction_output(pdata->pin_mosi, 0); |  | ||||||
| +	gpio_direction_output(pdata->pin_cs, |  | ||||||
| +			      pdata->cs_activelow ? 1 : 0); |  | ||||||
| +	gpio_direction_input(pdata->pin_miso); |  | ||||||
| + |  | ||||||
| +	err = spi_bitbang_start(&sp->bitbang); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_no_bitbang; |  | ||||||
| +	err = pdata->boardinfo_setup(&sp->bi, master, |  | ||||||
| +				     pdata->boardinfo_setup_data); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_bi_setup; |  | ||||||
| +	sp->bi.controller_data = sp; |  | ||||||
| +	spidev = spi_new_device(master, &sp->bi); |  | ||||||
| +	if (!spidev) |  | ||||||
| +		goto err_new_dev; |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| + |  | ||||||
| +err_new_dev: |  | ||||||
| +err_bi_setup: |  | ||||||
| +	spi_bitbang_stop(&sp->bitbang); |  | ||||||
| +err_no_bitbang: |  | ||||||
| +	spi_master_put(sp->bitbang.master); |  | ||||||
| +	gpio_free(pdata->pin_cs); |  | ||||||
| +err_request_cs: |  | ||||||
| +	gpio_free(pdata->pin_miso); |  | ||||||
| +err_request_miso: |  | ||||||
| +	gpio_free(pdata->pin_mosi); |  | ||||||
| +err_request_mosi: |  | ||||||
| +	gpio_free(pdata->pin_clk); |  | ||||||
| +err_request_clk: |  | ||||||
| +	kfree(master); |  | ||||||
| + |  | ||||||
| +err_alloc_master: |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int spi_gpio_remove(struct platform_device *pdev) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp; |  | ||||||
| +	struct spi_gpio_platform_data *pdata; |  | ||||||
| + |  | ||||||
| +	pdata = pdev->dev.platform_data; |  | ||||||
| +	sp = platform_get_drvdata(pdev); |  | ||||||
| + |  | ||||||
| +	gpio_free(pdata->pin_clk); |  | ||||||
| +	gpio_free(pdata->pin_mosi); |  | ||||||
| +	gpio_free(pdata->pin_miso); |  | ||||||
| +	gpio_free(pdata->pin_cs); |  | ||||||
| +	spi_bitbang_stop(&sp->bitbang); |  | ||||||
| +	spi_master_put(sp->bitbang.master); |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static struct platform_driver spi_gpio_driver = { |  | ||||||
| +	.driver		= { |  | ||||||
| +		.name	= SPI_GPIO_PLATDEV_NAME, |  | ||||||
| +		.owner	= THIS_MODULE, |  | ||||||
| +	}, |  | ||||||
| +	.probe		= spi_gpio_probe, |  | ||||||
| +	.remove		= spi_gpio_remove, |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +int spi_gpio_next_id(void) |  | ||||||
| +{ |  | ||||||
| +	static atomic_t counter = ATOMIC_INIT(-1); |  | ||||||
| + |  | ||||||
| +	return atomic_inc_return(&counter); |  | ||||||
| +} |  | ||||||
| +EXPORT_SYMBOL(spi_gpio_next_id); |  | ||||||
| + |  | ||||||
| +static int __init spi_gpio_init(void) |  | ||||||
| +{ |  | ||||||
| +	int err; |  | ||||||
| + |  | ||||||
| +	err = platform_driver_register(&spi_gpio_driver); |  | ||||||
| +	if (err) |  | ||||||
| +		printk(KERN_ERR "spi-gpio: register failed: %d\n", err); |  | ||||||
| + |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| +module_init(spi_gpio_init); |  | ||||||
| + |  | ||||||
| +static void __exit spi_gpio_exit(void) |  | ||||||
| +{ |  | ||||||
| +	platform_driver_unregister(&spi_gpio_driver); |  | ||||||
| +} |  | ||||||
| +module_exit(spi_gpio_exit); |  | ||||||
| + |  | ||||||
| +MODULE_AUTHOR("Piot Skamruk <piotr.skamruk at gmail.com>"); |  | ||||||
| +MODULE_AUTHOR("Michael Buesch"); |  | ||||||
| +MODULE_DESCRIPTION("Platform independent GPIO bitbanging SPI driver"); |  | ||||||
| +MODULE_LICENSE("GPL v2"); |  | ||||||
| --- a/drivers/spi/Kconfig |  | ||||||
| +++ b/drivers/spi/Kconfig |  | ||||||
| @@ -242,6 +242,15 @@ config SPI_IMG_SPFI |  | ||||||
|  	  This enables support for the SPFI master controller found on |  | ||||||
|  	  IMG SoCs. |  | ||||||
|   |  | ||||||
| +config SPI_GPIO_OLD |  | ||||||
| +	tristate "Old GPIO API based bitbanging SPI controller (DEPRECATED)" |  | ||||||
| +	depends on SPI_MASTER && GPIOLIB |  | ||||||
| +	select SPI_BITBANG |  | ||||||
| +	help |  | ||||||
| +	  This code is deprecated. Please use the new mainline SPI-GPIO driver. |  | ||||||
| + |  | ||||||
| +	  If unsure, say N. |  | ||||||
| + |  | ||||||
|  config SPI_IMX |  | ||||||
|  	tristate "Freescale i.MX SPI controllers" |  | ||||||
|  	depends on ARCH_MXC || COMPILE_TEST |  | ||||||
| --- a/drivers/spi/Makefile |  | ||||||
| +++ b/drivers/spi/Makefile |  | ||||||
| @@ -41,6 +41,7 @@ obj-$(CONFIG_SPI_FSL_LIB)		+= spi-fsl-li |  | ||||||
|  obj-$(CONFIG_SPI_FSL_ESPI)		+= spi-fsl-espi.o |  | ||||||
|  obj-$(CONFIG_SPI_FSL_SPI)		+= spi-fsl-spi.o |  | ||||||
|  obj-$(CONFIG_SPI_GPIO)			+= spi-gpio.o |  | ||||||
| +obj-$(CONFIG_SPI_GPIO_OLD)		+= spi_gpio_old.o |  | ||||||
|  obj-$(CONFIG_SPI_IMG_SPFI)		+= spi-img-spfi.o |  | ||||||
|  obj-$(CONFIG_SPI_IMX)			+= spi-imx.o |  | ||||||
|  obj-$(CONFIG_SPI_LM70_LLP)		+= spi-lm70llp.o |  | ||||||
| @@ -1,373 +0,0 @@ | |||||||
| THIS CODE IS DEPRECATED. |  | ||||||
|  |  | ||||||
| Please use the new mainline SPI-GPIO driver, as of 2.6.29. |  | ||||||
|  |  | ||||||
| --mb |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| --- |  | ||||||
|  drivers/spi/Kconfig              |    9 + |  | ||||||
|  drivers/spi/Makefile             |    1  |  | ||||||
|  drivers/spi/spi_gpio_old.c       |  251 +++++++++++++++++++++++++++++++++++++++ |  | ||||||
|  include/linux/spi/spi_gpio_old.h |   73 +++++++++++ |  | ||||||
|  4 files changed, 334 insertions(+) |  | ||||||
|  |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/include/linux/spi/spi_gpio_old.h |  | ||||||
| @@ -0,0 +1,73 @@ |  | ||||||
| +/* |  | ||||||
| + * spi_gpio interface to platform code |  | ||||||
| + * |  | ||||||
| + * Copyright (c) 2008 Piotr Skamruk |  | ||||||
| + * Copyright (c) 2008 Michael Buesch |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or modify |  | ||||||
| + * it under the terms of the GNU General Public License version 2 as |  | ||||||
| + * published by the Free Software Foundation. |  | ||||||
| + */ |  | ||||||
| +#ifndef _LINUX_SPI_SPI_GPIO |  | ||||||
| +#define _LINUX_SPI_SPI_GPIO |  | ||||||
| + |  | ||||||
| +#include <linux/types.h> |  | ||||||
| +#include <linux/spi/spi.h> |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
| + * struct spi_gpio_platform_data - Data definitions for a SPI-GPIO device. |  | ||||||
| + * |  | ||||||
| + * This structure holds information about a GPIO-based SPI device. |  | ||||||
| + * |  | ||||||
| + * @pin_clk: The GPIO pin number of the CLOCK pin. |  | ||||||
| + * |  | ||||||
| + * @pin_miso: The GPIO pin number of the MISO pin. |  | ||||||
| + * |  | ||||||
| + * @pin_mosi: The GPIO pin number of the MOSI pin. |  | ||||||
| + * |  | ||||||
| + * @pin_cs: The GPIO pin number of the CHIPSELECT pin. |  | ||||||
| + * |  | ||||||
| + * @cs_activelow: If true, the chip is selected when the CS line is low. |  | ||||||
| + * |  | ||||||
| + * @no_spi_delay: If true, no delay is done in the lowlevel bitbanging. |  | ||||||
| + *                Note that doing no delay is not standards compliant, |  | ||||||
| + *                but it might be needed to speed up transfers on some |  | ||||||
| + *                slow embedded machines. |  | ||||||
| + * |  | ||||||
| + * @boardinfo_setup: This callback is called after the |  | ||||||
| + *                   SPI master device was registered, but before the |  | ||||||
| + *                   device is registered. |  | ||||||
| + * @boardinfo_setup_data: Data argument passed to boardinfo_setup(). |  | ||||||
| + */ |  | ||||||
| +struct spi_gpio_platform_data { |  | ||||||
| +	unsigned int pin_clk; |  | ||||||
| +	unsigned int pin_miso; |  | ||||||
| +	unsigned int pin_mosi; |  | ||||||
| +	unsigned int pin_cs; |  | ||||||
| +	bool cs_activelow; |  | ||||||
| +	bool no_spi_delay; |  | ||||||
| +	int (*boardinfo_setup)(struct spi_board_info *bi, |  | ||||||
| +			       struct spi_master *master, |  | ||||||
| +			       void *data); |  | ||||||
| +	void *boardinfo_setup_data; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
| + * SPI_GPIO_PLATDEV_NAME - The platform device name string. |  | ||||||
| + * |  | ||||||
| + * The name string that has to be used for platform_device_alloc |  | ||||||
| + * when allocating a spi-gpio device. |  | ||||||
| + */ |  | ||||||
| +#define SPI_GPIO_PLATDEV_NAME	"spi-gpio" |  | ||||||
| + |  | ||||||
| +/** |  | ||||||
| + * spi_gpio_next_id - Get another platform device ID number. |  | ||||||
| + * |  | ||||||
| + * This returns the next platform device ID number that has to be used |  | ||||||
| + * for platform_device_alloc. The ID is opaque and should not be used for |  | ||||||
| + * anything else. |  | ||||||
| + */ |  | ||||||
| +int spi_gpio_next_id(void); |  | ||||||
| + |  | ||||||
| +#endif /* _LINUX_SPI_SPI_GPIO */ |  | ||||||
| --- /dev/null |  | ||||||
| +++ b/drivers/spi/spi_gpio_old.c |  | ||||||
| @@ -0,0 +1,251 @@ |  | ||||||
| +/* |  | ||||||
| + * Bitbanging SPI bus driver using GPIO API |  | ||||||
| + * |  | ||||||
| + * Copyright (c) 2008 Piotr Skamruk |  | ||||||
| + * Copyright (c) 2008 Michael Buesch |  | ||||||
| + * |  | ||||||
| + * based on spi_s3c2410_gpio.c |  | ||||||
| + *   Copyright (c) 2006 Ben Dooks |  | ||||||
| + *   Copyright (c) 2006 Simtec Electronics |  | ||||||
| + * and on i2c-gpio.c |  | ||||||
| + *   Copyright (C) 2007 Atmel Corporation |  | ||||||
| + * |  | ||||||
| + * This program is free software; you can redistribute it and/or modify |  | ||||||
| + * it under the terms of the GNU General Public License version 2 as |  | ||||||
| + * published by the Free Software Foundation. |  | ||||||
| + */ |  | ||||||
| + |  | ||||||
| +#include <linux/kernel.h> |  | ||||||
| +#include <linux/init.h> |  | ||||||
| +#include <linux/delay.h> |  | ||||||
| +#include <linux/spinlock.h> |  | ||||||
| +#include <linux/workqueue.h> |  | ||||||
| +#include <linux/module.h> |  | ||||||
| +#include <linux/platform_device.h> |  | ||||||
| +#include <linux/spi/spi.h> |  | ||||||
| +#include <linux/spi/spi_bitbang.h> |  | ||||||
| +#include <linux/spi/spi_gpio_old.h> |  | ||||||
| +#include <linux/gpio.h> |  | ||||||
| +#include <asm/atomic.h> |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +struct spi_gpio { |  | ||||||
| +	struct spi_bitbang bitbang; |  | ||||||
| +	struct spi_gpio_platform_data *info; |  | ||||||
| +	struct platform_device *pdev; |  | ||||||
| +	struct spi_board_info bi; |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| + |  | ||||||
| +static inline struct spi_gpio *spidev_to_sg(struct spi_device *dev) |  | ||||||
| +{ |  | ||||||
| +	return dev->controller_data; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void setsck(struct spi_device *dev, int val) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| +	gpio_set_value(sp->info->pin_clk, val ? 1 : 0); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void setmosi(struct spi_device *dev, int val) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| +	gpio_set_value(sp->info->pin_mosi, val ? 1 : 0); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline u32 getmiso(struct spi_device *dev) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| +	return gpio_get_value(sp->info->pin_miso) ? 1 : 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static inline void do_spidelay(struct spi_device *dev, unsigned nsecs) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| + |  | ||||||
| +	if (!sp->info->no_spi_delay) |  | ||||||
| +		ndelay(nsecs); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +#define spidelay(nsecs) do {					\ |  | ||||||
| +	/* Steal the spi_device pointer from our caller.	\ |  | ||||||
| +	 * The bitbang-API should probably get fixed here... */	\ |  | ||||||
| +	do_spidelay(spi, nsecs);				\ |  | ||||||
| +  } while (0) |  | ||||||
| + |  | ||||||
| +#define EXPAND_BITBANG_TXRX |  | ||||||
| +#include "spi-bitbang-txrx.h" |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode0(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode1(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode2(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static u32 spi_gpio_txrx_mode3(struct spi_device *spi, |  | ||||||
| +			       unsigned nsecs, u32 word, u8 bits) |  | ||||||
| +{ |  | ||||||
| +	return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static void spi_gpio_chipselect(struct spi_device *dev, int on) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp = spidev_to_sg(dev); |  | ||||||
| + |  | ||||||
| +	if (sp->info->cs_activelow) |  | ||||||
| +		on = !on; |  | ||||||
| +	gpio_set_value(sp->info->pin_cs, on ? 1 : 0); |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int spi_gpio_probe(struct platform_device *pdev) |  | ||||||
| +{ |  | ||||||
| +	struct spi_master *master; |  | ||||||
| +	struct spi_gpio_platform_data *pdata; |  | ||||||
| +	struct spi_gpio *sp; |  | ||||||
| +	struct spi_device *spidev; |  | ||||||
| +	int err; |  | ||||||
| + |  | ||||||
| +	pdata = pdev->dev.platform_data; |  | ||||||
| +	if (!pdata) |  | ||||||
| +		return -ENXIO; |  | ||||||
| + |  | ||||||
| +	err = -ENOMEM; |  | ||||||
| +	master = spi_alloc_master(&pdev->dev, sizeof(struct spi_gpio)); |  | ||||||
| +	if (!master) |  | ||||||
| +		goto err_alloc_master; |  | ||||||
| + |  | ||||||
| +	sp = spi_master_get_devdata(master); |  | ||||||
| +	platform_set_drvdata(pdev, sp); |  | ||||||
| +	sp->info = pdata; |  | ||||||
| + |  | ||||||
| +	err = gpio_request(pdata->pin_clk, "spi_clock"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_clk; |  | ||||||
| +	err = gpio_request(pdata->pin_mosi, "spi_mosi"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_mosi; |  | ||||||
| +	err = gpio_request(pdata->pin_miso, "spi_miso"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_miso; |  | ||||||
| +	err = gpio_request(pdata->pin_cs, "spi_cs"); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_request_cs; |  | ||||||
| + |  | ||||||
| +	sp->bitbang.master = spi_master_get(master); |  | ||||||
| +	sp->bitbang.master->bus_num = -1; |  | ||||||
| +	sp->bitbang.master->num_chipselect = 1; |  | ||||||
| +	sp->bitbang.chipselect = spi_gpio_chipselect; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_mode0; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_mode1; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_mode2; |  | ||||||
| +	sp->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_mode3; |  | ||||||
| + |  | ||||||
| +	gpio_direction_output(pdata->pin_clk, 0); |  | ||||||
| +	gpio_direction_output(pdata->pin_mosi, 0); |  | ||||||
| +	gpio_direction_output(pdata->pin_cs, |  | ||||||
| +			      pdata->cs_activelow ? 1 : 0); |  | ||||||
| +	gpio_direction_input(pdata->pin_miso); |  | ||||||
| + |  | ||||||
| +	err = spi_bitbang_start(&sp->bitbang); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_no_bitbang; |  | ||||||
| +	err = pdata->boardinfo_setup(&sp->bi, master, |  | ||||||
| +				     pdata->boardinfo_setup_data); |  | ||||||
| +	if (err) |  | ||||||
| +		goto err_bi_setup; |  | ||||||
| +	sp->bi.controller_data = sp; |  | ||||||
| +	spidev = spi_new_device(master, &sp->bi); |  | ||||||
| +	if (!spidev) |  | ||||||
| +		goto err_new_dev; |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| + |  | ||||||
| +err_new_dev: |  | ||||||
| +err_bi_setup: |  | ||||||
| +	spi_bitbang_stop(&sp->bitbang); |  | ||||||
| +err_no_bitbang: |  | ||||||
| +	spi_master_put(sp->bitbang.master); |  | ||||||
| +	gpio_free(pdata->pin_cs); |  | ||||||
| +err_request_cs: |  | ||||||
| +	gpio_free(pdata->pin_miso); |  | ||||||
| +err_request_miso: |  | ||||||
| +	gpio_free(pdata->pin_mosi); |  | ||||||
| +err_request_mosi: |  | ||||||
| +	gpio_free(pdata->pin_clk); |  | ||||||
| +err_request_clk: |  | ||||||
| +	kfree(master); |  | ||||||
| + |  | ||||||
| +err_alloc_master: |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static int spi_gpio_remove(struct platform_device *pdev) |  | ||||||
| +{ |  | ||||||
| +	struct spi_gpio *sp; |  | ||||||
| +	struct spi_gpio_platform_data *pdata; |  | ||||||
| + |  | ||||||
| +	pdata = pdev->dev.platform_data; |  | ||||||
| +	sp = platform_get_drvdata(pdev); |  | ||||||
| + |  | ||||||
| +	gpio_free(pdata->pin_clk); |  | ||||||
| +	gpio_free(pdata->pin_mosi); |  | ||||||
| +	gpio_free(pdata->pin_miso); |  | ||||||
| +	gpio_free(pdata->pin_cs); |  | ||||||
| +	spi_bitbang_stop(&sp->bitbang); |  | ||||||
| +	spi_master_put(sp->bitbang.master); |  | ||||||
| + |  | ||||||
| +	return 0; |  | ||||||
| +} |  | ||||||
| + |  | ||||||
| +static struct platform_driver spi_gpio_driver = { |  | ||||||
| +	.driver		= { |  | ||||||
| +		.name	= SPI_GPIO_PLATDEV_NAME, |  | ||||||
| +		.owner	= THIS_MODULE, |  | ||||||
| +	}, |  | ||||||
| +	.probe		= spi_gpio_probe, |  | ||||||
| +	.remove		= spi_gpio_remove, |  | ||||||
| +}; |  | ||||||
| + |  | ||||||
| +int spi_gpio_next_id(void) |  | ||||||
| +{ |  | ||||||
| +	static atomic_t counter = ATOMIC_INIT(-1); |  | ||||||
| + |  | ||||||
| +	return atomic_inc_return(&counter); |  | ||||||
| +} |  | ||||||
| +EXPORT_SYMBOL(spi_gpio_next_id); |  | ||||||
| + |  | ||||||
| +static int __init spi_gpio_init(void) |  | ||||||
| +{ |  | ||||||
| +	int err; |  | ||||||
| + |  | ||||||
| +	err = platform_driver_register(&spi_gpio_driver); |  | ||||||
| +	if (err) |  | ||||||
| +		printk(KERN_ERR "spi-gpio: register failed: %d\n", err); |  | ||||||
| + |  | ||||||
| +	return err; |  | ||||||
| +} |  | ||||||
| +module_init(spi_gpio_init); |  | ||||||
| + |  | ||||||
| +static void __exit spi_gpio_exit(void) |  | ||||||
| +{ |  | ||||||
| +	platform_driver_unregister(&spi_gpio_driver); |  | ||||||
| +} |  | ||||||
| +module_exit(spi_gpio_exit); |  | ||||||
| + |  | ||||||
| +MODULE_AUTHOR("Piot Skamruk <piotr.skamruk at gmail.com>"); |  | ||||||
| +MODULE_AUTHOR("Michael Buesch"); |  | ||||||
| +MODULE_DESCRIPTION("Platform independent GPIO bitbanging SPI driver"); |  | ||||||
| +MODULE_LICENSE("GPL v2"); |  | ||||||
| --- a/drivers/spi/Kconfig |  | ||||||
| +++ b/drivers/spi/Kconfig |  | ||||||
| @@ -254,6 +254,15 @@ config SPI_IMG_SPFI |  | ||||||
|  	  This enables support for the SPFI master controller found on |  | ||||||
|  	  IMG SoCs. |  | ||||||
|   |  | ||||||
| +config SPI_GPIO_OLD |  | ||||||
| +	tristate "Old GPIO API based bitbanging SPI controller (DEPRECATED)" |  | ||||||
| +	depends on SPI_MASTER && GPIOLIB |  | ||||||
| +	select SPI_BITBANG |  | ||||||
| +	help |  | ||||||
| +	  This code is deprecated. Please use the new mainline SPI-GPIO driver. |  | ||||||
| + |  | ||||||
| +	  If unsure, say N. |  | ||||||
| + |  | ||||||
|  config SPI_IMX |  | ||||||
|  	tristate "Freescale i.MX SPI controllers" |  | ||||||
|  	depends on ARCH_MXC || COMPILE_TEST |  | ||||||
| --- a/drivers/spi/Makefile |  | ||||||
| +++ b/drivers/spi/Makefile |  | ||||||
| @@ -42,6 +42,7 @@ obj-$(CONFIG_SPI_FSL_LIB)		+= spi-fsl-li |  | ||||||
|  obj-$(CONFIG_SPI_FSL_ESPI)		+= spi-fsl-espi.o |  | ||||||
|  obj-$(CONFIG_SPI_FSL_SPI)		+= spi-fsl-spi.o |  | ||||||
|  obj-$(CONFIG_SPI_GPIO)			+= spi-gpio.o |  | ||||||
| +obj-$(CONFIG_SPI_GPIO_OLD)		+= spi_gpio_old.o |  | ||||||
|  obj-$(CONFIG_SPI_IMG_SPFI)		+= spi-img-spfi.o |  | ||||||
|  obj-$(CONFIG_SPI_IMX)			+= spi-imx.o |  | ||||||
|  obj-$(CONFIG_SPI_LM70_LLP)		+= spi-lm70llp.o |  | ||||||
| @@ -13,7 +13,7 @@ Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> | |||||||
|  |  | ||||||
| --- a/drivers/spi/Kconfig | --- a/drivers/spi/Kconfig | ||||||
| +++ b/drivers/spi/Kconfig | +++ b/drivers/spi/Kconfig | ||||||
| @@ -355,6 +355,13 @@ config SPI_MT65XX | @@ -346,6 +346,13 @@ config SPI_MT65XX | ||||||
|  	  say Y or M here.If you are not sure, say N. |  	  say Y or M here.If you are not sure, say N. | ||||||
|  	  SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs. |  	  SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs. | ||||||
|   |   | ||||||
| @@ -29,8 +29,8 @@ Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com> | |||||||
|  	depends on GPIOLIB || COMPILE_TEST |  	depends on GPIOLIB || COMPILE_TEST | ||||||
| --- a/drivers/spi/Makefile | --- a/drivers/spi/Makefile | ||||||
| +++ b/drivers/spi/Makefile | +++ b/drivers/spi/Makefile | ||||||
| @@ -45,6 +45,7 @@ obj-$(CONFIG_SPI_GPIO)			+= spi-gpio.o | @@ -44,6 +44,7 @@ obj-$(CONFIG_SPI_FSL_SPI)		+= spi-fsl-sp | ||||||
|  obj-$(CONFIG_SPI_GPIO_OLD)		+= spi_gpio_old.o |  obj-$(CONFIG_SPI_GPIO)			+= spi-gpio.o | ||||||
|  obj-$(CONFIG_SPI_IMG_SPFI)		+= spi-img-spfi.o |  obj-$(CONFIG_SPI_IMG_SPFI)		+= spi-img-spfi.o | ||||||
|  obj-$(CONFIG_SPI_IMX)			+= spi-imx.o |  obj-$(CONFIG_SPI_IMX)			+= spi-imx.o | ||||||
| +obj-$(CONFIG_SPI_LANTIQ)		+= spi-lantiq.o | +obj-$(CONFIG_SPI_LANTIQ)		+= spi-lantiq.o | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Felix Fietkau
					Felix Fietkau