aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/greybus/audio_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/greybus/audio_codec.c')
-rw-r--r--drivers/staging/greybus/audio_codec.c178
1 files changed, 105 insertions, 73 deletions
diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c
index 08746c85dea6..74538f8c5fa4 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -14,6 +14,7 @@
#include "audio_codec.h"
#include "audio_apbridgea.h"
#include "audio_manager.h"
+#include "audio_helper.h"
static struct gbaudio_codec_info *gbcodec;
@@ -709,34 +710,58 @@ static struct snd_soc_dai_driver gbaudio_dai[] = {
};
static int gbaudio_init_jack(struct gbaudio_module_info *module,
- struct snd_soc_codec *codec)
+ struct snd_soc_card *card)
{
int ret;
+ struct gbaudio_jack *jack, *n;
+ struct snd_soc_jack_pin *headset, *button;
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, module->jack_mask,
- &module->headset_jack);
+
+ headset = devm_kzalloc(module->dev, sizeof(*headset), GFP_KERNEL);
+ if (!headset)
+ return -ENOMEM;
+
+ headset->pin = module->jack_name;
+ headset->mask = module->jack_mask;
+ ret = snd_soc_card_jack_new(card, module->jack_name, module->jack_mask,
+ &module->headset.jack, headset, 1);
if (ret) {
dev_err(module->dev, "Failed to create new jack\n");
return ret;
}
+ /* Add to module's jack list */
+ list_add(&module->headset.list, &module->jack_list);
+
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, module->button_mask,
- &module->button_jack);
+ button = devm_kzalloc(module->dev, sizeof(*button), GFP_KERNEL);
+ if (!button) {
+ ret = -ENOMEM;
+ goto free_jacks;
+ }
+
+ button->pin = module->button_name;
+ button->mask = module->button_mask;
+ ret = snd_soc_card_jack_new(card, module->button_name,
+ module->button_mask, &module->button.jack,
+ button, 1);
if (ret) {
dev_err(module->dev, "Failed to create button jack\n");
- return ret;
+ goto free_jacks;
}
+ /* Add to module's jack list */
+ list_add(&module->button.list, &module->jack_list);
+
/*
* Currently, max 4 buttons are supported with following key mapping
* BTN_0 = KEY_MEDIA
@@ -746,64 +771,72 @@ static int gbaudio_init_jack(struct gbaudio_module_info *module,
*/
if (module->button_mask & SND_JACK_BTN_0) {
- ret = snd_jack_set_key(module->button_jack.jack, 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;
+ goto free_jacks;
}
}
if (module->button_mask & SND_JACK_BTN_1) {
- ret = snd_jack_set_key(module->button_jack.jack, 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;
+ goto free_jacks;
}
}
if (module->button_mask & SND_JACK_BTN_2) {
- ret = snd_jack_set_key(module->button_jack.jack, 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;
+ goto free_jacks;
}
}
if (module->button_mask & SND_JACK_BTN_3) {
- ret = snd_jack_set_key(module->button_jack.jack, 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;
+ goto free_jacks;
}
}
/* FIXME
* verify if this is really required
set_bit(INPUT_PROP_NO_DUMMY_RELEASE,
- module->button_jack.jack->input_dev->propbit);
+ module->button.jack.jack->input_dev->propbit);
*/
return 0;
+
+free_jacks:
+ list_for_each_entry_safe(jack, n, &module->jack_list, list) {
+ snd_device_free(card->snd_card, jack->jack.jack);
+ list_del(&jack->list);
+ }
+
+ return ret;
}
int gbaudio_register_module(struct gbaudio_module_info *module)
{
int ret;
- struct snd_soc_codec *codec;
+ struct snd_soc_component *comp;
struct snd_card *card;
- struct snd_soc_jack *jack = NULL;
+ struct gbaudio_jack *jack = NULL;
if (!gbcodec) {
dev_err(module->dev, "GB Codec not yet probed\n");
return -EAGAIN;
}
- codec = gbcodec->codec;
- card = codec->card->snd_card;
+ comp = gbcodec->component;
+ card = comp->card->snd_card;
down_write(&card->controls_rwsem);
@@ -815,36 +848,34 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
return -EINVAL;
}
- ret = gbaudio_init_jack(module, codec);
+ ret = gbaudio_init_jack(module, comp->card);
if (ret) {
up_write(&card->controls_rwsem);
return ret;
}
if (module->dapm_widgets)
- snd_soc_dapm_new_controls(&codec->dapm, module->dapm_widgets,
+ snd_soc_dapm_new_controls(&comp->dapm, module->dapm_widgets,
module->num_dapm_widgets);
if (module->controls)
- snd_soc_add_codec_controls(codec, module->controls,
- module->num_controls);
+ snd_soc_add_component_controls(comp, module->controls,
+ module->num_controls);
if (module->dapm_routes)
- snd_soc_dapm_add_routes(&codec->dapm, module->dapm_routes,
+ snd_soc_dapm_add_routes(&comp->dapm, module->dapm_routes,
module->num_dapm_routes);
/* card already instantiated, create widgets here only */
- if (codec->card->instantiated) {
- snd_soc_dapm_link_component_dai_widgets(codec->card,
- &codec->dapm);
+ if (comp->card->instantiated) {
+ gbaudio_dapm_link_component_dai_widgets(comp->card,
+ &comp->dapm);
#ifdef CONFIG_SND_JACK
/*
* register jack devices for this module
* from codec->jack_list
*/
- list_for_each_entry(jack, &codec->jack_list, list) {
- if ((jack == &module->headset_jack) ||
- (jack == &module->button_jack))
- snd_device_register(codec->card->snd_card,
- jack->jack);
+ list_for_each_entry(jack, &module->jack_list, list) {
+ snd_device_register(comp->card->snd_card,
+ jack->jack.jack);
}
#endif
}
@@ -853,9 +884,9 @@ int gbaudio_register_module(struct gbaudio_module_info *module)
list_add(&module->list, &gbcodec->module_list);
mutex_unlock(&gbcodec->lock);
- if (codec->card->instantiated)
- ret = snd_soc_dapm_new_widgets(&codec->dapm);
- dev_dbg(codec->dev, "Registered %s module\n", module->name);
+ if (comp->card->instantiated)
+ ret = snd_soc_dapm_new_widgets(comp->card);
+ dev_dbg(comp->dev, "Registered %s module\n", module->name);
up_write(&card->controls_rwsem);
return ret;
@@ -926,126 +957,127 @@ static void gbaudio_codec_cleanup(struct gbaudio_module_info *module)
void gbaudio_unregister_module(struct gbaudio_module_info *module)
{
- struct snd_soc_codec *codec = gbcodec->codec;
- struct snd_card *card = codec->card->snd_card;
- struct snd_soc_jack *jack, *next_j;
+ struct snd_soc_component *comp = gbcodec->component;
+ struct snd_card *card = comp->card->snd_card;
+ struct gbaudio_jack *jack, *n;
int mask;
- dev_dbg(codec->dev, "Unregister %s module\n", module->name);
+ dev_dbg(comp->dev, "Unregister %s module\n", module->name);
down_write(&card->controls_rwsem);
mutex_lock(&gbcodec->lock);
gbaudio_codec_cleanup(module);
list_del(&module->list);
- dev_dbg(codec->dev, "Process Unregister %s module\n", module->name);
+ dev_dbg(comp->dev, "Process Unregister %s module\n", module->name);
mutex_unlock(&gbcodec->lock);
#ifdef CONFIG_SND_JACK
- /* free jack devices for this module from codec->jack_list */
- list_for_each_entry_safe(jack, next_j, &codec->jack_list, list) {
- if (jack == &module->headset_jack)
+ /* free jack devices for this module jack_list */
+ list_for_each_entry_safe(jack, n, &module->jack_list, list) {
+ if (jack == &module->headset)
mask = GBCODEC_JACK_MASK;
- else if (jack == &module->button_jack)
+ else if (jack == &module->button)
mask = GBCODEC_JACK_BUTTON_MASK;
else
mask = 0;
if (mask) {
dev_dbg(module->dev, "Report %s removal\n",
- jack->jack->id);
- snd_soc_jack_report(jack, 0, mask);
- snd_device_free(codec->card->snd_card, jack->jack);
+ jack->jack.jack->id);
+ snd_soc_jack_report(&jack->jack, 0, mask);
+ snd_device_free(comp->card->snd_card,
+ jack->jack.jack);
list_del(&jack->list);
}
}
#endif
if (module->dapm_routes) {
- dev_dbg(codec->dev, "Removing %d routes\n",
+ dev_dbg(comp->dev, "Removing %d routes\n",
module->num_dapm_routes);
- snd_soc_dapm_del_routes(&codec->dapm, module->dapm_routes,
+ snd_soc_dapm_del_routes(&comp->dapm, module->dapm_routes,
module->num_dapm_routes);
}
if (module->controls) {
- dev_dbg(codec->dev, "Removing %d controls\n",
+ dev_dbg(comp->dev, "Removing %d controls\n",
module->num_controls);
- snd_soc_remove_codec_controls(codec, module->controls,
- module->num_controls);
+ /* release control semaphore */
+ up_write(&card->controls_rwsem);
+ gbaudio_remove_component_controls(comp, module->controls,
+ module->num_controls);
+ down_write(&card->controls_rwsem);
}
if (module->dapm_widgets) {
- dev_dbg(codec->dev, "Removing %d widgets\n",
+ dev_dbg(comp->dev, "Removing %d widgets\n",
module->num_dapm_widgets);
- snd_soc_dapm_free_controls(&codec->dapm, module->dapm_widgets,
+ gbaudio_dapm_free_controls(&comp->dapm, module->dapm_widgets,
module->num_dapm_widgets);
}
- dev_dbg(codec->dev, "Unregistered %s module\n", module->name);
+ dev_dbg(comp->dev, "Unregistered %s module\n", module->name);
up_write(&card->controls_rwsem);
}
EXPORT_SYMBOL(gbaudio_unregister_module);
/*
- * codec driver ops
+ * component driver ops
*/
-static int gbcodec_probe(struct snd_soc_codec *codec)
+static int gbcodec_probe(struct snd_soc_component *comp)
{
int i;
struct gbaudio_codec_info *info;
struct gbaudio_codec_dai *dai;
- info = devm_kzalloc(codec->dev, sizeof(*info), GFP_KERNEL);
+ info = devm_kzalloc(comp->dev, sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
- info->dev = codec->dev;
+ info->dev = comp->dev;
INIT_LIST_HEAD(&info->module_list);
mutex_init(&info->lock);
INIT_LIST_HEAD(&info->dai_list);
/* init dai_list used to maintain runtime stream info */
for (i = 0; i < ARRAY_SIZE(gbaudio_dai); i++) {
- dai = devm_kzalloc(codec->dev, sizeof(*dai), GFP_KERNEL);
+ dai = devm_kzalloc(comp->dev, sizeof(*dai), GFP_KERNEL);
if (!dai)
return -ENOMEM;
dai->id = gbaudio_dai[i].id;
list_add(&dai->list, &info->dai_list);
}
- info->codec = codec;
- snd_soc_codec_set_drvdata(codec, info);
+ info->component = comp;
+ snd_soc_component_set_drvdata(comp, info);
gbcodec = info;
- device_init_wakeup(codec->dev, 1);
+ device_init_wakeup(comp->dev, 1);
return 0;
}
-static int gbcodec_remove(struct snd_soc_codec *codec)
+static void gbcodec_remove(struct snd_soc_component *comp)
{
/* Empty function for now */
- return 0;
+ return;
}
-static int gbcodec_write(struct snd_soc_codec *codec, unsigned int reg,
+static int gbcodec_write(struct snd_soc_component *comp, unsigned int reg,
unsigned int value)
{
return 0;
}
-static unsigned int gbcodec_read(struct snd_soc_codec *codec,
+static unsigned int gbcodec_read(struct snd_soc_component *comp,
unsigned int reg)
{
return 0;
}
-static struct snd_soc_codec_driver soc_codec_dev_gbaudio = {
+static const struct snd_soc_component_driver soc_codec_dev_gbaudio = {
.probe = gbcodec_probe,
.remove = gbcodec_remove,
.read = gbcodec_read,
.write = gbcodec_write,
-
- .idle_bias_off = true,
- .ignore_pmdown_time = 1,
};
#ifdef CONFIG_PM
@@ -1069,13 +1101,13 @@ static const struct dev_pm_ops gbaudio_codec_pm_ops = {
static int gbaudio_codec_probe(struct platform_device *pdev)
{
- return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_gbaudio,
+ return devm_snd_soc_register_component(&pdev->dev,
+ &soc_codec_dev_gbaudio,
gbaudio_dai, ARRAY_SIZE(gbaudio_dai));
}
static int gbaudio_codec_remove(struct platform_device *pdev)
{
- snd_soc_unregister_codec(&pdev->dev);
return 0;
}