Loading Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ Required properties: - "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 - "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and later Soc - reg : Offset and length of the register set for the device - interrupts : Should contain CSPI/eCSPI interrupt - cs-gpios : Specifies the gpio pins to be used for chipselects. Loading drivers/spi/spi-imx.c +196 −22 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ /* The maximum bytes that a sdma BD can transfer.*/ #define MAX_SDMA_BD_BYTES (1 << 15) #define MX51_ECSPI_CTRL_MAX_BURST 512 enum spi_imx_devtype { IMX1_CSPI, Loading @@ -63,7 +64,8 @@ enum spi_imx_devtype { IMX27_CSPI, IMX31_CSPI, IMX35_CSPI, /* CSPI on all i.mx except above */ IMX51_ECSPI, /* ECSPI on i.mx51 and later */ IMX51_ECSPI, /* ECSPI on i.mx51 */ IMX53_ECSPI, /* ECSPI on i.mx53 and later */ }; struct spi_imx_data; Loading @@ -74,6 +76,9 @@ struct spi_imx_devtype_data { void (*trigger)(struct spi_imx_data *); int (*rx_available)(struct spi_imx_data *); void (*reset)(struct spi_imx_data *); bool has_dmamode; unsigned int fifo_size; bool dynamic_burst; enum spi_imx_devtype devtype; }; Loading @@ -94,12 +99,14 @@ struct spi_imx_data { unsigned int bits_per_word; unsigned int spi_drctl; unsigned int count; unsigned int count, remainder; void (*tx)(struct spi_imx_data *); void (*rx)(struct spi_imx_data *); void *rx_buf; const void *tx_buf; unsigned int txfifo; /* number of words pushed in tx FIFO */ unsigned int dynamic_burst, read_u32; unsigned int word_mask; /* DMA */ bool usedma; Loading @@ -125,9 +132,9 @@ static inline int is_imx51_ecspi(struct spi_imx_data *d) return d->devtype_data->devtype == IMX51_ECSPI; } static inline unsigned spi_imx_get_fifosize(struct spi_imx_data *d) static inline int is_imx53_ecspi(struct spi_imx_data *d) { return is_imx51_ecspi(d) ? 64 : 8; return d->devtype_data->devtype == IMX53_ECSPI; } #define MXC_SPI_BUF_RX(type) \ Loading Loading @@ -219,7 +226,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, if (bytes_per_word != 1 && bytes_per_word != 2 && bytes_per_word != 4) return false; for (i = spi_imx_get_fifosize(spi_imx) / 2; i > 0; i--) { for (i = spi_imx->devtype_data->fifo_size / 2; i > 0; i--) { if (!(transfer->len % (i * bytes_per_word))) break; } Loading @@ -228,6 +235,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, return false; spi_imx->wml = i; spi_imx->dynamic_burst = 0; return true; } Loading @@ -242,6 +250,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 #define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18) #define MX51_ECSPI_CTRL_BL_OFFSET 20 #define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20) #define MX51_ECSPI_CONFIG 0x0c #define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0)) Loading Loading @@ -269,6 +278,106 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, #define MX51_ECSPI_TESTREG 0x20 #define MX51_ECSPI_TESTREG_LBC BIT(31) static void spi_imx_buf_rx_swap_u32(struct spi_imx_data *spi_imx) { unsigned int val = readl(spi_imx->base + MXC_CSPIRXDATA); #ifdef __LITTLE_ENDIAN unsigned int bytes_per_word; #endif if (spi_imx->rx_buf) { #ifdef __LITTLE_ENDIAN bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); if (bytes_per_word == 1) val = cpu_to_be32(val); else if (bytes_per_word == 2) val = (val << 16) | (val >> 16); #endif val &= spi_imx->word_mask; *(u32 *)spi_imx->rx_buf = val; spi_imx->rx_buf += sizeof(u32); } } static void spi_imx_buf_rx_swap(struct spi_imx_data *spi_imx) { unsigned int bytes_per_word; bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); if (spi_imx->read_u32) { spi_imx_buf_rx_swap_u32(spi_imx); return; } if (bytes_per_word == 1) spi_imx_buf_rx_u8(spi_imx); else if (bytes_per_word == 2) spi_imx_buf_rx_u16(spi_imx); } static void spi_imx_buf_tx_swap_u32(struct spi_imx_data *spi_imx) { u32 val = 0; #ifdef __LITTLE_ENDIAN unsigned int bytes_per_word; #endif if (spi_imx->tx_buf) { val = *(u32 *)spi_imx->tx_buf; val &= spi_imx->word_mask; spi_imx->tx_buf += sizeof(u32); } spi_imx->count -= sizeof(u32); #ifdef __LITTLE_ENDIAN bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); if (bytes_per_word == 1) val = cpu_to_be32(val); else if (bytes_per_word == 2) val = (val << 16) | (val >> 16); #endif writel(val, spi_imx->base + MXC_CSPITXDATA); } static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx) { u32 ctrl, val; unsigned int bytes_per_word; if (spi_imx->count == spi_imx->remainder) { ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; if (spi_imx->count > MX51_ECSPI_CTRL_MAX_BURST) { spi_imx->remainder = spi_imx->count % MX51_ECSPI_CTRL_MAX_BURST; val = MX51_ECSPI_CTRL_MAX_BURST * 8 - 1; } else if (spi_imx->count >= sizeof(u32)) { spi_imx->remainder = spi_imx->count % sizeof(u32); val = (spi_imx->count - spi_imx->remainder) * 8 - 1; } else { spi_imx->remainder = 0; val = spi_imx->bits_per_word - 1; spi_imx->read_u32 = 0; } ctrl |= (val << MX51_ECSPI_CTRL_BL_OFFSET); writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); } if (spi_imx->count >= sizeof(u32)) { spi_imx_buf_tx_swap_u32(spi_imx); return; } bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); if (bytes_per_word == 1) spi_imx_buf_tx_u8(spi_imx); else if (bytes_per_word == 2) spi_imx_buf_tx_u16(spi_imx); } /* MX51 eCSPI */ static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx, unsigned int fspi, unsigned int *fres) Loading Loading @@ -513,8 +622,8 @@ static int mx31_config(struct spi_device *spi) reg |= MX31_CSPICTRL_POL; if (spi->mode & SPI_CS_HIGH) reg |= MX31_CSPICTRL_SSPOL; if (spi->cs_gpio < 0) reg |= (spi->cs_gpio + 32) << if (!gpio_is_valid(spi->cs_gpio)) reg |= (spi->chip_select) << (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : MX31_CSPICTRL_CS_SHIFT); Loading Loading @@ -605,8 +714,8 @@ static int mx21_config(struct spi_device *spi) reg |= MX21_CSPICTRL_POL; if (spi->mode & SPI_CS_HIGH) reg |= MX21_CSPICTRL_SSPOL; if (spi->cs_gpio < 0) reg |= (spi->cs_gpio + 32) << MX21_CSPICTRL_CS_SHIFT; if (!gpio_is_valid(spi->cs_gpio)) reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT; writel(reg, spi_imx->base + MXC_CSPICTRL); Loading Loading @@ -693,6 +802,9 @@ static struct spi_imx_devtype_data imx1_cspi_devtype_data = { .trigger = mx1_trigger, .rx_available = mx1_rx_available, .reset = mx1_reset, .fifo_size = 8, .has_dmamode = false, .dynamic_burst = false, .devtype = IMX1_CSPI, }; Loading @@ -702,6 +814,9 @@ static struct spi_imx_devtype_data imx21_cspi_devtype_data = { .trigger = mx21_trigger, .rx_available = mx21_rx_available, .reset = mx21_reset, .fifo_size = 8, .has_dmamode = false, .dynamic_burst = false, .devtype = IMX21_CSPI, }; Loading @@ -712,6 +827,9 @@ static struct spi_imx_devtype_data imx27_cspi_devtype_data = { .trigger = mx21_trigger, .rx_available = mx21_rx_available, .reset = mx21_reset, .fifo_size = 8, .has_dmamode = false, .dynamic_burst = false, .devtype = IMX27_CSPI, }; Loading @@ -721,6 +839,9 @@ static struct spi_imx_devtype_data imx31_cspi_devtype_data = { .trigger = mx31_trigger, .rx_available = mx31_rx_available, .reset = mx31_reset, .fifo_size = 8, .has_dmamode = false, .dynamic_burst = false, .devtype = IMX31_CSPI, }; Loading @@ -731,6 +852,9 @@ static struct spi_imx_devtype_data imx35_cspi_devtype_data = { .trigger = mx31_trigger, .rx_available = mx31_rx_available, .reset = mx31_reset, .fifo_size = 8, .has_dmamode = true, .dynamic_burst = false, .devtype = IMX35_CSPI, }; Loading @@ -740,9 +864,23 @@ static struct spi_imx_devtype_data imx51_ecspi_devtype_data = { .trigger = mx51_ecspi_trigger, .rx_available = mx51_ecspi_rx_available, .reset = mx51_ecspi_reset, .fifo_size = 64, .has_dmamode = true, .dynamic_burst = true, .devtype = IMX51_ECSPI, }; static struct spi_imx_devtype_data imx53_ecspi_devtype_data = { .intctrl = mx51_ecspi_intctrl, .config = mx51_ecspi_config, .trigger = mx51_ecspi_trigger, .rx_available = mx51_ecspi_rx_available, .reset = mx51_ecspi_reset, .fifo_size = 64, .has_dmamode = true, .devtype = IMX53_ECSPI, }; static const struct platform_device_id spi_imx_devtype[] = { { .name = "imx1-cspi", Loading @@ -762,6 +900,9 @@ static const struct platform_device_id spi_imx_devtype[] = { }, { .name = "imx51-ecspi", .driver_data = (kernel_ulong_t) &imx51_ecspi_devtype_data, }, { .name = "imx53-ecspi", .driver_data = (kernel_ulong_t) &imx53_ecspi_devtype_data, }, { /* sentinel */ } Loading @@ -774,6 +915,7 @@ static const struct of_device_id spi_imx_dt_ids[] = { { .compatible = "fsl,imx31-cspi", .data = &imx31_cspi_devtype_data, }, { .compatible = "fsl,imx35-cspi", .data = &imx35_cspi_devtype_data, }, { .compatible = "fsl,imx51-ecspi", .data = &imx51_ecspi_devtype_data, }, { .compatible = "fsl,imx53-ecspi", .data = &imx53_ecspi_devtype_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, spi_imx_dt_ids); Loading @@ -783,6 +925,9 @@ static void spi_imx_chipselect(struct spi_device *spi, int is_active) int active = is_active != BITBANG_CS_INACTIVE; int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH); if (spi->mode & SPI_NO_CS) return; if (!gpio_is_valid(spi->cs_gpio)) return; Loading @@ -791,9 +936,11 @@ static void spi_imx_chipselect(struct spi_device *spi, int is_active) static void spi_imx_push(struct spi_imx_data *spi_imx) { while (spi_imx->txfifo < spi_imx_get_fifosize(spi_imx)) { while (spi_imx->txfifo < spi_imx->devtype_data->fifo_size) { if (!spi_imx->count) break; if (spi_imx->txfifo && (spi_imx->count == spi_imx->remainder)) break; spi_imx->tx(spi_imx); spi_imx->txfifo++; } Loading Loading @@ -887,6 +1034,27 @@ static int spi_imx_setupxfer(struct spi_device *spi, spi_imx->speed_hz = t->speed_hz; /* Initialize the functions for transfer */ if (spi_imx->devtype_data->dynamic_burst) { u32 mask; spi_imx->dynamic_burst = 0; spi_imx->remainder = 0; spi_imx->read_u32 = 1; mask = (1 << spi_imx->bits_per_word) - 1; spi_imx->rx = spi_imx_buf_rx_swap; spi_imx->tx = spi_imx_buf_tx_swap; spi_imx->dynamic_burst = 1; spi_imx->remainder = t->len; if (spi_imx->bits_per_word <= 8) spi_imx->word_mask = mask << 24 | mask << 16 | mask << 8 | mask; else if (spi_imx->bits_per_word <= 16) spi_imx->word_mask = mask << 16 | mask; else spi_imx->word_mask = mask; } else { if (spi_imx->bits_per_word <= 8) { spi_imx->rx = spi_imx_buf_rx_u8; spi_imx->tx = spi_imx_buf_tx_u8; Loading @@ -897,6 +1065,7 @@ static int spi_imx_setupxfer(struct spi_device *spi, spi_imx->rx = spi_imx_buf_rx_u32; spi_imx->tx = spi_imx_buf_tx_u32; } } if (spi_imx_can_dma(spi_imx->bitbang.master, spi, t)) spi_imx->usedma = 1; Loading Loading @@ -938,7 +1107,7 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, if (of_machine_is_compatible("fsl,imx6dl")) return 0; spi_imx->wml = spi_imx_get_fifosize(spi_imx) / 2; spi_imx->wml = spi_imx->devtype_data->fifo_size / 2; /* Prepare for TX DMA: */ master->dma_tx = dma_request_slave_channel_reason(dev, "tx"); Loading Loading @@ -1109,6 +1278,9 @@ static int spi_imx_setup(struct spi_device *spi) dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __func__, spi->mode, spi->bits_per_word, spi->max_speed_hz); if (spi->mode & SPI_NO_CS) return 0; if (gpio_is_valid(spi->cs_gpio)) gpio_direction_output(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); Loading Loading @@ -1208,8 +1380,10 @@ static int spi_imx_probe(struct platform_device *pdev) spi_imx->bitbang.master->cleanup = spi_imx_cleanup; spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message; spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx)) spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ | SPI_NO_CS; if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx) || is_imx53_ecspi(spi_imx)) spi_imx->bitbang.master->mode_bits |= SPI_LOOP | SPI_READY; spi_imx->spi_drctl = spi_drctl; Loading Loading @@ -1262,7 +1436,7 @@ static int spi_imx_probe(struct platform_device *pdev) * Only validated on i.mx35 and i.mx6 now, can remove the constraint * if validated on other chips. */ if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx)) { if (spi_imx->devtype_data->has_dmamode) { ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master); if (ret == -EPROBE_DEFER) goto out_clk_put; Loading drivers/spi/spi-loopback-test.c +28 −6 Original line number Diff line number Diff line Loading @@ -32,39 +32,50 @@ #include "spi-test.h" /* flag to only simulate transfers */ int simulate_only; static int simulate_only; module_param(simulate_only, int, 0); MODULE_PARM_DESC(simulate_only, "if not 0 do not execute the spi message"); /* dump spi messages */ int dump_messages; static int dump_messages; module_param(dump_messages, int, 0); MODULE_PARM_DESC(dump_messages, "=1 dump the basic spi_message_structure, " \ "=2 dump the spi_message_structure including data, " \ "=3 dump the spi_message structure before and after execution"); /* the device is jumpered for loopback - enabling some rx_buf tests */ int loopback; static int loopback; module_param(loopback, int, 0); MODULE_PARM_DESC(loopback, "if set enable loopback mode, where the rx_buf " \ "is checked to match tx_buf after the spi_message " \ "is executed"); static int loop_req; module_param(loop_req, int, 0); MODULE_PARM_DESC(loop_req, "if set controller will be asked to enable test loop mode. " \ "If controller supported it, MISO and MOSI will be connected"); static int no_cs; module_param(no_cs, int, 0); MODULE_PARM_DESC(no_cs, "if set Chip Select (CS) will not be used"); /* run only a specific test */ int run_only_test = -1; static int run_only_test = -1; module_param(run_only_test, int, 0); MODULE_PARM_DESC(run_only_test, "only run the test with this number (0-based !)"); /* use vmalloc'ed buffers */ int use_vmalloc; static int use_vmalloc; module_param(use_vmalloc, int, 0644); MODULE_PARM_DESC(use_vmalloc, "use vmalloc'ed buffers instead of kmalloc'ed"); /* check rx ranges */ int check_ranges = 1; static int check_ranges = 1; module_param(check_ranges, int, 0644); MODULE_PARM_DESC(check_ranges, "checks rx_buffer pattern are valid"); Loading Loading @@ -313,6 +324,17 @@ static int spi_loopback_test_probe(struct spi_device *spi) { int ret; if (loop_req || no_cs) { spi->mode |= loop_req ? SPI_LOOP : 0; spi->mode |= no_cs ? SPI_NO_CS : 0; ret = spi_setup(spi); if (ret) { dev_err(&spi->dev, "SPI setup with SPI_LOOP or SPI_NO_CS failed (%d)\n", ret); return ret; } } dev_info(&spi->dev, "Executing spi-loopback-tests\n"); ret = spi_test_run_tests(spi, spi_tests); Loading drivers/spi/spi-omap2-mcspi.c +0 −4 Original line number Diff line number Diff line Loading @@ -1338,7 +1338,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev) struct resource *r; int status = 0, i; u32 regs_offset = 0; static int bus_num = 1; struct device_node *node = pdev->dev.of_node; const struct of_device_id *match; Loading Loading @@ -1374,14 +1373,11 @@ static int omap2_mcspi_probe(struct platform_device *pdev) of_property_read_u32(node, "ti,spi-num-cs", &num_cs); master->num_chipselect = num_cs; master->bus_num = bus_num++; if (of_get_property(node, "ti,pindir-d0-out-d1-in", NULL)) mcspi->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; } else { pdata = dev_get_platdata(&pdev->dev); master->num_chipselect = pdata->num_cs; if (pdev->id != -1) master->bus_num = pdev->id; mcspi->pin_dir = pdata->pin_dir; } regs_offset = pdata->regs_offset; Loading drivers/spi/spi-pic32.c +2 −2 Original line number Diff line number Diff line Loading @@ -52,14 +52,14 @@ struct pic32_spi_regs { /* Bit fields of SPI Control Register */ #define CTRL_RX_INT_SHIFT 0 /* Rx interrupt generation */ #define RX_FIFO_EMTPY 0 #define RX_FIFO_EMPTY 0 #define RX_FIFO_NOT_EMPTY 1 /* not empty */ #define RX_FIFO_HALF_FULL 2 /* full by half or more */ #define RX_FIFO_FULL 3 /* completely full */ #define CTRL_TX_INT_SHIFT 2 /* TX interrupt generation */ #define TX_FIFO_ALL_EMPTY 0 /* completely empty */ #define TX_FIFO_EMTPY 1 /* empty */ #define TX_FIFO_EMPTY 1 /* empty */ #define TX_FIFO_HALF_EMPTY 2 /* empty by half or more */ #define TX_FIFO_NOT_FULL 3 /* atleast one empty */ Loading Loading
Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt +1 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ Required properties: - "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 - "fsl,imx53-ecspi" for SPI compatible with the one integrated on i.MX53 and later Soc - reg : Offset and length of the register set for the device - interrupts : Should contain CSPI/eCSPI interrupt - cs-gpios : Specifies the gpio pins to be used for chipselects. Loading
drivers/spi/spi-imx.c +196 −22 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ /* The maximum bytes that a sdma BD can transfer.*/ #define MAX_SDMA_BD_BYTES (1 << 15) #define MX51_ECSPI_CTRL_MAX_BURST 512 enum spi_imx_devtype { IMX1_CSPI, Loading @@ -63,7 +64,8 @@ enum spi_imx_devtype { IMX27_CSPI, IMX31_CSPI, IMX35_CSPI, /* CSPI on all i.mx except above */ IMX51_ECSPI, /* ECSPI on i.mx51 and later */ IMX51_ECSPI, /* ECSPI on i.mx51 */ IMX53_ECSPI, /* ECSPI on i.mx53 and later */ }; struct spi_imx_data; Loading @@ -74,6 +76,9 @@ struct spi_imx_devtype_data { void (*trigger)(struct spi_imx_data *); int (*rx_available)(struct spi_imx_data *); void (*reset)(struct spi_imx_data *); bool has_dmamode; unsigned int fifo_size; bool dynamic_burst; enum spi_imx_devtype devtype; }; Loading @@ -94,12 +99,14 @@ struct spi_imx_data { unsigned int bits_per_word; unsigned int spi_drctl; unsigned int count; unsigned int count, remainder; void (*tx)(struct spi_imx_data *); void (*rx)(struct spi_imx_data *); void *rx_buf; const void *tx_buf; unsigned int txfifo; /* number of words pushed in tx FIFO */ unsigned int dynamic_burst, read_u32; unsigned int word_mask; /* DMA */ bool usedma; Loading @@ -125,9 +132,9 @@ static inline int is_imx51_ecspi(struct spi_imx_data *d) return d->devtype_data->devtype == IMX51_ECSPI; } static inline unsigned spi_imx_get_fifosize(struct spi_imx_data *d) static inline int is_imx53_ecspi(struct spi_imx_data *d) { return is_imx51_ecspi(d) ? 64 : 8; return d->devtype_data->devtype == IMX53_ECSPI; } #define MXC_SPI_BUF_RX(type) \ Loading Loading @@ -219,7 +226,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, if (bytes_per_word != 1 && bytes_per_word != 2 && bytes_per_word != 4) return false; for (i = spi_imx_get_fifosize(spi_imx) / 2; i > 0; i--) { for (i = spi_imx->devtype_data->fifo_size / 2; i > 0; i--) { if (!(transfer->len % (i * bytes_per_word))) break; } Loading @@ -228,6 +235,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, return false; spi_imx->wml = i; spi_imx->dynamic_burst = 0; return true; } Loading @@ -242,6 +250,7 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 #define MX51_ECSPI_CTRL_CS(cs) ((cs) << 18) #define MX51_ECSPI_CTRL_BL_OFFSET 20 #define MX51_ECSPI_CTRL_BL_MASK (0xfff << 20) #define MX51_ECSPI_CONFIG 0x0c #define MX51_ECSPI_CONFIG_SCLKPHA(cs) (1 << ((cs) + 0)) Loading Loading @@ -269,6 +278,106 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, #define MX51_ECSPI_TESTREG 0x20 #define MX51_ECSPI_TESTREG_LBC BIT(31) static void spi_imx_buf_rx_swap_u32(struct spi_imx_data *spi_imx) { unsigned int val = readl(spi_imx->base + MXC_CSPIRXDATA); #ifdef __LITTLE_ENDIAN unsigned int bytes_per_word; #endif if (spi_imx->rx_buf) { #ifdef __LITTLE_ENDIAN bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); if (bytes_per_word == 1) val = cpu_to_be32(val); else if (bytes_per_word == 2) val = (val << 16) | (val >> 16); #endif val &= spi_imx->word_mask; *(u32 *)spi_imx->rx_buf = val; spi_imx->rx_buf += sizeof(u32); } } static void spi_imx_buf_rx_swap(struct spi_imx_data *spi_imx) { unsigned int bytes_per_word; bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); if (spi_imx->read_u32) { spi_imx_buf_rx_swap_u32(spi_imx); return; } if (bytes_per_word == 1) spi_imx_buf_rx_u8(spi_imx); else if (bytes_per_word == 2) spi_imx_buf_rx_u16(spi_imx); } static void spi_imx_buf_tx_swap_u32(struct spi_imx_data *spi_imx) { u32 val = 0; #ifdef __LITTLE_ENDIAN unsigned int bytes_per_word; #endif if (spi_imx->tx_buf) { val = *(u32 *)spi_imx->tx_buf; val &= spi_imx->word_mask; spi_imx->tx_buf += sizeof(u32); } spi_imx->count -= sizeof(u32); #ifdef __LITTLE_ENDIAN bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); if (bytes_per_word == 1) val = cpu_to_be32(val); else if (bytes_per_word == 2) val = (val << 16) | (val >> 16); #endif writel(val, spi_imx->base + MXC_CSPITXDATA); } static void spi_imx_buf_tx_swap(struct spi_imx_data *spi_imx) { u32 ctrl, val; unsigned int bytes_per_word; if (spi_imx->count == spi_imx->remainder) { ctrl = readl(spi_imx->base + MX51_ECSPI_CTRL); ctrl &= ~MX51_ECSPI_CTRL_BL_MASK; if (spi_imx->count > MX51_ECSPI_CTRL_MAX_BURST) { spi_imx->remainder = spi_imx->count % MX51_ECSPI_CTRL_MAX_BURST; val = MX51_ECSPI_CTRL_MAX_BURST * 8 - 1; } else if (spi_imx->count >= sizeof(u32)) { spi_imx->remainder = spi_imx->count % sizeof(u32); val = (spi_imx->count - spi_imx->remainder) * 8 - 1; } else { spi_imx->remainder = 0; val = spi_imx->bits_per_word - 1; spi_imx->read_u32 = 0; } ctrl |= (val << MX51_ECSPI_CTRL_BL_OFFSET); writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); } if (spi_imx->count >= sizeof(u32)) { spi_imx_buf_tx_swap_u32(spi_imx); return; } bytes_per_word = spi_imx_bytes_per_word(spi_imx->bits_per_word); if (bytes_per_word == 1) spi_imx_buf_tx_u8(spi_imx); else if (bytes_per_word == 2) spi_imx_buf_tx_u16(spi_imx); } /* MX51 eCSPI */ static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx, unsigned int fspi, unsigned int *fres) Loading Loading @@ -513,8 +622,8 @@ static int mx31_config(struct spi_device *spi) reg |= MX31_CSPICTRL_POL; if (spi->mode & SPI_CS_HIGH) reg |= MX31_CSPICTRL_SSPOL; if (spi->cs_gpio < 0) reg |= (spi->cs_gpio + 32) << if (!gpio_is_valid(spi->cs_gpio)) reg |= (spi->chip_select) << (is_imx35_cspi(spi_imx) ? MX35_CSPICTRL_CS_SHIFT : MX31_CSPICTRL_CS_SHIFT); Loading Loading @@ -605,8 +714,8 @@ static int mx21_config(struct spi_device *spi) reg |= MX21_CSPICTRL_POL; if (spi->mode & SPI_CS_HIGH) reg |= MX21_CSPICTRL_SSPOL; if (spi->cs_gpio < 0) reg |= (spi->cs_gpio + 32) << MX21_CSPICTRL_CS_SHIFT; if (!gpio_is_valid(spi->cs_gpio)) reg |= spi->chip_select << MX21_CSPICTRL_CS_SHIFT; writel(reg, spi_imx->base + MXC_CSPICTRL); Loading Loading @@ -693,6 +802,9 @@ static struct spi_imx_devtype_data imx1_cspi_devtype_data = { .trigger = mx1_trigger, .rx_available = mx1_rx_available, .reset = mx1_reset, .fifo_size = 8, .has_dmamode = false, .dynamic_burst = false, .devtype = IMX1_CSPI, }; Loading @@ -702,6 +814,9 @@ static struct spi_imx_devtype_data imx21_cspi_devtype_data = { .trigger = mx21_trigger, .rx_available = mx21_rx_available, .reset = mx21_reset, .fifo_size = 8, .has_dmamode = false, .dynamic_burst = false, .devtype = IMX21_CSPI, }; Loading @@ -712,6 +827,9 @@ static struct spi_imx_devtype_data imx27_cspi_devtype_data = { .trigger = mx21_trigger, .rx_available = mx21_rx_available, .reset = mx21_reset, .fifo_size = 8, .has_dmamode = false, .dynamic_burst = false, .devtype = IMX27_CSPI, }; Loading @@ -721,6 +839,9 @@ static struct spi_imx_devtype_data imx31_cspi_devtype_data = { .trigger = mx31_trigger, .rx_available = mx31_rx_available, .reset = mx31_reset, .fifo_size = 8, .has_dmamode = false, .dynamic_burst = false, .devtype = IMX31_CSPI, }; Loading @@ -731,6 +852,9 @@ static struct spi_imx_devtype_data imx35_cspi_devtype_data = { .trigger = mx31_trigger, .rx_available = mx31_rx_available, .reset = mx31_reset, .fifo_size = 8, .has_dmamode = true, .dynamic_burst = false, .devtype = IMX35_CSPI, }; Loading @@ -740,9 +864,23 @@ static struct spi_imx_devtype_data imx51_ecspi_devtype_data = { .trigger = mx51_ecspi_trigger, .rx_available = mx51_ecspi_rx_available, .reset = mx51_ecspi_reset, .fifo_size = 64, .has_dmamode = true, .dynamic_burst = true, .devtype = IMX51_ECSPI, }; static struct spi_imx_devtype_data imx53_ecspi_devtype_data = { .intctrl = mx51_ecspi_intctrl, .config = mx51_ecspi_config, .trigger = mx51_ecspi_trigger, .rx_available = mx51_ecspi_rx_available, .reset = mx51_ecspi_reset, .fifo_size = 64, .has_dmamode = true, .devtype = IMX53_ECSPI, }; static const struct platform_device_id spi_imx_devtype[] = { { .name = "imx1-cspi", Loading @@ -762,6 +900,9 @@ static const struct platform_device_id spi_imx_devtype[] = { }, { .name = "imx51-ecspi", .driver_data = (kernel_ulong_t) &imx51_ecspi_devtype_data, }, { .name = "imx53-ecspi", .driver_data = (kernel_ulong_t) &imx53_ecspi_devtype_data, }, { /* sentinel */ } Loading @@ -774,6 +915,7 @@ static const struct of_device_id spi_imx_dt_ids[] = { { .compatible = "fsl,imx31-cspi", .data = &imx31_cspi_devtype_data, }, { .compatible = "fsl,imx35-cspi", .data = &imx35_cspi_devtype_data, }, { .compatible = "fsl,imx51-ecspi", .data = &imx51_ecspi_devtype_data, }, { .compatible = "fsl,imx53-ecspi", .data = &imx53_ecspi_devtype_data, }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, spi_imx_dt_ids); Loading @@ -783,6 +925,9 @@ static void spi_imx_chipselect(struct spi_device *spi, int is_active) int active = is_active != BITBANG_CS_INACTIVE; int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH); if (spi->mode & SPI_NO_CS) return; if (!gpio_is_valid(spi->cs_gpio)) return; Loading @@ -791,9 +936,11 @@ static void spi_imx_chipselect(struct spi_device *spi, int is_active) static void spi_imx_push(struct spi_imx_data *spi_imx) { while (spi_imx->txfifo < spi_imx_get_fifosize(spi_imx)) { while (spi_imx->txfifo < spi_imx->devtype_data->fifo_size) { if (!spi_imx->count) break; if (spi_imx->txfifo && (spi_imx->count == spi_imx->remainder)) break; spi_imx->tx(spi_imx); spi_imx->txfifo++; } Loading Loading @@ -887,6 +1034,27 @@ static int spi_imx_setupxfer(struct spi_device *spi, spi_imx->speed_hz = t->speed_hz; /* Initialize the functions for transfer */ if (spi_imx->devtype_data->dynamic_burst) { u32 mask; spi_imx->dynamic_burst = 0; spi_imx->remainder = 0; spi_imx->read_u32 = 1; mask = (1 << spi_imx->bits_per_word) - 1; spi_imx->rx = spi_imx_buf_rx_swap; spi_imx->tx = spi_imx_buf_tx_swap; spi_imx->dynamic_burst = 1; spi_imx->remainder = t->len; if (spi_imx->bits_per_word <= 8) spi_imx->word_mask = mask << 24 | mask << 16 | mask << 8 | mask; else if (spi_imx->bits_per_word <= 16) spi_imx->word_mask = mask << 16 | mask; else spi_imx->word_mask = mask; } else { if (spi_imx->bits_per_word <= 8) { spi_imx->rx = spi_imx_buf_rx_u8; spi_imx->tx = spi_imx_buf_tx_u8; Loading @@ -897,6 +1065,7 @@ static int spi_imx_setupxfer(struct spi_device *spi, spi_imx->rx = spi_imx_buf_rx_u32; spi_imx->tx = spi_imx_buf_tx_u32; } } if (spi_imx_can_dma(spi_imx->bitbang.master, spi, t)) spi_imx->usedma = 1; Loading Loading @@ -938,7 +1107,7 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, if (of_machine_is_compatible("fsl,imx6dl")) return 0; spi_imx->wml = spi_imx_get_fifosize(spi_imx) / 2; spi_imx->wml = spi_imx->devtype_data->fifo_size / 2; /* Prepare for TX DMA: */ master->dma_tx = dma_request_slave_channel_reason(dev, "tx"); Loading Loading @@ -1109,6 +1278,9 @@ static int spi_imx_setup(struct spi_device *spi) dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", __func__, spi->mode, spi->bits_per_word, spi->max_speed_hz); if (spi->mode & SPI_NO_CS) return 0; if (gpio_is_valid(spi->cs_gpio)) gpio_direction_output(spi->cs_gpio, spi->mode & SPI_CS_HIGH ? 0 : 1); Loading Loading @@ -1208,8 +1380,10 @@ static int spi_imx_probe(struct platform_device *pdev) spi_imx->bitbang.master->cleanup = spi_imx_cleanup; spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message; spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx)) spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ | SPI_NO_CS; if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx) || is_imx53_ecspi(spi_imx)) spi_imx->bitbang.master->mode_bits |= SPI_LOOP | SPI_READY; spi_imx->spi_drctl = spi_drctl; Loading Loading @@ -1262,7 +1436,7 @@ static int spi_imx_probe(struct platform_device *pdev) * Only validated on i.mx35 and i.mx6 now, can remove the constraint * if validated on other chips. */ if (is_imx35_cspi(spi_imx) || is_imx51_ecspi(spi_imx)) { if (spi_imx->devtype_data->has_dmamode) { ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master); if (ret == -EPROBE_DEFER) goto out_clk_put; Loading
drivers/spi/spi-loopback-test.c +28 −6 Original line number Diff line number Diff line Loading @@ -32,39 +32,50 @@ #include "spi-test.h" /* flag to only simulate transfers */ int simulate_only; static int simulate_only; module_param(simulate_only, int, 0); MODULE_PARM_DESC(simulate_only, "if not 0 do not execute the spi message"); /* dump spi messages */ int dump_messages; static int dump_messages; module_param(dump_messages, int, 0); MODULE_PARM_DESC(dump_messages, "=1 dump the basic spi_message_structure, " \ "=2 dump the spi_message_structure including data, " \ "=3 dump the spi_message structure before and after execution"); /* the device is jumpered for loopback - enabling some rx_buf tests */ int loopback; static int loopback; module_param(loopback, int, 0); MODULE_PARM_DESC(loopback, "if set enable loopback mode, where the rx_buf " \ "is checked to match tx_buf after the spi_message " \ "is executed"); static int loop_req; module_param(loop_req, int, 0); MODULE_PARM_DESC(loop_req, "if set controller will be asked to enable test loop mode. " \ "If controller supported it, MISO and MOSI will be connected"); static int no_cs; module_param(no_cs, int, 0); MODULE_PARM_DESC(no_cs, "if set Chip Select (CS) will not be used"); /* run only a specific test */ int run_only_test = -1; static int run_only_test = -1; module_param(run_only_test, int, 0); MODULE_PARM_DESC(run_only_test, "only run the test with this number (0-based !)"); /* use vmalloc'ed buffers */ int use_vmalloc; static int use_vmalloc; module_param(use_vmalloc, int, 0644); MODULE_PARM_DESC(use_vmalloc, "use vmalloc'ed buffers instead of kmalloc'ed"); /* check rx ranges */ int check_ranges = 1; static int check_ranges = 1; module_param(check_ranges, int, 0644); MODULE_PARM_DESC(check_ranges, "checks rx_buffer pattern are valid"); Loading Loading @@ -313,6 +324,17 @@ static int spi_loopback_test_probe(struct spi_device *spi) { int ret; if (loop_req || no_cs) { spi->mode |= loop_req ? SPI_LOOP : 0; spi->mode |= no_cs ? SPI_NO_CS : 0; ret = spi_setup(spi); if (ret) { dev_err(&spi->dev, "SPI setup with SPI_LOOP or SPI_NO_CS failed (%d)\n", ret); return ret; } } dev_info(&spi->dev, "Executing spi-loopback-tests\n"); ret = spi_test_run_tests(spi, spi_tests); Loading
drivers/spi/spi-omap2-mcspi.c +0 −4 Original line number Diff line number Diff line Loading @@ -1338,7 +1338,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev) struct resource *r; int status = 0, i; u32 regs_offset = 0; static int bus_num = 1; struct device_node *node = pdev->dev.of_node; const struct of_device_id *match; Loading Loading @@ -1374,14 +1373,11 @@ static int omap2_mcspi_probe(struct platform_device *pdev) of_property_read_u32(node, "ti,spi-num-cs", &num_cs); master->num_chipselect = num_cs; master->bus_num = bus_num++; if (of_get_property(node, "ti,pindir-d0-out-d1-in", NULL)) mcspi->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; } else { pdata = dev_get_platdata(&pdev->dev); master->num_chipselect = pdata->num_cs; if (pdev->id != -1) master->bus_num = pdev->id; mcspi->pin_dir = pdata->pin_dir; } regs_offset = pdata->regs_offset; Loading
drivers/spi/spi-pic32.c +2 −2 Original line number Diff line number Diff line Loading @@ -52,14 +52,14 @@ struct pic32_spi_regs { /* Bit fields of SPI Control Register */ #define CTRL_RX_INT_SHIFT 0 /* Rx interrupt generation */ #define RX_FIFO_EMTPY 0 #define RX_FIFO_EMPTY 0 #define RX_FIFO_NOT_EMPTY 1 /* not empty */ #define RX_FIFO_HALF_FULL 2 /* full by half or more */ #define RX_FIFO_FULL 3 /* completely full */ #define CTRL_TX_INT_SHIFT 2 /* TX interrupt generation */ #define TX_FIFO_ALL_EMPTY 0 /* completely empty */ #define TX_FIFO_EMTPY 1 /* empty */ #define TX_FIFO_EMPTY 1 /* empty */ #define TX_FIFO_HALF_EMPTY 2 /* empty by half or more */ #define TX_FIFO_NOT_FULL 3 /* atleast one empty */ Loading