]> git.sur5r.net Git - u-boot/blob - drivers/twserial/soft_tws.c
Merge branch 'master' of git://git.denx.de/u-boot-nds32
[u-boot] / drivers / twserial / soft_tws.c
1 /*
2  * (C) Copyright 2009
3  * Detlev Zundel, DENX Software Engineering, dzu@denx.de.
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #define TWS_IMPLEMENTATION
9 #include <common.h>
10
11 /*=====================================================================*/
12 /*                         Public Functions                            */
13 /*=====================================================================*/
14
15 /*-----------------------------------------------------------------------
16  * Read bits
17  */
18 int tws_read(uchar *buffer, int len)
19 {
20         int rem = len;
21         uchar accu, shift;
22
23         debug("tws_read: buffer %p len %d\n", buffer, len);
24
25         /* Configure the data pin for input */
26         tws_data_config_output(0);
27
28         /* Disable WR, i.e. setup a read */
29         tws_wr(0);
30         udelay(1);
31
32         /* Rise CE */
33         tws_ce(1);
34         udelay(1);
35
36         for (; rem > 0; ) {
37                 for (shift = 0, accu = 0;
38                      (rem > 0) && (shift < 8);
39                      rem--, shift++) {
40                         tws_clk(1);
41                         udelay(10);
42                         accu |= (tws_data_read() << shift); /* LSB first */
43                         tws_clk(0);
44                         udelay(10);
45                 }
46                 *buffer++ = accu;
47         }
48
49         /* Lower CE */
50         tws_ce(0);
51
52         return len - rem;
53 }
54
55
56 /*-----------------------------------------------------------------------
57  * Write bits
58  */
59 int tws_write(uchar *buffer, int len)
60 {
61         int rem = len;
62         uchar accu, shift;
63
64         debug("tws_write: buffer %p len %d\n", buffer, len);
65
66         /* Configure the data pin for output */
67         tws_data_config_output(1);
68
69         /* Enable WR, i.e. setup a write */
70         tws_wr(1);
71         udelay(1);
72
73         /* Rise CE */
74         tws_ce(1);
75         udelay(1);
76
77         for (; rem > 0; ) {
78                 for (shift = 0, accu = *buffer++;
79                      (rem > 0) && (shift < 8);
80                      rem--, shift++) {
81                         tws_data(accu & 0x01); /* LSB first */
82                         tws_clk(1);
83                         udelay(10);
84                         tws_clk(0);
85                         udelay(10);
86                         accu >>= 1;
87                 }
88         }
89
90         /* Lower CE */
91         tws_ce(0);
92
93         return len - rem;
94 }