static int atmel_spi_claim_bus(struct udevice *dev) { struct udevice *bus = dev_get_parent(dev); struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus); struct atmel_spi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); struct at91_spi *reg_base = bus_plat->regs; u32 cs = slave_plat->cs; u32 freq = priv->freq; u32 scbr, csrx, mode; scbr = (priv->bus_clk_rate + freq - 1) / freq; if (scbr > ATMEL_SPI_CSRx_SCBR_MAX) return -EINVAL; if (scbr < 1) scbr = 1; csrx = ATMEL_SPI_CSRx_SCBR(scbr); csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8); if (!(priv->mode & SPI_CPHA)) csrx |= ATMEL_SPI_CSRx_NCPHA; if (priv->mode & SPI_CPOL) csrx |= ATMEL_SPI_CSRx_CPOL; writel(csrx, ®_base->csr[cs]); mode = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS | ATMEL_SPI_MR_WDRBT | ATMEL_SPI_MR_PCS(~(1 << cs)); writel(mode, ®_base->mr); writel(ATMEL_SPI_CR_SPIEN, ®_base->cr); return 0; }
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) { struct atmel_spi_slave *as; unsigned int scbr; u32 csrx; void *regs; if (!spi_cs_is_valid(bus, cs)) return NULL; switch (bus) { case 0: regs = (void *)ATMEL_BASE_SPI0; break; #ifdef ATMEL_BASE_SPI1 case 1: regs = (void *)ATMEL_BASE_SPI1; break; #endif #ifdef ATMEL_BASE_SPI2 case 2: regs = (void *)ATMEL_BASE_SPI2; break; #endif #ifdef ATMEL_BASE_SPI3 case 3: regs = (void *)ATMEL_BASE_SPI3; break; #endif default: return NULL; } scbr = (get_spi_clk_rate(bus) + max_hz - 1) / max_hz; if (scbr > ATMEL_SPI_CSRx_SCBR_MAX) /* Too low max SCK rate */ return NULL; if (scbr < 1) scbr = 1; csrx = ATMEL_SPI_CSRx_SCBR(scbr); csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8); if (!(mode & SPI_CPHA)) csrx |= ATMEL_SPI_CSRx_NCPHA; if (mode & SPI_CPOL) csrx |= ATMEL_SPI_CSRx_CPOL; as = spi_alloc_slave(struct atmel_spi_slave, bus, cs); if (!as) return NULL; as->regs = regs; as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS | ATMEL_SPI_MR_PCS(~(1 << cs) & 0xf); if (spi_has_wdrbt(as)) as->mr |= ATMEL_SPI_MR_WDRBT; spi_writel(as, CSR(cs), csrx); return &as->slave; }
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) { struct atmel_spi_slave *as; unsigned int scbr; u32 csrx; void *regs; if (cs > 3 || !spi_cs_is_valid(bus, cs)) return NULL; switch (bus) { case 0: regs = (void *)SPI0_BASE; break; #ifdef SPI1_BASE case 1: regs = (void *)SPI1_BASE; break; #endif #ifdef SPI2_BASE case 2: regs = (void *)SPI2_BASE; break; #endif #ifdef SPI3_BASE case 3: regs = (void *)SPI3_BASE; break; #endif default: return NULL; } scbr = (get_spi_clk_rate(bus) + max_hz - 1) / max_hz; if (scbr > ATMEL_SPI_CSRx_SCBR_MAX) /* Too low max SCK rate */ return NULL; if (scbr < 1) scbr = 1; csrx = ATMEL_SPI_CSRx_SCBR(scbr); csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8); if (!(mode & SPI_CPHA)) csrx |= ATMEL_SPI_CSRx_NCPHA; if (mode & SPI_CPOL) csrx |= ATMEL_SPI_CSRx_CPOL; as = malloc(sizeof(struct atmel_spi_slave)); if (!as) return NULL; as->slave.bus = bus; as->slave.cs = cs; as->regs = regs; as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS | ATMEL_SPI_MR_PCS(~(1 << cs) & 0xf); spi_writel(as, CSR(cs), csrx); return &as->slave; }