Commit 80e45c3b authored by Tony Lindgren's avatar Tony Lindgren

Sync SPI stuff with mainline tree manually

parent 3ec21be9
...@@ -75,15 +75,34 @@ config SPI_BUTTERFLY ...@@ -75,15 +75,34 @@ config SPI_BUTTERFLY
inexpensive battery powered microcontroller evaluation board. inexpensive battery powered microcontroller evaluation board.
This same cable can be used to flash new firmware. This same cable can be used to flash new firmware.
config SPI_BUTTERFLY config SPI_MPC83xx
tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" tristate "Freescale MPC83xx SPI controller"
depends on SPI_MASTER && PARPORT && EXPERIMENTAL depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL
select SPI_BITBANG select SPI_BITBANG
help help
This uses a custom parallel port cable to connect to an AVR This enables using the Freescale MPC83xx SPI controller in master
Butterfly <http://www.atmel.com/products/avr/butterfly>, an mode.
inexpensive battery powered microcontroller evaluation board.
This same cable can be used to flash new firmware. Note, this driver uniquely supports the SPI controller on the MPC83xx
family of PowerPC processors. The MPC83xx uses a simple set of shift
registers for data (opposed to the CPM based descriptor model).
config SPI_PXA2XX
tristate "PXA2xx SSP SPI master"
depends on SPI_MASTER && ARCH_PXA && EXPERIMENTAL
help
This enables using a PXA2xx SSP port as a SPI master controller.
The driver can be configured to use any SSP port and additional
documentation can be found a Documentation/spi/pxa2xx.
config SPI_S3C24XX_GPIO
tristate "Samsung S3C24XX series SPI by GPIO"
depends on SPI_MASTER && ARCH_S3C2410 && SPI_BITBANG && EXPERIMENTAL
help
SPI driver for Samsung S3C24XX series ARM SoCs using
GPIO lines to provide the SPI bus. This can be used where
the inbuilt hardware cannot provide the transfer mode, or
where the board is using non hardware connected pins.
config SPI_OMAP_UWIRE config SPI_OMAP_UWIRE
tristate "OMAP MicroWire" tristate "OMAP MicroWire"
...@@ -103,6 +122,12 @@ config SPI_OMAP24XX ...@@ -103,6 +122,12 @@ config SPI_OMAP24XX
# #
config SPI_S3C24XX
tristate "Samsung S3C24XX series SPI"
depends on SPI_MASTER && ARCH_S3C2410 && EXPERIMENTAL
help
SPI driver for Samsung S3C24XX series ARM SoCs
# #
# There are lots of SPI device types, with sensors and memory # There are lots of SPI device types, with sensors and memory
# being probably the most widely used ones. # being probably the most widely used ones.
......
...@@ -13,6 +13,10 @@ obj-$(CONFIG_SPI_MASTER) += spi.o ...@@ -13,6 +13,10 @@ obj-$(CONFIG_SPI_MASTER) += spi.o
# SPI master controller drivers (bus) # SPI master controller drivers (bus)
obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o
obj-$(CONFIG_SPI_PXA2XX) += pxa2xx_spi.o
obj-$(CONFIG_SPI_MPC83xx) += spi_mpc83xx.o
obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o
obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o
obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o obj-$(CONFIG_SPI_OMAP24XX) += omap2_mcspi.o
obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o obj-$(CONFIG_SPI_OMAP_UWIRE) += omap_uwire.o
# ... add above this line ... # ... add above this line ...
......
...@@ -167,9 +167,11 @@ int spi_bitbang_setup_transfer(struct spi_device *spi, struct spi_transfer *t) ...@@ -167,9 +167,11 @@ int spi_bitbang_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
/* nsecs = (clock period)/2 */ /* nsecs = (clock period)/2 */
if (!hz) if (!hz)
hz = spi->max_speed_hz; hz = spi->max_speed_hz;
cs->nsecs = (1000000000/2) / hz; if (hz) {
if (cs->nsecs > MAX_UDELAY_MS * 1000) cs->nsecs = (1000000000/2) / hz;
return -EINVAL; if (cs->nsecs > (MAX_UDELAY_MS * 1000 * 1000))
return -EINVAL;
}
return 0; return 0;
} }
...@@ -184,7 +186,14 @@ int spi_bitbang_setup(struct spi_device *spi) ...@@ -184,7 +186,14 @@ int spi_bitbang_setup(struct spi_device *spi)
struct spi_bitbang *bitbang; struct spi_bitbang *bitbang;
int retval; int retval;
if (!spi->max_speed_hz) bitbang = spi_master_get_devdata(spi->master);
/* REVISIT: some systems will want to support devices using lsb-first
* bit encodings on the wire. In pure software that would be trivial,
* just bitbang_txrx_le_cphaX() routines shifting the other way, and
* some hardware controllers also have this support.
*/
if ((spi->mode & SPI_LSB_FIRST) != 0)
return -EINVAL; return -EINVAL;
if (!cs) { if (!cs) {
...@@ -193,7 +202,6 @@ int spi_bitbang_setup(struct spi_device *spi) ...@@ -193,7 +202,6 @@ int spi_bitbang_setup(struct spi_device *spi)
return -ENOMEM; return -ENOMEM;
spi->controller_state = cs; spi->controller_state = cs;
} }
bitbang = spi_master_get_devdata(spi->master);
if (!spi->bits_per_word) if (!spi->bits_per_word)
spi->bits_per_word = 8; spi->bits_per_word = 8;
...@@ -207,7 +215,7 @@ int spi_bitbang_setup(struct spi_device *spi) ...@@ -207,7 +215,7 @@ int spi_bitbang_setup(struct spi_device *spi)
if (retval < 0) if (retval < 0)
return retval; return retval;
dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n", dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n",
__FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA), __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA),
spi->bits_per_word, 2 * cs->nsecs); spi->bits_per_word, 2 * cs->nsecs);
...@@ -396,6 +404,7 @@ int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m) ...@@ -396,6 +404,7 @@ int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m)
{ {
struct spi_bitbang *bitbang; struct spi_bitbang *bitbang;
unsigned long flags; unsigned long flags;
int status = 0;
m->actual_length = 0; m->actual_length = 0;
m->status = -EINPROGRESS; m->status = -EINPROGRESS;
...@@ -405,11 +414,15 @@ int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m) ...@@ -405,11 +414,15 @@ int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m)
return -ESHUTDOWN; return -ESHUTDOWN;
spin_lock_irqsave(&bitbang->lock, flags); spin_lock_irqsave(&bitbang->lock, flags);
list_add_tail(&m->queue, &bitbang->queue); if (!spi->max_speed_hz)
queue_work(bitbang->workqueue, &bitbang->work); status = -ENETDOWN;
else {
list_add_tail(&m->queue, &bitbang->queue);
queue_work(bitbang->workqueue, &bitbang->work);
}
spin_unlock_irqrestore(&bitbang->lock, flags); spin_unlock_irqrestore(&bitbang->lock, flags);
return 0; return status;
} }
EXPORT_SYMBOL_GPL(spi_bitbang_transfer); EXPORT_SYMBOL_GPL(spi_bitbang_transfer);
......
...@@ -35,16 +35,19 @@ extern struct bus_type spi_bus_type; ...@@ -35,16 +35,19 @@ extern struct bus_type spi_bus_type;
* @chip-select: Chipselect, distinguishing chips handled by "master". * @chip-select: Chipselect, distinguishing chips handled by "master".
* @mode: The spi mode defines how data is clocked out and in. * @mode: The spi mode defines how data is clocked out and in.
* This may be changed by the device's driver. * This may be changed by the device's driver.
* The "active low" default for chipselect mode can be overridden,
* as can the "MSB first" default for each word in a transfer.
* @bits_per_word: Data transfers involve one or more words; word sizes * @bits_per_word: Data transfers involve one or more words; word sizes
* like eight or 12 bits are common. In-memory wordsizes are * like eight or 12 bits are common. In-memory wordsizes are
* powers of two bytes (e.g. 20 bit samples use 32 bits). * powers of two bytes (e.g. 20 bit samples use 32 bits).
* This may be changed by the device's driver. * This may be changed by the device's driver, or left at the
* default (0) indicating protocol words are eight bit bytes.
* The spi_transfer.bits_per_word can override this for each transfer. * The spi_transfer.bits_per_word can override this for each transfer.
* @irq: Negative, or the number passed to request_irq() to receive * @irq: Negative, or the number passed to request_irq() to receive
* interrupts from this device. * interrupts from this device.
* @controller_state: Controller's runtime state * @controller_state: Controller's runtime state
* @controller_data: Board-specific definitions for controller, such as * @controller_data: Board-specific definitions for controller, such as
* FIFO initialization parameters; from board_info.controller_data * FIFO initialization parameters; from board_info.controller_data
* *
* An spi_device is used to interchange data between an SPI slave * An spi_device is used to interchange data between an SPI slave
* (usually a discrete chip) and CPU memory. * (usually a discrete chip) and CPU memory.
...@@ -67,6 +70,7 @@ struct spi_device { ...@@ -67,6 +70,7 @@ struct spi_device {
#define SPI_MODE_2 (SPI_CPOL|0) #define SPI_MODE_2 (SPI_CPOL|0)
#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
#define SPI_CS_HIGH 0x04 /* chipselect active high? */ #define SPI_CS_HIGH 0x04 /* chipselect active high? */
#define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */
u8 bits_per_word; u8 bits_per_word;
int irq; int irq;
void *controller_state; void *controller_state;
...@@ -75,7 +79,6 @@ struct spi_device { ...@@ -75,7 +79,6 @@ struct spi_device {
// likely need more hooks for more protocol options affecting how // likely need more hooks for more protocol options affecting how
// the controller talks to each chip, like: // the controller talks to each chip, like:
// - bit order (default is wordwise msb-first)
// - memory packing (12 bit samples into low bits, others zeroed) // - memory packing (12 bit samples into low bits, others zeroed)
// - priority // - priority
// - drop chipselect after each word // - drop chipselect after each word
...@@ -145,13 +148,13 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) ...@@ -145,13 +148,13 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
* struct spi_master - interface to SPI master controller * struct spi_master - interface to SPI master controller
* @cdev: class interface to this driver * @cdev: class interface to this driver
* @bus_num: board-specific (and often SOC-specific) identifier for a * @bus_num: board-specific (and often SOC-specific) identifier for a
* given SPI controller. * given SPI controller.
* @num_chipselect: chipselects are used to distinguish individual * @num_chipselect: chipselects are used to distinguish individual
* SPI slaves, and are numbered from zero to num_chipselects. * SPI slaves, and are numbered from zero to num_chipselects.
* each slave has a chipselect signal, but it's common that not * each slave has a chipselect signal, but it's common that not
* every chipselect is connected to a slave. * every chipselect is connected to a slave.
* @setup: updates the device mode and clocking records used by a * @setup: updates the device mode and clocking records used by a
* device's SPI controller; protocol code may call this. * device's SPI controller; protocol code may call this.
* @transfer: adds a message to the controller's transfer queue. * @transfer: adds a message to the controller's transfer queue.
* @cleanup: frees controller-specific state * @cleanup: frees controller-specific state
* *
...@@ -169,13 +172,13 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv) ...@@ -169,13 +172,13 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
struct spi_master { struct spi_master {
struct class_device cdev; struct class_device cdev;
/* other than zero (== assign one dynamically), bus_num is fully /* other than negative (== assign one dynamically), bus_num is fully
* board-specific. usually that simplifies to being SOC-specific. * board-specific. usually that simplifies to being SOC-specific.
* example: one SOC has three SPI controllers, numbered 1..3, * example: one SOC has three SPI controllers, numbered 0..2,
* and one board's schematics might show it using SPI-2. software * and one board's schematics might show it using SPI-2. software
* would normally use bus_num=2 for that controller. * would normally use bus_num=2 for that controller.
*/ */
u16 bus_num; s16 bus_num;
/* chipselects will be integral to many controllers; some others /* chipselects will be integral to many controllers; some others
* might use board-specific GPIOs. * might use board-specific GPIOs.
...@@ -276,8 +279,8 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum); ...@@ -276,8 +279,8 @@ extern struct spi_master *spi_busnum_to_master(u16 busnum);
* for this transfer. If 0 the default (from spi_device) is used. * for this transfer. If 0 the default (from spi_device) is used.
* @cs_change: affects chipselect after this transfer completes * @cs_change: affects chipselect after this transfer completes
* @delay_usecs: microseconds to delay after this transfer before * @delay_usecs: microseconds to delay after this transfer before
* (optionally) changing the chipselect status, then starting * (optionally) changing the chipselect status, then starting
* the next transfer or completing this spi_message. * the next transfer or completing this spi_message.
* @transfer_list: transfers are sequenced through spi_message.transfers * @transfer_list: transfers are sequenced through spi_message.transfers
* *
* SPI transfers always write the same number of bytes as they read. * SPI transfers always write the same number of bytes as they read.
...@@ -364,7 +367,7 @@ struct spi_transfer { ...@@ -364,7 +367,7 @@ struct spi_transfer {
* and its transfers, ignore them until its completion callback. * and its transfers, ignore them until its completion callback.
*/ */
struct spi_message { struct spi_message {
struct list_head transfers; struct list_head transfers;
struct spi_device *spi; struct spi_device *spi;
...@@ -382,7 +385,7 @@ struct spi_message { ...@@ -382,7 +385,7 @@ struct spi_message {
*/ */
/* completion is reported through a callback */ /* completion is reported through a callback */
void (*complete)(void *context); void (*complete)(void *context);
void *context; void *context;
unsigned actual_length; unsigned actual_length;
int status; int status;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment