Lines Matching +full:cs +full:- +full:0

8  * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
17 * SPDX-License-Identifier: GPL-2.0+
29 #define OMAP3_MCSPI1_BASE 0x48030100
30 #define OMAP3_MCSPI2_BASE 0x481A0100
32 #define OMAP3_MCSPI1_BASE 0x48098000
33 #define OMAP3_MCSPI2_BASE 0x4809A000
34 #define OMAP3_MCSPI3_BASE 0x480B8000
35 #define OMAP3_MCSPI4_BASE 0x480BA000
38 #define OMAP4_MCSPI_REG_OFFSET 0x100
44 /* per-register bitmasks */
47 #define OMAP3_MCSPI_SYSCONFIG_AUTOIDLE BIT(0)
50 #define OMAP3_MCSPI_SYSSTATUS_RESETDONE BIT(0)
52 #define OMAP3_MCSPI_MODULCTRL_SINGLE BIT(0)
56 #define OMAP3_MCSPI_CHCONF_PHA BIT(0)
72 #define OMAP3_MCSPI_CHSTAT_RXS BIT(0)
76 #define OMAP3_MCSPI_CHCTRL_EN BIT(0)
77 #define OMAP3_MCSPI_CHCTRL_DIS (0 << 0)
79 #define OMAP3_MCSPI_WAKEUPENABLE_WKEN BIT(0)
80 #define MCSPI_PINDIR_D0_IN_D1_OUT 0
88 unsigned int chconf; /* 0x2C, 0x40, 0x54, 0x68 */
89 unsigned int chstat; /* 0x30, 0x44, 0x58, 0x6C */
90 unsigned int chctrl; /* 0x34, 0x48, 0x5C, 0x70 */
91 unsigned int tx; /* 0x38, 0x4C, 0x60, 0x74 */
92 unsigned int rx; /* 0x3C, 0x50, 0x64, 0x78 */
96 unsigned char res1[0x10];
97 unsigned int sysconfig; /* 0x10 */
98 unsigned int sysstatus; /* 0x14 */
99 unsigned int irqstatus; /* 0x18 */
100 unsigned int irqenable; /* 0x1C */
101 unsigned int wakeupenable; /* 0x20 */
102 unsigned int syst; /* 0x24 */
103 unsigned int modulctrl; /* 0x28 */
105 /* channel0: 0x2C - 0x3C, bus 0 & 1 & 2 & 3 */
106 /* channel1: 0x40 - 0x50, bus 0 & 1 */
107 /* channel2: 0x54 - 0x64, bus 0 & 1 */
108 /* channel3: 0x68 - 0x78, bus 0 */
116 unsigned int cs; member
125 writel(val, &priv->regs->channel[priv->cs].chconf); in omap3_spi_write_chconf()
127 readl(&priv->regs->channel[priv->cs].chconf); in omap3_spi_write_chconf()
132 writel(enable, &priv->regs->channel[priv->cs].chctrl); in omap3_spi_set_enable()
134 readl(&priv->regs->channel[priv->cs].chctrl); in omap3_spi_set_enable()
143 chconf = readl(&priv->regs->channel[priv->cs].chconf); in omap3_spi_write()
149 chconf |= (priv->wordlen - 1) << 7; in omap3_spi_write()
154 for (i = 0; i < len; i++) { in omap3_spi_write()
156 start = get_timer(0); in omap3_spi_write()
157 while (!(readl(&priv->regs->channel[priv->cs].chstat) & in omap3_spi_write()
160 printf("SPI TXS timed out, status=0x%08x\n", in omap3_spi_write()
161 readl(&priv->regs->channel[priv->cs].chstat)); in omap3_spi_write()
162 return -1; in omap3_spi_write()
166 unsigned int *tx = &priv->regs->channel[priv->cs].tx; in omap3_spi_write()
167 if (priv->wordlen > 16) in omap3_spi_write()
169 else if (priv->wordlen > 8) in omap3_spi_write()
176 while ((readl(&priv->regs->channel[priv->cs].chstat) & in omap3_spi_write()
189 return 0; in omap3_spi_write()
198 chconf = readl(&priv->regs->channel[priv->cs].chconf); in omap3_spi_read()
204 chconf |= (priv->wordlen - 1) << 7; in omap3_spi_read()
209 writel(0, &priv->regs->channel[priv->cs].tx); in omap3_spi_read()
211 for (i = 0; i < len; i++) { in omap3_spi_read()
212 start = get_timer(0); in omap3_spi_read()
214 while (!(readl(&priv->regs->channel[priv->cs].chstat) & in omap3_spi_read()
217 printf("SPI RXS timed out, status=0x%08x\n", in omap3_spi_read()
218 readl(&priv->regs->channel[priv->cs].chstat)); in omap3_spi_read()
219 return -1; in omap3_spi_read()
224 if (i == (len - 1)) in omap3_spi_read()
228 unsigned int *rx = &priv->regs->channel[priv->cs].rx; in omap3_spi_read()
229 if (priv->wordlen > 16) in omap3_spi_read()
231 else if (priv->wordlen > 8) in omap3_spi_read()
242 return 0; in omap3_spi_read()
250 int chconf, i = 0; in omap3_spi_txrx()
252 chconf = readl(&priv->regs->channel[priv->cs].chconf); in omap3_spi_txrx()
257 /*set TRANSMIT-RECEIVE Mode*/ in omap3_spi_txrx()
259 chconf |= (priv->wordlen - 1) << 7; in omap3_spi_txrx()
264 for (i=0; i < len; i++){ in omap3_spi_txrx()
266 start = get_timer(0); in omap3_spi_txrx()
267 while (!(readl(&priv->regs->channel[priv->cs].chstat) & in omap3_spi_txrx()
270 printf("SPI TXS timed out, status=0x%08x\n", in omap3_spi_txrx()
271 readl(&priv->regs->channel[priv->cs].chstat)); in omap3_spi_txrx()
272 return -1; in omap3_spi_txrx()
276 unsigned int *tx = &priv->regs->channel[priv->cs].tx; in omap3_spi_txrx()
277 if (priv->wordlen > 16) in omap3_spi_txrx()
279 else if (priv->wordlen > 8) in omap3_spi_txrx()
285 start = get_timer(0); in omap3_spi_txrx()
286 while (!(readl(&priv->regs->channel[priv->cs].chstat) & in omap3_spi_txrx()
289 printf("SPI RXS timed out, status=0x%08x\n", in omap3_spi_txrx()
290 readl(&priv->regs->channel[priv->cs].chstat)); in omap3_spi_txrx()
291 return -1; in omap3_spi_txrx()
295 unsigned int *rx = &priv->regs->channel[priv->cs].rx; in omap3_spi_txrx()
296 if (priv->wordlen > 16) in omap3_spi_txrx()
298 else if (priv->wordlen > 8) in omap3_spi_txrx()
312 return 0; in omap3_spi_txrx()
319 int ret = -1; in _spi_xfer()
321 if (priv->wordlen < 4 || priv->wordlen > 32) { in _spi_xfer()
322 printf("omap3_spi: invalid wordlen %d\n", priv->wordlen); in _spi_xfer()
323 return -1; in _spi_xfer()
326 if (bitlen % priv->wordlen) in _spi_xfer()
327 return -1; in _spi_xfer()
329 len = bitlen / priv->wordlen; in _spi_xfer()
331 if (bitlen == 0) { /* only change CS */ in _spi_xfer()
332 int chconf = readl(&priv->regs->channel[priv->cs].chconf); in _spi_xfer()
344 ret = 0; in _spi_xfer()
358 uint32_t confr, div = 0; in _omap3_spi_set_speed()
360 confr = readl(&priv->regs->channel[priv->cs].chconf); in _omap3_spi_set_speed()
362 /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */ in _omap3_spi_set_speed()
363 if (priv->freq) { in _omap3_spi_set_speed()
364 while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div)) in _omap3_spi_set_speed()
365 > priv->freq) in _omap3_spi_set_speed()
368 div = 0xC; in _omap3_spi_set_speed()
382 confr = readl(&priv->regs->channel[priv->cs].chconf); in _omap3_spi_set_mode()
384 /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS in _omap3_spi_set_mode()
387 if (priv->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) { in _omap3_spi_set_mode()
395 /* set SPI mode 0..3 */ in _omap3_spi_set_mode()
397 if (priv->mode & SPI_CPHA) in _omap3_spi_set_mode()
399 if (priv->mode & SPI_CPOL) in _omap3_spi_set_mode()
403 if (!(priv->mode & SPI_CS_HIGH)) in _omap3_spi_set_mode()
404 confr |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */ in _omap3_spi_set_mode()
419 confr = readl(&priv->regs->channel[priv->wordlen].chconf); in _omap3_spi_set_wordlen()
423 confr |= (priv->wordlen - 1) << 7; in _omap3_spi_set_wordlen()
432 writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, &regs->sysconfig); in spi_reset()
434 tmp = readl(&regs->sysstatus); in spi_reset()
439 OMAP3_MCSPI_SYSCONFIG_SMARTIDLE, &regs->sysconfig); in spi_reset()
441 writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &regs->wakeupenable); in spi_reset()
448 spi_reset(priv->regs); in _omap3_spi_claim_bus()
452 * to single-channel master mode in _omap3_spi_claim_bus()
454 conf = readl(&priv->regs->modulctrl); in _omap3_spi_claim_bus()
458 writel(conf, &priv->regs->modulctrl); in _omap3_spi_claim_bus()
489 return 0; in spi_claim_bus()
497 spi_reset(priv->regs); in spi_release_bus()
500 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, in spi_setup_slave() argument
508 * with different number of chip selects (CS, channels): in spi_setup_slave()
509 * McSPI1 has 4 CS (bus 0, cs 0 - 3) in spi_setup_slave()
510 * McSPI2 has 2 CS (bus 1, cs 0 - 1) in spi_setup_slave()
511 * McSPI3 has 2 CS (bus 2, cs 0 - 1) in spi_setup_slave()
512 * McSPI4 has 1 CS (bus 3, cs 0) in spi_setup_slave()
516 case 0: in spi_setup_slave()
535 printf("SPI error: unsupported bus %i. Supported busses 0 - 3\n", bus); in spi_setup_slave()
539 if (((bus == 0) && (cs > 3)) || in spi_setup_slave()
540 ((bus == 1) && (cs > 1)) || in spi_setup_slave()
541 ((bus == 2) && (cs > 1)) || in spi_setup_slave()
542 ((bus == 3) && (cs > 0))) { in spi_setup_slave()
543 printf("SPI error: unsupported chip select %i on bus %i\n", cs, bus); in spi_setup_slave()
558 priv = spi_alloc_slave(struct omap3_spi_priv, bus, cs); in spi_setup_slave()
564 priv->regs = regs; in spi_setup_slave()
565 priv->cs = cs; in spi_setup_slave()
566 priv->freq = max_hz; in spi_setup_slave()
567 priv->mode = mode; in spi_setup_slave()
568 priv->wordlen = priv->slave.wordlen; in spi_setup_slave()
569 #if 0 in spi_setup_slave()
571 priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; in spi_setup_slave()
574 return &priv->slave; in spi_setup_slave()
589 struct udevice *bus = dev->parent; in omap3_spi_claim_bus()
593 priv->cs = slave_plat->cs; in omap3_spi_claim_bus()
596 return 0; in omap3_spi_claim_bus()
601 struct udevice *bus = dev->parent; in omap3_spi_release_bus()
605 spi_reset(priv->regs); in omap3_spi_release_bus()
607 return 0; in omap3_spi_release_bus()
612 struct udevice *bus = dev->parent; in omap3_spi_set_wordlen()
616 priv->cs = slave_plat->cs; in omap3_spi_set_wordlen()
617 priv->wordlen = wordlen; in omap3_spi_set_wordlen()
620 return 0; in omap3_spi_set_wordlen()
626 const void *blob = gd->fdt_blob; in omap3_spi_probe()
632 priv->regs = (struct mcspi *)(devfdt_get_addr(dev) + data->regs_offset); in omap3_spi_probe()
633 if (fdtdec_get_bool(blob, node, "ti,pindir-d0-out-d1-in")) in omap3_spi_probe()
634 priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; in omap3_spi_probe()
636 priv->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT; in omap3_spi_probe()
637 priv->wordlen = SPI_DEFAULT_WORDLEN; in omap3_spi_probe()
638 return 0; in omap3_spi_probe()
644 struct udevice *bus = dev->parent; in omap3_spi_xfer()
652 struct udevice *bus = dev->parent; in omap3_spi_set_speed()
656 priv->cs = slave_plat->cs; in omap3_spi_set_speed()
657 priv->freq = slave_plat->max_hz; in omap3_spi_set_speed()
660 return 0; in omap3_spi_set_speed()
665 struct udevice *bus = dev->parent; in omap3_spi_set_mode()
669 priv->cs = slave_plat->cs; in omap3_spi_set_mode()
670 priv->mode = slave_plat->mode; in omap3_spi_set_mode()
673 return 0; in omap3_spi_set_mode()
690 .regs_offset = 0,
698 { .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata },
699 { .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata },