summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-02-27 12:35:05 +0000
committerDave Chapman <dave@dchapman.com>2006-02-27 12:35:05 +0000
commit285079138b0baa5cf03221f8abcdaaec8e35f112 (patch)
treee73ba981e762f781ce7a5ea2d5ba24b07a4b2292 /firmware/drivers
parent0bdf0c6342fe1529a1a2f7a9a5086d088f51bc19 (diff)
downloadrockbox-285079138b0baa5cf03221f8abcdaaec8e35f112.tar.gz
rockbox-285079138b0baa5cf03221f8abcdaaec8e35f112.zip
Patch #3060 from Andrew Scott - iPod mini button driver
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8857 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/button.c89
-rw-r--r--firmware/drivers/i2c-pp5020.c8
2 files changed, 95 insertions, 2 deletions
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c
index d5855506fc..0b41fb10fe 100644
--- a/firmware/drivers/button.c
+++ b/firmware/drivers/button.c
@@ -87,7 +87,9 @@ static bool remote_button_hold_only(void);
87#if CONFIG_KEYPAD == IPOD_4G_PAD 87#if CONFIG_KEYPAD == IPOD_4G_PAD
88/* Variable to use for setting button status in interrupt handler */ 88/* Variable to use for setting button status in interrupt handler */
89int int_btn = BUTTON_NONE; 89int int_btn = BUTTON_NONE;
90#endif
90 91
92#if (CONFIG_KEYPAD == IPOD_4G_PAD) && (!defined(APPLE_IPODMINI))
91static void opto_i2c_init(void) 93static void opto_i2c_init(void)
92{ 94{
93 int i, curr_value; 95 int i, curr_value;
@@ -240,7 +242,7 @@ void ipod_4g_button_int(void)
240 CPU_HI_INT_EN = I2C_MASK; 242 CPU_HI_INT_EN = I2C_MASK;
241} 243}
242#endif 244#endif
243#if CONFIG_KEYPAD == IPOD_3G_PAD 245#if (CONFIG_KEYPAD == IPOD_3G_PAD) || (defined(APPLE_IPODMINI))
244/** 246/**
245 * 247 *
246 * 248 *
@@ -291,7 +293,68 @@ void handle_scroll_wheel(int new_scroll, int was_hold, int reverse)
291 queue_post(&button_queue, wheel_keycode, NULL); 293 queue_post(&button_queue, wheel_keycode, NULL);
292 prev_scroll = new_scroll; 294 prev_scroll = new_scroll;
293} 295}
296#endif
297#if (CONFIG_KEYPAD == IPOD_4G_PAD) && (defined(APPLE_IPODMINI))
298static int ipod_mini_button_read(void)
299{
300 unsigned char source, wheel_source, state, wheel_state;
301 int btn = BUTTON_NONE;
302
303 /*
304 * we need some delay for mini, cause hold generates several interrupts,
305 * some of them delayed
306 */
307 udelay(250);
294 308
309 /* get source(s) of interupt */
310 source = GPIOA_INT_STAT & 0x3f;
311 wheel_source = GPIOB_INT_STAT & 0x30;
312
313 if (source == 0 && wheel_source == 0) {
314 return BUTTON_NONE; /* not for us */
315 }
316
317 /* get current keypad & wheel status */
318 state = GPIOA_INPUT_VAL & 0x3f;
319 wheel_state = GPIOB_INPUT_VAL & 0x30;
320
321 /* toggle interrupt level */
322 GPIOA_INT_LEV = ~state;
323 GPIOB_INT_LEV = ~wheel_state;
324
325 if (source & 0x1)
326 btn |= BUTTON_SELECT;
327 if (source & 0x2)
328 btn |= BUTTON_MENU;
329 if (source & 0x4)
330 btn |= BUTTON_PLAY;
331 if (source & 0x8)
332 btn |= BUTTON_RIGHT;
333 if (source & 0x10)
334 btn |= BUTTON_LEFT;
335
336 if (wheel_source & 0x30) {
337 handle_scroll_wheel((wheel_state & 0x30) >> 4, 0, 1);
338 }
339
340 /* ack any active interrupts */
341 if (source)
342 GPIOA_INT_CLR = source;
343 if (wheel_source)
344 GPIOB_INT_CLR = wheel_source;
345
346 return btn;
347}
348
349void ipod_mini_button_int(void)
350{
351 CPU_HI_INT_CLR = GPIO_MASK;
352 int_btn = ipod_mini_button_read();
353 //CPU_INT_EN = 0x40000000;
354 CPU_HI_INT_EN = GPIO_MASK;
355}
356#endif
357#if CONFIG_KEYPAD == IPOD_3G_PAD
295static int ipod_3g_button_read(void) 358static int ipod_3g_button_read(void)
296{ 359{
297 unsigned char source, state; 360 unsigned char source, state;
@@ -541,7 +604,7 @@ void button_init(void)
541 /* nothing to initialize here */ 604 /* nothing to initialize here */
542#elif CONFIG_KEYPAD == GMINI100_PAD 605#elif CONFIG_KEYPAD == GMINI100_PAD
543 /* nothing to initialize here */ 606 /* nothing to initialize here */
544#elif CONFIG_KEYPAD == IPOD_4G_PAD 607#elif (CONFIG_KEYPAD == IPOD_4G_PAD) && (!defined(APPLE_IPODMINI))
545 opto_i2c_init(); 608 opto_i2c_init();
546 /* hold button - enable as input */ 609 /* hold button - enable as input */
547 GPIOA_ENABLE |= 0x20; 610 GPIOA_ENABLE |= 0x20;
@@ -551,9 +614,31 @@ void button_init(void)
551 GPIOA_INT_CLR = GPIOA_INT_STAT & 0x20; 614 GPIOA_INT_CLR = GPIOA_INT_STAT & 0x20;
552 /* enable interrupts */ 615 /* enable interrupts */
553 GPIOA_INT_EN = 0x20; 616 GPIOA_INT_EN = 0x20;
617 /* unmask interrupt */
554 CPU_INT_EN = 0x40000000; 618 CPU_INT_EN = 0x40000000;
555 CPU_HI_INT_EN = I2C_MASK; 619 CPU_HI_INT_EN = I2C_MASK;
556 620
621#elif (CONFIG_KEYPAD == IPOD_4G_PAD) && (defined(APPLE_IPODMINI))
622 /* iPod Mini G1 */
623 /* buttons - enable as input */
624 GPIOA_ENABLE |= 0x3f;
625 GPIOA_OUTPUT_EN &= ~0x3f;
626 /* scroll wheel- enable as input */
627 GPIOB_ENABLE |= 0x30; /* port b 4,5 */
628 GPIOB_OUTPUT_EN &= ~0x30; /* port b 4,5 */
629 /* buttons - set interrupt levels */
630 GPIOA_INT_LEV = ~(GPIOA_INPUT_VAL & 0x3f);
631 GPIOA_INT_CLR = GPIOA_INT_STAT & 0x3f;
632 /* scroll wheel - set interrupt levels */
633 GPIOB_INT_LEV = ~(GPIOB_INPUT_VAL & 0x3f);
634 GPIOB_INT_CLR = GPIOB_INT_STAT & 0x3f;
635 /* enable interrupts */
636 GPIOA_INT_EN = 0x3f;
637 GPIOB_INT_EN = 0x30;
638 /* unmask interrupt */
639 CPU_INT_EN = 0x40000000;
640 CPU_HI_INT_EN = GPIO_MASK;
641
557#elif CONFIG_KEYPAD == IPOD_3G_PAD 642#elif CONFIG_KEYPAD == IPOD_3G_PAD
558 GPIOA_INT_LEV = ~GPIOA_INPUT_VAL; 643 GPIOA_INT_LEV = ~GPIOA_INPUT_VAL;
559 GPIOA_INT_CLR = GPIOA_INT_STAT; 644 GPIOA_INT_CLR = GPIOA_INT_STAT;
diff --git a/firmware/drivers/i2c-pp5020.c b/firmware/drivers/i2c-pp5020.c
index fccaffc571..9f26d3be6e 100644
--- a/firmware/drivers/i2c-pp5020.c
+++ b/firmware/drivers/i2c-pp5020.c
@@ -161,6 +161,14 @@ void i2c_init(void)
161{ 161{
162 /* From ipodlinux */ 162 /* From ipodlinux */
163 163
164#if defined(APPLE_IPODMINI)
165 /* GPIO port C disable port 0x10 */
166 GPIOC_ENABLE &= ~0x10;
167
168 /* GPIO port C disable port 0x20 */
169 GPIOC_ENABLE &= ~0x20;
170#endif
171
164 outl(inl(0x6000600c) | 0x1000, 0x6000600c); /* enable 12 */ 172 outl(inl(0x6000600c) | 0x1000, 0x6000600c); /* enable 12 */
165 outl(inl(0x60006004) | 0x1000, 0x60006004); /* start reset 12 */ 173 outl(inl(0x60006004) | 0x1000, 0x60006004); /* start reset 12 */
166 outl(inl(0x60006004) & ~0x1000, 0x60006004); /* end reset 12 */ 174 outl(inl(0x60006004) & ~0x1000, 0x60006004); /* end reset 12 */