]> git.sur5r.net Git - u-boot/blob - common/miiphybb.c
[PATCH] I2C: Add support for multiple I2C busses for RTC & DTT
[u-boot] / common / miiphybb.c
1 /*
2  * (C) Copyright 2001
3  * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
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  * This provides a bit-banged interface to the ethernet MII management
26  * channel.
27  */
28
29 #include <common.h>
30 #include <ioports.h>
31 #include <ppc_asm.tmpl>
32
33 #ifdef CONFIG_BITBANGMII
34
35
36 /*****************************************************************************
37  *
38  * Utility to send the preamble, address, and register (common to read
39  * and write).
40  */
41 static void miiphy_pre (char read, unsigned char addr, unsigned char reg)
42 {
43         int j;                  /* counter */
44 #if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM))
45         volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT);
46 #endif
47
48         /*
49          * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
50          * The IEEE spec says this is a PHY optional requirement.  The AMD
51          * 79C874 requires one after power up and one after a MII communications
52          * error.  This means that we are doing more preambles than we need,
53          * but it is safer and will be much more robust.
54          */
55
56         MDIO_ACTIVE;
57         MDIO (1);
58         for (j = 0; j < 32; j++) {
59                 MDC (0);
60                 MIIDELAY;
61                 MDC (1);
62                 MIIDELAY;
63         }
64
65         /* send the start bit (01) and the read opcode (10) or write (10) */
66         MDC (0);
67         MDIO (0);
68         MIIDELAY;
69         MDC (1);
70         MIIDELAY;
71         MDC (0);
72         MDIO (1);
73         MIIDELAY;
74         MDC (1);
75         MIIDELAY;
76         MDC (0);
77         MDIO (read);
78         MIIDELAY;
79         MDC (1);
80         MIIDELAY;
81         MDC (0);
82         MDIO (!read);
83         MIIDELAY;
84         MDC (1);
85         MIIDELAY;
86
87         /* send the PHY address */
88         for (j = 0; j < 5; j++) {
89                 MDC (0);
90                 if ((addr & 0x10) == 0) {
91                         MDIO (0);
92                 } else {
93                         MDIO (1);
94                 }
95                 MIIDELAY;
96                 MDC (1);
97                 MIIDELAY;
98                 addr <<= 1;
99         }
100
101         /* send the register address */
102         for (j = 0; j < 5; j++) {
103                 MDC (0);
104                 if ((reg & 0x10) == 0) {
105                         MDIO (0);
106                 } else {
107                         MDIO (1);
108                 }
109                 MIIDELAY;
110                 MDC (1);
111                 MIIDELAY;
112                 reg <<= 1;
113         }
114 }
115
116
117 /*****************************************************************************
118  *
119  * Read a MII PHY register.
120  *
121  * Returns:
122  *   0 on success
123  */
124 int bb_miiphy_read (char *devname, unsigned char addr,
125                 unsigned char reg, unsigned short *value)
126 {
127         short rdreg;            /* register working value */
128         int j;                  /* counter */
129 #if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM))
130         volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT);
131 #endif
132
133         miiphy_pre (1, addr, reg);
134
135         /* tri-state our MDIO I/O pin so we can read */
136         MDC (0);
137         MDIO_TRISTATE;
138         MIIDELAY;
139         MDC (1);
140         MIIDELAY;
141
142         /* check the turnaround bit: the PHY should be driving it to zero */
143         if (MDIO_READ != 0) {
144                 /* puts ("PHY didn't drive TA low\n"); */
145                 for (j = 0; j < 32; j++) {
146                         MDC (0);
147                         MIIDELAY;
148                         MDC (1);
149                         MIIDELAY;
150                 }
151                 return (-1);
152         }
153
154         MDC (0);
155         MIIDELAY;
156
157         /* read 16 bits of register data, MSB first */
158         rdreg = 0;
159         for (j = 0; j < 16; j++) {
160                 MDC (1);
161                 MIIDELAY;
162                 rdreg <<= 1;
163                 rdreg |= MDIO_READ;
164                 MDC (0);
165                 MIIDELAY;
166         }
167
168         MDC (1);
169         MIIDELAY;
170         MDC (0);
171         MIIDELAY;
172         MDC (1);
173         MIIDELAY;
174
175         *value = rdreg;
176
177 #ifdef DEBUG
178         printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value);
179 #endif
180
181         return 0;
182 }
183
184
185 /*****************************************************************************
186  *
187  * Write a MII PHY register.
188  *
189  * Returns:
190  *   0 on success
191  */
192 int bb_miiphy_write (char *devname, unsigned char addr,
193                 unsigned char reg, unsigned short value)
194 {
195         int j;                  /* counter */
196 #if !(defined(CONFIG_EP8248) || defined(CONFIG_EP82XXM))
197         volatile ioport_t *iop = ioport_addr ((immap_t *) CFG_IMMR, MDIO_PORT);
198 #endif
199
200         miiphy_pre (0, addr, reg);
201
202         /* send the turnaround (10) */
203         MDC (0);
204         MDIO (1);
205         MIIDELAY;
206         MDC (1);
207         MIIDELAY;
208         MDC (0);
209         MDIO (0);
210         MIIDELAY;
211         MDC (1);
212         MIIDELAY;
213
214         /* write 16 bits of register data, MSB first */
215         for (j = 0; j < 16; j++) {
216                 MDC (0);
217                 if ((value & 0x00008000) == 0) {
218                         MDIO (0);
219                 } else {
220                         MDIO (1);
221                 }
222                 MIIDELAY;
223                 MDC (1);
224                 MIIDELAY;
225                 value <<= 1;
226         }
227
228         /*
229          * Tri-state the MDIO line.
230          */
231         MDIO_TRISTATE;
232         MDC (0);
233         MIIDELAY;
234         MDC (1);
235         MIIDELAY;
236
237         return 0;
238 }
239
240 #endif /* CONFIG_BITBANGMII */