diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2019-01-03 20:46:54 -0500 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2019-01-04 23:52:42 +0100 |
commit | d24edc605b9b52d3610efbb9cf691c437ea00746 (patch) | |
tree | bd8e6119e4611c6ff83bd316816e0b9534d84deb /firmware | |
parent | 100f4338deea5239423a0b8974784939d520385c (diff) | |
download | rockbox-d24edc605b9b52d3610efbb9cf691c437ea00746.tar.gz rockbox-d24edc605b9b52d3610efbb9cf691c437ea00746.zip |
Add HAVE_LINEOUT_DETECTION and associated logic
This allows targets to automatically switch audio settings when the
line out is plugged/unplugged.
Only hooked up on the xDuoo X3, but there are other potential users.
Change-Id: Ic46a329bc955cca2e2ad0335ca16295eab24ad59
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/button.c | 52 | ||||
-rw-r--r-- | firmware/export/button.h | 5 | ||||
-rw-r--r-- | firmware/export/config/xduoox3.h | 3 | ||||
-rw-r--r-- | firmware/kernel/include/queue.h | 2 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/codec-jz4760.c | 32 | ||||
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c | 11 |
6 files changed, 83 insertions, 22 deletions
diff --git a/firmware/drivers/button.c b/firmware/drivers/button.c index 64668b4ebf..608fe7e33a 100644 --- a/firmware/drivers/button.c +++ b/firmware/drivers/button.c | |||
@@ -59,6 +59,9 @@ static bool remote_filter_first_keypress; | |||
59 | #ifdef HAVE_HEADPHONE_DETECTION | 59 | #ifdef HAVE_HEADPHONE_DETECTION |
60 | static bool phones_present = false; | 60 | static bool phones_present = false; |
61 | #endif | 61 | #endif |
62 | #ifdef HAVE_LINEOUT_DETECTION | ||
63 | static bool lineout_present = false; | ||
64 | #endif | ||
62 | 65 | ||
63 | /* how long until repeat kicks in, in centiseconds */ | 66 | /* how long until repeat kicks in, in centiseconds */ |
64 | #define REPEAT_START (30*HZ/100) | 67 | #define REPEAT_START (30*HZ/100) |
@@ -94,12 +97,11 @@ static int button_read(void); | |||
94 | 97 | ||
95 | #ifdef HAVE_TOUCHSCREEN | 98 | #ifdef HAVE_TOUCHSCREEN |
96 | static int last_touchscreen_touch; | 99 | static int last_touchscreen_touch; |
97 | #endif | 100 | #endif |
98 | #if defined(HAVE_HEADPHONE_DETECTION) | 101 | #if defined(HAVE_HEADPHONE_DETECTION) |
99 | static struct timeout hp_detect_timeout; /* Debouncer for headphone plug/unplug */ | 102 | static struct timeout hp_detect_timeout; /* Debouncer for headphone plug/unplug */ |
100 | /* This callback can be used for many different functions if needed - | 103 | |
101 | just check to which object tmo points */ | 104 | static int hp_detect_callback(struct timeout *tmo) |
102 | static int btn_detect_callback(struct timeout *tmo) | ||
103 | { | 105 | { |
104 | /* Try to post only transistions */ | 106 | /* Try to post only transistions */ |
105 | const long id = tmo->data ? SYS_PHONE_PLUGGED : SYS_PHONE_UNPLUGGED; | 107 | const long id = tmo->data ? SYS_PHONE_PLUGGED : SYS_PHONE_UNPLUGGED; |
@@ -109,6 +111,19 @@ static int btn_detect_callback(struct timeout *tmo) | |||
109 | } | 111 | } |
110 | #endif | 112 | #endif |
111 | 113 | ||
114 | #if defined(HAVE_LINEOUT_DETECTION) | ||
115 | static struct timeout lo_detect_timeout; /* Debouncer for lineout plug/unplug */ | ||
116 | |||
117 | static int lo_detect_callback(struct timeout *tmo) | ||
118 | { | ||
119 | /* Try to post only transistions */ | ||
120 | const long id = tmo->data ? SYS_LINEOUT_PLUGGED : SYS_LINEOUT_UNPLUGGED; | ||
121 | queue_remove_from_head(&button_queue, id); | ||
122 | queue_post(&button_queue, id, 0); | ||
123 | return 0; | ||
124 | } | ||
125 | #endif | ||
126 | |||
112 | static bool button_try_post(int button, int data) | 127 | static bool button_try_post(int button, int data) |
113 | { | 128 | { |
114 | #ifdef HAVE_TOUCHSCREEN | 129 | #ifdef HAVE_TOUCHSCREEN |
@@ -176,10 +191,19 @@ static void button_tick(void) | |||
176 | { | 191 | { |
177 | /* Use the autoresetting oneshot to debounce the detection signal */ | 192 | /* Use the autoresetting oneshot to debounce the detection signal */ |
178 | phones_present = !phones_present; | 193 | phones_present = !phones_present; |
179 | timeout_register(&hp_detect_timeout, btn_detect_callback, | 194 | timeout_register(&hp_detect_timeout, hp_detect_callback, |
180 | HZ/2, phones_present); | 195 | HZ/2, phones_present); |
181 | } | 196 | } |
182 | #endif | 197 | #endif |
198 | #if defined(HAVE_LINEOUT_DETECTION) | ||
199 | if (lineout_inserted() != lineout_present) | ||
200 | { | ||
201 | /* Use the autoresetting oneshot to debounce the detection signal */ | ||
202 | lineout_present = !lineout_present; | ||
203 | timeout_register(&lo_detect_timeout, lo_detect_callback, | ||
204 | HZ/2, lineout_present); | ||
205 | } | ||
206 | #endif | ||
183 | 207 | ||
184 | /* Find out if a key has been released */ | 208 | /* Find out if a key has been released */ |
185 | diff = btn ^ lastbtn; | 209 | diff = btn ^ lastbtn; |
@@ -318,7 +342,7 @@ static void button_tick(void) | |||
318 | #ifdef HAVE_BACKLIGHT | 342 | #ifdef HAVE_BACKLIGHT |
319 | #ifdef HAVE_REMOTE_LCD | 343 | #ifdef HAVE_REMOTE_LCD |
320 | if (btn & BUTTON_REMOTE) { | 344 | if (btn & BUTTON_REMOTE) { |
321 | if (!remote_filter_first_keypress | 345 | if (!remote_filter_first_keypress |
322 | || is_remote_backlight_on(false) | 346 | || is_remote_backlight_on(false) |
323 | #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) | 347 | #if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) |
324 | || (remote_type()==REMOTETYPE_H300_NONLCD) | 348 | || (remote_type()==REMOTETYPE_H300_NONLCD) |
@@ -427,7 +451,7 @@ static void button_queue_wait(struct queue_event *evp, int timeout) | |||
427 | #endif | 451 | #endif |
428 | button_boost(true); | 452 | button_boost(true); |
429 | 453 | ||
430 | break; | 454 | break; |
431 | } | 455 | } |
432 | 456 | ||
433 | if (button_boosted && TIME_AFTER(current_tick, button_unboost_tick)) | 457 | if (button_boosted && TIME_AFTER(current_tick, button_unboost_tick)) |
@@ -462,7 +486,7 @@ long button_get(bool block) | |||
462 | 486 | ||
463 | long button_get_w_tmo(int ticks) | 487 | long button_get_w_tmo(int ticks) |
464 | { | 488 | { |
465 | struct queue_event ev; | 489 | struct queue_event ev; |
466 | button_queue_wait(&ev, ticks); | 490 | button_queue_wait(&ev, ticks); |
467 | 491 | ||
468 | if (ev.id == SYS_TIMEOUT) | 492 | if (ev.id == SYS_TIMEOUT) |
@@ -496,7 +520,7 @@ void button_init(void) | |||
496 | button_read(); | 520 | button_read(); |
497 | lastbtn = button_read(); | 521 | lastbtn = button_read(); |
498 | #endif | 522 | #endif |
499 | 523 | ||
500 | reset_poweroff_timer(); | 524 | reset_poweroff_timer(); |
501 | 525 | ||
502 | #ifdef HAVE_LCD_BITMAP | 526 | #ifdef HAVE_LCD_BITMAP |
@@ -506,11 +530,11 @@ void button_init(void) | |||
506 | filter_first_keypress = false; | 530 | filter_first_keypress = false; |
507 | #ifdef HAVE_REMOTE_LCD | 531 | #ifdef HAVE_REMOTE_LCD |
508 | remote_filter_first_keypress = false; | 532 | remote_filter_first_keypress = false; |
509 | #endif | 533 | #endif |
510 | #endif | 534 | #endif |
511 | #ifdef HAVE_TOUCHSCREEN | 535 | #ifdef HAVE_TOUCHSCREEN |
512 | last_touchscreen_touch = 0xffff; | 536 | last_touchscreen_touch = 0xffff; |
513 | #endif | 537 | #endif |
514 | /* Start polling last */ | 538 | /* Start polling last */ |
515 | tick_add_task(button_tick); | 539 | tick_add_task(button_tick); |
516 | } | 540 | } |
@@ -647,7 +671,7 @@ static int button_read(void) | |||
647 | #ifdef HAVE_TOUCHSCREEN | 671 | #ifdef HAVE_TOUCHSCREEN |
648 | if (btn & BUTTON_TOUCHSCREEN) | 672 | if (btn & BUTTON_TOUCHSCREEN) |
649 | last_touchscreen_touch = current_tick; | 673 | last_touchscreen_touch = current_tick; |
650 | #endif | 674 | #endif |
651 | /* Filter the button status. It is only accepted if we get the same | 675 | /* Filter the button status. It is only accepted if we get the same |
652 | status twice in a row. */ | 676 | status twice in a row. */ |
653 | #ifndef HAVE_TOUCHSCREEN | 677 | #ifndef HAVE_TOUCHSCREEN |
@@ -696,8 +720,8 @@ int touchscreen_last_touch(void) | |||
696 | * [23:0] Velocity - degree/sec | 720 | * [23:0] Velocity - degree/sec |
697 | * | 721 | * |
698 | * WHEEL_ACCEL_FACTOR: | 722 | * WHEEL_ACCEL_FACTOR: |
699 | * Value in degree/sec -- configurable via settings -- above which | 723 | * Value in degree/sec -- configurable via settings -- above which |
700 | * the accelerated scrolling starts. Factor is internally scaled by | 724 | * the accelerated scrolling starts. Factor is internally scaled by |
701 | * 1<<16 in respect to the following 32bit integer operations. | 725 | * 1<<16 in respect to the following 32bit integer operations. |
702 | */ | 726 | */ |
703 | int button_apply_acceleration(const unsigned int data) | 727 | int button_apply_acceleration(const unsigned int data) |
diff --git a/firmware/export/button.h b/firmware/export/button.h index 7109c00f97..d9732ebe8b 100644 --- a/firmware/export/button.h +++ b/firmware/export/button.h | |||
@@ -44,7 +44,7 @@ int button_read_device(void); | |||
44 | #ifdef HAS_BUTTON_HOLD | 44 | #ifdef HAS_BUTTON_HOLD |
45 | bool button_hold(void); | 45 | bool button_hold(void); |
46 | #endif | 46 | #endif |
47 | #ifdef HAS_REMOTE_BUTTON_HOLD | 47 | #ifdef HAS_REMOTE_BUTTON_HOLD |
48 | bool remote_button_hold(void); | 48 | bool remote_button_hold(void); |
49 | #endif | 49 | #endif |
50 | 50 | ||
@@ -72,6 +72,9 @@ void set_remote_backlight_filter_keypress(bool value); | |||
72 | #ifdef HAVE_HEADPHONE_DETECTION | 72 | #ifdef HAVE_HEADPHONE_DETECTION |
73 | bool headphones_inserted(void); | 73 | bool headphones_inserted(void); |
74 | #endif | 74 | #endif |
75 | #ifdef HAVE_LINEOUT_DETECTION | ||
76 | bool lineout_inserted(void); | ||
77 | #endif | ||
75 | #ifdef HAVE_WHEEL_POSITION | 78 | #ifdef HAVE_WHEEL_POSITION |
76 | int wheel_status(void); | 79 | int wheel_status(void); |
77 | void wheel_send_events(bool send); | 80 | void wheel_send_events(bool send); |
diff --git a/firmware/export/config/xduoox3.h b/firmware/export/config/xduoox3.h index d4d6f2ee2f..b2c8930531 100644 --- a/firmware/export/config/xduoox3.h +++ b/firmware/export/config/xduoox3.h | |||
@@ -73,6 +73,9 @@ | |||
73 | /* Define this if you can detect headphones */ | 73 | /* Define this if you can detect headphones */ |
74 | #define HAVE_HEADPHONE_DETECTION | 74 | #define HAVE_HEADPHONE_DETECTION |
75 | 75 | ||
76 | /* Define this if you can detect lineout */ | ||
77 | #define HAVE_LINEOUT_DETECTION | ||
78 | |||
76 | #define CONFIG_KEYPAD XDUOO_X3_PAD | 79 | #define CONFIG_KEYPAD XDUOO_X3_PAD |
77 | 80 | ||
78 | /* Define this if a programmable hotkey is mapped */ | 81 | /* Define this if a programmable hotkey is mapped */ |
diff --git a/firmware/kernel/include/queue.h b/firmware/kernel/include/queue.h index afee4c90ff..515a7e43a8 100644 --- a/firmware/kernel/include/queue.h +++ b/firmware/kernel/include/queue.h | |||
@@ -65,6 +65,8 @@ | |||
65 | #define SYS_PHONE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 3) | 65 | #define SYS_PHONE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 3) |
66 | #define SYS_REMOTE_PLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 4) | 66 | #define SYS_REMOTE_PLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 4) |
67 | #define SYS_REMOTE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 5) | 67 | #define SYS_REMOTE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 5) |
68 | #define SYS_LINEOUT_PLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 6) | ||
69 | #define SYS_LINEOUT_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 7) | ||
68 | #define SYS_CAR_ADAPTER_RESUME MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0) | 70 | #define SYS_CAR_ADAPTER_RESUME MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0) |
69 | #define SYS_CALL_INCOMING MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 3) | 71 | #define SYS_CALL_INCOMING MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 3) |
70 | #define SYS_CALL_HUNG_UP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 4) | 72 | #define SYS_CALL_HUNG_UP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 4) |
diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4760.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4760.c index 09d4858b34..a2de80a914 100644 --- a/firmware/target/mips/ingenic_jz47xx/codec-jz4760.c +++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4760.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "pcm_sw_volume.h" | 26 | #include "pcm_sw_volume.h" |
27 | #include "cs4398.h" | 27 | #include "cs4398.h" |
28 | #include "kernel.h" | 28 | #include "kernel.h" |
29 | #include "button.h" | ||
29 | 30 | ||
30 | #define PIN_CS_RST (32*1+10) | 31 | #define PIN_CS_RST (32*1+10) |
31 | #define PIN_CODEC_PWRON (32*1+13) | 32 | #define PIN_CODEC_PWRON (32*1+13) |
@@ -140,7 +141,11 @@ static int vol_tenthdb2hw(const int tdb) | |||
140 | } | 141 | } |
141 | } | 142 | } |
142 | 143 | ||
143 | void audiohw_set_volume(int vol_l, int vol_r) | 144 | #ifdef HAVE_LINEOUT_DETECTION |
145 | static int real_vol_l, real_vol_r; | ||
146 | #endif | ||
147 | |||
148 | static void jz4760_set_vol(int vol_l, int vol_r) | ||
144 | { | 149 | { |
145 | uint8_t val = cs4398_read_reg(CS4398_REG_MISC) &~ CS4398_FREEZE; | 150 | uint8_t val = cs4398_read_reg(CS4398_REG_MISC) &~ CS4398_FREEZE; |
146 | cs4398_write_reg(CS4398_REG_MISC, val | CS4398_FREEZE); | 151 | cs4398_write_reg(CS4398_REG_MISC, val | CS4398_FREEZE); |
@@ -149,14 +154,31 @@ void audiohw_set_volume(int vol_l, int vol_r) | |||
149 | cs4398_write_reg(CS4398_REG_MISC, val); | 154 | cs4398_write_reg(CS4398_REG_MISC, val); |
150 | } | 155 | } |
151 | 156 | ||
157 | void audiohw_set_volume(int vol_l, int vol_r) | ||
158 | { | ||
159 | #ifdef HAVE_LINEOUT_DETECTION | ||
160 | real_vol_l = vol_l; | ||
161 | real_vol_r = vol_r; | ||
162 | |||
163 | if (lineout_inserted()) { | ||
164 | vol_l = 0; | ||
165 | vol_r = 0; | ||
166 | } | ||
167 | #endif | ||
168 | jz4760_set_vol(vol_l, vol_r); | ||
169 | } | ||
170 | |||
152 | void audiohw_set_lineout_volume(int vol_l, int vol_r) | 171 | void audiohw_set_lineout_volume(int vol_l, int vol_r) |
153 | { | 172 | { |
154 | #if 0 /* unused */ | ||
155 | cs4398_write_reg(CS4398_REG_VOL_A, vol_tenthdb2hw(vol_l)); | ||
156 | cs4398_write_reg(CS4398_REG_VOL_B, vol_tenthdb2hw(vol_r)); | ||
157 | #else | ||
158 | (void)vol_l; | 173 | (void)vol_l; |
159 | (void)vol_r; | 174 | (void)vol_r; |
175 | |||
176 | #ifdef HAVE_LINEOUT_DETECTION | ||
177 | if (lineout_inserted()) { | ||
178 | jz4760_set_vol(0, 0); | ||
179 | } else { | ||
180 | jz4760_set_vol(real_vol_l, real_vol_r); | ||
181 | } | ||
160 | #endif | 182 | #endif |
161 | } | 183 | } |
162 | 184 | ||
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c index be02167a5d..d227255b8a 100644 --- a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c +++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c | |||
@@ -53,6 +53,13 @@ bool headphones_inserted(void) | |||
53 | return (__gpio_get_pin(PIN_PH_DECT) != 0); | 53 | return (__gpio_get_pin(PIN_PH_DECT) != 0); |
54 | } | 54 | } |
55 | 55 | ||
56 | bool lineout_inserted(void) | ||
57 | { | ||
58 | /* We want to prevent LO being "enabled" if HP is attached | ||
59 | to avoid potential eardrum damage */ | ||
60 | return (__gpio_get_pin(PIN_LO_DECT) == 0) && !headphones_inserted(); | ||
61 | } | ||
62 | |||
56 | void button_init_device(void) | 63 | void button_init_device(void) |
57 | { | 64 | { |
58 | key_val = 0xfff; | 65 | key_val = 0xfff; |
@@ -72,11 +79,11 @@ void button_init_device(void) | |||
72 | __gpio_set_pin(PIN_CHARGE_CON); /* 0.7 A */ | 79 | __gpio_set_pin(PIN_CHARGE_CON); /* 0.7 A */ |
73 | __gpio_as_output(PIN_CHARGE_CON); | 80 | __gpio_as_output(PIN_CHARGE_CON); |
74 | 81 | ||
75 | __gpio_as_input(PIN_LO_DECT); | ||
76 | __gpio_as_input(PIN_PH_DECT); | 82 | __gpio_as_input(PIN_PH_DECT); |
83 | __gpio_disable_pull(PIN_PH_DECT); | ||
77 | 84 | ||
85 | __gpio_as_input(PIN_LO_DECT); | ||
78 | __gpio_disable_pull(PIN_LO_DECT); | 86 | __gpio_disable_pull(PIN_LO_DECT); |
79 | __gpio_disable_pull(PIN_PH_DECT); | ||
80 | } | 87 | } |
81 | 88 | ||
82 | bool button_hold(void) | 89 | bool button_hold(void) |