1 /*
2  * (C) Copyright 2009
3  * Detlev Zundel, DENX Software Engineering, dzu@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  *
23  */
24 
25 #define TWS_IMPLEMENTATION
26 #include <common.h>
27 
28 /*=====================================================================*/
29 /*                         Public Functions                            */
30 /*=====================================================================*/
31 
32 /*-----------------------------------------------------------------------
33  * Read bits
34  */
tws_read(uchar * buffer,int len)35 int tws_read(uchar *buffer, int len)
36 {
37 	int rem = len;
38 	uchar accu, shift;
39 
40 	debug("tws_read: buffer %p len %d\n", buffer, len);
41 
42 	/* Configure the data pin for input */
43 	tws_data_config_output(0);
44 
45 	/* Disable WR, i.e. setup a read */
46 	tws_wr(0);
47 	udelay(1);
48 
49 	/* Rise CE */
50 	tws_ce(1);
51 	udelay(1);
52 
53 	for (; rem > 0; ) {
54 		for (shift = 0, accu = 0;
55 		     (rem > 0) && (shift < 8);
56 		     rem--, shift++) {
57 			tws_clk(1);
58 			udelay(10);
59 			accu |= (tws_data_read() << shift); /* LSB first */
60 			tws_clk(0);
61 			udelay(10);
62 		}
63 		*buffer++ = accu;
64 	}
65 
66 	/* Lower CE */
67 	tws_ce(0);
68 
69 	return len - rem;
70 }
71 
72 
73 /*-----------------------------------------------------------------------
74  * Write bits
75  */
tws_write(uchar * buffer,int len)76 int tws_write(uchar *buffer, int len)
77 {
78 	int rem = len;
79 	uchar accu, shift;
80 
81 	debug("tws_write: buffer %p len %d\n", buffer, len);
82 
83 	/* Configure the data pin for output */
84 	tws_data_config_output(1);
85 
86 	/* Enable WR, i.e. setup a write */
87 	tws_wr(1);
88 	udelay(1);
89 
90 	/* Rise CE */
91 	tws_ce(1);
92 	udelay(1);
93 
94 	for (; rem > 0; ) {
95 		for (shift = 0, accu = *buffer++;
96 		     (rem > 0) && (shift < 8);
97 		     rem--, shift++) {
98 			tws_data(accu & 0x01); /* LSB first */
99 			tws_clk(1);
100 			udelay(10);
101 			tws_clk(0);
102 			udelay(10);
103 			accu >>= 1;
104 		}
105 	}
106 
107 	/* Lower CE */
108 	tws_ce(0);
109 
110 	return len - rem;
111 }
112