rockbox/firmware/drivers/isp1362.c
Daniel Stenberg 2acc0ac542 Updated our source code header to explicitly mention that we are GPL v2 or
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
2008-06-28 18:10:04 +00:00

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();
}