summaryrefslogtreecommitdiff
path: root/sound/soc/pxa/spitz.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/pxa/spitz.c')
-rw-r--r--sound/soc/pxa/spitz.c230
1 files changed, 96 insertions, 134 deletions
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index fc052d8247ff..2ea21a2091ee 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* spitz.c -- SoC audio for Sharp SL-Cxx00 models Spitz, Borzoi and Akita
*
@@ -6,12 +7,6 @@
*
* Authors: Liam Girdwood <lrg@slimlogic.co.uk>
* Richard Purdie <richard@openedhand.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
*/
#include <linux/module.h>
@@ -19,13 +14,12 @@
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <asm/mach-types.h>
-#include <mach/spitz.h>
#include "../codecs/wm8750.h"
#include "pxa2xx-i2s.h"
@@ -42,78 +36,79 @@
static int spitz_jack_func;
static int spitz_spk_func;
-static int spitz_mic_gpio;
+static struct gpio_desc *gpiod_mic, *gpiod_mute_l, *gpiod_mute_r;
static void spitz_ext_control(struct snd_soc_dapm_context *dapm)
{
+ snd_soc_dapm_mutex_lock(dapm);
+
if (spitz_spk_func == SPITZ_SPK_ON)
- snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+ snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk");
else
- snd_soc_dapm_disable_pin(dapm, "Ext Spk");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk");
/* set up jack connection */
switch (spitz_jack_func) {
case SPITZ_HP:
/* enable and unmute hp jack, disable mic bias */
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- snd_soc_dapm_disable_pin(dapm, "Mic Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
- gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
- gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack");
+ gpiod_set_value(gpiod_mute_l, 1);
+ gpiod_set_value(gpiod_mute_r, 1);
break;
case SPITZ_MIC:
/* enable mic jack and bias, mute hp */
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
- gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
+ gpiod_set_value(gpiod_mute_l, 0);
+ gpiod_set_value(gpiod_mute_r, 0);
break;
case SPITZ_LINE:
/* enable line jack, disable mic bias and mute hp */
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- snd_soc_dapm_disable_pin(dapm, "Mic Jack");
- snd_soc_dapm_enable_pin(dapm, "Line Jack");
- gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
- gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
+ snd_soc_dapm_enable_pin_unlocked(dapm, "Line Jack");
+ gpiod_set_value(gpiod_mute_l, 0);
+ gpiod_set_value(gpiod_mute_r, 0);
break;
case SPITZ_HEADSET:
/* enable and unmute headset jack enable mic bias, mute L hp */
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_enable_pin(dapm, "Mic Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- snd_soc_dapm_enable_pin(dapm, "Headset Jack");
- gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
- gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
+ snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
+ snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack");
+ gpiod_set_value(gpiod_mute_l, 0);
+ gpiod_set_value(gpiod_mute_r, 1);
break;
case SPITZ_HP_OFF:
/* jack removed, everything off */
- snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
- snd_soc_dapm_disable_pin(dapm, "Headset Jack");
- snd_soc_dapm_disable_pin(dapm, "Mic Jack");
- snd_soc_dapm_disable_pin(dapm, "Line Jack");
- gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
- gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack");
+ snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack");
+ gpiod_set_value(gpiod_mute_l, 0);
+ gpiod_set_value(gpiod_mute_r, 0);
break;
}
- snd_soc_dapm_sync(dapm);
+
+ snd_soc_dapm_sync_unlocked(dapm);
+
+ snd_soc_dapm_mutex_unlock(dapm);
}
static int spitz_startup(struct snd_pcm_substream *substream)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
-
- mutex_lock(&codec->mutex);
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(rtd->card);
/* check the jack status at stream startup */
- spitz_ext_control(&codec->dapm);
-
- mutex_unlock(&codec->mutex);
+ spitz_ext_control(dapm);
return 0;
}
@@ -121,9 +116,9 @@ static int spitz_startup(struct snd_pcm_substream *substream)
static int spitz_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
+ struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
+ struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
unsigned int clk = 0;
int ret = 0;
@@ -156,7 +151,7 @@ static int spitz_hw_params(struct snd_pcm_substream *substream,
return 0;
}
-static struct snd_soc_ops spitz_ops = {
+static const struct snd_soc_ops spitz_ops = {
.startup = spitz_startup,
.hw_params = spitz_hw_params,
};
@@ -164,7 +159,7 @@ static struct snd_soc_ops spitz_ops = {
static int spitz_get_jack(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- ucontrol->value.integer.value[0] = spitz_jack_func;
+ ucontrol->value.enumerated.item[0] = spitz_jack_func;
return 0;
}
@@ -172,19 +167,20 @@ static int spitz_set_jack(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
- if (spitz_jack_func == ucontrol->value.integer.value[0])
+ if (spitz_jack_func == ucontrol->value.enumerated.item[0])
return 0;
- spitz_jack_func = ucontrol->value.integer.value[0];
- spitz_ext_control(&card->dapm);
+ spitz_jack_func = ucontrol->value.enumerated.item[0];
+ spitz_ext_control(dapm);
return 1;
}
static int spitz_get_spk(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- ucontrol->value.integer.value[0] = spitz_spk_func;
+ ucontrol->value.enumerated.item[0] = spitz_spk_func;
return 0;
}
@@ -192,19 +188,20 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
- if (spitz_spk_func == ucontrol->value.integer.value[0])
+ if (spitz_spk_func == ucontrol->value.enumerated.item[0])
return 0;
- spitz_spk_func = ucontrol->value.integer.value[0];
- spitz_ext_control(&card->dapm);
+ spitz_spk_func = ucontrol->value.enumerated.item[0];
+ spitz_ext_control(dapm);
return 1;
}
static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
- gpio_set_value_cansleep(spitz_mic_gpio, SND_SOC_DAPM_EVENT_ON(event));
+ gpiod_set_value_cansleep(gpiod_mic, SND_SOC_DAPM_EVENT_ON(event));
return 0;
}
@@ -230,8 +227,8 @@ static const struct snd_soc_dapm_route spitz_audio_map[] = {
{"Headset Jack", NULL, "ROUT1"},
/* ext speaker connected to LOUT2, ROUT2 */
- {"Ext Spk", NULL , "ROUT2"},
- {"Ext Spk", NULL , "LOUT2"},
+ {"Ext Spk", NULL, "ROUT2"},
+ {"Ext Spk", NULL, "LOUT2"},
/* mic is connected to input 1 - with bias */
{"LINPUT1", NULL, "Mic Bias"},
@@ -241,9 +238,9 @@ static const struct snd_soc_dapm_route spitz_audio_map[] = {
{"LINPUT1", NULL, "Line Jack"},
};
-static const char *jack_function[] = {"Headphone", "Mic", "Line", "Headset",
- "Off"};
-static const char *spk_function[] = {"On", "Off"};
+static const char * const jack_function[] = {"Headphone", "Mic", "Line",
+ "Headset", "Off"};
+static const char * const spk_function[] = {"On", "Off"};
static const struct soc_enum spitz_enum[] = {
SOC_ENUM_SINGLE_EXT(5, jack_function),
SOC_ENUM_SINGLE_EXT(2, spk_function),
@@ -256,38 +253,19 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = {
spitz_set_spk),
};
-/*
- * Logic for a wm8750 as connected on a Sharp SL-Cxx00 Device
- */
-static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
-{
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_soc_dapm_context *dapm = &codec->dapm;
-
- /* NC codec pins */
- snd_soc_dapm_nc_pin(dapm, "RINPUT1");
- snd_soc_dapm_nc_pin(dapm, "LINPUT2");
- snd_soc_dapm_nc_pin(dapm, "RINPUT2");
- snd_soc_dapm_nc_pin(dapm, "LINPUT3");
- snd_soc_dapm_nc_pin(dapm, "RINPUT3");
- snd_soc_dapm_nc_pin(dapm, "OUT3");
- snd_soc_dapm_nc_pin(dapm, "MONO1");
-
- return 0;
-}
-
/* spitz digital audio interface glue - connects codec <--> CPU */
+SND_SOC_DAILINK_DEFS(wm8750,
+ DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")),
+ DAILINK_COMP_ARRAY(COMP_CODEC("wm8750.0-001b", "wm8750-hifi")),
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio")));
+
static struct snd_soc_dai_link spitz_dai = {
.name = "wm8750",
.stream_name = "WM8750",
- .cpu_dai_name = "pxa2xx-i2s",
- .codec_dai_name = "wm8750-hifi",
- .platform_name = "pxa-pcm-audio",
- .codec_name = "wm8750.0-001b",
- .init = spitz_wm8750_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
- SND_SOC_DAIFMT_CBS_CFS,
+ SND_SOC_DAIFMT_CBC_CFC,
.ops = &spitz_ops,
+ SND_SOC_DAILINK_REG(wm8750),
};
/* spitz audio machine driver */
@@ -303,61 +281,45 @@ static struct snd_soc_card snd_soc_spitz = {
.num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets),
.dapm_routes = spitz_audio_map,
.num_dapm_routes = ARRAY_SIZE(spitz_audio_map),
+ .fully_routed = true,
};
-static struct platform_device *spitz_snd_device;
-
-static int __init spitz_init(void)
+static int spitz_probe(struct platform_device *pdev)
{
+ struct snd_soc_card *card = &snd_soc_spitz;
int ret;
- if (!(machine_is_spitz() || machine_is_borzoi() || machine_is_akita()))
- return -ENODEV;
-
- if (machine_is_borzoi() || machine_is_spitz())
- spitz_mic_gpio = SPITZ_GPIO_MIC_BIAS;
- else
- spitz_mic_gpio = AKITA_GPIO_MIC_BIAS;
-
- ret = gpio_request(spitz_mic_gpio, "MIC GPIO");
- if (ret)
- goto err1;
-
- ret = gpio_direction_output(spitz_mic_gpio, 0);
- if (ret)
- goto err2;
-
- spitz_snd_device = platform_device_alloc("soc-audio", -1);
- if (!spitz_snd_device) {
- ret = -ENOMEM;
- goto err2;
- }
+ gpiod_mic = devm_gpiod_get(&pdev->dev, "mic", GPIOD_OUT_LOW);
+ if (IS_ERR(gpiod_mic))
+ return PTR_ERR(gpiod_mic);
+ gpiod_mute_l = devm_gpiod_get(&pdev->dev, "mute-l", GPIOD_OUT_LOW);
+ if (IS_ERR(gpiod_mute_l))
+ return PTR_ERR(gpiod_mute_l);
+ gpiod_mute_r = devm_gpiod_get(&pdev->dev, "mute-r", GPIOD_OUT_LOW);
+ if (IS_ERR(gpiod_mute_r))
+ return PTR_ERR(gpiod_mute_r);
- platform_set_drvdata(spitz_snd_device, &snd_soc_spitz);
+ card->dev = &pdev->dev;
- ret = platform_device_add(spitz_snd_device);
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret)
- goto err3;
-
- return 0;
+ dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
+ ret);
-err3:
- platform_device_put(spitz_snd_device);
-err2:
- gpio_free(spitz_mic_gpio);
-err1:
return ret;
}
-static void __exit spitz_exit(void)
-{
- platform_device_unregister(spitz_snd_device);
- gpio_free(spitz_mic_gpio);
-}
+static struct platform_driver spitz_driver = {
+ .driver = {
+ .name = "spitz-audio",
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = spitz_probe,
+};
-module_init(spitz_init);
-module_exit(spitz_exit);
+module_platform_driver(spitz_driver);
MODULE_AUTHOR("Richard Purdie");
MODULE_DESCRIPTION("ALSA SoC Spitz");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:spitz-audio");