summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-06-05 00:12:01 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-06-06 11:06:14 +0000
commite85bc74b307365e9a7b4adab51d646638db12fbd (patch)
treec45ba9079344b5cc0ea48a77b6aa77aacd71cdc5
parent695d1701cdd1bb4539f652c2204f7787097b2715 (diff)
downloadrockbox-e85bc74b307365e9a7b4adab51d646638db12fbd.tar.gz
rockbox-e85bc74b307365e9a7b4adab51d646638db12fbd.zip
x1000: GPIO refactor
The GPIO API was pretty clunky and pin settings were decentralized, making it hard to see what was happening and making GPIO stuff look like a mess, frankly. Instead of passing clunky (port, pin) pairs everywhere, GPIOs are now identified with a single int. The extra overhead should be minimal as GPIO configuration is generally not on a performance-critical path. Pin assignments are now mostly consolidated in gpio-target.h and put in various tables so gpio_init() can assign most pins at boot time. Most drivers no longer need to touch GPIOs and basic pin I/O stuff can happen without config since pins are put into the right state. IRQ pins still need to be configured manually before use. Change-Id: Ic5326284b0b2a2f613e9e76a41cb50e24af3aa47
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/audiohw-fiiom3k.c2
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c16
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/gpio-target.h26
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/lcd-fiiom3k.c25
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/power-fiiom3k.c4
-rw-r--r--firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c2
-rw-r--r--firmware/target/mips/ingenic_x1000/gpio-x1000.c88
-rw-r--r--firmware/target/mips/ingenic_x1000/gpio-x1000.h164
-rw-r--r--firmware/target/mips/ingenic_x1000/i2c-x1000.c18
-rw-r--r--firmware/target/mips/ingenic_x1000/msc-x1000.c47
-rw-r--r--firmware/target/mips/ingenic_x1000/msc-x1000.h9
-rw-r--r--firmware/target/mips/ingenic_x1000/pcm-x1000.c2
-rw-r--r--firmware/target/mips/ingenic_x1000/pwm-x1000.c39
-rw-r--r--firmware/target/mips/ingenic_x1000/sd-x1000.c3
-rw-r--r--firmware/target/mips/ingenic_x1000/sfc-x1000.c2
-rw-r--r--firmware/target/mips/ingenic_x1000/usb-x1000.c26
17 files changed, 280 insertions, 195 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 4c1fa7bf46..10c9789069 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1659,7 +1659,9 @@ target/mips/ingenic_x1000/pwm-x1000.c
1659target/mips/ingenic_x1000/sfc-x1000.c 1659target/mips/ingenic_x1000/sfc-x1000.c
1660target/mips/ingenic_x1000/system-x1000.c 1660target/mips/ingenic_x1000/system-x1000.c
1661target/mips/ingenic_x1000/timer-x1000.c 1661target/mips/ingenic_x1000/timer-x1000.c
1662#ifndef USB_NONE
1662target/mips/ingenic_x1000/usb-x1000.c 1663target/mips/ingenic_x1000/usb-x1000.c
1664#endif
1663#if (CONFIG_STORAGE & (STORAGE_SD|STORAGE_MMC|STORAGE_ATA)) 1665#if (CONFIG_STORAGE & (STORAGE_SD|STORAGE_MMC|STORAGE_ATA))
1664target/mips/ingenic_x1000/msc-x1000.c 1666target/mips/ingenic_x1000/msc-x1000.c
1665#endif 1667#endif
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/audiohw-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/audiohw-fiiom3k.c
index 542d1745dc..8528b803f7 100644
--- a/firmware/target/mips/ingenic_x1000/fiiom3k/audiohw-fiiom3k.c
+++ b/firmware/target/mips/ingenic_x1000/fiiom3k/audiohw-fiiom3k.c
@@ -87,5 +87,5 @@ void audiohw_set_power_mode(int mode)
87 87
88void ak4376_set_pdn_pin(int level) 88void ak4376_set_pdn_pin(int level)
89{ 89{
90 gpio_config(GPIO_A, 1 << 16, GPIO_OUTPUT(level ? 1 : 0)); 90 gpio_set_level(GPIO_AK4376_POWER, level ? 1 : 0);
91} 91}
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c
index efc652c84f..47b5e3d6dc 100644
--- a/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c
+++ b/firmware/target/mips/ingenic_x1000/fiiom3k/button-fiiom3k.c
@@ -35,8 +35,6 @@
35# include "font.h" 35# include "font.h"
36#endif 36#endif
37 37
38#define FT_RST_PIN (1 << 15)
39#define FT_INT_PIN (1 << 12)
40#define ft_interrupt GPIOB12 38#define ft_interrupt GPIOB12
41 39
42/* Touch event types */ 40/* Touch event types */
@@ -389,11 +387,13 @@ static void ft_init(void)
389 i2c_x1000_set_freq(FT6x06_BUS, I2C_FREQ_400K); 387 i2c_x1000_set_freq(FT6x06_BUS, I2C_FREQ_400K);
390 388
391 /* Reset chip */ 389 /* Reset chip */
392 gpio_config(GPIO_B, FT_RST_PIN|FT_INT_PIN, GPIO_OUTPUT(0)); 390 gpio_set_level(GPIO_FT6x06_RESET, 0);
393 mdelay(5); 391 mdelay(5);
394 gpio_out_level(GPIO_B, FT_RST_PIN, 1); 392 gpio_set_level(GPIO_FT6x06_RESET, 1);
395 gpio_config(GPIO_B, FT_INT_PIN, GPIO_IRQ_EDGE(0)); 393
396 gpio_enable_irq(GPIO_B, FT_INT_PIN); 394 /* Configure the interrupt pin */
395 gpio_set_function(GPIO_FT6x06_INTERRUPT, GPIOF_IRQ_EDGE(0));
396 gpio_enable_irq(GPIO_FT6x06_INTERRUPT);
397} 397}
398 398
399void touchpad_set_sensitivity(int level) 399void touchpad_set_sensitivity(int level)
@@ -454,10 +454,6 @@ static void hp_detect_init(void)
454/* Rockbox interface */ 454/* Rockbox interface */
455void button_init_device(void) 455void button_init_device(void)
456{ 456{
457 /* Configure physical button GPIOs */
458 gpio_config(GPIO_A, (1 << 17) | (1 << 19), GPIO_INPUT);
459 gpio_config(GPIO_B, (1 << 28) | (1 << 31), GPIO_INPUT);
460
461 /* Initialize touchpad */ 457 /* Initialize touchpad */
462 ft_init(); 458 ft_init();
463 459
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/gpio-target.h b/firmware/target/mips/ingenic_x1000/fiiom3k/gpio-target.h
new file mode 100644
index 0000000000..f580cd9167
--- /dev/null
+++ b/firmware/target/mips/ingenic_x1000/fiiom3k/gpio-target.h
@@ -0,0 +1,26 @@
1/* Name Port Pins Function */
2DEFINE_PINGROUP(LCD_DATA, GPIO_A, 0xffff << 0, GPIOF_DEVICE(1))
3DEFINE_PINGROUP(LCD_CONTROL, GPIO_B, 0x1a << 16, GPIOF_DEVICE(1))
4DEFINE_PINGROUP(MSC0, GPIO_A, 0x3f << 20, GPIOF_DEVICE(1))
5DEFINE_PINGROUP(SFC, GPIO_A, 0x3f << 26, GPIOF_DEVICE(1))
6DEFINE_PINGROUP(I2S, GPIO_B, 0x1f << 0, GPIOF_DEVICE(1))
7DEFINE_PINGROUP(DMIC, GPIO_B, 3 << 21, GPIOF_DEVICE(0))
8DEFINE_PINGROUP(I2C0, GPIO_B, 3 << 23, GPIOF_DEVICE(0))
9DEFINE_PINGROUP(I2C1, GPIO_C, 3 << 26, GPIOF_DEVICE(0))
10DEFINE_PINGROUP(I2C2, GPIO_D, 3 << 0, GPIOF_DEVICE(1))
11
12/* Name Pin Function */
13DEFINE_GPIO(AK4376_POWER, GPIO_PA(16), GPIOF_OUTPUT(0))
14DEFINE_GPIO(BTN_PLAY, GPIO_PA(17), GPIOF_INPUT)
15DEFINE_GPIO(BTN_VOL_UP, GPIO_PA(19), GPIOF_INPUT)
16DEFINE_GPIO(MSC0_CD, GPIO_PB(6), GPIOF_INPUT)
17DEFINE_GPIO(USB_ID, GPIO_PB(7), GPIOF_INPUT)
18DEFINE_GPIO(AXP_IRQ, GPIO_PB(10), GPIOF_INPUT)
19DEFINE_GPIO(USB_DETECT, GPIO_PB(11), GPIOF_INPUT)
20DEFINE_GPIO(FT6x06_INTERRUPT, GPIO_PB(12), GPIOF_INPUT)
21DEFINE_GPIO(FT6x06_RESET, GPIO_PB(15), GPIOF_OUTPUT(0))
22DEFINE_GPIO(LCD_RD, GPIO_PB(16), GPIOF_OUTPUT(1))
23DEFINE_GPIO(LCD_CE, GPIO_PB(18), GPIOF_OUTPUT(1))
24DEFINE_GPIO(USB_DRVVBUS, GPIO_PB(25), GPIOF_OUTPUT(0))
25DEFINE_GPIO(BTN_VOL_DOWN, GPIO_PB(28), GPIOF_INPUT)
26DEFINE_GPIO(BTN_POWER, GPIO_PB(31), GPIOF_INPUT)
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/lcd-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/lcd-fiiom3k.c
index 96f794d7df..29e72286ff 100644
--- a/firmware/target/mips/ingenic_x1000/fiiom3k/lcd-fiiom3k.c
+++ b/firmware/target/mips/ingenic_x1000/fiiom3k/lcd-fiiom3k.c
@@ -25,9 +25,6 @@
25#include "gpio-x1000.h" 25#include "gpio-x1000.h"
26#include "system.h" 26#include "system.h"
27 27
28#define CS_PIN (1 << 18)
29#define RD_PIN (1 << 16)
30
31static const uint32_t fiio_lcd_cmd_enable[] = { 28static const uint32_t fiio_lcd_cmd_enable[] = {
32 /* Software reset */ 29 /* Software reset */
33 LCD_INSTR_CMD, 0x01, 30 LCD_INSTR_CMD, 0x01,
@@ -169,17 +166,27 @@ const struct lcd_tgt_config lcd_tgt_config = {
169void lcd_tgt_enable(bool enable) 166void lcd_tgt_enable(bool enable)
170{ 167{
171 if(enable) { 168 if(enable) {
172 gpio_config(GPIO_A, 0xffff, GPIO_DEVICE(1)); 169 /* reset controller, probably */
173 gpio_config(GPIO_B, 0x1f << 16, GPIO_DEVICE(1)); 170 gpio_set_level(GPIO_LCD_CE, 1);
174 gpio_config(GPIO_B, CS_PIN|RD_PIN, GPIO_OUTPUT(1)); 171 gpio_set_level(GPIO_LCD_RD, 1);
175 mdelay(5); 172 mdelay(5);
176 gpio_out_level(GPIO_B, CS_PIN, 0); 173 gpio_set_level(GPIO_LCD_CE, 0);
174
175 /* set the clock whatever it is... */
177 lcd_set_clock(X1000_CLK_SCLK_A, 30000000); 176 lcd_set_clock(X1000_CLK_SCLK_A, 30000000);
177
178 /* program the initial configuration */
178 lcd_exec_commands(&fiio_lcd_cmd_enable[0]); 179 lcd_exec_commands(&fiio_lcd_cmd_enable[0]);
179 } else { 180 } else {
181 /* go to sleep mode first */
180 lcd_exec_commands(&fiio_lcd_cmd_sleep[0]); 182 lcd_exec_commands(&fiio_lcd_cmd_sleep[0]);
181 mdelay(115); /* ensure we wait a total of 120ms before power off */ 183
182 gpio_config(GPIO_B, CS_PIN|RD_PIN, 0); 184 /* ensure we wait a total of 120ms before power off */
185 mdelay(115);
186
187 /* this is intended to power off the panel but I'm not sure it does */
188 gpio_set_level(GPIO_LCD_CE, 0);
189 gpio_set_level(GPIO_LCD_RD, 0);
183 } 190 }
184} 191}
185 192
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/power-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/power-fiiom3k.c
index a7f6165980..6b1ad2dbb5 100644
--- a/firmware/target/mips/ingenic_x1000/fiiom3k/power-fiiom3k.c
+++ b/firmware/target/mips/ingenic_x1000/fiiom3k/power-fiiom3k.c
@@ -28,7 +28,6 @@
28#endif 28#endif
29#include "axp-pmu.h" 29#include "axp-pmu.h"
30#include "i2c-x1000.h" 30#include "i2c-x1000.h"
31#include "gpio-x1000.h"
32 31
33const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = 32const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
34{ 33{
@@ -53,9 +52,6 @@ const unsigned short percent_to_volt_charge[11] =
53 3485, 3780, 3836, 3857, 3890, 3930, 3986, 4062, 4158, 4185, 4196 52 3485, 3780, 3836, 3857, 3890, 3930, 3986, 4062, 4158, 4185, 4196
54}; 53};
55 54
56#define AXP_IRQ_PORT GPIO_B
57#define AXP_IRQ_PIN (1 << 10)
58
59void power_init(void) 55void power_init(void)
60{ 56{
61 /* Initialize driver */ 57 /* Initialize driver */
diff --git a/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c b/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c
index efea5aa323..85ce4da8f6 100644
--- a/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c
+++ b/firmware/target/mips/ingenic_x1000/fiiom3k/spl-fiiom3k.c
@@ -116,7 +116,7 @@ int spl_get_boot_option(void)
116 const int max_iter_count = 30; 116 const int max_iter_count = 30;
117 117
118 /* Configure the button GPIOs as inputs */ 118 /* Configure the button GPIOs as inputs */
119 gpio_config(GPIO_A, pinmask, GPIO_INPUT); 119 gpioz_configure(GPIO_A, pinmask, GPIOF_INPUT);
120 120
121 /* Poll the pins for a short duration to detect a keypress */ 121 /* Poll the pins for a short duration to detect a keypress */
122 do { 122 do {
diff --git a/firmware/target/mips/ingenic_x1000/gpio-x1000.c b/firmware/target/mips/ingenic_x1000/gpio-x1000.c
index 40e4c5e631..14195359df 100644
--- a/firmware/target/mips/ingenic_x1000/gpio-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/gpio-x1000.c
@@ -20,37 +20,91 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "gpio-x1000.h" 22#include "gpio-x1000.h"
23#include "kernel.h" 23
24const struct gpio_setting gpio_settings[PIN_COUNT] = {
25#define DEFINE_GPIO(_name, _gpio, _func) \
26 {.gpio = _gpio, .func = _func},
27#define DEFINE_PINGROUP(...)
28#include "gpio-target.h"
29#undef DEFINE_GPIO
30#undef DEFINE_PINGROUP
31};
32
33const struct pingroup_setting pingroup_settings[PINGROUP_COUNT] = {
34#define DEFINE_GPIO(...)
35#define DEFINE_PINGROUP(_name, _port, _pins, _func) \
36 {.port = _port, .pins = _pins, .func = _func},
37#include "gpio-target.h"
38#undef DEFINE_GPIO
39#undef DEFINE_PINGROUP
40};
41
42const char* const gpio_names[PIN_COUNT] = {
43#define DEFINE_GPIO(_name, ...) #_name,
44#define DEFINE_PINGROUP(...)
45#include "gpio-target.h"
46#undef DEFINE_GPIO
47#undef DEFINE_PINGROUP
48};
49
50const char* const pingroup_names[PINGROUP_COUNT] = {
51#define DEFINE_GPIO(...)
52#define DEFINE_PINGROUP(_name, ...) #_name,
53#include "gpio-target.h"
54#undef DEFINE_GPIO
55#undef DEFINE_PINGROUP
56};
24 57
25void gpio_init(void) 58void gpio_init(void)
26{ 59{
60 /* Apply all initial GPIO settings */
61 for(int i = 0; i < PINGROUP_COUNT; ++i) {
62 const struct pingroup_setting* d = &pingroup_settings[i];
63 if(d->pins != 0)
64 gpioz_configure(d->port, d->pins, d->func);
65 }
66
67 for(int i = 0; i < PIN_COUNT; ++i) {
68 const struct gpio_setting* d = &gpio_settings[i];
69 if(d->gpio != GPIO_NONE)
70 gpioz_configure(GPION_PORT(d->gpio), GPION_MASK(d->gpio), d->func);
71 }
72
27 /* Any GPIO pins left in an IRQ trigger state need to be switched off, 73 /* Any GPIO pins left in an IRQ trigger state need to be switched off,
28 * because the drivers won't be ready to handle the interrupts until they 74 * because the drivers won't be ready to handle the interrupts until they
29 * get initialized later in the boot. */ 75 * get initialized later in the boot. */
30 for(int i = 0; i < 4; ++i) { 76 for(int i = 0; i < 4; ++i) {
31 uint32_t intbits = REG_GPIO_INT(i); 77 uint32_t intbits = REG_GPIO_INT(i);
32 if(intbits) { 78 if(intbits) {
33 gpio_config(i, intbits, GPIO_INPUT); 79 gpioz_configure(i, intbits, GPIOF_INPUT);
34 jz_clr(GPIO_FLAG(i), intbits); 80 jz_clr(GPIO_FLAG(i), intbits);
35 } 81 }
36 } 82 }
37} 83}
38 84
39void gpio_config(int port, unsigned pinmask, int func) 85void gpioz_configure(int port, uint32_t pins, int func)
40{ 86{
41 unsigned intr = REG_GPIO_INT(port); 87 uint32_t intr = REG_GPIO_INT(port);
42 unsigned mask = REG_GPIO_MSK(port); 88 uint32_t mask = REG_GPIO_MSK(port);
43 unsigned pat1 = REG_GPIO_PAT1(port); 89 uint32_t pat1 = REG_GPIO_PAT1(port);
44 unsigned pat0 = REG_GPIO_PAT0(port); 90 uint32_t pat0 = REG_GPIO_PAT0(port);
45 91
46 if(func & 8) jz_set(GPIO_INT(GPIO_Z), (intr & pinmask) ^ pinmask); 92 /* Note: GPIO Z has _only_ set and clear registers, which are used to
47 else jz_clr(GPIO_INT(GPIO_Z), (~intr & pinmask) ^ pinmask); 93 * atomically manipulate the selected GPIO port when we write GID2LD.
48 if(func & 4) jz_set(GPIO_MSK(GPIO_Z), (mask & pinmask) ^ pinmask); 94 * So there's not really any direct setting or clearing going on here...
49 else jz_clr(GPIO_MSK(GPIO_Z), (~mask & pinmask) ^ pinmask); 95 */
50 if(func & 2) jz_set(GPIO_PAT1(GPIO_Z), (pat1 & pinmask) ^ pinmask); 96 if(func & GPIO_F_INT) jz_set(GPIO_INT(GPIO_Z), (intr & pins) ^ pins);
51 else jz_clr(GPIO_PAT1(GPIO_Z), (~pat1 & pinmask) ^ pinmask); 97 else jz_clr(GPIO_INT(GPIO_Z), (~intr & pins) ^ pins);
52 if(func & 1) jz_set(GPIO_PAT0(GPIO_Z), (pat0 & pinmask) ^ pinmask); 98 if(func & GPIO_F_MASK) jz_set(GPIO_MSK(GPIO_Z), (mask & pins) ^ pins);
53 else jz_clr(GPIO_PAT0(GPIO_Z), (~pat0 & pinmask) ^ pinmask); 99 else jz_clr(GPIO_MSK(GPIO_Z), (~mask & pins) ^ pins);
100 if(func & GPIO_F_PAT1) jz_set(GPIO_PAT1(GPIO_Z), (pat1 & pins) ^ pins);
101 else jz_clr(GPIO_PAT1(GPIO_Z), (~pat1 & pins) ^ pins);
102 if(func & GPIO_F_PAT0) jz_set(GPIO_PAT0(GPIO_Z), (pat0 & pins) ^ pins);
103 else jz_clr(GPIO_PAT0(GPIO_Z), (~pat0 & pins) ^ pins);
54 REG_GPIO_Z_GID2LD = port; 104 REG_GPIO_Z_GID2LD = port;
55 gpio_set_pull(port, pinmask, func & 16); 105
106 if(func & GPIO_F_PULL)
107 jz_set(GPIO_PULL(port), pins);
108 else
109 jz_clr(GPIO_PULL(port), pins);
56} 110}
diff --git a/firmware/target/mips/ingenic_x1000/gpio-x1000.h b/firmware/target/mips/ingenic_x1000/gpio-x1000.h
index cfbe86338a..5d147fc18f 100644
--- a/firmware/target/mips/ingenic_x1000/gpio-x1000.h
+++ b/firmware/target/mips/ingenic_x1000/gpio-x1000.h
@@ -22,33 +22,6 @@
22#ifndef __GPIO_X1000_H__ 22#ifndef __GPIO_X1000_H__
23#define __GPIO_X1000_H__ 23#define __GPIO_X1000_H__
24 24
25/* GPIO API
26 * --------
27 *
28 * To assign a new function to a GPIO, call gpio_config(). This uses the
29 * hardware's GPIO Z facility to atomically set most GPIO registers at once,
30 * so it can be used to make any state transition safely. Since GPIO Z is
31 * a global hardware resource, it is unsafe to call gpio_config() from IRQ
32 * context -- if the interrupted code was also running gpio_config(), then
33 * the results would be unpredictable.
34 *
35 * Depending on the current GPIO state, certain state transitions are safe to
36 * perform without locking, as they only change one register:
37 *
38 * - for pins in GPIO_OUTPUT state:
39 * - use gpio_out_level() to change the output level
40 *
41 * - for pins in GPIO_IRQ_LEVEL or GPIO_IRQ_EDGE state:
42 * - use gpio_irq_level() to change the trigger level
43 * - use gpio_irq_mask() to mask/unmask the IRQ
44 *
45 * - for pins in GPIO_DEVICE or GPIO_INPUT state:
46 * - no special transitions allowed
47 *
48 * - in all states:
49 * - use gpio_set_pull() to change the pull-up/pull-down state
50 */
51
52#include "x1000/gpio.h" 25#include "x1000/gpio.h"
53 26
54/* GPIO port numbers */ 27/* GPIO port numbers */
@@ -66,42 +39,137 @@
66#define GPIO_F_PAT0 1 39#define GPIO_F_PAT0 1
67 40
68/* GPIO function numbers */ 41/* GPIO function numbers */
69#define GPIO_DEVICE(i) ((i)&3) 42#define GPIOF_DEVICE(i) ((i)&3)
70#define GPIO_OUTPUT(i) (0x4|((i)&1)) 43#define GPIOF_OUTPUT(i) (0x4|((i)&1))
71#define GPIO_INPUT 0x16 44#define GPIOF_INPUT 0x16
72#define GPIO_IRQ_LEVEL(i) (0x1c|((i)&1)) 45#define GPIOF_IRQ_LEVEL(i) (0x1c|((i)&1))
73#define GPIO_IRQ_EDGE(i) (0x1e|((i)&1)) 46#define GPIOF_IRQ_EDGE(i) (0x1e|((i)&1))
47
48/* GPIO pin numbers */
49#define GPION_CREATE(port, pin) ((((port) & 3) << 5) | ((pin) & 0x1f))
50#define GPION_PORT(gpio) (((gpio) >> 5) & 3)
51#define GPION_PIN(gpio) ((gpio) & 0x1f)
52#define GPION_MASK(gpio) (1u << GPION_PIN(gpio))
53
54/* Easy pin number macros */
55#define GPIO_PA(x) GPION_CREATE(GPIO_A, x)
56#define GPIO_PB(x) GPION_CREATE(GPIO_B, x)
57#define GPIO_PC(x) GPION_CREATE(GPIO_C, x)
58#define GPIO_PD(x) GPION_CREATE(GPIO_D, x)
59
60/* Pingroup settings are used for system devices */
61struct pingroup_setting {
62 int port;
63 uint32_t pins;
64 int func;
65};
66
67/* GPIO settings are used for single pins under software control */
68struct gpio_setting {
69 int gpio;
70 int func;
71};
72
73/* Target pins are defined as GPIO_XXX constants usable with the GPIO API */
74enum {
75#define DEFINE_GPIO(_name, _gpio, _func) GPIO_##_name = _gpio,
76#define DEFINE_PINGROUP(...)
77#include "gpio-target.h"
78#undef DEFINE_GPIO
79#undef DEFINE_PINGROUP
80 GPIO_NONE = -1,
81};
82
83/* These are pin IDs which index gpio_settings */
84enum {
85#define DEFINE_GPIO(_name, ...) PIN_##_name,
86#define DEFINE_PINGROUP(...)
87#include "gpio-target.h"
88#undef DEFINE_GPIO
89#undef DEFINE_PINGROUP
90 PIN_COUNT,
91};
92
93/* Pingroup IDs which index pingroup_settings */
94enum {
95#define DEFINE_GPIO(...)
96#define DEFINE_PINGROUP(_name, ...) PINGROUP_##_name,
97#include "gpio-target.h"
98#undef DEFINE_GPIO
99#undef DEFINE_PINGROUP
100 PINGROUP_COUNT,
101};
102
103/* arrays which define the target's GPIO settings */
104extern const struct gpio_setting gpio_settings[PIN_COUNT];
105extern const struct pingroup_setting pingroup_settings[PINGROUP_COUNT];
74 106
107/* stringified names for use in debug menus */
108extern const char* const gpio_names[PIN_COUNT];
109extern const char* const pingroup_names[PINGROUP_COUNT];
110
111/* called at early init to set up GPIOs */
75extern void gpio_init(void); 112extern void gpio_init(void);
76extern void gpio_config(int port, unsigned pinmask, int func);
77 113
78static inline void gpio_out_level(int port, unsigned pinmask, int level) 114/* Use GPIO Z to reconfigure several pins atomically */
115extern void gpioz_configure(int port, uint32_t pins, int func);
116
117static inline void gpio_set_function(int gpio, int func)
118{
119 gpioz_configure(GPION_PORT(gpio), GPION_MASK(gpio), func);
120}
121
122static inline int gpio_get_level(int gpio)
123{
124 return REG_GPIO_PIN(GPION_PORT(gpio)) & GPION_MASK(gpio) ? 1 : 0;
125}
126
127static inline void gpio_set_level(int gpio, int value)
79{ 128{
80 if(level) 129 if(value)
81 jz_set(GPIO_PAT0(port), pinmask); 130 jz_set(GPIO_PAT0(GPION_PORT(gpio)), GPION_MASK(gpio));
82 else 131 else
83 jz_clr(GPIO_PAT0(port), pinmask); 132 jz_clr(GPIO_PAT0(GPION_PORT(gpio)), GPION_MASK(gpio));
84} 133}
85 134
86#define gpio_irq_level gpio_out_level 135static inline void gpio_set_pull(int gpio, int state)
136{
137 if(state)
138 jz_set(GPIO_PULL(GPION_PORT(gpio)), GPION_MASK(gpio));
139 else
140 jz_clr(GPIO_PULL(GPION_PORT(gpio)), GPION_MASK(gpio));
141}
87 142
88static inline void gpio_irq_mask(int port, unsigned pinmask, int masked) 143static inline void gpio_mask_irq(int gpio, int mask)
89{ 144{
90 if(masked) 145 if(mask)
91 jz_set(GPIO_MSK(port), pinmask); 146 jz_set(GPIO_MSK(GPION_PORT(gpio)), GPION_MASK(gpio));
92 else 147 else
93 jz_clr(GPIO_MSK(port), pinmask); 148 jz_clr(GPIO_MSK(GPION_PORT(gpio)), GPION_MASK(gpio));
94} 149}
95 150
96#define gpio_enable_irq(port, pinmask) gpio_irq_mask((port), (pinmask), 0) 151#define gpio_set_irq_level gpio_set_level
97#define gpio_disable_irq(port, pinmask) gpio_irq_mask((port), (pinmask), 1) 152#define gpio_enable_irq(gpio) gpio_mask_irq((gpio), 0)
153#define gpio_disable_irq(gpio) gpio_mask_irq((gpio), 1)
98 154
99static inline void gpio_set_pull(int port, unsigned pinmask, int state) 155/* Helper function for edge-triggered IRQs when you want to get an
156 * interrupt on both the rising and falling edges. The hardware can
157 * only be set up to interrupt on one edge, so interrupt handlers
158 * can call this function to flip the trigger to the other edge.
159 *
160 * Despite the name, this doesn't depend on the currently set edge,
161 * it just reads the GPIO state and sets up an edge trigger to detect
162 * a change to the other state -- if some transitions were missed the
163 * IRQ trigger may remain unchanged.
164 *
165 * It can be safely used to initialize the IRQ level.
166 */
167static inline void gpio_flip_edge_irq(int gpio)
100{ 168{
101 if(state) 169 if(gpio_get_level(gpio))
102 jz_set(GPIO_PULL(port), pinmask); 170 gpio_set_irq_level(gpio, 0);
103 else 171 else
104 jz_clr(GPIO_PULL(port), pinmask); 172 gpio_set_irq_level(gpio, 1);
105} 173}
106 174
107#endif /* __GPIO_X1000_H__ */ 175#endif /* __GPIO_X1000_H__ */
diff --git a/firmware/target/mips/ingenic_x1000/i2c-x1000.c b/firmware/target/mips/ingenic_x1000/i2c-x1000.c
index 8bf606227b..6a5d2e08d2 100644
--- a/firmware/target/mips/ingenic_x1000/i2c-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/i2c-x1000.c
@@ -25,7 +25,6 @@
25#include "kernel.h" 25#include "kernel.h"
26#include "panic.h" 26#include "panic.h"
27#include "logf.h" 27#include "logf.h"
28#include "gpio-x1000.h"
29#include "clk-x1000.h" 28#include "clk-x1000.h"
30#include "irq-x1000.h" 29#include "irq-x1000.h"
31#include "x1000/i2c.h" 30#include "x1000/i2c.h"
@@ -375,18 +374,6 @@ void i2c_init(void)
375/* Stuff only required during initialization is below, basically the same as 374/* Stuff only required during initialization is below, basically the same as
376 * the old driver except for how the IRQs are initially set up. */ 375 * the old driver except for how the IRQs are initially set up. */
377 376
378static const struct {
379 int port;
380 unsigned pins;
381 int func;
382} i2c_x1000_gpio_data[] = {
383 {GPIO_B, 3 << 23, GPIO_DEVICE(0)},
384 {GPIO_C, 3 << 26, GPIO_DEVICE(0)},
385 /* Note: I2C1 is also on the following pins (normally used by LCD) */
386 /* {GPIO_A, 3 << 0, GPIO_DEVICE(2)}, */
387 {GPIO_D, 3 << 0, GPIO_DEVICE(1)},
388};
389
390static void i2c_x1000_gate(int chn, int gate) 377static void i2c_x1000_gate(int chn, int gate)
391{ 378{
392 switch(chn) { 379 switch(chn) {
@@ -468,11 +455,6 @@ void i2c_x1000_set_freq(int chn, int freq)
468 jz_write(I2C_FHCNT(chn), t_HIGH); 455 jz_write(I2C_FHCNT(chn), t_HIGH);
469 } 456 }
470 457
471 /* Claim pins */
472 gpio_config(i2c_x1000_gpio_data[chn].port,
473 i2c_x1000_gpio_data[chn].pins,
474 i2c_x1000_gpio_data[chn].func);
475
476 /* Enable the controller */ 458 /* Enable the controller */
477 i2c_x1000_enable(chn); 459 i2c_x1000_enable(chn);
478} 460}
diff --git a/firmware/target/mips/ingenic_x1000/msc-x1000.c b/firmware/target/mips/ingenic_x1000/msc-x1000.c
index b8f23053dc..92b3d4206a 100644
--- a/firmware/target/mips/ingenic_x1000/msc-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/msc-x1000.c
@@ -48,7 +48,8 @@ static const msc_config msc_configs[] = {
48 .msc_type = MSC_TYPE_SD, 48 .msc_type = MSC_TYPE_SD,
49 .bus_width = 4, 49 .bus_width = 4,
50 .label = "microSD", 50 .label = "microSD",
51 .cd_gpio = {GPIO_B, 1 << 6, 0}, 51 .cd_gpio = GPIO_MSC0_CD,
52 .cd_active_level = 0,
52 }, 53 },
53#else 54#else
54# error "Please add X1000 MSC config" 55# error "Please add X1000 MSC config"
@@ -117,40 +118,14 @@ static void msc_init_one(msc_drv* d, int msc)
117 msc_full_reset(d); 118 msc_full_reset(d);
118 system_enable_irq(msc == 0 ? IRQ_MSC0 : IRQ_MSC1); 119 system_enable_irq(msc == 0 ? IRQ_MSC0 : IRQ_MSC1);
119 120
120 /* Configure bus pins */
121 int port, device;
122 unsigned pins;
123 if(msc == 0) {
124 port = GPIO_A;
125 device = 1;
126 switch(d->config->bus_width) {
127 case 8: pins = 0x3ff << 16; break;
128 case 4: pins = 0x03f << 20; break;
129 case 1: pins = 0x007 << 23; break;
130 default: pins = 0; break;
131 }
132 } else {
133 port = GPIO_C;
134 device = 0;
135 switch(d->config->bus_width) {
136 case 4: pins = 0x3f; break;
137 case 1: pins = 0x07; break;
138 default: pins = 0; break;
139 }
140 }
141
142 gpio_config(port, pins, GPIO_DEVICE(device));
143
144 /* Setup the card detect IRQ */ 121 /* Setup the card detect IRQ */
145 if(d->config->cd_gpio.pin) { 122 if(d->config->cd_gpio != GPIO_NONE) {
146 port = d->config->cd_gpio.port; 123 if(gpio_get_level(d->config->cd_gpio) != d->config->cd_active_level)
147 pins = d->config->cd_gpio.pin;
148 int level = (REG_GPIO_PIN(port) & pins) ? 1 : 0;
149 if(level != d->config->cd_gpio.active_level)
150 d->card_present = 0; 124 d->card_present = 0;
151 125
152 gpio_config(port, pins, GPIO_IRQ_EDGE(level ? 0 : 1)); 126 gpio_set_function(d->config->cd_gpio, GPIOF_IRQ_EDGE(1));
153 gpio_enable_irq(port, pins); 127 gpio_flip_edge_irq(d->config->cd_gpio);
128 gpio_enable_irq(d->config->cd_gpio);
154 } 129 }
155} 130}
156 131
@@ -212,12 +187,10 @@ void msc_full_reset(msc_drv* d)
212 187
213bool msc_card_detect(msc_drv* d) 188bool msc_card_detect(msc_drv* d)
214{ 189{
215 if(!d->config->cd_gpio.pin) 190 if(d->config->cd_gpio == GPIO_NONE)
216 return true; 191 return true;
217 192
218 int l = REG_GPIO_PIN(d->config->cd_gpio.port) & d->config->cd_gpio.pin; 193 return gpio_get_level(d->config->cd_gpio) == d->config->cd_active_level;
219 l = l ? 1 : 0;
220 return l == d->config->cd_gpio.active_level;
221} 194}
222 195
223/* --------------------------------------------------------------------------- 196/* ---------------------------------------------------------------------------
@@ -661,7 +634,7 @@ static void msc_cd_interrupt(msc_drv* d)
661 } 634 }
662 635
663 /* Invert the IRQ */ 636 /* Invert the IRQ */
664 REG_GPIO_PAT0(d->config->cd_gpio.port) ^= d->config->cd_gpio.pin; 637 gpio_flip_edge_irq(d->config->cd_gpio);
665} 638}
666 639
667void MSC0(void) 640void MSC0(void)
diff --git a/firmware/target/mips/ingenic_x1000/msc-x1000.h b/firmware/target/mips/ingenic_x1000/msc-x1000.h
index 53a5b301f0..70f67a70d6 100644
--- a/firmware/target/mips/ingenic_x1000/msc-x1000.h
+++ b/firmware/target/mips/ingenic_x1000/msc-x1000.h
@@ -83,18 +83,13 @@
83#define MSC_SPEED_FAST 25000000 83#define MSC_SPEED_FAST 25000000
84#define MSC_SPEED_HIGH 50000000 84#define MSC_SPEED_HIGH 50000000
85 85
86typedef struct msc_gpio_data {
87 int port;
88 int pin;
89 int active_level;
90} msc_gpio_data;
91
92typedef struct msc_config { 86typedef struct msc_config {
93 int msc_nr; 87 int msc_nr;
94 int msc_type; 88 int msc_type;
95 int bus_width; 89 int bus_width;
96 const char* label; 90 const char* label;
97 struct msc_gpio_data cd_gpio; 91 int cd_gpio;
92 int cd_active_level;
98} msc_config; 93} msc_config;
99 94
100typedef struct msc_req { 95typedef struct msc_req {
diff --git a/firmware/target/mips/ingenic_x1000/pcm-x1000.c b/firmware/target/mips/ingenic_x1000/pcm-x1000.c
index fd5e9d20c8..a3da3411f2 100644
--- a/firmware/target/mips/ingenic_x1000/pcm-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/pcm-x1000.c
@@ -28,7 +28,6 @@
28#include "panic.h" 28#include "panic.h"
29#include "dma-x1000.h" 29#include "dma-x1000.h"
30#include "irq-x1000.h" 30#include "irq-x1000.h"
31#include "gpio-x1000.h"
32#include "x1000/aic.h" 31#include "x1000/aic.h"
33#include "x1000/cpm.h" 32#include "x1000/cpm.h"
34 33
@@ -55,7 +54,6 @@ void pcm_play_dma_init(void)
55 * on Ingenic's datasheets but I'm not sure what they are. Probably safe to 54 * on Ingenic's datasheets but I'm not sure what they are. Probably safe to
56 * assume they are not useful to Rockbox... */ 55 * assume they are not useful to Rockbox... */
57 jz_writef(CPM_CLKGR, AIC(0)); 56 jz_writef(CPM_CLKGR, AIC(0));
58 gpio_config(GPIO_B, 0x1f, GPIO_DEVICE(1));
59 57
60 /* Configure AIC with some sane defaults */ 58 /* Configure AIC with some sane defaults */
61 jz_writef(AIC_CFG, RST(1)); 59 jz_writef(AIC_CFG, RST(1));
diff --git a/firmware/target/mips/ingenic_x1000/pwm-x1000.c b/firmware/target/mips/ingenic_x1000/pwm-x1000.c
index 8530a38af5..e8243a42ce 100644
--- a/firmware/target/mips/ingenic_x1000/pwm-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/pwm-x1000.c
@@ -26,12 +26,6 @@
26#include "kernel.h" 26#include "kernel.h"
27#include "x1000/tcu.h" 27#include "x1000/tcu.h"
28 28
29struct pwm_gpio_data {
30 int port;
31 unsigned pin;
32 int func;
33};
34
35struct pwm_state { 29struct pwm_state {
36 int period_ns; 30 int period_ns;
37 int duty_ns; 31 int duty_ns;
@@ -40,14 +34,6 @@ struct pwm_state {
40 int prescaler; 34 int prescaler;
41}; 35};
42 36
43static const struct pwm_gpio_data pwm_gpios[] = {
44 {GPIO_C, 1 << 25, GPIO_DEVICE(0)},
45 {GPIO_C, 1 << 26, GPIO_DEVICE(1)},
46 {GPIO_C, 1 << 27, GPIO_DEVICE(1)},
47 {GPIO_B, 1 << 6, GPIO_DEVICE(2)},
48 {GPIO_C, 1 << 24, GPIO_DEVICE(0)},
49};
50
51static struct pwm_state pwm_state[] = { 37static struct pwm_state pwm_state[] = {
52 {-1, -1, -1, -1, -1}, 38 {-1, -1, -1, -1, -1},
53 {-1, -1, -1, -1, -1}, 39 {-1, -1, -1, -1, -1},
@@ -56,6 +42,22 @@ static struct pwm_state pwm_state[] = {
56 {-1, -1, -1, -1, -1}, 42 {-1, -1, -1, -1, -1},
57}; 43};
58 44
45static const int pwm_gpio[] = {
46 GPIO_PC(25),
47 GPIO_PC(26),
48 GPIO_PC(27),
49 GPIO_PB(6),
50 GPIO_PC(24),
51};
52
53static const int pwm_gpio_func[] = {
54 GPIOF_DEVICE(0),
55 GPIOF_DEVICE(1),
56 GPIOF_DEVICE(1),
57 GPIOF_DEVICE(2),
58 GPIOF_DEVICE(0),
59};
60
59void pwm_init(int chn) 61void pwm_init(int chn)
60{ 62{
61 /* clear cached state */ 63 /* clear cached state */
@@ -67,8 +69,7 @@ void pwm_init(int chn)
67 st->prescaler = -1; 69 st->prescaler = -1;
68 70
69 /* clear GPIO and disable timer */ 71 /* clear GPIO and disable timer */
70 const struct pwm_gpio_data* pg = &pwm_gpios[chn]; 72 gpio_set_function(pwm_gpio[chn], GPIOF_OUTPUT(0));
71 gpio_config(pg->port, pg->pin, GPIO_OUTPUT(0));
72 jz_clr(TCU_STOP, 1 << chn); 73 jz_clr(TCU_STOP, 1 << chn);
73 jz_clr(TCU_ENABLE, 1 << chn); 74 jz_clr(TCU_ENABLE, 1 << chn);
74 jz_set(TCU_STOP, 1 << chn); 75 jz_set(TCU_STOP, 1 << chn);
@@ -161,15 +162,13 @@ void pwm_enable(int chn)
161 jz_set(TCU_ENABLE, 1 << chn); 162 jz_set(TCU_ENABLE, 1 << chn);
162 163
163 /* Configure GPIO function */ 164 /* Configure GPIO function */
164 const struct pwm_gpio_data* pg = &pwm_gpios[chn]; 165 gpio_set_function(pwm_gpio[chn], pwm_gpio_func[chn]);
165 gpio_config(pg->port, pg->pin, pg->func);
166} 166}
167 167
168void pwm_disable(int chn) 168void pwm_disable(int chn)
169{ 169{
170 /* Set GPIO to output 0 */ 170 /* Set GPIO to output 0 */
171 const struct pwm_gpio_data* pg = &pwm_gpios[chn]; 171 gpio_set_function(pwm_gpio[chn], GPIOF_OUTPUT(0));
172 gpio_config(pg->port, pg->pin, GPIO_OUTPUT(0));
173 172
174 /* Stop timer */ 173 /* Stop timer */
175 jz_clr(TCU_ENABLE, 1 << chn); 174 jz_clr(TCU_ENABLE, 1 << chn);
diff --git a/firmware/target/mips/ingenic_x1000/sd-x1000.c b/firmware/target/mips/ingenic_x1000/sd-x1000.c
index 7fba617ce3..679a25a222 100644
--- a/firmware/target/mips/ingenic_x1000/sd-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/sd-x1000.c
@@ -23,6 +23,7 @@
23#include "sdmmc.h" 23#include "sdmmc.h"
24#include "sd.h" 24#include "sd.h"
25#include "msc-x1000.h" 25#include "msc-x1000.h"
26#include "gpio-x1000.h"
26#include <string.h> 27#include <string.h>
27 28
28/* #define LOGF_ENABLE */ 29/* #define LOGF_ENABLE */
@@ -201,7 +202,7 @@ bool sd_removable(IF_MD_NONVOID(int drive))
201 if(drive < 0) 202 if(drive < 0)
202 return false; 203 return false;
203 204
204 return sd_to_msc[IF_MD_DRV(drive)]->config->cd_gpio.pin != 0; 205 return sd_to_msc[IF_MD_DRV(drive)]->config->cd_gpio != GPIO_NONE;
205} 206}
206 207
207#ifndef CONFIG_STORAGE_MULTI 208#ifndef CONFIG_STORAGE_MULTI
diff --git a/firmware/target/mips/ingenic_x1000/sfc-x1000.c b/firmware/target/mips/ingenic_x1000/sfc-x1000.c
index 3f1cb25f07..c1ffb6a5e1 100644
--- a/firmware/target/mips/ingenic_x1000/sfc-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/sfc-x1000.c
@@ -23,7 +23,6 @@
23#include "kernel.h" 23#include "kernel.h"
24#include "panic.h" 24#include "panic.h"
25#include "sfc-x1000.h" 25#include "sfc-x1000.h"
26#include "gpio-x1000.h"
27#include "irq-x1000.h" 26#include "irq-x1000.h"
28#include "x1000/sfc.h" 27#include "x1000/sfc.h"
29#include "x1000/cpm.h" 28#include "x1000/cpm.h"
@@ -75,7 +74,6 @@ void sfc_unlock(void)
75 74
76void sfc_open(void) 75void sfc_open(void)
77{ 76{
78 gpio_config(GPIO_A, 0x3f << 26, GPIO_DEVICE(1));
79 jz_writef(CPM_CLKGR, SFC(0)); 77 jz_writef(CPM_CLKGR, SFC(0));
80 jz_writef(SFC_GLB, OP_MODE_V(SLAVE), PHASE_NUM(1), 78 jz_writef(SFC_GLB, OP_MODE_V(SLAVE), PHASE_NUM(1),
81 THRESHOLD(FIFO_THRESH), WP_EN(1)); 79 THRESHOLD(FIFO_THRESH), WP_EN(1));
diff --git a/firmware/target/mips/ingenic_x1000/usb-x1000.c b/firmware/target/mips/ingenic_x1000/usb-x1000.c
index 32413b0b94..1cedac4fa7 100644
--- a/firmware/target/mips/ingenic_x1000/usb-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/usb-x1000.c
@@ -29,20 +29,9 @@
29#include "x1000/cpm.h" 29#include "x1000/cpm.h"
30 30
31#ifdef FIIO_M3K 31#ifdef FIIO_M3K
32# define USB_DETECT_PORT GPIO_B 32# define USB_DETECT_PIN_INT GPIOB11 // TODO remove me
33# define USB_DETECT_PIN (1 << 11)
34# define USB_DETECT_PIN_INT GPIOB11
35# define USB_ID_PORT GPIO_B
36# define USB_ID_PIN (1 << 7)
37#else
38# ifndef USB_NONE
39# error "please add USB GPIO pins"
40# endif
41#endif 33#endif
42 34
43#define USB_DRVVBUS_PORT GPIO_B
44#define USB_DRVVBUS_PIN (1 << 25)
45
46/* 35/*
47 * USB-Designware driver API 36 * USB-Designware driver API
48 */ 37 */
@@ -165,7 +154,8 @@ static volatile int usb_status = USB_EXTRACTED;
165 154
166static int __usb_detect(void) 155static int __usb_detect(void)
167{ 156{
168 if(REG_GPIO_PIN(USB_DETECT_PORT) & USB_DETECT_PIN) 157 /* XXX: Do we need an active level define for this? */
158 if(gpio_get_level(GPIO_USB_DETECT))
169 return USB_INSERTED; 159 return USB_INSERTED;
170 else 160 else
171 return USB_EXTRACTED; 161 return USB_EXTRACTED;
@@ -183,7 +173,7 @@ void usb_init_device(void)
183{ 173{
184 /* Disable drvvbus pin -- it is only used when acting as a host, 174 /* Disable drvvbus pin -- it is only used when acting as a host,
185 * which Rockbox does not support */ 175 * which Rockbox does not support */
186 gpio_config(USB_DRVVBUS_PORT, USB_DRVVBUS_PIN, GPIO_OUTPUT(0)); 176 gpio_set_function(GPIO_USB_DRVVBUS, GPIOF_OUTPUT(0));
187 177
188 /* Power up the core clocks to allow writing 178 /* Power up the core clocks to allow writing
189 to some registers needed to power it down */ 179 to some registers needed to power it down */
@@ -194,9 +184,9 @@ void usb_init_device(void)
194#ifdef USB_STATUS_BY_EVENT 184#ifdef USB_STATUS_BY_EVENT
195 /* Setup USB detect pin IRQ */ 185 /* Setup USB detect pin IRQ */
196 usb_status = __usb_detect(); 186 usb_status = __usb_detect();
197 int level = (REG_GPIO_PIN(USB_DETECT_PORT) & USB_DETECT_PIN) ? 1 : 0; 187 gpio_set_function(GPIO_USB_DETECT, GPIOF_IRQ_EDGE(1));
198 gpio_config(USB_DETECT_PORT, USB_DETECT_PIN, GPIO_IRQ_EDGE(level ? 0 : 1)); 188 gpio_flip_edge_irq(GPIO_USB_DETECT);
199 gpio_enable_irq(USB_DETECT_PORT, USB_DETECT_PIN); 189 gpio_enable_irq(GPIO_USB_DETECT);
200#endif 190#endif
201} 191}
202 192
@@ -215,7 +205,7 @@ void USB_DETECT_PIN_INT(void)
215{ 205{
216 /* Update status and flip the IRQ trigger edge */ 206 /* Update status and flip the IRQ trigger edge */
217 usb_status = __usb_detect(); 207 usb_status = __usb_detect();
218 REG_GPIO_PAT0(USB_DETECT_PORT) ^= USB_DETECT_PIN; 208 gpio_flip_edge_irq(GPIO_USB_DETECT);
219 209
220 /* Notify Rockbox of event */ 210 /* Notify Rockbox of event */
221 usb_status_event(usb_status); 211 usb_status_event(usb_status);