diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-09 23:15:02 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-09 23:15:02 -0800 |
commit | 417248e494454b1add4cad702bd02236cd710d94 (patch) | |
tree | 6dc9f5144385da2afa44516ff706275a7303f633 /driver | |
parent | 2c9d0960a5ca4ded47926e03ff33edd220c8c31d (diff) | |
download | patches-417248e494454b1add4cad702bd02236cd710d94.tar.gz |
added spi patches
Diffstat (limited to 'driver')
-rw-r--r-- | driver/spi-add-spi_bitbang-driver.patch | 671 | ||||
-rw-r--r-- | driver/spi-add-spi_driver-to-spi-framework.patch | 553 | ||||
-rw-r--r-- | driver/spi-ads7836-uses-spi_driver.patch | 237 | ||||
-rw-r--r-- | driver/spi-ads7846-driver.patch | 734 | ||||
-rw-r--r-- | driver/spi-core-tweaks-bugfix.patch | 358 | ||||
-rw-r--r-- | driver/spi-m25-series-spi-flash.patch | 657 | ||||
-rw-r--r-- | driver/spi-misc-fixes.patch | 118 | ||||
-rw-r--r-- | driver/spi-mtd-dataflash-driver.patch | 712 | ||||
-rw-r--r-- | driver/spi-simple-spi-framework.patch | 1755 | ||||
-rw-r--r-- | driver/spi-use-linked-lists-rather-than-an-array.patch | 679 |
10 files changed, 6474 insertions, 0 deletions
diff --git a/driver/spi-add-spi_bitbang-driver.patch b/driver/spi-add-spi_bitbang-driver.patch new file mode 100644 index 0000000000000..a8ea669af707e --- /dev/null +++ b/driver/spi-add-spi_bitbang-driver.patch @@ -0,0 +1,671 @@ +From akpm@osdl.org Sun Jan 8 13:38:08 2006 +From: akpm@osdl.org +Message-Id: <200601082134.k08LYcfh004579@shell0.pdx.osdl.net> +Subject: [patch 07/10] spi: add spi_bitbang driver +To: greg@kroah.com +Cc: akpm@osdl.org, david-b@pacbell.net, dbrownell@users.sourceforge.net +Date: Sun, 08 Jan 2006 13:34:26 -0800 + + +From: David Brownell <david-b@pacbell.net> + +This adds a bitbanging spi master, hooking up to board/adapter-specific glue +code which knows how to set and read the signals (gpios etc). + +This code kicks in after the glue code creates a platform_device with the +right platform_data. That data includes I/O loops, which will usually +come from expanding an inline function (provided in the header). One goal +is that the I/O loops should be easily optimized down to a few GPIO register +accesses, in common cases, for speed and minimized overhead. + +This understands all the currently defined protocol tweaking options in the +SPI framework, and might eventually serve as as reference implementation. + + - different word sizes (1..32 bits) + - differing clock rates + - SPI modes differing by CPOL (affecting chip select and I/O loops) + - SPI modes differing by CPHA (affecting I/O loops) + - delays (usecs) after transfers + - temporarily deselecting chips in mid-transfer + +A lot of hardware could work with this framework, though common types of +controller can't reach peak performance without switching to a driver +structure that supports pipelining of transfers (e.g. DMA queues) and maybe +controllers (e.g. IRQ driven). + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + drivers/spi/Kconfig | 13 + + drivers/spi/Makefile | 1 + drivers/spi/spi_bitbang.c | 460 ++++++++++++++++++++++++++++++++++++++++ + include/linux/spi/spi_bitbang.h | 128 +++++++++++ + 4 files changed, 602 insertions(+) + +--- gregkh-2.6.orig/drivers/spi/Kconfig ++++ gregkh-2.6/drivers/spi/Kconfig +@@ -66,6 +66,19 @@ config SPI_MASTER + comment "SPI Master Controller Drivers" + depends on SPI_MASTER + ++config SPI_BITBANG ++ tristate "Bitbanging SPI master" ++ depends on SPI_MASTER && EXPERIMENTAL ++ help ++ With a few GPIO pins, your system can bitbang the SPI protocol. ++ Select this to get SPI support through I/O pins (GPIO, parallel ++ port, etc). Or, some systems' SPI master controller drivers use ++ this code to manage the per-word or per-transfer accesses to the ++ hardware shift registers. ++ ++ This is library code, and is automatically selected by drivers that ++ need it. You only need to select this explicitly to support driver ++ modules that aren't part of this kernel tree. + + # + # Add new SPI master controllers in alphabetical order above this line +--- gregkh-2.6.orig/drivers/spi/Makefile ++++ gregkh-2.6/drivers/spi/Makefile +@@ -11,6 +11,7 @@ endif + obj-$(CONFIG_SPI_MASTER) += spi.o + + # SPI master controller drivers (bus) ++obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o + # ... add above this line ... + + # SPI protocol drivers (device/link on bus) +--- /dev/null ++++ gregkh-2.6/drivers/spi/spi_bitbang.c +@@ -0,0 +1,460 @@ ++/* ++ * spi_bitbang.c - polling/bitbanging SPI master controller driver utilities ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include <linux/config.h> ++#include <linux/init.h> ++#include <linux/spinlock.h> ++#include <linux/workqueue.h> ++#include <linux/interrupt.h> ++#include <linux/delay.h> ++#include <linux/errno.h> ++#include <linux/platform_device.h> ++ ++#include <linux/spi/spi.h> ++#include <linux/spi/spi_bitbang.h> ++ ++ ++/*----------------------------------------------------------------------*/ ++ ++/* ++ * FIRST PART (OPTIONAL): word-at-a-time spi_transfer support. ++ * Use this for GPIO or shift-register level hardware APIs. ++ * ++ * spi_bitbang_cs is in spi_device->controller_state, which is unavailable ++ * to glue code. These bitbang setup() and cleanup() routines are always ++ * used, though maybe they're called from controller-aware code. ++ * ++ * chipselect() and friends may use use spi_device->controller_data and ++ * controller registers as appropriate. ++ * ++ * ++ * NOTE: SPI controller pins can often be used as GPIO pins instead, ++ * which means you could use a bitbang driver either to get hardware ++ * working quickly, or testing for differences that aren't speed related. ++ */ ++ ++struct spi_bitbang_cs { ++ unsigned nsecs; /* (clock cycle time)/2 */ ++ u32 (*txrx_word)(struct spi_device *spi, unsigned nsecs, ++ u32 word, u8 bits); ++ unsigned (*txrx_bufs)(struct spi_device *, ++ u32 (*txrx_word)( ++ struct spi_device *spi, ++ unsigned nsecs, ++ u32 word, u8 bits), ++ unsigned, struct spi_transfer *); ++}; ++ ++static unsigned bitbang_txrx_8( ++ struct spi_device *spi, ++ u32 (*txrx_word)(struct spi_device *spi, ++ unsigned nsecs, ++ u32 word, u8 bits), ++ unsigned ns, ++ struct spi_transfer *t ++) { ++ unsigned bits = spi->bits_per_word; ++ unsigned count = t->len; ++ const u8 *tx = t->tx_buf; ++ u8 *rx = t->rx_buf; ++ ++ while (likely(count > 0)) { ++ u8 word = 0; ++ ++ if (tx) ++ word = *tx++; ++ word = txrx_word(spi, ns, word, bits); ++ if (rx) ++ *rx++ = word; ++ count -= 1; ++ } ++ return t->len - count; ++} ++ ++static unsigned bitbang_txrx_16( ++ struct spi_device *spi, ++ u32 (*txrx_word)(struct spi_device *spi, ++ unsigned nsecs, ++ u32 word, u8 bits), ++ unsigned ns, ++ struct spi_transfer *t ++) { ++ unsigned bits = spi->bits_per_word; ++ unsigned count = t->len; ++ const u16 *tx = t->tx_buf; ++ u16 *rx = t->rx_buf; ++ ++ while (likely(count > 1)) { ++ u16 word = 0; ++ ++ if (tx) ++ word = *tx++; ++ word = txrx_word(spi, ns, word, bits); ++ if (rx) ++ *rx++ = word; ++ count -= 2; ++ } ++ return t->len - count; ++} ++ ++static unsigned bitbang_txrx_32( ++ struct spi_device *spi, ++ u32 (*txrx_word)(struct spi_device *spi, ++ unsigned nsecs, ++ u32 word, u8 bits), ++ unsigned ns, ++ struct spi_transfer *t ++) { ++ unsigned bits = spi->bits_per_word; ++ unsigned count = t->len; ++ const u32 *tx = t->tx_buf; ++ u32 *rx = t->rx_buf; ++ ++ while (likely(count > 3)) { ++ u32 word = 0; ++ ++ if (tx) ++ word = *tx++; ++ word = txrx_word(spi, ns, word, bits); ++ if (rx) ++ *rx++ = word; ++ count -= 4; ++ } ++ return t->len - count; ++} ++ ++/** ++ * spi_bitbang_setup - default setup for per-word I/O loops ++ */ ++int spi_bitbang_setup(struct spi_device *spi) ++{ ++ struct spi_bitbang_cs *cs = spi->controller_state; ++ struct spi_bitbang *bitbang; ++ ++ if (!cs) { ++ cs = kzalloc(sizeof *cs, SLAB_KERNEL); ++ if (!cs) ++ return -ENOMEM; ++ spi->controller_state = cs; ++ } ++ bitbang = spi_master_get_devdata(spi->master); ++ ++ if (!spi->bits_per_word) ++ spi->bits_per_word = 8; ++ ++ /* spi_transfer level calls that work per-word */ ++ if (spi->bits_per_word <= 8) ++ cs->txrx_bufs = bitbang_txrx_8; ++ else if (spi->bits_per_word <= 16) ++ cs->txrx_bufs = bitbang_txrx_16; ++ else if (spi->bits_per_word <= 32) ++ cs->txrx_bufs = bitbang_txrx_32; ++ else ++ return -EINVAL; ++ ++ /* per-word shift register access, in hardware or bitbanging */ ++ cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)]; ++ if (!cs->txrx_word) ++ return -EINVAL; ++ ++ if (!spi->max_speed_hz) ++ spi->max_speed_hz = 500 * 1000; ++ ++ /* nsecs = max(50, (clock period)/2), be optimistic */ ++ cs->nsecs = (1000000000/2) / (spi->max_speed_hz); ++ if (cs->nsecs < 50) ++ cs->nsecs = 50; ++ if (cs->nsecs > MAX_UDELAY_MS * 1000) ++ return -EINVAL; ++ ++ dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n", ++ __FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA), ++ spi->bits_per_word, 2 * cs->nsecs); ++ ++ /* NOTE we _need_ to call chipselect() early, ideally with adapter ++ * setup, unless the hardware defaults cooperate to avoid confusion ++ * between normal (active low) and inverted chipselects. ++ */ ++ ++ /* deselect chip (low or high) */ ++ spin_lock(&bitbang->lock); ++ if (!bitbang->busy) { ++ bitbang->chipselect(spi, 0); ++ ndelay(cs->nsecs); ++ } ++ spin_unlock(&bitbang->lock); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(spi_bitbang_setup); ++ ++/** ++ * spi_bitbang_cleanup - default cleanup for per-word I/O loops ++ */ ++void spi_bitbang_cleanup(const struct spi_device *spi) ++{ ++ kfree(spi->controller_state); ++} ++EXPORT_SYMBOL_GPL(spi_bitbang_cleanup); ++ ++static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) ++{ ++ struct spi_bitbang_cs *cs = spi->controller_state; ++ unsigned nsecs = cs->nsecs; ++ ++ return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t); ++} ++ ++/*----------------------------------------------------------------------*/ ++ ++/* ++ * SECOND PART ... simple transfer queue runner. ++ * ++ * This costs a task context per controller, running the queue by ++ * performing each transfer in sequence. Smarter hardware can queue ++ * several DMA transfers at once, and process several controller queues ++ * in parallel; this driver doesn't match such hardware very well. ++ * ++ * Drivers can provide word-at-a-time i/o primitives, or provide ++ * transfer-at-a-time ones to leverage dma or fifo hardware. ++ */ ++static void bitbang_work(void *_bitbang) ++{ ++ struct spi_bitbang *bitbang = _bitbang; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&bitbang->lock, flags); ++ bitbang->busy = 1; ++ while (!list_empty(&bitbang->queue)) { ++ struct spi_message *m; ++ struct spi_device *spi; ++ unsigned nsecs; ++ struct spi_transfer *t; ++ unsigned tmp; ++ unsigned chipselect; ++ int status; ++ ++ m = container_of(bitbang->queue.next, struct spi_message, ++ queue); ++ list_del_init(&m->queue); ++ spin_unlock_irqrestore(&bitbang->lock, flags); ++ ++// FIXME this is made-up ++nsecs = 100; ++ ++ spi = m->spi; ++ t = m->transfers; ++ tmp = 0; ++ chipselect = 0; ++ status = 0; ++ ++ for (;;t++) { ++ if (bitbang->shutdown) { ++ status = -ESHUTDOWN; ++ break; ++ } ++ ++ /* set up default clock polarity, and activate chip */ ++ if (!chipselect) { ++ bitbang->chipselect(spi, 1); ++ ndelay(nsecs); ++ } ++ if (!t->tx_buf && !t->rx_buf && t->len) { ++ status = -EINVAL; ++ break; ++ } ++ ++ /* transfer data */ ++ if (t->len) { ++ /* FIXME if bitbang->use_dma, dma_map_single() ++ * before the transfer, and dma_unmap_single() ++ * afterwards, for either or both buffers... ++ */ ++ status = bitbang->txrx_bufs(spi, t); ++ } ++ if (status != t->len) { ++ if (status > 0) ++ status = -EMSGSIZE; ++ break; ++ } ++ m->actual_length += status; ++ status = 0; ++ ++ /* protocol tweaks before next transfer */ ++ if (t->delay_usecs) ++ udelay(t->delay_usecs); ++ ++ tmp++; ++ if (tmp >= m->n_transfer) ++ break; ++ ++ chipselect = !t->cs_change; ++ if (chipselect); ++ continue; ++ ++ bitbang->chipselect(spi, 0); ++ ++ /* REVISIT do we want the udelay here instead? */ ++ msleep(1); ++ } ++ ++ tmp = m->n_transfer - 1; ++ tmp = m->transfers[tmp].cs_change; ++ ++ m->status = status; ++ m->complete(m->context); ++ ++ ndelay(2 * nsecs); ++ bitbang->chipselect(spi, status == 0 && tmp); ++ ndelay(nsecs); ++ ++ spin_lock_irqsave(&bitbang->lock, flags); ++ } ++ bitbang->busy = 0; ++ spin_unlock_irqrestore(&bitbang->lock, flags); ++} ++ ++/** ++ * spi_bitbang_transfer - default submit to transfer queue ++ */ ++int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m) ++{ ++ struct spi_bitbang *bitbang; ++ unsigned long flags; ++ ++ m->actual_length = 0; ++ m->status = -EINPROGRESS; ++ ++ bitbang = spi_master_get_devdata(spi->master); ++ if (bitbang->shutdown) ++ return -ESHUTDOWN; ++ ++ spin_lock_irqsave(&bitbang->lock, flags); ++ list_add_tail(&m->queue, &bitbang->queue); ++ queue_work(bitbang->workqueue, &bitbang->work); ++ spin_unlock_irqrestore(&bitbang->lock, flags); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(spi_bitbang_transfer); ++ ++/*----------------------------------------------------------------------*/ ++ ++/** ++ * spi_bitbang_start - start up a polled/bitbanging SPI master driver ++ * @bitbang: driver handle ++ * ++ * Caller should have zero-initialized all parts of the structure, and then ++ * provided callbacks for chip selection and I/O loops. If the master has ++ * a transfer method, its final step should call spi_bitbang_transfer; or, ++ * that's the default if the transfer routine is not initialized. It should ++ * also set up the bus number and number of chipselects. ++ * ++ * For i/o loops, provide callbacks either per-word (for bitbanging, or for ++ * hardware that basically exposes a shift register) or per-spi_transfer ++ * (which takes better advantage of hardware like fifos or DMA engines). ++ * ++ * Drivers using per-word I/O loops should use (or call) spi_bitbang_setup and ++ * spi_bitbang_cleanup to handle those spi master methods. Those methods are ++ * the defaults if the bitbang->txrx_bufs routine isn't initialized. ++ * ++ * This routine registers the spi_master, which will process requests in a ++ * dedicated task, keeping IRQs unblocked most of the time. To stop ++ * processing those requests, call spi_bitbang_stop(). ++ */ ++int spi_bitbang_start(struct spi_bitbang *bitbang) ++{ ++ int status; ++ ++ if (!bitbang->master || !bitbang->chipselect) ++ return -EINVAL; ++ ++ INIT_WORK(&bitbang->work, bitbang_work, bitbang); ++ spin_lock_init(&bitbang->lock); ++ INIT_LIST_HEAD(&bitbang->queue); ++ ++ if (!bitbang->master->transfer) ++ bitbang->master->transfer = spi_bitbang_transfer; ++ if (!bitbang->txrx_bufs) { ++ bitbang->use_dma = 0; ++ bitbang->txrx_bufs = spi_bitbang_bufs; ++ if (!bitbang->master->setup) { ++ bitbang->master->setup = spi_bitbang_setup; ++ bitbang->master->cleanup = spi_bitbang_cleanup; ++ } ++ } else if (!bitbang->master->setup) ++ return -EINVAL; ++ ++ /* this task is the only thing to touch the SPI bits */ ++ bitbang->busy = 0; ++ bitbang->workqueue = create_singlethread_workqueue( ++ bitbang->master->cdev.dev->bus_id); ++ if (bitbang->workqueue == NULL) { ++ status = -EBUSY; ++ goto err1; ++ } ++ ++ /* driver may get busy before register() returns, especially ++ * if someone registered boardinfo for devices ++ */ ++ status = spi_register_master(bitbang->master); ++ if (status < 0) ++ goto err2; ++ ++ return status; ++ ++err2: ++ destroy_workqueue(bitbang->workqueue); ++err1: ++ return status; ++} ++EXPORT_SYMBOL_GPL(spi_bitbang_start); ++ ++/** ++ * spi_bitbang_stop - stops the task providing spi communication ++ */ ++int spi_bitbang_stop(struct spi_bitbang *bitbang) ++{ ++ unsigned limit = 500; ++ ++ spin_lock_irq(&bitbang->lock); ++ bitbang->shutdown = 0; ++ while (!list_empty(&bitbang->queue) && limit--) { ++ spin_unlock_irq(&bitbang->lock); ++ ++ dev_dbg(bitbang->master->cdev.dev, "wait for queue\n"); ++ msleep(10); ++ ++ spin_lock_irq(&bitbang->lock); ++ } ++ spin_unlock_irq(&bitbang->lock); ++ if (!list_empty(&bitbang->queue)) { ++ dev_err(bitbang->master->cdev.dev, "queue didn't empty\n"); ++ return -EBUSY; ++ } ++ ++ destroy_workqueue(bitbang->workqueue); ++ ++ spi_unregister_master(bitbang->master); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(spi_bitbang_stop); ++ ++MODULE_LICENSE("GPL"); ++ +--- /dev/null ++++ gregkh-2.6/include/linux/spi/spi_bitbang.h +@@ -0,0 +1,128 @@ ++#ifndef __SPI_BITBANG_H ++#define __SPI_BITBANG_H ++ ++/* ++ * Mix this utility code with some glue code to get one of several types of ++ * simple SPI master driver. Two do polled word-at-a-time I/O: ++ * ++ * - GPIO/parport bitbangers. Provide chipselect() and txrx_word[](), ++ * expanding the per-word routines from the inline templates below. ++ * ++ * - Drivers for controllers resembling bare shift registers. Provide ++ * chipselect() and txrx_word[](), with custom setup()/cleanup() methods ++ * that use your controller's clock and chipselect registers. ++ * ++ * Some hardware works well with requests at spi_transfer scope: ++ * ++ * - Drivers leveraging smarter hardware, with fifos or DMA; or for half ++ * duplex (MicroWire) controllers. Provide chipslect() and txrx_bufs(), ++ * and custom setup()/cleanup() methods. ++ */ ++struct spi_bitbang { ++ struct workqueue_struct *workqueue; ++ struct work_struct work; ++ ++ spinlock_t lock; ++ struct list_head queue; ++ u8 busy; ++ u8 shutdown; ++ u8 use_dma; ++ ++ struct spi_master *master; ++ ++ void (*chipselect)(struct spi_device *spi, int is_on); ++ ++ int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t); ++ u32 (*txrx_word[4])(struct spi_device *spi, ++ unsigned nsecs, ++ u32 word, u8 bits); ++}; ++ ++/* you can call these default bitbang->master methods from your custom ++ * methods, if you like. ++ */ ++extern int spi_bitbang_setup(struct spi_device *spi); ++extern void spi_bitbang_cleanup(const struct spi_device *spi); ++extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m); ++ ++/* start or stop queue processing */ ++extern int spi_bitbang_start(struct spi_bitbang *spi); ++extern int spi_bitbang_stop(struct spi_bitbang *spi); ++ ++#endif /* __SPI_BITBANG_H */ ++ ++/*-------------------------------------------------------------------------*/ ++ ++#ifdef EXPAND_BITBANG_TXRX ++ ++/* ++ * The code that knows what GPIO pins do what should have declared four ++ * functions, ideally as inlines, before #defining EXPAND_BITBANG_TXRX ++ * and including this header: ++ * ++ * void setsck(struct spi_device *, int is_on); ++ * void setmosi(struct spi_device *, int is_on); ++ * int getmiso(struct spi_device *); ++ * void spidelay(unsigned); ++ * ++ * A non-inlined routine would call bitbang_txrx_*() routines. The ++ * main loop could easily compile down to a handful of instructions, ++ * especially if the delay is a NOP (to run at peak speed). ++ * ++ * Since this is software, the timings may not be exactly what your board's ++ * chips need ... there may be several reasons you'd need to tweak timings ++ * in these routines, not just make to make it faster or slower to match a ++ * particular CPU clock rate. ++ */ ++ ++static inline u32 ++bitbang_txrx_be_cpha0(struct spi_device *spi, ++ unsigned nsecs, unsigned cpol, ++ u32 word, u8 bits) ++{ ++ /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ ++ ++ /* clock starts at inactive polarity */ ++ for (word <<= (32 - bits); likely(bits); bits--) { ++ ++ /* setup MSB (to slave) on trailing edge */ ++ setmosi(spi, word & (1 << 31)); ++ spidelay(nsecs); /* T(setup) */ ++ ++ setsck(spi, !cpol); ++ spidelay(nsecs); ++ ++ /* sample MSB (from slave) on leading edge */ ++ word <<= 1; ++ word |= getmiso(spi); ++ setsck(spi, cpol); ++ } ++ return word; ++} ++ ++static inline u32 ++bitbang_txrx_be_cpha1(struct spi_device *spi, ++ unsigned nsecs, unsigned cpol, ++ u32 word, u8 bits) ++{ ++ /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ ++ ++ /* clock starts at inactive polarity */ ++ for (word <<= (32 - bits); likely(bits); bits--) { ++ ++ /* setup MSB (to slave) on leading edge */ ++ setsck(spi, !cpol); ++ setmosi(spi, word & (1 << 31)); ++ spidelay(nsecs); /* T(setup) */ ++ ++ setsck(spi, cpol); ++ spidelay(nsecs); ++ ++ /* sample MSB (from slave) on trailing edge */ ++ word <<= 1; ++ word |= getmiso(spi); ++ } ++ return word; ++} ++ ++#endif /* EXPAND_BITBANG_TXRX */ diff --git a/driver/spi-add-spi_driver-to-spi-framework.patch b/driver/spi-add-spi_driver-to-spi-framework.patch new file mode 100644 index 0000000000000..d9190bb43ff7a --- /dev/null +++ b/driver/spi-add-spi_driver-to-spi-framework.patch @@ -0,0 +1,553 @@ +From akpm@osdl.org Sun Jan 8 13:37:31 2006 +From: akpm@osdl.org +Message-Id: <200601082134.k08LYZ5W004570@shell0.pdx.osdl.net> +Subject: [patch 04/10] spi: add spi_driver to SPI framework +To: greg@kroah.com +Cc: akpm@osdl.org, david-b@pacbell.net, dbrownell@users.sourceforge.net +Date: Sun, 08 Jan 2006 13:34:23 -0800 + + +From: David Brownell <david-b@pacbell.net> + +This is a refresh of the "Simple SPI Framework" found in 2.6.15-rc3-mm1 +which makes the following changes: + + * There's now a "struct spi_driver". This increase the footprint + of the core a bit, since it now includes code to do what the driver + core was previously handling directly. Documentation and comments + were updated to match. + + * spi_alloc_master() now does class_device_initialize(), so it can + at least be refcounted before spi_register_master(). To match, + spi_register_master() switched over to class_device_add(). + + * States explicitly that after transfer errors, spi_devices will be + deselected. We want fault recovery procedures to work the same + for all controller drivers. + + * Minor tweaks: controller_data no longer points to readonly data; + prevent some potential cast-from-null bugs with container_of calls; + clarifies some existing kerneldoc, + +And a few small cleanups. + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + Documentation/spi/spi-summary | 52 +++++++++++------- + drivers/spi/spi.c | 118 ++++++++++++++++++++++++++++++------------ + include/linux/spi/spi.h | 75 ++++++++++++++++++-------- + 3 files changed, 170 insertions(+), 75 deletions(-) + +--- gregkh-2.6.orig/Documentation/spi/spi-summary ++++ gregkh-2.6/Documentation/spi/spi-summary +@@ -1,18 +1,19 @@ + Overview of Linux kernel SPI support + ==================================== + +-22-Nov-2005 ++02-Dec-2005 + + What is SPI? + ------------ +-The "Serial Peripheral Interface" (SPI) is a four-wire point-to-point +-serial link used to connect microcontrollers to sensors and memory. ++The "Serial Peripheral Interface" (SPI) is a synchronous four wire serial ++link used to connect microcontrollers to sensors, memory, and peripherals. + + The three signal wires hold a clock (SCLK, often on the order of 10 MHz), + and parallel data lines with "Master Out, Slave In" (MOSI) or "Master In, + Slave Out" (MISO) signals. (Other names are also used.) There are four + clocking modes through which data is exchanged; mode-0 and mode-3 are most +-commonly used. ++commonly used. Each clock cycle shifts data out and data in; the clock ++doesn't cycle except when there is data to shift. + + SPI masters may use a "chip select" line to activate a given SPI slave + device, so those three signal wires may be connected to several chips +@@ -79,11 +80,18 @@ The <linux/spi/spi.h> header file includ + main source code, and you should certainly read that. This is just + an overview, so you get the big picture before the details. + ++SPI requests always go into I/O queues. Requests for a given SPI device ++are always executed in FIFO order, and complete asynchronously through ++completion callbacks. There are also some simple synchronous wrappers ++for those calls, including ones for common transaction types like writing ++a command and then reading its response. ++ + There are two types of SPI driver, here called: + + Controller drivers ... these are often built in to System-On-Chip + processors, and often support both Master and Slave roles. + These drivers touch hardware registers and may use DMA. ++ Or they can be PIO bitbangers, needing just GPIO pins. + + Protocol drivers ... these pass messages through the controller + driver to communicate with a Slave or Master device on the +@@ -116,11 +124,6 @@ shows up in sysfs in several locations: + managing bus "B". All the spiB.* devices share the same + physical SPI bus segment, with SCLK, MOSI, and MISO. + +-The basic I/O primitive submits an asynchronous message to an I/O queue +-maintained by the controller driver. A completion callback is issued +-asynchronously when the data transfer(s) in that message completes. +-There are also some simple synchronous wrappers for those calls. +- + + How does board-specific init code declare SPI devices? + ------------------------------------------------------ +@@ -263,33 +266,40 @@ would just be another kernel driver, pro + access through aio_read(), aio_write(), and ioctl() calls and using the + standard userspace sysfs mechanisms to bind to a given SPI device. + +-SPI protocol drivers are normal device drivers, with no more wrapper +-than needed by platform devices: ++SPI protocol drivers somewhat resemble platform device drivers: ++ ++ static struct spi_driver CHIP_driver = { ++ .driver = { ++ .name = "CHIP", ++ .bus = &spi_bus_type, ++ .owner = THIS_MODULE, ++ }, + +- static struct device_driver CHIP_driver = { +- .name = "CHIP", +- .bus = &spi_bus_type, + .probe = CHIP_probe, +- .remove = __exit_p(CHIP_remove), ++ .remove = __devexit_p(CHIP_remove), + .suspend = CHIP_suspend, + .resume = CHIP_resume, + }; + +-The SPI core will autmatically attempt to bind this driver to any SPI ++The driver core will autmatically attempt to bind this driver to any SPI + device whose board_info gave a modalias of "CHIP". Your probe() code + might look like this unless you're creating a class_device: + +- static int __init CHIP_probe(struct device *dev) ++ static int __devinit CHIP_probe(struct spi_device *spi) + { +- struct spi_device *spi = to_spi_device(dev); + struct CHIP *chip; +- struct CHIP_platform_data *pdata = dev->platform_data; ++ struct CHIP_platform_data *pdata; ++ ++ /* assuming the driver requires board-specific data: */ ++ pdata = &spi->dev.platform_data; ++ if (!pdata) ++ return -ENODEV; + + /* get memory for driver's per-chip state */ + chip = kzalloc(sizeof *chip, GFP_KERNEL); + if (!chip) + return -ENOMEM; +- dev_set_drvdata(dev, chip); ++ dev_set_drvdata(&spi->dev, chip); + + ... etc + return 0; +@@ -328,6 +338,8 @@ the driver guarantees that it won't subm + - The basic I/O primitive is spi_async(). Async requests may be + issued in any context (irq handler, task, etc) and completion + is reported using a callback provided with the message. ++ After any detected error, the chip is deselected and processing ++ of that spi_message is aborted. + + - There are also synchronous wrappers like spi_sync(), and wrappers + like spi_read(), spi_write(), and spi_write_then_read(). These +--- gregkh-2.6.orig/drivers/spi/spi.c ++++ gregkh-2.6/drivers/spi/spi.c +@@ -26,13 +26,9 @@ + #include <linux/spi/spi.h> + + +-/* SPI bustype and spi_master class are registered during early boot, +- * usually before board init code provides the SPI device tables, and +- * are available later when driver init code needs them. +- * +- * Drivers for SPI devices started out like those for platform bus +- * devices. But both have changed in 2.6.15; maybe this should get +- * an "spi_driver" structure at some point (not currently needed) ++/* SPI bustype and spi_master class are registered after board init code ++ * provides the SPI device tables, ensuring that both are present by the ++ * time controller driver registration causes spi_devices to "enumerate". + */ + static void spidev_release(struct device *dev) + { +@@ -83,10 +79,7 @@ static int spi_uevent(struct device *dev + + #ifdef CONFIG_PM + +-/* Suspend/resume in "struct device_driver" don't really need that +- * strange third parameter, so we just make it a constant and expect +- * SPI drivers to ignore it just like most platform drivers do. +- * ++/* + * NOTE: the suspend() method for an spi_master controller driver + * should verify that all its child devices are marked as suspended; + * suspend requests delivered through sysfs power/state files don't +@@ -94,13 +87,14 @@ static int spi_uevent(struct device *dev + */ + static int spi_suspend(struct device *dev, pm_message_t message) + { +- int value; ++ int value; ++ struct spi_driver *drv = to_spi_driver(dev->driver); + +- if (!dev->driver || !dev->driver->suspend) ++ if (!drv || !drv->suspend) + return 0; + + /* suspend will stop irqs and dma; no more i/o */ +- value = dev->driver->suspend(dev, message); ++ value = drv->suspend(to_spi_device(dev), message); + if (value == 0) + dev->power.power_state = message; + return value; +@@ -108,13 +102,14 @@ static int spi_suspend(struct device *de + + static int spi_resume(struct device *dev) + { +- int value; ++ int value; ++ struct spi_driver *drv = to_spi_driver(dev->driver); + +- if (!dev->driver || !dev->driver->resume) ++ if (!drv || !drv->resume) + return 0; + + /* resume may restart the i/o queue */ +- value = dev->driver->resume(dev); ++ value = drv->resume(to_spi_device(dev)); + if (value == 0) + dev->power.power_state = PMSG_ON; + return value; +@@ -135,6 +130,41 @@ struct bus_type spi_bus_type = { + }; + EXPORT_SYMBOL_GPL(spi_bus_type); + ++ ++static int spi_drv_probe(struct device *dev) ++{ ++ const struct spi_driver *sdrv = to_spi_driver(dev->driver); ++ ++ return sdrv->probe(to_spi_device(dev)); ++} ++ ++static int spi_drv_remove(struct device *dev) ++{ ++ const struct spi_driver *sdrv = to_spi_driver(dev->driver); ++ ++ return sdrv->remove(to_spi_device(dev)); ++} ++ ++static void spi_drv_shutdown(struct device *dev) ++{ ++ const struct spi_driver *sdrv = to_spi_driver(dev->driver); ++ ++ sdrv->shutdown(to_spi_device(dev)); ++} ++ ++int spi_register_driver(struct spi_driver *sdrv) ++{ ++ sdrv->driver.bus = &spi_bus_type; ++ if (sdrv->probe) ++ sdrv->driver.probe = spi_drv_probe; ++ if (sdrv->remove) ++ sdrv->driver.remove = spi_drv_remove; ++ if (sdrv->shutdown) ++ sdrv->driver.shutdown = spi_drv_shutdown; ++ return driver_register(&sdrv->driver); ++} ++EXPORT_SYMBOL_GPL(spi_register_driver); ++ + /*-------------------------------------------------------------------------*/ + + /* SPI devices should normally not be created by SPI device drivers; that +@@ -208,13 +238,15 @@ spi_new_device(struct spi_master *master + if (status < 0) { + dev_dbg(dev, "can't %s %s, status %d\n", + "add", proxy->dev.bus_id, status); +-fail: +- class_device_put(&master->cdev); +- kfree(proxy); +- return NULL; ++ goto fail; + } + dev_dbg(dev, "registered child %s\n", proxy->dev.bus_id); + return proxy; ++ ++fail: ++ class_device_put(&master->cdev); ++ kfree(proxy); ++ return NULL; + } + EXPORT_SYMBOL_GPL(spi_new_device); + +@@ -237,11 +269,11 @@ spi_register_board_info(struct spi_board + { + struct boardinfo *bi; + +- bi = kmalloc (sizeof (*bi) + n * sizeof (*info), GFP_KERNEL); ++ bi = kmalloc(sizeof(*bi) + n * sizeof *info, GFP_KERNEL); + if (!bi) + return -ENOMEM; + bi->n_board_info = n; +- memcpy(bi->board_info, info, n * sizeof (*info)); ++ memcpy(bi->board_info, info, n * sizeof *info); + + down(&board_lock); + list_add_tail(&bi->list, &board_list); +@@ -330,6 +362,7 @@ spi_alloc_master(struct device *dev, uns + if (!master) + return NULL; + ++ class_device_initialize(&master->cdev); + master->cdev.class = &spi_master_class; + master->cdev.dev = get_device(dev); + class_set_devdata(&master->cdev, &master[1]); +@@ -366,7 +399,7 @@ spi_register_master(struct spi_master *m + /* convention: dynamically assigned bus IDs count down from the max */ + if (master->bus_num == 0) { + master->bus_num = atomic_dec_return(&dyn_bus_id); +- dynamic = 0; ++ dynamic = 1; + } + + /* register the device, then userspace will see it. +@@ -374,11 +407,9 @@ spi_register_master(struct spi_master *m + */ + snprintf(master->cdev.class_id, sizeof master->cdev.class_id, + "spi%u", master->bus_num); +- status = class_device_register(&master->cdev); +- if (status < 0) { +- class_device_put(&master->cdev); ++ status = class_device_add(&master->cdev); ++ if (status < 0) + goto done; +- } + dev_dbg(dev, "registered master %s%s\n", master->cdev.class_id, + dynamic ? " (dynamic)" : ""); + +@@ -491,6 +522,7 @@ static u8 *buf; + * This performs a half duplex MicroWire style transaction with the + * device, sending txbuf and then reading rxbuf. The return value + * is zero for success, else a negative errno status code. ++ * This call may only be used from a context that may sleep. + * + * Parameters to this routine are always copied using a small buffer, + * large transfers should use use spi_{async,sync}() calls with +@@ -553,16 +585,38 @@ EXPORT_SYMBOL_GPL(spi_write_then_read); + + static int __init spi_init(void) + { ++ int status; ++ + buf = kmalloc(SPI_BUFSIZ, SLAB_KERNEL); +- if (!buf) +- return -ENOMEM; ++ if (!buf) { ++ status = -ENOMEM; ++ goto err0; ++ } + +- bus_register(&spi_bus_type); +- class_register(&spi_master_class); ++ status = bus_register(&spi_bus_type); ++ if (status < 0) ++ goto err1; ++ ++ status = class_register(&spi_master_class); ++ if (status < 0) ++ goto err2; + return 0; ++ ++err2: ++ bus_unregister(&spi_bus_type); ++err1: ++ kfree(buf); ++ buf = NULL; ++err0: ++ return status; + } ++ + /* board_info is normally registered in arch_initcall(), + * but even essential drivers wait till later ++ * ++ * REVISIT only boardinfo really needs static linking. the rest (device and ++ * driver registration) _could_ be dynamically linked (modular) ... costs ++ * include needing to have boardinfo data structures be much more public. + */ + subsys_initcall(spi_init); + +--- gregkh-2.6.orig/include/linux/spi/spi.h ++++ gregkh-2.6/include/linux/spi/spi.h +@@ -20,13 +20,8 @@ + #define __LINUX_SPI_H + + /* +- * INTERFACES between SPI master drivers and infrastructure ++ * INTERFACES between SPI master-side drivers and SPI infrastructure. + * (There's no SPI slave support for Linux yet...) +- * +- * A "struct device_driver" for an spi_device uses "spi_bus_type" and +- * needs no special API wrappers (much like platform_bus). These drivers +- * are bound to devices based on their names (much like platform_bus), +- * and are available in dev->driver. + */ + extern struct bus_type spi_bus_type; + +@@ -46,8 +41,8 @@ extern struct bus_type spi_bus_type; + * @irq: Negative, or the number passed to request_irq() to receive + * interrupts from this device. + * @controller_state: Controller's runtime state +- * @controller_data: Static board-specific definitions for controller, such +- * as FIFO initialization parameters; from board_info.controller_data ++ * @controller_data: Board-specific definitions for controller, such as ++ * FIFO initialization parameters; from board_info.controller_data + * + * An spi_device is used to interchange data between an SPI slave + * (usually a discrete chip) and CPU memory. +@@ -63,31 +58,32 @@ struct spi_device { + u32 max_speed_hz; + u8 chip_select; + u8 mode; +-#define SPI_CPHA 0x01 /* clock phase */ +-#define SPI_CPOL 0x02 /* clock polarity */ ++#define SPI_CPHA 0x01 /* clock phase */ ++#define SPI_CPOL 0x02 /* clock polarity */ + #define SPI_MODE_0 (0|0) +-#define SPI_MODE_1 (0|SPI_CPHA) ++#define SPI_MODE_1 (0|SPI_CPHA) /* (original MicroWire) */ + #define SPI_MODE_2 (SPI_CPOL|0) + #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) +-#define SPI_CS_HIGH 0x04 /* chipselect active high? */ ++#define SPI_CS_HIGH 0x04 /* chipselect active high? */ + u8 bits_per_word; + int irq; + void *controller_state; +- const void *controller_data; ++ void *controller_data; + const char *modalias; + + // likely need more hooks for more protocol options affecting how +- // the controller talks to its chips, 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) + // - priority ++ // - drop chipselect after each word + // - chipselect delays + // - ... + }; + + static inline struct spi_device *to_spi_device(struct device *dev) + { +- return container_of(dev, struct spi_device, dev); ++ return dev ? container_of(dev, struct spi_device, dev) : NULL; + } + + /* most drivers won't need to care about device refcounting */ +@@ -117,12 +113,38 @@ static inline void spi_set_ctldata(struc + struct spi_message; + + ++ ++struct spi_driver { ++ int (*probe)(struct spi_device *spi); ++ int (*remove)(struct spi_device *spi); ++ void (*shutdown)(struct spi_device *spi); ++ int (*suspend)(struct spi_device *spi, pm_message_t mesg); ++ int (*resume)(struct spi_device *spi); ++ struct device_driver driver; ++}; ++ ++static inline struct spi_driver *to_spi_driver(struct device_driver *drv) ++{ ++ return drv ? container_of(drv, struct spi_driver, driver) : NULL; ++} ++ ++extern int spi_register_driver(struct spi_driver *sdrv); ++ ++static inline void spi_unregister_driver(struct spi_driver *sdrv) ++{ ++ if (!sdrv) ++ return; ++ driver_unregister(&sdrv->driver); ++} ++ ++ ++ + /** + * struct spi_master - interface to SPI master controller + * @cdev: class interface to this driver + * @bus_num: board-specific (and often SOC-specific) identifier for a + * given SPI controller. +- * @num_chipselects: chipselects are used to distinguish individual ++ * @num_chipselect: chipselects are used to distinguish individual + * SPI slaves, and are numbered from zero to num_chipselects. + * each slave has a chipselect signal, but it's common that not + * every chipselect is connected to a slave. +@@ -275,7 +297,8 @@ struct spi_transfer { + * addresses for each transfer buffer + * @complete: called to report transaction completions + * @context: the argument to complete() when it's called +- * @actual_length: how many bytes were transferd ++ * @actual_length: the total number of bytes that were transferred in all ++ * successful segments + * @status: zero for success, else negative errno + * @queue: for use by whichever driver currently owns the message + * @state: for use by whichever driver currently owns the message +@@ -295,7 +318,7 @@ struct spi_message { + * + * Some controller drivers (message-at-a-time queue processing) + * could provide that as their default scheduling algorithm. But +- * others (with multi-message pipelines) would need a flag to ++ * others (with multi-message pipelines) could need a flag to + * tell them about such special cases. + */ + +@@ -346,6 +369,13 @@ spi_setup(struct spi_device *spi) + * FIFO order, messages may go to different devices in other orders. + * Some device might be higher priority, or have various "hard" access + * time requirements, for example. ++ * ++ * On detection of any fault during the transfer, processing of ++ * the entire message is aborted, and the device is deselected. ++ * Until returning from the associated message completion callback, ++ * no other spi_message queued to that device will be processed. ++ * (This rule applies equally to all the synchronous transfer calls, ++ * which are wrappers around this core asynchronous primitive.) + */ + static inline int + spi_async(struct spi_device *spi, struct spi_message *message) +@@ -484,12 +514,12 @@ struct spi_board_info { + * "modalias" is normally the driver name. + * + * platform_data goes to spi_device.dev.platform_data, +- * controller_data goes to spi_device.platform_data, ++ * controller_data goes to spi_device.controller_data, + * irq is copied too + */ + char modalias[KOBJ_NAME_LEN]; + const void *platform_data; +- const void *controller_data; ++ void *controller_data; + int irq; + + /* slower signaling on noisy or low voltage boards */ +@@ -525,9 +555,8 @@ spi_register_board_info(struct spi_board + + + /* If you're hotplugging an adapter with devices (parport, usb, etc) +- * use spi_new_device() to describe each device. You can also call +- * spi_unregister_device() to get start making that device vanish, +- * but normally that would be handled by spi_unregister_master(). ++ * use spi_new_device() to describe each device. You would then call ++ * spi_unregister_device() to start making that device vanish. + */ + extern struct spi_device * + spi_new_device(struct spi_master *, struct spi_board_info *); diff --git a/driver/spi-ads7836-uses-spi_driver.patch b/driver/spi-ads7836-uses-spi_driver.patch new file mode 100644 index 0000000000000..1571b77b584ed --- /dev/null +++ b/driver/spi-ads7836-uses-spi_driver.patch @@ -0,0 +1,237 @@ +From akpm@osdl.org Sun Jan 8 13:39:04 2006 +From: akpm@osdl.org +Message-Id: <200601082134.k08LYbkH004576@shell0.pdx.osdl.net> +Subject: [patch 06/10] spi: ads7836 uses spi_driver +To: greg@kroah.com +Cc: akpm@osdl.org, david-b@pacbell.net, dbrownell@users.sourceforge.net +Date: Sun, 08 Jan 2006 13:34:25 -0800 + + +From: David Brownell <david-b@pacbell.net> + +This updates the ads7864 driver to use the new "spi_driver" struct, and +includes some minor unrelated cleanup. + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + drivers/input/touchscreen/ads7846.c | 84 ++++++++++++++++++------------------ + include/linux/spi/ads7846.h | 2 + 2 files changed, 43 insertions(+), 43 deletions(-) + +--- gregkh-2.6.orig/drivers/input/touchscreen/ads7846.c ++++ gregkh-2.6/drivers/input/touchscreen/ads7846.c +@@ -345,19 +345,15 @@ static irqreturn_t ads7846_irq(int irq, + + /*--------------------------------------------------------------------------*/ + +-/* non-empty "extra" is needed before 2.6.14-git5 or so */ +-#define EXTRA // , u32 level +-#define EXTRA2 // , 0 +- + static int +-ads7846_suspend(struct device *dev, pm_message_t message EXTRA) ++ads7846_suspend(struct spi_device *spi, pm_message_t message) + { +- struct ads7846 *ts = dev_get_drvdata(dev); ++ struct ads7846 *ts = dev_get_drvdata(&spi->dev); + unsigned long flags; + + spin_lock_irqsave(&ts->lock, flags); + +- ts->spi->dev.power.power_state = message; ++ spi->dev.power.power_state = message; + + /* are we waiting for IRQ, or polling? */ + if (!ts->pendown) { +@@ -387,36 +383,35 @@ ads7846_suspend(struct device *dev, pm_m + return 0; + } + +-static int ads7846_resume(struct device *dev EXTRA) ++static int ads7846_resume(struct spi_device *spi) + { +- struct ads7846 *ts = dev_get_drvdata(dev); ++ struct ads7846 *ts = dev_get_drvdata(&spi->dev); + + ts->irq_disabled = 0; + enable_irq(ts->spi->irq); +- dev->power.power_state = PMSG_ON; ++ spi->dev.power.power_state = PMSG_ON; + return 0; + } + +-static int __init ads7846_probe(struct device *dev) ++static int __devinit ads7846_probe(struct spi_device *spi) + { +- struct spi_device *spi = to_spi_device(dev); + struct ads7846 *ts; +- struct ads7846_platform_data *pdata = dev->platform_data; ++ struct ads7846_platform_data *pdata = spi->dev.platform_data; + struct spi_transfer *x; + + if (!spi->irq) { +- dev_dbg(dev, "no IRQ?\n"); ++ dev_dbg(&spi->dev, "no IRQ?\n"); + return -ENODEV; + } + + if (!pdata) { +- dev_dbg(dev, "no platform data?\n"); ++ dev_dbg(&spi->dev, "no platform data?\n"); + return -ENODEV; + } + + /* don't exceed max specified sample rate */ + if (spi->max_speed_hz > (125000 * 16)) { +- dev_dbg(dev, "f(sample) %d KHz?\n", ++ dev_dbg(&spi->dev, "f(sample) %d KHz?\n", + (spi->max_speed_hz/16)/1000); + return -EINVAL; + } +@@ -430,7 +425,7 @@ static int __init ads7846_probe(struct d + if (!(ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL))) + return -ENOMEM; + +- dev_set_drvdata(dev, ts); ++ dev_set_drvdata(&spi->dev, ts); + + ts->spi = spi; + spi->dev.power.power_state = PMSG_ON; +@@ -445,9 +440,9 @@ static int __init ads7846_probe(struct d + + init_input_dev(&ts->input); + +- ts->input.dev = dev; ++ ts->input.dev = &spi->dev; + ts->input.name = "ADS784x Touchscreen"; +- snprintf(ts->phys, sizeof ts->phys, "%s/input0", dev->bus_id); ++ snprintf(ts->phys, sizeof ts->phys, "%s/input0", spi->dev.bus_id); + ts->input.phys = ts->phys; + + ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); +@@ -511,65 +506,68 @@ static int __init ads7846_probe(struct d + ts->msg.context = ts; + + if (request_irq(spi->irq, ads7846_irq, SA_SAMPLE_RANDOM, +- dev->bus_id, ts)) { +- dev_dbg(dev, "irq %d busy?\n", spi->irq); ++ spi->dev.bus_id, ts)) { ++ dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); + input_unregister_device(&ts->input); + kfree(ts); + return -EBUSY; + } + set_irq_type(spi->irq, IRQT_FALLING); + +- dev_info(dev, "touchscreen, irq %d\n", spi->irq); ++ dev_info(&spi->dev, "touchscreen, irq %d\n", spi->irq); + + /* take a first sample, leaving nPENIRQ active; avoid + * the touchscreen, in case it's not connected. + */ +- (void) ads7846_read12_ser(dev, ++ (void) ads7846_read12_ser(&spi->dev, + READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); + + /* ads7843/7845 don't have temperature sensors, and + * use the other sensors a bit differently too + */ + if (ts->model == 7846) { +- device_create_file(dev, &dev_attr_temp0); +- device_create_file(dev, &dev_attr_temp1); ++ device_create_file(&spi->dev, &dev_attr_temp0); ++ device_create_file(&spi->dev, &dev_attr_temp1); + } + if (ts->model != 7845) +- device_create_file(dev, &dev_attr_vbatt); +- device_create_file(dev, &dev_attr_vaux); ++ device_create_file(&spi->dev, &dev_attr_vbatt); ++ device_create_file(&spi->dev, &dev_attr_vaux); + + return 0; + } + +-static int __exit ads7846_remove(struct device *dev) ++static int __devexit ads7846_remove(struct spi_device *spi) + { +- struct ads7846 *ts = dev_get_drvdata(dev); ++ struct ads7846 *ts = dev_get_drvdata(&spi->dev); + +- ads7846_suspend(dev, PMSG_SUSPEND EXTRA2); ++ ads7846_suspend(spi, PMSG_SUSPEND); + free_irq(ts->spi->irq, ts); + if (ts->irq_disabled) + enable_irq(ts->spi->irq); + + if (ts->model == 7846) { +- device_remove_file(dev, &dev_attr_temp0); +- device_remove_file(dev, &dev_attr_temp1); ++ device_remove_file(&spi->dev, &dev_attr_temp0); ++ device_remove_file(&spi->dev, &dev_attr_temp1); + } + if (ts->model != 7845) +- device_remove_file(dev, &dev_attr_vbatt); +- device_remove_file(dev, &dev_attr_vaux); ++ device_remove_file(&spi->dev, &dev_attr_vbatt); ++ device_remove_file(&spi->dev, &dev_attr_vaux); + + input_unregister_device(&ts->input); + kfree(ts); + +- dev_dbg(dev, "unregistered touchscreen\n"); ++ dev_dbg(&spi->dev, "unregistered touchscreen\n"); + return 0; + } + +-static struct device_driver ads7846_driver = { +- .name = "ads7846", +- .bus = &spi_bus_type, ++static struct spi_driver ads7846_driver = { ++ .driver = { ++ .name = "ads7846", ++ .bus = &spi_bus_type, ++ .owner = THIS_MODULE, ++ }, + .probe = ads7846_probe, +- .remove = __exit_p(ads7846_remove), ++ .remove = __devexit_p(ads7846_remove), + .suspend = ads7846_suspend, + .resume = ads7846_resume, + }; +@@ -594,18 +592,20 @@ static int __init ads7846_init(void) + // PXA: + // also Dell Axim X50 + // also HP iPaq H191x/H192x/H415x/H435x +- // also Intel Lubbock (alternate to UCB1400) ++ // also Intel Lubbock (additional to UCB1400; as temperature sensor) + // also Sharp Zaurus C7xx, C8xx (corgi/sheperd/husky) + ++ // Atmel at91sam9261-EK uses ads7843 ++ + // also various AMD Au1x00 devel boards + +- return driver_register(&ads7846_driver); ++ return spi_register_driver(&ads7846_driver); + } + module_init(ads7846_init); + + static void __exit ads7846_exit(void) + { +- driver_unregister(&ads7846_driver); ++ spi_unregister_driver(&ads7846_driver); + + #ifdef CONFIG_ARCH_OMAP + if (machine_is_omap_osk()) { +--- gregkh-2.6.orig/include/linux/spi/ads7846.h ++++ gregkh-2.6/include/linux/spi/ads7846.h +@@ -1,7 +1,7 @@ + /* linux/spi/ads7846.h */ + + /* Touchscreen characteristics vary between boards and models. The +- * platform_data for the device's "struct device" holts this information. ++ * platform_data for the device's "struct device" holds this information. + * + * It's OK if the min/max values are zero. + */ diff --git a/driver/spi-ads7846-driver.patch b/driver/spi-ads7846-driver.patch new file mode 100644 index 0000000000000..7dda097d803f9 --- /dev/null +++ b/driver/spi-ads7846-driver.patch @@ -0,0 +1,734 @@ +From akpm@osdl.org Sun Jan 8 13:37:01 2006 +From: akpm@osdl.org +Message-Id: <200601082134.k08LYWLu004559@shell0.pdx.osdl.net> +Subject: [patch 02/10] spi: ads7846 driver +To: greg@kroah.com +Cc: akpm@osdl.org, david-b@pacbell.net +Date: Sun, 08 Jan 2006 13:34:21 -0800 + + +From: David Brownell <david-b@pacbell.net> + +This is a driver for the ADS7846 touchscreen sensor, derived from +the corgi_ts and omap_ts drivers. Key differences from those two: + + - Uses the new SPI framework (minimalist version) + - <linux/spi/ads7846.h> abstracts board-specific touchscreen info + - Sysfs attributes for the temperature and voltage sensors + - Uses fewer ARM-specific IRQ primitives + +The temperature and voltage sensors show up in sysfs like this: + + $ pwd + /sys/devices/platform/omap-uwire/spi2.0 + $ ls + bus@ input:event0@ power/ temp1 vbatt + driver@ modalias temp0 vaux + $ cat modalias + ads7846 + $ cat temp0 + 991 + $ cat temp1 + 1177 + $ + +So far only basic testing has been done. There's a fair amount of hardware +that uses this sensor, and which also runs Linux, which should eventually +be able to use this driver. + +One portability note may be of special interest. It turns out that not all +SPI controllers are happy issuing requests that do things like "write 8 bit +command, read 12 bit response". Most of them seem happy to handle various +word sizes, so the issue isn't "12 bit response" but rather "different rx +and tx write sizes", despite that being a common MicroWire convention. So +this version of the driver no longer reads 12 bit native-endian words; it +reads 16-bit big-endian responses, then byteswaps them and shifts the +results to discard the noise. + +Signed-off-by: David Brownell <david-b@pacbell.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + drivers/input/touchscreen/Kconfig | 13 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/ads7846.c | 621 ++++++++++++++++++++++++++++++++++++ + include/linux/spi/ads7846.h | 18 + + 4 files changed, 653 insertions(+) + +--- /dev/null ++++ gregkh-2.6/drivers/input/touchscreen/ads7846.c +@@ -0,0 +1,621 @@ ++/* ++ * ADS7846 based touchscreen and sensor driver ++ * ++ * Copyright (c) 2005 David Brownell ++ * ++ * Using code from: ++ * - corgi_ts.c ++ * Copyright (C) 2004-2005 Richard Purdie ++ * - omap_ts.[hc], ads7846.h, ts_osk.c ++ * Copyright (C) 2002 MontaVista Software ++ * Copyright (C) 2004 Texas Instruments ++ * Copyright (C) 2005 Dirk Behme ++ * ++ * 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/device.h> ++#include <linux/init.h> ++#include <linux/delay.h> ++#include <linux/input.h> ++#include <linux/interrupt.h> ++#include <linux/slab.h> ++#include <linux/spi/spi.h> ++#include <linux/spi/ads7846.h> ++ ++#ifdef CONFIG_ARM ++#include <asm/mach-types.h> ++#ifdef CONFIG_ARCH_OMAP ++#include <asm/arch/gpio.h> ++#endif ++ ++#else ++#define set_irq_type(irq,type) do{}while(0) ++#endif ++ ++ ++/* ++ * This code has been lightly tested on an ads7846. ++ * Support for ads7843 and ads7845 has only been stubbed in. ++ * ++ * Not yet done: investigate the values reported. Are x/y/pressure ++ * event values sane enough for X11? How accurate are the temperature ++ * and voltage readings? (System-specific calibration should support ++ * accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.) ++ * ++ * app note sbaa036 talks in more detail about accurate sampling... ++ * that ought to help in situations like LCDs inducing noise (which ++ * can also be helped by using synch signals) and more generally. ++ */ ++ ++#define TS_POLL_PERIOD msecs_to_jiffies(10) ++ ++struct ts_event { ++ /* For portability, we can't read 12 bit values using SPI (which ++ * would make the controller deliver them as native byteorder u16 ++ * with msbs zeroed). Instead, we read them as two 8-byte values, ++ * which need byteswapping then range adjustment. ++ */ ++ __be16 x; ++ __be16 y; ++ __be16 z1, z2; ++}; ++ ++struct ads7846 { ++ struct input_dev input; ++ char phys[32]; ++ ++ struct spi_device *spi; ++ u16 model; ++ u16 vref_delay_usecs; ++ u16 x_plate_ohms; ++ ++ struct ts_event tc; ++ ++ struct spi_transfer xfer[8]; ++ struct spi_message msg; ++ ++ spinlock_t lock; ++ struct timer_list timer; /* P: lock */ ++ unsigned pendown:1; /* P: lock */ ++ unsigned pending:1; /* P: lock */ ++// FIXME remove "irq_disabled" ++ unsigned irq_disabled:1; /* P: lock */ ++}; ++ ++/* leave chip selected when we're done, for quicker re-select? */ ++#if 0 ++#define CS_CHANGE(xfer) ((xfer).cs_change = 1) ++#else ++#define CS_CHANGE(xfer) ((xfer).cs_change = 0) ++#endif ++ ++/*--------------------------------------------------------------------------*/ ++ ++/* The ADS7846 has touchscreen and other sensors. ++ * Earlier ads784x chips are somewhat compatible. ++ */ ++#define ADS_START (1 << 7) ++#define ADS_A2A1A0_d_y (1 << 4) /* differential */ ++#define ADS_A2A1A0_d_z1 (3 << 4) /* differential */ ++#define ADS_A2A1A0_d_z2 (4 << 4) /* differential */ ++#define ADS_A2A1A0_d_x (5 << 4) /* differential */ ++#define ADS_A2A1A0_temp0 (0 << 4) /* non-differential */ ++#define ADS_A2A1A0_vbatt (2 << 4) /* non-differential */ ++#define ADS_A2A1A0_vaux (6 << 4) /* non-differential */ ++#define ADS_A2A1A0_temp1 (7 << 4) /* non-differential */ ++#define ADS_8_BIT (1 << 3) ++#define ADS_12_BIT (0 << 3) ++#define ADS_SER (1 << 2) /* non-differential */ ++#define ADS_DFR (0 << 2) /* differential */ ++#define ADS_PD10_PDOWN (0 << 0) /* lowpower mode + penirq */ ++#define ADS_PD10_ADC_ON (1 << 0) /* ADC on */ ++#define ADS_PD10_REF_ON (2 << 0) /* vREF on + penirq */ ++#define ADS_PD10_ALL_ON (3 << 0) /* ADC + vREF on */ ++ ++#define MAX_12BIT ((1<<12)-1) ++ ++/* leave ADC powered up (disables penirq) between differential samples */ ++#define READ_12BIT_DFR(x) (ADS_START | ADS_A2A1A0_d_ ## x \ ++ | ADS_12_BIT | ADS_DFR) ++ ++static const u8 read_y = READ_12BIT_DFR(y) | ADS_PD10_ADC_ON; ++static const u8 read_z1 = READ_12BIT_DFR(z1) | ADS_PD10_ADC_ON; ++static const u8 read_z2 = READ_12BIT_DFR(z2) | ADS_PD10_ADC_ON; ++static const u8 read_x = READ_12BIT_DFR(x) | ADS_PD10_PDOWN; /* LAST */ ++ ++/* single-ended samples need to first power up reference voltage; ++ * we leave both ADC and VREF powered ++ */ ++#define READ_12BIT_SER(x) (ADS_START | ADS_A2A1A0_ ## x \ ++ | ADS_12_BIT | ADS_SER) ++ ++static const u8 ref_on = READ_12BIT_DFR(x) | ADS_PD10_ALL_ON; ++static const u8 ref_off = READ_12BIT_DFR(y) | ADS_PD10_PDOWN; ++ ++/*--------------------------------------------------------------------------*/ ++ ++/* ++ * Non-touchscreen sensors only use single-ended conversions. ++ */ ++ ++struct ser_req { ++ u8 command; ++ u16 scratch; ++ __be16 sample; ++ struct spi_message msg; ++ struct spi_transfer xfer[6]; ++}; ++ ++static int ads7846_read12_ser(struct device *dev, unsigned command) ++{ ++ struct spi_device *spi = to_spi_device(dev); ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL); ++ int status; ++ int sample; ++ ++ if (!req) ++ return -ENOMEM; ++ ++ /* activate reference, so it has time to settle; */ ++ req->xfer[0].tx_buf = &ref_on; ++ req->xfer[0].len = 1; ++ req->xfer[1].rx_buf = &req->scratch; ++ req->xfer[1].len = 2; ++ ++ /* ++ * for external VREF, 0 usec (and assume it's always on); ++ * for 1uF, use 800 usec; ++ * no cap, 100 usec. ++ */ ++ req->xfer[1].delay_usecs = ts->vref_delay_usecs; ++ ++ /* take sample */ ++ req->command = (u8) command; ++ req->xfer[2].tx_buf = &req->command; ++ req->xfer[2].len = 1; ++ req->xfer[3].rx_buf = &req->sample; ++ req->xfer[3].len = 2; ++ ++ /* REVISIT: take a few more samples, and compare ... */ ++ ++ /* turn off reference */ ++ req->xfer[4].tx_buf = &ref_off; ++ req->xfer[4].len = 1; ++ req->xfer[5].rx_buf = &req->scratch; ++ req->xfer[5].len = 2; ++ ++ CS_CHANGE(req->xfer[5]); ++ ++ /* group all the transfers together, so we can't interfere with ++ * reading touchscreen state; disable penirq while sampling ++ */ ++ req->msg.transfers = req->xfer; ++ req->msg.n_transfer = 6; ++ ++ disable_irq(spi->irq); ++ status = spi_sync(spi, &req->msg); ++ enable_irq(spi->irq); ++ ++ if (req->msg.status) ++ status = req->msg.status; ++ sample = be16_to_cpu(req->sample); ++ sample = sample >> 4; ++ kfree(req); ++ ++ return status ? status : sample; ++} ++ ++#define SHOW(name) static ssize_t \ ++name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \ ++{ \ ++ ssize_t v = ads7846_read12_ser(dev, \ ++ READ_12BIT_SER(name) | ADS_PD10_ALL_ON); \ ++ if (v < 0) \ ++ return v; \ ++ return sprintf(buf, "%u\n", (unsigned) v); \ ++} \ ++static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL); ++ ++SHOW(temp0) ++SHOW(temp1) ++SHOW(vaux) ++SHOW(vbatt) ++ ++/*--------------------------------------------------------------------------*/ ++ ++/* ++ * PENIRQ only kicks the timer. The timer only reissues the SPI transfer, ++ * to retrieve touchscreen status. ++ * ++ * The SPI transfer completion callback does the real work. It reports ++ * touchscreen events and reactivates the timer (or IRQ) as appropriate. ++ */ ++ ++static void ads7846_rx(void *ads) ++{ ++ struct ads7846 *ts = ads; ++ unsigned Rt; ++ unsigned sync = 0; ++ u16 x, y, z1, z2; ++ unsigned long flags; ++ ++ /* adjust: 12 bit samples (left aligned), built from ++ * two 8 bit values writen msb-first. ++ */ ++ x = be16_to_cpu(ts->tc.x) >> 4; ++ y = be16_to_cpu(ts->tc.y) >> 4; ++ z1 = be16_to_cpu(ts->tc.z1) >> 4; ++ z2 = be16_to_cpu(ts->tc.z2) >> 4; ++ ++ /* range filtering */ ++ if (x == MAX_12BIT) ++ x = 0; ++ ++ if (x && z1 && ts->spi->dev.power.power_state.event == PM_EVENT_ON) { ++ /* compute touch pressure resistance using equation #2 */ ++ Rt = z2; ++ Rt -= z1; ++ Rt *= x; ++ Rt *= ts->x_plate_ohms; ++ Rt /= z1; ++ Rt = (Rt + 2047) >> 12; ++ } else ++ Rt = 0; ++ ++ /* NOTE: "pendown" is inferred from pressure; we don't rely on ++ * being able to check nPENIRQ status, or "friendly" trigger modes ++ * (both-edges is much better than just-falling or low-level). ++ * ++ * REVISIT: some boards may require reading nPENIRQ; it's ++ * needed on 7843. and 7845 reads pressure differently... ++ * ++ * REVISIT: the touchscreen might not be connected; this code ++ * won't notice that, even if nPENIRQ never fires ... ++ */ ++ if (!ts->pendown && Rt != 0) { ++ input_report_key(&ts->input, BTN_TOUCH, 1); ++ sync = 1; ++ } else if (ts->pendown && Rt == 0) { ++ input_report_key(&ts->input, BTN_TOUCH, 0); ++ sync = 1; ++ } ++ ++ if (Rt) { ++ input_report_abs(&ts->input, ABS_X, x); ++ input_report_abs(&ts->input, ABS_Y, y); ++ input_report_abs(&ts->input, ABS_PRESSURE, Rt); ++ sync = 1; ++ } ++ if (sync) ++ input_sync(&ts->input); ++ ++#ifdef VERBOSE ++ if (Rt || ts->pendown) ++ pr_debug("%s: %d/%d/%d%s\n", ts->spi->dev.bus_id, ++ x, y, Rt, Rt ? "" : " UP"); ++#endif ++ ++ /* don't retrigger while we're suspended */ ++ spin_lock_irqsave(&ts->lock, flags); ++ ++ ts->pendown = (Rt != 0); ++ ts->pending = 0; ++ ++ if (ts->spi->dev.power.power_state.event == PM_EVENT_ON) { ++ if (ts->pendown) ++ mod_timer(&ts->timer, jiffies + TS_POLL_PERIOD); ++ else if (ts->irq_disabled) { ++ ts->irq_disabled = 0; ++ enable_irq(ts->spi->irq); ++ } ++ } ++ ++ spin_unlock_irqrestore(&ts->lock, flags); ++} ++ ++static void ads7846_timer(unsigned long handle) ++{ ++ struct ads7846 *ts = (void *)handle; ++ int status = 0; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ts->lock, flags); ++ if (!ts->pending) { ++ ts->pending = 1; ++ if (!ts->irq_disabled) { ++ ts->irq_disabled = 1; ++ disable_irq(ts->spi->irq); ++ } ++ status = spi_async(ts->spi, &ts->msg); ++ if (status) ++ dev_err(&ts->spi->dev, "spi_async --> %d\n", ++ status); ++ } ++ spin_unlock_irqrestore(&ts->lock, flags); ++} ++ ++static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs) ++{ ++ ads7846_timer((unsigned long) handle); ++ return IRQ_HANDLED; ++} ++ ++/*--------------------------------------------------------------------------*/ ++ ++/* non-empty "extra" is needed before 2.6.14-git5 or so */ ++#define EXTRA // , u32 level ++#define EXTRA2 // , 0 ++ ++static int ++ads7846_suspend(struct device *dev, pm_message_t message EXTRA) ++{ ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ unsigned long flags; ++ ++ spin_lock_irqsave(&ts->lock, flags); ++ ++ ts->spi->dev.power.power_state = message; ++ ++ /* are we waiting for IRQ, or polling? */ ++ if (!ts->pendown) { ++ if (!ts->irq_disabled) { ++ ts->irq_disabled = 1; ++ disable_irq(ts->spi->irq); ++ } ++ } else { ++ /* polling; force a final SPI completion; ++ * that will clean things up neatly ++ */ ++ if (!ts->pending) ++ mod_timer(&ts->timer, jiffies); ++ ++ while (ts->pendown || ts->pending) { ++ spin_unlock_irqrestore(&ts->lock, flags); ++ udelay(10); ++ spin_lock_irqsave(&ts->lock, flags); ++ } ++ } ++ ++ /* we know the chip's in lowpower mode since we always ++ * leave it that way after every request ++ */ ++ ++ spin_unlock_irqrestore(&ts->lock, flags); ++ return 0; ++} ++ ++static int ads7846_resume(struct device *dev EXTRA) ++{ ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ ++ ts->irq_disabled = 0; ++ enable_irq(ts->spi->irq); ++ dev->power.power_state = PMSG_ON; ++ return 0; ++} ++ ++static int __init ads7846_probe(struct device *dev) ++{ ++ struct spi_device *spi = to_spi_device(dev); ++ struct ads7846 *ts; ++ struct ads7846_platform_data *pdata = dev->platform_data; ++ struct spi_transfer *x; ++ ++ if (!spi->irq) { ++ dev_dbg(dev, "no IRQ?\n"); ++ return -ENODEV; ++ } ++ ++ if (!pdata) { ++ dev_dbg(dev, "no platform data?\n"); ++ return -ENODEV; ++ } ++ ++ /* don't exceed max specified sample rate */ ++ if (spi->max_speed_hz > (125000 * 16)) { ++ dev_dbg(dev, "f(sample) %d KHz?\n", ++ (spi->max_speed_hz/16)/1000); ++ return -EINVAL; ++ } ++ ++ /* We'd set the wordsize to 12 bits ... except that some controllers ++ * will then treat the 8 bit command words as 12 bits (and drop the ++ * four MSBs of the 12 bit result). Result: inputs must be shifted ++ * to discard the four garbage LSBs. ++ */ ++ ++ if (!(ts = kzalloc(sizeof(struct ads7846), GFP_KERNEL))) ++ return -ENOMEM; ++ ++ dev_set_drvdata(dev, ts); ++ ++ ts->spi = spi; ++ spi->dev.power.power_state = PMSG_ON; ++ ++ init_timer(&ts->timer); ++ ts->timer.data = (unsigned long) ts; ++ ts->timer.function = ads7846_timer; ++ ++ ts->model = pdata->model ? : 7846; ++ ts->vref_delay_usecs = pdata->vref_delay_usecs ? : 100; ++ ts->x_plate_ohms = pdata->x_plate_ohms ? : 400; ++ ++ init_input_dev(&ts->input); ++ ++ ts->input.dev = dev; ++ ts->input.name = "ADS784x Touchscreen"; ++ snprintf(ts->phys, sizeof ts->phys, "%s/input0", dev->bus_id); ++ ts->input.phys = ts->phys; ++ ++ ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); ++ ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); ++ input_set_abs_params(&ts->input, ABS_X, ++ pdata->x_min ? : 0, ++ pdata->x_max ? : MAX_12BIT, ++ 0, 0); ++ input_set_abs_params(&ts->input, ABS_Y, ++ pdata->y_min ? : 0, ++ pdata->y_max ? : MAX_12BIT, ++ 0, 0); ++ input_set_abs_params(&ts->input, ABS_PRESSURE, ++ pdata->pressure_min, pdata->pressure_max, 0, 0); ++ ++ input_register_device(&ts->input); ++ ++ /* set up the transfers to read touchscreen state; this assumes we ++ * use formula #2 for pressure, not #3. ++ */ ++ x = ts->xfer; ++ ++ /* y- still on; turn on only y+ (and ADC) */ ++ x->tx_buf = &read_y; ++ x->len = 1; ++ x++; ++ x->rx_buf = &ts->tc.y; ++ x->len = 2; ++ x++; ++ ++ /* turn y+ off, x- on; we'll use formula #2 */ ++ if (ts->model == 7846) { ++ x->tx_buf = &read_z1; ++ x->len = 1; ++ x++; ++ x->rx_buf = &ts->tc.z1; ++ x->len = 2; ++ x++; ++ ++ x->tx_buf = &read_z2; ++ x->len = 1; ++ x++; ++ x->rx_buf = &ts->tc.z2; ++ x->len = 2; ++ x++; ++ } ++ ++ /* turn y- off, x+ on, then leave in lowpower */ ++ x->tx_buf = &read_x; ++ x->len = 1; ++ x++; ++ x->rx_buf = &ts->tc.x; ++ x->len = 2; ++ x++; ++ ++ CS_CHANGE(x[-1]); ++ ++ ts->msg.transfers = ts->xfer; ++ ts->msg.n_transfer = x - ts->xfer; ++ ts->msg.complete = ads7846_rx; ++ ts->msg.context = ts; ++ ++ if (request_irq(spi->irq, ads7846_irq, SA_SAMPLE_RANDOM, ++ dev->bus_id, ts)) { ++ dev_dbg(dev, "irq %d busy?\n", spi->irq); ++ input_unregister_device(&ts->input); ++ kfree(ts); ++ return -EBUSY; ++ } ++ set_irq_type(spi->irq, IRQT_FALLING); ++ ++ dev_info(dev, "touchscreen, irq %d\n", spi->irq); ++ ++ /* take a first sample, leaving nPENIRQ active; avoid ++ * the touchscreen, in case it's not connected. ++ */ ++ (void) ads7846_read12_ser(dev, ++ READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON); ++ ++ /* ads7843/7845 don't have temperature sensors, and ++ * use the other sensors a bit differently too ++ */ ++ if (ts->model == 7846) { ++ device_create_file(dev, &dev_attr_temp0); ++ device_create_file(dev, &dev_attr_temp1); ++ } ++ if (ts->model != 7845) ++ device_create_file(dev, &dev_attr_vbatt); ++ device_create_file(dev, &dev_attr_vaux); ++ ++ return 0; ++} ++ ++static int __exit ads7846_remove(struct device *dev) ++{ ++ struct ads7846 *ts = dev_get_drvdata(dev); ++ ++ ads7846_suspend(dev, PMSG_SUSPEND EXTRA2); ++ free_irq(ts->spi->irq, ts); ++ if (ts->irq_disabled) ++ enable_irq(ts->spi->irq); ++ ++ if (ts->model == 7846) { ++ device_remove_file(dev, &dev_attr_temp0); ++ device_remove_file(dev, &dev_attr_temp1); ++ } ++ if (ts->model != 7845) ++ device_remove_file(dev, &dev_attr_vbatt); ++ device_remove_file(dev, &dev_attr_vaux); ++ ++ input_unregister_device(&ts->input); ++ kfree(ts); ++ ++ dev_dbg(dev, "unregistered touchscreen\n"); ++ return 0; ++} ++ ++static struct device_driver ads7846_driver = { ++ .name = "ads7846", ++ .bus = &spi_bus_type, ++ .probe = ads7846_probe, ++ .remove = __exit_p(ads7846_remove), ++ .suspend = ads7846_suspend, ++ .resume = ads7846_resume, ++}; ++ ++static int __init ads7846_init(void) ++{ ++ /* grr, board-specific init should stay out of drivers!! */ ++ ++#ifdef CONFIG_ARCH_OMAP ++ if (machine_is_omap_osk()) { ++ /* GPIO4 = PENIRQ; GPIO6 = BUSY */ ++ omap_request_gpio(4); ++ omap_set_gpio_direction(4, 1); ++ omap_request_gpio(6); ++ omap_set_gpio_direction(6, 1); ++ } ++ // also TI 1510 Innovator, bitbanging through FPGA ++ // also Nokia 770 ++ // also Palm Tungsten T2 ++#endif ++ ++ // PXA: ++ // also Dell Axim X50 ++ // also HP iPaq H191x/H192x/H415x/H435x ++ // also Intel Lubbock (alternate to UCB1400) ++ // also Sharp Zaurus C7xx, C8xx (corgi/sheperd/husky) ++ ++ // also various AMD Au1x00 devel boards ++ ++ return driver_register(&ads7846_driver); ++} ++module_init(ads7846_init); ++ ++static void __exit ads7846_exit(void) ++{ ++ driver_unregister(&ads7846_driver); ++ ++#ifdef CONFIG_ARCH_OMAP ++ if (machine_is_omap_osk()) { ++ omap_free_gpio(4); ++ omap_free_gpio(6); ++ } ++#endif ++ ++} ++module_exit(ads7846_exit); ++ ++MODULE_DESCRIPTION("ADS7846 TouchScreen Driver"); ++MODULE_LICENSE("GPL"); +--- gregkh-2.6.orig/drivers/input/touchscreen/Kconfig ++++ gregkh-2.6/drivers/input/touchscreen/Kconfig +@@ -11,6 +11,19 @@ menuconfig INPUT_TOUCHSCREEN + + if INPUT_TOUCHSCREEN + ++config TOUCHSCREEN_ADS7846 ++ tristate "ADS 7846 based touchscreens" ++ depends on SPI_MASTER ++ help ++ Say Y here if you have a touchscreen interface using the ++ ADS7846 controller, and your board-specific initialization ++ code includes that in its table of SPI devices. ++ ++ If unsure, say N (but it's safe to say "Y"). ++ ++ To compile this driver as a module, choose M here: the ++ module will be called ads7846. ++ + config TOUCHSCREEN_BITSY + tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" + depends on SA1100_BITSY +--- gregkh-2.6.orig/drivers/input/touchscreen/Makefile ++++ gregkh-2.6/drivers/input/touchscreen/Makefile +@@ -4,6 +4,7 @@ + + # Each configuration option enables a list of files. + ++obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o + obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o + obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o + obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o +--- /dev/null ++++ gregkh-2.6/include/linux/spi/ads7846.h +@@ -0,0 +1,18 @@ ++/* linux/spi/ads7846.h */ ++ ++/* Touchscreen characteristics vary between boards and models. The ++ * platform_data for the device's "struct device" holts this information. ++ * ++ * It's OK if the min/max values are zero. ++ */ ++struct ads7846_platform_data { ++ u16 model; /* 7843, 7845, 7846. */ ++ u16 vref_delay_usecs; /* 0 for external vref; etc */ ++ u16 x_plate_ohms; ++ u16 y_plate_ohms; ++ ++ u16 x_min, x_max; ++ u16 y_min, y_max; ++ u16 pressure_min, pressure_max; ++}; ++ diff --git a/driver/spi-core-tweaks-bugfix.patch b/driver/spi-core-tweaks-bugfix.patch new file mode 100644 index 0000000000000..433ad11e4f2be --- /dev/null +++ b/driver/spi-core-tweaks-bugfix.patch @@ -0,0 +1,358 @@ +From akpm@osdl.org Sun Jan 8 13:39:08 2006 +From: akpm@osdl.org +Message-Id: <200601082134.k08LYaxO004573@shell0.pdx.osdl.net> +Subject: [patch 05/10] SPI core tweaks, bugfix +To: greg@kroah.com +Cc: akpm@osdl.org, david-b@pacbell.net, dbrownell@users.sourceforge.net +Date: Sun, 08 Jan 2006 13:34:25 -0800 + + +From: David Brownell <david-b@pacbell.net> + +This includes various updates to the SPI core: + + - Fixes a driver model refcount bug in spi_unregister_master() paths. + + - The spi_master structures now have wrappers which help keep drivers + from needing class-level get/put for device data or for refcounts. + + - Check for a few setup errors that would cause oopsing later. + + - Docs say more about memory management. Highlights the use of DMA-safe + i/o buffers, and zero-initializing spi_message and such metadata. + + - Provide a simple alloc/free for spi_message and its spi_transfer; + this is only one of the possible memory management policies. + +Nothing to break code that already works. + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + Documentation/spi/spi-summary | 16 ++++++++ + drivers/spi/spi.c | 45 +++++++++++++++---------- + include/linux/spi/spi.h | 75 ++++++++++++++++++++++++++++++++++++++---- + 3 files changed, 113 insertions(+), 23 deletions(-) + +--- gregkh-2.6.orig/Documentation/spi/spi-summary ++++ gregkh-2.6/Documentation/spi/spi-summary +@@ -363,6 +363,22 @@ upper boundaries might include sysfs (es + the input layer, ALSA, networking, MTD, the character device framework, + or other Linux subsystems. + ++Note that there are two types of memory your driver must manage as part ++of interacting with SPI devices. ++ ++ - I/O buffers use the usual Linux rules, and must be DMA-safe. ++ You'd normally allocate them from the heap or free page pool. ++ Don't use the stack, or anything that's declared "static". ++ ++ - The spi_message and spi_transfer metadata used to glue those ++ I/O buffers into a group of protocol transactions. These can ++ be allocated anywhere it's convenient, including as part of ++ other allocate-once driver data structures. Zero-init these. ++ ++If you like, spi_message_alloc() and spi_message_free() convenience ++routines are available to allocate and zero-initialize an spi_message ++with several transfers. ++ + + How do I write an "SPI Master Controller Driver"? + ------------------------------------------------- +--- gregkh-2.6.orig/drivers/spi/spi.c ++++ gregkh-2.6/drivers/spi/spi.c +@@ -38,7 +38,7 @@ static void spidev_release(struct device + if (spi->master->cleanup) + spi->master->cleanup(spi); + +- class_device_put(&spi->master->cdev); ++ spi_master_put(spi->master); + kfree(dev); + } + +@@ -90,7 +90,7 @@ static int spi_suspend(struct device *de + int value; + struct spi_driver *drv = to_spi_driver(dev->driver); + +- if (!drv || !drv->suspend) ++ if (!drv->suspend) + return 0; + + /* suspend will stop irqs and dma; no more i/o */ +@@ -105,7 +105,7 @@ static int spi_resume(struct device *dev + int value; + struct spi_driver *drv = to_spi_driver(dev->driver); + +- if (!drv || !drv->resume) ++ if (!drv->resume) + return 0; + + /* resume may restart the i/o queue */ +@@ -198,7 +198,7 @@ spi_new_device(struct spi_master *master + + /* NOTE: caller did any chip->bus_num checks necessary */ + +- if (!class_device_get(&master->cdev)) ++ if (!spi_master_get(master)) + return NULL; + + proxy = kzalloc(sizeof *proxy, GFP_KERNEL); +@@ -244,7 +244,7 @@ spi_new_device(struct spi_master *master + return proxy; + + fail: +- class_device_put(&master->cdev); ++ spi_master_put(master); + kfree(proxy); + return NULL; + } +@@ -324,8 +324,6 @@ static void spi_master_release(struct cl + struct spi_master *master; + + master = container_of(cdev, struct spi_master, cdev); +- put_device(master->cdev.dev); +- master->cdev.dev = NULL; + kfree(master); + } + +@@ -339,8 +337,9 @@ static struct class spi_master_class = { + /** + * spi_alloc_master - allocate SPI master controller + * @dev: the controller, possibly using the platform_bus +- * @size: how much driver-private data to preallocate; a pointer to this +- * memory in the class_data field of the returned class_device ++ * @size: how much driver-private data to preallocate; the pointer to this ++ * memory is in the class_data field of the returned class_device, ++ * accessible with spi_master_get_devdata(). + * + * This call is used only by SPI master controller drivers, which are the + * only ones directly touching chip registers. It's how they allocate +@@ -350,14 +349,17 @@ static struct class spi_master_class = { + * master structure on success, else NULL. + * + * The caller is responsible for assigning the bus number and initializing +- * the master's methods before calling spi_add_master(), or else (on error) +- * calling class_device_put() to prevent a memory leak. ++ * the master's methods before calling spi_add_master(); and (after errors ++ * adding the device) calling spi_master_put() to prevent a memory leak. + */ + struct spi_master * __init_or_module + spi_alloc_master(struct device *dev, unsigned size) + { + struct spi_master *master; + ++ if (!dev) ++ return NULL; ++ + master = kzalloc(size + sizeof *master, SLAB_KERNEL); + if (!master) + return NULL; +@@ -365,7 +367,7 @@ spi_alloc_master(struct device *dev, uns + class_device_initialize(&master->cdev); + master->cdev.class = &spi_master_class; + master->cdev.dev = get_device(dev); +- class_set_devdata(&master->cdev, &master[1]); ++ spi_master_set_devdata(master, &master[1]); + + return master; + } +@@ -387,6 +389,8 @@ EXPORT_SYMBOL_GPL(spi_alloc_master); + * + * This must be called from context that can sleep. It returns zero on + * success, else a negative error code (dropping the master's refcount). ++ * After a successful return, the caller is responsible for calling ++ * spi_unregister_master(). + */ + int __init_or_module + spi_register_master(struct spi_master *master) +@@ -396,6 +400,9 @@ spi_register_master(struct spi_master *m + int status = -ENODEV; + int dynamic = 0; + ++ if (!dev) ++ return -ENODEV; ++ + /* convention: dynamically assigned bus IDs count down from the max */ + if (master->bus_num == 0) { + master->bus_num = atomic_dec_return(&dyn_bus_id); +@@ -425,7 +432,7 @@ EXPORT_SYMBOL_GPL(spi_register_master); + static int __unregister(struct device *dev, void *unused) + { + /* note: before about 2.6.14-rc1 this would corrupt memory: */ +- device_unregister(dev); ++ spi_unregister_device(to_spi_device(dev)); + return 0; + } + +@@ -440,8 +447,9 @@ static int __unregister(struct device *d + */ + void spi_unregister_master(struct spi_master *master) + { +- class_device_unregister(&master->cdev); + (void) device_for_each_child(master->cdev.dev, NULL, __unregister); ++ class_device_unregister(&master->cdev); ++ master->cdev.dev = NULL; + } + EXPORT_SYMBOL_GPL(spi_unregister_master); + +@@ -487,6 +495,9 @@ EXPORT_SYMBOL_GPL(spi_busnum_to_master); + * by leaving it selected in anticipation that the next message will go + * to the same chip. (That may increase power usage.) + * ++ * Also, the caller is guaranteeing that the memory associated with the ++ * message will not be freed before this call returns. ++ * + * The return value is a negative error code if the message could not be + * submitted, else zero. When the value is zero, then message->status is + * also defined: it's the completion code for the transfer, either zero +@@ -524,9 +535,9 @@ static u8 *buf; + * is zero for success, else a negative errno status code. + * This call may only be used from a context that may sleep. + * +- * Parameters to this routine are always copied using a small buffer, +- * large transfers should use use spi_{async,sync}() calls with +- * dma-safe buffers. ++ * Parameters to this routine are always copied using a small buffer; ++ * performance-sensitive or bulk transfer code should instead use ++ * spi_{async,sync}() calls with dma-safe buffers. + */ + int spi_write_then_read(struct spi_device *spi, + const u8 *txbuf, unsigned n_tx, +--- gregkh-2.6.orig/include/linux/spi/spi.h ++++ gregkh-2.6/include/linux/spi/spi.h +@@ -60,8 +60,8 @@ struct spi_device { + u8 mode; + #define SPI_CPHA 0x01 /* clock phase */ + #define SPI_CPOL 0x02 /* clock polarity */ +-#define SPI_MODE_0 (0|0) +-#define SPI_MODE_1 (0|SPI_CPHA) /* (original MicroWire) */ ++#define SPI_MODE_0 (0|0) /* (original MicroWire) */ ++#define SPI_MODE_1 (0|SPI_CPHA) + #define SPI_MODE_2 (SPI_CPOL|0) + #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) + #define SPI_CS_HIGH 0x04 /* chipselect active high? */ +@@ -209,6 +209,30 @@ struct spi_master { + void (*cleanup)(const struct spi_device *spi); + }; + ++static inline void *spi_master_get_devdata(struct spi_master *master) ++{ ++ return class_get_devdata(&master->cdev); ++} ++ ++static inline void spi_master_set_devdata(struct spi_master *master, void *data) ++{ ++ class_set_devdata(&master->cdev, data); ++} ++ ++static inline struct spi_master *spi_master_get(struct spi_master *master) ++{ ++ if (!master || !class_device_get(&master->cdev)) ++ return NULL; ++ return master; ++} ++ ++static inline void spi_master_put(struct spi_master *master) ++{ ++ if (master) ++ class_device_put(&master->cdev); ++} ++ ++ + /* the spi driver core manages memory for the spi_master classdev */ + extern struct spi_master * + spi_alloc_master(struct device *host, unsigned size); +@@ -271,11 +295,17 @@ extern struct spi_master *spi_busnum_to_ + * stay selected until the next transfer. This is purely a performance + * hint; the controller driver may need to select a different device + * for the next message. ++ * ++ * The code that submits an spi_message (and its spi_transfers) ++ * to the lower layers is responsible for managing its memory. ++ * Zero-initialize every field you don't set up explicitly, to ++ * insulate against future API updates. + */ + struct spi_transfer { + /* it's ok if tx_buf == rx_buf (right?) + * for MicroWire, one buffer must be null +- * buffers must work with dma_*map_single() calls ++ * buffers must work with dma_*map_single() calls, unless ++ * spi_message.is_dma_mapped reports a pre-existing mapping + */ + const void *tx_buf; + void *rx_buf; +@@ -302,6 +332,11 @@ struct spi_transfer { + * @status: zero for success, else negative errno + * @queue: for use by whichever driver currently owns the message + * @state: for use by whichever driver currently owns the message ++ * ++ * The code that submits an spi_message (and its spi_transfers) ++ * to the lower layers is responsible for managing its memory. ++ * Zero-initialize every field you don't set up explicitly, to ++ * insulate against future API updates. + */ + struct spi_message { + struct spi_transfer *transfers; +@@ -336,6 +371,29 @@ struct spi_message { + void *state; + }; + ++/* It's fine to embed message and transaction structures in other data ++ * structures so long as you don't free them while they're in use. ++ */ ++ ++static inline struct spi_message *spi_message_alloc(unsigned ntrans, gfp_t flags) ++{ ++ struct spi_message *m; ++ ++ m = kzalloc(sizeof(struct spi_message) ++ + ntrans * sizeof(struct spi_transfer), ++ flags); ++ if (m) { ++ m->transfers = (void *)(m + 1); ++ m->n_transfer = ntrans; ++ } ++ return m; ++} ++ ++static inline void spi_message_free(struct spi_message *m) ++{ ++ kfree(m); ++} ++ + /** + * spi_setup -- setup SPI mode and clock rate + * @spi: the device whose settings are being modified +@@ -363,7 +421,10 @@ spi_setup(struct spi_device *spi) + * The completion callback is invoked in a context which can't sleep. + * Before that invocation, the value of message->status is undefined. + * When the callback is issued, message->status holds either zero (to +- * indicate complete success) or a negative error code. ++ * indicate complete success) or a negative error code. After that ++ * callback returns, the driver which issued the transfer request may ++ * deallocate the associated memory; it's no longer in use by any SPI ++ * core or controller driver code. + * + * Note that although all messages to a spi_device are handled in + * FIFO order, messages may go to different devices in other orders. +@@ -445,6 +506,7 @@ spi_read(struct spi_device *spi, u8 *buf + return spi_sync(spi, &m); + } + ++/* this copies txbuf and rxbuf data; for small transfers only! */ + extern int spi_write_then_read(struct spi_device *spi, + const u8 *txbuf, unsigned n_tx, + u8 *rxbuf, unsigned n_rx); +@@ -555,8 +617,9 @@ spi_register_board_info(struct spi_board + + + /* If you're hotplugging an adapter with devices (parport, usb, etc) +- * use spi_new_device() to describe each device. You would then call +- * spi_unregister_device() to start making that device vanish. ++ * use spi_new_device() to describe each device. You can also call ++ * spi_unregister_device() to start making that device vanish, but ++ * normally that would be handled by spi_unregister_master(). + */ + extern struct spi_device * + spi_new_device(struct spi_master *, struct spi_board_info *); diff --git a/driver/spi-m25-series-spi-flash.patch b/driver/spi-m25-series-spi-flash.patch new file mode 100644 index 0000000000000..5f5d0bc0da9a9 --- /dev/null +++ b/driver/spi-m25-series-spi-flash.patch @@ -0,0 +1,657 @@ +From akpm@osdl.org Sun Jan 8 13:38:43 2006 +From: akpm@osdl.org +Message-Id: <200601082134.k08LYd2q004582@shell0.pdx.osdl.net> +Subject: [patch 08/10] spi: M25 series SPI flash +To: greg@kroah.com +Cc: akpm@osdl.org, mike@steroidmicros.com, dbrownell@users.sourceforge.net +Date: Sun, 08 Jan 2006 13:34:27 -0800 + + +From: Mike Lavender <mike@steroidmicros.com> + +This was originally a driver for the ST M25P80 SPI flash. It's been +updated slightly to handle other M25P series chips. + +For many of these chips, the specific type could be probed, but for now +this just requires static setup with flash_platform_data that lists the +chip type (size, format) and any default partitioning to use. + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Cc: Mike Lavender <mike@steroidmicros.com> +Cc: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + drivers/mtd/devices/Kconfig | 8 + drivers/mtd/devices/Makefile | 1 + drivers/mtd/devices/m25p80.c | 580 +++++++++++++++++++++++++++++++++++++++++++ + include/linux/spi/flash.h | 4 + 4 files changed, 593 insertions(+) + +--- gregkh-2.6.orig/drivers/mtd/devices/Kconfig ++++ gregkh-2.6/drivers/mtd/devices/Kconfig +@@ -55,6 +55,14 @@ config MTD_DATAFLASH + Sometimes DataFlash chips are packaged inside MMC-format + cards; at this writing, the MMC stack won't handle those. + ++config MTD_M25P80 ++ tristate "Support for M25 SPI Flash" ++ depends on MTD && SPI_MASTER && EXPERIMENTAL ++ help ++ This enables access to ST M25P80 and similar SPI flash chips, ++ used for program and data storage. Set up your spi devices ++ with the right board-specific platform data. ++ + config MTD_SLRAM + tristate "Uncached system RAM" + depends on MTD +--- /dev/null ++++ gregkh-2.6/drivers/mtd/devices/m25p80.c +@@ -0,0 +1,580 @@ ++/* ++ * MTD SPI driver for ST M25Pxx flash chips ++ * ++ * Author: Mike Lavender, mike@steroidmicros.com ++ * ++ * Copyright (c) 2005, Intec Automation Inc. ++ * ++ * Some parts are based on lart.c by Abraham Van Der Merwe ++ * ++ * Cleaned up and generalized based on mtd_dataflash.c ++ * ++ * This code 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/init.h> ++#include <linux/module.h> ++#include <linux/device.h> ++#include <linux/interrupt.h> ++#include <linux/interrupt.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/partitions.h> ++#include <linux/spi/spi.h> ++#include <linux/spi/flash.h> ++ ++#include <asm/semaphore.h> ++ ++ ++/* NOTE: AT 25F and SST 25LF series are very similar, ++ * but commands for sector erase and chip id differ... ++ */ ++ ++#define FLASH_PAGESIZE 256 ++ ++/* Flash opcodes. */ ++#define OPCODE_WREN 6 /* Write enable */ ++#define OPCODE_RDSR 5 /* Read status register */ ++#define OPCODE_READ 3 /* Read data bytes */ ++#define OPCODE_PP 2 /* Page program */ ++#define OPCODE_SE 0xd8 /* Sector erase */ ++#define OPCODE_RES 0xab /* Read Electronic Signature */ ++#define OPCODE_RDID 0x9f /* Read JEDEC ID */ ++ ++/* Status Register bits. */ ++#define SR_WIP 1 /* Write in progress */ ++#define SR_WEL 2 /* Write enable latch */ ++#define SR_BP0 4 /* Block protect 0 */ ++#define SR_BP1 8 /* Block protect 1 */ ++#define SR_BP2 0x10 /* Block protect 2 */ ++#define SR_SRWD 0x80 /* SR write protect */ ++ ++/* Define max times to check status register before we give up. */ ++#define MAX_READY_WAIT_COUNT 100000 ++ ++ ++#ifdef CONFIG_MTD_PARTITIONS ++#define mtd_has_partitions() (1) ++#else ++#define mtd_has_partitions() (0) ++#endif ++ ++/****************************************************************************/ ++ ++struct m25p { ++ struct spi_device *spi; ++ struct semaphore lock; ++ struct mtd_info mtd; ++ unsigned partitioned; ++ u8 command[4]; ++}; ++ ++static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) ++{ ++ return container_of(mtd, struct m25p, mtd); ++} ++ ++/****************************************************************************/ ++ ++/* ++ * Internal helper functions ++ */ ++ ++/* ++ * Read the status register, returning its value in the location ++ * Return the status register value. ++ * Returns negative if error occurred. ++ */ ++static int read_sr(struct m25p *flash) ++{ ++ ssize_t retval; ++ u8 code = OPCODE_RDSR; ++ u8 val; ++ ++ retval = spi_write_then_read(flash->spi, &code, 1, &val, 1); ++ ++ if (retval < 0) { ++ dev_err(&flash->spi->dev, "error %d reading SR\n", ++ (int) retval); ++ return retval; ++ } ++ ++ return val; ++} ++ ++ ++/* ++ * Set write enable latch with Write Enable command. ++ * Returns negative if error occurred. ++ */ ++static inline int write_enable(struct m25p *flash) ++{ ++ u8 code = OPCODE_WREN; ++ ++ return spi_write_then_read(flash->spi, &code, 1, NULL, 0); ++} ++ ++ ++/* ++ * Service routine to read status register until ready, or timeout occurs. ++ * Returns non-zero if error. ++ */ ++static int wait_till_ready(struct m25p *flash) ++{ ++ int count; ++ int sr; ++ ++ /* one chip guarantees max 5 msec wait here after page writes, ++ * but potentially three seconds (!) after page erase. ++ */ ++ for (count = 0; count < MAX_READY_WAIT_COUNT; count++) { ++ if ((sr = read_sr(flash)) < 0) ++ break; ++ else if (!(sr & SR_WIP)) ++ return 0; ++ ++ /* REVISIT sometimes sleeping would be best */ ++ } ++ ++ return 1; ++} ++ ++ ++/* ++ * Erase one sector of flash memory at offset ``offset'' which is any ++ * address within the sector which should be erased. ++ * ++ * Returns 0 if successful, non-zero otherwise. ++ */ ++static int erase_sector(struct m25p *flash, u32 offset) ++{ ++ DEBUG(MTD_DEBUG_LEVEL3, "%s: %s at 0x%08x\n", flash->spi->dev.bus_id, ++ __FUNCTION__, offset); ++ ++ /* Wait until finished previous write command. */ ++ if (wait_till_ready(flash)) ++ return 1; ++ ++ /* Send write enable, then erase commands. */ ++ write_enable(flash); ++ ++ /* Set up command buffer. */ ++ flash->command[0] = OPCODE_SE; ++ flash->command[1] = offset >> 16; ++ flash->command[2] = offset >> 8; ++ flash->command[3] = offset; ++ ++ spi_write(flash->spi, flash->command, sizeof(flash->command)); ++ ++ return 0; ++} ++ ++/****************************************************************************/ ++ ++/* ++ * MTD implementation ++ */ ++ ++/* ++ * Erase an address range on the flash chip. The address range may extend ++ * one or more erase sectors. Return an error is there is a problem erasing. ++ */ ++static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ struct m25p *flash = mtd_to_m25p(mtd); ++ u32 addr,len; ++ ++ DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", ++ flash->spi->dev.bus_id, __FUNCTION__, "at", ++ (u32)instr->addr, instr->len); ++ ++ /* sanity checks */ ++ if (instr->addr + instr->len > flash->mtd.size) ++ return -EINVAL; ++ if ((instr->addr % mtd->erasesize) != 0 ++ || (instr->len % mtd->erasesize) != 0) { ++ return -EINVAL; ++ } ++ ++ addr = instr->addr; ++ len = instr->len; ++ ++ down(&flash->lock); ++ ++ /* now erase those sectors */ ++ while (len) { ++ if (erase_sector(flash, addr)) { ++ instr->state = MTD_ERASE_FAILED; ++ up(&flash->lock); ++ return -EIO; ++ } ++ ++ addr += mtd->erasesize; ++ len -= mtd->erasesize; ++ } ++ ++ up(&flash->lock); ++ ++ instr->state = MTD_ERASE_DONE; ++ mtd_erase_callback(instr); ++ ++ return 0; ++} ++ ++/* ++ * Read an address range from the flash chip. The address range ++ * may be any size provided it is within the physical boundaries. ++ */ ++static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ struct m25p *flash = mtd_to_m25p(mtd); ++ struct spi_transfer t[2]; ++ struct spi_message m; ++ ++ DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", ++ flash->spi->dev.bus_id, __FUNCTION__, "from", ++ (u32)from, len); ++ ++ /* sanity checks */ ++ if (!len) ++ return 0; ++ ++ if (from + len > flash->mtd.size) ++ return -EINVAL; ++ ++ down(&flash->lock); ++ ++ /* Wait till previous write/erase is done. */ ++ if (wait_till_ready(flash)) { ++ /* REVISIT status return?? */ ++ up(&flash->lock); ++ return 1; ++ } ++ ++ memset(t, 0, (sizeof t)); ++ ++ /* NOTE: OPCODE_FAST_READ (if available) is faster... */ ++ ++ /* Set up the write data buffer. */ ++ flash->command[0] = OPCODE_READ; ++ flash->command[1] = from >> 16; ++ flash->command[2] = from >> 8; ++ flash->command[3] = from; ++ ++ /* Byte count starts at zero. */ ++ if (retlen) ++ *retlen = 0; ++ ++ t[0].tx_buf = flash->command; ++ t[0].len = sizeof(flash->command); ++ ++ t[1].rx_buf = buf; ++ t[1].len = len; ++ ++ m.transfers = t; ++ m.n_transfer = 2; ++ ++ spi_sync(flash->spi, &m); ++ ++ *retlen = m.actual_length - sizeof(flash->command); ++ ++ up(&flash->lock); ++ ++ return 0; ++} ++ ++/* ++ * Write an address range to the flash chip. Data must be written in ++ * FLASH_PAGESIZE chunks. The address range may be any size provided ++ * it is within the physical boundaries. ++ */ ++static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ struct m25p *flash = mtd_to_m25p(mtd); ++ u32 page_offset, page_size; ++ struct spi_transfer t[2]; ++ struct spi_message m; ++ ++ DEBUG(MTD_DEBUG_LEVEL2, "%s: %s %s 0x%08x, len %zd\n", ++ flash->spi->dev.bus_id, __FUNCTION__, "to", ++ (u32)to, len); ++ ++ if (retlen) ++ *retlen = 0; ++ ++ /* sanity checks */ ++ if (!len) ++ return(0); ++ ++ if (to + len > flash->mtd.size) ++ return -EINVAL; ++ ++ down(&flash->lock); ++ ++ /* Wait until finished previous write command. */ ++ if (wait_till_ready(flash)) ++ return 1; ++ ++ write_enable(flash); ++ ++ memset(t, 0, (sizeof t)); ++ ++ /* Set up the opcode in the write buffer. */ ++ flash->command[0] = OPCODE_PP; ++ flash->command[1] = to >> 16; ++ flash->command[2] = to >> 8; ++ flash->command[3] = to; ++ ++ t[0].tx_buf = flash->command; ++ t[0].len = sizeof(flash->command); ++ ++ m.transfers = t; ++ m.n_transfer = 2; ++ ++ /* what page do we start with? */ ++ page_offset = to % FLASH_PAGESIZE; ++ ++ /* do all the bytes fit onto one page? */ ++ if (page_offset + len <= FLASH_PAGESIZE) { ++ t[1].tx_buf = buf; ++ t[1].len = len; ++ ++ spi_sync(flash->spi, &m); ++ ++ *retlen = m.actual_length - sizeof(flash->command); ++ } else { ++ u32 i; ++ ++ /* the size of data remaining on the first page */ ++ page_size = FLASH_PAGESIZE - page_offset; ++ ++ t[1].tx_buf = buf; ++ t[1].len = page_size; ++ spi_sync(flash->spi, &m); ++ ++ *retlen = m.actual_length - sizeof(flash->command); ++ ++ /* write everything in PAGESIZE chunks */ ++ for (i = page_size; i < len; i += page_size) { ++ page_size = len - i; ++ if (page_size > FLASH_PAGESIZE) ++ page_size = FLASH_PAGESIZE; ++ ++ /* write the next page to flash */ ++ flash->command[1] = (to + i) >> 16; ++ flash->command[2] = (to + i) >> 8; ++ flash->command[3] = (to + i); ++ ++ t[1].tx_buf = buf + i; ++ t[1].len = page_size; ++ ++ wait_till_ready(flash); ++ ++ write_enable(flash); ++ ++ spi_sync(flash->spi, &m); ++ ++ *retlen += m.actual_length - sizeof(flash->command); ++ } ++ } ++ ++ up(&flash->lock); ++ ++ return 0; ++} ++ ++ ++/****************************************************************************/ ++ ++/* ++ * SPI device driver setup and teardown ++ */ ++ ++struct flash_info { ++ char *name; ++ u8 id; ++ u16 jedec_id; ++ unsigned sector_size; ++ unsigned n_sectors; ++}; ++ ++static struct flash_info __devinitdata m25p_data [] = { ++ /* REVISIT: fill in JEDEC ids, for parts that have them */ ++ { "m25p05", 0x05, 0x0000, 32 * 1024, 2 }, ++ { "m25p10", 0x10, 0x0000, 32 * 1024, 4 }, ++ { "m25p20", 0x11, 0x0000, 64 * 1024, 4 }, ++ { "m25p40", 0x12, 0x0000, 64 * 1024, 8 }, ++ { "m25p80", 0x13, 0x0000, 64 * 1024, 16 }, ++ { "m25p16", 0x14, 0x0000, 64 * 1024, 32 }, ++ { "m25p32", 0x15, 0x0000, 64 * 1024, 64 }, ++ { "m25p64", 0x16, 0x2017, 64 * 1024, 128 }, ++}; ++ ++/* ++ * board specific setup should have ensured the SPI clock used here ++ * matches what the READ command supports, at least until this driver ++ * understands FAST_READ (for clocks over 25 MHz). ++ */ ++static int __devinit m25p_probe(struct spi_device *spi) ++{ ++ struct flash_platform_data *data; ++ struct m25p *flash; ++ struct flash_info *info; ++ unsigned i; ++ ++ /* Platform data helps sort out which chip type we have, as ++ * well as how this board partitions it. ++ */ ++ data = spi->dev.platform_data; ++ if (!data || !data->type) { ++ /* FIXME some chips can identify themselves with RES ++ * or JEDEC get-id commands. Try them ... ++ */ ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: no chip id\n", ++ flash->spi->dev.bus_id); ++ return -ENODEV; ++ } ++ ++ for (i = 0, info = m25p_data; i < ARRAY_SIZE(m25p_data); i++, info++) { ++ if (strcmp(data->type, info->name) == 0) ++ break; ++ } ++ if (i == ARRAY_SIZE(m25p_data)) { ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: unrecognized id %s\n", ++ flash->spi->dev.bus_id, data->type); ++ return -ENODEV; ++ } ++ ++ flash = kzalloc(sizeof *flash, SLAB_KERNEL); ++ if (!flash) ++ return -ENOMEM; ++ ++ flash->spi = spi; ++ init_MUTEX(&flash->lock); ++ dev_set_drvdata(&spi->dev, flash); ++ ++ if (data->name) ++ flash->mtd.name = data->name; ++ else ++ flash->mtd.name = spi->dev.bus_id; ++ ++ flash->mtd.type = MTD_NORFLASH; ++ flash->mtd.flags = MTD_CAP_NORFLASH; ++ flash->mtd.size = info->sector_size * info->n_sectors; ++ flash->mtd.erasesize = info->sector_size; ++ flash->mtd.erase = m25p80_erase; ++ flash->mtd.read = m25p80_read; ++ flash->mtd.write = m25p80_write; ++ ++ dev_info(&spi->dev, "%s (%d Kbytes)\n", info->name, ++ flash->mtd.size / 1024); ++ ++ DEBUG(MTD_DEBUG_LEVEL2, ++ "mtd .name = %s, .size = 0x%.8x (%uM) " ++ ".erasesize = 0x%.8x (%uK) .numeraseregions = %d\n", ++ flash->mtd.name, ++ flash->mtd.size, flash->mtd.size / (1024*1024), ++ flash->mtd.erasesize, flash->mtd.erasesize / 1024, ++ flash->mtd.numeraseregions); ++ ++ if (flash->mtd.numeraseregions) ++ for (i = 0; i < flash->mtd.numeraseregions; i++) ++ DEBUG(MTD_DEBUG_LEVEL2, ++ "mtd.eraseregions[%d] = { .offset = 0x%.8x, " ++ ".erasesize = 0x%.8x (%uK), " ++ ".numblocks = %d }\n", ++ i, flash->mtd.eraseregions[i].offset, ++ flash->mtd.eraseregions[i].erasesize, ++ flash->mtd.eraseregions[i].erasesize / 1024, ++ flash->mtd.eraseregions[i].numblocks); ++ ++ ++ /* partitions should match sector boundaries; and it may be good to ++ * use readonly partitions for writeprotected sectors (BP2..BP0). ++ */ ++ if (mtd_has_partitions()) { ++ struct mtd_partition *parts = NULL; ++ int nr_parts = 0; ++ ++#ifdef CONFIG_MTD_CMDLINE_PARTS ++ static const char *part_probes[] = { "cmdlinepart", NULL, }; ++ ++ nr_parts = parse_mtd_partitions(&flash->mtd, ++ part_probes, &parts, 0); ++#endif ++ ++ if (nr_parts <= 0 && data && data->parts) { ++ parts = data->parts; ++ nr_parts = data->nr_parts; ++ } ++ ++ if (nr_parts > 0) { ++ for (i = 0; i < data->nr_parts; i++) { ++ DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = " ++ "{.name = %s, .offset = 0x%.8x, " ++ ".size = 0x%.8x (%uK) }\n", ++ i, data->parts[i].name, ++ data->parts[i].offset, ++ data->parts[i].size, ++ data->parts[i].size / 1024); ++ } ++ flash->partitioned = 1; ++ return add_mtd_partitions(&flash->mtd, parts, nr_parts); ++ } ++ } else if (data->nr_parts) ++ dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", ++ data->nr_parts, data->name); ++ ++ return add_mtd_device(&flash->mtd) == 1 ? -ENODEV : 0; ++} ++ ++ ++static int __devexit m25p_remove(struct spi_device *spi) ++{ ++ struct m25p *flash = dev_get_drvdata(&spi->dev); ++ int status; ++ ++ /* Clean up MTD stuff. */ ++ if (mtd_has_partitions() && flash->partitioned) ++ status = del_mtd_partitions(&flash->mtd); ++ else ++ status = del_mtd_device(&flash->mtd); ++ if (status == 0) ++ kfree(flash); ++ return 0; ++} ++ ++ ++static struct spi_driver m25p80_driver = { ++ .driver = { ++ .name = "m25p80", ++ .bus = &spi_bus_type, ++ .owner = THIS_MODULE, ++ }, ++ .probe = m25p_probe, ++ .remove = __devexit_p(m25p_remove), ++}; ++ ++ ++static int m25p80_init(void) ++{ ++ return spi_register_driver(&m25p80_driver); ++} ++ ++ ++static void m25p80_exit(void) ++{ ++ spi_unregister_driver(&m25p80_driver); ++} ++ ++ ++module_init(m25p80_init); ++module_exit(m25p80_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Mike Lavender"); ++MODULE_DESCRIPTION("MTD SPI driver for ST M25Pxx flash chips"); +--- gregkh-2.6.orig/drivers/mtd/devices/Makefile ++++ gregkh-2.6/drivers/mtd/devices/Makefile +@@ -24,3 +24,4 @@ obj-$(CONFIG_MTD_LART) += lart.o + obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o + obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o + obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o ++obj-$(CONFIG_MTD_M25P80) += m25p80.o +--- gregkh-2.6.orig/include/linux/spi/flash.h ++++ gregkh-2.6/include/linux/spi/flash.h +@@ -8,6 +8,8 @@ struct mtd_partition; + * @name: optional flash device name (eg, as used with mtdparts=) + * @parts: optional array of mtd_partitions for static partitioning + * @nr_parts: number of mtd_partitions for static partitoning ++ * @type: optional flash device type (e.g. m25p80 vs m25p64), for use ++ * with chips that can't be queried for JEDEC or other IDs + * + * Board init code (in arch/.../mach-xxx/board-yyy.c files) can + * provide information about SPI flash parts (such as DataFlash) to +@@ -21,6 +23,8 @@ struct flash_platform_data { + struct mtd_partition *parts; + unsigned int nr_parts; + ++ char *type; ++ + /* we'll likely add more ... use JEDEC IDs, etc */ + }; + diff --git a/driver/spi-misc-fixes.patch b/driver/spi-misc-fixes.patch new file mode 100644 index 0000000000000..f6abb373da270 --- /dev/null +++ b/driver/spi-misc-fixes.patch @@ -0,0 +1,118 @@ +From akpm@osdl.org Sun Jan 8 13:39:13 2006 +From: akpm@osdl.org +Message-Id: <200601082134.k08LYfjI004588@shell0.pdx.osdl.net> +Subject: [patch 10/10] spi: misc fixes +To: greg@kroah.com +Cc: akpm@osdl.org, david-b@pacbell.net, dbrownell@users.sourceforge.net +Date: Sun, 08 Jan 2006 13:34:29 -0800 + + +From: David Brownell <david-b@pacbell.net> + +This collects some small SPI patches that seem to be missing from the MM tree: + + - spi_butterfly kbuild hooks got dropped somehow; this restores them + - quick fix for a (theoretical?) m25p80_write() oops noted by Andrew + - quick fix for a potential config-specific oops for mtd_dataflash() + - minor doc tweaks + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + Documentation/spi/spi-summary | 13 +++++++++++++ + drivers/mtd/devices/m25p80.c | 4 +++- + drivers/mtd/devices/mtd_dataflash.c | 2 +- + drivers/spi/Kconfig | 10 ++++++++++ + drivers/spi/Makefile | 1 + + 5 files changed, 28 insertions(+), 2 deletions(-) + +--- gregkh-2.6.orig/Documentation/spi/spi-summary ++++ gregkh-2.6/Documentation/spi/spi-summary +@@ -115,6 +115,9 @@ shows up in sysfs in several locations: + /sys/devices/.../CTLR/spiB.C ... spi_device for on bus "B", + chipselect C, accessed through CTLR. + ++ /sys/devices/.../CTLR/spiB.C/modalias ... identifies the driver ++ that should be used with this device (for hotplug/coldplug) ++ + /sys/bus/spi/devices/spiB.C ... symlink to the physical + spiB-C device + +@@ -247,6 +250,12 @@ driver is registered: + + Like with other static board-specific setup, you won't unregister those. + ++The widely used "card" style computers bundle memory, cpu, and little else ++onto a card that's maybe just thirty square centimeters. On such systems, ++your arch/.../mach-.../board-*.c file would primarily provide information ++about the devices on the mainboard into which such a card is plugged. That ++certainly includes SPI devices hooked up through the card connectors! ++ + + NON-STATIC CONFIGURATIONS + +@@ -258,6 +267,10 @@ up the spi bus master, and will likely n + board info based on the board that was hotplugged. Of course, you'd later + call at least spi_unregister_device() when that board is removed. + ++When Linux includes support for MMC/SD/SDIO/DataFlash cards through SPI, those ++configurations will also be dynamic. Fortunately, those devices all support ++basic device identification probes, so that support should hotplug normally. ++ + + How do I write an "SPI Protocol Driver"? + ---------------------------------------- +--- gregkh-2.6.orig/drivers/mtd/devices/m25p80.c ++++ gregkh-2.6/drivers/mtd/devices/m25p80.c +@@ -378,7 +378,9 @@ static int m25p80_write(struct mtd_info + + spi_sync(flash->spi, &m); + +- *retlen += m.actual_length - sizeof(flash->command); ++ if (retlen) ++ *retlen += m.actual_length ++ - sizeof(flash->command); + } + } + +--- gregkh-2.6.orig/drivers/mtd/devices/mtd_dataflash.c ++++ gregkh-2.6/drivers/mtd/devices/mtd_dataflash.c +@@ -508,7 +508,7 @@ add_dataflash(struct spi_device *spi, ch + priv->partitioned = 1; + return add_mtd_partitions(device, parts, nr_parts); + } +- } else if (pdata->nr_parts) ++ } else if (pdata && pdata->nr_parts) + dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", + pdata->nr_parts, device->name); + +--- gregkh-2.6.orig/drivers/spi/Kconfig ++++ gregkh-2.6/drivers/spi/Kconfig +@@ -80,6 +80,16 @@ config SPI_BITBANG + need it. You only need to select this explicitly to support driver + modules that aren't part of this kernel tree. + ++config SPI_BUTTERFLY ++ tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" ++ depends on SPI_MASTER && PARPORT && EXPERIMENTAL ++ select SPI_BITBANG ++ help ++ This uses a custom parallel port cable to connect to an AVR ++ Butterfly <http://www.atmel.com/products/avr/butterfly>, an ++ inexpensive battery powered microcontroller evaluation board. ++ This same cable can be used to flash new firmware. ++ + # + # Add new SPI master controllers in alphabetical order above this line + # +--- gregkh-2.6.orig/drivers/spi/Makefile ++++ gregkh-2.6/drivers/spi/Makefile +@@ -12,6 +12,7 @@ obj-$(CONFIG_SPI_MASTER) += spi.o + + # SPI master controller drivers (bus) + obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o ++obj-$(CONFIG_SPI_BUTTERFLY) += spi_butterfly.o + # ... add above this line ... + + # SPI protocol drivers (device/link on bus) diff --git a/driver/spi-mtd-dataflash-driver.patch b/driver/spi-mtd-dataflash-driver.patch new file mode 100644 index 0000000000000..657bbdd2ecf9f --- /dev/null +++ b/driver/spi-mtd-dataflash-driver.patch @@ -0,0 +1,712 @@ +From akpm@osdl.org Sun Jan 8 13:38:50 2006 +From: akpm@osdl.org +Message-Id: <200601082134.k08LYX02004567@shell0.pdx.osdl.net> +Subject: [patch 03/10] spi: mtd dataflash driver +To: greg@kroah.com +Cc: akpm@osdl.org, david-b@pacbell.net, dbrownell@users.sourceforge.net +Date: Sun, 08 Jan 2006 13:34:22 -0800 + + +From: David Brownell <david-b@pacbell.net> + +This is a conversion of the AT91rm9200 DataFlash MTD driver to use the +lightweight SPI framework, and no longer be AT91-specific. It compiles +down to less than 3KBytes on ARM. + +The driver allows board-specific init code to provide platform_data with +the relevant MTD partitioning information, and hotplugs. + +This version has been lightly tested. Its parent at91_dataflash driver has +been pretty well banged on, although kernel.org JFFS2 dataflash support was +acting broken the last time I tried it. + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + drivers/mtd/devices/Kconfig | 8 + drivers/mtd/devices/Makefile | 1 + drivers/mtd/devices/mtd_dataflash.c | 623 ++++++++++++++++++++++++++++++++++++ + include/linux/spi/flash.h | 27 + + 4 files changed, 659 insertions(+) + +--- gregkh-2.6.orig/drivers/mtd/devices/Kconfig ++++ gregkh-2.6/drivers/mtd/devices/Kconfig +@@ -47,6 +47,14 @@ config MTD_MS02NV + accelerator. Say Y here if you have a DECstation 5000/2x0 or a + DECsystem 5900 equipped with such a module. + ++config MTD_DATAFLASH ++ tristate "Support for AT45xxx DataFlash" ++ depends on MTD && SPI_MASTER && EXPERIMENTAL ++ help ++ This enables access to AT45xxx DataFlash chips, using SPI. ++ Sometimes DataFlash chips are packaged inside MMC-format ++ cards; at this writing, the MMC stack won't handle those. ++ + config MTD_SLRAM + tristate "Uncached system RAM" + depends on MTD +--- gregkh-2.6.orig/drivers/mtd/devices/Makefile ++++ gregkh-2.6/drivers/mtd/devices/Makefile +@@ -23,3 +23,4 @@ obj-$(CONFIG_MTD_MTDRAM) += mtdram.o + obj-$(CONFIG_MTD_LART) += lart.o + obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o + obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o ++obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o +--- /dev/null ++++ gregkh-2.6/drivers/mtd/devices/mtd_dataflash.c +@@ -0,0 +1,623 @@ ++/* ++ * Atmel AT45xxx DataFlash MTD driver for lightweight SPI framework ++ * ++ * Largely derived from at91_dataflash.c: ++ * Copyright (C) 2003-2005 SAN People (Pty) Ltd ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++*/ ++#include <linux/config.h> ++#include <linux/module.h> ++#include <linux/init.h> ++#include <linux/slab.h> ++#include <linux/delay.h> ++#include <linux/device.h> ++#include <linux/spi/spi.h> ++#include <linux/spi/flash.h> ++ ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/partitions.h> ++ ++ ++/* ++ * DataFlash is a kind of SPI flash. Most AT45 chips have two buffers in ++ * each chip, which may be used for double buffered I/O; but this driver ++ * doesn't (yet) use these for any kind of i/o overlap or prefetching. ++ * ++ * Sometimes DataFlash is packaged in MMC-format cards, although the ++ * MMC stack can't use SPI (yet), or distinguish between MMC and DataFlash ++ * protocols during enumeration. ++ */ ++ ++#define CONFIG_DATAFLASH_WRITE_VERIFY ++ ++/* reads can bypass the buffers */ ++#define OP_READ_CONTINUOUS 0xE8 ++#define OP_READ_PAGE 0xD2 ++ ++/* group B requests can run even while status reports "busy" */ ++#define OP_READ_STATUS 0xD7 /* group B */ ++ ++/* move data between host and buffer */ ++#define OP_READ_BUFFER1 0xD4 /* group B */ ++#define OP_READ_BUFFER2 0xD6 /* group B */ ++#define OP_WRITE_BUFFER1 0x84 /* group B */ ++#define OP_WRITE_BUFFER2 0x87 /* group B */ ++ ++/* erasing flash */ ++#define OP_ERASE_PAGE 0x81 ++#define OP_ERASE_BLOCK 0x50 ++ ++/* move data between buffer and flash */ ++#define OP_TRANSFER_BUF1 0x53 ++#define OP_TRANSFER_BUF2 0x55 ++#define OP_MREAD_BUFFER1 0xD4 ++#define OP_MREAD_BUFFER2 0xD6 ++#define OP_MWERASE_BUFFER1 0x83 ++#define OP_MWERASE_BUFFER2 0x86 ++#define OP_MWRITE_BUFFER1 0x88 /* sector must be pre-erased */ ++#define OP_MWRITE_BUFFER2 0x89 /* sector must be pre-erased */ ++ ++/* write to buffer, then write-erase to flash */ ++#define OP_PROGRAM_VIA_BUF1 0x82 ++#define OP_PROGRAM_VIA_BUF2 0x85 ++ ++/* compare buffer to flash */ ++#define OP_COMPARE_BUF1 0x60 ++#define OP_COMPARE_BUF2 0x61 ++ ++/* read flash to buffer, then write-erase to flash */ ++#define OP_REWRITE_VIA_BUF1 0x58 ++#define OP_REWRITE_VIA_BUF2 0x59 ++ ++/* newer chips report JEDEC manufacturer and device IDs; chip ++ * serial number and OTP bits; and per-sector writeprotect. ++ */ ++#define OP_READ_ID 0x9F ++#define OP_READ_SECURITY 0x77 ++#define OP_WRITE_SECURITY 0x9A /* OTP bits */ ++ ++ ++struct dataflash { ++ u8 command[4]; ++ char name[24]; ++ ++ unsigned partitioned:1; ++ ++ unsigned short page_offset; /* offset in flash address */ ++ unsigned int page_size; /* of bytes per page */ ++ ++ struct semaphore lock; ++ struct spi_device *spi; ++ ++ struct mtd_info mtd; ++}; ++ ++#ifdef CONFIG_MTD_PARTITIONS ++#define mtd_has_partitions() (1) ++#else ++#define mtd_has_partitions() (0) ++#endif ++ ++/* ......................................................................... */ ++ ++/* ++ * Return the status of the DataFlash device. ++ */ ++static inline int dataflash_status(struct spi_device *spi) ++{ ++ /* NOTE: at45db321c over 25 MHz wants to write ++ * a dummy byte after the opcode... ++ */ ++ return spi_w8r8(spi, OP_READ_STATUS); ++} ++ ++/* ++ * Poll the DataFlash device until it is READY. ++ * This usually takes 5-20 msec or so; more for sector erase. ++ */ ++static int dataflash_waitready(struct spi_device *spi) ++{ ++ int status; ++ ++ for (;;) { ++ status = dataflash_status(spi); ++ if (status < 0) { ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: status %d?\n", ++ spi->dev.bus_id, status); ++ status = 0; ++ } ++ ++ if (status & (1 << 7)) /* RDY/nBSY */ ++ return status; ++ ++ msleep(3); ++ } ++} ++ ++/* ......................................................................... */ ++ ++/* ++ * Erase pages of flash. ++ */ ++static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ struct dataflash *priv = (struct dataflash *)mtd->priv; ++ struct spi_device *spi = priv->spi; ++ struct spi_transfer x[1] = { { .tx_dma = 0, }, }; ++ struct spi_message msg; ++ unsigned blocksize = priv->page_size << 3; ++ u8 *command; ++ ++ DEBUG(MTD_DEBUG_LEVEL2, "%s: erase addr=0x%x len 0x%x\n", ++ spi->dev.bus_id, ++ instr->addr, instr->len); ++ ++ /* Sanity checks */ ++ if ((instr->addr + instr->len) > mtd->size ++ || (instr->len % priv->page_size) != 0 ++ || (instr->addr % priv->page_size) != 0) ++ return -EINVAL; ++ ++ x[0].tx_buf = command = priv->command; ++ x[0].len = 4; ++ msg.transfers = x; ++ msg.n_transfer = 1; ++ ++ down(&priv->lock); ++ while (instr->len > 0) { ++ unsigned int pageaddr; ++ int status; ++ int do_block; ++ ++ /* Calculate flash page address; use block erase (for speed) if ++ * we're at a block boundary and need to erase the whole block. ++ */ ++ pageaddr = instr->addr / priv->page_size; ++ do_block = (pageaddr & 0x7) == 0 && instr->len <= blocksize; ++ pageaddr = pageaddr << priv->page_offset; ++ ++ command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE; ++ command[1] = (u8)(pageaddr >> 16); ++ command[2] = (u8)(pageaddr >> 8); ++ command[3] = 0; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "ERASE %s: (%x) %x %x %x [%i]\n", ++ do_block ? "block" : "page", ++ command[0], command[1], command[2], command[3], ++ pageaddr); ++ ++ status = spi_sync(spi, &msg); ++ (void) dataflash_waitready(spi); ++ ++ if (status < 0) { ++ printk(KERN_ERR "%s: erase %x, err %d\n", ++ spi->dev.bus_id, pageaddr, status); ++ /* REVISIT: can retry instr->retries times; or ++ * giveup and instr->fail_addr = instr->addr; ++ */ ++ continue; ++ } ++ ++ if (do_block) { ++ instr->addr += blocksize; ++ instr->len -= blocksize; ++ } else { ++ instr->addr += priv->page_size; ++ instr->len -= priv->page_size; ++ } ++ } ++ up(&priv->lock); ++ ++ /* Inform MTD subsystem that erase is complete */ ++ instr->state = MTD_ERASE_DONE; ++ mtd_erase_callback(instr); ++ ++ return 0; ++} ++ ++/* ++ * Read from the DataFlash device. ++ * from : Start offset in flash device ++ * len : Amount to read ++ * retlen : About of data actually read ++ * buf : Buffer containing the data ++ */ ++static int dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ struct dataflash *priv = (struct dataflash *)mtd->priv; ++ struct spi_transfer x[2] = { { .tx_dma = 0, }, }; ++ struct spi_message msg; ++ unsigned int addr; ++ u8 *command; ++ int status; ++ ++ DEBUG(MTD_DEBUG_LEVEL2, "%s: read 0x%x..0x%x\n", ++ priv->spi->dev.bus_id, (unsigned)from, (unsigned)(from + len)); ++ ++ *retlen = 0; ++ ++ /* Sanity checks */ ++ if (!len) ++ return 0; ++ if (from + len > mtd->size) ++ return -EINVAL; ++ ++ /* Calculate flash page/byte address */ ++ addr = (((unsigned)from / priv->page_size) << priv->page_offset) ++ + ((unsigned)from % priv->page_size); ++ ++ command = priv->command; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "READ: (%x) %x %x %x\n", ++ command[0], command[1], command[2], command[3]); ++ ++ x[0].tx_buf = command; ++ x[0].len = 8; ++ x[1].rx_buf = buf; ++ x[1].len = len; ++ msg.transfers = x; ++ msg.n_transfer = 2; ++ ++ down(&priv->lock); ++ ++ /* Continuous read, max clock = f(car) which may be less than ++ * the peak rate available. Some chips support commands with ++ * fewer "don't care" bytes. Both buffers stay unchanged. ++ */ ++ command[0] = OP_READ_CONTINUOUS; ++ command[1] = (u8)(addr >> 16); ++ command[2] = (u8)(addr >> 8); ++ command[3] = (u8)(addr >> 0); ++ /* plus 4 "don't care" bytes */ ++ ++ status = spi_sync(priv->spi, &msg); ++ up(&priv->lock); ++ ++ if (status >= 0) { ++ *retlen = msg.actual_length - 8; ++ status = 0; ++ } else ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: read %x..%x --> %d\n", ++ priv->spi->dev.bus_id, ++ (unsigned)from, (unsigned)(from + len), ++ status); ++ return status; ++} ++ ++/* ++ * Write to the DataFlash device. ++ * to : Start offset in flash device ++ * len : Amount to write ++ * retlen : Amount of data actually written ++ * buf : Buffer containing the data ++ */ ++static int dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, ++ size_t * retlen, const u_char * buf) ++{ ++ struct dataflash *priv = (struct dataflash *)mtd->priv; ++ struct spi_device *spi = priv->spi; ++ struct spi_transfer x[2] = { { .tx_dma = 0, }, }; ++ struct spi_message msg; ++ unsigned int pageaddr, addr, offset, writelen; ++ size_t remaining = len; ++ u_char *writebuf = (u_char *) buf; ++ int status = -EINVAL; ++ u8 *command; ++ ++ DEBUG(MTD_DEBUG_LEVEL2, "%s: write 0x%x..0x%x\n", ++ spi->dev.bus_id, (unsigned)to, (unsigned)(to + len)); ++ ++ *retlen = 0; ++ ++ /* Sanity checks */ ++ if (!len) ++ return 0; ++ if ((to + len) > mtd->size) ++ return -EINVAL; ++ ++ x[0].tx_buf = command = priv->command; ++ x[0].len = 4; ++ msg.transfers = x; ++ ++ pageaddr = ((unsigned)to / priv->page_size); ++ offset = ((unsigned)to % priv->page_size); ++ if (offset + len > priv->page_size) ++ writelen = priv->page_size - offset; ++ else ++ writelen = len; ++ ++ down(&priv->lock); ++ while (remaining > 0) { ++ DEBUG(MTD_DEBUG_LEVEL3, "write @ %i:%i len=%i\n", ++ pageaddr, offset, writelen); ++ ++ /* REVISIT: ++ * (a) each page in a sector must be rewritten at least ++ * once every 10K sibling erase/program operations. ++ * (b) for pages that are already erased, we could ++ * use WRITE+MWRITE not PROGRAM for ~30% speedup. ++ * (c) WRITE to buffer could be done while waiting for ++ * a previous MWRITE/MWERASE to complete ... ++ * (d) error handling here seems to be mostly missing. ++ * ++ * Two persistent bits per page, plus a per-sector counter, ++ * could support (a) and (b) ... we might consider using ++ * the second half of sector zero, which is just one block, ++ * to track that state. (On AT91, that sector should also ++ * support boot-from-DataFlash.) ++ */ ++ ++ addr = pageaddr << priv->page_offset; ++ ++ /* (1) Maybe transfer partial page to Buffer1 */ ++ if (writelen != priv->page_size) { ++ command[0] = OP_TRANSFER_BUF1; ++ command[1] = (addr & 0x00FF0000) >> 16; ++ command[2] = (addr & 0x0000FF00) >> 8; ++ command[3] = 0; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "TRANSFER: (%x) %x %x %x\n", ++ command[0], command[1], command[2], command[3]); ++ ++ msg.n_transfer = 1; ++ status = spi_sync(spi, &msg); ++ if (status < 0) ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: xfer %u -> %d \n", ++ spi->dev.bus_id, addr, status); ++ ++ (void) dataflash_waitready(priv->spi); ++ } ++ ++ /* (2) Program full page via Buffer1 */ ++ addr += offset; ++ command[0] = OP_PROGRAM_VIA_BUF1; ++ command[1] = (addr & 0x00FF0000) >> 16; ++ command[2] = (addr & 0x0000FF00) >> 8; ++ command[3] = (addr & 0x000000FF); ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "PROGRAM: (%x) %x %x %x\n", ++ command[0], command[1], command[2], command[3]); ++ ++ x[1].tx_buf = writebuf; ++ x[1].len = writelen; ++ msg.n_transfer = 2; ++ status = spi_sync(spi, &msg); ++ if (status < 0) ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: pgm %u/%u -> %d \n", ++ spi->dev.bus_id, addr, writelen, status); ++ ++ (void) dataflash_waitready(priv->spi); ++ ++#ifdef CONFIG_DATAFLASH_WRITE_VERIFY ++ ++ /* (3) Compare to Buffer1 */ ++ addr = pageaddr << priv->page_offset; ++ command[0] = OP_COMPARE_BUF1; ++ command[1] = (addr & 0x00FF0000) >> 16; ++ command[2] = (addr & 0x0000FF00) >> 8; ++ command[3] = 0; ++ ++ DEBUG(MTD_DEBUG_LEVEL3, "COMPARE: (%x) %x %x %x\n", ++ command[0], command[1], command[2], command[3]); ++ ++ msg.n_transfer = 1; ++ status = spi_sync(spi, &msg); ++ if (status < 0) ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: compare %u -> %d \n", ++ spi->dev.bus_id, addr, status); ++ ++ status = dataflash_waitready(priv->spi); ++ ++ /* Check result of the compare operation */ ++ if ((status & (1 << 6)) == 1) { ++ printk(KERN_ERR "%s: compare page %u, err %d\n", ++ spi->dev.bus_id, pageaddr, status); ++ remaining = 0; ++ status = -EIO; ++ break; ++ } else ++ status = 0; ++ ++#endif /* CONFIG_DATAFLASH_WRITE_VERIFY */ ++ ++ remaining = remaining - writelen; ++ pageaddr++; ++ offset = 0; ++ writebuf += writelen; ++ *retlen += writelen; ++ ++ if (remaining > priv->page_size) ++ writelen = priv->page_size; ++ else ++ writelen = remaining; ++ } ++ up(&priv->lock); ++ ++ return status; ++} ++ ++/* ......................................................................... */ ++ ++/* ++ * Register DataFlash device with MTD subsystem. ++ */ ++static int __devinit ++add_dataflash(struct spi_device *spi, char *name, ++ int nr_pages, int pagesize, int pageoffset) ++{ ++ struct dataflash *priv; ++ struct mtd_info *device; ++ struct flash_platform_data *pdata = spi->dev.platform_data; ++ ++ priv = (struct dataflash *) kzalloc(sizeof *priv, GFP_KERNEL); ++ if (!priv) ++ return -ENOMEM; ++ ++ init_MUTEX(&priv->lock); ++ priv->spi = spi; ++ priv->page_size = pagesize; ++ priv->page_offset = pageoffset; ++ ++ /* name must be usable with cmdlinepart */ ++ sprintf(priv->name, "spi%d.%d-%s", ++ spi->master->bus_num, spi->chip_select, ++ name); ++ ++ device = &priv->mtd; ++ device->name = (pdata && pdata->name) ? pdata->name : priv->name; ++ device->size = nr_pages * pagesize; ++ device->erasesize = pagesize; ++ device->owner = THIS_MODULE; ++ device->type = MTD_DATAFLASH; ++ device->flags = MTD_CAP_NORFLASH; ++ device->erase = dataflash_erase; ++ device->read = dataflash_read; ++ device->write = dataflash_write; ++ device->priv = priv; ++ ++ dev_info(&spi->dev, "%s (%d KBytes)\n", name, device->size/1024); ++ dev_set_drvdata(&spi->dev, priv); ++ ++ if (mtd_has_partitions()) { ++ struct mtd_partition *parts; ++ int nr_parts = 0; ++ ++#ifdef CONFIG_MTD_CMDLINE_PARTS ++ static const char *part_probes[] = { "cmdlinepart", NULL, }; ++ ++ nr_parts = parse_mtd_partitions(device, part_probes, &parts, 0); ++#endif ++ ++ if (nr_parts <= 0 && pdata && pdata->parts) { ++ parts = pdata->parts; ++ nr_parts = pdata->nr_parts; ++ } ++ ++ if (nr_parts > 0) { ++ priv->partitioned = 1; ++ return add_mtd_partitions(device, parts, nr_parts); ++ } ++ } else if (pdata->nr_parts) ++ dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", ++ pdata->nr_parts, device->name); ++ ++ return add_mtd_device(device) == 1 ? -ENODEV : 0; ++} ++ ++/* ++ * Detect and initialize DataFlash device: ++ * ++ * Device Density ID code #Pages PageSize Offset ++ * AT45DB011B 1Mbit (128K) xx0011xx (0x0c) 512 264 9 ++ * AT45DB021B 2Mbit (256K) xx0101xx (0x14) 1025 264 9 ++ * AT45DB041B 4Mbit (512K) xx0111xx (0x1c) 2048 264 9 ++ * AT45DB081B 8Mbit (1M) xx1001xx (0x24) 4096 264 9 ++ * AT45DB0161B 16Mbit (2M) xx1011xx (0x2c) 4096 528 10 ++ * AT45DB0321B 32Mbit (4M) xx1101xx (0x34) 8192 528 10 ++ * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11 ++ * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11 ++ */ ++static int __devinit dataflash_probe(struct spi_device *spi) ++{ ++ int status; ++ ++ status = dataflash_status(spi); ++ if (status <= 0 || status == 0xff) { ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: status error %d\n", ++ spi->dev.bus_id, status); ++ if (status == 0xff) ++ status = -ENODEV; ++ return status; ++ } ++ ++ /* if there's a device there, assume it's dataflash. ++ * board setup should have set spi->max_speed_max to ++ * match f(car) for continuous reads, mode 0 or 3. ++ */ ++ switch (status & 0x3c) { ++ case 0x0c: /* 0 0 1 1 x x */ ++ status = add_dataflash(spi, "AT45DB011B", 512, 264, 9); ++ break; ++ case 0x14: /* 0 1 0 1 x x */ ++ status = add_dataflash(spi, "AT45DB021B", 1025, 264, 9); ++ break; ++ case 0x1c: /* 0 1 1 1 x x */ ++ status = add_dataflash(spi, "AT45DB041x", 2048, 264, 9); ++ break; ++ case 0x24: /* 1 0 0 1 x x */ ++ status = add_dataflash(spi, "AT45DB081B", 4096, 264, 9); ++ break; ++ case 0x2c: /* 1 0 1 1 x x */ ++ status = add_dataflash(spi, "AT45DB161x", 4096, 528, 10); ++ break; ++ case 0x34: /* 1 1 0 1 x x */ ++ status = add_dataflash(spi, "AT45DB321x", 8192, 528, 10); ++ break; ++ case 0x38: /* 1 1 1 x x x */ ++ case 0x3c: ++ status = add_dataflash(spi, "AT45DB642x", 8192, 1056, 11); ++ break; ++ /* obsolete AT45DB1282 not (yet?) supported */ ++ default: ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: unsupported device (%x)\n", ++ spi->dev.bus_id, status & 0x3c); ++ status = -ENODEV; ++ } ++ ++ if (status < 0) ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: add_dataflash --> %d\n", ++ spi->dev.bus_id, status); ++ ++ return status; ++} ++ ++static int __devexit dataflash_remove(struct spi_device *spi) ++{ ++ struct dataflash *flash = dev_get_drvdata(&spi->dev); ++ int status; ++ ++ DEBUG(MTD_DEBUG_LEVEL1, "%s: remove\n", spi->dev.bus_id); ++ ++ if (mtd_has_partitions() && flash->partitioned) ++ status = del_mtd_partitions(&flash->mtd); ++ else ++ status = del_mtd_device(&flash->mtd); ++ if (status == 0) ++ kfree(flash); ++ return status; ++} ++ ++static struct spi_driver dataflash_driver = { ++ .driver = { ++ .name = "mtd_dataflash", ++ .bus = &spi_bus_type, ++ .owner = THIS_MODULE, ++ }, ++ ++ .probe = dataflash_probe, ++ .remove = __devexit_p(dataflash_remove), ++ ++ /* FIXME: investigate suspend and resume... */ ++}; ++ ++static int __init dataflash_init(void) ++{ ++ return spi_register_driver(&dataflash_driver); ++} ++module_init(dataflash_init); ++ ++static void __exit dataflash_exit(void) ++{ ++ spi_unregister_driver(&dataflash_driver); ++} ++module_exit(dataflash_exit); ++ ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Andrew Victor, David Brownell"); ++MODULE_DESCRIPTION("MTD DataFlash driver"); +--- /dev/null ++++ gregkh-2.6/include/linux/spi/flash.h +@@ -0,0 +1,27 @@ ++#ifndef LINUX_SPI_FLASH_H ++#define LINUX_SPI_FLASH_H ++ ++struct mtd_partition; ++ ++/** ++ * struct flash_platform_data: board-specific flash data ++ * @name: optional flash device name (eg, as used with mtdparts=) ++ * @parts: optional array of mtd_partitions for static partitioning ++ * @nr_parts: number of mtd_partitions for static partitoning ++ * ++ * Board init code (in arch/.../mach-xxx/board-yyy.c files) can ++ * provide information about SPI flash parts (such as DataFlash) to ++ * help set up the device and its appropriate default partitioning. ++ * ++ * Note that for DataFlash, sizes for pages, blocks, and sectors are ++ * rarely powers of two; and partitions should be sector-aligned. ++ */ ++struct flash_platform_data { ++ char *name; ++ struct mtd_partition *parts; ++ unsigned int nr_parts; ++ ++ /* we'll likely add more ... use JEDEC IDs, etc */ ++}; ++ ++#endif diff --git a/driver/spi-simple-spi-framework.patch b/driver/spi-simple-spi-framework.patch new file mode 100644 index 0000000000000..09ac4e040737a --- /dev/null +++ b/driver/spi-simple-spi-framework.patch @@ -0,0 +1,1755 @@ +From akpm@osdl.org Sun Jan 8 13:38:03 2006 +From: akpm@osdl.org +Message-Id: <200601082134.k08LYVu1004555@shell0.pdx.osdl.net> +Subject: [patch 01/10] spi: simple SPI framework +To: greg@kroah.com +Cc: akpm@osdl.org, david-b@pacbell.net, basicmark@yahoo.com, dbrownell@users.sourceforge.net +Date: Sun, 08 Jan 2006 13:34:19 -0800 + + +From: David Brownell <david-b@pacbell.net> + +This is the core of a small SPI framework, implementing the model of a +queue of messages which complete asynchronously (with thin synchronous +wrappers on top). + + - It's still less than 2KB of ".text" (ARM). If there's got to be a + mid-layer for something so simple, that's the right size budget. :) + + - The guts use board-specific SPI device tables to build the driver + model tree. (Hardware probing is rarely an option.) + + - This version of Kconfig includes no drivers. At this writing there + are two known master controller drivers (PXA/SSP, OMAP MicroWire) + and three protocol drivers (CS8415a, ADS7846, DataFlash) with LKML + mentions of other drivers in development. + + - No userspace API. There are several implementations to compare. + Implement them like any other driver, and bind them with sysfs. + +The changes from last version posted to LKML (on 11-Nov-2005) are minor, +and include: + + - One bugfix (removes a FIXME), with the visible effect of making device + names be "spiB.C" where B is the bus number and C is the chipselect. + + - The "caller provides DMA mappings" mechanism now has kerneldoc, for + DMA drivers that want to be fancy. + + - Hey, the framework init can be subsys_init. Even though board init + logic fires earlier, at arch_init ... since the framework init is + for driver support, and the board init support uses static init. + + - Various additional spec/doc clarifications based on discussions + with other folk. It adds a brief "thank you" at the end, for folk + who've helped nudge this framework into existence. + +As I've said before, I think that "protocol tweaking" is the main support +that this driver framework will need to evolve. + +From: Mark Underwood <basicmark@yahoo.com> + + Update the SPI framework to remove a potential priority inversion case by + reverting to kmalloc if the pre-allocated DMA-safe buffer isn't available. + +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + Documentation/spi/spi-summary | 416 ++++++++++++++++++++++++++++++ + arch/arm/Kconfig | 2 + drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/spi/Kconfig | 91 ++++++ + drivers/spi/Makefile | 23 + + drivers/spi/spi.c | 568 ++++++++++++++++++++++++++++++++++++++++++ + include/linux/spi/spi.h | 542 ++++++++++++++++++++++++++++++++++++++++ + 8 files changed, 1645 insertions(+) + +--- gregkh-2.6.orig/arch/arm/Kconfig ++++ gregkh-2.6/arch/arm/Kconfig +@@ -729,6 +729,8 @@ source "drivers/char/Kconfig" + + source "drivers/i2c/Kconfig" + ++source "drivers/spi/Kconfig" ++ + source "drivers/hwmon/Kconfig" + + #source "drivers/l3/Kconfig" +--- /dev/null ++++ gregkh-2.6/Documentation/spi/spi-summary +@@ -0,0 +1,416 @@ ++Overview of Linux kernel SPI support ++==================================== ++ ++22-Nov-2005 ++ ++What is SPI? ++------------ ++The "Serial Peripheral Interface" (SPI) is a four-wire point-to-point ++serial link used to connect microcontrollers to sensors and memory. ++ ++The three signal wires hold a clock (SCLK, often on the order of 10 MHz), ++and parallel data lines with "Master Out, Slave In" (MOSI) or "Master In, ++Slave Out" (MISO) signals. (Other names are also used.) There are four ++clocking modes through which data is exchanged; mode-0 and mode-3 are most ++commonly used. ++ ++SPI masters may use a "chip select" line to activate a given SPI slave ++device, so those three signal wires may be connected to several chips ++in parallel. All SPI slaves support chipselects. Some devices have ++other signals, often including an interrupt to the master. ++ ++Unlike serial busses like USB or SMBUS, even low level protocols for ++SPI slave functions are usually not interoperable between vendors ++(except for cases like SPI memory chips). ++ ++ - SPI may be used for request/response style device protocols, as with ++ touchscreen sensors and memory chips. ++ ++ - It may also be used to stream data in either direction (half duplex), ++ or both of them at the same time (full duplex). ++ ++ - Some devices may use eight bit words. Others may different word ++ lengths, such as streams of 12-bit or 20-bit digital samples. ++ ++In the same way, SPI slaves will only rarely support any kind of automatic ++discovery/enumeration protocol. The tree of slave devices accessible from ++a given SPI master will normally be set up manually, with configuration ++tables. ++ ++SPI is only one of the names used by such four-wire protocols, and ++most controllers have no problem handling "MicroWire" (think of it as ++half-duplex SPI, for request/response protocols), SSP ("Synchronous ++Serial Protocol"), PSP ("Programmable Serial Protocol"), and other ++related protocols. ++ ++Microcontrollers often support both master and slave sides of the SPI ++protocol. This document (and Linux) currently only supports the master ++side of SPI interactions. ++ ++ ++Who uses it? On what kinds of systems? ++--------------------------------------- ++Linux developers using SPI are probably writing device drivers for embedded ++systems boards. SPI is used to control external chips, and it is also a ++protocol supported by every MMC or SD memory card. (The older "DataFlash" ++cards, predating MMC cards but using the same connectors and card shape, ++support only SPI.) Some PC hardware uses SPI flash for BIOS code. ++ ++SPI slave chips range from digital/analog converters used for analog ++sensors and codecs, to memory, to peripherals like USB controllers ++or Ethernet adapters; and more. ++ ++Most systems using SPI will integrate a few devices on a mainboard. ++Some provide SPI links on expansion connectors; in cases where no ++dedicated SPI controller exists, GPIO pins can be used to create a ++low speed "bitbanging" adapter. Very few systems will "hotplug" an SPI ++controller; the reasons to use SPI focus on low cost and simple operation, ++and if dynamic reconfiguration is important, USB will often be a more ++appropriate low-pincount peripheral bus. ++ ++Many microcontrollers that can run Linux integrate one or more I/O ++interfaces with SPI modes. Given SPI support, they could use MMC or SD ++cards without needing a special purpose MMC/SD/SDIO controller. ++ ++ ++How do these driver programming interfaces work? ++------------------------------------------------ ++The <linux/spi/spi.h> header file includes kerneldoc, as does the ++main source code, and you should certainly read that. This is just ++an overview, so you get the big picture before the details. ++ ++There are two types of SPI driver, here called: ++ ++ Controller drivers ... these are often built in to System-On-Chip ++ processors, and often support both Master and Slave roles. ++ These drivers touch hardware registers and may use DMA. ++ ++ Protocol drivers ... these pass messages through the controller ++ driver to communicate with a Slave or Master device on the ++ other side of an SPI link. ++ ++So for example one protocol driver might talk to the MTD layer to export ++data to filesystems stored on SPI flash like DataFlash; and others might ++control audio interfaces, present touchscreen sensors as input interfaces, ++or monitor temperature and voltage levels during industrial processing. ++And those might all be sharing the same controller driver. ++ ++A "struct spi_device" encapsulates the master-side interface between ++those two types of driver. At this writing, Linux has no slave side ++programming interface. ++ ++There is a minimal core of SPI programming interfaces, focussing on ++using driver model to connect controller and protocol drivers using ++device tables provided by board specific initialization code. SPI ++shows up in sysfs in several locations: ++ ++ /sys/devices/.../CTLR/spiB.C ... spi_device for on bus "B", ++ chipselect C, accessed through CTLR. ++ ++ /sys/bus/spi/devices/spiB.C ... symlink to the physical ++ spiB-C device ++ ++ /sys/bus/spi/drivers/D ... driver for one or more spi*.* devices ++ ++ /sys/class/spi_master/spiB ... class device for the controller ++ managing bus "B". All the spiB.* devices share the same ++ physical SPI bus segment, with SCLK, MOSI, and MISO. ++ ++The basic I/O primitive submits an asynchronous message to an I/O queue ++maintained by the controller driver. A completion callback is issued ++asynchronously when the data transfer(s) in that message completes. ++There are also some simple synchronous wrappers for those calls. ++ ++ ++How does board-specific init code declare SPI devices? ++------------------------------------------------------ ++Linux needs several kinds of information to properly configure SPI devices. ++That information is normally provided by board-specific code, even for ++chips that do support some of automated discovery/enumeration. ++ ++DECLARE CONTROLLERS ++ ++The first kind of information is a list of what SPI controllers exist. ++For System-on-Chip (SOC) based boards, these will usually be platform ++devices, and the controller may need some platform_data in order to ++operate properly. The "struct platform_device" will include resources ++like the physical address of the controller's first register and its IRQ. ++ ++Platforms will often abstract the "register SPI controller" operation, ++maybe coupling it with code to initialize pin configurations, so that ++the arch/.../mach-*/board-*.c files for several boards can all share the ++same basic controller setup code. This is because most SOCs have several ++SPI-capable controllers, and only the ones actually usable on a given ++board should normally be set up and registered. ++ ++So for example arch/.../mach-*/board-*.c files might have code like: ++ ++ #include <asm/arch/spi.h> /* for mysoc_spi_data */ ++ ++ /* if your mach-* infrastructure doesn't support kernels that can ++ * run on multiple boards, pdata wouldn't benefit from "__init". ++ */ ++ static struct mysoc_spi_data __init pdata = { ... }; ++ ++ static __init board_init(void) ++ { ++ ... ++ /* this board only uses SPI controller #2 */ ++ mysoc_register_spi(2, &pdata); ++ ... ++ } ++ ++And SOC-specific utility code might look something like: ++ ++ #include <asm/arch/spi.h> ++ ++ static struct platform_device spi2 = { ... }; ++ ++ void mysoc_register_spi(unsigned n, struct mysoc_spi_data *pdata) ++ { ++ struct mysoc_spi_data *pdata2; ++ ++ pdata2 = kmalloc(sizeof *pdata2, GFP_KERNEL); ++ *pdata2 = pdata; ++ ... ++ if (n == 2) { ++ spi2->dev.platform_data = pdata2; ++ register_platform_device(&spi2); ++ ++ /* also: set up pin modes so the spi2 signals are ++ * visible on the relevant pins ... bootloaders on ++ * production boards may already have done this, but ++ * developer boards will often need Linux to do it. ++ */ ++ } ++ ... ++ } ++ ++Notice how the platform_data for boards may be different, even if the ++same SOC controller is used. For example, on one board SPI might use ++an external clock, where another derives the SPI clock from current ++settings of some master clock. ++ ++ ++DECLARE SLAVE DEVICES ++ ++The second kind of information is a list of what SPI slave devices exist ++on the target board, often with some board-specific data needed for the ++driver to work correctly. ++ ++Normally your arch/.../mach-*/board-*.c files would provide a small table ++listing the SPI devices on each board. (This would typically be only a ++small handful.) That might look like: ++ ++ static struct ads7846_platform_data ads_info = { ++ .vref_delay_usecs = 100, ++ .x_plate_ohms = 580, ++ .y_plate_ohms = 410, ++ }; ++ ++ static struct spi_board_info spi_board_info[] __initdata = { ++ { ++ .modalias = "ads7846", ++ .platform_data = &ads_info, ++ .mode = SPI_MODE_0, ++ .irq = GPIO_IRQ(31), ++ .max_speed_hz = 120000 /* max sample rate at 3V */ * 16, ++ .bus_num = 1, ++ .chip_select = 0, ++ }, ++ }; ++ ++Again, notice how board-specific information is provided; each chip may need ++several types. This example shows generic constraints like the fastest SPI ++clock to allow (a function of board voltage in this case) or how an IRQ pin ++is wired, plus chip-specific constraints like an important delay that's ++changed by the capacitance at one pin. ++ ++(There's also "controller_data", information that may be useful to the ++controller driver. An example would be peripheral-specific DMA tuning ++data or chipselect callbacks. This is stored in spi_device later.) ++ ++The board_info should provide enough information to let the system work ++without the chip's driver being loaded. The most troublesome aspect of ++that is likely the SPI_CS_HIGH bit in the spi_device.mode field, since ++sharing a bus with a device that interprets chipselect "backwards" is ++not possible. ++ ++Then your board initialization code would register that table with the SPI ++infrastructure, so that it's available later when the SPI master controller ++driver is registered: ++ ++ spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info)); ++ ++Like with other static board-specific setup, you won't unregister those. ++ ++ ++NON-STATIC CONFIGURATIONS ++ ++Developer boards often play by different rules than product boards, and one ++example is the potential need to hotplug SPI devices and/or controllers. ++ ++For those cases you might need to use use spi_busnum_to_master() to look ++up the spi bus master, and will likely need spi_new_device() to provide the ++board info based on the board that was hotplugged. Of course, you'd later ++call at least spi_unregister_device() when that board is removed. ++ ++ ++How do I write an "SPI Protocol Driver"? ++---------------------------------------- ++All SPI drivers are currently kernel drivers. A userspace driver API ++would just be another kernel driver, probably offering some lowlevel ++access through aio_read(), aio_write(), and ioctl() calls and using the ++standard userspace sysfs mechanisms to bind to a given SPI device. ++ ++SPI protocol drivers are normal device drivers, with no more wrapper ++than needed by platform devices: ++ ++ static struct device_driver CHIP_driver = { ++ .name = "CHIP", ++ .bus = &spi_bus_type, ++ .probe = CHIP_probe, ++ .remove = __exit_p(CHIP_remove), ++ .suspend = CHIP_suspend, ++ .resume = CHIP_resume, ++ }; ++ ++The SPI core will autmatically attempt to bind this driver to any SPI ++device whose board_info gave a modalias of "CHIP". Your probe() code ++might look like this unless you're creating a class_device: ++ ++ static int __init CHIP_probe(struct device *dev) ++ { ++ struct spi_device *spi = to_spi_device(dev); ++ struct CHIP *chip; ++ struct CHIP_platform_data *pdata = dev->platform_data; ++ ++ /* get memory for driver's per-chip state */ ++ chip = kzalloc(sizeof *chip, GFP_KERNEL); ++ if (!chip) ++ return -ENOMEM; ++ dev_set_drvdata(dev, chip); ++ ++ ... etc ++ return 0; ++ } ++ ++As soon as it enters probe(), the driver may issue I/O requests to ++the SPI device using "struct spi_message". When remove() returns, ++the driver guarantees that it won't submit any more such messages. ++ ++ - An spi_message is a sequence of of protocol operations, executed ++ as one atomic sequence. SPI driver controls include: ++ ++ + when bidirectional reads and writes start ... by how its ++ sequence of spi_transfer requests is arranged; ++ ++ + optionally defining short delays after transfers ... using ++ the spi_transfer.delay_usecs setting; ++ ++ + whether the chipselect becomes inactive after a transfer and ++ any delay ... by using the spi_transfer.cs_change flag; ++ ++ + hinting whether the next message is likely to go to this same ++ device ... using the spi_transfer.cs_change flag on the last ++ transfer in that atomic group, and potentially saving costs ++ for chip deselect and select operations. ++ ++ - Follow standard kernel rules, and provide DMA-safe buffers in ++ your messages. That way controller drivers using DMA aren't forced ++ to make extra copies unless the hardware requires it (e.g. working ++ around hardware errata that force the use of bounce buffering). ++ ++ If standard dma_map_single() handling of these buffers is inappropriate, ++ you can use spi_message.is_dma_mapped to tell the controller driver ++ that you've already provided the relevant DMA addresses. ++ ++ - The basic I/O primitive is spi_async(). Async requests may be ++ issued in any context (irq handler, task, etc) and completion ++ is reported using a callback provided with the message. ++ ++ - There are also synchronous wrappers like spi_sync(), and wrappers ++ like spi_read(), spi_write(), and spi_write_then_read(). These ++ may be issued only in contexts that may sleep, and they're all ++ clean (and small, and "optional") layers over spi_async(). ++ ++ - The spi_write_then_read() call, and convenience wrappers around ++ it, should only be used with small amounts of data where the ++ cost of an extra copy may be ignored. It's designed to support ++ common RPC-style requests, such as writing an eight bit command ++ and reading a sixteen bit response -- spi_w8r16() being one its ++ wrappers, doing exactly that. ++ ++Some drivers may need to modify spi_device characteristics like the ++transfer mode, wordsize, or clock rate. This is done with spi_setup(), ++which would normally be called from probe() before the first I/O is ++done to the device. ++ ++While "spi_device" would be the bottom boundary of the driver, the ++upper boundaries might include sysfs (especially for sensor readings), ++the input layer, ALSA, networking, MTD, the character device framework, ++or other Linux subsystems. ++ ++ ++How do I write an "SPI Master Controller Driver"? ++------------------------------------------------- ++An SPI controller will probably be registered on the platform_bus; write ++a driver to bind to the device, whichever bus is involved. ++ ++The main task of this type of driver is to provide an "spi_master". ++Use spi_alloc_master() to allocate the master, and class_get_devdata() ++to get the driver-private data allocated for that device. ++ ++ struct spi_master *master; ++ struct CONTROLLER *c; ++ ++ master = spi_alloc_master(dev, sizeof *c); ++ if (!master) ++ return -ENODEV; ++ ++ c = class_get_devdata(&master->cdev); ++ ++The driver will initialize the fields of that spi_master, including the ++bus number (maybe the same as the platform device ID) and three methods ++used to interact with the SPI core and SPI protocol drivers. It will ++also initialize its own internal state. ++ ++ master->setup(struct spi_device *spi) ++ This sets up the device clock rate, SPI mode, and word sizes. ++ Drivers may change the defaults provided by board_info, and then ++ call spi_setup(spi) to invoke this routine. It may sleep. ++ ++ master->transfer(struct spi_device *spi, struct spi_message *message) ++ This must not sleep. Its responsibility is arrange that the ++ transfer happens and its complete() callback is issued; the two ++ will normally happen later, after other transfers complete. ++ ++ master->cleanup(struct spi_device *spi) ++ Your controller driver may use spi_device.controller_state to hold ++ state it dynamically associates with that device. If you do that, ++ be sure to provide the cleanup() method to free that state. ++ ++The bulk of the driver will be managing the I/O queue fed by transfer(). ++ ++That queue could be purely conceptual. For example, a driver used only ++for low-frequency sensor acess might be fine using synchronous PIO. ++ ++But the queue will probably be very real, using message->queue, PIO, ++often DMA (especially if the root filesystem is in SPI flash), and ++execution contexts like IRQ handlers, tasklets, or workqueues (such ++as keventd). Your driver can be as fancy, or as simple, as you need. ++ ++ ++THANKS TO ++--------- ++Contributors to Linux-SPI discussions include (in alphabetical order, ++by last name): ++ ++David Brownell ++Russell King ++Dmitry Pervushin ++Stephen Street ++Mark Underwood ++Andrew Victor ++Vitaly Wool ++ +--- gregkh-2.6.orig/drivers/Kconfig ++++ gregkh-2.6/drivers/Kconfig +@@ -44,6 +44,8 @@ source "drivers/char/Kconfig" + + source "drivers/i2c/Kconfig" + ++source "drivers/spi/Kconfig" ++ + source "drivers/w1/Kconfig" + + source "drivers/hwmon/Kconfig" +--- gregkh-2.6.orig/drivers/Makefile ++++ gregkh-2.6/drivers/Makefile +@@ -41,6 +41,7 @@ obj-$(CONFIG_FUSION) += message/ + obj-$(CONFIG_IEEE1394) += ieee1394/ + obj-y += cdrom/ + obj-$(CONFIG_MTD) += mtd/ ++obj-$(CONFIG_SPI) += spi/ + obj-$(CONFIG_PCCARD) += pcmcia/ + obj-$(CONFIG_DIO) += dio/ + obj-$(CONFIG_SBUS) += sbus/ +--- /dev/null ++++ gregkh-2.6/drivers/spi/Kconfig +@@ -0,0 +1,91 @@ ++# ++# SPI driver configuration ++# ++# NOTE: the reason this doesn't show SPI slave support is mostly that ++# nobody's needed a slave side API yet. The master-role API is not ++# fully appropriate there, so it'd need some thought to do well. ++# ++menu "SPI support" ++ ++# someday this stuff should be set using arch/CPU/PLATFORM/Kconfig ++config SPI_ARCH_HAS_MASTER ++ boolean ++ default y if ARCH_AT91 ++ default y if ARCH_OMAP ++ default y if ARCH_PXA ++ default y if X86 # devel hack only!! (ICH7 can...) ++ ++config SPI_ARCH_HAS_SLAVE ++ boolean ++ default y if ARCH_AT91 ++ default y if ARCH_OMAP ++ default y if ARCH_PXA ++ ++config SPI ++ bool "SPI support" ++ depends on SPI_ARCH_HAS_MASTER || SPI_ARCH_HAS_SLAVE ++ help ++ The "Serial Peripheral Interface" is a low level synchronous ++ protocol. Chips that support SPI can have data transfer rates ++ up to several tens of Mbit/sec. Chips are addressed with a ++ controller and a chipselect. Most SPI slaves don't support ++ dynamic device discovery; some are even write-only or read-only. ++ ++ SPI is widely used by microcontollers to talk with sensors, ++ eeprom and flash memory, codecs and various other controller ++ chips, analog to digital (and d-to-a) converters, and more. ++ MMC and SD cards can be accessed using SPI protocol; and for ++ DataFlash cards used in MMC sockets, SPI must always be used. ++ ++ SPI is one of a family of similar protocols using a four wire ++ interface (select, clock, data in, data out) including Microwire ++ (half duplex), SSP, SSI, and PSP. This driver framework should ++ work with most such devices and controllers. ++ ++config SPI_DEBUG ++ boolean "Debug support for SPI drivers" ++ depends on SPI && DEBUG_KERNEL ++ help ++ Say "yes" to enable debug messaging (like dev_dbg and pr_debug), ++ sysfs, and debugfs support in SPI controller and protocol drivers. ++ ++# ++# MASTER side ... talking to discrete SPI slave chips including microcontrollers ++# ++ ++config SPI_MASTER ++# boolean "SPI Master Support" ++ boolean ++ default SPI && SPI_ARCH_HAS_MASTER ++ help ++ If your system has an master-capable SPI controller (which ++ provides the clock and chipselect), you can enable that ++ controller and the protocol drivers for the SPI slave chips ++ that are connected. ++ ++comment "SPI Master Controller Drivers" ++ depends on SPI_MASTER ++ ++ ++# ++# Add new SPI master controllers in alphabetical order above this line ++# ++ ++ ++# ++# There are lots of SPI device types, with sensors and memory ++# being probably the most widely used ones. ++# ++comment "SPI Protocol Masters" ++ depends on SPI_MASTER ++ ++ ++# ++# Add new SPI protocol masters in alphabetical order above this line ++# ++ ++ ++# (slave support would go here) ++ ++endmenu # "SPI support" ++ +--- /dev/null ++++ gregkh-2.6/drivers/spi/Makefile +@@ -0,0 +1,23 @@ ++# ++# Makefile for kernel SPI drivers. ++# ++ ++ifeq ($(CONFIG_SPI_DEBUG),y) ++EXTRA_CFLAGS += -DDEBUG ++endif ++ ++# small core, mostly translating board-specific ++# config declarations into driver model code ++obj-$(CONFIG_SPI_MASTER) += spi.o ++ ++# SPI master controller drivers (bus) ++# ... add above this line ... ++ ++# SPI protocol drivers (device/link on bus) ++# ... add above this line ... ++ ++# SPI slave controller drivers (upstream link) ++# ... add above this line ... ++ ++# SPI slave drivers (protocol for that link) ++# ... add above this line ... +--- /dev/null ++++ gregkh-2.6/drivers/spi/spi.c +@@ -0,0 +1,568 @@ ++/* ++ * spi.c - SPI init/core code ++ * ++ * Copyright (C) 2005 David Brownell ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include <linux/autoconf.h> ++#include <linux/kernel.h> ++#include <linux/device.h> ++#include <linux/init.h> ++#include <linux/cache.h> ++#include <linux/spi/spi.h> ++ ++ ++/* SPI bustype and spi_master class are registered during early boot, ++ * usually before board init code provides the SPI device tables, and ++ * are available later when driver init code needs them. ++ * ++ * Drivers for SPI devices started out like those for platform bus ++ * devices. But both have changed in 2.6.15; maybe this should get ++ * an "spi_driver" structure at some point (not currently needed) ++ */ ++static void spidev_release(struct device *dev) ++{ ++ const struct spi_device *spi = to_spi_device(dev); ++ ++ /* spi masters may cleanup for released devices */ ++ if (spi->master->cleanup) ++ spi->master->cleanup(spi); ++ ++ class_device_put(&spi->master->cdev); ++ kfree(dev); ++} ++ ++static ssize_t ++modalias_show(struct device *dev, struct device_attribute *a, char *buf) ++{ ++ const struct spi_device *spi = to_spi_device(dev); ++ ++ return snprintf(buf, BUS_ID_SIZE + 1, "%s\n", spi->modalias); ++} ++ ++static struct device_attribute spi_dev_attrs[] = { ++ __ATTR_RO(modalias), ++ __ATTR_NULL, ++}; ++ ++/* modalias support makes "modprobe $MODALIAS" new-style hotplug work, ++ * and the sysfs version makes coldplug work too. ++ */ ++ ++static int spi_match_device(struct device *dev, struct device_driver *drv) ++{ ++ const struct spi_device *spi = to_spi_device(dev); ++ ++ return strncmp(spi->modalias, drv->name, BUS_ID_SIZE) == 0; ++} ++ ++static int spi_uevent(struct device *dev, char **envp, int num_envp, ++ char *buffer, int buffer_size) ++{ ++ const struct spi_device *spi = to_spi_device(dev); ++ ++ envp[0] = buffer; ++ snprintf(buffer, buffer_size, "MODALIAS=%s", spi->modalias); ++ envp[1] = NULL; ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++ ++/* Suspend/resume in "struct device_driver" don't really need that ++ * strange third parameter, so we just make it a constant and expect ++ * SPI drivers to ignore it just like most platform drivers do. ++ * ++ * NOTE: the suspend() method for an spi_master controller driver ++ * should verify that all its child devices are marked as suspended; ++ * suspend requests delivered through sysfs power/state files don't ++ * enforce such constraints. ++ */ ++static int spi_suspend(struct device *dev, pm_message_t message) ++{ ++ int value; ++ ++ if (!dev->driver || !dev->driver->suspend) ++ return 0; ++ ++ /* suspend will stop irqs and dma; no more i/o */ ++ value = dev->driver->suspend(dev, message); ++ if (value == 0) ++ dev->power.power_state = message; ++ return value; ++} ++ ++static int spi_resume(struct device *dev) ++{ ++ int value; ++ ++ if (!dev->driver || !dev->driver->resume) ++ return 0; ++ ++ /* resume may restart the i/o queue */ ++ value = dev->driver->resume(dev); ++ if (value == 0) ++ dev->power.power_state = PMSG_ON; ++ return value; ++} ++ ++#else ++#define spi_suspend NULL ++#define spi_resume NULL ++#endif ++ ++struct bus_type spi_bus_type = { ++ .name = "spi", ++ .dev_attrs = spi_dev_attrs, ++ .match = spi_match_device, ++ .uevent = spi_uevent, ++ .suspend = spi_suspend, ++ .resume = spi_resume, ++}; ++EXPORT_SYMBOL_GPL(spi_bus_type); ++ ++/*-------------------------------------------------------------------------*/ ++ ++/* SPI devices should normally not be created by SPI device drivers; that ++ * would make them board-specific. Similarly with SPI master drivers. ++ * Device registration normally goes into like arch/.../mach.../board-YYY.c ++ * with other readonly (flashable) information about mainboard devices. ++ */ ++ ++struct boardinfo { ++ struct list_head list; ++ unsigned n_board_info; ++ struct spi_board_info board_info[0]; ++}; ++ ++static LIST_HEAD(board_list); ++static DECLARE_MUTEX(board_lock); ++ ++ ++/* On typical mainboards, this is purely internal; and it's not needed ++ * after board init creates the hard-wired devices. Some development ++ * platforms may not be able to use spi_register_board_info though, and ++ * this is exported so that for example a USB or parport based adapter ++ * driver could add devices (which it would learn about out-of-band). ++ */ ++struct spi_device *__init_or_module ++spi_new_device(struct spi_master *master, struct spi_board_info *chip) ++{ ++ struct spi_device *proxy; ++ struct device *dev = master->cdev.dev; ++ int status; ++ ++ /* NOTE: caller did any chip->bus_num checks necessary */ ++ ++ if (!class_device_get(&master->cdev)) ++ return NULL; ++ ++ proxy = kzalloc(sizeof *proxy, GFP_KERNEL); ++ if (!proxy) { ++ dev_err(dev, "can't alloc dev for cs%d\n", ++ chip->chip_select); ++ goto fail; ++ } ++ proxy->master = master; ++ proxy->chip_select = chip->chip_select; ++ proxy->max_speed_hz = chip->max_speed_hz; ++ proxy->irq = chip->irq; ++ proxy->modalias = chip->modalias; ++ ++ snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id, ++ "%s.%u", master->cdev.class_id, ++ chip->chip_select); ++ proxy->dev.parent = dev; ++ proxy->dev.bus = &spi_bus_type; ++ proxy->dev.platform_data = (void *) chip->platform_data; ++ proxy->controller_data = chip->controller_data; ++ proxy->controller_state = NULL; ++ proxy->dev.release = spidev_release; ++ ++ /* drivers may modify this default i/o setup */ ++ status = master->setup(proxy); ++ if (status < 0) { ++ dev_dbg(dev, "can't %s %s, status %d\n", ++ "setup", proxy->dev.bus_id, status); ++ goto fail; ++ } ++ ++ /* driver core catches callers that misbehave by defining ++ * devices that already exist. ++ */ ++ status = device_register(&proxy->dev); ++ if (status < 0) { ++ dev_dbg(dev, "can't %s %s, status %d\n", ++ "add", proxy->dev.bus_id, status); ++fail: ++ class_device_put(&master->cdev); ++ kfree(proxy); ++ return NULL; ++ } ++ dev_dbg(dev, "registered child %s\n", proxy->dev.bus_id); ++ return proxy; ++} ++EXPORT_SYMBOL_GPL(spi_new_device); ++ ++/* ++ * Board-specific early init code calls this (probably during arch_initcall) ++ * with segments of the SPI device table. Any device nodes are created later, ++ * after the relevant parent SPI controller (bus_num) is defined. We keep ++ * this table of devices forever, so that reloading a controller driver will ++ * not make Linux forget about these hard-wired devices. ++ * ++ * Other code can also call this, e.g. a particular add-on board might provide ++ * SPI devices through its expansion connector, so code initializing that board ++ * would naturally declare its SPI devices. ++ * ++ * The board info passed can safely be __initdata ... but be careful of ++ * any embedded pointers (platform_data, etc), they're copied as-is. ++ */ ++int __init ++spi_register_board_info(struct spi_board_info const *info, unsigned n) ++{ ++ struct boardinfo *bi; ++ ++ bi = kmalloc (sizeof (*bi) + n * sizeof (*info), GFP_KERNEL); ++ if (!bi) ++ return -ENOMEM; ++ bi->n_board_info = n; ++ memcpy(bi->board_info, info, n * sizeof (*info)); ++ ++ down(&board_lock); ++ list_add_tail(&bi->list, &board_list); ++ up(&board_lock); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(spi_register_board_info); ++ ++/* FIXME someone should add support for a __setup("spi", ...) that ++ * creates board info from kernel command lines ++ */ ++ ++static void __init_or_module ++scan_boardinfo(struct spi_master *master) ++{ ++ struct boardinfo *bi; ++ struct device *dev = master->cdev.dev; ++ ++ down(&board_lock); ++ list_for_each_entry(bi, &board_list, list) { ++ struct spi_board_info *chip = bi->board_info; ++ unsigned n; ++ ++ for (n = bi->n_board_info; n > 0; n--, chip++) { ++ if (chip->bus_num != master->bus_num) ++ continue; ++ /* some controllers only have one chip, so they ++ * might not use chipselects. otherwise, the ++ * chipselects are numbered 0..max. ++ */ ++ if (chip->chip_select >= master->num_chipselect ++ && master->num_chipselect) { ++ dev_dbg(dev, "cs%d > max %d\n", ++ chip->chip_select, ++ master->num_chipselect); ++ continue; ++ } ++ (void) spi_new_device(master, chip); ++ } ++ } ++ up(&board_lock); ++} ++ ++/*-------------------------------------------------------------------------*/ ++ ++static void spi_master_release(struct class_device *cdev) ++{ ++ struct spi_master *master; ++ ++ master = container_of(cdev, struct spi_master, cdev); ++ put_device(master->cdev.dev); ++ master->cdev.dev = NULL; ++ kfree(master); ++} ++ ++static struct class spi_master_class = { ++ .name = "spi_master", ++ .owner = THIS_MODULE, ++ .release = spi_master_release, ++}; ++ ++ ++/** ++ * spi_alloc_master - allocate SPI master controller ++ * @dev: the controller, possibly using the platform_bus ++ * @size: how much driver-private data to preallocate; a pointer to this ++ * memory in the class_data field of the returned class_device ++ * ++ * This call is used only by SPI master controller drivers, which are the ++ * only ones directly touching chip registers. It's how they allocate ++ * an spi_master structure, prior to calling spi_add_master(). ++ * ++ * This must be called from context that can sleep. It returns the SPI ++ * master structure on success, else NULL. ++ * ++ * The caller is responsible for assigning the bus number and initializing ++ * the master's methods before calling spi_add_master(), or else (on error) ++ * calling class_device_put() to prevent a memory leak. ++ */ ++struct spi_master * __init_or_module ++spi_alloc_master(struct device *dev, unsigned size) ++{ ++ struct spi_master *master; ++ ++ master = kzalloc(size + sizeof *master, SLAB_KERNEL); ++ if (!master) ++ return NULL; ++ ++ master->cdev.class = &spi_master_class; ++ master->cdev.dev = get_device(dev); ++ class_set_devdata(&master->cdev, &master[1]); ++ ++ return master; ++} ++EXPORT_SYMBOL_GPL(spi_alloc_master); ++ ++/** ++ * spi_register_master - register SPI master controller ++ * @master: initialized master, originally from spi_alloc_master() ++ * ++ * SPI master controllers connect to their drivers using some non-SPI bus, ++ * such as the platform bus. The final stage of probe() in that code ++ * includes calling spi_register_master() to hook up to this SPI bus glue. ++ * ++ * SPI controllers use board specific (often SOC specific) bus numbers, ++ * and board-specific addressing for SPI devices combines those numbers ++ * with chip select numbers. Since SPI does not directly support dynamic ++ * device identification, boards need configuration tables telling which ++ * chip is at which address. ++ * ++ * This must be called from context that can sleep. It returns zero on ++ * success, else a negative error code (dropping the master's refcount). ++ */ ++int __init_or_module ++spi_register_master(struct spi_master *master) ++{ ++ static atomic_t dyn_bus_id = ATOMIC_INIT(0); ++ struct device *dev = master->cdev.dev; ++ int status = -ENODEV; ++ int dynamic = 0; ++ ++ /* convention: dynamically assigned bus IDs count down from the max */ ++ if (master->bus_num == 0) { ++ master->bus_num = atomic_dec_return(&dyn_bus_id); ++ dynamic = 0; ++ } ++ ++ /* register the device, then userspace will see it. ++ * registration fails if the bus ID is in use. ++ */ ++ snprintf(master->cdev.class_id, sizeof master->cdev.class_id, ++ "spi%u", master->bus_num); ++ status = class_device_register(&master->cdev); ++ if (status < 0) { ++ class_device_put(&master->cdev); ++ goto done; ++ } ++ dev_dbg(dev, "registered master %s%s\n", master->cdev.class_id, ++ dynamic ? " (dynamic)" : ""); ++ ++ /* populate children from any spi device tables */ ++ scan_boardinfo(master); ++ status = 0; ++done: ++ return status; ++} ++EXPORT_SYMBOL_GPL(spi_register_master); ++ ++ ++static int __unregister(struct device *dev, void *unused) ++{ ++ /* note: before about 2.6.14-rc1 this would corrupt memory: */ ++ device_unregister(dev); ++ return 0; ++} ++ ++/** ++ * spi_unregister_master - unregister SPI master controller ++ * @master: the master being unregistered ++ * ++ * This call is used only by SPI master controller drivers, which are the ++ * only ones directly touching chip registers. ++ * ++ * This must be called from context that can sleep. ++ */ ++void spi_unregister_master(struct spi_master *master) ++{ ++ class_device_unregister(&master->cdev); ++ (void) device_for_each_child(master->cdev.dev, NULL, __unregister); ++} ++EXPORT_SYMBOL_GPL(spi_unregister_master); ++ ++/** ++ * spi_busnum_to_master - look up master associated with bus_num ++ * @bus_num: the master's bus number ++ * ++ * This call may be used with devices that are registered after ++ * arch init time. It returns a refcounted pointer to the relevant ++ * spi_master (which the caller must release), or NULL if there is ++ * no such master registered. ++ */ ++struct spi_master *spi_busnum_to_master(u16 bus_num) ++{ ++ if (bus_num) { ++ char name[8]; ++ struct kobject *bus; ++ ++ snprintf(name, sizeof name, "spi%u", bus_num); ++ bus = kset_find_obj(&spi_master_class.subsys.kset, name); ++ if (bus) ++ return container_of(bus, struct spi_master, cdev.kobj); ++ } ++ return NULL; ++} ++EXPORT_SYMBOL_GPL(spi_busnum_to_master); ++ ++ ++/*-------------------------------------------------------------------------*/ ++ ++/** ++ * spi_sync - blocking/synchronous SPI data transfers ++ * @spi: device with which data will be exchanged ++ * @message: describes the data transfers ++ * ++ * This call may only be used from a context that may sleep. The sleep ++ * is non-interruptible, and has no timeout. Low-overhead controller ++ * drivers may DMA directly into and out of the message buffers. ++ * ++ * Note that the SPI device's chip select is active during the message, ++ * and then is normally disabled between messages. Drivers for some ++ * frequently-used devices may want to minimize costs of selecting a chip, ++ * by leaving it selected in anticipation that the next message will go ++ * to the same chip. (That may increase power usage.) ++ * ++ * The return value is a negative error code if the message could not be ++ * submitted, else zero. When the value is zero, then message->status is ++ * also defined: it's the completion code for the transfer, either zero ++ * or a negative error code from the controller driver. ++ */ ++int spi_sync(struct spi_device *spi, struct spi_message *message) ++{ ++ DECLARE_COMPLETION(done); ++ int status; ++ ++ message->complete = (void (*)(void *)) complete; ++ message->context = &done; ++ status = spi_async(spi, message); ++ if (status == 0) ++ wait_for_completion(&done); ++ message->context = NULL; ++ return status; ++} ++EXPORT_SYMBOL_GPL(spi_sync); ++ ++#define SPI_BUFSIZ (SMP_CACHE_BYTES) ++ ++static u8 *buf; ++ ++/** ++ * spi_write_then_read - SPI synchronous write followed by read ++ * @spi: device with which data will be exchanged ++ * @txbuf: data to be written (need not be dma-safe) ++ * @n_tx: size of txbuf, in bytes ++ * @rxbuf: buffer into which data will be read ++ * @n_rx: size of rxbuf, in bytes (need not be dma-safe) ++ * ++ * This performs a half duplex MicroWire style transaction with the ++ * device, sending txbuf and then reading rxbuf. The return value ++ * is zero for success, else a negative errno status code. ++ * ++ * Parameters to this routine are always copied using a small buffer, ++ * large transfers should use use spi_{async,sync}() calls with ++ * dma-safe buffers. ++ */ ++int spi_write_then_read(struct spi_device *spi, ++ const u8 *txbuf, unsigned n_tx, ++ u8 *rxbuf, unsigned n_rx) ++{ ++ static DECLARE_MUTEX(lock); ++ ++ int status; ++ struct spi_message message; ++ struct spi_transfer x[2]; ++ u8 *local_buf; ++ ++ /* Use preallocated DMA-safe buffer. We can't avoid copying here, ++ * (as a pure convenience thing), but we can keep heap costs ++ * out of the hot path ... ++ */ ++ if ((n_tx + n_rx) > SPI_BUFSIZ) ++ return -EINVAL; ++ ++ /* ... unless someone else is using the pre-allocated buffer */ ++ if (down_trylock(&lock)) { ++ local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL); ++ if (!local_buf) ++ return -ENOMEM; ++ } else ++ local_buf = buf; ++ ++ memset(x, 0, sizeof x); ++ ++ memcpy(local_buf, txbuf, n_tx); ++ x[0].tx_buf = local_buf; ++ x[0].len = n_tx; ++ ++ x[1].rx_buf = local_buf + n_tx; ++ x[1].len = n_rx; ++ ++ /* do the i/o */ ++ message.transfers = x; ++ message.n_transfer = ARRAY_SIZE(x); ++ status = spi_sync(spi, &message); ++ if (status == 0) { ++ memcpy(rxbuf, x[1].rx_buf, n_rx); ++ status = message.status; ++ } ++ ++ if (x[0].tx_buf == buf) ++ up(&lock); ++ else ++ kfree(local_buf); ++ ++ return status; ++} ++EXPORT_SYMBOL_GPL(spi_write_then_read); ++ ++/*-------------------------------------------------------------------------*/ ++ ++static int __init spi_init(void) ++{ ++ buf = kmalloc(SPI_BUFSIZ, SLAB_KERNEL); ++ if (!buf) ++ return -ENOMEM; ++ ++ bus_register(&spi_bus_type); ++ class_register(&spi_master_class); ++ return 0; ++} ++/* board_info is normally registered in arch_initcall(), ++ * but even essential drivers wait till later ++ */ ++subsys_initcall(spi_init); ++ +--- /dev/null ++++ gregkh-2.6/include/linux/spi/spi.h +@@ -0,0 +1,542 @@ ++/* ++ * Copyright (C) 2005 David Brownell ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef __LINUX_SPI_H ++#define __LINUX_SPI_H ++ ++/* ++ * INTERFACES between SPI master drivers and infrastructure ++ * (There's no SPI slave support for Linux yet...) ++ * ++ * A "struct device_driver" for an spi_device uses "spi_bus_type" and ++ * needs no special API wrappers (much like platform_bus). These drivers ++ * are bound to devices based on their names (much like platform_bus), ++ * and are available in dev->driver. ++ */ ++extern struct bus_type spi_bus_type; ++ ++/** ++ * struct spi_device - Master side proxy for an SPI slave device ++ * @dev: Driver model representation of the device. ++ * @master: SPI controller used with the device. ++ * @max_speed_hz: Maximum clock rate to be used with this chip ++ * (on this board); may be changed by the device's driver. ++ * @chip-select: Chipselect, distinguishing chips handled by "master". ++ * @mode: The spi mode defines how data is clocked out and in. ++ * This may be changed by the device's driver. ++ * @bits_per_word: Data transfers involve one or more words; word sizes ++ * like eight or 12 bits are common. In-memory wordsizes are ++ * powers of two bytes (e.g. 20 bit samples use 32 bits). ++ * This may be changed by the device's driver. ++ * @irq: Negative, or the number passed to request_irq() to receive ++ * interrupts from this device. ++ * @controller_state: Controller's runtime state ++ * @controller_data: Static board-specific definitions for controller, such ++ * as FIFO initialization parameters; from board_info.controller_data ++ * ++ * An spi_device is used to interchange data between an SPI slave ++ * (usually a discrete chip) and CPU memory. ++ * ++ * In "dev", the platform_data is used to hold information about this ++ * device that's meaningful to the device's protocol driver, but not ++ * to its controller. One example might be an identifier for a chip ++ * variant with slightly different functionality. ++ */ ++struct spi_device { ++ struct device dev; ++ struct spi_master *master; ++ u32 max_speed_hz; ++ u8 chip_select; ++ u8 mode; ++#define SPI_CPHA 0x01 /* clock phase */ ++#define SPI_CPOL 0x02 /* clock polarity */ ++#define SPI_MODE_0 (0|0) ++#define SPI_MODE_1 (0|SPI_CPHA) ++#define SPI_MODE_2 (SPI_CPOL|0) ++#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) ++#define SPI_CS_HIGH 0x04 /* chipselect active high? */ ++ u8 bits_per_word; ++ int irq; ++ void *controller_state; ++ const void *controller_data; ++ const char *modalias; ++ ++ // likely need more hooks for more protocol options affecting how ++ // the controller talks to its chips, like: ++ // - bit order (default is wordwise msb-first) ++ // - memory packing (12 bit samples into low bits, others zeroed) ++ // - priority ++ // - chipselect delays ++ // - ... ++}; ++ ++static inline struct spi_device *to_spi_device(struct device *dev) ++{ ++ return container_of(dev, struct spi_device, dev); ++} ++ ++/* most drivers won't need to care about device refcounting */ ++static inline struct spi_device *spi_dev_get(struct spi_device *spi) ++{ ++ return (spi && get_device(&spi->dev)) ? spi : NULL; ++} ++ ++static inline void spi_dev_put(struct spi_device *spi) ++{ ++ if (spi) ++ put_device(&spi->dev); ++} ++ ++/* ctldata is for the bus_master driver's runtime state */ ++static inline void *spi_get_ctldata(struct spi_device *spi) ++{ ++ return spi->controller_state; ++} ++ ++static inline void spi_set_ctldata(struct spi_device *spi, void *state) ++{ ++ spi->controller_state = state; ++} ++ ++ ++struct spi_message; ++ ++ ++/** ++ * struct spi_master - interface to SPI master controller ++ * @cdev: class interface to this driver ++ * @bus_num: board-specific (and often SOC-specific) identifier for a ++ * given SPI controller. ++ * @num_chipselects: chipselects are used to distinguish individual ++ * SPI slaves, and are numbered from zero to num_chipselects. ++ * each slave has a chipselect signal, but it's common that not ++ * every chipselect is connected to a slave. ++ * @setup: updates the device mode and clocking records used by a ++ * device's SPI controller; protocol code may call this. ++ * @transfer: adds a message to the controller's transfer queue. ++ * @cleanup: frees controller-specific state ++ * ++ * Each SPI master controller can communicate with one or more spi_device ++ * children. These make a small bus, sharing MOSI, MISO and SCK signals ++ * but not chip select signals. Each device may be configured to use a ++ * different clock rate, since those shared signals are ignored unless ++ * the chip is selected. ++ * ++ * The driver for an SPI controller manages access to those devices through ++ * a queue of spi_message transactions, copyin data between CPU memory and ++ * an SPI slave device). For each such message it queues, it calls the ++ * message's completion function when the transaction completes. ++ */ ++struct spi_master { ++ struct class_device cdev; ++ ++ /* other than zero (== assign one dynamically), bus_num is fully ++ * board-specific. usually that simplifies to being SOC-specific. ++ * example: one SOC has three SPI controllers, numbered 1..3, ++ * and one board's schematics might show it using SPI-2. software ++ * would normally use bus_num=2 for that controller. ++ */ ++ u16 bus_num; ++ ++ /* chipselects will be integral to many controllers; some others ++ * might use board-specific GPIOs. ++ */ ++ u16 num_chipselect; ++ ++ /* setup mode and clock, etc (spi driver may call many times) */ ++ int (*setup)(struct spi_device *spi); ++ ++ /* bidirectional bulk transfers ++ * ++ * + The transfer() method may not sleep; its main role is ++ * just to add the message to the queue. ++ * + For now there's no remove-from-queue operation, or ++ * any other request management ++ * + To a given spi_device, message queueing is pure fifo ++ * ++ * + The master's main job is to process its message queue, ++ * selecting a chip then transferring data ++ * + If there are multiple spi_device children, the i/o queue ++ * arbitration algorithm is unspecified (round robin, fifo, ++ * priority, reservations, preemption, etc) ++ * ++ * + Chipselect stays active during the entire message ++ * (unless modified by spi_transfer.cs_change != 0). ++ * + The message transfers use clock and SPI mode parameters ++ * previously established by setup() for this device ++ */ ++ int (*transfer)(struct spi_device *spi, ++ struct spi_message *mesg); ++ ++ /* called on release() to free memory provided by spi_master */ ++ void (*cleanup)(const struct spi_device *spi); ++}; ++ ++/* the spi driver core manages memory for the spi_master classdev */ ++extern struct spi_master * ++spi_alloc_master(struct device *host, unsigned size); ++ ++extern int spi_register_master(struct spi_master *master); ++extern void spi_unregister_master(struct spi_master *master); ++ ++extern struct spi_master *spi_busnum_to_master(u16 busnum); ++ ++/*---------------------------------------------------------------------------*/ ++ ++/* ++ * I/O INTERFACE between SPI controller and protocol drivers ++ * ++ * Protocol drivers use a queue of spi_messages, each transferring data ++ * between the controller and memory buffers. ++ * ++ * The spi_messages themselves consist of a series of read+write transfer ++ * segments. Those segments always read the same number of bits as they ++ * write; but one or the other is easily ignored by passing a null buffer ++ * pointer. (This is unlike most types of I/O API, because SPI hardware ++ * is full duplex.) ++ * ++ * NOTE: Allocation of spi_transfer and spi_message memory is entirely ++ * up to the protocol driver, which guarantees the integrity of both (as ++ * well as the data buffers) for as long as the message is queued. ++ */ ++ ++/** ++ * struct spi_transfer - a read/write buffer pair ++ * @tx_buf: data to be written (dma-safe address), or NULL ++ * @rx_buf: data to be read (dma-safe address), or NULL ++ * @tx_dma: DMA address of buffer, if spi_message.is_dma_mapped ++ * @rx_dma: DMA address of buffer, if spi_message.is_dma_mapped ++ * @len: size of rx and tx buffers (in bytes) ++ * @cs_change: affects chipselect after this transfer completes ++ * @delay_usecs: microseconds to delay after this transfer before ++ * (optionally) changing the chipselect status, then starting ++ * the next transfer or completing this spi_message. ++ * ++ * SPI transfers always write the same number of bytes as they read. ++ * Protocol drivers should always provide rx_buf and/or tx_buf. ++ * In some cases, they may also want to provide DMA addresses for ++ * the data being transferred; that may reduce overhead, when the ++ * underlying driver uses dma. ++ * ++ * All SPI transfers start with the relevant chipselect active. Drivers ++ * can change behavior of the chipselect after the transfer finishes ++ * (including any mandatory delay). The normal behavior is to leave it ++ * selected, except for the last transfer in a message. Setting cs_change ++ * allows two additional behavior options: ++ * ++ * (i) If the transfer isn't the last one in the message, this flag is ++ * used to make the chipselect briefly go inactive in the middle of the ++ * message. Toggling chipselect in this way may be needed to terminate ++ * a chip command, letting a single spi_message perform all of group of ++ * chip transactions together. ++ * ++ * (ii) When the transfer is the last one in the message, the chip may ++ * stay selected until the next transfer. This is purely a performance ++ * hint; the controller driver may need to select a different device ++ * for the next message. ++ */ ++struct spi_transfer { ++ /* it's ok if tx_buf == rx_buf (right?) ++ * for MicroWire, one buffer must be null ++ * buffers must work with dma_*map_single() calls ++ */ ++ const void *tx_buf; ++ void *rx_buf; ++ unsigned len; ++ ++ dma_addr_t tx_dma; ++ dma_addr_t rx_dma; ++ ++ unsigned cs_change:1; ++ u16 delay_usecs; ++}; ++ ++/** ++ * struct spi_message - one multi-segment SPI transaction ++ * @transfers: the segements of the transaction ++ * @n_transfer: how many segments ++ * @spi: SPI device to which the transaction is queued ++ * @is_dma_mapped: if true, the caller provided both dma and cpu virtual ++ * addresses for each transfer buffer ++ * @complete: called to report transaction completions ++ * @context: the argument to complete() when it's called ++ * @actual_length: how many bytes were transferd ++ * @status: zero for success, else negative errno ++ * @queue: for use by whichever driver currently owns the message ++ * @state: for use by whichever driver currently owns the message ++ */ ++struct spi_message { ++ struct spi_transfer *transfers; ++ unsigned n_transfer; ++ ++ struct spi_device *spi; ++ ++ unsigned is_dma_mapped:1; ++ ++ /* REVISIT: we might want a flag affecting the behavior of the ++ * last transfer ... allowing things like "read 16 bit length L" ++ * immediately followed by "read L bytes". Basically imposing ++ * a specific message scheduling algorithm. ++ * ++ * Some controller drivers (message-at-a-time queue processing) ++ * could provide that as their default scheduling algorithm. But ++ * others (with multi-message pipelines) would need a flag to ++ * tell them about such special cases. ++ */ ++ ++ /* completion is reported through a callback */ ++ void FASTCALL((*complete)(void *context)); ++ void *context; ++ unsigned actual_length; ++ int status; ++ ++ /* for optional use by whatever driver currently owns the ++ * spi_message ... between calls to spi_async and then later ++ * complete(), that's the spi_master controller driver. ++ */ ++ struct list_head queue; ++ void *state; ++}; ++ ++/** ++ * spi_setup -- setup SPI mode and clock rate ++ * @spi: the device whose settings are being modified ++ * ++ * SPI protocol drivers may need to update the transfer mode if the ++ * device doesn't work with the mode 0 default. They may likewise need ++ * to update clock rates or word sizes from initial values. This function ++ * changes those settings, and must be called from a context that can sleep. ++ */ ++static inline int ++spi_setup(struct spi_device *spi) ++{ ++ return spi->master->setup(spi); ++} ++ ++ ++/** ++ * spi_async -- asynchronous SPI transfer ++ * @spi: device with which data will be exchanged ++ * @message: describes the data transfers, including completion callback ++ * ++ * This call may be used in_irq and other contexts which can't sleep, ++ * as well as from task contexts which can sleep. ++ * ++ * The completion callback is invoked in a context which can't sleep. ++ * Before that invocation, the value of message->status is undefined. ++ * When the callback is issued, message->status holds either zero (to ++ * indicate complete success) or a negative error code. ++ * ++ * Note that although all messages to a spi_device are handled in ++ * FIFO order, messages may go to different devices in other orders. ++ * Some device might be higher priority, or have various "hard" access ++ * time requirements, for example. ++ */ ++static inline int ++spi_async(struct spi_device *spi, struct spi_message *message) ++{ ++ message->spi = spi; ++ return spi->master->transfer(spi, message); ++} ++ ++/*---------------------------------------------------------------------------*/ ++ ++/* All these synchronous SPI transfer routines are utilities layered ++ * over the core async transfer primitive. Here, "synchronous" means ++ * they will sleep uninterruptibly until the async transfer completes. ++ */ ++ ++extern int spi_sync(struct spi_device *spi, struct spi_message *message); ++ ++/** ++ * spi_write - SPI synchronous write ++ * @spi: device to which data will be written ++ * @buf: data buffer ++ * @len: data buffer size ++ * ++ * This writes the buffer and returns zero or a negative error code. ++ * Callable only from contexts that can sleep. ++ */ ++static inline int ++spi_write(struct spi_device *spi, const u8 *buf, size_t len) ++{ ++ struct spi_transfer t = { ++ .tx_buf = buf, ++ .rx_buf = NULL, ++ .len = len, ++ .cs_change = 0, ++ }; ++ struct spi_message m = { ++ .transfers = &t, ++ .n_transfer = 1, ++ }; ++ ++ return spi_sync(spi, &m); ++} ++ ++/** ++ * spi_read - SPI synchronous read ++ * @spi: device from which data will be read ++ * @buf: data buffer ++ * @len: data buffer size ++ * ++ * This writes the buffer and returns zero or a negative error code. ++ * Callable only from contexts that can sleep. ++ */ ++static inline int ++spi_read(struct spi_device *spi, u8 *buf, size_t len) ++{ ++ struct spi_transfer t = { ++ .tx_buf = NULL, ++ .rx_buf = buf, ++ .len = len, ++ .cs_change = 0, ++ }; ++ struct spi_message m = { ++ .transfers = &t, ++ .n_transfer = 1, ++ }; ++ ++ return spi_sync(spi, &m); ++} ++ ++extern int spi_write_then_read(struct spi_device *spi, ++ const u8 *txbuf, unsigned n_tx, ++ u8 *rxbuf, unsigned n_rx); ++ ++/** ++ * spi_w8r8 - SPI synchronous 8 bit write followed by 8 bit read ++ * @spi: device with which data will be exchanged ++ * @cmd: command to be written before data is read back ++ * ++ * This returns the (unsigned) eight bit number returned by the ++ * device, or else a negative error code. Callable only from ++ * contexts that can sleep. ++ */ ++static inline ssize_t spi_w8r8(struct spi_device *spi, u8 cmd) ++{ ++ ssize_t status; ++ u8 result; ++ ++ status = spi_write_then_read(spi, &cmd, 1, &result, 1); ++ ++ /* return negative errno or unsigned value */ ++ return (status < 0) ? status : result; ++} ++ ++/** ++ * spi_w8r16 - SPI synchronous 8 bit write followed by 16 bit read ++ * @spi: device with which data will be exchanged ++ * @cmd: command to be written before data is read back ++ * ++ * This returns the (unsigned) sixteen bit number returned by the ++ * device, or else a negative error code. Callable only from ++ * contexts that can sleep. ++ * ++ * The number is returned in wire-order, which is at least sometimes ++ * big-endian. ++ */ ++static inline ssize_t spi_w8r16(struct spi_device *spi, u8 cmd) ++{ ++ ssize_t status; ++ u16 result; ++ ++ status = spi_write_then_read(spi, &cmd, 1, (u8 *) &result, 2); ++ ++ /* return negative errno or unsigned value */ ++ return (status < 0) ? status : result; ++} ++ ++/*---------------------------------------------------------------------------*/ ++ ++/* ++ * INTERFACE between board init code and SPI infrastructure. ++ * ++ * No SPI driver ever sees these SPI device table segments, but ++ * it's how the SPI core (or adapters that get hotplugged) grows ++ * the driver model tree. ++ * ++ * As a rule, SPI devices can't be probed. Instead, board init code ++ * provides a table listing the devices which are present, with enough ++ * information to bind and set up the device's driver. There's basic ++ * support for nonstatic configurations too; enough to handle adding ++ * parport adapters, or microcontrollers acting as USB-to-SPI bridges. ++ */ ++ ++/* board-specific information about each SPI device */ ++struct spi_board_info { ++ /* the device name and module name are coupled, like platform_bus; ++ * "modalias" is normally the driver name. ++ * ++ * platform_data goes to spi_device.dev.platform_data, ++ * controller_data goes to spi_device.platform_data, ++ * irq is copied too ++ */ ++ char modalias[KOBJ_NAME_LEN]; ++ const void *platform_data; ++ const void *controller_data; ++ int irq; ++ ++ /* slower signaling on noisy or low voltage boards */ ++ u32 max_speed_hz; ++ ++ ++ /* bus_num is board specific and matches the bus_num of some ++ * spi_master that will probably be registered later. ++ * ++ * chip_select reflects how this chip is wired to that master; ++ * it's less than num_chipselect. ++ */ ++ u16 bus_num; ++ u16 chip_select; ++ ++ /* ... may need additional spi_device chip config data here. ++ * avoid stuff protocol drivers can set; but include stuff ++ * needed to behave without being bound to a driver: ++ * - chipselect polarity ++ * - quirks like clock rate mattering when not selected ++ */ ++}; ++ ++#ifdef CONFIG_SPI ++extern int ++spi_register_board_info(struct spi_board_info const *info, unsigned n); ++#else ++/* board init code may ignore whether SPI is configured or not */ ++static inline int ++spi_register_board_info(struct spi_board_info const *info, unsigned n) ++ { return 0; } ++#endif ++ ++ ++/* If you're hotplugging an adapter with devices (parport, usb, etc) ++ * use spi_new_device() to describe each device. You can also call ++ * spi_unregister_device() to get start making that device vanish, ++ * but normally that would be handled by spi_unregister_master(). ++ */ ++extern struct spi_device * ++spi_new_device(struct spi_master *, struct spi_board_info *); ++ ++static inline void ++spi_unregister_device(struct spi_device *spi) ++{ ++ if (spi) ++ device_unregister(&spi->dev); ++} ++ ++#endif /* __LINUX_SPI_H */ diff --git a/driver/spi-use-linked-lists-rather-than-an-array.patch b/driver/spi-use-linked-lists-rather-than-an-array.patch new file mode 100644 index 0000000000000..2df3c2346ed34 --- /dev/null +++ b/driver/spi-use-linked-lists-rather-than-an-array.patch @@ -0,0 +1,679 @@ +From akpm@osdl.org Sun Jan 8 13:38:59 2006 +From: akpm@osdl.org +Message-Id: <200601082134.k08LYe8T004585@shell0.pdx.osdl.net> +Subject: [patch 09/10] spi: use linked lists rather than an array +To: greg@kroah.com +Cc: akpm@osdl.org, vwool@ru.mvista.com, dbrownell@users.sourceforge.net, dpervushin@gmail.com +Date: Sun, 08 Jan 2006 13:34:28 -0800 + + +From: Vitaly Wool <vwool@ru.mvista.com> + +This makes the SPI core and its users access transfers in the SPI message +structure as linked list not as an array, as discussed on LKML. + +From: David Brownell <dbrownell@users.sourceforge.net> + + Updates including doc, bugfixes to the list code, add + spi_message_add_tail(). Plus, initialize things _before_ grabbing the + locks in some cases (in case it grows more expensive). This also merges + some bitbang updates of mine that didn't yet make it into the mm tree. + +Signed-off-by: Vitaly Wool <vwool@ru.mvista.com> +Signed-off-by: Dmitry Pervushin <dpervushin@gmail.com> +Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Andrew Morton <akpm@osdl.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> +--- + drivers/input/touchscreen/ads7846.c | 12 +++- + drivers/mtd/devices/m25p80.c | 50 +++++++++---------- + drivers/mtd/devices/mtd_dataflash.c | 28 ++++++---- + drivers/spi/spi.c | 18 ++++--- + drivers/spi/spi_bitbang.c | 86 +++++++++++++++++++-------------- + include/linux/spi/spi.h | 92 ++++++++++++++++++++++++------------ + include/linux/spi/spi_bitbang.h | 7 ++ + 7 files changed, 180 insertions(+), 113 deletions(-) + +--- gregkh-2.6.orig/drivers/input/touchscreen/ads7846.c ++++ gregkh-2.6/drivers/input/touchscreen/ads7846.c +@@ -155,10 +155,13 @@ static int ads7846_read12_ser(struct dev + struct ser_req *req = kzalloc(sizeof *req, SLAB_KERNEL); + int status; + int sample; ++ int i; + + if (!req) + return -ENOMEM; + ++ INIT_LIST_HEAD(&req->msg.transfers); ++ + /* activate reference, so it has time to settle; */ + req->xfer[0].tx_buf = &ref_on; + req->xfer[0].len = 1; +@@ -192,8 +195,8 @@ static int ads7846_read12_ser(struct dev + /* group all the transfers together, so we can't interfere with + * reading touchscreen state; disable penirq while sampling + */ +- req->msg.transfers = req->xfer; +- req->msg.n_transfer = 6; ++ for (i = 0; i < 6; i++) ++ spi_message_add_tail(&req->xfer[i], &req->msg); + + disable_irq(spi->irq); + status = spi_sync(spi, &req->msg); +@@ -398,6 +401,7 @@ static int __devinit ads7846_probe(struc + struct ads7846 *ts; + struct ads7846_platform_data *pdata = spi->dev.platform_data; + struct spi_transfer *x; ++ int i; + + if (!spi->irq) { + dev_dbg(&spi->dev, "no IRQ?\n"); +@@ -500,8 +504,8 @@ static int __devinit ads7846_probe(struc + + CS_CHANGE(x[-1]); + +- ts->msg.transfers = ts->xfer; +- ts->msg.n_transfer = x - ts->xfer; ++ for (i = 0; i < x - ts->xfer; i++) ++ spi_message_add_tail(&ts->xfer[i], &ts->msg); + ts->msg.complete = ads7846_rx; + ts->msg.context = ts; + +--- gregkh-2.6.orig/drivers/mtd/devices/m25p80.c ++++ gregkh-2.6/drivers/mtd/devices/m25p80.c +@@ -245,6 +245,21 @@ static int m25p80_read(struct mtd_info * + if (from + len > flash->mtd.size) + return -EINVAL; + ++ spi_message_init(&m); ++ memset(t, 0, (sizeof t)); ++ ++ t[0].tx_buf = flash->command; ++ t[0].len = sizeof(flash->command); ++ spi_message_add_tail(&t[0], &m); ++ ++ t[1].rx_buf = buf; ++ t[1].len = len; ++ spi_message_add_tail(&t[1], &m); ++ ++ /* Byte count starts at zero. */ ++ if (retlen) ++ *retlen = 0; ++ + down(&flash->lock); + + /* Wait till previous write/erase is done. */ +@@ -254,8 +269,6 @@ static int m25p80_read(struct mtd_info * + return 1; + } + +- memset(t, 0, (sizeof t)); +- + /* NOTE: OPCODE_FAST_READ (if available) is faster... */ + + /* Set up the write data buffer. */ +@@ -264,19 +277,6 @@ static int m25p80_read(struct mtd_info * + flash->command[2] = from >> 8; + flash->command[3] = from; + +- /* Byte count starts at zero. */ +- if (retlen) +- *retlen = 0; +- +- t[0].tx_buf = flash->command; +- t[0].len = sizeof(flash->command); +- +- t[1].rx_buf = buf; +- t[1].len = len; +- +- m.transfers = t; +- m.n_transfer = 2; +- + spi_sync(flash->spi, &m); + + *retlen = m.actual_length - sizeof(flash->command); +@@ -313,6 +313,16 @@ static int m25p80_write(struct mtd_info + if (to + len > flash->mtd.size) + return -EINVAL; + ++ spi_message_init(&m); ++ memset(t, 0, (sizeof t)); ++ ++ t[0].tx_buf = flash->command; ++ t[0].len = sizeof(flash->command); ++ spi_message_add_tail(&t[0], &m); ++ ++ t[1].tx_buf = buf; ++ spi_message_add_tail(&t[1], &m); ++ + down(&flash->lock); + + /* Wait until finished previous write command. */ +@@ -321,26 +331,17 @@ static int m25p80_write(struct mtd_info + + write_enable(flash); + +- memset(t, 0, (sizeof t)); +- + /* Set up the opcode in the write buffer. */ + flash->command[0] = OPCODE_PP; + flash->command[1] = to >> 16; + flash->command[2] = to >> 8; + flash->command[3] = to; + +- t[0].tx_buf = flash->command; +- t[0].len = sizeof(flash->command); +- +- m.transfers = t; +- m.n_transfer = 2; +- + /* what page do we start with? */ + page_offset = to % FLASH_PAGESIZE; + + /* do all the bytes fit onto one page? */ + if (page_offset + len <= FLASH_PAGESIZE) { +- t[1].tx_buf = buf; + t[1].len = len; + + spi_sync(flash->spi, &m); +@@ -352,7 +353,6 @@ static int m25p80_write(struct mtd_info + /* the size of data remaining on the first page */ + page_size = FLASH_PAGESIZE - page_offset; + +- t[1].tx_buf = buf; + t[1].len = page_size; + spi_sync(flash->spi, &m); + +--- gregkh-2.6.orig/drivers/mtd/devices/mtd_dataflash.c ++++ gregkh-2.6/drivers/mtd/devices/mtd_dataflash.c +@@ -147,7 +147,7 @@ static int dataflash_erase(struct mtd_in + { + struct dataflash *priv = (struct dataflash *)mtd->priv; + struct spi_device *spi = priv->spi; +- struct spi_transfer x[1] = { { .tx_dma = 0, }, }; ++ struct spi_transfer x = { .tx_dma = 0, }; + struct spi_message msg; + unsigned blocksize = priv->page_size << 3; + u8 *command; +@@ -162,10 +162,11 @@ static int dataflash_erase(struct mtd_in + || (instr->addr % priv->page_size) != 0) + return -EINVAL; + +- x[0].tx_buf = command = priv->command; +- x[0].len = 4; +- msg.transfers = x; +- msg.n_transfer = 1; ++ spi_message_init(&msg); ++ ++ x.tx_buf = command = priv->command; ++ x.len = 4; ++ spi_message_add_tail(&x, &msg); + + down(&priv->lock); + while (instr->len > 0) { +@@ -256,12 +257,15 @@ static int dataflash_read(struct mtd_inf + DEBUG(MTD_DEBUG_LEVEL3, "READ: (%x) %x %x %x\n", + command[0], command[1], command[2], command[3]); + ++ spi_message_init(&msg); ++ + x[0].tx_buf = command; + x[0].len = 8; ++ spi_message_add_tail(&x[0], &msg); ++ + x[1].rx_buf = buf; + x[1].len = len; +- msg.transfers = x; +- msg.n_transfer = 2; ++ spi_message_add_tail(&x[1], &msg); + + down(&priv->lock); + +@@ -320,9 +324,11 @@ static int dataflash_write(struct mtd_in + if ((to + len) > mtd->size) + return -EINVAL; + ++ spi_message_init(&msg); ++ + x[0].tx_buf = command = priv->command; + x[0].len = 4; +- msg.transfers = x; ++ spi_message_add_tail(&x[0], &msg); + + pageaddr = ((unsigned)to / priv->page_size); + offset = ((unsigned)to % priv->page_size); +@@ -364,7 +370,6 @@ static int dataflash_write(struct mtd_in + DEBUG(MTD_DEBUG_LEVEL3, "TRANSFER: (%x) %x %x %x\n", + command[0], command[1], command[2], command[3]); + +- msg.n_transfer = 1; + status = spi_sync(spi, &msg); + if (status < 0) + DEBUG(MTD_DEBUG_LEVEL1, "%s: xfer %u -> %d \n", +@@ -385,14 +390,16 @@ static int dataflash_write(struct mtd_in + + x[1].tx_buf = writebuf; + x[1].len = writelen; +- msg.n_transfer = 2; ++ spi_message_add_tail(x + 1, &msg); + status = spi_sync(spi, &msg); ++ spi_transfer_del(x + 1); + if (status < 0) + DEBUG(MTD_DEBUG_LEVEL1, "%s: pgm %u/%u -> %d \n", + spi->dev.bus_id, addr, writelen, status); + + (void) dataflash_waitready(priv->spi); + ++ + #ifdef CONFIG_DATAFLASH_WRITE_VERIFY + + /* (3) Compare to Buffer1 */ +@@ -405,7 +412,6 @@ static int dataflash_write(struct mtd_in + DEBUG(MTD_DEBUG_LEVEL3, "COMPARE: (%x) %x %x %x\n", + command[0], command[1], command[2], command[3]); + +- msg.n_transfer = 1; + status = spi_sync(spi, &msg); + if (status < 0) + DEBUG(MTD_DEBUG_LEVEL1, "%s: compare %u -> %d \n", +--- gregkh-2.6.orig/drivers/spi/spi_bitbang.c ++++ gregkh-2.6/drivers/spi/spi_bitbang.c +@@ -146,6 +146,9 @@ int spi_bitbang_setup(struct spi_device + struct spi_bitbang_cs *cs = spi->controller_state; + struct spi_bitbang *bitbang; + ++ if (!spi->max_speed_hz) ++ return -EINVAL; ++ + if (!cs) { + cs = kzalloc(sizeof *cs, SLAB_KERNEL); + if (!cs) +@@ -172,13 +175,8 @@ int spi_bitbang_setup(struct spi_device + if (!cs->txrx_word) + return -EINVAL; + +- if (!spi->max_speed_hz) +- spi->max_speed_hz = 500 * 1000; +- +- /* nsecs = max(50, (clock period)/2), be optimistic */ ++ /* nsecs = (clock period)/2 */ + cs->nsecs = (1000000000/2) / (spi->max_speed_hz); +- if (cs->nsecs < 50) +- cs->nsecs = 50; + if (cs->nsecs > MAX_UDELAY_MS * 1000) + return -EINVAL; + +@@ -194,7 +192,7 @@ int spi_bitbang_setup(struct spi_device + /* deselect chip (low or high) */ + spin_lock(&bitbang->lock); + if (!bitbang->busy) { +- bitbang->chipselect(spi, 0); ++ bitbang->chipselect(spi, BITBANG_CS_INACTIVE); + ndelay(cs->nsecs); + } + spin_unlock(&bitbang->lock); +@@ -244,9 +242,9 @@ static void bitbang_work(void *_bitbang) + struct spi_message *m; + struct spi_device *spi; + unsigned nsecs; +- struct spi_transfer *t; ++ struct spi_transfer *t = NULL; + unsigned tmp; +- unsigned chipselect; ++ unsigned cs_change; + int status; + + m = container_of(bitbang->queue.next, struct spi_message, +@@ -254,37 +252,49 @@ static void bitbang_work(void *_bitbang) + list_del_init(&m->queue); + spin_unlock_irqrestore(&bitbang->lock, flags); + +-// FIXME this is made-up +-nsecs = 100; ++ /* FIXME this is made-up ... the correct value is known to ++ * word-at-a-time bitbang code, and presumably chipselect() ++ * should enforce these requirements too? ++ */ ++ nsecs = 100; + + spi = m->spi; +- t = m->transfers; + tmp = 0; +- chipselect = 0; ++ cs_change = 1; + status = 0; + +- for (;;t++) { ++ list_for_each_entry (t, &m->transfers, transfer_list) { + if (bitbang->shutdown) { + status = -ESHUTDOWN; + break; + } + +- /* set up default clock polarity, and activate chip */ +- if (!chipselect) { +- bitbang->chipselect(spi, 1); ++ /* set up default clock polarity, and activate chip; ++ * this implicitly updates clock and spi modes as ++ * previously recorded for this device via setup(). ++ * (and also deselects any other chip that might be ++ * selected ...) ++ */ ++ if (cs_change) { ++ bitbang->chipselect(spi, BITBANG_CS_ACTIVE); + ndelay(nsecs); + } ++ cs_change = t->cs_change; + if (!t->tx_buf && !t->rx_buf && t->len) { + status = -EINVAL; + break; + } + +- /* transfer data */ ++ /* transfer data. the lower level code handles any ++ * new dma mappings it needs. our caller always gave ++ * us dma-safe buffers. ++ */ + if (t->len) { +- /* FIXME if bitbang->use_dma, dma_map_single() +- * before the transfer, and dma_unmap_single() +- * afterwards, for either or both buffers... ++ /* REVISIT dma API still needs a designated ++ * DMA_ADDR_INVALID; ~0 might be better. + */ ++ if (!m->is_dma_mapped) ++ t->rx_dma = t->tx_dma = 0; + status = bitbang->txrx_bufs(spi, t); + } + if (status != t->len) { +@@ -299,29 +309,31 @@ nsecs = 100; + if (t->delay_usecs) + udelay(t->delay_usecs); + +- tmp++; +- if (tmp >= m->n_transfer) +- break; +- +- chipselect = !t->cs_change; +- if (chipselect); ++ if (!cs_change) + continue; ++ if (t->transfer_list.next == &m->transfers) ++ break; + +- bitbang->chipselect(spi, 0); +- +- /* REVISIT do we want the udelay here instead? */ +- msleep(1); ++ /* sometimes a short mid-message deselect of the chip ++ * may be needed to terminate a mode or command ++ */ ++ ndelay(nsecs); ++ bitbang->chipselect(spi, BITBANG_CS_INACTIVE); ++ ndelay(nsecs); + } + +- tmp = m->n_transfer - 1; +- tmp = m->transfers[tmp].cs_change; +- + m->status = status; + m->complete(m->context); + +- ndelay(2 * nsecs); +- bitbang->chipselect(spi, status == 0 && tmp); +- ndelay(nsecs); ++ /* normally deactivate chipselect ... unless no error and ++ * cs_change has hinted that the next message will probably ++ * be for this chip too. ++ */ ++ if (!(status == 0 && cs_change)) { ++ ndelay(nsecs); ++ bitbang->chipselect(spi, BITBANG_CS_INACTIVE); ++ ndelay(nsecs); ++ } + + spin_lock_irqsave(&bitbang->lock, flags); + } +--- gregkh-2.6.orig/drivers/spi/spi.c ++++ gregkh-2.6/drivers/spi/spi.c +@@ -557,6 +557,17 @@ int spi_write_then_read(struct spi_devic + if ((n_tx + n_rx) > SPI_BUFSIZ) + return -EINVAL; + ++ spi_message_init(&message); ++ memset(x, 0, sizeof x); ++ if (n_tx) { ++ x[0].len = n_tx; ++ spi_message_add_tail(&x[0], &message); ++ } ++ if (n_rx) { ++ x[1].len = n_rx; ++ spi_message_add_tail(&x[1], &message); ++ } ++ + /* ... unless someone else is using the pre-allocated buffer */ + if (down_trylock(&lock)) { + local_buf = kmalloc(SPI_BUFSIZ, GFP_KERNEL); +@@ -565,18 +576,11 @@ int spi_write_then_read(struct spi_devic + } else + local_buf = buf; + +- memset(x, 0, sizeof x); +- + memcpy(local_buf, txbuf, n_tx); + x[0].tx_buf = local_buf; +- x[0].len = n_tx; +- + x[1].rx_buf = local_buf + n_tx; +- x[1].len = n_rx; + + /* do the i/o */ +- message.transfers = x; +- message.n_transfer = ARRAY_SIZE(x); + status = spi_sync(spi, &message); + if (status == 0) { + memcpy(rxbuf, x[1].rx_buf, n_rx); +--- gregkh-2.6.orig/include/linux/spi/spi_bitbang.h ++++ gregkh-2.6/include/linux/spi/spi_bitbang.h +@@ -31,8 +31,15 @@ struct spi_bitbang { + struct spi_master *master; + + void (*chipselect)(struct spi_device *spi, int is_on); ++#define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */ ++#define BITBANG_CS_INACTIVE 0 + ++ /* txrx_bufs() may handle dma mapping for transfers that don't ++ * already have one (transfer.{tx,rx}_dma is zero), or use PIO ++ */ + int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t); ++ ++ /* txrx_word[SPI_MODE_*]() just looks like a shift register */ + u32 (*txrx_word[4])(struct spi_device *spi, + unsigned nsecs, + u32 word, u8 bits); +--- gregkh-2.6.orig/include/linux/spi/spi.h ++++ gregkh-2.6/include/linux/spi/spi.h +@@ -263,15 +263,16 @@ extern struct spi_master *spi_busnum_to_ + + /** + * struct spi_transfer - a read/write buffer pair +- * @tx_buf: data to be written (dma-safe address), or NULL +- * @rx_buf: data to be read (dma-safe address), or NULL +- * @tx_dma: DMA address of buffer, if spi_message.is_dma_mapped +- * @rx_dma: DMA address of buffer, if spi_message.is_dma_mapped ++ * @tx_buf: data to be written (dma-safe memory), or NULL ++ * @rx_buf: data to be read (dma-safe memory), or NULL ++ * @tx_dma: DMA address of tx_buf, if spi_message.is_dma_mapped ++ * @rx_dma: DMA address of rx_buf, if spi_message.is_dma_mapped + * @len: size of rx and tx buffers (in bytes) + * @cs_change: affects chipselect after this transfer completes + * @delay_usecs: microseconds to delay after this transfer before + * (optionally) changing the chipselect status, then starting + * the next transfer or completing this spi_message. ++ * @transfer_list: transfers are sequenced through spi_message.transfers + * + * SPI transfers always write the same number of bytes as they read. + * Protocol drivers should always provide rx_buf and/or tx_buf. +@@ -279,11 +280,16 @@ extern struct spi_master *spi_busnum_to_ + * the data being transferred; that may reduce overhead, when the + * underlying driver uses dma. + * +- * All SPI transfers start with the relevant chipselect active. Drivers +- * can change behavior of the chipselect after the transfer finishes +- * (including any mandatory delay). The normal behavior is to leave it +- * selected, except for the last transfer in a message. Setting cs_change +- * allows two additional behavior options: ++ * If the transmit buffer is null, undefined data will be shifted out ++ * while filling rx_buf. If the receive buffer is null, the data ++ * shifted in will be discarded. Only "len" bytes shift out (or in). ++ * It's an error to try to shift out a partial word. (For example, by ++ * shifting out three bytes with word size of sixteen or twenty bits; ++ * the former uses two bytes per word, the latter uses four bytes.) ++ * ++ * All SPI transfers start with the relevant chipselect active. Normally ++ * it stays selected until after the last transfer in a message. Drivers ++ * can affect the chipselect signal using cs_change: + * + * (i) If the transfer isn't the last one in the message, this flag is + * used to make the chipselect briefly go inactive in the middle of the +@@ -299,7 +305,8 @@ extern struct spi_master *spi_busnum_to_ + * The code that submits an spi_message (and its spi_transfers) + * to the lower layers is responsible for managing its memory. + * Zero-initialize every field you don't set up explicitly, to +- * insulate against future API updates. ++ * insulate against future API updates. After you submit a message ++ * and its transfers, ignore them until its completion callback. + */ + struct spi_transfer { + /* it's ok if tx_buf == rx_buf (right?) +@@ -316,12 +323,13 @@ struct spi_transfer { + + unsigned cs_change:1; + u16 delay_usecs; ++ ++ struct list_head transfer_list; + }; + + /** + * struct spi_message - one multi-segment SPI transaction +- * @transfers: the segements of the transaction +- * @n_transfer: how many segments ++ * @transfers: list of transfer segments in this transaction + * @spi: SPI device to which the transaction is queued + * @is_dma_mapped: if true, the caller provided both dma and cpu virtual + * addresses for each transfer buffer +@@ -333,14 +341,22 @@ struct spi_transfer { + * @queue: for use by whichever driver currently owns the message + * @state: for use by whichever driver currently owns the message + * ++ * An spi_message is used to execute an atomic sequence of data transfers, ++ * each represented by a struct spi_transfer. The sequence is "atomic" ++ * in the sense that no other spi_message may use that SPI bus until that ++ * sequence completes. On some systems, many such sequences can execute as ++ * as single programmed DMA transfer. On all systems, these messages are ++ * queued, and might complete after transactions to other devices. Messages ++ * sent to a given spi_device are alway executed in FIFO order. ++ * + * The code that submits an spi_message (and its spi_transfers) + * to the lower layers is responsible for managing its memory. + * Zero-initialize every field you don't set up explicitly, to +- * insulate against future API updates. ++ * insulate against future API updates. After you submit a message ++ * and its transfers, ignore them until its completion callback. + */ + struct spi_message { +- struct spi_transfer *transfers; +- unsigned n_transfer; ++ struct list_head transfers; + + struct spi_device *spi; + +@@ -371,6 +387,24 @@ struct spi_message { + void *state; + }; + ++static inline void spi_message_init(struct spi_message *m) ++{ ++ memset(m, 0, sizeof *m); ++ INIT_LIST_HEAD(&m->transfers); ++} ++ ++static inline void ++spi_message_add_tail(struct spi_transfer *t, struct spi_message *m) ++{ ++ list_add_tail(&t->transfer_list, &m->transfers); ++} ++ ++static inline void ++spi_transfer_del(struct spi_transfer *t) ++{ ++ list_del(&t->transfer_list); ++} ++ + /* It's fine to embed message and transaction structures in other data + * structures so long as you don't free them while they're in use. + */ +@@ -383,8 +417,12 @@ static inline struct spi_message *spi_me + + ntrans * sizeof(struct spi_transfer), + flags); + if (m) { +- m->transfers = (void *)(m + 1); +- m->n_transfer = ntrans; ++ int i; ++ struct spi_transfer *t = (struct spi_transfer *)(m + 1); ++ ++ INIT_LIST_HEAD(&m->transfers); ++ for (i = 0; i < ntrans; i++, t++) ++ spi_message_add_tail(t, m); + } + return m; + } +@@ -402,6 +440,8 @@ static inline void spi_message_free(stru + * device doesn't work with the mode 0 default. They may likewise need + * to update clock rates or word sizes from initial values. This function + * changes those settings, and must be called from a context that can sleep. ++ * The changes take effect the next time the device is selected and data ++ * is transferred to or from it. + */ + static inline int + spi_setup(struct spi_device *spi) +@@ -468,15 +508,12 @@ spi_write(struct spi_device *spi, const + { + struct spi_transfer t = { + .tx_buf = buf, +- .rx_buf = NULL, + .len = len, +- .cs_change = 0, +- }; +- struct spi_message m = { +- .transfers = &t, +- .n_transfer = 1, + }; ++ struct spi_message m; + ++ spi_message_init(&m); ++ spi_message_add_tail(&t, &m); + return spi_sync(spi, &m); + } + +@@ -493,16 +530,13 @@ static inline int + spi_read(struct spi_device *spi, u8 *buf, size_t len) + { + struct spi_transfer t = { +- .tx_buf = NULL, + .rx_buf = buf, + .len = len, +- .cs_change = 0, +- }; +- struct spi_message m = { +- .transfers = &t, +- .n_transfer = 1, + }; ++ struct spi_message m; + ++ spi_message_init(&m); ++ spi_message_add_tail(&t, &m); + return spi_sync(spi, &m); + } + |