Commit fc579056 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/topic/fsl-dspi', 'spi/topic/mpc512x',...

Merge remote-tracking branches 'spi/topic/fsl-dspi', 'spi/topic/mpc512x', 'spi/topic/mtk', 'spi/topic/oc-tiny' and 'spi/topic/octeon' into spi-next
...@@ -29,8 +29,11 @@ Required properties: ...@@ -29,8 +29,11 @@ Required properties:
muxes clock, and "spi-clk" for the clock gate. muxes clock, and "spi-clk" for the clock gate.
Optional properties: Optional properties:
-cs-gpios: see spi-bus.txt, only required for MT8173.
- mediatek,pad-select: specify which pins group(ck/mi/mo/cs) spi - 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. 0: specify GPIO69,70,71,72 for spi pins.
1: specify GPIO102,103,104,105 for spi pins. 1: specify GPIO102,103,104,105 for spi pins.
2: specify GPIO128,129,130,131 for spi pins. 2: specify GPIO128,129,130,131 for spi pins.
...@@ -49,7 +52,7 @@ spi: spi@1100a000 { ...@@ -49,7 +52,7 @@ spi: spi@1100a000 {
<&topckgen CLK_TOP_SPI_SEL>, <&topckgen CLK_TOP_SPI_SEL>,
<&pericfg CLK_PERI_SPI0>; <&pericfg CLK_PERI_SPI0>;
clock-names = "parent-clk", "sel-clk", "spi-clk"; clock-names = "parent-clk", "sel-clk", "spi-clk";
cs-gpios = <&pio 105 GPIO_ACTIVE_LOW>, <&pio 72 GPIO_ACTIVE_LOW>;
mediatek,pad-select = <0>; mediatek,pad-select = <1>, <0>;
status = "disabled"; status = "disabled";
}; };
...@@ -315,7 +315,7 @@ config SPI_FSL_SPI ...@@ -315,7 +315,7 @@ config SPI_FSL_SPI
config SPI_FSL_DSPI config SPI_FSL_DSPI
tristate "Freescale DSPI controller" tristate "Freescale DSPI controller"
select REGMAP_MMIO select REGMAP_MMIO
depends on SOC_VF610 || SOC_LS1021A || COMPILE_TEST depends on SOC_VF610 || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST
help help
This enables support for the Freescale DSPI controller in master This enables support for the Freescale DSPI controller in master
mode. VF610 platform uses the controller. mode. VF610 platform uses the controller.
......
...@@ -409,9 +409,6 @@ static int dspi_transfer_one_message(struct spi_master *master, ...@@ -409,9 +409,6 @@ static int dspi_transfer_one_message(struct spi_master *master,
SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF); SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);
regmap_write(dspi->regmap, SPI_CTAR(dspi->cs), regmap_write(dspi->regmap, SPI_CTAR(dspi->cs),
dspi->cur_chip->ctar_val); 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; trans_mode = dspi->devtype_data->trans_mode;
switch (trans_mode) { switch (trans_mode) {
......
...@@ -302,11 +302,9 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master, ...@@ -302,11 +302,9 @@ static int mpc512x_psc_spi_msg_xfer(struct spi_master *master,
cs_change = 1; cs_change = 1;
status = 0; status = 0;
list_for_each_entry(t, &m->transfers, transfer_list) { 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); status = mpc512x_psc_spi_transfer_setup(spi, t);
if (status < 0) if (status < 0)
break; break;
}
if (cs_change) if (cs_change)
mpc512x_psc_spi_activate_cs(spi); mpc512x_psc_spi_activate_cs(spi);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/platform_data/spi-mt65xx.h> #include <linux/platform_data/spi-mt65xx.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
...@@ -84,7 +85,8 @@ struct mtk_spi_compatible { ...@@ -84,7 +85,8 @@ struct mtk_spi_compatible {
struct mtk_spi { struct mtk_spi {
void __iomem *base; void __iomem *base;
u32 state; u32 state;
u32 pad_sel; int pad_num;
u32 *pad_sel;
struct clk *parent_clk, *sel_clk, *spi_clk; struct clk *parent_clk, *sel_clk, *spi_clk;
struct spi_transfer *cur_transfer; struct spi_transfer *cur_transfer;
u32 xfer_len; u32 xfer_len;
...@@ -131,10 +133,28 @@ static void mtk_spi_reset(struct mtk_spi *mdata) ...@@ -131,10 +133,28 @@ static void mtk_spi_reset(struct mtk_spi *mdata)
writel(reg_val, mdata->base + SPI_CMD_REG); writel(reg_val, mdata->base + SPI_CMD_REG);
} }
static void mtk_spi_config(struct mtk_spi *mdata, static int mtk_spi_prepare_message(struct spi_master *master,
struct mtk_chip_config *chip_config) struct spi_message *msg)
{ {
u16 cpha, cpol;
u32 reg_val; 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); reg_val = readl(mdata->base + SPI_CMD_REG);
...@@ -170,38 +190,8 @@ static void mtk_spi_config(struct mtk_spi *mdata, ...@@ -170,38 +190,8 @@ static void mtk_spi_config(struct mtk_spi *mdata,
/* pad select */ /* pad select */
if (mdata->dev_comp->need_pad_sel) 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);
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; return 0;
} }
...@@ -413,6 +403,19 @@ static bool mtk_spi_can_dma(struct spi_master *master, ...@@ -413,6 +403,19 @@ static bool mtk_spi_can_dma(struct spi_master *master,
return xfer->len > MTK_SPI_MAX_FIFO_SIZE; 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) static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id)
{ {
u32 cmd, reg_val, cnt; u32 cmd, reg_val, cnt;
...@@ -484,7 +487,7 @@ static int mtk_spi_probe(struct platform_device *pdev) ...@@ -484,7 +487,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
struct mtk_spi *mdata; struct mtk_spi *mdata;
const struct of_device_id *of_id; const struct of_device_id *of_id;
struct resource *res; struct resource *res;
int irq, ret; int i, irq, ret;
master = spi_alloc_master(&pdev->dev, sizeof(*mdata)); master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
if (!master) { if (!master) {
...@@ -500,6 +503,7 @@ static int mtk_spi_probe(struct platform_device *pdev) ...@@ -500,6 +503,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
master->prepare_message = mtk_spi_prepare_message; master->prepare_message = mtk_spi_prepare_message;
master->transfer_one = mtk_spi_transfer_one; master->transfer_one = mtk_spi_transfer_one;
master->can_dma = mtk_spi_can_dma; 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); of_id = of_match_node(mtk_spi_of_match, pdev->dev.of_node);
if (!of_id) { if (!of_id) {
...@@ -514,22 +518,35 @@ static int mtk_spi_probe(struct platform_device *pdev) ...@@ -514,22 +518,35 @@ static int mtk_spi_probe(struct platform_device *pdev)
master->flags = SPI_MASTER_MUST_TX; master->flags = SPI_MASTER_MUST_TX;
if (mdata->dev_comp->need_pad_sel) { if (mdata->dev_comp->need_pad_sel) {
ret = of_property_read_u32(pdev->dev.of_node, mdata->pad_num = of_property_count_u32_elems(
"mediatek,pad-select", pdev->dev.of_node,
&mdata->pad_sel); "mediatek,pad-select");
if (ret) { if (mdata->pad_num < 0) {
dev_err(&pdev->dev, "failed to read pad select: %d\n", dev_err(&pdev->dev,
ret); "No 'mediatek,pad-select' property\n");
ret = -EINVAL;
goto err_put_master; goto err_put_master;
} }
if (mdata->pad_sel > MT8173_SPI_MAX_PAD_SEL) { mdata->pad_sel = devm_kmalloc_array(&pdev->dev, mdata->pad_num,
dev_err(&pdev->dev, "wrong pad-select: %u\n", sizeof(u32), GFP_KERNEL);
mdata->pad_sel); 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; ret = -EINVAL;
goto err_put_master; goto err_put_master;
} }
} }
}
platform_set_drvdata(pdev, master); platform_set_drvdata(pdev, master);
...@@ -606,6 +623,26 @@ static int mtk_spi_probe(struct platform_device *pdev) ...@@ -606,6 +623,26 @@ static int mtk_spi_probe(struct platform_device *pdev)
goto err_put_master; 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; return 0;
err_disable_clk: err_disable_clk:
......
...@@ -207,8 +207,7 @@ static int tiny_spi_of_probe(struct platform_device *pdev) ...@@ -207,8 +207,7 @@ static int tiny_spi_of_probe(struct platform_device *pdev)
struct tiny_spi *hw = platform_get_drvdata(pdev); struct tiny_spi *hw = platform_get_drvdata(pdev);
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
unsigned int i; unsigned int i;
const __be32 *val; u32 val;
int len;
if (!np) if (!np)
return 0; return 0;
...@@ -226,13 +225,10 @@ static int tiny_spi_of_probe(struct platform_device *pdev) ...@@ -226,13 +225,10 @@ static int tiny_spi_of_probe(struct platform_device *pdev)
return -ENODEV; return -ENODEV;
} }
hw->bitbang.master->dev.of_node = pdev->dev.of_node; hw->bitbang.master->dev.of_node = pdev->dev.of_node;
val = of_get_property(pdev->dev.of_node, if (!of_property_read_u32(np, "clock-frequency", &val))
"clock-frequency", &len); hw->freq = val;
if (val && len >= sizeof(__be32)) if (!of_property_read_u32(np, "baud-width", &val))
hw->freq = be32_to_cpup(val); hw->baudwidth = val;
val = of_get_property(pdev->dev.of_node, "baud-width", &len);
if (val && len >= sizeof(__be32))
hw->baudwidth = be32_to_cpup(val);
return 0; return 0;
} }
#else /* !CONFIG_OF */ #else /* !CONFIG_OF */
......
...@@ -65,7 +65,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p, ...@@ -65,7 +65,7 @@ static int octeon_spi_do_transfer(struct octeon_spi *p,
cpha = mode & SPI_CPHA; cpha = mode & SPI_CPHA;
cpol = mode & SPI_CPOL; 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); clkdiv = octeon_get_io_clock_rate() / (2 * speed_hz);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment