]>
git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/spi/davinci_spi.c
2 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
4 * Driver for SPI controller on DaVinci. Based on atmel_spi.c
7 * Copyright (C) 2007 Atmel Corporation
9 * See file CREDITS for list of people who contributed to this
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.
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.
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,
31 #include <asm/arch/hardware.h>
32 #include "davinci_spi.h"
39 struct spi_slave
*spi_setup_slave(unsigned int bus
, unsigned int cs
,
40 unsigned int max_hz
, unsigned int mode
)
42 struct davinci_spi_slave
*ds
;
44 if (!spi_cs_is_valid(bus
, cs
))
47 ds
= malloc(sizeof(*ds
));
53 ds
->regs
= (struct davinci_spi_regs
*)CONFIG_SYS_SPI_BASE
;
59 void spi_free_slave(struct spi_slave
*slave
)
61 struct davinci_spi_slave
*ds
= to_davinci_spi(slave
);
66 int spi_claim_bus(struct spi_slave
*slave
)
68 struct davinci_spi_slave
*ds
= to_davinci_spi(slave
);
69 unsigned int scalar
, data1_reg_val
= 0;
71 /* Enable the SPI hardware */
72 writel(SPIGCR0_SPIRST_MASK
, &ds
->regs
->gcr0
);
74 writel(SPIGCR0_SPIENA_MASK
, &ds
->regs
->gcr0
);
76 /* Set master mode, powered up and not activated */
77 writel(SPIGCR1_MASTER_MASK
| SPIGCR1_CLKMOD_MASK
, &ds
->regs
->gcr1
);
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
);
84 scalar
= ((CONFIG_SYS_SPI_CLK
/ ds
->freq
) - 1) & 0xFF;
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
93 writel(8 | (scalar
<< SPIFMT_PRESCALE_SHIFT
) |
94 (1 << SPIFMT_PHASE_SHIFT
), &ds
->regs
->fmt0
);
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
);
102 * Including a minor delay. No science here. Should be good even with
105 writel((50 << SPI_C2TDELAY_SHIFT
) |
106 (50 << SPI_T2CDELAY_SHIFT
), &ds
->regs
->delay
);
108 /* default chip select register */
109 writel(SPIDEF_CSDEF0_MASK
, &ds
->regs
->def
);
112 writel(0, &ds
->regs
->int0
);
113 writel(0, &ds
->regs
->lvl
);
116 writel((readl(&ds
->regs
->gcr1
) |
117 SPIGCR1_SPIENA_MASK
), &ds
->regs
->gcr1
);
122 void spi_release_bus(struct spi_slave
*slave
)
124 struct davinci_spi_slave
*ds
= to_davinci_spi(slave
);
126 /* Disable the SPI hardware */
127 writel(SPIGCR0_SPIRST_MASK
, &ds
->regs
->gcr0
);
130 int spi_xfer(struct spi_slave
*slave
, unsigned int bitlen
,
131 const void *dout
, void *din
, unsigned long flags
)
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 */
140 /* Finish any previously submitted transfers */
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
150 /* Errors always terminate an ongoing transfer */
151 flags
|= SPI_XFER_END
;
157 /* do an empty read to clear the current contents */
158 readl(&ds
->regs
->buf
);
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
);
165 /* if data is available */
167 (buf_reg_val
& SPIBUF_RXEMPTY_MASK
) == 0) {
169 * If there is no read buffer simply
170 * ignore the read character
173 *rxp
++ = buf_reg_val
& 0xFF;
174 /* increment read words count */
179 * if the tx buffer is empty and there
180 * is still data to transmit
183 ((buf_reg_val
& SPIBUF_TXFULL_MASK
) == 0)) {
185 data1_reg_val
&= ~0xFFFF;
187 data1_reg_val
|= *txp
++;
189 * Write to DAT1 is required to keep
190 * the serial transfer going.
191 * We just terminate when we reach the end.
193 if ((o_cnt
== (len
- 1)) && (flags
& SPI_XFER_END
)) {
195 writel(data1_reg_val
&
196 ~(1 << SPIDAT1_CSHOLD_SHIFT
),
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
);
204 /* increment written words count */
211 if (flags
& SPI_XFER_END
) {
212 writel(data1_reg_val
&
213 ~(1 << SPIDAT1_CSHOLD_SHIFT
), &ds
->regs
->dat1
);
218 int spi_cs_is_valid(unsigned int bus
, unsigned int cs
)
220 return bus
== 0 && cs
== 0;
223 void spi_cs_activate(struct spi_slave
*slave
)
228 void spi_cs_deactivate(struct spi_slave
*slave
)