Merge git://git.infradead.org/mtd-2.6
[linux-2.6] / drivers / net / fs_enet / mii-bitbang.c
1 /*
2  * Combined Ethernet driver for Motorola MPC8xx and MPC82xx.
3  *
4  * Copyright (c) 2003 Intracom S.A. 
5  *  by Pantelis Antoniou <panto@intracom.gr>
6  * 
7  * 2005 (c) MontaVista Software, Inc. 
8  * Vitaly Bordug <vbordug@ru.mvista.com>
9  *
10  * This file is licensed under the terms of the GNU General Public License 
11  * version 2. This program is licensed "as is" without any warranty of any 
12  * kind, whether express or implied.
13  */
14
15
16 #include <linux/module.h>
17 #include <linux/types.h>
18 #include <linux/kernel.h>
19 #include <linux/string.h>
20 #include <linux/ptrace.h>
21 #include <linux/errno.h>
22 #include <linux/ioport.h>
23 #include <linux/slab.h>
24 #include <linux/interrupt.h>
25 #include <linux/init.h>
26 #include <linux/delay.h>
27 #include <linux/netdevice.h>
28 #include <linux/etherdevice.h>
29 #include <linux/skbuff.h>
30 #include <linux/spinlock.h>
31 #include <linux/mii.h>
32 #include <linux/ethtool.h>
33 #include <linux/bitops.h>
34 #include <linux/platform_device.h>
35
36 #include <asm/pgtable.h>
37 #include <asm/irq.h>
38 #include <asm/uaccess.h>
39
40 #include "fs_enet.h"
41
42 static int bitbang_prep_bit(u8 **datp, u8 *mskp,
43                 struct fs_mii_bit *mii_bit)
44 {
45         void *dat;
46         int adv;
47         u8 msk;
48
49         dat = (void*) mii_bit->offset;
50
51         adv = mii_bit->bit >> 3;
52         dat = (char *)dat + adv;
53
54         msk = 1 << (7 - (mii_bit->bit & 7));
55
56         *datp = dat;
57         *mskp = msk;
58
59         return 0;
60 }
61
62 static inline void bb_set(u8 *p, u8 m)
63 {
64         out_8(p, in_8(p) | m);
65 }
66
67 static inline void bb_clr(u8 *p, u8 m)
68 {
69         out_8(p, in_8(p) & ~m);
70 }
71
72 static inline int bb_read(u8 *p, u8 m)
73 {
74         return (in_8(p) & m) != 0;
75 }
76
77 static inline void mdio_active(struct bb_info *bitbang)
78 {
79         bb_set(bitbang->mdio_dir, bitbang->mdio_dir_msk);
80 }
81
82 static inline void mdio_tristate(struct bb_info *bitbang )
83 {
84         bb_clr(bitbang->mdio_dir, bitbang->mdio_dir_msk);
85 }
86
87 static inline int mdio_read(struct bb_info *bitbang )
88 {
89         return bb_read(bitbang->mdio_dat, bitbang->mdio_dat_msk);
90 }
91
92 static inline void mdio(struct bb_info *bitbang , int what)
93 {
94         if (what)
95                 bb_set(bitbang->mdio_dat, bitbang->mdio_dat_msk);
96         else
97                 bb_clr(bitbang->mdio_dat, bitbang->mdio_dat_msk);
98 }
99
100 static inline void mdc(struct bb_info *bitbang , int what)
101 {
102         if (what)
103                 bb_set(bitbang->mdc_dat, bitbang->mdc_msk);
104         else
105                 bb_clr(bitbang->mdc_dat, bitbang->mdc_msk);
106 }
107
108 static inline void mii_delay(struct bb_info *bitbang )
109 {
110         udelay(bitbang->delay);
111 }
112
113 /* Utility to send the preamble, address, and register (common to read and write). */
114 static void bitbang_pre(struct bb_info *bitbang , int read, u8 addr, u8 reg)
115 {
116         int j;
117
118         /*
119          * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
120          * The IEEE spec says this is a PHY optional requirement.  The AMD
121          * 79C874 requires one after power up and one after a MII communications
122          * error.  This means that we are doing more preambles than we need,
123          * but it is safer and will be much more robust.
124          */
125
126         mdio_active(bitbang);
127         mdio(bitbang, 1);
128         for (j = 0; j < 32; j++) {
129                 mdc(bitbang, 0);
130                 mii_delay(bitbang);
131                 mdc(bitbang, 1);
132                 mii_delay(bitbang);
133         }
134
135         /* send the start bit (01) and the read opcode (10) or write (10) */
136         mdc(bitbang, 0);
137         mdio(bitbang, 0);
138         mii_delay(bitbang);
139         mdc(bitbang, 1);
140         mii_delay(bitbang);
141         mdc(bitbang, 0);
142         mdio(bitbang, 1);
143         mii_delay(bitbang);
144         mdc(bitbang, 1);
145         mii_delay(bitbang);
146         mdc(bitbang, 0);
147         mdio(bitbang, read);
148         mii_delay(bitbang);
149         mdc(bitbang, 1);
150         mii_delay(bitbang);
151         mdc(bitbang, 0);
152         mdio(bitbang, !read);
153         mii_delay(bitbang);
154         mdc(bitbang, 1);
155         mii_delay(bitbang);
156
157         /* send the PHY address */
158         for (j = 0; j < 5; j++) {
159                 mdc(bitbang, 0);
160                 mdio(bitbang, (addr & 0x10) != 0);
161                 mii_delay(bitbang);
162                 mdc(bitbang, 1);
163                 mii_delay(bitbang);
164                 addr <<= 1;
165         }
166
167         /* send the register address */
168         for (j = 0; j < 5; j++) {
169                 mdc(bitbang, 0);
170                 mdio(bitbang, (reg & 0x10) != 0);
171                 mii_delay(bitbang);
172                 mdc(bitbang, 1);
173                 mii_delay(bitbang);
174                 reg <<= 1;
175         }
176 }
177
178 static int fs_enet_mii_bb_read(struct mii_bus *bus , int phy_id, int location)
179 {
180         u16 rdreg;
181         int ret, j;
182         u8 addr = phy_id & 0xff;
183         u8 reg = location & 0xff;
184         struct bb_info* bitbang = bus->priv;
185
186         bitbang_pre(bitbang, 1, addr, reg);
187
188         /* tri-state our MDIO I/O pin so we can read */
189         mdc(bitbang, 0);
190         mdio_tristate(bitbang);
191         mii_delay(bitbang);
192         mdc(bitbang, 1);
193         mii_delay(bitbang);
194
195         /* check the turnaround bit: the PHY should be driving it to zero */
196         if (mdio_read(bitbang) != 0) {
197                 /* PHY didn't drive TA low */
198                 for (j = 0; j < 32; j++) {
199                         mdc(bitbang, 0);
200                         mii_delay(bitbang);
201                         mdc(bitbang, 1);
202                         mii_delay(bitbang);
203                 }
204                 ret = -1;
205                 goto out;
206         }
207
208         mdc(bitbang, 0);
209         mii_delay(bitbang);
210
211         /* read 16 bits of register data, MSB first */
212         rdreg = 0;
213         for (j = 0; j < 16; j++) {
214                 mdc(bitbang, 1);
215                 mii_delay(bitbang);
216                 rdreg <<= 1;
217                 rdreg |= mdio_read(bitbang);
218                 mdc(bitbang, 0);
219                 mii_delay(bitbang);
220         }
221
222         mdc(bitbang, 1);
223         mii_delay(bitbang);
224         mdc(bitbang, 0);
225         mii_delay(bitbang);
226         mdc(bitbang, 1);
227         mii_delay(bitbang);
228
229         ret = rdreg;
230 out:
231         return ret;
232 }
233
234 static int fs_enet_mii_bb_write(struct mii_bus *bus, int phy_id, int location, u16 val)
235 {
236         int j;
237         struct bb_info* bitbang = bus->priv;
238
239         u8 addr = phy_id & 0xff;
240         u8 reg = location & 0xff;
241         u16 value = val & 0xffff;
242
243         bitbang_pre(bitbang, 0, addr, reg);
244
245         /* send the turnaround (10) */
246         mdc(bitbang, 0);
247         mdio(bitbang, 1);
248         mii_delay(bitbang);
249         mdc(bitbang, 1);
250         mii_delay(bitbang);
251         mdc(bitbang, 0);
252         mdio(bitbang, 0);
253         mii_delay(bitbang);
254         mdc(bitbang, 1);
255         mii_delay(bitbang);
256
257         /* write 16 bits of register data, MSB first */
258         for (j = 0; j < 16; j++) {
259                 mdc(bitbang, 0);
260                 mdio(bitbang, (value & 0x8000) != 0);
261                 mii_delay(bitbang);
262                 mdc(bitbang, 1);
263                 mii_delay(bitbang);
264                 value <<= 1;
265         }
266
267         /*
268          * Tri-state the MDIO line.
269          */
270         mdio_tristate(bitbang);
271         mdc(bitbang, 0);
272         mii_delay(bitbang);
273         mdc(bitbang, 1);
274         mii_delay(bitbang);
275         return 0;
276 }
277
278 static int fs_enet_mii_bb_reset(struct mii_bus *bus)
279 {
280         /*nothing here - dunno how to reset it*/
281         return 0;
282 }
283
284 static int fs_mii_bitbang_init(struct bb_info *bitbang, struct fs_mii_bb_platform_info* fmpi)
285 {
286         int r;
287
288         bitbang->delay = fmpi->delay;
289
290         r = bitbang_prep_bit(&bitbang->mdio_dir,
291                          &bitbang->mdio_dir_msk,
292                          &fmpi->mdio_dir);
293         if (r != 0)
294                 return r;
295
296         r = bitbang_prep_bit(&bitbang->mdio_dat,
297                          &bitbang->mdio_dat_msk,
298                          &fmpi->mdio_dat);
299         if (r != 0)
300                 return r;
301
302         r = bitbang_prep_bit(&bitbang->mdc_dat,
303                          &bitbang->mdc_msk,
304                          &fmpi->mdc_dat);
305         if (r != 0)
306                 return r;
307
308         return 0;
309 }
310
311
312 static int __devinit fs_enet_mdio_probe(struct device *dev)
313 {
314         struct platform_device *pdev = to_platform_device(dev);
315         struct fs_mii_bb_platform_info *pdata;
316         struct mii_bus *new_bus;
317         struct bb_info *bitbang;
318         int err = 0;
319
320         if (NULL == dev)
321                 return -EINVAL;
322
323         new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
324
325         if (NULL == new_bus)
326                 return -ENOMEM;
327
328         bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
329
330         if (NULL == bitbang)
331                 return -ENOMEM;
332
333         new_bus->name = "BB MII Bus",
334         new_bus->read = &fs_enet_mii_bb_read,
335         new_bus->write = &fs_enet_mii_bb_write,
336         new_bus->reset = &fs_enet_mii_bb_reset,
337         new_bus->id = pdev->id;
338
339         new_bus->phy_mask = ~0x9;
340         pdata = (struct fs_mii_bb_platform_info *)pdev->dev.platform_data;
341
342         if (NULL == pdata) {
343                 printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
344                 return -ENODEV;
345         }
346
347         /*set up workspace*/
348         fs_mii_bitbang_init(bitbang, pdata);
349
350         new_bus->priv = bitbang;
351
352         new_bus->irq = pdata->irq;
353
354         new_bus->dev = dev;
355         dev_set_drvdata(dev, new_bus);
356
357         err = mdiobus_register(new_bus);
358
359         if (0 != err) {
360                 printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
361                                 new_bus->name);
362                 goto bus_register_fail;
363         }
364
365         return 0;
366
367 bus_register_fail:
368         kfree(bitbang);
369         kfree(new_bus);
370
371         return err;
372 }
373
374
375 static int fs_enet_mdio_remove(struct device *dev)
376 {
377         struct mii_bus *bus = dev_get_drvdata(dev);
378
379         mdiobus_unregister(bus);
380
381         dev_set_drvdata(dev, NULL);
382
383         iounmap((void *) (&bus->priv));
384         bus->priv = NULL;
385         kfree(bus);
386
387         return 0;
388 }
389
390 static struct device_driver fs_enet_bb_mdio_driver = {
391         .name = "fsl-bb-mdio",
392         .bus = &platform_bus_type,
393         .probe = fs_enet_mdio_probe,
394         .remove = fs_enet_mdio_remove,
395 };
396
397 int fs_enet_mdio_bb_init(void)
398 {
399         return driver_register(&fs_enet_bb_mdio_driver);
400 }
401
402 void fs_enet_mdio_bb_exit(void)
403 {
404         driver_unregister(&fs_enet_bb_mdio_driver);
405 }
406