From 5cf91d6bdc3e60bd43f9ba1bbb97a43ee49b2b2d Mon Sep 17 00:00:00 2001 From: wdenk Date: Fri, 23 Apr 2004 20:32:05 +0000 Subject: [PATCH] * Modify KUP4X board configuration to use SL811 driver for USB memory sticks (including FAT / VFAT filesystem support) * Add SL811 Host Controller Interface driver for USB * Add CFG_I2C_EEPROM_ADDR_OVERFLOW desription to README * Patch by Pantelis Antoniou, 19 Apr 2004: Allow to use shell style syntax (i. e. ${var} ) with standard parser. Minor patches for Intracom boards. * Patch by Christian Pell, 19 Apr 2004: cleanup support for CF/IDE on PCMCIA for PXA25X --- CHANGELOG | 14 + README | 21 + board/icecube/icecube.c | 17 +- board/kup/kup4x/Makefile | 2 +- board/kup/kup4x/usb.c | 81 ---- board/netphone/netphone.c | 8 + board/netphone/phone_console.c | 20 +- common/cmd_ide.c | 69 ++-- common/cmd_mii.c | 2 +- common/cmd_usb.c | 16 +- common/main.c | 8 +- drivers/Makefile | 2 +- drivers/sl811.h | 104 +++++ drivers/sl811_usb.c | 705 +++++++++++++++++++++++++++++++++ include/configs/KUP4X.h | 7 +- include/configs/NETPHONE.h | 4 +- include/configs/NETTA.h | 4 +- include/configs/NETVIA.h | 4 +- include/fat.h | 9 +- include/usb.h | 44 +- 20 files changed, 954 insertions(+), 187 deletions(-) delete mode 100644 board/kup/kup4x/usb.c create mode 100644 drivers/sl811.h create mode 100644 drivers/sl811_usb.c diff --git a/CHANGELOG b/CHANGELOG index f4112df900..2e01d69606 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,20 @@ Changes for U-Boot 1.1.1: ====================================================================== +* Modify KUP4X board configuration to use SL811 driver for USB memory + sticks (including FAT / VFAT filesystem support) + +* Add SL811 Host Controller Interface driver for USB + +* Add CFG_I2C_EEPROM_ADDR_OVERFLOW desription to README + +* Patch by Pantelis Antoniou, 19 Apr 2004: + Allow to use shell style syntax (i. e. ${var} ) with standard parser. + Minor patches for Intracom boards. + +* Patch by Christian Pell, 19 Apr 2004: + cleanup support for CF/IDE on PCMCIA for PXA25X + * Temporarily disabled John Kerl's extended MII command code because "miivals.h" is missing diff --git a/README b/README index df2c29531e..d441442d63 100644 --- a/README +++ b/README @@ -1751,6 +1751,17 @@ to save the current settings. The length in bytes of the EEPROM memory array address. Note that this is NOT the chip address length! + - CFG_I2C_EEPROM_ADDR_OVERFLOW: + EEPROM chips that implement "address overflow" are ones + like Catalyst 24WC04/08/16 which has 9/10/11 bits of + address and the extra bits end up in the "chip address" bit + slots. This makes a 24WC08 (1Kbyte) chip look like four 256 + byte chips. + + Note that we consider the length of the address field to + still be one byte because the extra address bits are hidden + in the chip address. + - CFG_EEPROM_SIZE: The size in bytes of the EEPROM device. @@ -1972,6 +1983,16 @@ Low Level (hardware related) configuration options: Note that this is a global option, we can't have one FEC in standard MII mode and another in RMII mode. +- CONFIG_CRC32_VERIFY + Add a verify option to the crc32 command. + The syntax is: + + => crc32 -v
+ + Where address/count indicate a memory area + and crc32 is the correct crc32 which the + area should have. + Building the Software: ====================== diff --git a/board/icecube/icecube.c b/board/icecube/icecube.c index 5a206c0f48..15def0c61a 100644 --- a/board/icecube/icecube.c +++ b/board/icecube/icecube.c @@ -42,7 +42,7 @@ static void sdram_start (int hi_addr) /* unlock mode register */ *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000000 | hi_addr_bit; __asm__ volatile ("sync"); - + /* precharge all banks */ *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | 0x80000002 | hi_addr_bit; __asm__ volatile ("sync"); @@ -68,7 +68,7 @@ static void sdram_start (int hi_addr) /* set mode register */ *(vu_long *)MPC5XXX_SDRAM_MODE = SDRAM_MODE; __asm__ volatile ("sync"); - + /* normal operation */ *(vu_long *)MPC5XXX_SDRAM_CTRL = SDRAM_CONTROL | hi_addr_bit; __asm__ volatile ("sync"); @@ -88,7 +88,7 @@ long int initdram (int board_type) ulong dramsize2 = 0; #ifndef CFG_RAMBOOT ulong test1, test2; - + /* setup SDRAM chip selects */ *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x0000001e;/* 2G at 0x0 */ *(vu_long *)MPC5XXX_SDRAM_CS1CFG = 0x80000000;/* disabled */ @@ -121,7 +121,7 @@ long int initdram (int board_type) if (dramsize < (1 << 20)) { dramsize = 0; } - + /* set SDRAM CS0 size according to the amount of RAM found */ if (dramsize > 0) { *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0x13 + __builtin_ffs(dramsize >> 20) - 1; @@ -129,7 +129,6 @@ long int initdram (int board_type) *(vu_long *)MPC5XXX_SDRAM_CS0CFG = 0; /* disabled */ } - /* let SDRAM CS1 start right after CS0 */ *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize + 0x0000001e;/* 2G */ @@ -144,12 +143,12 @@ long int initdram (int board_type) } else { dramsize2 = test2; } - + /* memory smaller than 1MB is impossible */ if (dramsize2 < (1 << 20)) { dramsize2 = 0; } - + /* set SDRAM CS1 size according to the amount of RAM found */ if (dramsize2 > 0) { *(vu_long *)MPC5XXX_SDRAM_CS1CFG = dramsize @@ -188,7 +187,7 @@ long int initdram (int board_type) ulong dramsize = 0; #ifndef CFG_RAMBOOT ulong test1, test2; - + /* setup and enable SDRAM chip selects */ *(vu_long *)MPC5XXX_SDRAM_START = 0x00000000; *(vu_long *)MPC5XXX_SDRAM_STOP = 0x0000ffff;/* 2G */ @@ -217,7 +216,7 @@ long int initdram (int board_type) /* set SDRAM end address according to size */ *(vu_long *)MPC5XXX_SDRAM_STOP = ((dramsize - 1) >> 15); - + #else /* CFG_RAMBOOT */ /* Retrieve amount of SDRAM available */ diff --git a/board/kup/kup4x/Makefile b/board/kup/kup4x/Makefile index 3fed0f0485..573204491e 100644 --- a/board/kup/kup4x/Makefile +++ b/board/kup/kup4x/Makefile @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk LIB = lib$(BOARD).a -OBJS = $(BOARD).o ../common/flash.o ../common/kup.o usb.o +OBJS = $(BOARD).o ../common/flash.o ../common/kup.o $(LIB): .depend $(OBJS) $(AR) crv $@ $(OBJS) diff --git a/board/kup/kup4x/usb.c b/board/kup/kup4x/usb.c deleted file mode 100644 index 5444008ecd..0000000000 --- a/board/kup/kup4x/usb.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * (C) Copyright 2004 - * Klaus Heydeck, Kieback & Peter GmbH & Co KG, heydeck@kieback-peter.de - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include "../common/kup.h" - - -#define SL811_ADR (0x50000000) -#define SL811_DAT (0x50000001) - - -static void sl811_write_index_data (__u8 index, __u8 data) -{ - *(volatile unsigned char *) (SL811_ADR) = index; - __asm__ ("eieio"); - *(volatile unsigned char *) (SL811_DAT) = data; - __asm__ ("eieio"); -} - -static __u8 sl811_read_index_data (__u8 index) -{ - __u8 data; - - *(volatile unsigned char *) (SL811_ADR) = index; - __asm__ ("eieio"); - data = *(volatile unsigned char *) (SL811_DAT); - __asm__ ("eieio"); - return (data); -} - -int usb_init_kup4x (void) -{ - volatile immap_t *immap = (immap_t *) CFG_IMMR; - volatile memctl8xx_t *memctl = &immap->im_memctl; - int i; - unsigned char tmp; - - memctl = &immap->im_memctl; - memctl->memc_or7 = 0xFFFF8726; - memctl->memc_br7 = 0x50000401; /* start at 0x50000000 */ - /* BP 14 low = USB ON */ - immap->im_cpm.cp_pbdat &= ~(BP_USB_VCC); - /* PB 14 nomal port */ - immap->im_cpm.cp_pbpar &= ~(BP_USB_VCC); - /* output */ - immap->im_cpm.cp_pbdir |= (BP_USB_VCC); - - puts ("USB: "); - - for (i = 0x10; i < 0xff; i++) { - sl811_write_index_data (i, i); - tmp = (sl811_read_index_data (i)); - if (tmp != i) { - printf ("SL811 compare error index=0x%02x read=0x%02x\n", i, tmp); - return (-1); - } - } - printf ("SL811 ready\n"); - return (0); -} diff --git a/board/netphone/netphone.c b/board/netphone/netphone.c index 91943c97de..698115a319 100644 --- a/board/netphone/netphone.c +++ b/board/netphone/netphone.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "mpc8xx.h" @@ -659,6 +660,7 @@ int overwrite_console(void) extern int drv_phone_init(void); extern int drv_phone_use_me(void); +extern int drv_phone_is_idle(void); int misc_init_r(void) { @@ -691,6 +693,12 @@ int last_stage_init(void) do_poll(); if (drv_phone_use_me()) { + status_led_set(0, STATUS_LED_ON); + while (!drv_phone_is_idle()) { + do_poll(); + udelay(1000000 / CFG_HZ); + } + console_assign(stdin, "phone"); console_assign(stdout, "phone"); console_assign(stderr, "phone"); diff --git a/board/netphone/phone_console.c b/board/netphone/phone_console.c index a0485b0927..c6a59af0c3 100644 --- a/board/netphone/phone_console.c +++ b/board/netphone/phone_console.c @@ -179,7 +179,6 @@ static int last_input_mode; static int refresh_time; static int blink_time; static char last_fast_punct; -static int last_tab_indicator = -1; /*************************************************************************************************/ @@ -239,8 +238,6 @@ static void console_init(void) refresh_time = REFRESH_HZ; blink_time = BLINK_HZ; - tab_indicator = 1; - memset(vty_buf, ' ', sizeof(vty_buf)); memset(last_visible_buf, ' ', sizeof(last_visible_buf)); @@ -253,6 +250,8 @@ static void console_init(void) sed156x_init(); width = sed156x_text_width; height = sed156x_text_height - 1; + + tab_indicator = 0; } /*****************************************************************************/ @@ -718,8 +717,10 @@ static void update(void) if (input_mode != last_input_mode) sed156x_output_at(sed156x_text_width - 3, sed156x_text_height - 1, input_mode_txt[input_mode], 3); - if (tab_indicator != last_tab_indicator) + if (tab_indicator == 0) { sed156x_output_at(0, sed156x_text_height - 1, "\\t", 2); + tab_indicator = 1; + } if (fast_punct != last_fast_punct) sed156x_output_at(4, sed156x_text_height - 1, &fast_punct, 1); @@ -779,7 +780,6 @@ static void update(void) last_input_mode = input_mode; last_fast_punct = fast_punct; - last_tab_indicator = tab_indicator; } /* ensure visibility; the trick is to minimize the screen movement */ @@ -891,7 +891,8 @@ void phone_putc(const char c) blink_time = BLINK_HZ; switch (c) { - case 13: /* ignore */ + case '\a': /* ignore bell */ + case '\r': /* ignore carriage return */ break; case '\n': /* next line */ @@ -1141,3 +1142,10 @@ static void kp_do_poll(void) break; } } + +/**************************************************************************************/ + +int drv_phone_is_idle(void) +{ + return kp_state == SCAN; +} diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 50ada33e86..0c9927be74 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -60,6 +60,11 @@ static unsigned long mips_io_port_base = 0; # define SHOW_BOOT_PROGRESS(arg) #endif +#ifdef __PPC__ +# define EIEIO __asm__ volatile ("eieio") +#else +# define EIEIO /* nothing */ +#endif #undef IDE_DEBUG @@ -790,9 +795,7 @@ ide_outb(int dev, int port, unsigned char val) dev, port, val, (ATA_CURR_BASE(dev)+port)); /* Ensure I/O operations complete */ -#ifdef __PPC__ - __asm__ volatile("eieio"); -#endif + EIEIO; *((uchar *)(ATA_CURR_BASE(dev)+port)) = val; } #else /* ! __PPC__ */ @@ -810,9 +813,7 @@ ide_inb(int dev, int port) { uchar val; /* Ensure I/O operations complete */ -#ifdef __PPC__ - __asm__ volatile("eieio"); -#endif + EIEIO; val = *((uchar *)(ATA_CURR_BASE(dev)+port)); PRINTF ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n", dev, port, (ATA_CURR_BASE(dev)+port), val); @@ -837,9 +838,9 @@ output_data_short(int dev, ulong *sect_buf, int words) pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); dbuf = (ushort *)sect_buf; while (words--) { - __asm__ volatile ("eieio"); + EIEIO; *pbuf = *dbuf++; - __asm__ volatile ("eieio"); + EIEIO; } if (words&1) @@ -895,13 +896,9 @@ output_data(int dev, ulong *sect_buf, int words) pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); dbuf = (ushort *)sect_buf; while (words--) { -#ifdef __PPC__ - __asm__ volatile ("eieio"); -#endif + EIEIO; *pbuf = *dbuf++; -#ifdef __PPC__ - __asm__ volatile ("eieio"); -#endif + EIEIO; *pbuf = *dbuf++; } #else /* CONFIG_HMI10 */ @@ -913,13 +910,13 @@ output_data(int dev, ulong *sect_buf, int words) pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); dbuf = (uchar *)sect_buf; while (words--) { - __asm__ volatile ("eieio"); + EIEIO; *pbuf_even = *dbuf++; - __asm__ volatile ("eieio"); + EIEIO; *pbuf_odd = *dbuf++; - __asm__ volatile ("eieio"); + EIEIO; *pbuf_even = *dbuf++; - __asm__ volatile ("eieio"); + EIEIO; *pbuf_odd = *dbuf++; } #endif /* CONFIG_HMI10 */ @@ -946,13 +943,9 @@ input_data(int dev, ulong *sect_buf, int words) PRINTF("in input data base for read is %lx\n", (unsigned long) pbuf); while (words--) { -#ifdef __PPC__ - __asm__ volatile ("eieio"); -#endif + EIEIO; *dbuf++ = *pbuf; -#ifdef __PPC__ - __asm__ volatile ("eieio"); -#endif + EIEIO; *dbuf++ = *pbuf; } #else /* CONFIG_HMI10 */ @@ -964,13 +957,13 @@ input_data(int dev, ulong *sect_buf, int words) pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); dbuf = (uchar *)sect_buf; while (words--) { - __asm__ volatile ("eieio"); + EIEIO; *dbuf++ = *pbuf_even; - __asm__ volatile ("eieio"); + EIEIO; *dbuf++ = *pbuf_odd; - __asm__ volatile ("eieio"); + EIEIO; *dbuf++ = *pbuf_even; - __asm__ volatile ("eieio"); + EIEIO; *dbuf++ = *pbuf_odd; } #endif /* CONFIG_HMI10 */ @@ -994,9 +987,9 @@ input_data_short(int dev, ulong *sect_buf, int words) pbuf = (ushort *)(ATA_CURR_BASE(dev)+ATA_DATA_REG); dbuf = (ushort *)sect_buf; while (words--) { - __asm__ volatile ("eieio"); + EIEIO; *dbuf++ = *pbuf; - __asm__ volatile ("eieio"); + EIEIO; } if (words&1) { @@ -1608,9 +1601,7 @@ output_data_shorts(int dev, ushort *sect_buf, int shorts) PRINTF("in output data shorts base for read is %lx\n", (unsigned long) pbuf); while (shorts--) { -#ifdef __PPC__ - __asm__ volatile ("eieio"); -#endif + EIEIO; *pbuf = *dbuf++; } #else /* CONFIG_HMI10 */ @@ -1621,9 +1612,9 @@ output_data_shorts(int dev, ushort *sect_buf, int shorts) pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN); pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); while (shorts--) { - __asm__ volatile ("eieio"); + EIEIO; *pbuf_even = *dbuf++; - __asm__ volatile ("eieio"); + EIEIO; *pbuf_odd = *dbuf++; } #endif /* CONFIG_HMI10 */ @@ -1642,9 +1633,7 @@ input_data_shorts(int dev, ushort *sect_buf, int shorts) PRINTF("in input data shorts base for read is %lx\n", (unsigned long) pbuf); while (shorts--) { -#ifdef __PPC__ - __asm__ volatile ("eieio"); -#endif + EIEIO; *dbuf++ = *pbuf; } #else /* CONFIG_HMI10 */ @@ -1655,9 +1644,9 @@ input_data_shorts(int dev, ushort *sect_buf, int shorts) pbuf_even = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_EVEN); pbuf_odd = (uchar *)(ATA_CURR_BASE(dev)+ATA_DATA_ODD); while (shorts--) { - __asm__ volatile ("eieio"); + EIEIO; *dbuf++ = *pbuf_even; - __asm__ volatile ("eieio"); + EIEIO; *dbuf++ = *pbuf_odd; } #endif /* CONFIG_HMI10 */ diff --git a/common/cmd_mii.c b/common/cmd_mii.c index 4539dc54ca..8ec05c80fa 100644 --- a/common/cmd_mii.c +++ b/common/cmd_mii.c @@ -413,7 +413,7 @@ static void extract_range( } } -// ---------------------------------------------------------------- +/* ---------------------------------------------------------------- */ int do_mii (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) { char op; diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 150b106b60..83004b53ac 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -598,14 +598,14 @@ U_BOOT_CMD( usb, 5, 1, do_usb, "usb - USB sub-system\n", "reset - reset (rescan) USB controller\n" - "usb stop [f] - stop USB [f]=force stop\n" - "usb tree - show USB device tree\n" - "usb info [dev] - show available USB devices\n" - "usb scan - (re-)scan USB bus for storage devices\n" - "usb device [dev] - show or set current USB storage device\n" - "usb part [dev] - print partition table of one or all USB storage devices\n" - "usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n" - " to memory address `addr'\n" + "usb stop [f] - stop USB [f]=force stop\n" + "usb tree - show USB device tree\n" + "usb info [dev] - show available USB devices\n" + "usb scan - (re-)scan USB bus for storage devices\n" + "usb device [dev] - show or set current USB storage device\n" + "usb part [dev] - print partition table of one or all USB storage devices\n" + "usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n" + " to memory address `addr'\n" ); diff --git a/common/main.c b/common/main.c index 7ce9b75f90..0869426f17 100644 --- a/common/main.c +++ b/common/main.c @@ -726,8 +726,8 @@ static void process_macros (const char *input, char *output) int inputcnt = strlen (input); int outputcnt = CFG_CBSIZE; int state = 0; /* 0 = waiting for '$' */ - /* 1 = waiting for '(' */ - /* 2 = waiting for ')' */ + /* 1 = waiting for '(' or '{' */ + /* 2 = waiting for ')' or '}' */ /* 3 = waiting for ''' */ #ifdef DEBUG_PARSER char *output_start = output; @@ -765,7 +765,7 @@ static void process_macros (const char *input, char *output) } break; case 1: /* Waiting for ( */ - if (c == '(') { + if (c == '(' || c == '{') { state++; varname_start = input; } else { @@ -780,7 +780,7 @@ static void process_macros (const char *input, char *output) } break; case 2: /* Waiting for ) */ - if (c == ')') { + if (c == ')' || c == '}') { int i; char envname[CFG_CBSIZE], *envval; int envcnt = input-varname_start-1; /* Varname # of chars */ diff --git a/drivers/Makefile b/drivers/Makefile index ee2d8b9cd5..0d1860e6e1 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -40,7 +40,7 @@ OBJS = 3c589.o 5701rls.o ali512x.o \ rtl8019.o rtl8139.o rtl8169.o \ s3c24x0_i2c.o sed13806.o sed156x.o \ serial.o serial_max3100.o serial_pl010.o serial_pl011.o \ - serial_xuartlite.o \ + serial_xuartlite.o sl811_usb.o \ smc91111.o smiLynxEM.o status_led.o sym53c8xx.o \ ti_pci1410a.o tigon3.o w83c553f.o omap1510_i2c.o \ usbdcore.o usbdcore_ep0.o usbdcore_omap1510.o usbtty.o \ diff --git a/drivers/sl811.h b/drivers/sl811.h new file mode 100644 index 0000000000..c1f9f013bd --- /dev/null +++ b/drivers/sl811.h @@ -0,0 +1,104 @@ +#ifndef __UBOOT_SL811_H +#define __UBOOT_SL811_H + +#undef SL811_DEBUG + +#ifdef SL811_DEBUG + #define PDEBUG(level, fmt, args...) \ + if (debug >= (level)) printf("[%s:%d] " fmt, \ + __PRETTY_FUNCTION__, __LINE__ , ## args) +#else + #define PDEBUG(level, fmt, args...) do {} while(0) +#endif + +/* Sl811 host control register */ +#define SL811_CTRL_A 0x00 +#define SL811_ADDR_A 0x01 +#define SL811_LEN_A 0x02 +#define SL811_STS_A 0x03 /* read */ +#define SL811_PIDEP_A 0x03 /* write */ +#define SL811_CNT_A 0x04 /* read */ +#define SL811_DEV_A 0x04 /* write */ +#define SL811_CTRL1 0x05 +#define SL811_INTR 0x06 +#define SL811_CTRL_B 0x08 +#define SL811_ADDR_B 0x09 +#define SL811_LEN_B 0x0A +#define SL811_STS_B 0x0B /* read */ +#define SL811_PIDEP_B 0x0B /* write */ +#define SL811_CNT_B 0x0C /* read */ +#define SL811_DEV_B 0x0C /* write */ +#define SL811_INTRSTS 0x0D /* write clears bitwise */ +#define SL811_HWREV 0x0E /* read */ +#define SL811_SOFLOW 0x0E /* write */ +#define SL811_SOFCNTDIV 0x0F /* read */ +#define SL811_CTRL2 0x0F /* write */ + +/* USB control register bits (addr 0x00 and addr 0x08) */ +#define SL811_USB_CTRL_ARM 0x01 +#define SL811_USB_CTRL_ENABLE 0x02 +#define SL811_USB_CTRL_DIR_OUT 0x04 +#define SL811_USB_CTRL_ISO 0x10 +#define SL811_USB_CTRL_SOF 0x20 +#define SL811_USB_CTRL_TOGGLE_1 0x40 +#define SL811_USB_CTRL_PREAMBLE 0x80 + +/* USB status register bits (addr 0x03 and addr 0x0B) */ +#define SL811_USB_STS_ACK 0x01 +#define SL811_USB_STS_ERROR 0x02 +#define SL811_USB_STS_TIMEOUT 0x04 +#define SL811_USB_STS_TOGGLE_1 0x08 +#define SL811_USB_STS_SETUP 0x10 +#define SL811_USB_STS_OVERFLOW 0x20 +#define SL811_USB_STS_NAK 0x40 +#define SL811_USB_STS_STALL 0x80 + +/* Control register 1 bits (addr 0x05) */ +#define SL811_CTRL1_SOF 0x01 +#define SL811_CTRL1_RESET 0x08 +#define SL811_CTRL1_JKSTATE 0x10 +#define SL811_CTRL1_SPEED_LOW 0x20 +#define SL811_CTRL1_SUSPEND 0x40 + +/* Interrut enable (addr 0x06) and interrupt status register bits (addr 0x0D) */ +#define SL811_INTR_DONE_A 0x01 +#define SL811_INTR_DONE_B 0x02 +#define SL811_INTR_SOF 0x10 +#define SL811_INTR_INSRMV 0x20 +#define SL811_INTR_DETECT 0x40 +#define SL811_INTR_NOTPRESENT 0x40 +#define SL811_INTR_SPEED_FULL 0x80 /* only in status reg */ + +/* HW rev and SOF lo register bits (addr 0x0E) */ +#define SL811_HWR_HWREV 0xF0 + +/* SOF counter and control reg 2 (addr 0x0F) */ +#define SL811_CTL2_SOFHI 0x3F +#define SL811_CTL2_DSWAP 0x40 +#define SL811_CTL2_HOST 0x80 + +/* Set up for 1-ms SOF time. */ +#define SL811_12M_LOW 0xE0 +#define SL811_12M_HI 0x2E + +#define SL811_DATA_START 0x10 +#define SL811_DATA_LIMIT 240 + +/* Requests: bRequest << 8 | bmRequestType */ +#define RH_GET_STATUS 0x0080 +#define RH_CLEAR_FEATURE 0x0100 +#define RH_SET_FEATURE 0x0300 +#define RH_SET_ADDRESS 0x0500 +#define RH_GET_DESCRIPTOR 0x0680 +#define RH_SET_DESCRIPTOR 0x0700 +#define RH_GET_CONFIGURATION 0x0880 +#define RH_SET_CONFIGURATION 0x0900 +#define RH_GET_STATE 0x0280 +#define RH_GET_INTERFACE 0x0A80 +#define RH_SET_INTERFACE 0x0B00 +#define RH_SYNC_FRAME 0x0C80 + + +#define PIDEP(pid, ep) (((pid) & 0x0f) << 4 | (ep)) + +#endif /* __UBOOT_SL811_H */ diff --git a/drivers/sl811_usb.c b/drivers/sl811_usb.c new file mode 100644 index 0000000000..a18e54d775 --- /dev/null +++ b/drivers/sl811_usb.c @@ -0,0 +1,705 @@ +/* + * (C) Copyright 2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * This code is based on linux driver for sl811hs chip, source at + * drivers/usb/host/sl811.c: + * + * SL811 Host Controller Interface driver for USB. + * + * Copyright (c) 2003/06, Courage Co., Ltd. + * + * Based on: + * 1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap, + * Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, + * Adam Richter, Gregory P. Smith; + * 2.Original SL811 driver (hc_sl811.o) by Pei Liu + * 3.Rewrited as sl811.o by Yin Aihua + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#ifdef CONFIG_USB_SL811HS +#include +#include +#include "sl811.h" + +#include "../board/kup/common/kup.h" + +#ifdef __PPC__ +# define EIEIO __asm__ volatile ("eieio") +#else +# define EIEIO /* nothing */ +#endif + +#define SL811_ADR (0x50000000) +#define SL811_DAT (0x50000001) + +#define mdelay(n) ({unsigned long msec=(n); while (msec--) udelay(1000);}) + +#ifdef SL811_DEBUG +static int debug = 9; +#endif + +static int root_hub_devnum = 0; +static struct usb_port_status rh_status = { 0 };/* root hub port status */ + +static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe, + void *data, int buf_len, struct devrequest *cmd); + +static void sl811_write (__u8 index, __u8 data) +{ + *(volatile unsigned char *) (SL811_ADR) = index; + EIEIO; + *(volatile unsigned char *) (SL811_DAT) = data; + EIEIO; +} + +static __u8 sl811_read (__u8 index) +{ + __u8 data; + + *(volatile unsigned char *) (SL811_ADR) = index; + EIEIO; + data = *(volatile unsigned char *) (SL811_DAT); + EIEIO; + return (data); +} + +/* + * Read consecutive bytes of data from the SL811H/SL11H buffer + */ +static void inline sl811_read_buf(__u8 offset, __u8 *buf, __u8 size) +{ + *(volatile unsigned char *) (SL811_ADR) = offset; + EIEIO; + while (size--) { + *buf++ = *(volatile unsigned char *) (SL811_DAT); + EIEIO; + } +} + +/* + * Write consecutive bytes of data to the SL811H/SL11H buffer + */ +static void inline sl811_write_buf(__u8 offset, __u8 *buf, __u8 size) +{ + *(volatile unsigned char *) (SL811_ADR) = offset; + EIEIO; + while (size--) { + *(volatile unsigned char *) (SL811_DAT) = *buf++; + EIEIO; + } +} + +int usb_init_kup4x (void) +{ + volatile immap_t *immap = (immap_t *) CFG_IMMR; + volatile memctl8xx_t *memctl = &immap->im_memctl; + int i; + unsigned char tmp; + + memctl = &immap->im_memctl; + memctl->memc_or7 = 0xFFFF8726; + memctl->memc_br7 = 0x50000401; /* start at 0x50000000 */ + /* BP 14 low = USB ON */ + immap->im_cpm.cp_pbdat &= ~(BP_USB_VCC); + /* PB 14 nomal port */ + immap->im_cpm.cp_pbpar &= ~(BP_USB_VCC); + /* output */ + immap->im_cpm.cp_pbdir |= (BP_USB_VCC); + + puts ("USB: "); + + for (i = 0x10; i < 0xff; i++) { + sl811_write(i, i); + tmp = (sl811_read(i)); + if (tmp != i) { + printf ("SL811 compare error index=0x%02x read=0x%02x\n", i, tmp); + return (-1); + } + } + printf ("SL811 ready\n"); + return (0); +} + +/* + * This function resets SL811HS controller and detects the speed of + * the connecting device + * + * Return: 0 = no device attached; 1 = USB device attached + */ +static int sl811_hc_reset(void) +{ + int status ; + + sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI); + sl811_write(SL811_CTRL1, SL811_CTRL1_RESET); + + mdelay(20); + + /* Disable hardware SOF generation, clear all irq status. */ + sl811_write(SL811_CTRL1, 0); + mdelay(2); + sl811_write(SL811_INTRSTS, 0xff); + status = sl811_read(SL811_INTRSTS); + + if (status & SL811_INTR_NOTPRESENT) { + /* Device is not present */ + PDEBUG(0, "Device not present\n"); + rh_status.wPortStatus &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE); + rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION; + sl811_write(SL811_INTR, SL811_INTR_INSRMV); + return 0; + } + + /* Send SOF to address 0, endpoint 0. */ + sl811_write(SL811_LEN_B, 0); + sl811_write(SL811_PIDEP_B, PIDEP(USB_PID_SOF, 0)); + sl811_write(SL811_DEV_B, 0x00); + sl811_write(SL811_SOFLOW, SL811_12M_LOW); + + if (status & SL811_INTR_SPEED_FULL) { + /* full speed device connect directly to root hub */ + PDEBUG (0, "Full speed Device attached\n"); + + sl811_write(SL811_CTRL1, SL811_CTRL1_RESET); + mdelay(20); + sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI); + sl811_write(SL811_CTRL1, SL811_CTRL1_SOF); + + /* start the SOF or EOP */ + sl811_write(SL811_CTRL_B, SL811_USB_CTRL_ARM); + rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION; + rh_status.wPortStatus &= ~USB_PORT_STAT_LOW_SPEED; + mdelay(2); + sl811_write(SL811_INTRSTS, 0xff); + } else { + /* slow speed device connect directly to root-hub */ + PDEBUG(0, "Low speed Device attached\n"); + + sl811_write(SL811_CTRL1, SL811_CTRL1_RESET); + mdelay(20); + sl811_write(SL811_CTRL2, SL811_CTL2_HOST | SL811_CTL2_DSWAP | SL811_12M_HI); + sl811_write(SL811_CTRL1, SL811_CTRL1_SPEED_LOW | SL811_CTRL1_SOF); + + /* start the SOF or EOP */ + sl811_write(SL811_CTRL_B, SL811_USB_CTRL_ARM); + rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION | USB_PORT_STAT_LOW_SPEED; + mdelay(2); + sl811_write(SL811_INTRSTS, 0xff); + } + + rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION; + sl811_write(SL811_INTR, /*SL811_INTR_INSRMV*/SL811_INTR_DONE_A); + + return 1; +} + +int usb_lowlevel_init(void) +{ + root_hub_devnum = 0; + sl811_hc_reset(); + return 0; +} + +int usb_lowlevel_stop(void) +{ + sl811_hc_reset(); + return 0; +} + +int sl811_send_packet(int dir_to_host, int data1, __u8 *buffer, int len) +{ + __u8 ctrl = SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE; + __u16 status; + int err = 0; + + if (len > 239) + return -1; + + if (!dir_to_host) + ctrl |= SL811_USB_CTRL_DIR_OUT; + if (data1) + ctrl |= SL811_USB_CTRL_TOGGLE_1; + + sl811_write(SL811_ADDR_A, 0x10); + sl811_write(SL811_LEN_A, len); + if (!dir_to_host && len) + sl811_write_buf(0x10, buffer, len); + + while (err < 3) { + if (sl811_read(SL811_SOFCNTDIV)*64 < len * 8 * 2) + ctrl |= SL811_USB_CTRL_SOF; + else + ctrl &= ~SL811_USB_CTRL_SOF; + sl811_write(SL811_CTRL_A, ctrl); + while (!(sl811_read(SL811_INTRSTS) & SL811_INTR_DONE_A)) + ; /* do nothing */ + + sl811_write(SL811_INTRSTS, 0xff); + status = sl811_read(SL811_STS_A); + + if (status & SL811_USB_STS_ACK) { + int remainder = sl811_read(SL811_CNT_A); + if (remainder) { + PDEBUG(0, "usb transfer remainder = %d\n", remainder); + len -= remainder; + } + if (dir_to_host && len) + sl811_read_buf(0x10, buffer, len); + return len; + } + + if ((status & SL811_USB_STS_NAK) == SL811_USB_STS_NAK) + continue; + + PDEBUG(0, "usb transfer error %#x\n", (int)status); + err++; + } + + return -1; +} + +int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int len) +{ + int dir_out = usb_pipeout(pipe); + int ep = usb_pipeendpoint(pipe); + __u8* buf = (__u8*)buffer; + int max = usb_maxpacket(dev, pipe); + int done = 0; + + PDEBUG(7, "dev = %ld pipe = %ld buf = %p size = %d dir_out = %d\n", + usb_pipedevice(pipe), usb_pipeendpoint(pipe), buffer, len, dir_out); + + dev->status = 0; + + sl811_write(SL811_DEV_A, usb_pipedevice(pipe)); + sl811_write(SL811_PIDEP_A, PIDEP(!dir_out ? USB_PID_IN : USB_PID_OUT, ep)); + while (done < len) { + int res = sl811_send_packet(!dir_out, usb_gettoggle(dev, ep, dir_out), + buf+done, + max > len - done ? len - done : max); + if (res < 0) { + dev->status = res; + return res; + } + + if (!dir_out && res < max) /* short packet */ + break; + + done += res; + usb_dotoggle(dev, ep, dir_out); + } + + dev->act_len = done; + + return 0; +} + +int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int len,struct devrequest *setup) +{ + int done = 0; + int devnum = usb_pipedevice(pipe); + + dev->status = 0; + + if (devnum == root_hub_devnum) + return sl811_rh_submit_urb(dev, pipe, buffer, len, setup); + + PDEBUG(7, "dev = %d pipe = %ld buf = %p size = %d rt = %#x req = %#x\n", + devnum, usb_pipeendpoint(pipe), buffer, len, (int)setup->requesttype, + (int)setup->request); + + sl811_write(SL811_DEV_A, devnum); + sl811_write(SL811_PIDEP_A, PIDEP(USB_PID_SETUP, 0)); + /* setup phase */ + if (sl811_send_packet(0, 0, (__u8*)setup, sizeof(*setup)) == sizeof(*setup)) { + int dir_in = setup->requesttype & USB_DIR_IN; + __u8* buf = (__u8*)buffer; + int data1 = 1; + int max = usb_maxpacket(dev, pipe); + + /* data phase */ + sl811_write(SL811_PIDEP_A, + PIDEP(dir_in ? USB_PID_IN : USB_PID_OUT, 0)); + while (done < len) { + int res = sl811_send_packet(dir_in, data1, buf+done, + max > len - done ? len - done : max); + if (res < 0) + return res; + done += res; + + if (dir_in && res < max) /* short packet */ + break; + + data1 = !data1; + } + + /* status phase */ + sl811_write(SL811_PIDEP_A, + PIDEP(!dir_in ? USB_PID_IN : USB_PID_OUT, 0)); + if (sl811_send_packet(!dir_in, 1, 0, 0) < 0) { + PDEBUG(0, "status phase failed!\n"); + dev->status = -1; + } + } else { + PDEBUG(0, "setup phase failed!\n"); + dev->status = -1; + } + + dev->act_len = done; + + return done; +} + +int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, + int len, int interval) +{ + PDEBUG(7, "dev = %p pipe = %#lx buf = %p size = %d int = %d\n", dev, pipe, + buffer, len, interval); + return -1; +} + +/* + * SL811 Virtual Root Hub + */ + +/* Device descriptor */ +static __u8 sl811_rh_dev_des[] = +{ + 0x12, /* __u8 bLength; */ + 0x01, /* __u8 bDescriptorType; Device */ + 0x10, /* __u16 bcdUSB; v1.1 */ + 0x01, + 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */ + 0x00, /* __u8 bDeviceSubClass; */ + 0x00, /* __u8 bDeviceProtocol; */ + 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */ + 0x00, /* __u16 idVendor; */ + 0x00, + 0x00, /* __u16 idProduct; */ + 0x00, + 0x00, /* __u16 bcdDevice; */ + 0x00, + 0x00, /* __u8 iManufacturer; */ + 0x02, /* __u8 iProduct; */ + 0x01, /* __u8 iSerialNumber; */ + 0x01 /* __u8 bNumConfigurations; */ +}; + +/* Configuration descriptor */ +static __u8 sl811_rh_config_des[] = +{ + 0x09, /* __u8 bLength; */ + 0x02, /* __u8 bDescriptorType; Configuration */ + 0x19, /* __u16 wTotalLength; */ + 0x00, + 0x01, /* __u8 bNumInterfaces; */ + 0x01, /* __u8 bConfigurationValue; */ + 0x00, /* __u8 iConfiguration; */ + 0x40, /* __u8 bmAttributes; + Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, + 4..0: resvd */ + 0x00, /* __u8 MaxPower; */ + + /* interface */ + 0x09, /* __u8 if_bLength; */ + 0x04, /* __u8 if_bDescriptorType; Interface */ + 0x00, /* __u8 if_bInterfaceNumber; */ + 0x00, /* __u8 if_bAlternateSetting; */ + 0x01, /* __u8 if_bNumEndpoints; */ + 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */ + 0x00, /* __u8 if_bInterfaceSubClass; */ + 0x00, /* __u8 if_bInterfaceProtocol; */ + 0x00, /* __u8 if_iInterface; */ + + /* endpoint */ + 0x07, /* __u8 ep_bLength; */ + 0x05, /* __u8 ep_bDescriptorType; Endpoint */ + 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */ + 0x03, /* __u8 ep_bmAttributes; Interrupt */ + 0x08, /* __u16 ep_wMaxPacketSize; */ + 0x00, + 0xff /* __u8 ep_bInterval; 255 ms */ +}; + +/* root hub class descriptor*/ +static __u8 sl811_rh_hub_des[] = +{ + 0x09, /* __u8 bLength; */ + 0x29, /* __u8 bDescriptorType; Hub-descriptor */ + 0x01, /* __u8 bNbrPorts; */ + 0x00, /* __u16 wHubCharacteristics; */ + 0x00, + 0x50, /* __u8 bPwrOn2pwrGood; 2ms */ + 0x00, /* __u8 bHubContrCurrent; 0 mA */ + 0xfc, /* __u8 DeviceRemovable; *** 7 Ports max *** */ + 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */ +}; + +/* + * helper routine for returning string descriptors in UTF-16LE + * input can actually be ISO-8859-1; ASCII is its 7-bit subset + */ +static int ascii2utf (char *s, u8 *utf, int utfmax) +{ + int retval; + + for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { + *utf++ = *s++; + *utf++ = 0; + } + return retval; +} + +/* + * root_hub_string is used by each host controller's root hub code, + * so that they're identified consistently throughout the system. + */ +int usb_root_hub_string (int id, int serial, char *type, __u8 *data, int len) +{ + char buf [30]; + + /* assert (len > (2 * (sizeof (buf) + 1))); + assert (strlen (type) <= 8);*/ + + /* language ids */ + if (id == 0) { + *data++ = 4; *data++ = 3; /* 4 bytes data */ + *data++ = 0; *data++ = 0; /* some language id */ + return 4; + + /* serial number */ + } else if (id == 1) { + sprintf (buf, "%x", serial); + + /* product description */ + } else if (id == 2) { + sprintf (buf, "USB %s Root Hub", type); + + /* id 3 == vendor description */ + + /* unsupported IDs --> "stall" */ + } else + return 0; + + data [0] = 2 + ascii2utf (buf, data + 2, len - 2); + data [1] = 3; + return data [0]; +} + +/* helper macro */ +#define OK(x) len = (x); break + +/* + * This function handles all USB request to the the virtual root hub + */ +static int sl811_rh_submit_urb(struct usb_device *usb_dev, unsigned long pipe, + void *data, int buf_len, struct devrequest *cmd) +{ + __u8 data_buf[16]; + __u8 *bufp = data_buf; + int len = 0; + int status = 0; + + __u16 bmRType_bReq; + __u16 wValue; + __u16 wIndex; + __u16 wLength; + + if (usb_pipeint(pipe)) { + PDEBUG(0, "interrupt transfer unimplemented!\n"); + return 0; + } + + bmRType_bReq = cmd->requesttype | (cmd->request << 8); + wValue = le16_to_cpu (cmd->value); + wIndex = le16_to_cpu (cmd->index); + wLength = le16_to_cpu (cmd->length); + + PDEBUG(5, "submit rh urb, req = %d(%x) val = %#x index = %#x len=%d\n", + bmRType_bReq, bmRType_bReq, wValue, wIndex, wLength); + + /* Request Destination: + without flags: Device, + USB_RECIP_INTERFACE: interface, + USB_RECIP_ENDPOINT: endpoint, + USB_TYPE_CLASS means HUB here, + USB_RECIP_OTHER | USB_TYPE_CLASS almost ever means HUB_PORT here + */ + switch (bmRType_bReq) { + case RH_GET_STATUS: + *(__u16 *)bufp = cpu_to_le16(1); + OK(2); + + case RH_GET_STATUS | USB_RECIP_INTERFACE: + *(__u16 *)bufp = cpu_to_le16(0); + OK(2); + + case RH_GET_STATUS | USB_RECIP_ENDPOINT: + *(__u16 *)bufp = cpu_to_le16(0); + OK(2); + + case RH_GET_STATUS | USB_TYPE_CLASS: + *(__u32 *)bufp = cpu_to_le32(0); + OK(4); + + case RH_GET_STATUS | USB_RECIP_OTHER | USB_TYPE_CLASS: + *(__u32 *)bufp = cpu_to_le32(rh_status.wPortChange<<16 | rh_status.wPortStatus); + OK(4); + + case RH_CLEAR_FEATURE | USB_RECIP_ENDPOINT: + switch (wValue) { + case 1: + OK(0); + } + break; + + case RH_CLEAR_FEATURE | USB_TYPE_CLASS: + switch (wValue) { + case C_HUB_LOCAL_POWER: + OK(0); + + case C_HUB_OVER_CURRENT: + OK(0); + } + break; + + case RH_CLEAR_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS: + switch (wValue) { + case USB_PORT_FEAT_ENABLE: + rh_status.wPortStatus &= ~USB_PORT_STAT_ENABLE; + OK(0); + + case USB_PORT_FEAT_SUSPEND: + rh_status.wPortStatus &= ~USB_PORT_STAT_SUSPEND; + OK(0); + + case USB_PORT_FEAT_POWER: + rh_status.wPortStatus &= ~USB_PORT_STAT_POWER; + OK(0); + + case USB_PORT_FEAT_C_CONNECTION: + rh_status.wPortChange &= ~USB_PORT_STAT_C_CONNECTION; + OK(0); + + case USB_PORT_FEAT_C_ENABLE: + rh_status.wPortChange &= ~USB_PORT_STAT_C_ENABLE; + OK(0); + + case USB_PORT_FEAT_C_SUSPEND: + rh_status.wPortChange &= ~USB_PORT_STAT_C_SUSPEND; + OK(0); + + case USB_PORT_FEAT_C_OVER_CURRENT: + rh_status.wPortChange &= ~USB_PORT_STAT_C_OVERCURRENT; + OK(0); + + case USB_PORT_FEAT_C_RESET: + rh_status.wPortChange &= ~USB_PORT_STAT_C_RESET; + OK(0); + } + break; + + case RH_SET_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS: + switch (wValue) { + case USB_PORT_FEAT_SUSPEND: + rh_status.wPortStatus |= USB_PORT_STAT_SUSPEND; + OK(0); + + case USB_PORT_FEAT_RESET: + rh_status.wPortStatus |= USB_PORT_STAT_RESET; + rh_status.wPortChange = 0; + rh_status.wPortChange |= USB_PORT_STAT_C_RESET; + rh_status.wPortStatus &= ~USB_PORT_STAT_RESET; + rh_status.wPortStatus |= USB_PORT_STAT_ENABLE; + OK(0); + + case USB_PORT_FEAT_POWER: + rh_status.wPortStatus |= USB_PORT_STAT_POWER; + OK(0); + + case USB_PORT_FEAT_ENABLE: + rh_status.wPortStatus |= USB_PORT_STAT_ENABLE; + OK(0); + } + break; + + case RH_SET_ADDRESS: + root_hub_devnum = wValue; + OK(0); + + case RH_GET_DESCRIPTOR: + switch ((wValue & 0xff00) >> 8) { + case USB_DT_DEVICE: + len = sizeof(sl811_rh_dev_des); + bufp = sl811_rh_dev_des; + OK(len); + + case USB_DT_CONFIG: + len = sizeof(sl811_rh_config_des); + bufp = sl811_rh_config_des; + OK(len); + + case USB_DT_STRING: + len = usb_root_hub_string(wValue & 0xff, (int)(long)0, "SL811HS", data, wLength); + if (len > 0) { + bufp = data; + OK(len); + } + + default: + status = -32; + } + break; + + case RH_GET_DESCRIPTOR | USB_TYPE_CLASS: + len = sizeof(sl811_rh_hub_des); + bufp = sl811_rh_hub_des; + OK(len); + + case RH_GET_CONFIGURATION: + bufp[0] = 0x01; + OK(1); + + case RH_SET_CONFIGURATION: + OK(0); + + default: + PDEBUG(1, "unsupported root hub command\n"); + status = -32; + } + + len = min(len, buf_len); + if (data != bufp) + memcpy(data, bufp, len); + + PDEBUG(5, "len = %d, status = %d\n", len, status); + + usb_dev->status = status; + usb_dev->act_len = len; + + return status == 0 ? len : status; +} + +#endif /* CONFIG_USB_SL811HS */ diff --git a/include/configs/KUP4X.h b/include/configs/KUP4X.h index 4451f2a0e1..a5dcb4e7c7 100644 --- a/include/configs/KUP4X.h +++ b/include/configs/KUP4X.h @@ -118,7 +118,9 @@ #define CONFIG_COMMANDS ( CONFIG_CMD_DFL | \ CFG_CMD_DHCP | \ CFG_CMD_I2C | \ - CFG_CMD_IDE ) + CFG_CMD_IDE | \ + CFG_CMD_USB | \ + CFG_CMD_FAT) /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */ #include @@ -386,4 +388,7 @@ #define CONFIG_AUTOBOOT_STOP_STR "." /* easy to stop for now */ #define CONFIG_SILENT_CONSOLE 1 +#define CONFIG_USB_STORAGE 1 +#define CONFIG_USB_SL811HS 1 + #endif /* __CONFIG_H */ diff --git a/include/configs/NETPHONE.h b/include/configs/NETPHONE.h index d82d5a7811..9dadaa836a 100644 --- a/include/configs/NETPHONE.h +++ b/include/configs/NETPHONE.h @@ -67,8 +67,8 @@ #undef CONFIG_BOOTARGS #define CONFIG_BOOTCOMMAND \ "tftpboot; " \ - "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \ - "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \ + "setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; " \ "bootm" #define CONFIG_AUTOSCRIPT diff --git a/include/configs/NETTA.h b/include/configs/NETTA.h index d9a78bdead..b720ec5be8 100644 --- a/include/configs/NETTA.h +++ b/include/configs/NETTA.h @@ -65,8 +65,8 @@ #undef CONFIG_BOOTARGS #define CONFIG_BOOTCOMMAND \ "tftpboot; " \ - "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \ - "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \ + "setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; " \ "bootm" #define CONFIG_LOADS_ECHO 0 /* echo off for serial download */ diff --git a/include/configs/NETVIA.h b/include/configs/NETVIA.h index 8f93a49c08..dc6b15fcdc 100644 --- a/include/configs/NETVIA.h +++ b/include/configs/NETVIA.h @@ -64,8 +64,8 @@ #undef CONFIG_BOOTARGS #define CONFIG_BOOTCOMMAND \ "tftpboot; " \ - "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) " \ - "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; " \ + "setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath} " \ + "ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}::off; " \ "bootm" #define CONFIG_LOADS_ECHO 0 /* echo off for serial download */ diff --git a/include/fat.h b/include/fat.h index 3e7c91c9b6..0645458f17 100644 --- a/include/fat.h +++ b/include/fat.h @@ -27,6 +27,8 @@ #ifndef _FAT_H_ #define _FAT_H_ +#include + #define CONFIG_SUPPORT_VFAT #define SECTOR_SIZE FS_BLOCK_SIZE @@ -210,11 +212,4 @@ long file_fat_read(const char *filename, void *buffer, unsigned long maxsize); const char *file_getfsname(int idx); int fat_register_device(block_dev_desc_t *dev_desc, int part_no); -#ifdef CONFIG_PXA250 -#undef FAT2CPU16 -#define FAT2CPU16(x) x -#undef FAT2CPU32 -#define FAT2CPU32(x) x -#endif - #endif /* _FAT_H_ */ diff --git a/include/usb.h b/include/usb.h index 074e0f169c..6940d32510 100644 --- a/include/usb.h +++ b/include/usb.h @@ -12,7 +12,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -29,15 +29,15 @@ #include /* Everything is aribtrary */ -#define USB_ALTSETTINGALLOC 4 -#define USB_MAXALTSETTING 128 /* Hard limit */ +#define USB_ALTSETTINGALLOC 4 +#define USB_MAXALTSETTING 128 /* Hard limit */ -#define USB_MAX_DEVICE 32 -#define USB_MAXCONFIG 8 -#define USB_MAXINTERFACES 8 -#define USB_MAXENDPOINTS 16 -#define USB_MAXCHILDREN 8 /* This is arbitrary */ -#define USB_MAX_HUB 16 +#define USB_MAX_DEVICE 32 +#define USB_MAXCONFIG 8 +#define USB_MAXINTERFACES 8 +#define USB_MAXENDPOINTS 16 +#define USB_MAXCHILDREN 8 /* This is arbitrary */ +#define USB_MAX_HUB 16 #define USB_CNTL_TIMEOUT 100 /* 100ms timeout */ @@ -125,19 +125,19 @@ struct usb_config_descriptor { unsigned char bmAttributes; unsigned char MaxPower; - unsigned char no_of_if; /* number of interfaces */ + unsigned char no_of_if; /* number of interfaces */ struct usb_interface_descriptor if_desc[USB_MAXINTERFACES]; } __attribute__ ((packed)); struct usb_device { - int devnum; /* Device number on USB bus */ - int slow; /* Slow device? */ - char mf[32]; /* manufacturer */ - char prod[32]; /* product */ - char serial[32]; /* serial number */ + int devnum; /* Device number on USB bus */ + int slow; /* Slow device? */ + char mf[32]; /* manufacturer */ + char prod[32]; /* product */ + char serial[32]; /* serial number */ - int maxpacketsize; /* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */ + int maxpacketsize; /* Maximum packet size; encoded as 0,1,2,3 = 8,16,32,64 */ unsigned int toggle[2]; /* one bit for each endpoint ([0] = IN, [1] = OUT) */ unsigned int halted[2]; /* endpoint halts; one bit per endpoint # & direction; */ /* [0] = IN, [1] = OUT */ @@ -152,7 +152,7 @@ struct usb_device { int string_langid; /* language ID for strings */ int (*irq_handle)(struct usb_device *dev); unsigned long irq_status; - int irq_act_len; /* transfered bytes */ + int irq_act_len; /* transfered bytes */ void *privptr; /* * Child devices - if this is a hub device @@ -169,7 +169,7 @@ struct usb_device { * this is how the lowlevel part communicate with the outer world */ -#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined (CONFIG_USB_SL811HS) int usb_lowlevel_init(void); int usb_lowlevel_stop(void); int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,int transfer_len); @@ -180,7 +180,7 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, /* Defines */ #define USB_UHCI_VEND_ID 0x8086 -#define USB_UHCI_DEV_ID 0x7112 +#define USB_UHCI_DEV_ID 0x7112 #else #error USB Lowlevel not defined @@ -242,8 +242,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate); ({ unsigned long x_ = (unsigned long)x; \ (unsigned long)( \ ((x_ & 0x000000FFUL) << 24) | \ - ((x_ & 0x0000FF00UL) << 8) | \ - ((x_ & 0x00FF0000UL) >> 8) | \ + ((x_ & 0x0000FF00UL) << 8) | \ + ((x_ & 0x00FF0000UL) >> 8) | \ ((x_ & 0xFF000000UL) >> 24) ); \ }) #endif /* LITTLEENDIAN */ @@ -298,7 +298,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate); /* The D0/D1 toggle bits */ #define usb_gettoggle(dev, ep, out) (((dev)->toggle[out] >> ep) & 1) -#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << ep)) +#define usb_dotoggle(dev, ep, out) ((dev)->toggle[out] ^= (1 << ep)) #define usb_settoggle(dev, ep, out, bit) ((dev)->toggle[out] = ((dev)->toggle[out] & ~(1 << ep)) | ((bit) << ep)) /* Endpoint halt control/status */ -- 2.30.2