diff options
Diffstat (limited to 'firmware/target/arm/ipod/button-clickwheel.c')
-rw-r--r-- | firmware/target/arm/ipod/button-clickwheel.c | 97 |
1 files changed, 33 insertions, 64 deletions
diff --git a/firmware/target/arm/ipod/button-clickwheel.c b/firmware/target/arm/ipod/button-clickwheel.c index f01666a8b8..f8dd818a01 100644 --- a/firmware/target/arm/ipod/button-clickwheel.c +++ b/firmware/target/arm/ipod/button-clickwheel.c | |||
@@ -73,64 +73,40 @@ int int_btn = BUTTON_NONE; | |||
73 | 73 | ||
74 | static void opto_i2c_init(void) | 74 | static void opto_i2c_init(void) |
75 | { | 75 | { |
76 | int i, curr_value; | 76 | DEV_EN |= DEV_OPTO; |
77 | 77 | DEV_RS |= DEV_OPTO; | |
78 | /* wait for value to settle */ | ||
79 | i = 1000; | ||
80 | curr_value = (inl(0x7000c104) << 16) >> 24; | ||
81 | while (i > 0) | ||
82 | { | ||
83 | int new_value = (inl(0x7000c104) << 16) >> 24; | ||
84 | |||
85 | if (new_value != curr_value) { | ||
86 | i = 10000; | ||
87 | curr_value = new_value; | ||
88 | } | ||
89 | else { | ||
90 | i--; | ||
91 | } | ||
92 | } | ||
93 | |||
94 | GPIOB_OUTPUT_VAL |= 0x10; | ||
95 | DEV_EN |= 0x10000; | ||
96 | DEV_RS |= 0x10000; | ||
97 | udelay(5); | 78 | udelay(5); |
98 | DEV_RS &= ~0x10000; /* finish reset */ | 79 | DEV_RS &= ~DEV_OPTO; /* finish reset */ |
80 | DEV_INIT1 |= INIT_BUTTONS; /* enable buttons (needed for "hold"-detection) */ | ||
99 | 81 | ||
100 | outl(0xffffffff, 0x7000c120); | ||
101 | outl(0xffffffff, 0x7000c124); | ||
102 | outl(0xc00a1f00, 0x7000c100); | 82 | outl(0xc00a1f00, 0x7000c100); |
103 | outl(0x1000000, 0x7000c104); | 83 | outl(0x01000000, 0x7000c104); |
104 | } | 84 | } |
105 | 85 | ||
106 | static inline int ipod_4g_button_read(void) | 86 | static inline int ipod_4g_button_read(void) |
107 | { | 87 | { |
108 | int whl = -1; | 88 | int whl = -1; |
89 | int btn = BUTTON_NONE; | ||
109 | 90 | ||
110 | /* The ipodlinux source had a udelay(250) here, but testing has shown that | 91 | /* The following delay was 250 in the ipodlinux source, but 50 seems to |
111 | it is not needed - tested on Nano, Color/Photo and Video. */ | 92 | work fine - tested on Nano, Color/Photo and Video. */ |
112 | /* udelay(250);*/ | 93 | udelay(50); |
113 | 94 | ||
114 | int btn = BUTTON_NONE; | 95 | if ((inl(0x7000c104) & 0x04000000) != 0) |
115 | unsigned reg = 0x7000c104; | ||
116 | if ((inl(0x7000c104) & 0x4000000) != 0) | ||
117 | { | 96 | { |
118 | unsigned status = inl(0x7000c140); | 97 | unsigned status = inl(0x7000c140); |
119 | 98 | ||
120 | reg = reg + 0x3C; /* 0x7000c140 */ | ||
121 | outl(0x0, 0x7000c140); /* clear interrupt status? */ | ||
122 | |||
123 | if ((status & 0x800000ff) == 0x8000001a) | 99 | if ((status & 0x800000ff) == 0x8000001a) |
124 | { | 100 | { |
125 | if (status & 0x100) | 101 | if (status & 0x00000100) |
126 | btn |= BUTTON_SELECT; | 102 | btn |= BUTTON_SELECT; |
127 | if (status & 0x200) | 103 | if (status & 0x00000200) |
128 | btn |= BUTTON_RIGHT; | 104 | btn |= BUTTON_RIGHT; |
129 | if (status & 0x400) | 105 | if (status & 0x00000400) |
130 | btn |= BUTTON_LEFT; | 106 | btn |= BUTTON_LEFT; |
131 | if (status & 0x800) | 107 | if (status & 0x00000800) |
132 | btn |= BUTTON_PLAY; | 108 | btn |= BUTTON_PLAY; |
133 | if (status & 0x1000) | 109 | if (status & 0x00001000) |
134 | btn |= BUTTON_MENU; | 110 | btn |= BUTTON_MENU; |
135 | if (status & 0x40000000) | 111 | if (status & 0x40000000) |
136 | { | 112 | { |
@@ -263,19 +239,10 @@ static inline int ipod_4g_button_read(void) | |||
263 | } | 239 | } |
264 | 240 | ||
265 | } | 241 | } |
266 | else if (status == 0xffffffff) | ||
267 | { | ||
268 | opto_i2c_init(); | ||
269 | } | ||
270 | } | 242 | } |
271 | 243 | ||
272 | if ((inl(reg) & 0x8000000) != 0) | ||
273 | { | ||
274 | outl(0xffffffff, 0x7000c120); | ||
275 | outl(0xffffffff, 0x7000c124); | ||
276 | } | ||
277 | /* Save the new absolute wheel position */ | ||
278 | #ifdef HAVE_WHEEL_POSITION | 244 | #ifdef HAVE_WHEEL_POSITION |
245 | /* Save the new absolute wheel position */ | ||
279 | wheel_position = whl; | 246 | wheel_position = whl; |
280 | #endif | 247 | #endif |
281 | return btn; | 248 | return btn; |
@@ -296,16 +263,12 @@ void wheel_send_events(bool send) | |||
296 | void ipod_4g_button_int(void) | 263 | void ipod_4g_button_int(void) |
297 | { | 264 | { |
298 | CPU_HI_INT_CLR = I2C_MASK; | 265 | CPU_HI_INT_CLR = I2C_MASK; |
299 | /* The following delay was 250 in the ipodlinux source, but 50 seems to | 266 | |
300 | work fine - tested on Nano, Color/Photo and Video. */ | ||
301 | udelay(50); | ||
302 | outl(0x0, 0x7000c140); | ||
303 | int_btn = ipod_4g_button_read(); | 267 | int_btn = ipod_4g_button_read(); |
304 | outl(inl(0x7000c104) | 0xC000000, 0x7000c104); | 268 | |
269 | outl(inl(0x7000c104) | 0x0c000000, 0x7000c104); | ||
305 | outl(0x400a1f00, 0x7000c100); | 270 | outl(0x400a1f00, 0x7000c100); |
306 | 271 | ||
307 | GPIOB_OUTPUT_VAL |= 0x10; | ||
308 | CPU_INT_EN = 0x40000000; | ||
309 | CPU_HI_INT_EN = I2C_MASK; | 272 | CPU_HI_INT_EN = I2C_MASK; |
310 | } | 273 | } |
311 | 274 | ||
@@ -317,15 +280,8 @@ void button_init_device(void) | |||
317 | GPIOA_ENABLE |= 0x20; | 280 | GPIOA_ENABLE |= 0x20; |
318 | GPIOA_OUTPUT_EN &= ~0x20; | 281 | GPIOA_OUTPUT_EN &= ~0x20; |
319 | 282 | ||
320 | /* hold button - set interrupt levels */ | ||
321 | GPIOA_INT_LEV = ~(GPIOA_INPUT_VAL & 0x20); | ||
322 | GPIOA_INT_CLR = GPIOA_INT_STAT & 0x20; | ||
323 | |||
324 | /* enable interrupts */ | ||
325 | GPIOA_INT_EN = 0x20; | ||
326 | |||
327 | /* unmask interrupt */ | 283 | /* unmask interrupt */ |
328 | CPU_INT_EN = 0x40000000; | 284 | CPU_INT_EN = HI_MASK; |
329 | CPU_HI_INT_EN = I2C_MASK; | 285 | CPU_HI_INT_EN = I2C_MASK; |
330 | } | 286 | } |
331 | 287 | ||
@@ -342,7 +298,20 @@ int button_read_device(void) | |||
342 | hold_button = button_hold(); | 298 | hold_button = button_hold(); |
343 | 299 | ||
344 | if (hold_button != hold_button_old) | 300 | if (hold_button != hold_button_old) |
301 | { | ||
345 | backlight_hold_changed(hold_button); | 302 | backlight_hold_changed(hold_button); |
303 | |||
304 | if (hold_button) | ||
305 | { | ||
306 | /* lock -> disable wheel sensor */ | ||
307 | DEV_EN &= ~DEV_OPTO; | ||
308 | } | ||
309 | else | ||
310 | { | ||
311 | /* unlock -> enable wheel sensor */ | ||
312 | DEV_EN |= DEV_OPTO; | ||
313 | } | ||
314 | } | ||
346 | 315 | ||
347 | /* The int_btn variable is set in the button interrupt handler */ | 316 | /* The int_btn variable is set in the button interrupt handler */ |
348 | return int_btn; | 317 | return int_btn; |