439b023da82804a57e0fd790df281eeade6359de
[platform/kernel/u-boot.git] / board / ti / beagle / beagle.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2004-2011
4  * Texas Instruments, <www.ti.com>
5  *
6  * Author :
7  *      Sunil Kumar <sunilsaini05@gmail.com>
8  *      Shashi Ranjan <shashiranjanmca05@gmail.com>
9  *
10  * Derived from Beagle Board and 3430 SDP code by
11  *      Richard Woodruff <r-woodruff2@ti.com>
12  *      Syed Mohammed Khasim <khasim@ti.com>
13  *
14  */
15 #include <common.h>
16 #include <bootstage.h>
17 #include <dm.h>
18 #include <env.h>
19 #include <net.h>
20 #include <ns16550.h>
21 #include <serial.h>
22 #ifdef CONFIG_LED_STATUS
23 #include <status_led.h>
24 #endif
25 #include <twl4030.h>
26 #include <linux/mtd/rawnand.h>
27 #include <asm/io.h>
28 #include <asm/arch/mmc_host_def.h>
29 #include <asm/arch/mux.h>
30 #include <asm/arch/mem.h>
31 #include <asm/arch/sys_proto.h>
32 #include <asm/gpio.h>
33 #include <asm/mach-types.h>
34 #include <asm/omap_musb.h>
35 #include <linux/errno.h>
36 #include <linux/usb/ch9.h>
37 #include <linux/usb/gadget.h>
38 #include <linux/usb/musb.h>
39 #include "beagle.h"
40 #include <command.h>
41
42 #ifdef CONFIG_USB_EHCI_HCD
43 #include <usb.h>
44 #include <asm/ehci-omap.h>
45 #endif
46
47 #define TWL4030_I2C_BUS                 0
48 #define EXPANSION_EEPROM_I2C_BUS        1
49 #define EXPANSION_EEPROM_I2C_ADDRESS    0x50
50
51 #define TINCANTOOLS_ZIPPY               0x01000100
52 #define TINCANTOOLS_ZIPPY2              0x02000100
53 #define TINCANTOOLS_TRAINER             0x04000100
54 #define TINCANTOOLS_SHOWDOG             0x03000100
55 #define KBADC_BEAGLEFPGA                0x01000600
56 #define LW_BEAGLETOUCH                  0x01000700
57 #define BRAINMUX_LCDOG                  0x01000800
58 #define BRAINMUX_LCDOGTOUCH             0x02000800
59 #define BBTOYS_WIFI                     0x01000B00
60 #define BBTOYS_VGA                      0x02000B00
61 #define BBTOYS_LCD                      0x03000B00
62 #define BCT_BRETTL3                     0x01000F00
63 #define BCT_BRETTL4                     0x02000F00
64 #define LSR_COM6L_ADPT                  0x01001300
65 #define BEAGLE_NO_EEPROM                0xffffffff
66
67 DECLARE_GLOBAL_DATA_PTR;
68
69 static struct {
70         unsigned int device_vendor;
71         unsigned char revision;
72         unsigned char content;
73         char fab_revision[8];
74         char env_var[16];
75         char env_setting[64];
76 } expansion_config;
77
78 /*
79  * Routine: board_init
80  * Description: Early hardware init.
81  */
82 int board_init(void)
83 {
84         gpmc_init(); /* in SRAM or SDRAM, finish GPMC */
85         /* board id for Linux */
86         gd->bd->bi_arch_number = MACH_TYPE_OMAP3_BEAGLE;
87         /* boot param addr */
88         gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100);
89
90 #if defined(CONFIG_LED_STATUS) && defined(CONFIG_LED_STATUS_BOOT_ENABLE)
91         status_led_set(CONFIG_LED_STATUS_BOOT, CONFIG_LED_STATUS_ON);
92 #endif
93
94         return 0;
95 }
96
97 #if defined(CONFIG_SPL_OS_BOOT)
98 int spl_start_uboot(void)
99 {
100         /* break into full u-boot on 'c' */
101         if (serial_tstc() && serial_getc() == 'c')
102                 return 1;
103
104         return 0;
105 }
106 #endif /* CONFIG_SPL_OS_BOOT */
107
108 /*
109  * Routine: get_board_revision
110  * Description: Detect if we are running on a Beagle revision Ax/Bx,
111  *              C1/2/3, C4, xM Ax/Bx or xM Cx. This can be done by reading
112  *              the level of GPIO173, GPIO172 and GPIO171. This should
113  *              result in
114  *              GPIO173, GPIO172, GPIO171: 1 1 1 => Ax/Bx
115  *              GPIO173, GPIO172, GPIO171: 1 1 0 => C1/2/3
116  *              GPIO173, GPIO172, GPIO171: 1 0 1 => C4
117  *              GPIO173, GPIO172, GPIO171: 0 1 0 => xM Cx
118  *              GPIO173, GPIO172, GPIO171: 0 0 0 => xM Ax/Bx
119  */
120 static int get_board_revision(void)
121 {
122         static int revision = -1;
123
124         if (revision == -1) {
125                 if (!gpio_request(171, "rev0") &&
126                     !gpio_request(172, "rev1") &&
127                     !gpio_request(173, "rev2")) {
128                         gpio_direction_input(171);
129                         gpio_direction_input(172);
130                         gpio_direction_input(173);
131
132                         revision = gpio_get_value(173) << 2 |
133                                 gpio_get_value(172) << 1 |
134                                 gpio_get_value(171);
135                 } else {
136                         printf("Error: unable to acquire board revision GPIOs\n");
137                 }
138         }
139
140         return revision;
141 }
142
143 #ifdef CONFIG_SPL_BUILD
144 /*
145  * Routine: get_board_mem_timings
146  * Description: If we use SPL then there is no x-loader nor config header
147  * so we have to setup the DDR timings ourself on both banks.
148  */
149 void get_board_mem_timings(struct board_sdrc_timings *timings)
150 {
151         int pop_mfr, pop_id;
152
153         /*
154          * We need to identify what PoP memory is on the board so that
155          * we know what timings to use.  If we can't identify it then
156          * we know it's an xM.  To map the ID values please see nand_ids.c
157          */
158         identify_nand_chip(&pop_mfr, &pop_id);
159
160         timings->mr = MICRON_V_MR_165;
161         switch (get_board_revision()) {
162         case REVISION_C4:
163                 if (pop_mfr == NAND_MFR_STMICRO && pop_id == 0xba) {
164                         /* 512MB DDR */
165                         timings->mcfg = NUMONYX_V_MCFG_165(512 << 20);
166                         timings->ctrla = NUMONYX_V_ACTIMA_165;
167                         timings->ctrlb = NUMONYX_V_ACTIMB_165;
168                         timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
169                         break;
170                 } else if (pop_mfr == NAND_MFR_MICRON && pop_id == 0xba) {
171                         /* Beagleboard Rev C4, 512MB Nand/256MB DDR*/
172                         timings->mcfg = MICRON_V_MCFG_165(128 << 20);
173                         timings->ctrla = MICRON_V_ACTIMA_165;
174                         timings->ctrlb = MICRON_V_ACTIMB_165;
175                         timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
176                         break;
177                 } else if (pop_mfr == NAND_MFR_MICRON && pop_id == 0xbc) {
178                         /* Beagleboard Rev C5, 256MB DDR */
179                         timings->mcfg = MICRON_V_MCFG_200(256 << 20);
180                         timings->ctrla = MICRON_V_ACTIMA_200;
181                         timings->ctrlb = MICRON_V_ACTIMB_200;
182                         timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
183                         break;
184                 }
185         case REVISION_XM_AB:
186         case REVISION_XM_C:
187                 if (pop_mfr == 0) {
188                         /* 256MB DDR */
189                         timings->mcfg = MICRON_V_MCFG_200(256 << 20);
190                         timings->ctrla = MICRON_V_ACTIMA_200;
191                         timings->ctrlb = MICRON_V_ACTIMB_200;
192                         timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
193                 } else {
194                         /* 512MB DDR */
195                         timings->mcfg = NUMONYX_V_MCFG_165(512 << 20);
196                         timings->ctrla = NUMONYX_V_ACTIMA_165;
197                         timings->ctrlb = NUMONYX_V_ACTIMB_165;
198                         timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
199                 }
200                 break;
201         default:
202                 /* Assume 128MB and Micron/165MHz timings to be safe */
203                 timings->mcfg = MICRON_V_MCFG_165(128 << 20);
204                 timings->ctrla = MICRON_V_ACTIMA_165;
205                 timings->ctrlb = MICRON_V_ACTIMB_165;
206                 timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
207         }
208 }
209 #endif
210
211 /*
212  * Routine: get_expansion_id
213  * Description: This function checks for expansion board by checking I2C
214  *              bus 1 for the availability of an AT24C01B serial EEPROM.
215  *              returns the device_vendor field from the EEPROM
216  */
217 static unsigned int get_expansion_id(void)
218 {
219         i2c_set_bus_num(EXPANSION_EEPROM_I2C_BUS);
220
221         /* return BEAGLE_NO_EEPROM if eeprom doesn't respond */
222         if (i2c_probe(EXPANSION_EEPROM_I2C_ADDRESS) == 1) {
223                 i2c_set_bus_num(TWL4030_I2C_BUS);
224                 return BEAGLE_NO_EEPROM;
225         }
226
227         /* read configuration data */
228         i2c_read(EXPANSION_EEPROM_I2C_ADDRESS, 0, 1, (u8 *)&expansion_config,
229                  sizeof(expansion_config));
230
231         /* retry reading configuration data with 16bit addressing */
232         if ((expansion_config.device_vendor == 0xFFFFFF00) ||
233             (expansion_config.device_vendor == 0xFFFFFFFF)) {
234                 printf("EEPROM is blank or 8bit addressing failed: retrying with 16bit:\n");
235                 i2c_read(EXPANSION_EEPROM_I2C_ADDRESS, 0, 2, (u8 *)&expansion_config,
236                          sizeof(expansion_config));
237         }
238
239         i2c_set_bus_num(TWL4030_I2C_BUS);
240
241         return expansion_config.device_vendor;
242 }
243
244 #ifdef CONFIG_VIDEO_OMAP3
245 /*
246  * Configure DSS to display background color on DVID
247  * Configure VENC to display color bar on S-Video
248  */
249 static void beagle_display_init(void)
250 {
251         omap3_dss_venc_config(&venc_config_std_tv, VENC_HEIGHT, VENC_WIDTH);
252         switch (get_board_revision()) {
253         case REVISION_AXBX:
254         case REVISION_CX:
255         case REVISION_C4:
256                 omap3_dss_panel_config(&dvid_cfg);
257                 break;
258         case REVISION_XM_AB:
259         case REVISION_XM_C:
260         default:
261                 omap3_dss_panel_config(&dvid_cfg_xm);
262                 break;
263         }
264 }
265
266 /*
267  * Enable DVI power
268  */
269 static void beagle_dvi_pup(void)
270 {
271         uchar val;
272
273         switch (get_board_revision()) {
274         case REVISION_AXBX:
275         case REVISION_CX:
276         case REVISION_C4:
277                 gpio_request(170, "dvi");
278                 gpio_direction_output(170, 0);
279                 gpio_set_value(170, 1);
280                 break;
281         case REVISION_XM_AB:
282         case REVISION_XM_C:
283         default:
284                 #define GPIODATADIR1 (TWL4030_BASEADD_GPIO+3)
285                 #define GPIODATAOUT1 (TWL4030_BASEADD_GPIO+6)
286
287                 i2c_read(TWL4030_CHIP_GPIO, GPIODATADIR1, 1, &val, 1);
288                 val |= 4;
289                 i2c_write(TWL4030_CHIP_GPIO, GPIODATADIR1, 1, &val, 1);
290
291                 i2c_read(TWL4030_CHIP_GPIO, GPIODATAOUT1, 1, &val, 1);
292                 val |= 4;
293                 i2c_write(TWL4030_CHIP_GPIO, GPIODATAOUT1, 1, &val, 1);
294                 break;
295         }
296 }
297 #endif
298
299 #ifdef CONFIG_USB_MUSB_OMAP2PLUS
300 static struct musb_hdrc_config musb_config = {
301         .multipoint     = 1,
302         .dyn_fifo       = 1,
303         .num_eps        = 16,
304         .ram_bits       = 12,
305 };
306
307 static struct omap_musb_board_data musb_board_data = {
308         .interface_type = MUSB_INTERFACE_ULPI,
309 };
310
311 static struct musb_hdrc_platform_data musb_plat = {
312 #if defined(CONFIG_USB_MUSB_HOST)
313         .mode           = MUSB_HOST,
314 #elif defined(CONFIG_USB_MUSB_GADGET)
315         .mode           = MUSB_PERIPHERAL,
316 #else
317 #error "Please define either CONFIG_USB_MUSB_HOST or CONFIG_USB_MUSB_GADGET"
318 #endif
319         .config         = &musb_config,
320         .power          = 100,
321         .platform_ops   = &omap2430_ops,
322         .board_data     = &musb_board_data,
323 };
324 #endif
325
326 /*
327  * Routine: misc_init_r
328  * Description: Configure board specific parts
329  */
330 int misc_init_r(void)
331 {
332         struct gpio *gpio5_base = (struct gpio *)OMAP34XX_GPIO5_BASE;
333         struct gpio *gpio6_base = (struct gpio *)OMAP34XX_GPIO6_BASE;
334         struct control_prog_io *prog_io_base = (struct control_prog_io *)OMAP34XX_CTRL_BASE;
335         bool generate_fake_mac = false;
336         u32 value;
337
338         /* Enable i2c2 pullup resisters */
339         value = readl(&prog_io_base->io1);
340         value &= ~(PRG_I2C2_PULLUPRESX);
341         writel(value, &prog_io_base->io1);
342
343         switch (get_board_revision()) {
344         case REVISION_AXBX:
345                 printf("Beagle Rev Ax/Bx\n");
346                 env_set("beaglerev", "AxBx");
347                 break;
348         case REVISION_CX:
349                 printf("Beagle Rev C1/C2/C3\n");
350                 env_set("beaglerev", "Cx");
351                 MUX_BEAGLE_C();
352                 break;
353         case REVISION_C4:
354                 printf("Beagle Rev C4\n");
355                 env_set("beaglerev", "C4");
356                 MUX_BEAGLE_C();
357                 /* Set VAUX2 to 1.8V for EHCI PHY */
358                 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
359                                         TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
360                                         TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
361                                         TWL4030_PM_RECEIVER_DEV_GRP_P1);
362                 break;
363         case REVISION_XM_AB:
364                 printf("Beagle xM Rev A/B\n");
365                 env_set("beaglerev", "xMAB");
366                 MUX_BEAGLE_XM();
367                 /* Set VAUX2 to 1.8V for EHCI PHY */
368                 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
369                                         TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
370                                         TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
371                                         TWL4030_PM_RECEIVER_DEV_GRP_P1);
372                 generate_fake_mac = true;
373                 break;
374         case REVISION_XM_C:
375                 printf("Beagle xM Rev C\n");
376                 env_set("beaglerev", "xMC");
377                 MUX_BEAGLE_XM();
378                 /* Set VAUX2 to 1.8V for EHCI PHY */
379                 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
380                                         TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
381                                         TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
382                                         TWL4030_PM_RECEIVER_DEV_GRP_P1);
383                 generate_fake_mac = true;
384                 break;
385         default:
386                 printf("Beagle unknown 0x%02x\n", get_board_revision());
387                 MUX_BEAGLE_XM();
388                 /* Set VAUX2 to 1.8V for EHCI PHY */
389                 twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX2_DEDICATED,
390                                         TWL4030_PM_RECEIVER_VAUX2_VSEL_18,
391                                         TWL4030_PM_RECEIVER_VAUX2_DEV_GRP,
392                                         TWL4030_PM_RECEIVER_DEV_GRP_P1);
393                 generate_fake_mac = true;
394         }
395
396         switch (get_expansion_id()) {
397         case TINCANTOOLS_ZIPPY:
398                 printf("Recognized Tincantools Zippy board (rev %d %s)\n",
399                         expansion_config.revision,
400                         expansion_config.fab_revision);
401                 MUX_TINCANTOOLS_ZIPPY();
402                 env_set("buddy", "zippy");
403                 break;
404         case TINCANTOOLS_ZIPPY2:
405                 printf("Recognized Tincantools Zippy2 board (rev %d %s)\n",
406                         expansion_config.revision,
407                         expansion_config.fab_revision);
408                 MUX_TINCANTOOLS_ZIPPY();
409                 env_set("buddy", "zippy2");
410                 break;
411         case TINCANTOOLS_TRAINER:
412                 printf("Recognized Tincantools Trainer board (rev %d %s)\n",
413                         expansion_config.revision,
414                         expansion_config.fab_revision);
415                 MUX_TINCANTOOLS_ZIPPY();
416                 MUX_TINCANTOOLS_TRAINER();
417                 env_set("buddy", "trainer");
418                 break;
419         case TINCANTOOLS_SHOWDOG:
420                 printf("Recognized Tincantools Showdow board (rev %d %s)\n",
421                         expansion_config.revision,
422                         expansion_config.fab_revision);
423                 /* Place holder for DSS2 definition for showdog lcd */
424                 env_set("defaultdisplay", "showdoglcd");
425                 env_set("buddy", "showdog");
426                 break;
427         case KBADC_BEAGLEFPGA:
428                 printf("Recognized KBADC Beagle FPGA board\n");
429                 MUX_KBADC_BEAGLEFPGA();
430                 env_set("buddy", "beaglefpga");
431                 break;
432         case LW_BEAGLETOUCH:
433                 printf("Recognized Liquidware BeagleTouch board\n");
434                 env_set("buddy", "beagletouch");
435                 break;
436         case BRAINMUX_LCDOG:
437                 printf("Recognized Brainmux LCDog board\n");
438                 env_set("buddy", "lcdog");
439                 break;
440         case BRAINMUX_LCDOGTOUCH:
441                 printf("Recognized Brainmux LCDog Touch board\n");
442                 env_set("buddy", "lcdogtouch");
443                 break;
444         case BBTOYS_WIFI:
445                 printf("Recognized BeagleBoardToys WiFi board\n");
446                 MUX_BBTOYS_WIFI()
447                 env_set("buddy", "bbtoys-wifi");
448                 break;
449         case BBTOYS_VGA:
450                 printf("Recognized BeagleBoardToys VGA board\n");
451                 break;
452         case BBTOYS_LCD:
453                 printf("Recognized BeagleBoardToys LCD board\n");
454                 break;
455         case BCT_BRETTL3:
456                 printf("Recognized bct electronic GmbH brettl3 board\n");
457                 break;
458         case BCT_BRETTL4:
459                 printf("Recognized bct electronic GmbH brettl4 board\n");
460                 break;
461         case LSR_COM6L_ADPT:
462                 printf("Recognized LSR COM6L Adapter Board\n");
463                 MUX_BBTOYS_WIFI()
464                 env_set("buddy", "lsr-com6l-adpt");
465                 break;
466         case BEAGLE_NO_EEPROM:
467                 printf("No EEPROM on expansion board\n");
468                 env_set("buddy", "none");
469                 break;
470         default:
471                 printf("Unrecognized expansion board: %x\n",
472                         expansion_config.device_vendor);
473                 env_set("buddy", "unknown");
474         }
475
476         if (expansion_config.content == 1)
477                 env_set(expansion_config.env_var, expansion_config.env_setting);
478
479         twl4030_power_init();
480         switch (get_board_revision()) {
481         case REVISION_XM_AB:
482                 twl4030_led_init(TWL4030_LED_LEDEN_LEDBON);
483                 break;
484         default:
485                 twl4030_led_init(TWL4030_LED_LEDEN_LEDAON | TWL4030_LED_LEDEN_LEDBON);
486                 break;
487         }
488
489         /* Set GPIO states before they are made outputs */
490         writel(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1,
491                 &gpio6_base->setdataout);
492         writel(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 |
493                 GPIO15 | GPIO14 | GPIO13 | GPIO12, &gpio5_base->setdataout);
494
495         /* Configure GPIOs to output */
496         writel(~(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1), &gpio6_base->oe);
497         writel(~(GPIO31 | GPIO30 | GPIO29 | GPIO28 | GPIO22 | GPIO21 |
498                 GPIO15 | GPIO14 | GPIO13 | GPIO12), &gpio5_base->oe);
499
500         omap_die_id_display();
501
502 #ifdef CONFIG_VIDEO_OMAP3
503         beagle_dvi_pup();
504         beagle_display_init();
505         omap3_dss_enable();
506 #endif
507
508 #ifdef CONFIG_USB_MUSB_OMAP2PLUS
509         musb_register(&musb_plat, &musb_board_data, (void *)MUSB_BASE);
510 #endif
511
512         if (generate_fake_mac)
513                 omap_die_id_usbethaddr();
514
515 #if defined(CONFIG_MTDIDS_DEFAULT) && defined(CONFIG_MTDPARTS_DEFAULT)
516         if (strlen(CONFIG_MTDIDS_DEFAULT))
517                 env_set("mtdids", CONFIG_MTDIDS_DEFAULT);
518
519         if (strlen(CONFIG_MTDPARTS_DEFAULT))
520                 env_set("mtdparts", CONFIG_MTDPARTS_DEFAULT);
521 #endif
522
523         return 0;
524 }
525
526 /*
527  * Routine: set_muxconf_regs
528  * Description: Setting up the configuration Mux registers specific to the
529  *              hardware. Many pins need to be moved from protect to primary
530  *              mode.
531  */
532 void set_muxconf_regs(void)
533 {
534         MUX_BEAGLE();
535 }
536
537 #if defined(CONFIG_MMC)
538 int board_mmc_init(bd_t *bis)
539 {
540         return omap_mmc_init(0, 0, 0, -1, -1);
541 }
542 #endif
543
544 #if defined(CONFIG_MMC)
545 void board_mmc_power_init(void)
546 {
547         twl4030_power_mmc_init(0);
548 }
549 #endif
550
551 #if defined(CONFIG_USB_EHCI_HCD) && !defined(CONFIG_SPL_BUILD)
552 /* Call usb_stop() before starting the kernel */
553 void show_boot_progress(int val)
554 {
555         if (val == BOOTSTAGE_ID_RUN_OS)
556                 usb_stop();
557 }
558
559 static struct omap_usbhs_board_data usbhs_bdata = {
560         .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
561         .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
562         .port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED
563 };
564
565 int ehci_hcd_init(int index, enum usb_init_type init,
566                 struct ehci_hccr **hccr, struct ehci_hcor **hcor)
567 {
568         return omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
569 }
570
571 int ehci_hcd_stop(int index)
572 {
573         return omap_ehci_hcd_stop();
574 }
575
576 #endif /* CONFIG_USB_EHCI_HCD */
577
578 #if defined(CONFIG_USB_ETHER) && defined(CONFIG_USB_MUSB_GADGET)
579 int board_eth_init(bd_t *bis)
580 {
581         return usb_eth_initialize(bis);
582 }
583 #endif