]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/spi/davinci_spi.c
Merge branch 'master' into next
[karo-tx-uboot.git] / drivers / spi / davinci_spi.c
1 /*
2  * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
3  *
4  * Driver for SPI controller on DaVinci. Based on atmel_spi.c
5  * by Atmel Corporation
6  *
7  * Copyright (C) 2007 Atmel Corporation
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License as
14  * published by the Free Software Foundation; either version 2 of
15  * the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25  * MA 02111-1307 USA
26  */
27 #include <common.h>
28 #include <spi.h>
29 #include <malloc.h>
30 #include <asm/io.h>
31 #include <asm/arch/hardware.h>
32 #include "davinci_spi.h"
33
34 void spi_init()
35 {
36         /* do nothing */
37 }
38
39 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
40                         unsigned int max_hz, unsigned int mode)
41 {
42         struct davinci_spi_slave        *ds;
43
44         if (!spi_cs_is_valid(bus, cs))
45                 return NULL;
46
47         ds = malloc(sizeof(*ds));
48         if (!ds)
49                 return NULL;
50
51         ds->slave.bus = bus;
52         ds->slave.cs = cs;
53         ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
54         ds->freq = max_hz;
55
56         return &ds->slave;
57 }
58
59 void spi_free_slave(struct spi_slave *slave)
60 {
61         struct davinci_spi_slave *ds = to_davinci_spi(slave);
62
63         free(ds);
64 }
65
66 int spi_claim_bus(struct spi_slave *slave)
67 {
68         struct davinci_spi_slave *ds = to_davinci_spi(slave);
69         unsigned int scalar, data1_reg_val = 0;
70
71         /* Enable the SPI hardware */
72         writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
73         udelay(1000);
74         writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0);
75
76         /* Set master mode, powered up and not activated */
77         writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
78
79         /* CS, CLK, SIMO and SOMI are functional pins */
80         writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
81                 SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
82
83         /* setup format */
84         scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF;
85
86         /*
87          * Use following format:
88          *   character length = 8,
89          *   clock signal delayed by half clk cycle,
90          *   clock low in idle state - Mode 0,
91          *   MSB shifted out first
92          */
93         writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) |
94                 (1 << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0);
95
96         /* hold cs active at end of transfer until explicitly de-asserted */
97         data1_reg_val = (1 << SPIDAT1_CSHOLD_SHIFT) |
98                         (slave->cs << SPIDAT1_CSNR_SHIFT);
99         writel(data1_reg_val, &ds->regs->dat1);
100
101         /*
102          * Including a minor delay. No science here. Should be good even with
103          * no delay
104          */
105         writel((50 << SPI_C2TDELAY_SHIFT) |
106                 (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay);
107
108         /* default chip select register */
109         writel(SPIDEF_CSDEF0_MASK, &ds->regs->def);
110
111         /* no interrupts */
112         writel(0, &ds->regs->int0);
113         writel(0, &ds->regs->lvl);
114
115         /* enable SPI */
116         writel((readl(&ds->regs->gcr1) |
117                 SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
118
119         return 0;
120 }
121
122 void spi_release_bus(struct spi_slave *slave)
123 {
124         struct davinci_spi_slave *ds = to_davinci_spi(slave);
125
126         /* Disable the SPI hardware */
127         writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
128 }
129
130 int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
131                 const void *dout, void *din, unsigned long flags)
132 {
133         struct davinci_spi_slave *ds = to_davinci_spi(slave);
134         unsigned int    len, data1_reg_val = readl(&ds->regs->dat1);
135         unsigned int    i_cnt = 0, o_cnt = 0, buf_reg_val;
136         const u8        *txp = dout; /* dout can be NULL for read operation */
137         u8              *rxp = din;  /* din can be NULL for write operation */
138
139         if (bitlen == 0)
140                 /* Finish any previously submitted transfers */
141                 goto out;
142
143         /*
144          * It's not clear how non-8-bit-aligned transfers are supposed to be
145          * represented as a stream of bytes...this is a limitation of
146          * the current SPI interface - here we terminate on receiving such a
147          * transfer request.
148          */
149         if (bitlen % 8) {
150                 /* Errors always terminate an ongoing transfer */
151                 flags |= SPI_XFER_END;
152                 goto out;
153         }
154
155         len = bitlen / 8;
156
157         /* do an empty read to clear the current contents */
158         readl(&ds->regs->buf);
159
160         /* keep writing and reading 1 byte until done */
161         while ((i_cnt < len) || (o_cnt < len)) {
162                 /* read RX buffer and flags */
163                 buf_reg_val = readl(&ds->regs->buf);
164
165                 /* if data is available */
166                 if ((i_cnt < len) &&
167                         (buf_reg_val & SPIBUF_RXEMPTY_MASK) == 0) {
168                         /*
169                          * If there is no read buffer simply
170                          * ignore the read character
171                          */
172                         if (rxp)
173                                 *rxp++ = buf_reg_val & 0xFF;
174                         /* increment read words count */
175                         i_cnt++;
176                 }
177
178                 /*
179                  * if the tx buffer is empty and there
180                  * is still data to transmit
181                  */
182                 if ((o_cnt < len) &&
183                         ((buf_reg_val & SPIBUF_TXFULL_MASK) == 0)) {
184                         /* write the data */
185                         data1_reg_val &= ~0xFFFF;
186                         if (txp)
187                                 data1_reg_val |= *txp++;
188                         /*
189                          * Write to DAT1 is required to keep
190                          * the serial transfer going.
191                          * We just terminate when we reach the end.
192                          */
193                         if ((o_cnt == (len - 1)) && (flags & SPI_XFER_END)) {
194                                 /* clear CS hold */
195                                 writel(data1_reg_val &
196                                                 ~(1 << SPIDAT1_CSHOLD_SHIFT),
197                                                 &ds->regs->dat1);
198                         } else {
199                                 /* enable CS hold and write TX register */
200                                 data1_reg_val |= ((1 << SPIDAT1_CSHOLD_SHIFT) |
201                                         (slave->cs << SPIDAT1_CSNR_SHIFT));
202                                 writel(data1_reg_val, &ds->regs->dat1);
203                         }
204                         /* increment written words count */
205                         o_cnt++;
206                 }
207         }
208         return 0;
209
210 out:
211         if (flags & SPI_XFER_END) {
212                 writel(data1_reg_val &
213                         ~(1 << SPIDAT1_CSHOLD_SHIFT), &ds->regs->dat1);
214         }
215         return 0;
216 }
217
218 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
219 {
220         return bus == 0 && cs == 0;
221 }
222
223 void spi_cs_activate(struct spi_slave *slave)
224 {
225         /* do nothing */
226 }
227
228 void spi_cs_deactivate(struct spi_slave *slave)
229 {
230         /* do nothing */
231 }