diff options
Diffstat (limited to 'sound/soc/samsung/speyside.c')
| -rw-r--r-- | sound/soc/samsung/speyside.c | 163 |
1 files changed, 99 insertions, 64 deletions
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 4b4147d07804..26701a55fe0a 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c @@ -1,24 +1,19 @@ -/* - * Speyside audio support - * - * Copyright 2011 Wolfson Microelectronics - * - * 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. - */ +// SPDX-License-Identifier: GPL-2.0+ +// +// Speyside audio support +// +// Copyright 2011 Wolfson Microelectronics #include <sound/soc.h> #include <sound/soc-dapm.h> #include <sound/jack.h> -#include <linux/gpio.h> +#include <linux/gpio/machine.h> +#include <linux/gpio/consumer.h> #include <linux/module.h> #include "../codecs/wm8996.h" #include "../codecs/wm9081.h" -#define WM8996_HPSEL_GPIO 214 #define MCLK_AUDIO_RATE (512 * 48000) static int speyside_set_bias_level(struct snd_soc_card *card, @@ -29,10 +24,10 @@ static int speyside_set_bias_level(struct snd_soc_card *card, struct snd_soc_dai *codec_dai; int ret; - rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name); - codec_dai = rtd->codec_dai; + rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[1]); + codec_dai = snd_soc_rtd_to_codec(rtd, 0); - if (dapm->dev != codec_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != codec_dai->dev) return 0; switch (level) { @@ -65,15 +60,15 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card, struct snd_soc_dai *codec_dai; int ret; - rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name); - codec_dai = rtd->codec_dai; + rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[1]); + codec_dai = snd_soc_rtd_to_codec(rtd, 0); - if (dapm->dev != codec_dai->dev) + if (snd_soc_dapm_to_dev(dapm) != codec_dai->dev) return 0; switch (level) { case SND_SOC_BIAS_PREPARE: - if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) { + if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_STANDBY) { ret = snd_soc_dai_set_pll(codec_dai, 0, WM8996_FLL_MCLK2, 32768, MCLK_AUDIO_RATE); @@ -95,8 +90,6 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card, break; } - card->dapm.bias_level = level; - return 0; } @@ -110,15 +103,16 @@ static struct snd_soc_jack_pin speyside_headset_pins[] = { }, }; +static struct gpio_desc *speyside_hpsel_gpio; /* Default the headphone selection to active high */ static int speyside_jack_polarity; static int speyside_get_micbias(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { - if (speyside_jack_polarity && (strcmp(source->name, "MICB1") == 0)) + if (speyside_jack_polarity && (snd_soc_dapm_widget_name_cmp(source, "MICB1") == 0)) return 1; - if (!speyside_jack_polarity && (strcmp(source->name, "MICB2") == 0)) + if (!speyside_jack_polarity && (snd_soc_dapm_widget_name_cmp(source, "MICB2") == 0)) return 1; return 0; @@ -128,15 +122,15 @@ static void speyside_set_polarity(struct snd_soc_component *component, int polarity) { speyside_jack_polarity = !polarity; - gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); + gpiod_direction_output(speyside_hpsel_gpio, speyside_jack_polarity); /* Re-run DAPM to make sure we're using the correct mic bias */ - snd_soc_dapm_sync(snd_soc_component_get_dapm(component)); + snd_soc_dapm_sync(snd_soc_component_to_dapm(component)); } static int speyside_wm0010_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *dai = rtd->codec_dai; + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); int ret; ret = snd_soc_dai_set_sysclk(dai, 0, MCLK_AUDIO_RATE, 0); @@ -148,23 +142,31 @@ static int speyside_wm0010_init(struct snd_soc_pcm_runtime *rtd) static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_dai *dai = rtd->codec_dai; + struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0); struct snd_soc_component *component = dai->component; + enum gpiod_flags flags; int ret; ret = snd_soc_dai_set_sysclk(dai, WM8996_SYSCLK_MCLK2, 32768, 0); if (ret < 0) return ret; - ret = gpio_request(WM8996_HPSEL_GPIO, "HP_SEL"); - if (ret != 0) - pr_err("Failed to request HP_SEL GPIO: %d\n", ret); - gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); - - ret = snd_soc_card_jack_new(rtd->card, "Headset", SND_JACK_LINEOUT | - SND_JACK_HEADSET | SND_JACK_BTN_0, - &speyside_headset, speyside_headset_pins, - ARRAY_SIZE(speyside_headset_pins)); + if (speyside_jack_polarity) + flags = GPIOD_OUT_HIGH; + else + flags = GPIOD_OUT_LOW; + speyside_hpsel_gpio = devm_gpiod_get(rtd->card->dev, + "hp-sel", + flags); + if (IS_ERR(speyside_hpsel_gpio)) + return PTR_ERR(speyside_hpsel_gpio); + + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset", + SND_JACK_LINEOUT | SND_JACK_HEADSET | + SND_JACK_BTN_0, + &speyside_headset, + speyside_headset_pins, + ARRAY_SIZE(speyside_headset_pins)); if (ret) return ret; @@ -175,13 +177,15 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) static int speyside_late_probe(struct snd_soc_card *card) { - snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Main Speaker"); - snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output"); - snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input"); + struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card); + + snd_soc_dapm_ignore_suspend(dapm, "Headphone"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Main AMIC"); + snd_soc_dapm_ignore_suspend(dapm, "Main DMIC"); + snd_soc_dapm_ignore_suspend(dapm, "Main Speaker"); + snd_soc_dapm_ignore_suspend(dapm, "WM1250 Output"); + snd_soc_dapm_ignore_suspend(dapm, "WM1250 Input"); return 0; } @@ -194,39 +198,46 @@ static const struct snd_soc_pcm_stream dsp_codec_params = { .channels_max = 2, }; +SND_SOC_DAILINK_DEFS(cpu_dsp, + DAILINK_COMP_ARRAY(COMP_CPU("samsung-i2s.0")), + DAILINK_COMP_ARRAY(COMP_CODEC("spi0.0", "wm0010-sdi1")), + DAILINK_COMP_ARRAY(COMP_PLATFORM("samsung-i2s.0"))); + +SND_SOC_DAILINK_DEFS(dsp_codec, + DAILINK_COMP_ARRAY(COMP_CPU("wm0010-sdi2")), + DAILINK_COMP_ARRAY(COMP_CODEC("wm8996.1-001a", "wm8996-aif1"))); + +SND_SOC_DAILINK_DEFS(baseband, + DAILINK_COMP_ARRAY(COMP_CPU("wm8996-aif2")), + DAILINK_COMP_ARRAY(COMP_CODEC("wm1250-ev1.1-0027", "wm1250-ev1"))); + static struct snd_soc_dai_link speyside_dai[] = { { .name = "CPU-DSP", .stream_name = "CPU-DSP", - .cpu_dai_name = "samsung-i2s.0", - .codec_dai_name = "wm0010-sdi1", - .platform_name = "samsung-i2s.0", - .codec_name = "spi0.0", .init = speyside_wm0010_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, + SND_SOC_DAILINK_REG(cpu_dsp), }, { .name = "DSP-CODEC", .stream_name = "DSP-CODEC", - .cpu_dai_name = "wm0010-sdi2", - .codec_dai_name = "wm8996-aif1", - .codec_name = "wm8996.1-001a", .init = speyside_wm8996_init, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, - .params = &dsp_codec_params, + | SND_SOC_DAIFMT_CBP_CFP, + .c2c_params = &dsp_codec_params, + .num_c2c_params = 1, .ignore_suspend = 1, + SND_SOC_DAILINK_REG(dsp_codec), }, { .name = "Baseband", .stream_name = "Baseband", - .cpu_dai_name = "wm8996-aif2", - .codec_dai_name = "wm1250-ev1", - .codec_name = "wm1250-ev1.1-0027", .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM, + | SND_SOC_DAIFMT_CBP_CFP, .ignore_suspend = 1, + SND_SOC_DAILINK_REG(baseband), }, }; @@ -239,15 +250,14 @@ static int speyside_wm9081_init(struct snd_soc_component *component) static struct snd_soc_aux_dev speyside_aux_dev[] = { { - .name = "wm9081", - .codec_name = "wm9081.1-006c", + .dlc = COMP_AUX("wm9081.1-006c"), .init = speyside_wm9081_init, }, }; static struct snd_soc_codec_conf speyside_codec_conf[] = { { - .dev_name = "wm9081.1-006c", + .dlc = COMP_CODEC_CONF("wm9081.1-006c"), .name_prefix = "Sub", }, }; @@ -261,7 +271,7 @@ static const struct snd_kcontrol_new controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), }; -static struct snd_soc_dapm_widget widgets[] = { +static const struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), @@ -271,7 +281,7 @@ static struct snd_soc_dapm_widget widgets[] = { SND_SOC_DAPM_MIC("Main DMIC", NULL), }; -static struct snd_soc_dapm_route audio_paths[] = { +static const struct snd_soc_dapm_route audio_paths[] = { { "IN1RN", NULL, "MICB1" }, { "IN1RP", NULL, "MICB1" }, { "IN1RN", NULL, "MICB2" }, @@ -322,6 +332,26 @@ static struct snd_soc_card speyside = { .late_probe = speyside_late_probe, }; +static struct gpiod_lookup_table wm8996_gpiod_table = { + /* Hardcoded device name in board file mach-crag6410.c */ + .dev_id = "speyside", + .table = { + /* + * This line was hardcoded to 214 in the global GPIO + * number space, S3C GPIO macros seems top set the + * wm8996 codec GPIO start offset to 212, so this will + * be GPIO 214 - 212 = 2 on the wm8996. + */ + GPIO_LOOKUP("wm8996", 2, "hp-sel", GPIO_ACTIVE_HIGH), + { }, + }, +}; + +static void speyside_gpiod_table_action(void *data) +{ + gpiod_remove_lookup_table(&wm8996_gpiod_table); +} + static int speyside_probe(struct platform_device *pdev) { struct snd_soc_card *card = &speyside; @@ -329,10 +359,15 @@ static int speyside_probe(struct platform_device *pdev) card->dev = &pdev->dev; + gpiod_add_lookup_table(&wm8996_gpiod_table); + ret = devm_add_action_or_reset(&pdev->dev, speyside_gpiod_table_action, + NULL); + if (ret) + return ret; + ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); + dev_err_probe(&pdev->dev, ret, "snd_soc_register_card() failed\n"); return ret; } |
