From 847175e8e660045f9366e7efd091969e8f32cc0c Mon Sep 17 00:00:00 2001 From: Vaibhav Agarwal Date: Thu, 1 Sep 2016 11:38:40 +0530 Subject: greybus: audio: Fetch jack_mask, button_mask from module's topology data Added extra fields namely jack_mask & button_mask for each module_info. These fields are required while registering jack & reporting jack events. Earlier, these were hard coded values assuming fixed capabilities say HEADSET, LINEOUT, etc. supported by GB-codec driver. Now these are computed dynamically based on module's jack capability shared via topology data. Signed-off-by: Vaibhav Agarwal Reviewed-by: Mark Greer Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/audio_codec.c | 68 +++++++++++++++++++++----------- drivers/staging/greybus/audio_codec.h | 8 ++-- drivers/staging/greybus/audio_module.c | 15 ++++--- drivers/staging/greybus/audio_topology.c | 7 ++++ 4 files changed, 63 insertions(+), 35 deletions(-) (limited to 'drivers/staging') diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c index 810ac62..2f70295 100644 --- a/drivers/staging/greybus/audio_codec.c +++ b/drivers/staging/greybus/audio_codec.c @@ -707,50 +707,72 @@ static int gbaudio_init_jack(struct gbaudio_module_info *module, { int ret; + if (!module->jack_mask) + return 0; + snprintf(module->jack_name, NAME_SIZE, "GB %d Headset Jack", module->dev_id); - ret = snd_soc_jack_new(codec, module->jack_name, GBCODEC_JACK_MASK, + ret = snd_soc_jack_new(codec, module->jack_name, module->jack_mask, &module->headset_jack); if (ret) { dev_err(module->dev, "Failed to create new jack\n"); return ret; } + if (!module->button_mask) + return 0; + snprintf(module->button_name, NAME_SIZE, "GB %d Button Jack", module->dev_id); - ret = snd_soc_jack_new(codec, module->button_name, - GBCODEC_JACK_BUTTON_MASK, &module->button_jack); + ret = snd_soc_jack_new(codec, module->button_name, module->button_mask, + &module->button_jack); if (ret) { dev_err(module->dev, "Failed to create button jack\n"); return ret; } - ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_0, - KEY_MEDIA); - if (ret) { - dev_err(module->dev, "Failed to set BTN_0\n"); - return ret; + /* + * Currently, max 4 buttons are supported with following key mapping + * BTN_0 = KEY_MEDIA + * BTN_1 = KEY_VOICECOMMAND + * BTN_2 = KEY_VOLUMEUP + * BTN_3 = KEY_VOLUMEDOWN + */ + + if (module->button_mask & SND_JACK_BTN_0) { + ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_0, + KEY_MEDIA); + if (ret) { + dev_err(module->dev, "Failed to set BTN_0\n"); + return ret; + } } - ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_1, - KEY_VOICECOMMAND); - if (ret) { - dev_err(module->dev, "Failed to set BTN_1\n"); - return ret; + if (module->button_mask & SND_JACK_BTN_1) { + ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_1, + KEY_VOICECOMMAND); + if (ret) { + dev_err(module->dev, "Failed to set BTN_1\n"); + return ret; + } } - ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_2, - KEY_VOLUMEUP); - if (ret) { - dev_err(module->dev, "Failed to set BTN_2\n"); - return ret; + if (module->button_mask & SND_JACK_BTN_2) { + ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_2, + KEY_VOLUMEUP); + if (ret) { + dev_err(module->dev, "Failed to set BTN_2\n"); + return ret; + } } - ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_3, - KEY_VOLUMEDOWN); - if (ret) { - dev_err(module->dev, "Failed to set BTN_0\n"); - return ret; + if (module->button_mask & SND_JACK_BTN_3) { + ret = snd_jack_set_key(module->button_jack.jack, SND_JACK_BTN_3, + KEY_VOLUMEDOWN); + if (ret) { + dev_err(module->dev, "Failed to set BTN_0\n"); + return ret; + } } /* FIXME diff --git a/drivers/staging/greybus/audio_codec.h b/drivers/staging/greybus/audio_codec.h index 5a397b0..0a86459 100644 --- a/drivers/staging/greybus/audio_codec.h +++ b/drivers/staging/greybus/audio_codec.h @@ -73,10 +73,8 @@ enum { #define GBCODEC_APB1_MUX_REG_DEFAULT 0x00 #define GBCODEC_APB2_MUX_REG_DEFAULT 0x00 -#define GBCODEC_JACK_MASK (SND_JACK_HEADSET | SND_JACK_LINEOUT | \ - SND_JACK_LINEIN | SND_JACK_UNSUPPORTED) -#define GBCODEC_JACK_BUTTON_MASK (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \ - SND_JACK_BTN_2 | SND_JACK_BTN_3) +#define GBCODEC_JACK_MASK 0x0000FFFF +#define GBCODEC_JACK_BUTTON_MASK 0xFFFF0000 static const u8 gbcodec_reg_defaults[GBCODEC_REG_COUNT] = { GBCODEC_CTL_REG_DEFAULT, @@ -176,6 +174,8 @@ struct gbaudio_module_info { char jack_name[NAME_SIZE]; char button_name[NAME_SIZE]; int jack_type; + int jack_mask; + int button_mask; int button_status; struct snd_soc_jack headset_jack; struct snd_soc_jack button_jack; diff --git a/drivers/staging/greybus/audio_module.c b/drivers/staging/greybus/audio_module.c index c217271..f764f00 100644 --- a/drivers/staging/greybus/audio_module.c +++ b/drivers/staging/greybus/audio_module.c @@ -33,22 +33,22 @@ static int gbaudio_request_jack(struct gbaudio_module_info *module, module->button_status = 0; if (button_status) snd_soc_jack_report(&module->button_jack, 0, - GBCODEC_JACK_BUTTON_MASK); + module->button_mask); snd_soc_jack_report(&module->headset_jack, 0, - GBCODEC_JACK_MASK); + module->jack_mask); return 0; } /* currently supports Headphone, Headset & Lineout only */ - report &= ~GBCODEC_JACK_MASK; - report |= req->jack_attribute & GBCODEC_JACK_MASK; + report &= ~module->jack_mask; + report |= req->jack_attribute & module->jack_mask; if (module->jack_type) dev_warn_ratelimited(module->dev, "Modifying jack from %d to %d\n", module->jack_type, report); module->jack_type = report; - snd_soc_jack_report(&module->headset_jack, report, GBCODEC_JACK_MASK); + snd_soc_jack_report(&module->headset_jack, report, module->jack_mask); return 0; } @@ -69,7 +69,7 @@ static int gbaudio_request_button(struct gbaudio_module_info *module, return -EINVAL; } - report = module->button_status & GBCODEC_JACK_BUTTON_MASK; + report = module->button_status & module->button_mask; switch (req->button_id) { case 1: @@ -100,8 +100,7 @@ static int gbaudio_request_button(struct gbaudio_module_info *module, module->button_status = report; - snd_soc_jack_report(&module->button_jack, report, - GBCODEC_JACK_BUTTON_MASK); + snd_soc_jack_report(&module->button_jack, report, module->button_mask); return 0; } diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c index e2fc186..5eef536 100644 --- a/drivers/staging/greybus/audio_topology.c +++ b/drivers/staging/greybus/audio_topology.c @@ -1393,6 +1393,13 @@ int gbaudio_tplg_parse_data(struct gbaudio_module_info *module, } dev_dbg(module->dev, "Route parsing finished\n"); + /* parse jack capabilities */ + if (tplg_data->jack_type) { + module->jack_mask = tplg_data->jack_type & GBCODEC_JACK_MASK; + module->button_mask = tplg_data->jack_type & + GBCODEC_JACK_BUTTON_MASK; + } + return ret; } -- cgit v1.1