diff options
author | David Brownell <david-b@pacbell.net> | 2006-01-08 16:34:23 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-13 19:29:54 -0500 |
commit | b885244eb2628e0b8206e7edaaa6a314da78e9a4 (patch) | |
tree | e548fb3a94603c4a5406920c97246a78fe16b64a /include | |
parent | 1d6432fe10c3e724e307dd7137cd293a0edcae80 (diff) |
[PATCH] spi: add spi_driver to SPI framework
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>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/spi/spi.h | 75 |
1 files changed, 52 insertions, 23 deletions
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 51a6769114df..c851b3d13208 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h | |||
@@ -20,13 +20,8 @@ | |||
20 | #define __LINUX_SPI_H | 20 | #define __LINUX_SPI_H |
21 | 21 | ||
22 | /* | 22 | /* |
23 | * INTERFACES between SPI master drivers and infrastructure | 23 | * INTERFACES between SPI master-side drivers and SPI infrastructure. |
24 | * (There's no SPI slave support for Linux yet...) | 24 | * (There's no SPI slave support for Linux yet...) |
25 | * | ||
26 | * A "struct device_driver" for an spi_device uses "spi_bus_type" and | ||
27 | * needs no special API wrappers (much like platform_bus). These drivers | ||
28 | * are bound to devices based on their names (much like platform_bus), | ||
29 | * and are available in dev->driver. | ||
30 | */ | 25 | */ |
31 | extern struct bus_type spi_bus_type; | 26 | extern struct bus_type spi_bus_type; |
32 | 27 | ||
@@ -46,8 +41,8 @@ extern struct bus_type spi_bus_type; | |||
46 | * @irq: Negative, or the number passed to request_irq() to receive | 41 | * @irq: Negative, or the number passed to request_irq() to receive |
47 | * interrupts from this device. | 42 | * interrupts from this device. |
48 | * @controller_state: Controller's runtime state | 43 | * @controller_state: Controller's runtime state |
49 | * @controller_data: Static board-specific definitions for controller, such | 44 | * @controller_data: Board-specific definitions for controller, such as |
50 | * as FIFO initialization parameters; from board_info.controller_data | 45 | * FIFO initialization parameters; from board_info.controller_data |
51 | * | 46 | * |
52 | * An spi_device is used to interchange data between an SPI slave | 47 | * An spi_device is used to interchange data between an SPI slave |
53 | * (usually a discrete chip) and CPU memory. | 48 | * (usually a discrete chip) and CPU memory. |
@@ -63,31 +58,32 @@ struct spi_device { | |||
63 | u32 max_speed_hz; | 58 | u32 max_speed_hz; |
64 | u8 chip_select; | 59 | u8 chip_select; |
65 | u8 mode; | 60 | u8 mode; |
66 | #define SPI_CPHA 0x01 /* clock phase */ | 61 | #define SPI_CPHA 0x01 /* clock phase */ |
67 | #define SPI_CPOL 0x02 /* clock polarity */ | 62 | #define SPI_CPOL 0x02 /* clock polarity */ |
68 | #define SPI_MODE_0 (0|0) | 63 | #define SPI_MODE_0 (0|0) |
69 | #define SPI_MODE_1 (0|SPI_CPHA) | 64 | #define SPI_MODE_1 (0|SPI_CPHA) /* (original MicroWire) */ |
70 | #define SPI_MODE_2 (SPI_CPOL|0) | 65 | #define SPI_MODE_2 (SPI_CPOL|0) |
71 | #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) | 66 | #define SPI_MODE_3 (SPI_CPOL|SPI_CPHA) |
72 | #define SPI_CS_HIGH 0x04 /* chipselect active high? */ | 67 | #define SPI_CS_HIGH 0x04 /* chipselect active high? */ |
73 | u8 bits_per_word; | 68 | u8 bits_per_word; |
74 | int irq; | 69 | int irq; |
75 | void *controller_state; | 70 | void *controller_state; |
76 | const void *controller_data; | 71 | void *controller_data; |
77 | const char *modalias; | 72 | const char *modalias; |
78 | 73 | ||
79 | // likely need more hooks for more protocol options affecting how | 74 | // likely need more hooks for more protocol options affecting how |
80 | // the controller talks to its chips, like: | 75 | // the controller talks to each chip, like: |
81 | // - bit order (default is wordwise msb-first) | 76 | // - bit order (default is wordwise msb-first) |
82 | // - memory packing (12 bit samples into low bits, others zeroed) | 77 | // - memory packing (12 bit samples into low bits, others zeroed) |
83 | // - priority | 78 | // - priority |
79 | // - drop chipselect after each word | ||
84 | // - chipselect delays | 80 | // - chipselect delays |
85 | // - ... | 81 | // - ... |
86 | }; | 82 | }; |
87 | 83 | ||
88 | static inline struct spi_device *to_spi_device(struct device *dev) | 84 | static inline struct spi_device *to_spi_device(struct device *dev) |
89 | { | 85 | { |
90 | return container_of(dev, struct spi_device, dev); | 86 | return dev ? container_of(dev, struct spi_device, dev) : NULL; |
91 | } | 87 | } |
92 | 88 | ||
93 | /* most drivers won't need to care about device refcounting */ | 89 | /* most drivers won't need to care about device refcounting */ |
@@ -117,12 +113,38 @@ static inline void spi_set_ctldata(struct spi_device *spi, void *state) | |||
117 | struct spi_message; | 113 | struct spi_message; |
118 | 114 | ||
119 | 115 | ||
116 | |||
117 | struct spi_driver { | ||
118 | int (*probe)(struct spi_device *spi); | ||
119 | int (*remove)(struct spi_device *spi); | ||
120 | void (*shutdown)(struct spi_device *spi); | ||
121 | int (*suspend)(struct spi_device *spi, pm_message_t mesg); | ||
122 | int (*resume)(struct spi_device *spi); | ||
123 | struct device_driver driver; | ||
124 | }; | ||
125 | |||
126 | static inline struct spi_driver *to_spi_driver(struct device_driver *drv) | ||
127 | { | ||
128 | return drv ? container_of(drv, struct spi_driver, driver) : NULL; | ||
129 | } | ||
130 | |||
131 | extern int spi_register_driver(struct spi_driver *sdrv); | ||
132 | |||
133 | static inline void spi_unregister_driver(struct spi_driver *sdrv) | ||
134 | { | ||
135 | if (!sdrv) | ||
136 | return; | ||
137 | driver_unregister(&sdrv->driver); | ||
138 | } | ||
139 | |||
140 | |||
141 | |||
120 | /** | 142 | /** |
121 | * struct spi_master - interface to SPI master controller | 143 | * struct spi_master - interface to SPI master controller |
122 | * @cdev: class interface to this driver | 144 | * @cdev: class interface to this driver |
123 | * @bus_num: board-specific (and often SOC-specific) identifier for a | 145 | * @bus_num: board-specific (and often SOC-specific) identifier for a |
124 | * given SPI controller. | 146 | * given SPI controller. |
125 | * @num_chipselects: chipselects are used to distinguish individual | 147 | * @num_chipselect: chipselects are used to distinguish individual |
126 | * SPI slaves, and are numbered from zero to num_chipselects. | 148 | * SPI slaves, and are numbered from zero to num_chipselects. |
127 | * each slave has a chipselect signal, but it's common that not | 149 | * each slave has a chipselect signal, but it's common that not |
128 | * every chipselect is connected to a slave. | 150 | * every chipselect is connected to a slave. |
@@ -275,7 +297,8 @@ struct spi_transfer { | |||
275 | * addresses for each transfer buffer | 297 | * addresses for each transfer buffer |
276 | * @complete: called to report transaction completions | 298 | * @complete: called to report transaction completions |
277 | * @context: the argument to complete() when it's called | 299 | * @context: the argument to complete() when it's called |
278 | * @actual_length: how many bytes were transferd | 300 | * @actual_length: the total number of bytes that were transferred in all |
301 | * successful segments | ||
279 | * @status: zero for success, else negative errno | 302 | * @status: zero for success, else negative errno |
280 | * @queue: for use by whichever driver currently owns the message | 303 | * @queue: for use by whichever driver currently owns the message |
281 | * @state: for use by whichever driver currently owns the message | 304 | * @state: for use by whichever driver currently owns the message |
@@ -295,7 +318,7 @@ struct spi_message { | |||
295 | * | 318 | * |
296 | * Some controller drivers (message-at-a-time queue processing) | 319 | * Some controller drivers (message-at-a-time queue processing) |
297 | * could provide that as their default scheduling algorithm. But | 320 | * could provide that as their default scheduling algorithm. But |
298 | * others (with multi-message pipelines) would need a flag to | 321 | * others (with multi-message pipelines) could need a flag to |
299 | * tell them about such special cases. | 322 | * tell them about such special cases. |
300 | */ | 323 | */ |
301 | 324 | ||
@@ -346,6 +369,13 @@ spi_setup(struct spi_device *spi) | |||
346 | * FIFO order, messages may go to different devices in other orders. | 369 | * FIFO order, messages may go to different devices in other orders. |
347 | * Some device might be higher priority, or have various "hard" access | 370 | * Some device might be higher priority, or have various "hard" access |
348 | * time requirements, for example. | 371 | * time requirements, for example. |
372 | * | ||
373 | * On detection of any fault during the transfer, processing of | ||
374 | * the entire message is aborted, and the device is deselected. | ||
375 | * Until returning from the associated message completion callback, | ||
376 | * no other spi_message queued to that device will be processed. | ||
377 | * (This rule applies equally to all the synchronous transfer calls, | ||
378 | * which are wrappers around this core asynchronous primitive.) | ||
349 | */ | 379 | */ |
350 | static inline int | 380 | static inline int |
351 | spi_async(struct spi_device *spi, struct spi_message *message) | 381 | spi_async(struct spi_device *spi, struct spi_message *message) |
@@ -484,12 +514,12 @@ struct spi_board_info { | |||
484 | * "modalias" is normally the driver name. | 514 | * "modalias" is normally the driver name. |
485 | * | 515 | * |
486 | * platform_data goes to spi_device.dev.platform_data, | 516 | * platform_data goes to spi_device.dev.platform_data, |
487 | * controller_data goes to spi_device.platform_data, | 517 | * controller_data goes to spi_device.controller_data, |
488 | * irq is copied too | 518 | * irq is copied too |
489 | */ | 519 | */ |
490 | char modalias[KOBJ_NAME_LEN]; | 520 | char modalias[KOBJ_NAME_LEN]; |
491 | const void *platform_data; | 521 | const void *platform_data; |
492 | const void *controller_data; | 522 | void *controller_data; |
493 | int irq; | 523 | int irq; |
494 | 524 | ||
495 | /* slower signaling on noisy or low voltage boards */ | 525 | /* slower signaling on noisy or low voltage boards */ |
@@ -525,9 +555,8 @@ spi_register_board_info(struct spi_board_info const *info, unsigned n) | |||
525 | 555 | ||
526 | 556 | ||
527 | /* If you're hotplugging an adapter with devices (parport, usb, etc) | 557 | /* If you're hotplugging an adapter with devices (parport, usb, etc) |
528 | * use spi_new_device() to describe each device. You can also call | 558 | * use spi_new_device() to describe each device. You would then call |
529 | * spi_unregister_device() to get start making that device vanish, | 559 | * spi_unregister_device() to start making that device vanish. |
530 | * but normally that would be handled by spi_unregister_master(). | ||
531 | */ | 560 | */ |
532 | extern struct spi_device * | 561 | extern struct spi_device * |
533 | spi_new_device(struct spi_master *, struct spi_board_info *); | 562 | spi_new_device(struct spi_master *, struct spi_board_info *); |