mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
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
This commit is contained in:
parent
100f4338de
commit
d24edc605b
7 changed files with 110 additions and 28 deletions
27
apps/misc.c
27
apps/misc.c
|
@ -521,7 +521,7 @@ void car_adapter_mode_init(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_HEADPHONE_DETECTION
|
#ifdef HAVE_HEADPHONE_DETECTION
|
||||||
static void unplug_change(bool inserted)
|
static void hp_unplug_change(bool inserted)
|
||||||
{
|
{
|
||||||
static bool headphone_caused_pause = false;
|
static bool headphone_caused_pause = false;
|
||||||
|
|
||||||
|
@ -553,6 +553,18 @@ static void unplug_change(bool inserted)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LINEOUT_DETECTION
|
||||||
|
static void lo_unplug_change(bool inserted)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LINEOUT_POWEROFF
|
||||||
|
lineout_set(inserted);
|
||||||
|
#else
|
||||||
|
(void)inserted;
|
||||||
|
audiohw_set_lineout_volume(0,0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
long default_event_handler_ex(long event, void (*callback)(void *), void *parameter)
|
long default_event_handler_ex(long event, void (*callback)(void *), void *parameter)
|
||||||
{
|
{
|
||||||
#if CONFIG_PLATFORM & (PLATFORM_ANDROID|PLATFORM_MAEMO)
|
#if CONFIG_PLATFORM & (PLATFORM_ANDROID|PLATFORM_MAEMO)
|
||||||
|
@ -632,13 +644,22 @@ long default_event_handler_ex(long event, void (*callback)(void *), void *parame
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_HEADPHONE_DETECTION
|
#ifdef HAVE_HEADPHONE_DETECTION
|
||||||
case SYS_PHONE_PLUGGED:
|
case SYS_PHONE_PLUGGED:
|
||||||
unplug_change(true);
|
hp_unplug_change(true);
|
||||||
return SYS_PHONE_PLUGGED;
|
return SYS_PHONE_PLUGGED;
|
||||||
|
|
||||||
case SYS_PHONE_UNPLUGGED:
|
case SYS_PHONE_UNPLUGGED:
|
||||||
unplug_change(false);
|
hp_unplug_change(false);
|
||||||
return SYS_PHONE_UNPLUGGED;
|
return SYS_PHONE_UNPLUGGED;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_LINEOUT_DETECTION
|
||||||
|
case SYS_LINEOUT_PLUGGED:
|
||||||
|
lo_unplug_change(true);
|
||||||
|
return SYS_LINEOUT_PLUGGED;
|
||||||
|
|
||||||
|
case SYS_LINEOUT_UNPLUGGED:
|
||||||
|
lo_unplug_change(false);
|
||||||
|
return SYS_LINEOUT_UNPLUGGED;
|
||||||
|
#endif
|
||||||
#if CONFIG_PLATFORM & (PLATFORM_ANDROID|PLATFORM_MAEMO)
|
#if CONFIG_PLATFORM & (PLATFORM_ANDROID|PLATFORM_MAEMO)
|
||||||
/* stop playback if we receive a call */
|
/* stop playback if we receive a call */
|
||||||
case SYS_CALL_INCOMING:
|
case SYS_CALL_INCOMING:
|
||||||
|
|
|
@ -59,6 +59,9 @@ static bool remote_filter_first_keypress;
|
||||||
#ifdef HAVE_HEADPHONE_DETECTION
|
#ifdef HAVE_HEADPHONE_DETECTION
|
||||||
static bool phones_present = false;
|
static bool phones_present = false;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_LINEOUT_DETECTION
|
||||||
|
static bool lineout_present = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* how long until repeat kicks in, in centiseconds */
|
/* how long until repeat kicks in, in centiseconds */
|
||||||
#define REPEAT_START (30*HZ/100)
|
#define REPEAT_START (30*HZ/100)
|
||||||
|
@ -97,9 +100,8 @@ static int last_touchscreen_touch;
|
||||||
#endif
|
#endif
|
||||||
#if defined(HAVE_HEADPHONE_DETECTION)
|
#if defined(HAVE_HEADPHONE_DETECTION)
|
||||||
static struct timeout hp_detect_timeout; /* Debouncer for headphone plug/unplug */
|
static struct timeout hp_detect_timeout; /* Debouncer for headphone plug/unplug */
|
||||||
/* This callback can be used for many different functions if needed -
|
|
||||||
just check to which object tmo points */
|
static int hp_detect_callback(struct timeout *tmo)
|
||||||
static int btn_detect_callback(struct timeout *tmo)
|
|
||||||
{
|
{
|
||||||
/* Try to post only transistions */
|
/* Try to post only transistions */
|
||||||
const long id = tmo->data ? SYS_PHONE_PLUGGED : SYS_PHONE_UNPLUGGED;
|
const long id = tmo->data ? SYS_PHONE_PLUGGED : SYS_PHONE_UNPLUGGED;
|
||||||
|
@ -109,6 +111,19 @@ static int btn_detect_callback(struct timeout *tmo)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_LINEOUT_DETECTION)
|
||||||
|
static struct timeout lo_detect_timeout; /* Debouncer for lineout plug/unplug */
|
||||||
|
|
||||||
|
static int lo_detect_callback(struct timeout *tmo)
|
||||||
|
{
|
||||||
|
/* Try to post only transistions */
|
||||||
|
const long id = tmo->data ? SYS_LINEOUT_PLUGGED : SYS_LINEOUT_UNPLUGGED;
|
||||||
|
queue_remove_from_head(&button_queue, id);
|
||||||
|
queue_post(&button_queue, id, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool button_try_post(int button, int data)
|
static bool button_try_post(int button, int data)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_TOUCHSCREEN
|
#ifdef HAVE_TOUCHSCREEN
|
||||||
|
@ -176,10 +191,19 @@ static void button_tick(void)
|
||||||
{
|
{
|
||||||
/* Use the autoresetting oneshot to debounce the detection signal */
|
/* Use the autoresetting oneshot to debounce the detection signal */
|
||||||
phones_present = !phones_present;
|
phones_present = !phones_present;
|
||||||
timeout_register(&hp_detect_timeout, btn_detect_callback,
|
timeout_register(&hp_detect_timeout, hp_detect_callback,
|
||||||
HZ/2, phones_present);
|
HZ/2, phones_present);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_LINEOUT_DETECTION)
|
||||||
|
if (lineout_inserted() != lineout_present)
|
||||||
|
{
|
||||||
|
/* Use the autoresetting oneshot to debounce the detection signal */
|
||||||
|
lineout_present = !lineout_present;
|
||||||
|
timeout_register(&lo_detect_timeout, lo_detect_callback,
|
||||||
|
HZ/2, lineout_present);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Find out if a key has been released */
|
/* Find out if a key has been released */
|
||||||
diff = btn ^ lastbtn;
|
diff = btn ^ lastbtn;
|
||||||
|
|
|
@ -72,6 +72,9 @@ void set_remote_backlight_filter_keypress(bool value);
|
||||||
#ifdef HAVE_HEADPHONE_DETECTION
|
#ifdef HAVE_HEADPHONE_DETECTION
|
||||||
bool headphones_inserted(void);
|
bool headphones_inserted(void);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_LINEOUT_DETECTION
|
||||||
|
bool lineout_inserted(void);
|
||||||
|
#endif
|
||||||
#ifdef HAVE_WHEEL_POSITION
|
#ifdef HAVE_WHEEL_POSITION
|
||||||
int wheel_status(void);
|
int wheel_status(void);
|
||||||
void wheel_send_events(bool send);
|
void wheel_send_events(bool send);
|
||||||
|
|
|
@ -73,6 +73,9 @@
|
||||||
/* Define this if you can detect headphones */
|
/* Define this if you can detect headphones */
|
||||||
#define HAVE_HEADPHONE_DETECTION
|
#define HAVE_HEADPHONE_DETECTION
|
||||||
|
|
||||||
|
/* Define this if you can detect lineout */
|
||||||
|
#define HAVE_LINEOUT_DETECTION
|
||||||
|
|
||||||
#define CONFIG_KEYPAD XDUOO_X3_PAD
|
#define CONFIG_KEYPAD XDUOO_X3_PAD
|
||||||
|
|
||||||
/* Define this if a programmable hotkey is mapped */
|
/* Define this if a programmable hotkey is mapped */
|
||||||
|
|
|
@ -65,6 +65,8 @@
|
||||||
#define SYS_PHONE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 3)
|
#define SYS_PHONE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 3)
|
||||||
#define SYS_REMOTE_PLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 4)
|
#define SYS_REMOTE_PLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 4)
|
||||||
#define SYS_REMOTE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 5)
|
#define SYS_REMOTE_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 5)
|
||||||
|
#define SYS_LINEOUT_PLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 6)
|
||||||
|
#define SYS_LINEOUT_UNPLUGGED MAKE_SYS_EVENT(SYS_EVENT_CLS_PLUG, 7)
|
||||||
#define SYS_CAR_ADAPTER_RESUME MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0)
|
#define SYS_CAR_ADAPTER_RESUME MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 0)
|
||||||
#define SYS_CALL_INCOMING MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 3)
|
#define SYS_CALL_INCOMING MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 3)
|
||||||
#define SYS_CALL_HUNG_UP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 4)
|
#define SYS_CALL_HUNG_UP MAKE_SYS_EVENT(SYS_EVENT_CLS_MISC, 4)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "pcm_sw_volume.h"
|
#include "pcm_sw_volume.h"
|
||||||
#include "cs4398.h"
|
#include "cs4398.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
#include "button.h"
|
||||||
|
|
||||||
#define PIN_CS_RST (32*1+10)
|
#define PIN_CS_RST (32*1+10)
|
||||||
#define PIN_CODEC_PWRON (32*1+13)
|
#define PIN_CODEC_PWRON (32*1+13)
|
||||||
|
@ -140,7 +141,11 @@ static int vol_tenthdb2hw(const int tdb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void audiohw_set_volume(int vol_l, int vol_r)
|
#ifdef HAVE_LINEOUT_DETECTION
|
||||||
|
static int real_vol_l, real_vol_r;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void jz4760_set_vol(int vol_l, int vol_r)
|
||||||
{
|
{
|
||||||
uint8_t val = cs4398_read_reg(CS4398_REG_MISC) &~ CS4398_FREEZE;
|
uint8_t val = cs4398_read_reg(CS4398_REG_MISC) &~ CS4398_FREEZE;
|
||||||
cs4398_write_reg(CS4398_REG_MISC, val | CS4398_FREEZE);
|
cs4398_write_reg(CS4398_REG_MISC, val | CS4398_FREEZE);
|
||||||
|
@ -149,14 +154,31 @@ void audiohw_set_volume(int vol_l, int vol_r)
|
||||||
cs4398_write_reg(CS4398_REG_MISC, val);
|
cs4398_write_reg(CS4398_REG_MISC, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void audiohw_set_volume(int vol_l, int vol_r)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LINEOUT_DETECTION
|
||||||
|
real_vol_l = vol_l;
|
||||||
|
real_vol_r = vol_r;
|
||||||
|
|
||||||
|
if (lineout_inserted()) {
|
||||||
|
vol_l = 0;
|
||||||
|
vol_r = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
jz4760_set_vol(vol_l, vol_r);
|
||||||
|
}
|
||||||
|
|
||||||
void audiohw_set_lineout_volume(int vol_l, int vol_r)
|
void audiohw_set_lineout_volume(int vol_l, int vol_r)
|
||||||
{
|
{
|
||||||
#if 0 /* unused */
|
|
||||||
cs4398_write_reg(CS4398_REG_VOL_A, vol_tenthdb2hw(vol_l));
|
|
||||||
cs4398_write_reg(CS4398_REG_VOL_B, vol_tenthdb2hw(vol_r));
|
|
||||||
#else
|
|
||||||
(void)vol_l;
|
(void)vol_l;
|
||||||
(void)vol_r;
|
(void)vol_r;
|
||||||
|
|
||||||
|
#ifdef HAVE_LINEOUT_DETECTION
|
||||||
|
if (lineout_inserted()) {
|
||||||
|
jz4760_set_vol(0, 0);
|
||||||
|
} else {
|
||||||
|
jz4760_set_vol(real_vol_l, real_vol_r);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,13 @@ bool headphones_inserted(void)
|
||||||
return (__gpio_get_pin(PIN_PH_DECT) != 0);
|
return (__gpio_get_pin(PIN_PH_DECT) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool lineout_inserted(void)
|
||||||
|
{
|
||||||
|
/* We want to prevent LO being "enabled" if HP is attached
|
||||||
|
to avoid potential eardrum damage */
|
||||||
|
return (__gpio_get_pin(PIN_LO_DECT) == 0) && !headphones_inserted();
|
||||||
|
}
|
||||||
|
|
||||||
void button_init_device(void)
|
void button_init_device(void)
|
||||||
{
|
{
|
||||||
key_val = 0xfff;
|
key_val = 0xfff;
|
||||||
|
@ -72,11 +79,11 @@ void button_init_device(void)
|
||||||
__gpio_set_pin(PIN_CHARGE_CON); /* 0.7 A */
|
__gpio_set_pin(PIN_CHARGE_CON); /* 0.7 A */
|
||||||
__gpio_as_output(PIN_CHARGE_CON);
|
__gpio_as_output(PIN_CHARGE_CON);
|
||||||
|
|
||||||
__gpio_as_input(PIN_LO_DECT);
|
|
||||||
__gpio_as_input(PIN_PH_DECT);
|
__gpio_as_input(PIN_PH_DECT);
|
||||||
|
|
||||||
__gpio_disable_pull(PIN_LO_DECT);
|
|
||||||
__gpio_disable_pull(PIN_PH_DECT);
|
__gpio_disable_pull(PIN_PH_DECT);
|
||||||
|
|
||||||
|
__gpio_as_input(PIN_LO_DECT);
|
||||||
|
__gpio_disable_pull(PIN_LO_DECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool button_hold(void)
|
bool button_hold(void)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue