diff options
Diffstat (limited to 'sound/soc/omap')
-rw-r--r-- | sound/soc/omap/Kconfig | 4 | ||||
-rw-r--r-- | sound/soc/omap/am3517evm.c | 2 | ||||
-rw-r--r-- | sound/soc/omap/ams-delta.c | 80 | ||||
-rw-r--r-- | sound/soc/omap/n810.c | 2 | ||||
-rw-r--r-- | sound/soc/omap/omap-abe-twl6040.c | 13 | ||||
-rw-r--r-- | sound/soc/omap/omap-dmic.c | 9 | ||||
-rw-r--r-- | sound/soc/omap/omap-hdmi-card.c | 2 | ||||
-rw-r--r-- | sound/soc/omap/omap-hdmi.c | 6 | ||||
-rw-r--r-- | sound/soc/omap/omap-mcbsp.c | 25 | ||||
-rw-r--r-- | sound/soc/omap/omap-mcbsp.h | 2 | ||||
-rw-r--r-- | sound/soc/omap/omap-mcpdm.c | 16 | ||||
-rw-r--r-- | sound/soc/omap/omap-pcm.c | 25 | ||||
-rw-r--r-- | sound/soc/omap/omap-twl4030.c | 42 | ||||
-rw-r--r-- | sound/soc/omap/omap3pandora.c | 35 | ||||
-rw-r--r-- | sound/soc/omap/osk5912.c | 2 | ||||
-rw-r--r-- | sound/soc/omap/rx51.c | 275 |
16 files changed, 297 insertions, 243 deletions
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index e00659351a4..d44463a7b0f 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -26,7 +26,7 @@ config SND_OMAP_SOC_N810 config SND_OMAP_SOC_RX51 tristate "SoC Audio support for Nokia RX-51" - depends on SND_OMAP_SOC && ARM && (MACH_NOKIA_RX51 || COMPILE_TEST) + depends on SND_OMAP_SOC && ARM && (MACH_NOKIA_RX51 || COMPILE_TEST) && I2C select SND_OMAP_SOC_MCBSP select SND_SOC_TLV320AIC3X select SND_SOC_TPA6130A2 @@ -37,7 +37,7 @@ config SND_OMAP_SOC_RX51 config SND_OMAP_SOC_AMS_DELTA tristate "SoC Audio support for Amstrad E3 (Delta) videophone" - depends on SND_OMAP_SOC && MACH_AMS_DELTA + depends on SND_OMAP_SOC && MACH_AMS_DELTA && TTY select SND_OMAP_SOC_MCBSP select SND_SOC_CX20442 help diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index 994dcf34597..25a33e9d417 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c @@ -77,7 +77,7 @@ static struct snd_soc_dai_link am3517evm_dai = { .stream_name = "AIC23", .cpu_dai_name = "omap-mcbsp.1", .codec_dai_name = "tlv320aic23-hifi", - .platform_name = "omap-pcm-audio", + .platform_name = "omap-mcbsp.1", .codec_name = "tlv320aic23-codec.2-001a", .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 56a5219c0a0..0cc41f94de4 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -38,7 +38,6 @@ #include "omap-mcbsp.h" #include "../codecs/cx20442.h" - /* Board specific DAPM widgets */ static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = { /* Handset */ @@ -90,17 +89,23 @@ static const unsigned short ams_delta_audio_mode_pins[] = { static unsigned short ams_delta_audio_agc; +/* + * Used for passing a codec structure pointer + * from the board initialization code to the tty line discipline. + */ +static struct snd_soc_codec *cx20442_codec; + static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = &card->dapm; struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; unsigned short pins; int pin, changed = 0; /* Refuse any mode changes if we are not able to control the codec. */ - if (!codec->hw_write) + if (!cx20442_codec->hw_write) return -EUNATCH; if (ucontrol->value.enumerated.item[0] >= control->items) @@ -166,8 +171,8 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); + struct snd_soc_dapm_context *dapm = &card->dapm; unsigned short pins, mode; pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") << @@ -270,12 +275,6 @@ static void cx81801_timeout(unsigned long data) ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0); } -/* - * Used for passing a codec structure pointer - * from the board initialization code to the tty line discipline. - */ -static struct snd_soc_codec *cx20442_codec; - /* Line discipline .open() */ static int cx81801_open(struct tty_struct *tty) { @@ -302,7 +301,7 @@ static int cx81801_open(struct tty_struct *tty) static void cx81801_close(struct tty_struct *tty) { struct snd_soc_codec *codec = tty->disc_data; - struct snd_soc_dapm_context *dapm = &codec->dapm; + struct snd_soc_dapm_context *dapm = &codec->card->dapm; del_timer_sync(&cx81801_timer); @@ -475,15 +474,14 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream) static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dai *codec_dai = rtd->codec_dai; struct snd_soc_card *card = rtd->card; + struct snd_soc_dapm_context *dapm = &card->dapm; int ret; /* Codec is ready, now add/activate board specific controls */ /* Store a pointer to the codec structure for tty ldisc use */ - cx20442_codec = codec; + cx20442_codec = rtd->codec; /* Set up digital mute if not provided by the codec */ if (!codec_dai->driver->ops) { @@ -520,40 +518,20 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) return 0; } - /* Add board specific DAPM widgets and routes */ - ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets, - ARRAY_SIZE(ams_delta_dapm_widgets)); - if (ret) { - dev_warn(card->dev, - "Failed to register DAPM controls, " - "will continue without any.\n"); - return 0; - } - - ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map, - ARRAY_SIZE(ams_delta_audio_map)); - if (ret) { - dev_warn(card->dev, - "Failed to set up DAPM routes, " - "will continue with codec default map.\n"); - return 0; - } - /* Set up initial pin constellation */ snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); - snd_soc_dapm_enable_pin(dapm, "Earpiece"); - snd_soc_dapm_enable_pin(dapm, "Microphone"); snd_soc_dapm_disable_pin(dapm, "Speaker"); snd_soc_dapm_disable_pin(dapm, "AGCIN"); snd_soc_dapm_disable_pin(dapm, "AGCOUT"); - /* Add virtual switch */ - ret = snd_soc_add_codec_controls(codec, ams_delta_audio_controls, - ARRAY_SIZE(ams_delta_audio_controls)); - if (ret) - dev_warn(card->dev, - "Failed to register audio mode control, " - "will continue without it.\n"); + return 0; +} + +static int ams_delta_card_remove(struct snd_soc_card *card) +{ + snd_soc_jack_free_gpios(&ams_delta_hook_switch, + ARRAY_SIZE(ams_delta_hook_switch_gpios), + ams_delta_hook_switch_gpios); return 0; } @@ -565,7 +543,7 @@ static struct snd_soc_dai_link ams_delta_dai_link = { .cpu_dai_name = "omap-mcbsp.1", .codec_dai_name = "cx20442-voice", .init = ams_delta_cx20442_init, - .platform_name = "omap-pcm-audio", + .platform_name = "omap-mcbsp.1", .codec_name = "cx20442-codec", .ops = &ams_delta_ops, }; @@ -574,8 +552,16 @@ static struct snd_soc_dai_link ams_delta_dai_link = { static struct snd_soc_card ams_delta_audio_card = { .name = "AMS_DELTA", .owner = THIS_MODULE, + .remove = ams_delta_card_remove, .dai_link = &ams_delta_dai_link, .num_links = 1, + + .controls = ams_delta_audio_controls, + .num_controls = ARRAY_SIZE(ams_delta_audio_controls), + .dapm_widgets = ams_delta_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(ams_delta_dapm_widgets), + .dapm_routes = ams_delta_audio_map, + .num_dapm_routes = ARRAY_SIZE(ams_delta_audio_map), }; /* Module init/exit */ @@ -603,10 +589,6 @@ static int ams_delta_remove(struct platform_device *pdev) dev_warn(&pdev->dev, "failed to unregister V253 line discipline\n"); - snd_soc_jack_free_gpios(&ams_delta_hook_switch, - ARRAY_SIZE(ams_delta_hook_switch_gpios), - ams_delta_hook_switch_gpios); - snd_soc_unregister_card(card); card->dev = NULL; return 0; diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index fd4d9c809e5..5d7f9cebe04 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -278,7 +278,7 @@ static struct snd_soc_dai_link n810_dai = { .name = "TLV320AIC33", .stream_name = "AIC33", .cpu_dai_name = "omap-mcbsp.2", - .platform_name = "omap-pcm-audio", + .platform_name = "omap-mcbsp.2", .codec_name = "tlv320aic3x-codec.2-0018", .codec_dai_name = "tlv320aic3x-hifi", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index 024dafc3e29..cec836ed0c0 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c @@ -47,8 +47,7 @@ static int omap_abe_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_card *card = codec->card; + struct snd_soc_card *card = rtd->card; struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); int clk_id, freq; int ret; @@ -168,7 +167,7 @@ static const struct snd_soc_dapm_route audio_map[] = { static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_card *card = codec->card; + struct snd_soc_card *card = rtd->card; struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); int hs_trim; int ret = 0; @@ -214,9 +213,7 @@ static struct snd_soc_dai_link abe_twl6040_dai_links[] = { { .name = "TWL6040", .stream_name = "TWL6040", - .cpu_dai_name = "omap-mcpdm", .codec_dai_name = "twl6040-legacy", - .platform_name = "omap-pcm-audio", .codec_name = "twl6040-codec", .init = omap_abe_twl6040_init, .ops = &omap_abe_ops, @@ -224,9 +221,7 @@ static struct snd_soc_dai_link abe_twl6040_dai_links[] = { { .name = "DMIC", .stream_name = "DMIC Capture", - .cpu_dai_name = "omap-dmic", .codec_dai_name = "dmic-hifi", - .platform_name = "omap-pcm-audio", .codec_name = "dmic-codec", .init = omap_abe_dmic_init, .ops = &omap_abe_dmic_ops, @@ -281,14 +276,14 @@ static int omap_abe_probe(struct platform_device *pdev) dev_err(&pdev->dev, "McPDM node is not provided\n"); return -EINVAL; } - abe_twl6040_dai_links[0].cpu_dai_name = NULL; abe_twl6040_dai_links[0].cpu_of_node = dai_node; + abe_twl6040_dai_links[0].platform_of_node = dai_node; dai_node = of_parse_phandle(node, "ti,dmic", 0); if (dai_node) { num_links = 2; - abe_twl6040_dai_links[1].cpu_dai_name = NULL; abe_twl6040_dai_links[1].cpu_of_node = dai_node; + abe_twl6040_dai_links[1].platform_of_node = dai_node; priv->dmic_codec_dev = platform_device_register_simple( "dmic-codec", -1, NULL, 0); diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 1bd531d718f..6925d714121 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c @@ -40,6 +40,7 @@ #include <sound/initval.h> #include <sound/soc.h> #include <sound/dmaengine_pcm.h> +#include <sound/omap-pcm.h> #include "omap-dmic.h" @@ -113,7 +114,6 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, mutex_unlock(&dmic->mutex); - snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data); return ret; } @@ -417,6 +417,9 @@ static int omap_dmic_probe(struct snd_soc_dai *dai) /* Configure DMIC threshold value */ dmic->threshold = OMAP_DMIC_THRES_MAX - 3; + + snd_soc_dai_init_dma_data(dai, NULL, &dmic->dma_data); + return 0; } @@ -492,6 +495,10 @@ static int asoc_dmic_probe(struct platform_device *pdev) if (ret) goto err_put_clk; + ret = omap_pcm_platform_register(&pdev->dev); + if (ret) + goto err_put_clk; + return 0; err_put_clk: diff --git a/sound/soc/omap/omap-hdmi-card.c b/sound/soc/omap/omap-hdmi-card.c index 7e66e9cba5a..f649fe84b62 100644 --- a/sound/soc/omap/omap-hdmi-card.c +++ b/sound/soc/omap/omap-hdmi-card.c @@ -33,7 +33,7 @@ static struct snd_soc_dai_link omap_hdmi_dai = { .name = "HDMI", .stream_name = "HDMI", .cpu_dai_name = "omap-hdmi-audio-dai", - .platform_name = "omap-pcm-audio", + .platform_name = "omap-hdmi-audio-dai", .codec_name = "hdmi-audio-codec", .codec_dai_name = "hdmi-hifi", }; diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index ced3b88b44d..eb9c39299f8 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c @@ -34,6 +34,7 @@ #include <sound/asoundef.h> #include <sound/dmaengine_pcm.h> #include <video/omapdss.h> +#include <sound/omap-pcm.h> #include "omap-hdmi.h" @@ -324,7 +325,10 @@ static int omap_hdmi_probe(struct platform_device *pdev) ret = snd_soc_register_component(&pdev->dev, &omap_hdmi_component, &omap_hdmi_dai, 1); - return ret; + if (ret) + return ret; + + return omap_pcm_platform_register(&pdev->dev); } static int omap_hdmi_remove(struct platform_device *pdev) diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 6c19bba2357..efe2cd699b7 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -34,6 +34,7 @@ #include <sound/initval.h> #include <sound/soc.h> #include <sound/dmaengine_pcm.h> +#include <sound/omap-pcm.h> #include <linux/platform_data/asoc-ti-mcbsp.h> #include "mcbsp.h" @@ -149,9 +150,6 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); } - snd_soc_dai_set_dma_data(cpu_dai, substream, - &mcbsp->dma_data[substream->stream]); - return err; } @@ -559,6 +557,10 @@ static int omap_mcbsp_probe(struct snd_soc_dai *dai) pm_runtime_enable(mcbsp->dev); + snd_soc_dai_init_dma_data(dai, + &mcbsp->dma_data[SNDRV_PCM_STREAM_PLAYBACK], + &mcbsp->dma_data[SNDRV_PCM_STREAM_CAPTURE]); + return 0; } @@ -691,7 +693,7 @@ OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \ OMAP_MCBSP_ST_CONTROLS(2); OMAP_MCBSP_ST_CONTROLS(3); -int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) +int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id) { struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); @@ -701,7 +703,7 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) return 0; } - switch (mcbsp->id) { + switch (port_id) { case 2: /* McBSP 2 */ return snd_soc_add_dai_controls(cpu_dai, omap_mcbsp2_st_controls, @@ -711,6 +713,7 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) omap_mcbsp3_st_controls, ARRAY_SIZE(omap_mcbsp3_st_controls)); default: + dev_err(mcbsp->dev, "Port %d not supported\n", port_id); break; } @@ -799,11 +802,15 @@ static int asoc_mcbsp_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mcbsp); ret = omap_mcbsp_init(pdev); - if (!ret) - return snd_soc_register_component(&pdev->dev, &omap_mcbsp_component, - &omap_mcbsp_dai, 1); + if (ret) + return ret; + + ret = snd_soc_register_component(&pdev->dev, &omap_mcbsp_component, + &omap_mcbsp_dai, 1); + if (ret) + return ret; - return ret; + return omap_pcm_platform_register(&pdev->dev); } static int asoc_mcbsp_remove(struct platform_device *pdev) diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h index ba8386a0d8d..2e3369c27be 100644 --- a/sound/soc/omap/omap-mcbsp.h +++ b/sound/soc/omap/omap-mcbsp.h @@ -39,6 +39,6 @@ enum omap_mcbsp_div { OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ }; -int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd); +int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id); #endif diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 2f5b1536477..f0e2ebeab02 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c @@ -40,6 +40,7 @@ #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/dmaengine_pcm.h> +#include <sound/omap-pcm.h> #include "omap-mcpdm.h" @@ -265,9 +266,6 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, } mutex_unlock(&mcpdm->mutex); - snd_soc_dai_set_dma_data(dai, substream, - &mcpdm->dma_data[substream->stream]); - return 0; } @@ -406,6 +404,11 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2; mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold = MCPDM_UP_THRES_MAX - 3; + + snd_soc_dai_init_dma_data(dai, + &mcpdm->dma_data[SNDRV_PCM_STREAM_PLAYBACK], + &mcpdm->dma_data[SNDRV_PCM_STREAM_CAPTURE]); + return ret; } @@ -460,6 +463,7 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) { struct omap_mcpdm *mcpdm; struct resource *res; + int ret; mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL); if (!mcpdm) @@ -490,9 +494,13 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) mcpdm->dev = &pdev->dev; - return devm_snd_soc_register_component(&pdev->dev, + ret = devm_snd_soc_register_component(&pdev->dev, &omap_mcpdm_component, &omap_mcpdm_dai, 1); + if (ret) + return ret; + + return omap_pcm_platform_register(&pdev->dev); } static const struct of_device_id omap_mcpdm_of_match[] = { diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 07b8b7bc9d2..8d809f8509c 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c @@ -232,31 +232,12 @@ static struct snd_soc_platform_driver omap_soc_platform = { .pcm_free = omap_pcm_free_dma_buffers, }; -static int omap_pcm_probe(struct platform_device *pdev) +int omap_pcm_platform_register(struct device *dev) { - return snd_soc_register_platform(&pdev->dev, - &omap_soc_platform); + return devm_snd_soc_register_platform(dev, &omap_soc_platform); } - -static int omap_pcm_remove(struct platform_device *pdev) -{ - snd_soc_unregister_platform(&pdev->dev); - return 0; -} - -static struct platform_driver omap_pcm_driver = { - .driver = { - .name = "omap-pcm-audio", - .owner = THIS_MODULE, - }, - - .probe = omap_pcm_probe, - .remove = omap_pcm_remove, -}; - -module_platform_driver(omap_pcm_driver); +EXPORT_SYMBOL_GPL(omap_pcm_platform_register); MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); MODULE_DESCRIPTION("OMAP PCM DMA module"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:omap-pcm-audio"); diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index 6a8d6b5f160..f8a6adc2d81 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c @@ -55,8 +55,7 @@ static int omap_twl4030_hw_params(struct snd_pcm_substream *substream, 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_codec *codec = rtd->codec; - struct snd_soc_card *card = codec->card; + struct snd_soc_card *card = rtd->card; unsigned int fmt; int ret; @@ -179,7 +178,7 @@ static inline void twl4030_disconnect_pin(struct snd_soc_dapm_context *dapm, static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_card *card = codec->card; + struct snd_soc_card *card = rtd->card; struct snd_soc_dapm_context *dapm = &codec->dapm; struct omap_tw4030_pdata *pdata = dev_get_platdata(card->dev); struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card); @@ -232,6 +231,18 @@ static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd) return ret; } +static int omap_twl4030_card_remove(struct snd_soc_card *card) +{ + struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card); + + if (priv->jack_detect > 0) + snd_soc_jack_free_gpios(&priv->hs_jack, + ARRAY_SIZE(hs_jack_gpios), + hs_jack_gpios); + + return 0; +} + /* Digital audio interface glue - connects codec <--> CPU */ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { { @@ -239,7 +250,7 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { .stream_name = "TWL4030 HiFi", .cpu_dai_name = "omap-mcbsp.2", .codec_dai_name = "twl4030-hifi", - .platform_name = "omap-pcm-audio", + .platform_name = "omap-mcbsp.2", .codec_name = "twl4030-codec", .init = omap_twl4030_init, .ops = &omap_twl4030_ops, @@ -249,7 +260,7 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { .stream_name = "TWL4030 Voice", .cpu_dai_name = "omap-mcbsp.3", .codec_dai_name = "twl4030-voice", - .platform_name = "omap-pcm-audio", + .platform_name = "omap-mcbsp.2", .codec_name = "twl4030-codec", .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM, @@ -259,6 +270,7 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { /* Audio machine driver */ static struct snd_soc_card omap_twl4030_card = { .owner = THIS_MODULE, + .remove = omap_twl4030_card_remove, .dai_link = omap_twl4030_dai_links, .num_links = ARRAY_SIZE(omap_twl4030_dai_links), @@ -299,12 +311,18 @@ static int omap_twl4030_probe(struct platform_device *pdev) omap_twl4030_dai_links[0].cpu_dai_name = NULL; omap_twl4030_dai_links[0].cpu_of_node = dai_node; + omap_twl4030_dai_links[0].platform_name = NULL; + omap_twl4030_dai_links[0].platform_of_node = dai_node; + dai_node = of_parse_phandle(node, "ti,mcbsp-voice", 0); if (!dai_node) { card->num_links = 1; } else { omap_twl4030_dai_links[1].cpu_dai_name = NULL; omap_twl4030_dai_links[1].cpu_of_node = dai_node; + + omap_twl4030_dai_links[1].platform_name = NULL; + omap_twl4030_dai_links[1].platform_of_node = dai_node; } priv->jack_detect = of_get_named_gpio(node, @@ -348,19 +366,6 @@ static int omap_twl4030_probe(struct platform_device *pdev) return 0; } -static int omap_twl4030_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card); - - if (priv->jack_detect > 0) - snd_soc_jack_free_gpios(&priv->hs_jack, - ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - - return 0; -} - static const struct of_device_id omap_twl4030_of_match[] = { {.compatible = "ti,omap-twl4030", }, { }, @@ -375,7 +380,6 @@ static struct platform_driver omap_twl4030_driver = { .of_match_table = omap_twl4030_of_match, }, .probe = omap_twl4030_probe, - .remove = omap_twl4030_remove, }; module_platform_driver(omap_twl4030_driver); diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index cf604a2faa1..076bec606d7 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -121,7 +121,7 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w, * |A| <~~clk~~+ * |P| <--- TWL4030 <--------- Line In and MICs */ -static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { +static const struct snd_soc_dapm_widget omap3pandora_dapm_widgets[] = { SND_SOC_DAPM_DAC_E("PCM DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0, omap3pandora_dac_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), @@ -130,22 +130,18 @@ static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_LINE("Line Out", NULL), -}; -static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = { SND_SOC_DAPM_MIC("Mic (internal)", NULL), SND_SOC_DAPM_MIC("Mic (external)", NULL), SND_SOC_DAPM_LINE("Line In", NULL), }; -static const struct snd_soc_dapm_route omap3pandora_out_map[] = { +static const struct snd_soc_dapm_route omap3pandora_map[] = { {"PCM DAC", NULL, "APLL Enable"}, {"Headphone Amplifier", NULL, "PCM DAC"}, {"Line Out", NULL, "PCM DAC"}, {"Headphone Jack", NULL, "Headphone Amplifier"}, -}; -static const struct snd_soc_dapm_route omap3pandora_in_map[] = { {"AUXL", NULL, "Line In"}, {"AUXR", NULL, "Line In"}, @@ -160,7 +156,6 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; /* All TWL4030 output pins are floating */ snd_soc_dapm_nc_pin(dapm, "EARPIECE"); @@ -174,20 +169,13 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "HFR"); snd_soc_dapm_nc_pin(dapm, "VIBRA"); - ret = snd_soc_dapm_new_controls(dapm, omap3pandora_out_dapm_widgets, - ARRAY_SIZE(omap3pandora_out_dapm_widgets)); - if (ret < 0) - return ret; - - return snd_soc_dapm_add_routes(dapm, omap3pandora_out_map, - ARRAY_SIZE(omap3pandora_out_map)); + return 0; } static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; /* Not comnnected */ snd_soc_dapm_nc_pin(dapm, "HSMIC"); @@ -195,13 +183,7 @@ static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); - ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets, - ARRAY_SIZE(omap3pandora_in_dapm_widgets)); - if (ret < 0) - return ret; - - return snd_soc_dapm_add_routes(dapm, omap3pandora_in_map, - ARRAY_SIZE(omap3pandora_in_map)); + return 0; } static struct snd_soc_ops omap3pandora_ops = { @@ -215,7 +197,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { .stream_name = "HiFi Out", .cpu_dai_name = "omap-mcbsp.2", .codec_dai_name = "twl4030-hifi", - .platform_name = "omap-pcm-audio", + .platform_name = "omap-mcbsp.2", .codec_name = "twl4030-codec", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, @@ -226,7 +208,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { .stream_name = "Line/Mic In", .cpu_dai_name = "omap-mcbsp.4", .codec_dai_name = "twl4030-hifi", - .platform_name = "omap-pcm-audio", + .platform_name = "omap-mcbsp.4", .codec_name = "twl4030-codec", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, @@ -241,6 +223,11 @@ static struct snd_soc_card snd_soc_card_omap3pandora = { .owner = THIS_MODULE, .dai_link = omap3pandora_dai, .num_links = ARRAY_SIZE(omap3pandora_dai), + + .dapm_widgets = omap3pandora_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(omap3pandora_dapm_widgets), + .dapm_routes = omap3pandora_map, + .num_dapm_routes = ARRAY_SIZE(omap3pandora_map), }; static struct platform_device *omap3pandora_snd_device; diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c index d03e57da770..aa4053bf671 100644 --- a/sound/soc/omap/osk5912.c +++ b/sound/soc/omap/osk5912.c @@ -96,7 +96,7 @@ static struct snd_soc_dai_link osk_dai = { .stream_name = "AIC23", .cpu_dai_name = "omap-mcbsp.1", .codec_dai_name = "tlv320aic23-hifi", - .platform_name = "omap-pcm-audio", + .platform_name = "omap-mcbsp.1", .codec_name = "tlv320aic23-codec", .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM, diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 7fb3d4b1037..943922c79f7 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -26,6 +26,7 @@ #include <linux/delay.h> #include <linux/gpio.h> #include <linux/platform_device.h> +#include <linux/gpio/consumer.h> #include <linux/module.h> #include <sound/core.h> #include <sound/jack.h> @@ -38,15 +39,6 @@ #include "omap-mcbsp.h" -#define RX51_TVOUT_SEL_GPIO 40 -#define RX51_JACK_DETECT_GPIO 177 -#define RX51_ECI_SW_GPIO 182 -/* - * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This - * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c - */ -#define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7) - enum { RX51_JACK_DISABLED, RX51_JACK_TVOUT, /* tv-out with stereo output */ @@ -54,12 +46,21 @@ enum { RX51_JACK_HS, /* headset: stereo output with mic */ }; +struct rx51_audio_pdata { + struct gpio_desc *tvout_selection_gpio; + struct gpio_desc *jack_detection_gpio; + struct gpio_desc *eci_sw_gpio; + struct gpio_desc *speaker_amp_gpio; +}; + static int rx51_spk_func; static int rx51_dmic_func; static int rx51_jack_func; static void rx51_ext_control(struct snd_soc_dapm_context *dapm) { + struct snd_soc_card *card = dapm->card; + struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); int hp = 0, hs = 0, tvout = 0; switch (rx51_jack_func) { @@ -93,7 +94,7 @@ static void rx51_ext_control(struct snd_soc_dapm_context *dapm) else snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic"); - gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout); + gpiod_set_value(pdata->tvout_selection_gpio, tvout); snd_soc_dapm_sync_unlocked(dapm); @@ -154,10 +155,12 @@ static int rx51_set_spk(struct snd_kcontrol *kcontrol, static int rx51_spk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *k, int event) { - if (SND_SOC_DAPM_EVENT_ON(event)) - gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 1); - else - gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 0); + struct snd_soc_dapm_context *dapm = w->dapm; + struct snd_soc_card *card = dapm->card; + struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); + + gpiod_set_raw_value_cansleep(pdata->speaker_amp_gpio, + !!SND_SOC_DAPM_EVENT_ON(event)); return 0; } @@ -223,7 +226,6 @@ static struct snd_soc_jack rx51_av_jack; static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = { { - .gpio = RX51_JACK_DETECT_GPIO, .name = "avdet-gpio", .report = SND_JACK_HEADSET, .invert = 1, @@ -237,9 +239,6 @@ static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event), SND_SOC_DAPM_MIC("HS Mic", NULL), SND_SOC_DAPM_LINE("FM Transmitter", NULL), -}; - -static const struct snd_soc_dapm_widget aic34_dapm_widgetsb[] = { SND_SOC_DAPM_SPK("Earphone", NULL), }; @@ -253,9 +252,7 @@ static const struct snd_soc_dapm_route audio_map[] = { {"DMic Rate 64", NULL, "Mic Bias"}, {"Mic Bias", NULL, "DMic"}, -}; -static const struct snd_soc_dapm_route audio_mapb[] = { {"b LINE2R", NULL, "MONO_LOUT"}, {"Earphone", NULL, "b HPLOUT"}, @@ -263,9 +260,11 @@ static const struct snd_soc_dapm_route audio_mapb[] = { {"b Mic Bias", NULL, "HS Mic"} }; -static const char *spk_function[] = {"Off", "On"}; -static const char *input_function[] = {"ADC", "Digital Mic"}; -static const char *jack_function[] = {"Off", "TV-OUT", "Headphone", "Headset"}; +static const char * const spk_function[] = {"Off", "On"}; +static const char * const input_function[] = {"ADC", "Digital Mic"}; +static const char * const jack_function[] = { + "Off", "TV-OUT", "Headphone", "Headset" +}; static const struct soc_enum rx51_enum[] = { SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), @@ -281,15 +280,15 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = { SOC_ENUM_EXT("Jack Function", rx51_enum[2], rx51_get_jack, rx51_set_jack), SOC_DAPM_PIN_SWITCH("FM Transmitter"), -}; - -static const struct snd_kcontrol_new aic34_rx51_controlsb[] = { SOC_DAPM_PIN_SWITCH("Earphone"), }; static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_card *card = rtd->card; + struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; @@ -298,57 +297,49 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "MIC3R"); snd_soc_dapm_nc_pin(dapm, "LINE1R"); - /* Add RX-51 specific controls */ - err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls, - ARRAY_SIZE(aic34_rx51_controls)); - if (err < 0) - return err; - - /* Add RX-51 specific widgets */ - snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets, - ARRAY_SIZE(aic34_dapm_widgets)); - - /* Set up RX-51 specific audio path audio_map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - err = tpa6130a2_add_controls(codec); - if (err < 0) + if (err < 0) { + dev_err(card->dev, "Failed to add TPA6130A2 controls\n"); return err; + } snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42); - err = omap_mcbsp_st_add_controls(rtd); - if (err < 0) + err = omap_mcbsp_st_add_controls(rtd, 2); + if (err < 0) { + dev_err(card->dev, "Failed to add MCBSP controls\n"); return err; + } /* AV jack detection */ err = snd_soc_jack_new(codec, "AV Jack", SND_JACK_HEADSET | SND_JACK_VIDEOOUT, &rx51_av_jack); - if (err) + if (err) { + dev_err(card->dev, "Failed to add AV Jack\n"); return err; + } + + /* prepare gpio for snd_soc_jack_add_gpios */ + rx51_av_jack_gpios[0].gpio = desc_to_gpio(pdata->jack_detection_gpio); + devm_gpiod_put(card->dev, pdata->jack_detection_gpio); + err = snd_soc_jack_add_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), rx51_av_jack_gpios); + if (err) { + dev_err(card->dev, "Failed to add GPIOs\n"); + return err; + } return err; } -static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm) +static int rx51_card_remove(struct snd_soc_card *card) { - int err; - - err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb, - ARRAY_SIZE(aic34_rx51_controlsb)); - if (err < 0) - return err; - - err = snd_soc_dapm_new_controls(dapm, aic34_dapm_widgetsb, - ARRAY_SIZE(aic34_dapm_widgetsb)); - if (err < 0) - return 0; + snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), + rx51_av_jack_gpios); - return snd_soc_dapm_add_routes(dapm, audio_mapb, - ARRAY_SIZE(audio_mapb)); + return 0; } /* Digital audio interface glue - connects codec <--> CPU */ @@ -358,7 +349,7 @@ static struct snd_soc_dai_link rx51_dai[] = { .stream_name = "AIC34", .cpu_dai_name = "omap-mcbsp.2", .codec_dai_name = "tlv320aic3x-hifi", - .platform_name = "omap-pcm-audio", + .platform_name = "omap-mcbsp.2", .codec_name = "tlv320aic3x-codec.2-0018", .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM, @@ -371,7 +362,6 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = { { .name = "TLV320AIC34b", .codec_name = "tlv320aic3x-codec.2-0019", - .init = rx51_aic34b_init, }, }; @@ -386,69 +376,158 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = { static struct snd_soc_card rx51_sound_card = { .name = "RX-51", .owner = THIS_MODULE, + .remove = rx51_card_remove, .dai_link = rx51_dai, .num_links = ARRAY_SIZE(rx51_dai), .aux_dev = rx51_aux_dev, .num_aux_devs = ARRAY_SIZE(rx51_aux_dev), .codec_conf = rx51_codec_conf, .num_configs = ARRAY_SIZE(rx51_codec_conf), -}; -static struct platform_device *rx51_snd_device; + .controls = aic34_rx51_controls, + .num_controls = ARRAY_SIZE(aic34_rx51_controls), + .dapm_widgets = aic34_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(aic34_dapm_widgets), + .dapm_routes = audio_map, + .num_dapm_routes = ARRAY_SIZE(audio_map), +}; -static int __init rx51_soc_init(void) +static int rx51_soc_probe(struct platform_device *pdev) { + struct rx51_audio_pdata *pdata; + struct device_node *np = pdev->dev.of_node; + struct snd_soc_card *card = &rx51_sound_card; int err; if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900")) return -ENODEV; - err = gpio_request_one(RX51_TVOUT_SEL_GPIO, - GPIOF_DIR_OUT | GPIOF_INIT_LOW, "tvout_sel"); - if (err) - goto err_gpio_tvout_sel; - err = gpio_request_one(RX51_ECI_SW_GPIO, - GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "eci_sw"); - if (err) - goto err_gpio_eci_sw; - - rx51_snd_device = platform_device_alloc("soc-audio", -1); - if (!rx51_snd_device) { - err = -ENOMEM; - goto err1; + card->dev = &pdev->dev; + + if (np) { + struct device_node *dai_node; + + dai_node = of_parse_phandle(np, "nokia,cpu-dai", 0); + if (!dai_node) { + dev_err(&pdev->dev, "McBSP node is not provided\n"); + return -EINVAL; + } + rx51_dai[0].cpu_dai_name = NULL; + rx51_dai[0].platform_name = NULL; + rx51_dai[0].cpu_of_node = dai_node; + rx51_dai[0].platform_of_node = dai_node; + + dai_node = of_parse_phandle(np, "nokia,audio-codec", 0); + if (!dai_node) { + dev_err(&pdev->dev, "Codec node is not provided\n"); + return -EINVAL; + } + rx51_dai[0].codec_name = NULL; + rx51_dai[0].codec_of_node = dai_node; + + dai_node = of_parse_phandle(np, "nokia,audio-codec", 1); + if (!dai_node) { + dev_err(&pdev->dev, "Auxiliary Codec node is not provided\n"); + return -EINVAL; + } + rx51_aux_dev[0].codec_name = NULL; + rx51_aux_dev[0].codec_of_node = dai_node; + rx51_codec_conf[0].dev_name = NULL; + rx51_codec_conf[0].of_node = dai_node; + + dai_node = of_parse_phandle(np, "nokia,headphone-amplifier", 0); + if (!dai_node) { + dev_err(&pdev->dev, "Headphone amplifier node is not provided\n"); + return -EINVAL; + } + + /* TODO: tpa6130a2a driver supports only a single instance, so + * this driver ignores the headphone-amplifier node for now. + * It's already mandatory in the DT binding to be future proof. + */ } - platform_set_drvdata(rx51_snd_device, &rx51_sound_card); + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (pdata == NULL) { + dev_err(card->dev, "failed to create private data\n"); + return -ENOMEM; + } + snd_soc_card_set_drvdata(card, pdata); - err = platform_device_add(rx51_snd_device); - if (err) - goto err2; + pdata->tvout_selection_gpio = devm_gpiod_get(card->dev, + "tvout-selection"); + if (IS_ERR(pdata->tvout_selection_gpio)) { + dev_err(card->dev, "could not get tvout selection gpio\n"); + return PTR_ERR(pdata->tvout_selection_gpio); + } - return 0; -err2: - platform_device_put(rx51_snd_device); -err1: - gpio_free(RX51_ECI_SW_GPIO); -err_gpio_eci_sw: - gpio_free(RX51_TVOUT_SEL_GPIO); -err_gpio_tvout_sel: + err = gpiod_direction_output(pdata->tvout_selection_gpio, 0); + if (err) { + dev_err(card->dev, "could not setup tvout selection gpio\n"); + return err; + } - return err; -} + pdata->jack_detection_gpio = devm_gpiod_get(card->dev, + "jack-detection"); + if (IS_ERR(pdata->jack_detection_gpio)) { + dev_err(card->dev, "could not get jack detection gpio\n"); + return PTR_ERR(pdata->jack_detection_gpio); + } -static void __exit rx51_soc_exit(void) -{ - snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), - rx51_av_jack_gpios); + pdata->eci_sw_gpio = devm_gpiod_get(card->dev, "eci-switch"); + if (IS_ERR(pdata->eci_sw_gpio)) { + dev_err(card->dev, "could not get eci switch gpio\n"); + return PTR_ERR(pdata->eci_sw_gpio); + } - platform_device_unregister(rx51_snd_device); - gpio_free(RX51_ECI_SW_GPIO); - gpio_free(RX51_TVOUT_SEL_GPIO); + err = gpiod_direction_output(pdata->eci_sw_gpio, 1); + if (err) { + dev_err(card->dev, "could not setup eci switch gpio\n"); + return err; + } + + pdata->speaker_amp_gpio = devm_gpiod_get(card->dev, + "speaker-amplifier"); + if (IS_ERR(pdata->speaker_amp_gpio)) { + dev_err(card->dev, "could not get speaker enable gpio\n"); + return PTR_ERR(pdata->speaker_amp_gpio); + } + + err = gpiod_direction_output(pdata->speaker_amp_gpio, 0); + if (err) { + dev_err(card->dev, "could not setup speaker enable gpio\n"); + return err; + } + + err = devm_snd_soc_register_card(card->dev, card); + if (err) { + dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", err); + return err; + } + + return 0; } -module_init(rx51_soc_init); -module_exit(rx51_soc_exit); +#if defined(CONFIG_OF) +static const struct of_device_id rx51_audio_of_match[] = { + { .compatible = "nokia,n900-audio", }, + {}, +}; +MODULE_DEVICE_TABLE(of, rx51_audio_of_match); +#endif + +static struct platform_driver rx51_soc_driver = { + .driver = { + .name = "rx51-audio", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(rx51_audio_of_match), + }, + .probe = rx51_soc_probe, +}; + +module_platform_driver(rx51_soc_driver); MODULE_AUTHOR("Nokia Corporation"); MODULE_DESCRIPTION("ALSA SoC Nokia RX-51"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:rx51-audio"); |