1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (c) 2009 by Michael Sevakis
12 * Driver to handle headphone jack events
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
22 ****************************************************************************/
28 #include "mc13783-target.h"
32 static struct wakeup headphone_wakeup
;
33 static unsigned int headphone_thread_id
;
34 static int headphone_stack
[200/sizeof(int)]; /* Not much stack needed */
35 static const char * const headphone_thread_name
= "headphone";
36 static bool headphones_detect
= false;
38 /* Convert ADC reading into a button value. */
39 static int adc_data_to_button(unsigned int data
)
41 int btn
= BUTTON_NONE
;
54 /* else headphone direct */
83 btn
= BUTTON_RC_VOL_UP
;
88 btn
= BUTTON_RC_VOL_DOWN
;
111 static void headphone_thread(void)
113 int headphone_sleep_countdown
= 0;
114 int headphone_wait_timeout
= TIMEOUT_BLOCK
;
118 int rc
= wakeup_wait(&headphone_wakeup
, headphone_wait_timeout
);
119 unsigned int data
= adc_read(ADC_HPREMOTE
);
121 if (rc
== OBJ_WAIT_TIMEDOUT
)
123 if (headphone_sleep_countdown
<= 0)
128 btn
= adc_data_to_button(data
);
130 data
= adc_read(ADC_HPREMOTE
);
131 btn2
= adc_data_to_button(data
);
135 /* If the buttons dont agree twice in a row, then it's
136 * none (from meg-fx remote reader). */
140 button_headphone_set(btn
);
144 if (--headphone_sleep_countdown
== 0)
146 /* Nothing has changed and remote is not present -
148 headphone_wait_timeout
= TIMEOUT_BLOCK
;
153 headphones_detect
= data
<= 951; /* Max remote value */
155 /* Cancel any buttons if jack readings are unstable. */
156 button_headphone_set(BUTTON_NONE
);
158 if (data
>= 64 && data
<= 951)
160 /* Should be a remote control - accelerate */
161 headphone_wait_timeout
= HZ
/20-HZ
/50;
162 headphone_sleep_countdown
= 0;
164 else if (rc
== OBJ_WAIT_SUCCEEDED
)
166 /* Got signaled - something is being plugged/unplugged. Set
167 * countdown until we just give up and go to sleep (~10s). */
168 headphone_wait_timeout
= HZ
/2;
169 headphone_sleep_countdown
= 10*2;
174 /* This is called from the mc13783 interrupt thread */
175 void headphone_detect_event(void)
177 /* Trigger the thread immediately. */
178 wakeup_signal(&headphone_wakeup
);
181 /* Tell if anything is in the jack. */
182 bool headphones_inserted(void)
184 return headphones_detect
;
187 void INIT_ATTR
headphone_init(void)
189 /* A thread is required to monitor the remote ADC and jack state. */
190 wakeup_init(&headphone_wakeup
);
191 headphone_thread_id
= create_thread(headphone_thread
,
193 sizeof(headphone_stack
),
194 0, headphone_thread_name
195 IF_PRIO(, PRIORITY_REALTIME
)
198 /* Initially poll and then enable PMIC event */
199 headphone_detect_event();
200 mc13783_enable_event(MC13783_ONOFD2_EVENT
);