2acc0ac542
later. We still need to hunt down snippets used that are not. 1324 modified files... http://www.rockbox.org/mail/archive/rockbox-dev-archive-2008-06/0060.shtml git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17847 a1c6a512-1295-4272-9138-f99709370657
179 lines
4.7 KiB
C
179 lines
4.7 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2006 Jens Arnold
|
|
*
|
|
* 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 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();
|
|
}
|