diff options
author | Leilk Liu <leilk.liu@mediatek.com> | 2015-09-07 07:37:57 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-09-07 12:26:39 -0400 |
commit | 6583d2032d57df9f1c00c753ca58e1a822901bf0 (patch) | |
tree | b6721f9a52e34679452377bdcaa591bd79a830f3 /drivers/spi/spi-mt65xx.c | |
parent | c5992f610f78e6c9d0a78e8fef1066ad640e17e8 (diff) |
spi: mediatek: fix spi cs polarity error
Mediatek spi HW can't set cs inactive(keep cs high) directly.
Instead, it supplies pause mode to do it indirectly. If driver
unsets SPI_CMD_PAUSE_MODE in CMD_REG, it also needs to reset
internal state machine to let cs inactive at once.
Signed-off-by: Leilk Liu <leilk.liu@mediatek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-mt65xx.c')
-rw-r--r-- | drivers/spi/spi-mt65xx.c | 27 |
1 files changed, 7 insertions, 20 deletions
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c index 5f6315c47920..b6073bbff8d9 100644 --- a/drivers/spi/spi-mt65xx.c +++ b/drivers/spi/spi-mt65xx.c | |||
@@ -173,22 +173,6 @@ static void mtk_spi_config(struct mtk_spi *mdata, | |||
173 | writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG); | 173 | writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG); |
174 | } | 174 | } |
175 | 175 | ||
176 | static int mtk_spi_prepare_hardware(struct spi_master *master) | ||
177 | { | ||
178 | struct spi_transfer *trans; | ||
179 | struct mtk_spi *mdata = spi_master_get_devdata(master); | ||
180 | struct spi_message *msg = master->cur_msg; | ||
181 | |||
182 | trans = list_first_entry(&msg->transfers, struct spi_transfer, | ||
183 | transfer_list); | ||
184 | if (!trans->cs_change) { | ||
185 | mdata->state = MTK_SPI_IDLE; | ||
186 | mtk_spi_reset(mdata); | ||
187 | } | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int mtk_spi_prepare_message(struct spi_master *master, | 176 | static int mtk_spi_prepare_message(struct spi_master *master, |
193 | struct spi_message *msg) | 177 | struct spi_message *msg) |
194 | { | 178 | { |
@@ -228,11 +212,15 @@ static void mtk_spi_set_cs(struct spi_device *spi, bool enable) | |||
228 | struct mtk_spi *mdata = spi_master_get_devdata(spi->master); | 212 | struct mtk_spi *mdata = spi_master_get_devdata(spi->master); |
229 | 213 | ||
230 | reg_val = readl(mdata->base + SPI_CMD_REG); | 214 | reg_val = readl(mdata->base + SPI_CMD_REG); |
231 | if (!enable) | 215 | if (!enable) { |
232 | reg_val |= SPI_CMD_PAUSE_EN; | 216 | reg_val |= SPI_CMD_PAUSE_EN; |
233 | else | 217 | writel(reg_val, mdata->base + SPI_CMD_REG); |
218 | } else { | ||
234 | reg_val &= ~SPI_CMD_PAUSE_EN; | 219 | reg_val &= ~SPI_CMD_PAUSE_EN; |
235 | writel(reg_val, mdata->base + SPI_CMD_REG); | 220 | writel(reg_val, mdata->base + SPI_CMD_REG); |
221 | mdata->state = MTK_SPI_IDLE; | ||
222 | mtk_spi_reset(mdata); | ||
223 | } | ||
236 | } | 224 | } |
237 | 225 | ||
238 | static void mtk_spi_prepare_transfer(struct spi_master *master, | 226 | static void mtk_spi_prepare_transfer(struct spi_master *master, |
@@ -509,7 +497,6 @@ static int mtk_spi_probe(struct platform_device *pdev) | |||
509 | master->mode_bits = SPI_CPOL | SPI_CPHA; | 497 | master->mode_bits = SPI_CPOL | SPI_CPHA; |
510 | 498 | ||
511 | master->set_cs = mtk_spi_set_cs; | 499 | master->set_cs = mtk_spi_set_cs; |
512 | master->prepare_transfer_hardware = mtk_spi_prepare_hardware; | ||
513 | master->prepare_message = mtk_spi_prepare_message; | 500 | master->prepare_message = mtk_spi_prepare_message; |
514 | master->transfer_one = mtk_spi_transfer_one; | 501 | master->transfer_one = mtk_spi_transfer_one; |
515 | master->can_dma = mtk_spi_can_dma; | 502 | master->can_dma = mtk_spi_can_dma; |