mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
s5l87xx: Add support for S5L8720 to the GPIO driver
This is a part of the large iPod Nano 3G/4G support patch. Credit: Cástor Muñoz <cmvidal@gmail.com> Change-Id: I577eef01f42e8752ad9b2ee64e2b30ad0a9e55be
This commit is contained in:
parent
da9d67a0fe
commit
12aea7dae6
3 changed files with 47 additions and 15 deletions
|
@ -32,23 +32,41 @@ int rec_hw_ver;
|
||||||
|
|
||||||
static uint32_t gpio_data[] =
|
static uint32_t gpio_data[] =
|
||||||
{
|
{
|
||||||
|
#if defined(IPOD_6G)
|
||||||
0x5322222F, 0xEEEEEE00, 0x2332EEEE, 0x3333E222,
|
0x5322222F, 0xEEEEEE00, 0x2332EEEE, 0x3333E222,
|
||||||
0x33333333, 0x33333333, 0x3F000E33, 0xEEEEEEEE,
|
0x33333333, 0x33333333, 0x3F000E33, 0xEEEEEEEE,
|
||||||
0xEEEEEEEE, 0xEEEEEEEE, 0xE0EEEEEE, 0xEE00EE0E,
|
0xEEEEEEEE, 0xEEEEEEEE, 0xE0EEEEEE, 0xEE00EE0E,
|
||||||
0xEEEE0EEE, 0xEEEEEEEE, 0xEE2222EE, 0xEEEE0EEE
|
0xEEEE0EEE, 0xEEEEEEEE, 0xEE2222EE, 0xEEEE0EEE,
|
||||||
|
#elif defined(IPOD_NANO3G)
|
||||||
|
0xE322222F, 0xEEEEEE00, 0x2332EEEE, 0x3333E222,
|
||||||
|
0xEEE33333, 0x3EE0EEEE, 0x0F00EE33, 0xEEEEEEE0,
|
||||||
|
0x22222222, 0x22222222, 0x33322222, 0xEEEEEEEE,
|
||||||
|
0xEEEEEEEE, 0xEEEEEEEE, 0xEE2222EE, 0xEEEE0EEE,
|
||||||
|
#elif defined(IPOD_NANO4G)
|
||||||
|
0x3202EEEE, 0xE0EE2253, 0x2223EEEE, 0x33333332,
|
||||||
|
0xFF333E33, 0xE0FEE200, 0x2222222E, 0x22222222,
|
||||||
|
0xEEEEEEE2, 0xEEE0EEEE, 0x2EEEEEEE, 0xEEEE0222,
|
||||||
|
0xEEEEE00E, 0xEEEEEEEE, 0xEEEEEEEE,
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
void INIT_ATTR gpio_preinit(void)
|
void INIT_ATTR gpio_preinit(void)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 16; i++) {
|
for (int i = 0; i < GPIO_N_GROUPS; i++) {
|
||||||
PCON(i) = gpio_data[i];
|
PCON(i) = gpio_data[i];
|
||||||
PUNB(i) = 0;
|
PUNB(i) = 0;
|
||||||
PUNC(i) = 0;
|
PUNC(i) = 0;
|
||||||
}
|
}
|
||||||
|
#if defined(IPOD_NANO4G)
|
||||||
|
PUNB(0) = 0x20;
|
||||||
|
PUNC(1) = 0x40;
|
||||||
|
GPIOUNK388 = (GPIOUNK388 & ~3) | 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void INIT_ATTR gpio_init(void)
|
void INIT_ATTR gpio_init(void)
|
||||||
{
|
{
|
||||||
|
#ifdef IPOD_6G
|
||||||
/* Capture hardware versions:
|
/* Capture hardware versions:
|
||||||
*
|
*
|
||||||
* HW version 1 includes an amplifier for the jack plug
|
* HW version 1 includes an amplifier for the jack plug
|
||||||
|
@ -75,6 +93,9 @@ void INIT_ATTR gpio_init(void)
|
||||||
GPIOCMD = 0xe0600;
|
GPIOCMD = 0xe0600;
|
||||||
PUNB(14) |= (1 << 6);
|
PUNB(14) |= (1 << 6);
|
||||||
}
|
}
|
||||||
|
#elif defined(IPOD_NANO3G)
|
||||||
|
rec_hw_ver = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -109,16 +130,20 @@ void gpio_group_set(int group, uint32_t mask, uint32_t cfg)
|
||||||
#ifndef EINT_MAX_HANDLERS
|
#ifndef EINT_MAX_HANDLERS
|
||||||
#define EINT_MAX_HANDLERS 1
|
#define EINT_MAX_HANDLERS 1
|
||||||
#endif
|
#endif
|
||||||
static struct eint_handler* l_handlers[EINT_MAX_HANDLERS] IDATA_ATTR;
|
static struct eic_handler* l_handlers[EINT_MAX_HANDLERS] IDATA_ATTR;
|
||||||
|
|
||||||
void INIT_ATTR eint_init(void)
|
void INIT_ATTR eint_init(void)
|
||||||
{
|
{
|
||||||
/* disable external interrupts */
|
/* disable and clear external interrupts */
|
||||||
for (int i = 0; i < EIC_N_GROUPS; i++)
|
for (int i = 0; i < EIC_N_GROUPS; i++) {
|
||||||
EIC_INTEN(i) = 0;
|
EIC_INTEN(i) = 0;
|
||||||
|
EIC_INTLEVEL(i) = 0;
|
||||||
|
EIC_INTTYPE(i) = 0;
|
||||||
|
EIC_INTSTAT(i) = ~0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void eint_register(struct eint_handler *h)
|
void eint_register(struct eic_handler *h)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int flags = disable_irq_save();
|
int flags = disable_irq_save();
|
||||||
|
@ -147,7 +172,7 @@ void eint_register(struct eint_handler *h)
|
||||||
panicf("%s(): too many handlers!", __func__);
|
panicf("%s(): too many handlers!", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eint_unregister(struct eint_handler *h)
|
void eint_unregister(struct eic_handler *h)
|
||||||
{
|
{
|
||||||
int flags = disable_irq_save();
|
int flags = disable_irq_save();
|
||||||
|
|
||||||
|
@ -179,7 +204,7 @@ static void ICODE_ATTR eint_handler(int group)
|
||||||
ints = EIC_INTSTAT(group) & EIC_INTEN(group);
|
ints = EIC_INTSTAT(group) & EIC_INTEN(group);
|
||||||
|
|
||||||
for (i = 0; i < EINT_MAX_HANDLERS; i++) {
|
for (i = 0; i < EINT_MAX_HANDLERS; i++) {
|
||||||
struct eint_handler *h = l_handlers[i];
|
struct eic_handler *h = l_handlers[i];
|
||||||
|
|
||||||
if (!h || (EIC_GROUP(h->gpio_n) != group))
|
if (!h || (EIC_GROUP(h->gpio_n) != group))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -52,7 +52,11 @@
|
||||||
#define GPIO_EINT_ALIVE 0xda
|
#define GPIO_EINT_ALIVE 0xda
|
||||||
|
|
||||||
/* probably a part of the system controller */
|
/* probably a part of the system controller */
|
||||||
|
#if CONFIG_CPU == S5L8702
|
||||||
#define EIC_BASE 0x39a00000
|
#define EIC_BASE 0x39a00000
|
||||||
|
#elif CONFIG_CPU == S5L8720
|
||||||
|
#define EIC_BASE 0x39700000
|
||||||
|
#endif
|
||||||
|
|
||||||
#define EIC_INTLEVEL(g) (*((REG32_PTR_T)(EIC_BASE + 0x80 + 4*(g))))
|
#define EIC_INTLEVEL(g) (*((REG32_PTR_T)(EIC_BASE + 0x80 + 4*(g))))
|
||||||
#define EIC_INTSTAT(g) (*((REG32_PTR_T)(EIC_BASE + 0xA0 + 4*(g))))
|
#define EIC_INTSTAT(g) (*((REG32_PTR_T)(EIC_BASE + 0xA0 + 4*(g))))
|
||||||
|
@ -66,17 +70,17 @@
|
||||||
#define EIC_INTTYPE_LEVEL 1
|
#define EIC_INTTYPE_LEVEL 1
|
||||||
|
|
||||||
|
|
||||||
struct eint_handler {
|
struct eic_handler {
|
||||||
uint8_t gpio_n;
|
uint8_t gpio_n;
|
||||||
uint8_t type; /* EIC_INTTYPE_ */
|
uint8_t type; /* EIC_INTTYPE_ */
|
||||||
uint8_t level; /* EIC_INTLEVEL_ */
|
uint8_t level; /* EIC_INTLEVEL_ */
|
||||||
uint8_t autoflip;
|
uint8_t autoflip;
|
||||||
void (*isr)(struct eint_handler*);
|
void (*isr)(struct eic_handler*);
|
||||||
};
|
};
|
||||||
|
|
||||||
void eint_init(void);
|
void eint_init(void);
|
||||||
void eint_register(struct eint_handler *h);
|
void eint_register(struct eic_handler *h);
|
||||||
void eint_unregister(struct eint_handler *h);
|
void eint_unregister(struct eic_handler *h);
|
||||||
|
|
||||||
void gpio_preinit(void);
|
void gpio_preinit(void);
|
||||||
void gpio_init(void);
|
void gpio_init(void);
|
||||||
|
@ -85,6 +89,7 @@ uint32_t gpio_group_get(int group);
|
||||||
void gpio_group_set(int group, uint32_t mask, uint32_t cfg);
|
void gpio_group_set(int group, uint32_t mask, uint32_t cfg);
|
||||||
|
|
||||||
|
|
||||||
|
#if CONFIG_CPU == S5L8702
|
||||||
/*
|
/*
|
||||||
* This is very preliminary work in progress, ATM this region is called
|
* This is very preliminary work in progress, ATM this region is called
|
||||||
* system 'alive' because it seems there are similiarities when mixing
|
* system 'alive' because it seems there are similiarities when mixing
|
||||||
|
@ -158,4 +163,6 @@ void gpio_group_set(int group, uint32_t mask, uint32_t cfg);
|
||||||
#define ALVTCNT (*((REG32_PTR_T)(SYSALV_BASE + 0x78)))
|
#define ALVTCNT (*((REG32_PTR_T)(SYSALV_BASE + 0x78)))
|
||||||
#define ALVTSTAT (*((REG32_PTR_T)(SYSALV_BASE + 0x7c)))
|
#define ALVTSTAT (*((REG32_PTR_T)(SYSALV_BASE + 0x7c)))
|
||||||
|
|
||||||
|
#endif /* CONFIG_CPU == S5L8702 */
|
||||||
|
|
||||||
#endif /* __GPIO_S5L8702_H__ */
|
#endif /* __GPIO_S5L8702_H__ */
|
||||||
|
|
|
@ -199,9 +199,9 @@ static char pmu_thread_stack[DEFAULT_STACK_SIZE/2];
|
||||||
static struct event_queue pmu_queue;
|
static struct event_queue pmu_queue;
|
||||||
static unsigned char ints_msk[6];
|
static unsigned char ints_msk[6];
|
||||||
|
|
||||||
static void pmu_eint_isr(struct eint_handler*);
|
static void pmu_eint_isr(struct eic_handler*);
|
||||||
|
|
||||||
static struct eint_handler pmu_eint =
|
static struct eic_handler pmu_eint =
|
||||||
{
|
{
|
||||||
.gpio_n = GPIO_EINT_PMU,
|
.gpio_n = GPIO_EINT_PMU,
|
||||||
.type = EIC_INTTYPE_LEVEL,
|
.type = EIC_INTTYPE_LEVEL,
|
||||||
|
@ -258,7 +258,7 @@ static void pmu_read_inputs_ooc(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmu_eint_isr(struct eint_handler *h)
|
static void pmu_eint_isr(struct eic_handler *h)
|
||||||
{
|
{
|
||||||
eint_unregister(h);
|
eint_unregister(h);
|
||||||
queue_post(&pmu_queue, Q_EINT, 0);
|
queue_post(&pmu_queue, Q_EINT, 0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue