blob: 9f84fb186900fbb19ef03efc7d66d40f29c5ce83 [file] [log] [blame]
Dirk Eibacha605ea72010-10-21 10:50:05 +02001/*
2 * (C) Copyright 2010
3 * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de
4 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02005 * SPDX-License-Identifier: GPL-2.0+
Dirk Eibacha605ea72010-10-21 10:50:05 +02006 */
7
8#include <common.h>
9#include <command.h>
Dirk Eibache50e8962013-07-25 19:28:13 +020010#include <errno.h>
Dirk Eibacha605ea72010-10-21 10:50:05 +020011#include <asm/processor.h>
12#include <asm/io.h>
13#include <asm/ppc4xx-gpio.h>
14
Dirk Eibach6e9e6c32012-04-26 03:54:22 +000015#include "405ep.h"
Dirk Eibach2da0fc02011-01-21 09:31:21 +010016#include <gdsys_fpga.h>
Dirk Eibacha605ea72010-10-21 10:50:05 +020017
Dirk Eibach2da0fc02011-01-21 09:31:21 +010018#include "../common/osd.h"
Dirk Eibache50e8962013-07-25 19:28:13 +020019#include "../common/mclink.h"
20
21#include <i2c.h>
22#include <pca953x.h>
23#include <pca9698.h>
24
25#include <miiphy.h>
26
27DECLARE_GLOBAL_DATA_PTR;
Dirk Eibacha605ea72010-10-21 10:50:05 +020028
Dirk Eibach6e9e6c32012-04-26 03:54:22 +000029#define LATCH0_BASE (CONFIG_SYS_LATCH_BASE)
30#define LATCH1_BASE (CONFIG_SYS_LATCH_BASE + 0x100)
31#define LATCH2_BASE (CONFIG_SYS_LATCH_BASE + 0x200)
32
Dirk Eibacha605ea72010-10-21 10:50:05 +020033enum {
34 UNITTYPE_MAIN_SERVER = 0,
35 UNITTYPE_MAIN_USER = 1,
36 UNITTYPE_VIDEO_SERVER = 2,
37 UNITTYPE_VIDEO_USER = 3,
38};
39
40enum {
41 HWVER_100 = 0,
42 HWVER_104 = 1,
43 HWVER_110 = 2,
Dirk Eibache50e8962013-07-25 19:28:13 +020044 HWVER_120 = 3,
45 HWVER_200 = 4,
46 HWVER_210 = 5,
47};
48
49enum {
50 FPGA_HWVER_200 = 0,
51 FPGA_HWVER_210 = 1,
Dirk Eibacha605ea72010-10-21 10:50:05 +020052};
53
54enum {
55 COMPRESSION_NONE = 0,
Dirk Eibache50e8962013-07-25 19:28:13 +020056 COMPRESSION_TYPE1_DELTA = 1,
57 COMPRESSION_TYPE1_TYPE2_DELTA = 3,
Dirk Eibacha605ea72010-10-21 10:50:05 +020058};
59
60enum {
61 AUDIO_NONE = 0,
62 AUDIO_TX = 1,
63 AUDIO_RX = 2,
64 AUDIO_RXTX = 3,
65};
66
67enum {
68 SYSCLK_147456 = 0,
69};
70
71enum {
72 RAM_DDR2_32 = 0,
Dirk Eibache50e8962013-07-25 19:28:13 +020073 RAM_DDR3_32 = 1,
Dirk Eibacha605ea72010-10-21 10:50:05 +020074};
75
Dirk Eibache50e8962013-07-25 19:28:13 +020076enum {
77 MCFPGA_DONE = 1 << 0,
78 MCFPGA_INIT_N = 1 << 1,
79 MCFPGA_PROGRAM_N = 1 << 2,
80 MCFPGA_UPDATE_ENABLE_N = 1 << 3,
81 MCFPGA_RESET_N = 1 << 4,
82};
83
84enum {
85 GPIO_MDC = 1 << 14,
86 GPIO_MDIO = 1 << 15,
87};
88
89unsigned int mclink_fpgacount;
Dirk Eibachaba27ac2013-06-26 16:04:26 +020090struct ihs_fpga *fpga_ptr[] = CONFIG_SYS_FPGA_PTR;
91
Dirk Eibache50e8962013-07-25 19:28:13 +020092static int setup_88e1518(const char *bus, unsigned char addr);
93static int verify_88e1518(const char *bus, unsigned char addr);
94
95int fpga_set_reg(u32 fpga, u16 *reg, off_t regoff, u16 data)
96{
97 int res;
98
99 switch (fpga) {
100 case 0:
101 out_le16(reg, data);
102 break;
103 default:
104 res = mclink_send(fpga - 1, regoff, data);
105 if (res < 0) {
106 printf("mclink_send reg %02lx data %04x returned %d\n",
107 regoff, data, res);
108 return res;
109 }
110 break;
111 }
112
113 return 0;
114}
115
116int fpga_get_reg(u32 fpga, u16 *reg, off_t regoff, u16 *data)
117{
118 int res;
119
120 switch (fpga) {
121 case 0:
122 *data = in_le16(reg);
123 break;
124 default:
125 if (fpga > mclink_fpgacount)
126 return -EINVAL;
127 res = mclink_receive(fpga - 1, regoff, data);
128 if (res < 0) {
129 printf("mclink_receive reg %02lx returned %d\n",
130 regoff, res);
131 return res;
132 }
133 }
134
135 return 0;
136}
137
Dirk Eibacha605ea72010-10-21 10:50:05 +0200138/*
139 * Check Board Identity:
140 */
141int checkboard(void)
142{
Dirk Eibachb19bf832012-04-26 03:54:23 +0000143 char *s = getenv("serial#");
144
145 puts("Board: ");
146
147 puts("IoCon");
148
149 if (s != NULL) {
150 puts(", serial# ");
151 puts(s);
152 }
153
154 puts("\n");
155
156 return 0;
157}
158
Dirk Eibache50e8962013-07-25 19:28:13 +0200159static void print_fpga_info(unsigned int fpga)
Dirk Eibachb19bf832012-04-26 03:54:23 +0000160{
Dirk Eibachaba27ac2013-06-26 16:04:26 +0200161 u16 versions;
162 u16 fpga_version;
163 u16 fpga_features;
Dirk Eibacha605ea72010-10-21 10:50:05 +0200164 unsigned unit_type;
165 unsigned hardware_version;
166 unsigned feature_compression;
167 unsigned feature_osd;
168 unsigned feature_audio;
169 unsigned feature_sysclock;
170 unsigned feature_ramconfig;
171 unsigned feature_carriers;
172 unsigned feature_video_channels;
Dirk Eibache50e8962013-07-25 19:28:13 +0200173 int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
Dirk Eibacha605ea72010-10-21 10:50:05 +0200174
Dirk Eibachaba27ac2013-06-26 16:04:26 +0200175 FPGA_GET_REG(0, versions, &versions);
176 FPGA_GET_REG(0, fpga_version, &fpga_version);
177 FPGA_GET_REG(0, fpga_features, &fpga_features);
178
Dirk Eibacha605ea72010-10-21 10:50:05 +0200179 unit_type = (versions & 0xf000) >> 12;
Dirk Eibacha605ea72010-10-21 10:50:05 +0200180 feature_compression = (fpga_features & 0xe000) >> 13;
181 feature_osd = fpga_features & (1<<11);
182 feature_audio = (fpga_features & 0x0600) >> 9;
183 feature_sysclock = (fpga_features & 0x0180) >> 7;
184 feature_ramconfig = (fpga_features & 0x0060) >> 5;
185 feature_carriers = (fpga_features & 0x000c) >> 2;
186 feature_video_channels = fpga_features & 0x0003;
187
Dirk Eibache50e8962013-07-25 19:28:13 +0200188 if (legacy)
189 printf("legacy ");
190
Dirk Eibacha605ea72010-10-21 10:50:05 +0200191 switch (unit_type) {
192 case UNITTYPE_MAIN_USER:
193 printf("Mainchannel");
194 break;
195
196 case UNITTYPE_VIDEO_USER:
197 printf("Videochannel");
198 break;
199
200 default:
201 printf("UnitType %d(not supported)", unit_type);
202 break;
203 }
204
Dirk Eibache50e8962013-07-25 19:28:13 +0200205 if (unit_type == UNITTYPE_MAIN_USER) {
206 if (legacy)
207 hardware_version =
208 (in_le16((void *)LATCH2_BASE)>>8) & 0x0f;
209 else
210 hardware_version =
211 (!!pca9698_get_value(0x20, 24) << 0)
212 | (!!pca9698_get_value(0x20, 25) << 1)
213 | (!!pca9698_get_value(0x20, 26) << 2)
214 | (!!pca9698_get_value(0x20, 27) << 3);
215 switch (hardware_version) {
216 case HWVER_100:
217 printf(" HW-Ver 1.00,");
218 break;
Dirk Eibacha605ea72010-10-21 10:50:05 +0200219
Dirk Eibache50e8962013-07-25 19:28:13 +0200220 case HWVER_104:
221 printf(" HW-Ver 1.04,");
222 break;
Dirk Eibacha605ea72010-10-21 10:50:05 +0200223
Dirk Eibache50e8962013-07-25 19:28:13 +0200224 case HWVER_110:
225 printf(" HW-Ver 1.10,");
226 break;
Dirk Eibacha605ea72010-10-21 10:50:05 +0200227
Dirk Eibache50e8962013-07-25 19:28:13 +0200228 case HWVER_120:
229 printf(" HW-Ver 1.20-1.21,");
230 break;
231
232 case HWVER_200:
233 printf(" HW-Ver 2.00,");
234 break;
235
236 case HWVER_210:
237 printf(" HW-Ver 2.10,");
238 break;
239
240 default:
241 printf(" HW-Ver %d(not supported),",
242 hardware_version);
243 break;
244 }
Dirk Eibacha605ea72010-10-21 10:50:05 +0200245 }
246
Dirk Eibache50e8962013-07-25 19:28:13 +0200247 if (unit_type == UNITTYPE_VIDEO_USER) {
248 hardware_version = versions & 0x000f;
249 switch (hardware_version) {
250 case FPGA_HWVER_200:
251 printf(" HW-Ver 2.00,");
252 break;
253
254 case FPGA_HWVER_210:
255 printf(" HW-Ver 2.10,");
256 break;
257
258 default:
259 printf(" HW-Ver %d(not supported),",
260 hardware_version);
261 break;
262 }
263 }
264
265 printf(" FPGA V %d.%02d\n features:",
266 fpga_version / 100, fpga_version % 100);
Dirk Eibacha605ea72010-10-21 10:50:05 +0200267
268
269 switch (feature_compression) {
270 case COMPRESSION_NONE:
271 printf(" no compression");
272 break;
273
274 case COMPRESSION_TYPE1_DELTA:
275 printf(" type1-deltacompression");
276 break;
277
Dirk Eibache50e8962013-07-25 19:28:13 +0200278 case COMPRESSION_TYPE1_TYPE2_DELTA:
279 printf(" type1-deltacompression, type2-inlinecompression");
280 break;
281
Dirk Eibacha605ea72010-10-21 10:50:05 +0200282 default:
283 printf(" compression %d(not supported)", feature_compression);
284 break;
285 }
286
287 printf(", %sosd", feature_osd ? "" : "no ");
288
289 switch (feature_audio) {
290 case AUDIO_NONE:
291 printf(", no audio");
292 break;
293
294 case AUDIO_TX:
295 printf(", audio tx");
296 break;
297
298 case AUDIO_RX:
299 printf(", audio rx");
300 break;
301
302 case AUDIO_RXTX:
303 printf(", audio rx+tx");
304 break;
305
306 default:
307 printf(", audio %d(not supported)", feature_audio);
308 break;
309 }
310
311 puts(",\n ");
312
313 switch (feature_sysclock) {
314 case SYSCLK_147456:
315 printf("clock 147.456 MHz");
316 break;
317
318 default:
319 printf("clock %d(not supported)", feature_sysclock);
320 break;
321 }
322
323 switch (feature_ramconfig) {
324 case RAM_DDR2_32:
325 printf(", RAM 32 bit DDR2");
326 break;
327
Dirk Eibache50e8962013-07-25 19:28:13 +0200328 case RAM_DDR3_32:
329 printf(", RAM 32 bit DDR3");
330 break;
331
Dirk Eibacha605ea72010-10-21 10:50:05 +0200332 default:
333 printf(", RAM %d(not supported)", feature_ramconfig);
334 break;
335 }
336
337 printf(", %d carrier(s)", feature_carriers);
338
339 printf(", %d video channel(s)\n", feature_video_channels);
Dirk Eibacha605ea72010-10-21 10:50:05 +0200340}
341
342int last_stage_init(void)
343{
Dirk Eibache50e8962013-07-25 19:28:13 +0200344 int slaves;
345 unsigned int k;
346 unsigned char mclink_controllers[] = { 0x24, 0x25, 0x26 };
347 int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
Dirk Eibachb19bf832012-04-26 03:54:23 +0000348
Dirk Eibache50e8962013-07-25 19:28:13 +0200349 print_fpga_info(0);
350 osd_probe(0);
351
352 /* wait for FPGA done */
353 for (k = 0; k < ARRAY_SIZE(mclink_controllers); ++k) {
354 unsigned int ctr = 0;
355
356 if (i2c_probe(mclink_controllers[k]))
357 continue;
358
359 while (!(pca953x_get_val(mclink_controllers[k])
360 & MCFPGA_DONE)) {
361 udelay(100000);
362 if (ctr++ > 5) {
363 printf("no done for mclink_controller %d\n", k);
364 break;
365 }
366 }
367 }
368
369 if (!legacy) {
370 miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read,
371 bb_miiphy_write);
372 if (!verify_88e1518(bb_miiphy_buses[0].name, 0)) {
373 printf("Fixup 88e1518 erratum on %s\n",
374 bb_miiphy_buses[0].name);
375 setup_88e1518(bb_miiphy_buses[0].name, 0);
376 }
377 }
378
379 /* wait for slave-PLLs to be up and running */
380 udelay(500000);
381
382 mclink_fpgacount = CONFIG_SYS_MCLINK_MAX;
383 slaves = mclink_probe();
384 mclink_fpgacount = 0;
385
386 if (slaves <= 0)
387 return 0;
388
389 mclink_fpgacount = slaves;
390
391 for (k = 1; k <= slaves; ++k) {
392 print_fpga_info(k);
393 osd_probe(k);
394 miiphy_register(bb_miiphy_buses[k].name,
395 bb_miiphy_read, bb_miiphy_write);
396 if (!verify_88e1518(bb_miiphy_buses[k].name, 0)) {
397 printf("Fixup 88e1518 erratum on %s\n",
398 bb_miiphy_buses[k].name);
399 setup_88e1518(bb_miiphy_buses[k].name, 0);
400 }
401 }
402
403 return 0;
Dirk Eibacha605ea72010-10-21 10:50:05 +0200404}
405
406/*
407 * provide access to fpga gpios (for I2C bitbang)
Dirk Eibachaba27ac2013-06-26 16:04:26 +0200408 * (these may look all too simple but make iocon.h much more readable)
Dirk Eibacha605ea72010-10-21 10:50:05 +0200409 */
Dirk Eibache50e8962013-07-25 19:28:13 +0200410void fpga_gpio_set(unsigned int bus, int pin)
Dirk Eibacha605ea72010-10-21 10:50:05 +0200411{
Dirk Eibache50e8962013-07-25 19:28:13 +0200412 FPGA_SET_REG(bus, gpio.set, pin);
Dirk Eibacha605ea72010-10-21 10:50:05 +0200413}
414
Dirk Eibache50e8962013-07-25 19:28:13 +0200415void fpga_gpio_clear(unsigned int bus, int pin)
Dirk Eibacha605ea72010-10-21 10:50:05 +0200416{
Dirk Eibache50e8962013-07-25 19:28:13 +0200417 FPGA_SET_REG(bus, gpio.clear, pin);
Dirk Eibacha605ea72010-10-21 10:50:05 +0200418}
419
Dirk Eibache50e8962013-07-25 19:28:13 +0200420int fpga_gpio_get(unsigned int bus, int pin)
Dirk Eibacha605ea72010-10-21 10:50:05 +0200421{
Dirk Eibachaba27ac2013-06-26 16:04:26 +0200422 u16 val;
423
Dirk Eibache50e8962013-07-25 19:28:13 +0200424 FPGA_GET_REG(bus, gpio.read, &val);
Dirk Eibachaba27ac2013-06-26 16:04:26 +0200425
426 return val & pin;
Dirk Eibacha605ea72010-10-21 10:50:05 +0200427}
Dirk Eibach6e9e6c32012-04-26 03:54:22 +0000428
429void gd405ep_init(void)
430{
Dirk Eibache50e8962013-07-25 19:28:13 +0200431 unsigned int k;
432
433 if (i2c_probe(0x20)) { /* i2c_probe returns 0 on success */
434 for (k = 0; k < CONFIG_SYS_FPGA_COUNT; ++k)
435 gd->arch.fpga_state[k] |= FPGA_STATE_PLATFORM;
436 } else {
437 pca9698_direction_output(0x20, 4, 1);
438 }
Dirk Eibach6e9e6c32012-04-26 03:54:22 +0000439}
440
441void gd405ep_set_fpga_reset(unsigned state)
442{
Dirk Eibache50e8962013-07-25 19:28:13 +0200443 int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
444
445 if (legacy) {
446 if (state) {
447 out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_RESET);
448 out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_RESET);
449 } else {
450 out_le16((void *)LATCH0_BASE, CONFIG_SYS_LATCH0_BOOT);
451 out_le16((void *)LATCH1_BASE, CONFIG_SYS_LATCH1_BOOT);
452 }
Dirk Eibach6e9e6c32012-04-26 03:54:22 +0000453 } else {
Dirk Eibache50e8962013-07-25 19:28:13 +0200454 pca9698_set_value(0x20, 4, state ? 0 : 1);
Dirk Eibach6e9e6c32012-04-26 03:54:22 +0000455 }
456}
457
458void gd405ep_setup_hw(void)
459{
460 /*
461 * set "startup-finished"-gpios
462 */
463 gpio_write_bit(21, 0);
464 gpio_write_bit(22, 1);
465}
466
467int gd405ep_get_fpga_done(unsigned fpga)
468{
Dirk Eibache50e8962013-07-25 19:28:13 +0200469 int legacy = get_fpga_state(0) & FPGA_STATE_PLATFORM;
470
471 if (legacy)
472 return in_le16((void *)LATCH2_BASE)
473 & CONFIG_SYS_FPGA_DONE(fpga);
474 else
475 return pca9698_get_value(0x20, 20);
476}
477
478/*
479 * FPGA MII bitbang implementation
480 */
481
482struct fpga_mii {
483 unsigned fpga;
484 int mdio;
485} fpga_mii[] = {
486 { 0, 1},
487 { 1, 1},
488 { 2, 1},
489 { 3, 1},
490};
491
492static int mii_dummy_init(struct bb_miiphy_bus *bus)
493{
494 return 0;
495}
496
497static int mii_mdio_active(struct bb_miiphy_bus *bus)
498{
499 struct fpga_mii *fpga_mii = bus->priv;
500
501 if (fpga_mii->mdio)
502 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
503 else
504 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
505
506 return 0;
507}
508
509static int mii_mdio_tristate(struct bb_miiphy_bus *bus)
510{
511 struct fpga_mii *fpga_mii = bus->priv;
512
513 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
514
515 return 0;
516}
517
518static int mii_set_mdio(struct bb_miiphy_bus *bus, int v)
519{
520 struct fpga_mii *fpga_mii = bus->priv;
521
522 if (v)
523 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDIO);
524 else
525 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDIO);
526
527 fpga_mii->mdio = v;
528
529 return 0;
530}
531
532static int mii_get_mdio(struct bb_miiphy_bus *bus, int *v)
533{
534 u16 gpio;
535 struct fpga_mii *fpga_mii = bus->priv;
536
537 FPGA_GET_REG(fpga_mii->fpga, gpio.read, &gpio);
538
539 *v = ((gpio & GPIO_MDIO) != 0);
540
541 return 0;
542}
543
544static int mii_set_mdc(struct bb_miiphy_bus *bus, int v)
545{
546 struct fpga_mii *fpga_mii = bus->priv;
547
548 if (v)
549 FPGA_SET_REG(fpga_mii->fpga, gpio.set, GPIO_MDC);
550 else
551 FPGA_SET_REG(fpga_mii->fpga, gpio.clear, GPIO_MDC);
552
553 return 0;
554}
555
556static int mii_delay(struct bb_miiphy_bus *bus)
557{
558 udelay(1);
559
560 return 0;
561}
562
563struct bb_miiphy_bus bb_miiphy_buses[] = {
564 {
565 .name = "trans1",
566 .init = mii_dummy_init,
567 .mdio_active = mii_mdio_active,
568 .mdio_tristate = mii_mdio_tristate,
569 .set_mdio = mii_set_mdio,
570 .get_mdio = mii_get_mdio,
571 .set_mdc = mii_set_mdc,
572 .delay = mii_delay,
573 .priv = &fpga_mii[0],
574 },
575 {
576 .name = "trans2",
577 .init = mii_dummy_init,
578 .mdio_active = mii_mdio_active,
579 .mdio_tristate = mii_mdio_tristate,
580 .set_mdio = mii_set_mdio,
581 .get_mdio = mii_get_mdio,
582 .set_mdc = mii_set_mdc,
583 .delay = mii_delay,
584 .priv = &fpga_mii[1],
585 },
586 {
587 .name = "trans3",
588 .init = mii_dummy_init,
589 .mdio_active = mii_mdio_active,
590 .mdio_tristate = mii_mdio_tristate,
591 .set_mdio = mii_set_mdio,
592 .get_mdio = mii_get_mdio,
593 .set_mdc = mii_set_mdc,
594 .delay = mii_delay,
595 .priv = &fpga_mii[2],
596 },
597 {
598 .name = "trans4",
599 .init = mii_dummy_init,
600 .mdio_active = mii_mdio_active,
601 .mdio_tristate = mii_mdio_tristate,
602 .set_mdio = mii_set_mdio,
603 .get_mdio = mii_get_mdio,
604 .set_mdc = mii_set_mdc,
605 .delay = mii_delay,
606 .priv = &fpga_mii[3],
607 },
608};
609
610int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
611 sizeof(bb_miiphy_buses[0]);
612
613/*
614 * Workaround for erratum mentioned in 88E1518 release notes
615 */
616
617static int verify_88e1518(const char *bus, unsigned char addr)
618{
619 u16 phy_id1, phy_id2;
620
621 if (miiphy_read(bus, addr, 2, &phy_id1) ||
622 miiphy_read(bus, addr, 3, &phy_id2)) {
623 printf("Error reading from the PHY addr=%02x\n", addr);
624 return -EIO;
625 }
626
627 if ((phy_id1 != 0x0141) || ((phy_id2 & 0xfff0) != 0x0dd0))
628 return -EINVAL;
629
630 return 0;
631}
632
633struct regfix_88e1518 {
634 u8 reg;
635 u16 data;
636} regfix_88e1518[] = {
637 { 22, 0x00ff },
638 { 17, 0x214b },
639 { 16, 0x2144 },
640 { 17, 0x0c28 },
641 { 16, 0x2146 },
642 { 17, 0xb233 },
643 { 16, 0x214d },
644 { 17, 0xcc0c },
645 { 16, 0x2159 },
646 { 22, 0x00fb },
647 { 7, 0xc00d },
648 { 22, 0x0000 },
649};
650
651static int setup_88e1518(const char *bus, unsigned char addr)
652{
653 unsigned int k;
654
655 for (k = 0; k < ARRAY_SIZE(regfix_88e1518); ++k) {
656 if (miiphy_write(bus, addr,
657 regfix_88e1518[k].reg,
658 regfix_88e1518[k].data)) {
659 printf("Error writing to the PHY addr=%02x\n", addr);
660 return -1;
661 }
662 }
663
664 return 0;
Dirk Eibach6e9e6c32012-04-26 03:54:22 +0000665}