aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi_imx.c73
1 files changed, 53 insertions, 20 deletions
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index 20cdee3b5a2e..60a52d173d8f 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -75,6 +75,7 @@ struct spi_imx_devtype_data {
75 int (*config)(struct spi_imx_data *, struct spi_imx_config *); 75 int (*config)(struct spi_imx_data *, struct spi_imx_config *);
76 void (*trigger)(struct spi_imx_data *); 76 void (*trigger)(struct spi_imx_data *);
77 int (*rx_available)(struct spi_imx_data *); 77 int (*rx_available)(struct spi_imx_data *);
78 void (*reset)(struct spi_imx_data *);
78}; 79};
79 80
80struct spi_imx_data { 81struct spi_imx_data {
@@ -213,7 +214,7 @@ static void __maybe_unused mx31_trigger(struct spi_imx_data *spi_imx)
213 writel(reg, spi_imx->base + MXC_CSPICTRL); 214 writel(reg, spi_imx->base + MXC_CSPICTRL);
214} 215}
215 216
216static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx, 217static int __maybe_unused spi_imx0_4_config(struct spi_imx_data *spi_imx,
217 struct spi_imx_config *config) 218 struct spi_imx_config *config)
218{ 219{
219 unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER; 220 unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER;
@@ -221,12 +222,7 @@ static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx,
221 reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) << 222 reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) <<
222 MX31_CSPICTRL_DR_SHIFT; 223 MX31_CSPICTRL_DR_SHIFT;
223 224
224 if (cpu_is_mx31()) 225 reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT;
225 reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT;
226 else if (cpu_is_mx25() || cpu_is_mx35()) {
227 reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT;
228 reg |= MX31_CSPICTRL_SSCTL;
229 }
230 226
231 if (config->mode & SPI_CPHA) 227 if (config->mode & SPI_CPHA)
232 reg |= MX31_CSPICTRL_PHA; 228 reg |= MX31_CSPICTRL_PHA;
@@ -235,10 +231,7 @@ static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx,
235 if (config->mode & SPI_CS_HIGH) 231 if (config->mode & SPI_CS_HIGH)
236 reg |= MX31_CSPICTRL_SSPOL; 232 reg |= MX31_CSPICTRL_SSPOL;
237 if (config->cs < 0) { 233 if (config->cs < 0) {
238 if (cpu_is_mx31()) 234 reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT;
239 reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT;
240 else if (cpu_is_mx25() || cpu_is_mx35())
241 reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT;
242 } 235 }
243 236
244 writel(reg, spi_imx->base + MXC_CSPICTRL); 237 writel(reg, spi_imx->base + MXC_CSPICTRL);
@@ -246,11 +239,43 @@ static int __maybe_unused mx31_config(struct spi_imx_data *spi_imx,
246 return 0; 239 return 0;
247} 240}
248 241
242static int __maybe_unused spi_imx0_7_config(struct spi_imx_data *spi_imx,
243 struct spi_imx_config *config)
244{
245 unsigned int reg = MX31_CSPICTRL_ENABLE | MX31_CSPICTRL_MASTER;
246
247 reg |= spi_imx_clkdiv_2(spi_imx->spi_clk, config->speed_hz) <<
248 MX31_CSPICTRL_DR_SHIFT;
249
250 reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT;
251 reg |= MX31_CSPICTRL_SSCTL;
252
253 if (config->mode & SPI_CPHA)
254 reg |= MX31_CSPICTRL_PHA;
255 if (config->mode & SPI_CPOL)
256 reg |= MX31_CSPICTRL_POL;
257 if (config->mode & SPI_CS_HIGH)
258 reg |= MX31_CSPICTRL_SSPOL;
259 if (config->cs < 0)
260 reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT;
261
262 writel(reg, spi_imx->base + MXC_CSPICTRL);
263
264 return 0;
265}
266
249static int __maybe_unused mx31_rx_available(struct spi_imx_data *spi_imx) 267static int __maybe_unused mx31_rx_available(struct spi_imx_data *spi_imx)
250{ 268{
251 return readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR; 269 return readl(spi_imx->base + MX31_CSPISTATUS) & MX31_STATUS_RR;
252} 270}
253 271
272static void __maybe_unused spi_imx0_4_reset(struct spi_imx_data *spi_imx)
273{
274 /* drain receive buffer */
275 while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR)
276 readl(spi_imx->base + MXC_CSPIRXDATA);
277}
278
254#define MX27_INTREG_RR (1 << 4) 279#define MX27_INTREG_RR (1 << 4)
255#define MX27_INTREG_TEEN (1 << 9) 280#define MX27_INTREG_TEEN (1 << 9)
256#define MX27_INTREG_RREN (1 << 13) 281#define MX27_INTREG_RREN (1 << 13)
@@ -313,6 +338,11 @@ static int __maybe_unused mx27_rx_available(struct spi_imx_data *spi_imx)
313 return readl(spi_imx->base + MXC_CSPIINT) & MX27_INTREG_RR; 338 return readl(spi_imx->base + MXC_CSPIINT) & MX27_INTREG_RR;
314} 339}
315 340
341static void __maybe_unused spi_imx0_0_reset(struct spi_imx_data *spi_imx)
342{
343 writel(1, spi_imx->base + MXC_RESET);
344}
345
316#define MX1_INTREG_RR (1 << 3) 346#define MX1_INTREG_RR (1 << 3)
317#define MX1_INTREG_TEEN (1 << 8) 347#define MX1_INTREG_TEEN (1 << 8)
318#define MX1_INTREG_RREN (1 << 11) 348#define MX1_INTREG_RREN (1 << 11)
@@ -369,6 +399,11 @@ static int __maybe_unused mx1_rx_available(struct spi_imx_data *spi_imx)
369 return readl(spi_imx->base + MXC_CSPIINT) & MX1_INTREG_RR; 399 return readl(spi_imx->base + MXC_CSPIINT) & MX1_INTREG_RR;
370} 400}
371 401
402static void __maybe_unused mx1_reset(struct spi_imx_data *spi_imx)
403{
404 writel(1, spi_imx->base + MXC_RESET);
405}
406
372/* 407/*
373 * These version numbers are taken from the Freescale driver. Unfortunately it 408 * These version numbers are taken from the Freescale driver. Unfortunately it
374 * doesn't support i.MX1, so this entry doesn't match the scheme. :-( 409 * doesn't support i.MX1, so this entry doesn't match the scheme. :-(
@@ -380,6 +415,7 @@ static struct spi_imx_devtype_data spi_imx_devtype_data[] __devinitdata = {
380 .config = mx1_config, 415 .config = mx1_config,
381 .trigger = mx1_trigger, 416 .trigger = mx1_trigger,
382 .rx_available = mx1_rx_available, 417 .rx_available = mx1_rx_available,
418 .reset = mx1_reset,
383 }, 419 },
384#endif 420#endif
385#ifdef CONFIG_SPI_IMX_VER_0_0 421#ifdef CONFIG_SPI_IMX_VER_0_0
@@ -388,22 +424,25 @@ static struct spi_imx_devtype_data spi_imx_devtype_data[] __devinitdata = {
388 .config = mx27_config, 424 .config = mx27_config,
389 .trigger = mx27_trigger, 425 .trigger = mx27_trigger,
390 .rx_available = mx27_rx_available, 426 .rx_available = mx27_rx_available,
427 .reset = spi_imx0_0_reset,
391 }, 428 },
392#endif 429#endif
393#ifdef CONFIG_SPI_IMX_VER_0_4 430#ifdef CONFIG_SPI_IMX_VER_0_4
394 [SPI_IMX_VER_0_4] = { 431 [SPI_IMX_VER_0_4] = {
395 .intctrl = mx31_intctrl, 432 .intctrl = mx31_intctrl,
396 .config = mx31_config, 433 .config = spi_imx0_4_config,
397 .trigger = mx31_trigger, 434 .trigger = mx31_trigger,
398 .rx_available = mx31_rx_available, 435 .rx_available = mx31_rx_available,
436 .reset = spi_imx0_4_reset,
399 }, 437 },
400#endif 438#endif
401#ifdef CONFIG_SPI_IMX_VER_0_7 439#ifdef CONFIG_SPI_IMX_VER_0_7
402 [SPI_IMX_VER_0_7] = { 440 [SPI_IMX_VER_0_7] = {
403 .intctrl = mx31_intctrl, 441 .intctrl = mx31_intctrl,
404 .config = mx31_config, 442 .config = spi_imx0_7_config,
405 .trigger = mx31_trigger, 443 .trigger = mx31_trigger,
406 .rx_available = mx31_rx_available, 444 .rx_available = mx31_rx_available,
445 .reset = spi_imx0_4_reset,
407 }, 446 },
408#endif 447#endif
409}; 448};
@@ -683,13 +722,7 @@ static int __devinit spi_imx_probe(struct platform_device *pdev)
683 clk_enable(spi_imx->clk); 722 clk_enable(spi_imx->clk);
684 spi_imx->spi_clk = clk_get_rate(spi_imx->clk); 723 spi_imx->spi_clk = clk_get_rate(spi_imx->clk);
685 724
686 if (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) 725 spi_imx->devtype_data.reset(spi_imx);
687 writel(1, spi_imx->base + MXC_RESET);
688
689 /* drain receive buffer */
690 if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35())
691 while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR)
692 readl(spi_imx->base + MXC_CSPIRXDATA);
693 726
694 spi_imx->devtype_data.intctrl(spi_imx, 0); 727 spi_imx->devtype_data.intctrl(spi_imx, 0);
695 728