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:
parent
cd69996450
commit
977169ea7a
8 changed files with 355 additions and 7 deletions
177
firmware/drivers/isp1362.c
Executable file
177
firmware/drivers/isp1362.c
Executable 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();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue