1
0
Fork 0
forked from len0rd/rockbox

H300: Rudimentary driver for the ISP1362 USB on-the-go controller. For now it just sends the chip to sleep, solving the poor battery runtime issue.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10128 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2006-06-16 17:34:18 +00:00
parent cd69996450
commit 977169ea7a
8 changed files with 355 additions and 7 deletions

View file

@ -88,6 +88,10 @@
#include "lcd-remote.h" #include "lcd-remote.h"
#endif #endif
#if CONFIG_USBOTG == USBOTG_ISP1362
#include "isp1362.h"
#endif
/*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */ /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */
const char appsversion[]=APPSVERSION; const char appsversion[]=APPSVERSION;
@ -276,6 +280,9 @@ void init(void)
adc_init(); adc_init();
usb_init(); usb_init();
#if CONFIG_USBOTG == USBOTG_ISP1362
isp1362_init();
#endif
backlight_init(); backlight_init();

View file

@ -203,6 +203,10 @@ sound.c
common/sscanf.c common/sscanf.c
usb_serial.c usb_serial.c
#endif #endif
#if CONFIG_USBOTG == USBOTG_ISP1362
drivers/isp1362.c
#endif
#ifndef SIMULATOR #ifndef SIMULATOR
#ifdef IAUDIO_X5 #ifdef IAUDIO_X5

View file

@ -531,7 +531,7 @@ irq_handler:
/* Chip select 1 - LCD controller */ /* Chip select 1 - LCD controller */
move.l #0xf0000000,%d0 /* CSAR1 - Base = 0xf0000000 */ move.l #0xf0000000,%d0 /* CSAR1 - Base = 0xf0000000 */
move.l %d0,(0x08c,%a0) move.l %d0,(0x08c,%a0)
moveq.l #0x1,%d0 /* CSMR1 - 64K */ moveq.l #0x1,%d0 /* CSMR1 - 64K */
move.l %d0,(0x090,%a0) move.l %d0,(0x090,%a0)
move.l #0x00000180,%d0 /* CSCR1 - no wait states, 16 bits, no bursts */ move.l #0x00000180,%d0 /* CSCR1 - no wait states, 16 bits, no bursts */
move.l %d0,(0x094,%a0) move.l %d0,(0x094,%a0)
@ -545,7 +545,16 @@ irq_handler:
move.l %d0,(0x0a0,%a0) /* NOTE: I'm not sure about the wait states. move.l %d0,(0x0a0,%a0) /* NOTE: I'm not sure about the wait states.
We have to be careful with the access times, We have to be careful with the access times,
since IORDY isn't connected to the HDD. */ since IORDY isn't connected to the HDD. */
#if CONFIG_USBOTG == USBOTG_ISP1362
/* Chip select 3 - USBOTG controller */
move.l #0xc0000000,%d0 /* CSAR3 - Base = 0xc0000000 */
move.l %d0,(0x0a4,%a0)
moveq.l #0x1,%d0 /* CSMR3 - 64K */
move.l %d0,(0x0a8,%a0)
move.l #0x00000180,%d0 /* CSCR3 - no wait states, 16 bits, no bursts */
move.l %d0,(0x0ac,%a0)
#endif
#ifdef BOOTLOADER #ifdef BOOTLOADER
/* The cookie is not reset. This must mean that the boot loader /* The cookie is not reset. This must mean that the boot loader

177
firmware/drivers/isp1362.c Executable file
View file

@ -0,0 +1,177 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 Jens Arnold
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "system.h"
#include "kernel.h"
#include "isp1362.h"
#define HC_DATA (*((volatile unsigned short*)0xc0000000))
#define HC_CMD (*((volatile unsigned short*)0xc0000002))
#define DC_DATA (*((volatile unsigned short*)0xc0000004))
#define DC_CMD (*((volatile unsigned short*)0xc0000006))
/* host controller access */
unsigned isp1362_read_hc_reg16(unsigned reg)
{
HC_CMD = reg;
asm ("nop\n nop\n nop\n nop\n");
asm ("nop\n nop\n nop\n nop\n");
asm ("nop\n nop\n nop\n nop\n");
return HC_DATA;
}
unsigned isp1362_read_hc_reg32(unsigned reg)
{
unsigned data;
HC_CMD = reg;
asm ("nop\n nop\n nop\n nop\n");
asm ("nop\n nop\n nop\n nop\n");
asm ("nop\n nop\n nop\n nop\n");
data = HC_DATA;
data |= HC_DATA << 16;
return data;
}
void isp1362_write_hc_reg16(unsigned reg, unsigned data)
{
HC_CMD = reg | 0x80;
asm ("nop\n nop\n nop\n");
HC_DATA = data;
}
void isp1362_write_hc_reg32(unsigned reg, unsigned data)
{
HC_CMD = reg | 0x80;
asm ("nop\n nop\n nop\n");
HC_DATA = data;
HC_DATA = data >> 16;
}
/* device controller access */
unsigned isp1362_read_dc_reg16(unsigned reg)
{
DC_CMD = reg;
asm ("nop\n nop\n nop\n nop\n");
asm ("nop\n nop\n nop\n nop\n");
asm ("nop\n nop\n nop\n nop\n");
return DC_DATA;
}
unsigned isp1362_read_dc_reg32(unsigned reg)
{
unsigned data;
DC_CMD = reg;
asm ("nop\n nop\n nop\n nop\n");
asm ("nop\n nop\n nop\n nop\n");
asm ("nop\n nop\n nop\n nop\n");
data = DC_DATA;
data |= DC_DATA << 16;
return data;
}
void isp1362_write_dc_reg16(unsigned reg, unsigned data)
{
DC_CMD = reg;
asm ("nop\n nop\n nop\n");
DC_DATA = data;
}
void isp1362_write_dc_reg32(unsigned reg, unsigned data)
{
DC_CMD = reg;
asm ("nop\n nop\n nop\n");
DC_DATA = data;
DC_DATA = data >> 16;
}
static void isp1362_suspend(void)
{
unsigned data;
data = isp1362_read_hc_reg16(ISP1362_OTG_CONTROL);
data &= ~0x0001; /* DRV_VBUS = 0 */
isp1362_write_hc_reg16(ISP1362_OTG_CONTROL, data);
/* prepare the DC */
data = isp1362_read_dc_reg16(ISP1362_DC_HARDWARE_CONFIG_R);
data &= ~0x1008; /* CLKRUN = WKUPCS = 0. Wakeup is still possible via /D_WAKEUP */
isp1362_write_dc_reg16(ISP1362_DC_HARDWARE_CONFIG_W, data);
/* send the DC to sleep */
data = isp1362_read_dc_reg16(ISP1362_DC_MODE_R);
data |= 0x20; /* GOSUSP = 1 */
isp1362_write_dc_reg16(ISP1362_DC_MODE_W, data);
data &= ~0x20; /* GOSUSP = 0 */
isp1362_write_dc_reg16(ISP1362_DC_MODE_W, data);
/* prepare the HC */
data = isp1362_read_hc_reg16(ISP1362_HC_HARDWARE_CONFIG);
data &= ~0x0800; /* SuspendClkNotStop = 0 */
data |= 0x4001; /* GlobalPowerDown = InterruptPinEnable = 1 */
isp1362_write_hc_reg16(ISP1362_HC_HARDWARE_CONFIG, data);
/* TODO: OTG wake-up cfg */
/* TODO: Interrupt setup */
/* set the HC to operational */
isp1362_write_hc_reg32(ISP1362_HC_CONTROL, 0x0680);
/* RWE = RWC = 1, HCFS = 0b10 (USBOperational) */
/* ..then send it to sleep */
isp1362_write_hc_reg32(ISP1362_HC_CONTROL, 0x06c0);
/* RWE = RWC = 1, HCFS = 0b11 (USBSuspend) */
}
/* init */
void isp1362_init(void)
{
and_l(~0x00200080, &GPIO1_OUT); /* disable 5V USB host power and ??? */
or_l( 0x00200080, &GPIO1_ENABLE);
or_l( 0x00200080, &GPIO1_FUNCTION);
or_l( 0x20600000, &GPIO_OUT); /* ID = D_SUSPEND = /OTGMODE = 1 */
and_l(~0x04000000, &GPIO_OUT); /* ?R26? = 0 */
or_l( 0x24600000, &GPIO_ENABLE); /* ID, ?R26?, D_SUSPEND, /OTGMODE outputs */
and_l(~0x000000a8, &GPIO_ENABLE); /* /INT2, /INT1, /RESET inputs */
or_l( 0x246000a8, &GPIO_FUNCTION); /* GPIO for these pins */
sleep(HZ/5);
isp1362_suspend();
}

View file

@ -110,6 +110,9 @@
#define USB_IRIVERSTYLE #define USB_IRIVERSTYLE
/* USB On-the-go */
#define CONFIG_USBOTG USBOTG_ISP1362
/* Define this if you have adjustable CPU frequency */ /* Define this if you have adjustable CPU frequency */
#define HAVE_ADJUSTABLE_CPU_FREQ #define HAVE_ADJUSTABLE_CPU_FREQ

View file

@ -122,6 +122,7 @@
/* CONFIG_LED */ /* CONFIG_LED */
#define LED_REAL 1 /* SW controlled LED (Archos recorders, player, Gmini) */ #define LED_REAL 1 /* SW controlled LED (Archos recorders, player, Gmini) */
#define LED_VIRTUAL 2 /* Virtual LED (icon) (Archos Ondio) */ #define LED_VIRTUAL 2 /* Virtual LED (icon) (Archos Ondio) */
/* else HW controlled LED (iRiver H1x0) */
/* CONFIG_FLASH */ /* CONFIG_FLASH */
#define FLASH_IFP7XX 1 #define FLASH_IFP7XX 1
@ -132,7 +133,8 @@
#define RTC_PCF50606 3 /* iriver H300 */ #define RTC_PCF50606 3 /* iriver H300 */
#define RTC_S3C2440 4 #define RTC_S3C2440 4
/* else HW controlled LED (iRiver H1x0) */ /* USB On-the-go */
#define USBOTG_ISP1362 1362
/* now go and pick yours */ /* now go and pick yours */
#if defined(ARCHOS_PLAYER) #if defined(ARCHOS_PLAYER)

134
firmware/export/isp1362.h Executable file
View file

@ -0,0 +1,134 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006 Jens Arnold
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
unsigned isp1362_read_hc_reg16(unsigned reg);
unsigned isp1362_read_hc_reg32(unsigned reg);
void isp1362_write_hc_reg16(unsigned reg, unsigned data);
void isp1362_write_hc_reg32(unsigned reg, unsigned data);
#define ISP1362_OTG_CONTROL 0x62
#define ISP1362_OTG_STATUS 0x67 /* read only */
#define ISP1362_OTG_INTERRUPT 0x68
#define ISP1362_OTG_INT_ENABLE 0x69
#define ISP1362_OTG_TIMER 0x6a
#define ISP1362_OTG_ALT_TIMER 0x6c
#define ISP1362_HC_REVISION 0x00 /* read only */
#define ISP1362_HC_CONTROL 0x01
#define ISP1362_HC_COMMAND_STATUS 0x02
#define ISP1362_HC_INT_STATUS 0x03
#define ISP1362_HC_INT_ENABLE 0x04
#define ISP1362_HC_INT_DISABLE 0x05
#define ISP1362_HC_FM_INTERVAL 0x0d
#define ISP1362_HC_FM_REMAINING 0x0e
#define ISP1362_HC_FM_NUMBER 0x0f
#define ISP1362_HC_LS_THRESHOLD 0x11
#define ISP1362_HC_RH_DESCRIPTOR_A 0x12
#define ISP1362_HC_RH_DESCRIPTOR_B 0x13
#define ISP1362_HC_RH_STATUS 0x14
#define ISP1362_HC_RH_PORT_STATUS1 0x15
#define ISP1362_HC_RH_PORT_STATUS2 0x16
#define ISP1362_HC_HARDWARE_CONFIG 0x20
#define ISP1362_HC_DMA_CONFIG 0x21
#define ISP1362_HC_TRANSFER_COUNTER 0x22
#define ISP1362_HC_UP_INTERRUPT 0x24
#define ISP1362_HC_UP_INT_ENABLE 0x25
#define ISP1362_HC_CHIP_ID 0x27 /* read only */
#define ISP1362_HC_SCRATCH 0x28
#define ISP1362_HC_SOFTWARE_RESET 0x29 /* write only */
#define ISP1362_HC_BUFFER_STATUS 0x2c
#define ISP1362_HC_DIRECT_ADDR_LEN 0x32
#define ISP1362_HC_DIRECT_ADDR_DATA 0x45
#define ISP1362_HC_ISTL_BUF_SIZE 0x30
#define ISP1362_HC_ISTL0_BUF_PORT 0x40
#define ISP1362_HC_ISTL1_BUF_PORT 0x42
#define ISP1362_HC_ISTL_TOGGLE_RATE 0x47
#define ISP1362_HC_INTL_BUF_SIZE 0x33
#define ISP1362_HC_INTL_BUF_PORT 0x43
#define ISP1362_HC_INTL_BLK_SIZE 0x53
#define ISP1362_HC_INTL_PRD_DONE_MAP 0x17 /* read only */
#define ISP1362_HC_INTL_PTD_SKIP_MAP 0x18
#define ISP1362_HC_INTL_LAST_PTD 0x19
#define ISP1362_HC_INTL_CUR_ACT_PTD 0x1a /* read only */
#define ISP1362_HC_ATL_BUF_SIZE 0x34
#define ISP1362_HC_ATL_BUF_PORT 0x44
#define ISP1362_HC_ATL_BLK_SIZE 0x54
#define ISP1362_HC_ATL_PTD_DONE_MAP 0x1b /* read only */
#define ISP1362_HC_ATL_PTD_SKIP_MAP 0x1c
#define ISP1362_HC_ATL_LAST_PTD 0x1d
#define ISP1362_HC_ATL_CUR_ACT_PTD 0x1e /* read only */
#define ISP1362_HC_ATL_PTD_DONE_THR_CNT 0x51
#define ISP1362_HC_ATL_PTD_DONE_THR_TMO 0x52
unsigned isp1362_read_dc_reg16(unsigned reg);
unsigned isp1362_read_dc_reg32(unsigned reg);
void isp1362_write_dc_reg16(unsigned reg, unsigned data);
void isp1362_write_dc_reg32(unsigned reg, unsigned data);
#define ISP1362_DC_CTRL_OUT_CFG_W 0x20
#define ISP1362_DC_CTRL_IN_CFG_W 0x21
#define ISP1362_DC_ENDPOINT_CFG_BASE_W 0x22
#define ISP1362_DC_CTRL_OUT_CFG_R 0x30
#define ISP1362_DC_CTRL_IN_CFG_R 0x31
#define ISP1362_DC_ENDPOINT_CFG_BASE_R 0x32
#define ISP1362_DC_ADDRESS_W 0xb6
#define ISP1362_DC_ADDRESS_R 0xb7
#define ISP1362_DC_MODE_W 0xb8
#define ISP1362_DC_MODE_R 0xb9
#define ISP1362_DC_HARDWARE_CONFIG_W 0xba
#define ISP1362_DC_HARDWARE_CONFIG_R 0xbb
#define ISP1362_DC_INT_ENABLE_W 0xc2
#define ISP1362_DC_INT_ENABLE_R 0xc3
#define ISP1362_DC_DMA_CONFIG_W 0xf0
#define ISP1362_DC_DMA_CONFIG_R 0xf1
#define ISP1362_DC_DMA_COUNTER_W 0xf2
#define ISP1362_DC_DMA_COUNTER_R 0xf3
#define ISP1362_DC_RESET 0xf6
#define ISP1362_DC_CTRL_IN_BUF_W 0x01
#define ISP1362_DC_ENDPOINT_BUF_BASE_W 0x02
#define ISP1362_DC_CTRL_OUT_BUF_R 0x10
#define ISP1362_DC_ENDPOINT_BUF_BASE_R 0x12
#define ISP1362_DC_CTRL_OUT_STALL 0x40
#define ISP1362_DC_CTRL_IN_STALL 0x41
#define ISP1362_DC_ENDPOINT_STALL_BASE 0x42
#define ISP1362_DC_CTRL_OUT_STATUS_R 0x50
#define ISP1362_DC_CTRL_IN_STATUS_R 0x51
#define ISP1362_DC_ENDPOINT_STATUS_BASE_R 0x52
#define ISP1362_DC_CTRL_IN_VALIDATE 0x61
#define ISP1362_DC_ENDPOINT_VALIDATE_BASE 0x62
#define ISP1362_DC_CTRL_OUT_CLEAR 0x70
#define ISP1362_DC_ENDPOINT_CLEAR_BASE 0x72
#define ISP1362_DC_CTRL_OUT_UNSTALL 0x80
#define ISP1362_DC_CTRL_IN_UNSTALL 0x81
#define ISP1362_DC_ENDPOINT_UNSTALL_BASE 0x82
#define ISP1362_DC_CTRL_OUT_STAT_IMG_R 0xd0
#define ISP1362_DC_CTRL_IN_STAT_IMG_R 0xd1
#define ISP1362_DC_ENDPOINT_STAT_IMG_BASE_R 0xd2
#define ISP1362_DC_SETUP_ACK 0xf4
#define ISP1362_DC_CTRL_OUT_ERROR_R 0xa0
#define ISP1362_DC_CTRL_IN_ERROR_R 0xa1
#define ISP1362_DC_ENDPOINT_ERROR_BASE_R 0xa2
#define ISP1362_DC_UNLOCK_DEVICE 0xb0
#define ISP1362_DC_SCRATCH_W 0xb2
#define ISP1362_DC_SCRATCH_R 0xb3
#define ISP1362_DC_FRAME_NUMBER_R 0xb4
#define ISP1362_DC_CHIP_ID_R 0xb5
#define ISP1362_DC_INTERRUPT_R 0xc0
void isp1362_init(void);

View file

@ -616,13 +616,17 @@ void set_cpu_frequency(long frequency)
PLLCR = 0x11c56005; PLLCR = 0x11c56005;
CSCR0 = 0x00001180; /* Flash: 4 wait states */ CSCR0 = 0x00001180; /* Flash: 4 wait states */
CSCR1 = 0x00000980; /* LCD: 2 wait states */ CSCR1 = 0x00000980; /* LCD: 2 wait states */
#if CONFIG_USBOTG == USBOTG_ISP1362
CSCR3 = 0x00002180; /* USBOTG: 8 wait states */
#endif
while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked. while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
This may take up to 10ms! */ This may take up to 10ms! */
timers_adjust_prescale(CPUFREQ_MAX_MULT, true); timers_adjust_prescale(CPUFREQ_MAX_MULT, true);
DCR = (0x8200 | MAX_REFRESH_TIMER); /* Refresh timer */ DCR = (0x8200 | MAX_REFRESH_TIMER); /* Refresh timer */
cpu_frequency = CPUFREQ_MAX; cpu_frequency = CPUFREQ_MAX;
IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */ IDECONFIG1 = 0x10100000 | (3 << 13) | (5 << 10);
IDECONFIG2 = 0x40000 | (1 << 8); /* TA enable + CS2wait */ /* SRE active on write (H300 USBOTG) | BUFEN2 enable | CS2Post | CS2Pre */
IDECONFIG2 = 0x40000 | (2 << 8); /* TA enable + CS2wait */
break; break;
case CPUFREQ_NORMAL: case CPUFREQ_NORMAL:
@ -634,12 +638,16 @@ void set_cpu_frequency(long frequency)
PLLCR = 0x13c5e005; PLLCR = 0x13c5e005;
CSCR0 = 0x00000580; /* Flash: 1 wait state */ CSCR0 = 0x00000580; /* Flash: 1 wait state */
CSCR1 = 0x00000180; /* LCD: 0 wait states */ CSCR1 = 0x00000180; /* LCD: 0 wait states */
#if CONFIG_USBOTG == USBOTG_ISP1362
CSCR3 = 0x00000580; /* USBOTG: 1 wait state */
#endif
while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked. while(!(PLLCR & 0x80000000)) {}; /* Wait until the PLL has locked.
This may take up to 10ms! */ This may take up to 10ms! */
timers_adjust_prescale(CPUFREQ_NORMAL_MULT, true); timers_adjust_prescale(CPUFREQ_NORMAL_MULT, true);
DCR = (0x8000 | NORMAL_REFRESH_TIMER); /* Refresh timer */ DCR = (0x8000 | NORMAL_REFRESH_TIMER); /* Refresh timer */
cpu_frequency = CPUFREQ_NORMAL; cpu_frequency = CPUFREQ_NORMAL;
IDECONFIG1 = 0x106000 | (5 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */ IDECONFIG1 = 0x10100000 | (3 << 13) | (5 << 10);
/* SRE active on write (H300 USBOTG) | BUFEN2 enable | CS2Post | CS2Pre */
IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */ IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */
break; break;
default: default:
@ -651,9 +659,13 @@ void set_cpu_frequency(long frequency)
PLLCR = 0x10c00200; /* Power down PLL, but keep CLSEL and CRSEL */ PLLCR = 0x10c00200; /* Power down PLL, but keep CLSEL and CRSEL */
CSCR0 = 0x00000180; /* Flash: 0 wait states */ CSCR0 = 0x00000180; /* Flash: 0 wait states */
CSCR1 = 0x00000180; /* LCD: 0 wait states */ CSCR1 = 0x00000180; /* LCD: 0 wait states */
#if CONFIG_USBOTG == USBOTG_ISP1362
CSCR3 = 0x00000180; /* USBOTG: 0 wait states */
#endif
DCR = (0x8000 | DEFAULT_REFRESH_TIMER); /* Refresh timer */ DCR = (0x8000 | DEFAULT_REFRESH_TIMER); /* Refresh timer */
cpu_frequency = CPUFREQ_DEFAULT; cpu_frequency = CPUFREQ_DEFAULT;
IDECONFIG1 = 0x106000 | (1 << 10); /* BUFEN2 enable + CS2Pre/CS2Post */ IDECONFIG1 = 0x10100000 | (3 << 13) | (1 << 10);
/* SRE active on write (H300 USBOTG) | BUFEN2 enable | CS2Post | CS2Pre */
IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */ IDECONFIG2 = 0x40000 | (0 << 8); /* TA enable + CS2wait */
break; break;
} }