]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/spi/davinci_spi.c
Prepare v2010.03-rc1
[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) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
117
118         return 0;
119 }
120
121 void spi_release_bus(struct spi_slave *slave)
122 {
123         struct davinci_spi_slave *ds = to_davinci_spi(slave);
124
125         /* Disable the SPI hardware */
126         writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
127 }
128
129 int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
130                 const void *dout, void *din, unsigned long flags)
131 {
132         struct davinci_spi_slave *ds = to_davinci_spi(slave);
133         unsigned int    len, data1_reg_val = readl(&ds->regs->dat1);
134         int             ret, i;
135         const u8        *txp = dout; /* dout can be NULL for read operation */
136         u8              *rxp = din;  /* din can be NULL for write operation */
137
138         ret = 0;
139
140         if (bitlen == 0)
141                 /* Finish any previously submitted transfers */
142                 goto out;
143
144         /*
145          * It's not clear how non-8-bit-aligned transfers are supposed to be
146          * represented as a stream of bytes...this is a limitation of
147          * the current SPI interface - here we terminate on receiving such a
148          * transfer request.
149          */
150         if (bitlen % 8) {
151                 /* Errors always terminate an ongoing transfer */
152                 flags |= SPI_XFER_END;
153                 goto out;
154         }
155
156         len = bitlen / 8;
157
158         /* do an empty read to clear the current contents */
159         readl(&ds->regs->buf);
160
161         /* keep writing and reading 1 byte until done */
162         for (i = 0; i < len; i++) {
163                 /* wait till TXFULL is asserted */
164                 while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK);
165
166                 /* write the data */
167                 data1_reg_val &= ~0xFFFF;
168                 if (txp) {
169                         data1_reg_val |= *txp;
170                         txp++;
171                 }
172
173                 /*
174                  * Write to DAT1 is required to keep the serial transfer going.
175                  * We just terminate when we reach the end.
176                  */
177                 if ((i == (len - 1)) && (flags & SPI_XFER_END)) {
178                         /* clear CS hold */
179                         writel(data1_reg_val &
180                                 ~(1 << SPIDAT1_CSHOLD_SHIFT), &ds->regs->dat1);
181                 } else {
182                         /* enable CS hold */
183                         data1_reg_val |= ((1 << SPIDAT1_CSHOLD_SHIFT) |
184                                         (slave->cs << SPIDAT1_CSNR_SHIFT));
185                         writel(data1_reg_val, &ds->regs->dat1);
186                 }
187
188                 /* read the data - wait for data availability */
189                 while (readl(&ds->regs->buf) & SPIBUF_RXEMPTY_MASK);
190
191                 if (rxp) {
192                         *rxp = readl(&ds->regs->buf) & 0xFF;
193                         rxp++;
194                 } else {
195                         /* simply drop the read character */
196                         readl(&ds->regs->buf);
197                 }
198         }
199         return 0;
200
201 out:
202         if (flags & SPI_XFER_END) {
203                 writel(data1_reg_val &
204                         ~(1 << SPIDAT1_CSHOLD_SHIFT), &ds->regs->dat1);
205         }
206         return 0;
207 }
208
209 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
210 {
211         return bus == 0 && cs == 0;
212 }
213
214 void spi_cs_activate(struct spi_slave *slave)
215 {
216         /* do nothing */
217 }
218
219 void spi_cs_deactivate(struct spi_slave *slave)
220 {
221         /* do nothing */
222 }