2 * BRIEF MODULE DESCRIPTION
4 * uWire interface driver for the OMAP Platform
6 * Copyright 2003 MontaVista Software Inc.
7 * Author: MontaVista Software, Inc.
10 * Ported to 2.6 uwire interface.
11 * Copyright (C) 2004 Texas Instruments.
13 * Generalization patches by Juha Yrjölä <juha.yrjola@nokia.com>
15 * This program is free software; you can redistribute it and/or modify it
16 * under the terms of the GNU General Public License as published by the
17 * Free Software Foundation; either version 2 of the License, or (at your
18 * option) any later version.
20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
23 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * You should have received a copy of the GNU General Public License along
32 * with this program; if not, write to the Free Software Foundation, Inc.,
33 * 675 Mass Ave, Cambridge, MA 02139, USA.
36 #include <linux/module.h>
37 #include <linux/init.h>
38 #include <linux/sched.h>
39 #include <linux/errno.h>
40 #include <linux/delay.h>
42 #include <asm/system.h>
44 #include <asm/hardware.h>
46 #include <asm/mach-types.h>
47 #include <asm/arch/mux.h>
48 #include <asm/arch/omap730.h> /* OMAP730_IO_CONF registers */
50 #include "omap-uwire.h"
52 /* uWire Registers: */
53 #define UWIRE_BASE 0xFFFB3000
54 #define UWIRE_IO_SIZE 0x20
55 #define UWIRE_TDR 0x00
56 #define UWIRE_RDR 0x00
57 #define UWIRE_CSR 0x01
58 #define UWIRE_SR1 0x02
59 #define UWIRE_SR2 0x03
60 #define UWIRE_SR3 0x04
61 #define UWIRE_SR4 0x05
62 #define UWIRE_SR5 0x06
64 static unsigned short uwire_flags[4];
65 static unsigned long uwire_base = io_p2v(UWIRE_BASE);
66 static spinlock_t uwire_lock;
67 static unsigned int uwire_idx_shift;
69 static inline void uwire_write_reg(int idx, u16 val)
71 __raw_writew(val, uwire_base + (idx << uwire_idx_shift));
74 static inline u16 uwire_read_reg(int idx)
76 return __raw_readw(uwire_base + (idx << uwire_idx_shift));
79 void omap_uwire_configure_mode(int cs, unsigned long flags)
87 if (flags & UWIRE_CLK_INVERTED)
97 spin_lock(&uwire_lock);
98 w = uwire_read_reg(reg);
99 w &= ~(0x3f << shift);
101 uwire_write_reg(reg, w);
102 spin_unlock(&uwire_lock);
104 uwire_flags[cs] = flags;
107 static int wait_uwire_csr_flag(u16 mask, u16 val, int might_not_catch)
111 unsigned long max_jiffies = jiffies + HZ;
114 w = uwire_read_reg(UWIRE_CSR);
115 if ((w & mask) == val)
117 if (time_after(jiffies, max_jiffies)) {
118 printk(KERN_ERR "%s: timeout. reg=%#06x mask=%#06x val=%#06x\n",
119 __FUNCTION__, w, mask, val);
123 if (might_not_catch && c > 64)
129 int omap_uwire_data_transfer(int cs, u16 tx_data, int tx_size, int rx_size,
130 u16 *rx_buf, int leave_cs_active)
136 BUG_ON(rx_size && !rx_buf);
138 spin_lock(&uwire_lock);
140 if (wait_uwire_csr_flag(1 << 14, 0, 0))
143 if (uwire_flags[cs] & UWIRE_CLK_INVERTED)
144 uwire_write_reg(UWIRE_SR4, 1);
146 uwire_write_reg(UWIRE_SR4, 0);
149 w |= 1 << 12; /* CS_CMD : activate CS */
150 uwire_write_reg(UWIRE_CSR, w);
152 /* Shift data to 16bit MSb and place it in TX register. */
153 uwire_write_reg(UWIRE_TDR, tx_data << (16 - tx_size));
155 if (wait_uwire_csr_flag(1 << 14, 0, 0))
158 w = rx_size | (tx_size << 5) | (cs << 10);
159 w |= (1 << 12) | (1 << 13);
160 /* Start uWire read/write */
161 uwire_write_reg(UWIRE_CSR, w);
163 /* Wait till read/write actually starts.
164 * This is needed at high (>=60MHz) MPU frequencies
165 * REVISIT: But occasionally we won't have time to catch it
167 if (wait_uwire_csr_flag(1 << 14, 1 << 14, 1))
170 /* Wait for both transfers to be completed */
171 mask = 1 << 14; /* CSRB : reg busy */
174 mask |= 1 << 15; /* RDRB : reg busy */
178 if (wait_uwire_csr_flag(mask, w, 0))
182 *rx_buf = uwire_read_reg(UWIRE_RDR);
184 if (!leave_cs_active)
185 uwire_write_reg(UWIRE_CSR, cs << 10);
190 spin_unlock(&uwire_lock);
194 static int __init omap_uwire_init(void)
196 spin_lock_init(&uwire_lock);
197 if (cpu_is_omap730())
202 uwire_write_reg(UWIRE_SR3, 1);
203 if (machine_is_omap_h2()) {
204 /* defaults: W21 SDO, U18 SDI, V19 SCL */
205 omap_cfg_reg(N14_1610_UWIRE_CS0);
206 omap_cfg_reg(N15_1610_UWIRE_CS1);
208 if (machine_is_omap_osk()) {
209 /* this is the standard expansion connector usage, with
210 * the other chipselect pins for MPUIO2 and MPUIO4.
212 omap_cfg_reg(N14_1610_UWIRE_CS0);
213 omap_cfg_reg(P15_1610_UWIRE_CS3);
215 if (machine_is_omap_perseus2()) {
216 /* configure pins: MPU_UW_nSCS1, MPU_UW_SDO, MPU_UW_SCLK */
217 int val = omap_readl(OMAP730_IO_CONF_9) & ~0x00EEE000;
218 omap_writel(val | 0x00AAA000, OMAP730_IO_CONF_9);
223 static void __exit omap_uwire_exit(void)
227 subsys_initcall(omap_uwire_init);
228 module_exit(omap_uwire_exit);
230 EXPORT_SYMBOL(omap_uwire_configure_mode);
231 EXPORT_SYMBOL(omap_uwire_data_transfer);
233 MODULE_LICENSE("GPL");