From 45a3e771085d16c95eb54f8009d795941b21fb28 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 9 Sep 2015 13:55:53 +0200 Subject: spi: oc-tiny: Use of_property_read_u32 instead of open-coding it Use of_property_read_u32 instead of of_get_property with return value checks and endianness conversion. Signed-off-by: Tobias Klauser Signed-off-by: Mark Brown diff --git a/drivers/spi/spi-oc-tiny.c b/drivers/spi/spi-oc-tiny.c index 76656a7..b591128 100644 --- a/drivers/spi/spi-oc-tiny.c +++ b/drivers/spi/spi-oc-tiny.c @@ -207,8 +207,7 @@ static int tiny_spi_of_probe(struct platform_device *pdev) struct tiny_spi *hw = platform_get_drvdata(pdev); struct device_node *np = pdev->dev.of_node; unsigned int i; - const __be32 *val; - int len; + u32 val; if (!np) return 0; @@ -226,13 +225,10 @@ static int tiny_spi_of_probe(struct platform_device *pdev) return -ENODEV; } hw->bitbang.master->dev.of_node = pdev->dev.of_node; - val = of_get_property(pdev->dev.of_node, - "clock-frequency", &len); - if (val && len >= sizeof(__be32)) - hw->freq = be32_to_cpup(val); - val = of_get_property(pdev->dev.of_node, "baud-width", &len); - if (val && len >= sizeof(__be32)) - hw->baudwidth = be32_to_cpup(val); + if (!of_property_read_u32(np, "clock-frequency", &val)) + hw->freq = val; + if (!of_property_read_u32(np, "baud-width", &val)) + hw->baudwidth = val; return 0; } #else /* !CONFIG_OF */ -- cgit v0.10.2 From 8cf3af32902d14f6a0fbc4ad9a3025d9e7d4701b Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 15 Sep 2015 16:26:15 +0300 Subject: spi: octeon: Use transfer speed unconditionally SPI core validates the transfer speed and defaults to spi->max_speed_hz in case the transfer speed is not set. Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown diff --git a/drivers/spi/spi-octeon.c b/drivers/spi/spi-octeon.c index e99d6a9..07e4ce8 100644 --- a/drivers/spi/spi-octeon.c +++ b/drivers/spi/spi-octeon.c @@ -65,7 +65,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p, cpha = mode & SPI_CPHA; cpol = mode & SPI_CPOL; - speed_hz = xfer->speed_hz ? : spi->max_speed_hz; + speed_hz = xfer->speed_hz; clkdiv = octeon_get_io_clock_rate() / (2 * speed_hz); -- cgit v0.10.2 From 85c1912d44081173b9cd796955959a8201aa7a4e Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 15 Sep 2015 16:26:19 +0300 Subject: spi: mpc512x: Call mpc512x_psc_spi_transfer_setup() unconditionally SPI core validates both bits_per_word and speed_hz transfer parameters and thus the if statement here is needless as it will always call the mpc512x_psc_spi_transfer_setup(). Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index 1e75341..c3ec46c 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -302,11 +302,9 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master, cs_change = 1; status = 0; list_for_each_entry(t, &m->transfers, transfer_list) { - if (t->bits_per_word || t->speed_hz) { - status = mpc512x_psc_spi_transfer_setup(spi, t); - if (status < 0) - break; - } + status = mpc512x_psc_spi_transfer_setup(spi, t); + if (status < 0) + break; if (cs_change) mpc512x_psc_spi_activate_cs(spi); -- cgit v0.10.2 From fa14e47fc409390f1be92da679a365faef187937 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 15 Sep 2015 16:26:25 +0300 Subject: spi: spi-fsl-dspi: Remove duplicated register write SPI core makes sure that transfer speed is always set so code here writes the same register with the same value twice. Code has been doing this from the beginning. This looks to me some sort of copy paste error so I'm removing the second write. If this is not the case we can bring it back with a comment. Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 86bcdd6..59a1143 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -409,9 +409,6 @@ static int dspi_transfer_one_message(struct spi_master *master, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), dspi->cur_chip->ctar_val); - if (transfer->speed_hz) - regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), - dspi->cur_chip->ctar_val); trans_mode = dspi->devtype_data->trans_mode; switch (trans_mode) { -- cgit v0.10.2 From eca3a1ee8dd7ec5819bd77d598044eb6ecdf4495 Mon Sep 17 00:00:00 2001 From: Leilk Liu Date: Mon, 26 Oct 2015 16:09:41 +0800 Subject: spi: mediatek: Update document devicetree bindings to support multiple devices This patch updates document devicetree bindings to support multiple devices. Signed-off-by: Leilk Liu Signed-off-by: Mark Brown diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt index 6160ffb..ce363c923f 100644 --- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt +++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt @@ -29,8 +29,11 @@ Required properties: muxes clock, and "spi-clk" for the clock gate. Optional properties: +-cs-gpios: see spi-bus.txt, only required for MT8173. + - mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi - controller used, this value should be 0~3, only required for MT8173. + controller used. This is a array, the element value should be 0~3, + only required for MT8173. 0: specify GPIO69,70,71,72 for spi pins. 1: specify GPIO102,103,104,105 for spi pins. 2: specify GPIO128,129,130,131 for spi pins. @@ -49,7 +52,7 @@ spi: spi@1100a000 { <&topckgen CLK_TOP_SPI_SEL>, <&pericfg CLK_PERI_SPI0>; clock-names = "parent-clk", "sel-clk", "spi-clk"; - - mediatek,pad-select = <0>; + cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>; + mediatek,pad-select = <1>, <0>; status = "disabled"; }; -- cgit v0.10.2 From 79b5d3f24dcec547ea5db7d2e0b557a36f92b16b Mon Sep 17 00:00:00 2001 From: Leilk Liu Date: Mon, 26 Oct 2015 16:09:41 +0800 Subject: spi: mediatek: remove mtk_spi_config mtk_spi_config() and mtk_spi_prepare_message() both initialize spi register, so remove mtk_spi_config() and init all register in mtk_spi_prepare_message(). Signed-off-by: Leilk Liu Signed-off-by: Mark Brown diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index ecb6c58..7bd84c8 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -131,10 +131,34 @@ static void mtk_spi_reset(struct mtk_spi *mdata) writel(reg_val, mdata->base + SPI_CMD_REG); } -static void mtk_spi_config(struct mtk_spi *mdata, - struct mtk_chip_config *chip_config) +static int mtk_spi_prepare_message(struct spi_master *master, + struct spi_message *msg) { + u16 cpha, cpol; u32 reg_val; + struct mtk_chip_config *chip_config; + struct spi_device *spi = msg->spi; + struct mtk_spi *mdata = spi_master_get_devdata(master); + + cpha = spi->mode & SPI_CPHA ? 1 : 0; + cpol = spi->mode & SPI_CPOL ? 1 : 0; + + chip_config = spi->controller_data; + if (!chip_config) { + chip_config = (void *)&mtk_default_chip_info; + spi->controller_data = chip_config; + } + + reg_val = readl(mdata->base + SPI_CMD_REG); + if (cpha) + reg_val |= SPI_CMD_CPHA; + else + reg_val &= ~SPI_CMD_CPHA; + if (cpol) + reg_val |= SPI_CMD_CPOL; + else + reg_val &= ~SPI_CMD_CPOL; + writel(reg_val, mdata->base + SPI_CMD_REG); reg_val = readl(mdata->base + SPI_CMD_REG); @@ -171,37 +195,6 @@ static void mtk_spi_config(struct mtk_spi *mdata, /* pad select */ if (mdata->dev_comp->need_pad_sel) writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG); -} - -static int mtk_spi_prepare_message(struct spi_master *master, - struct spi_message *msg) -{ - u32 reg_val; - u8 cpha, cpol; - struct mtk_chip_config *chip_config; - struct spi_device *spi = msg->spi; - struct mtk_spi *mdata = spi_master_get_devdata(master); - - cpha = spi->mode & SPI_CPHA ? 1 : 0; - cpol = spi->mode & SPI_CPOL ? 1 : 0; - - reg_val = readl(mdata->base + SPI_CMD_REG); - if (cpha) - reg_val |= SPI_CMD_CPHA; - else - reg_val &= ~SPI_CMD_CPHA; - if (cpol) - reg_val |= SPI_CMD_CPOL; - else - reg_val &= ~SPI_CMD_CPOL; - writel(reg_val, mdata->base + SPI_CMD_REG); - - chip_config = spi->controller_data; - if (!chip_config) { - chip_config = (void *)&mtk_default_chip_info; - spi->controller_data = chip_config; - } - mtk_spi_config(mdata, chip_config); return 0; } -- cgit v0.10.2 From 58a984c79a68d508ccfccf4b82c0eaf7f487c399 Mon Sep 17 00:00:00 2001 From: Leilk Liu Date: Mon, 26 Oct 2015 16:09:43 +0800 Subject: spi: mediatek: handle controller_data in mtk_spi_setup controller_data is related with device, so move to master->setup function. Signed-off-by: Leilk Liu Signed-off-by: Mark Brown diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 7bd84c8..406695a 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -136,19 +136,13 @@ static int mtk_spi_prepare_message(struct spi_master *master, { u16 cpha, cpol; u32 reg_val; - struct mtk_chip_config *chip_config; struct spi_device *spi = msg->spi; + struct mtk_chip_config *chip_config = spi->controller_data; struct mtk_spi *mdata = spi_master_get_devdata(master); cpha = spi->mode & SPI_CPHA ? 1 : 0; cpol = spi->mode & SPI_CPOL ? 1 : 0; - chip_config = spi->controller_data; - if (!chip_config) { - chip_config = (void *)&mtk_default_chip_info; - spi->controller_data = chip_config; - } - reg_val = readl(mdata->base + SPI_CMD_REG); if (cpha) reg_val |= SPI_CMD_CPHA; @@ -406,6 +400,16 @@ static bool mtk_spi_can_dma(struct spi_master *master, return xfer->len > MTK_SPI_MAX_FIFO_SIZE; } +static int mtk_spi_setup(struct spi_device *spi) +{ + struct mtk_spi *mdata = spi_master_get_devdata(spi->master); + + if (!spi->controller_data) + spi->controller_data = (void *)&mtk_default_chip_info; + + return 0; +} + static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) { u32 cmd, reg_val, cnt; @@ -493,6 +497,7 @@ static int mtk_spi_probe(struct platform_device *pdev) master->prepare_message = mtk_spi_prepare_message; master->transfer_one = mtk_spi_transfer_one; master->can_dma = mtk_spi_can_dma; + master->setup = mtk_spi_setup; of_id = of_match_node(mtk_spi_of_match, pdev->dev.of_node); if (!of_id) { -- cgit v0.10.2 From 37457607ecaffe56718a0e423548edeb3d4a11b7 Mon Sep 17 00:00:00 2001 From: Leilk Liu Date: Mon, 26 Oct 2015 16:09:44 +0800 Subject: spi: mediatek: mt8173 spi multiple devices support mt8173 IC spi HW has 4 gpio group, it's possible to support max <= 4 slave devices, even mtk spi HW is not congruent to spi core. 1. When a device do a spi_message transfer, spi HW should know which pad-group this device is on, and then writes pad-select register. 2. Mtk pad-select register just selects which MISO pin HW will receive data. For example, pad-select=1(select spi1 pins), HW just receives data from spi1 MISO, but it still send waveform to all 4 group cs/clk/mosi. If cs pin in other groups is still spi mode, after spi1 is selected(by active cs pin), devices on other group will also be selected. Signed-off-by: Leilk Liu Signed-off-by: Mark Brown diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 406695a..563954a 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -84,7 +85,8 @@ struct mtk_spi_compatible { struct mtk_spi { void __iomem *base; u32 state; - u32 pad_sel; + int pad_num; + u32 *pad_sel; struct clk *parent_clk, *sel_clk, *spi_clk; struct spi_transfer *cur_transfer; u32 xfer_len; @@ -188,7 +190,8 @@ static int mtk_spi_prepare_message(struct spi_master *master, /* pad select */ if (mdata->dev_comp->need_pad_sel) - writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG); + writel(mdata->pad_sel[spi->chip_select], + mdata->base + SPI_PAD_SEL_REG); return 0; } @@ -407,6 +410,9 @@ static int mtk_spi_setup(struct spi_device *spi) if (!spi->controller_data) spi->controller_data = (void *)&mtk_default_chip_info; + if (mdata->dev_comp->need_pad_sel) + gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); + return 0; } @@ -481,7 +487,7 @@ static int mtk_spi_probe(struct platform_device *pdev) struct mtk_spi *mdata; const struct of_device_id *of_id; struct resource *res; - int irq, ret; + int i, irq, ret; master = spi_alloc_master(&pdev->dev, sizeof(*mdata)); if (!master) { @@ -512,21 +518,34 @@ static int mtk_spi_probe(struct platform_device *pdev) master->flags = SPI_MASTER_MUST_TX; if (mdata->dev_comp->need_pad_sel) { - ret = of_property_read_u32(pdev->dev.of_node, - "mediatek,pad-select", - &mdata->pad_sel); - if (ret) { - dev_err(&pdev->dev, "failed to read pad select: %d\n", - ret); + mdata->pad_num = of_property_count_u32_elems( + pdev->dev.of_node, + "mediatek,pad-select"); + if (mdata->pad_num < 0) { + dev_err(&pdev->dev, + "No 'mediatek,pad-select' property\n"); + ret = -EINVAL; goto err_put_master; } - if (mdata->pad_sel > MT8173_SPI_MAX_PAD_SEL) { - dev_err(&pdev->dev, "wrong pad-select: %u\n", - mdata->pad_sel); - ret = -EINVAL; + mdata->pad_sel = devm_kmalloc_array(&pdev->dev, mdata->pad_num, + sizeof(u32), GFP_KERNEL); + if (!mdata->pad_sel) { + ret = -ENOMEM; goto err_put_master; } + + for (i = 0; i < mdata->pad_num; i++) { + of_property_read_u32_index(pdev->dev.of_node, + "mediatek,pad-select", + i, &mdata->pad_sel[i]); + if (mdata->pad_sel[i] > MT8173_SPI_MAX_PAD_SEL) { + dev_err(&pdev->dev, "wrong pad-sel[%d]: %u\n", + i, mdata->pad_sel[i]); + ret = -EINVAL; + goto err_put_master; + } + } } platform_set_drvdata(pdev, master); @@ -604,6 +623,26 @@ static int mtk_spi_probe(struct platform_device *pdev) goto err_put_master; } + if (mdata->dev_comp->need_pad_sel) { + if (mdata->pad_num != master->num_chipselect) { + dev_err(&pdev->dev, + "pad_num does not match num_chipselect(%d != %d)\n", + mdata->pad_num, master->num_chipselect); + ret = -EINVAL; + goto err_put_master; + } + + for (i = 0; i < master->num_chipselect; i++) { + ret = devm_gpio_request(&pdev->dev, master->cs_gpios[i], + dev_name(&pdev->dev)); + if (ret) { + dev_err(&pdev->dev, + "can't get CS GPIO %i\n", i); + goto err_put_master; + } + } + } + return 0; err_disable_clk: -- cgit v0.10.2 From 5a60adafb95263d63dfaaf7168680c4b7e50b370 Mon Sep 17 00:00:00 2001 From: Yuan Yao Date: Wed, 28 Oct 2015 17:41:59 +0800 Subject: spi: Add DSPI support for layerscape family LS1043a and LS2080A in the Layerscape family also support DSPI, make DSPI selectable for these hardwares. Signed-off-by: Yuan Yao Signed-off-by: Mark Brown diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 4887f31..bb41bd5 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -304,7 +304,7 @@ config SPI_FSL_SPI config SPI_FSL_DSPI tristate "Freescale DSPI controller" select REGMAP_MMIO - depends on SOC_VF610 || SOC_LS1021A || COMPILE_TEST + depends on SOC_VF610 || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST help This enables support for the Freescale DSPI controller in master mode. VF610 platform uses the controller. -- cgit v0.10.2