]>
Commit | Line | Data |
---|---|---|
6325b778 GB |
1 | /* |
2 | * (C) Copyright 2009 | |
3 | * Frank Bodammer <[email protected]> | |
4 | * (C) Copyright 2009 Semihalf, Grzegorz Bernacki | |
5 | * | |
1a459660 | 6 | * SPDX-License-Identifier: GPL-2.0+ |
6325b778 GB |
7 | */ |
8 | ||
9 | #include <common.h> | |
10 | #include <asm/io.h> | |
11 | #include <malloc.h> | |
12 | #include <spi.h> | |
13 | #include <mpc5xxx.h> | |
14 | ||
15 | void spi_init(void) | |
16 | { | |
17 | struct mpc5xxx_spi *spi = (struct mpc5xxx_spi *)MPC5XXX_SPI; | |
18 | /* | |
19 | * Its important to use the correct order when initializing the | |
20 | * registers | |
21 | */ | |
22 | out_8(&spi->ddr, 0x0F); /* set all SPI pins as output */ | |
23 | out_8(&spi->pdr, 0x00); /* set SS low */ | |
24 | /* SPI is master, SS is general purpose output */ | |
25 | out_8(&spi->cr1, SPI_CR_MSTR | SPI_CR_SPE); | |
26 | out_8(&spi->cr2, 0x00); /* normal operation */ | |
27 | out_8(&spi->brr, 0x77); /* baud rate: IPB clock / 2048 */ | |
28 | } | |
29 | ||
30 | struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, | |
31 | unsigned int max_hz, unsigned int mode) | |
32 | { | |
33 | struct spi_slave *slave; | |
34 | ||
d3504fee | 35 | slave = spi_alloc_slave_base(bus, cs); |
6325b778 GB |
36 | if (!slave) |
37 | return NULL; | |
38 | ||
6325b778 GB |
39 | return slave; |
40 | } | |
41 | ||
42 | void spi_free_slave(struct spi_slave *slave) | |
43 | { | |
44 | free(slave); | |
45 | } | |
46 | ||
47 | int spi_claim_bus(struct spi_slave *slave) | |
48 | { | |
49 | return 0; | |
50 | } | |
51 | ||
52 | void spi_release_bus(struct spi_slave *slave) | |
53 | { | |
54 | return; | |
55 | } | |
56 | ||
57 | int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, | |
58 | void *din, unsigned long flags) | |
59 | { | |
60 | struct mpc5xxx_spi *spi = (struct mpc5xxx_spi *)MPC5XXX_SPI; | |
61 | int i, iter = bitlen >> 3; | |
62 | const uchar *txp = dout; | |
63 | uchar *rxp = din; | |
64 | ||
65 | debug("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n", | |
66 | slave->bus, slave->cs, *(uint *) dout, *(uint *) din, bitlen); | |
67 | ||
68 | if (flags & SPI_XFER_BEGIN) | |
69 | setbits_8(&spi->pdr, SPI_PDR_SS); | |
70 | ||
71 | for (i = 0; i < iter; i++) { | |
72 | udelay(1000); | |
73 | debug("spi_xfer: sending %x\n", txp[i]); | |
74 | out_8(&spi->dr, txp[i]); | |
75 | while (!(in_8(&spi->sr) & SPI_SR_SPIF)) { | |
76 | udelay(1000); | |
77 | if (in_8(&spi->sr) & SPI_SR_WCOL) { | |
78 | rxp[i] = in_8(&spi->dr); | |
79 | puts("spi_xfer: write collision\n"); | |
80 | return -1; | |
81 | } | |
82 | } | |
83 | rxp[i] = in_8(&spi->dr); | |
84 | debug("spi_xfer: received %x\n", rxp[i]); | |
85 | } | |
86 | if (flags & SPI_XFER_END) | |
87 | clrbits_8(&spi->pdr, SPI_PDR_SS); | |
88 | ||
89 | return 0; | |
90 | } |