aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-mt65xx.c45
-rw-r--r--include/linux/platform_data/spi-mt65xx.h2
2 files changed, 42 insertions, 5 deletions
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 278867a31950..eae73b58248b 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -35,11 +35,15 @@
35#define SPI_CMD_REG 0x0018 35#define SPI_CMD_REG 0x0018
36#define SPI_STATUS0_REG 0x001c 36#define SPI_STATUS0_REG 0x001c
37#define SPI_PAD_SEL_REG 0x0024 37#define SPI_PAD_SEL_REG 0x0024
38#define SPI_CFG2_REG 0x0028
38 39
39#define SPI_CFG0_SCK_HIGH_OFFSET 0 40#define SPI_CFG0_SCK_HIGH_OFFSET 0
40#define SPI_CFG0_SCK_LOW_OFFSET 8 41#define SPI_CFG0_SCK_LOW_OFFSET 8
41#define SPI_CFG0_CS_HOLD_OFFSET 16 42#define SPI_CFG0_CS_HOLD_OFFSET 16
42#define SPI_CFG0_CS_SETUP_OFFSET 24 43#define SPI_CFG0_CS_SETUP_OFFSET 24
44#define SPI_ADJUST_CFG0_SCK_LOW_OFFSET 16
45#define SPI_ADJUST_CFG0_CS_HOLD_OFFSET 0
46#define SPI_ADJUST_CFG0_CS_SETUP_OFFSET 16
43 47
44#define SPI_CFG1_CS_IDLE_OFFSET 0 48#define SPI_CFG1_CS_IDLE_OFFSET 0
45#define SPI_CFG1_PACKET_LOOP_OFFSET 8 49#define SPI_CFG1_PACKET_LOOP_OFFSET 8
@@ -55,6 +59,8 @@
55#define SPI_CMD_RST BIT(2) 59#define SPI_CMD_RST BIT(2)
56#define SPI_CMD_PAUSE_EN BIT(4) 60#define SPI_CMD_PAUSE_EN BIT(4)
57#define SPI_CMD_DEASSERT BIT(5) 61#define SPI_CMD_DEASSERT BIT(5)
62#define SPI_CMD_SAMPLE_SEL BIT(6)
63#define SPI_CMD_CS_POL BIT(7)
58#define SPI_CMD_CPHA BIT(8) 64#define SPI_CMD_CPHA BIT(8)
59#define SPI_CMD_CPOL BIT(9) 65#define SPI_CMD_CPOL BIT(9)
60#define SPI_CMD_RX_DMA BIT(10) 66#define SPI_CMD_RX_DMA BIT(10)
@@ -80,6 +86,8 @@ struct mtk_spi_compatible {
80 bool need_pad_sel; 86 bool need_pad_sel;
81 /* Must explicitly send dummy Tx bytes to do Rx only transfer */ 87 /* Must explicitly send dummy Tx bytes to do Rx only transfer */
82 bool must_tx; 88 bool must_tx;
89 /* some IC design adjust cfg register to enhance time accuracy */
90 bool enhance_timing;
83}; 91};
84 92
85struct mtk_spi { 93struct mtk_spi {
@@ -108,6 +116,8 @@ static const struct mtk_spi_compatible mt8173_compat = {
108static const struct mtk_chip_config mtk_default_chip_info = { 116static const struct mtk_chip_config mtk_default_chip_info = {
109 .rx_mlsb = 1, 117 .rx_mlsb = 1,
110 .tx_mlsb = 1, 118 .tx_mlsb = 1,
119 .cs_pol = 0,
120 .sample_sel = 0,
111}; 121};
112 122
113static const struct of_device_id mtk_spi_of_match[] = { 123static const struct of_device_id mtk_spi_of_match[] = {
@@ -182,6 +192,17 @@ static int mtk_spi_prepare_message(struct spi_master *master,
182 reg_val |= SPI_CMD_RX_ENDIAN; 192 reg_val |= SPI_CMD_RX_ENDIAN;
183#endif 193#endif
184 194
195 if (mdata->dev_comp->enhance_timing) {
196 if (chip_config->cs_pol)
197 reg_val |= SPI_CMD_CS_POL;
198 else
199 reg_val &= ~SPI_CMD_CS_POL;
200 if (chip_config->sample_sel)
201 reg_val |= SPI_CMD_SAMPLE_SEL;
202 else
203 reg_val &= ~SPI_CMD_SAMPLE_SEL;
204 }
205
185 /* set finish and pause interrupt always enable */ 206 /* set finish and pause interrupt always enable */
186 reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_IE; 207 reg_val |= SPI_CMD_FINISH_IE | SPI_CMD_PAUSE_IE;
187 208
@@ -233,11 +254,25 @@ static void mtk_spi_prepare_transfer(struct spi_master *master,
233 sck_time = (div + 1) / 2; 254 sck_time = (div + 1) / 2;
234 cs_time = sck_time * 2; 255 cs_time = sck_time * 2;
235 256
236 reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_HIGH_OFFSET); 257 if (mdata->dev_comp->enhance_timing) {
237 reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET); 258 reg_val |= (((sck_time - 1) & 0xffff)
238 reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET); 259 << SPI_CFG0_SCK_HIGH_OFFSET);
239 reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET); 260 reg_val |= (((sck_time - 1) & 0xffff)
240 writel(reg_val, mdata->base + SPI_CFG0_REG); 261 << SPI_ADJUST_CFG0_SCK_LOW_OFFSET);
262 writel(reg_val, mdata->base + SPI_CFG2_REG);
263 reg_val |= (((cs_time - 1) & 0xffff)
264 << SPI_ADJUST_CFG0_CS_HOLD_OFFSET);
265 reg_val |= (((cs_time - 1) & 0xffff)
266 << SPI_ADJUST_CFG0_CS_SETUP_OFFSET);
267 writel(reg_val, mdata->base + SPI_CFG0_REG);
268 } else {
269 reg_val |= (((sck_time - 1) & 0xff)
270 << SPI_CFG0_SCK_HIGH_OFFSET);
271 reg_val |= (((sck_time - 1) & 0xff) << SPI_CFG0_SCK_LOW_OFFSET);
272 reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_HOLD_OFFSET);
273 reg_val |= (((cs_time - 1) & 0xff) << SPI_CFG0_CS_SETUP_OFFSET);
274 writel(reg_val, mdata->base + SPI_CFG0_REG);
275 }
241 276
242 reg_val = readl(mdata->base + SPI_CFG1_REG); 277 reg_val = readl(mdata->base + SPI_CFG1_REG);
243 reg_val &= ~SPI_CFG1_CS_IDLE_MASK; 278 reg_val &= ~SPI_CFG1_CS_IDLE_MASK;
diff --git a/include/linux/platform_data/spi-mt65xx.h b/include/linux/platform_data/spi-mt65xx.h
index 54b04483976c..ba4e4bb70262 100644
--- a/include/linux/platform_data/spi-mt65xx.h
+++ b/include/linux/platform_data/spi-mt65xx.h
@@ -16,5 +16,7 @@
16struct mtk_chip_config { 16struct mtk_chip_config {
17 u32 tx_mlsb; 17 u32 tx_mlsb;
18 u32 rx_mlsb; 18 u32 rx_mlsb;
19 u32 cs_pol;
20 u32 sample_sel;
19}; 21};
20#endif 22#endif