Loading Documentation/devicetree/bindings/spi/spi-mt65xx.txt +6 −3 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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"; }; drivers/spi/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -315,7 +315,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. Loading drivers/spi/spi-fsl-dspi.c +0 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading drivers/spi/spi-mpc512x-psc.c +3 −5 Original line number Diff line number Diff line Loading @@ -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; } if (cs_change) mpc512x_psc_spi_activate_cs(spi); Loading drivers/spi/spi-mt65xx.c +83 −46 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/ioport.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/platform_device.h> #include <linux/platform_data/spi-mt65xx.h> #include <linux/pm_runtime.h> Loading Loading @@ -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; Loading Loading @@ -131,10 +133,28 @@ 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 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; 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); Loading Loading @@ -170,38 +190,8 @@ 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); writel(mdata->pad_sel[spi->chip_select], mdata->base + SPI_PAD_SEL_REG); return 0; } Loading Loading @@ -413,6 +403,19 @@ 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; if (mdata->dev_comp->need_pad_sel) gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); return 0; } static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) { u32 cmd, reg_val, cnt; Loading Loading @@ -484,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) { Loading @@ -500,6 +503,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) { Loading @@ -514,22 +518,35 @@ 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); 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); Loading Loading @@ -606,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: Loading Loading
Documentation/devicetree/bindings/spi/spi-mt65xx.txt +6 −3 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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"; };
drivers/spi/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -315,7 +315,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. Loading
drivers/spi/spi-fsl-dspi.c +0 −3 Original line number Diff line number Diff line Loading @@ -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) { Loading
drivers/spi/spi-mpc512x-psc.c +3 −5 Original line number Diff line number Diff line Loading @@ -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; } if (cs_change) mpc512x_psc_spi_activate_cs(spi); Loading
drivers/spi/spi-mt65xx.c +83 −46 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <linux/ioport.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/platform_device.h> #include <linux/platform_data/spi-mt65xx.h> #include <linux/pm_runtime.h> Loading Loading @@ -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; Loading Loading @@ -131,10 +133,28 @@ 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 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; 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); Loading Loading @@ -170,38 +190,8 @@ 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); writel(mdata->pad_sel[spi->chip_select], mdata->base + SPI_PAD_SEL_REG); return 0; } Loading Loading @@ -413,6 +403,19 @@ 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; if (mdata->dev_comp->need_pad_sel) gpio_direction_output(spi->cs_gpio, !(spi->mode & SPI_CS_HIGH)); return 0; } static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) { u32 cmd, reg_val, cnt; Loading Loading @@ -484,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) { Loading @@ -500,6 +503,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) { Loading @@ -514,22 +518,35 @@ 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); 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); Loading Loading @@ -606,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: Loading