diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-13 15:05:40 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-13 15:05:40 -0700 |
commit | 0055dc5b23cc1738fc2f14221cf922a83057d8fb (patch) | |
tree | 791ace137da6784403804b15cd8195fd51a1a4a0 /Documentation | |
parent | 1b57c7c2fbb81763cd4a6940c8530c98022c409c (diff) | |
parent | 56afdb70ca9140cdcbdcf01870f3e4e2e8be17f5 (diff) |
Merge tag 'spi-v4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown:
"Only one framework update this time around, a change from Lars-Peter
to move full to pm_ops and remove the legacy bus PM ops. Otherwise
it's all driver updates:
- make the spidev driver complain loudly if registered as spidev with
DT rather than with a compatible string, hopefully helping people
avoid making that mistake.
- error handling and robustness fixes for the Designware and Intel
MID drivers from Andy Shevchenko.
- substantial performance improvements for the Raspberry Pi driver
from Martin Sperl.
- several new features for spidev_test from Adrian Remonda and Ian
Abbott"
* tag 'spi-v4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (75 commits)
spi: bcm2835: enabling polling mode for transfers shorter than 30us
spi: bcm2835: transform native-cs to gpio-cs on first spi_setup
spi: img-spfi: Control CS lines with GPIO
spi: img-spfi: Reset controller after each message
spi: img-spfi: Implement a handle_err() callback
spi: img-spfi: Setup TRANSACTION register before CONTROL register
spi: Make master->handle_err() callback optional to avoid crashes
spi: img-spfi: Limit bit clock to 1/4th of input clock
spi: img-spfi: Implement a prepare_message() callback
spi: fsl-dspi: Add ~50ns delay between cs and sck
spi: fsl-dspi: Add cs-sck delays
spi: fsl-dspi: Fix clock rate scale values
spi: signedness bug in qspi_trigger_transfer_out_int()
spi: imx: read back the RX/TX watermark levels earlier
spi: spi-bfin5xx: Initialize cr_width in bfin_spi_pump_transfers()
spi: bitbang: only toggle bitchanges
spi: pxa2xx: missing break in pxa2xx_ssp_get_clk_div()
spi: fsl-dspi: Fix clock rate scale values
spi: Using Trigger number to transmit/receive data
spi: bcm2835: fill FIFO before enabling interrupts to reduce interrupts/message
...
Diffstat (limited to 'Documentation')
-rw-r--r-- | Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt | 12 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/spi/qcom,spi-qup.txt | 8 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt | 8 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/spi/spi-img-spfi.txt | 1 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/spi/spi-rockchip.txt | 4 | ||||
-rw-r--r-- | Documentation/spi/spi-summary | 3 | ||||
-rw-r--r-- | Documentation/spi/spidev_test.c | 115 |
7 files changed, 128 insertions, 23 deletions
diff --git a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt index aad527b357a0..523341a0e113 100644 --- a/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt @@ -2,11 +2,21 @@ (CSPI/eCSPI) for i.MX Required properties: -- compatible : Should be "fsl,<soc>-cspi" or "fsl,<soc>-ecspi" +- compatible : + - "fsl,imx1-cspi" for SPI compatible with the one integrated on i.MX1 + - "fsl,imx21-cspi" for SPI compatible with the one integrated on i.MX21 + - "fsl,imx27-cspi" for SPI compatible with the one integrated on i.MX27 + - "fsl,imx31-cspi" for SPI compatible with the one integrated on i.MX31 + - "fsl,imx35-cspi" for SPI compatible with the one integrated on i.MX35 + - "fsl,imx51-ecspi" for SPI compatible with the one integrated on i.MX51 - reg : Offset and length of the register set for the device - interrupts : Should contain CSPI/eCSPI interrupt - fsl,spi-num-chipselects : Contains the number of the chipselect - cs-gpios : Specifies the gpio pins to be used for chipselects. +- clocks : Clock specifiers for both ipg and per clocks. +- clock-names : Clock names should include both "ipg" and "per" +See the clock consumer binding, + Documentation/devicetree/bindings/clock/clock-bindings.txt - dmas: DMA specifiers for tx and rx dma. See the DMA client binding, Documentation/devicetree/bindings/dma/dma.txt - dma-names: DMA request names should include "tx" and "rx" if present. diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt index e2c88df2cc15..5c090771c016 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qup.txt @@ -33,6 +33,11 @@ Optional properties: nodes. If unspecified, a single SPI device without a chip select can be used. +- dmas: Two DMA channel specifiers following the convention outlined + in bindings/dma/dma.txt +- dma-names: Names for the dma channels, if present. There must be at + least one channel named "tx" for transmit and named "rx" for + receive. SPI slave nodes must be children of the SPI master node and can contain properties described in Documentation/devicetree/bindings/spi/spi-bus.txt @@ -51,6 +56,9 @@ Example: clocks = <&gcc GCC_BLSP2_QUP2_SPI_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>; clock-names = "core", "iface"; + dmas = <&blsp1_bam 13>, <&blsp1_bam 12>; + dma-names = "rx", "tx"; + pinctrl-names = "default"; pinctrl-0 = <&spi8_default>; diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt index cbbe16ed3874..70af78a9185e 100644 --- a/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt +++ b/Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt @@ -16,6 +16,12 @@ Optional property: in big endian mode, otherwise in native mode(same with CPU), for more detail please see: Documentation/devicetree/bindings/regmap/regmap.txt. +Optional SPI slave node properties: +- fsl,spi-cs-sck-delay: a delay in nanoseconds between activating chip + select and the start of clock signal, at the start of a transfer. +- fsl,spi-sck-cs-delay: a delay in nanoseconds between stopping the clock + signal and deactivating chip select, at the end of a transfer. + Example: dspi0@4002c000 { @@ -43,6 +49,8 @@ dspi0@4002c000 { reg = <0>; linux,modalias = "m25p80"; modal = "at26df081a"; + fsl,spi-cs-sck-delay = <100>; + fsl,spi-sck-cs-delay = <50>; }; }; diff --git a/Documentation/devicetree/bindings/spi/spi-img-spfi.txt b/Documentation/devicetree/bindings/spi/spi-img-spfi.txt index c7dd50fb8eb2..e02fbf18c82c 100644 --- a/Documentation/devicetree/bindings/spi/spi-img-spfi.txt +++ b/Documentation/devicetree/bindings/spi/spi-img-spfi.txt @@ -14,6 +14,7 @@ Required properties: - dma-names: Must include the following entries: - rx - tx +- cs-gpios: Must specify the GPIOs used for chipselect lines. - #address-cells: Must be 1. - #size-cells: Must be 0. diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.txt b/Documentation/devicetree/bindings/spi/spi-rockchip.txt index 467dec441c62..0c491bda4c65 100644 --- a/Documentation/devicetree/bindings/spi/spi-rockchip.txt +++ b/Documentation/devicetree/bindings/spi/spi-rockchip.txt @@ -24,6 +24,9 @@ Optional Properties: - dmas: DMA specifiers for tx and rx dma. See the DMA client binding, Documentation/devicetree/bindings/dma/dma.txt - dma-names: DMA request names should include "tx" and "rx" if present. +- rx-sample-delay-ns: nanoseconds to delay after the SCLK edge before sampling + Rx data (may need to be fine tuned for high capacitance lines). + No delay (0) by default. Example: @@ -33,6 +36,7 @@ Example: reg = <0xff110000 0x1000>; dmas = <&pdma1 11>, <&pdma1 12>; dma-names = "tx", "rx"; + rx-sample-delay-ns = <10>; #address-cells = <1>; #size-cells = <0>; interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index d29734bff28c..d1824b399b2d 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary @@ -342,12 +342,11 @@ SPI protocol drivers somewhat resemble platform device drivers: .driver = { .name = "CHIP", .owner = THIS_MODULE, + .pm = &CHIP_pm_ops, }, .probe = CHIP_probe, .remove = CHIP_remove, - .suspend = CHIP_suspend, - .resume = CHIP_resume, }; The driver core will automatically attempt to bind this driver to any SPI diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c index 3a2f9d59edab..94f574b0fdb2 100644 --- a/Documentation/spi/spidev_test.c +++ b/Documentation/spi/spidev_test.c @@ -15,6 +15,7 @@ #include <unistd.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <getopt.h> #include <fcntl.h> #include <sys/ioctl.h> @@ -34,24 +35,79 @@ static uint32_t mode; static uint8_t bits = 8; static uint32_t speed = 500000; static uint16_t delay; +static int verbose; -static void transfer(int fd) +uint8_t default_tx[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF0, 0x0D, +}; + +uint8_t default_rx[ARRAY_SIZE(default_tx)] = {0, }; +char *input_tx; + +static void hex_dump(const void *src, size_t length, size_t line_size, char *prefix) +{ + int i = 0; + const unsigned char *address = src; + const unsigned char *line = address; + unsigned char c; + + printf("%s | ", prefix); + while (length-- > 0) { + printf("%02X ", *address++); + if (!(++i % line_size) || (length == 0 && i % line_size)) { + if (length == 0) { + while (i++ % line_size) + printf("__ "); + } + printf(" | "); /* right close */ + while (line < address) { + c = *line++; + printf("%c", (c < 33 || c == 255) ? 0x2E : c); + } + printf("\n"); + if (length > 0) + printf("%s | ", prefix); + } + } +} + +/* + * Unescape - process hexadecimal escape character + * converts shell input "\x23" -> 0x23 + */ +int unespcape(char *_dst, char *_src, size_t len) +{ + int ret = 0; + char *src = _src; + char *dst = _dst; + unsigned int ch; + + while (*src) { + if (*src == '\\' && *(src+1) == 'x') { + sscanf(src + 2, "%2x", &ch); + src += 4; + *dst++ = (unsigned char)ch; + } else { + *dst++ = *src++; + } + ret++; + } + return ret; +} + +static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) { int ret; - uint8_t tx[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x95, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xAD, - 0xF0, 0x0D, - }; - uint8_t rx[ARRAY_SIZE(tx)] = {0, }; + struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)tx, .rx_buf = (unsigned long)rx, - .len = ARRAY_SIZE(tx), + .len = len, .delay_usecs = delay, .speed_hz = speed, .bits_per_word = bits, @@ -76,12 +132,9 @@ static void transfer(int fd) if (ret < 1) pabort("can't send spi message"); - for (ret = 0; ret < ARRAY_SIZE(tx); ret++) { - if (!(ret % 6)) - puts(""); - printf("%.2X ", rx[ret]); - } - puts(""); + if (verbose) + hex_dump(tx, len, 32, "TX"); + hex_dump(rx, len, 32, "RX"); } static void print_usage(const char *prog) @@ -97,6 +150,8 @@ static void print_usage(const char *prog) " -L --lsb least significant bit first\n" " -C --cs-high chip select active high\n" " -3 --3wire SI/SO signals shared\n" + " -v --verbose Verbose (show tx buffer)\n" + " -p Send data (e.g. \"1234\\xde\\xad\")\n" " -N --no-cs no chip select\n" " -R --ready slave pulls low to pause\n" " -2 --dual dual transfer\n" @@ -121,12 +176,13 @@ static void parse_opts(int argc, char *argv[]) { "no-cs", 0, 0, 'N' }, { "ready", 0, 0, 'R' }, { "dual", 0, 0, '2' }, + { "verbose", 0, 0, 'v' }, { "quad", 0, 0, '4' }, { NULL, 0, 0, 0 }, }; int c; - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24", lopts, NULL); + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR24p:v", lopts, NULL); if (c == -1) break; @@ -165,9 +221,15 @@ static void parse_opts(int argc, char *argv[]) case 'N': mode |= SPI_NO_CS; break; + case 'v': + verbose = 1; + break; case 'R': mode |= SPI_READY; break; + case 'p': + input_tx = optarg; + break; case '2': mode |= SPI_TX_DUAL; break; @@ -191,6 +253,9 @@ int main(int argc, char *argv[]) { int ret = 0; int fd; + uint8_t *tx; + uint8_t *rx; + int size; parse_opts(argc, argv); @@ -235,7 +300,17 @@ int main(int argc, char *argv[]) printf("bits per word: %d\n", bits); printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); - transfer(fd); + if (input_tx) { + size = strlen(input_tx+1); + tx = malloc(size); + rx = malloc(size); + size = unespcape((char *)tx, input_tx, size); + transfer(fd, tx, rx, size); + free(rx); + free(tx); + } else { + transfer(fd, default_tx, default_rx, sizeof(default_tx)); + } close(fd); |