diff options
Diffstat (limited to 'sound/soc/sunxi')
-rw-r--r-- | sound/soc/sunxi/sun4i-codec.c | 57 | ||||
-rw-r--r-- | sound/soc/sunxi/sun4i-spdif.c | 6 | ||||
-rw-r--r-- | sound/soc/sunxi/sun50i-dmic.c | 6 | ||||
-rw-r--r-- | sound/soc/sunxi/sun8i-codec.c | 19 |
4 files changed, 70 insertions, 18 deletions
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 886b3fa537d2..93733ff2e32a 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c @@ -22,6 +22,7 @@ #include <linux/gpio/consumer.h> #include <sound/core.h> +#include <sound/jack.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> @@ -331,6 +332,7 @@ struct sun4i_codec { struct clk *clk_module; struct reset_control *rst; struct gpio_desc *gpio_pa; + struct gpio_desc *gpio_hp; /* ADC_FIFOC register is at different offset on different SoCs */ struct regmap_field *reg_adc_fifoc; @@ -1583,6 +1585,49 @@ static struct snd_soc_dai_driver dummy_cpu_dai = { .ops = &dummy_dai_ops, }; +static struct snd_soc_jack sun4i_headphone_jack; + +static struct snd_soc_jack_pin sun4i_headphone_jack_pins[] = { + { .pin = "Headphone", .mask = SND_JACK_HEADPHONE }, +}; + +static struct snd_soc_jack_gpio sun4i_headphone_jack_gpio = { + .name = "hp-det", + .report = SND_JACK_HEADPHONE, + .debounce_time = 150, +}; + +static int sun4i_codec_machine_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct sun4i_codec *scodec = snd_soc_card_get_drvdata(card); + int ret; + + if (scodec->gpio_hp) { + ret = snd_soc_card_jack_new_pins(card, "Headphone Jack", + SND_JACK_HEADPHONE, + &sun4i_headphone_jack, + sun4i_headphone_jack_pins, + ARRAY_SIZE(sun4i_headphone_jack_pins)); + if (ret) { + dev_err(rtd->dev, + "Headphone jack creation failed: %d\n", ret); + return ret; + } + + sun4i_headphone_jack_gpio.desc = scodec->gpio_hp; + ret = snd_soc_jack_add_gpios(&sun4i_headphone_jack, 1, + &sun4i_headphone_jack_gpio); + + if (ret) { + dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret); + return ret; + } + } + + return 0; +} + static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev, int *num_links) { @@ -1608,6 +1653,7 @@ static struct snd_soc_dai_link *sun4i_codec_create_link(struct device *dev, link->codecs->name = dev_name(dev); link->platforms->name = dev_name(dev); link->dai_fmt = SND_SOC_DAIFMT_I2S; + link->init = sun4i_codec_machine_init; *num_links = 1; @@ -1916,10 +1962,11 @@ static const struct snd_soc_component_driver sun50i_h616_codec_codec = { }; static const struct snd_kcontrol_new sun50i_h616_card_controls[] = { - SOC_DAPM_PIN_SWITCH("LINEOUT"), + SOC_DAPM_PIN_SWITCH("Speaker"), }; static const struct snd_soc_dapm_widget sun50i_h616_codec_card_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_LINE("Line Out", NULL), SND_SOC_DAPM_SPK("Speaker", sun4i_codec_spk_event), }; @@ -1966,6 +2013,7 @@ static struct snd_soc_card *sun50i_h616_codec_create_card(struct device *dev) card->dev = dev; card->owner = THIS_MODULE; card->name = "H616 Audio Codec"; + card->long_name = "h616-audio-codec"; card->driver_name = "sun4i-codec"; card->controls = sun50i_h616_card_controls; card->num_controls = ARRAY_SIZE(sun50i_h616_card_controls); @@ -2301,6 +2349,13 @@ static int sun4i_codec_probe(struct platform_device *pdev) return ret; } + scodec->gpio_hp = devm_gpiod_get_optional(&pdev->dev, "hp-det", GPIOD_IN); + if (IS_ERR(scodec->gpio_hp)) { + ret = PTR_ERR(scodec->gpio_hp); + dev_err_probe(&pdev->dev, ret, "Failed to get hp-det gpio\n"); + return ret; + } + /* reg_field setup */ scodec->reg_adc_fifoc = devm_regmap_field_alloc(&pdev->dev, scodec->regmap, diff --git a/sound/soc/sunxi/sun4i-spdif.c b/sound/soc/sunxi/sun4i-spdif.c index 41caf1795d09..34e5bd94e9af 100644 --- a/sound/soc/sunxi/sun4i-spdif.c +++ b/sound/soc/sunxi/sun4i-spdif.c @@ -727,15 +727,15 @@ static void sun4i_spdif_remove(struct platform_device *pdev) } static const struct dev_pm_ops sun4i_spdif_pm = { - SET_RUNTIME_PM_OPS(sun4i_spdif_runtime_suspend, - sun4i_spdif_runtime_resume, NULL) + RUNTIME_PM_OPS(sun4i_spdif_runtime_suspend, + sun4i_spdif_runtime_resume, NULL) }; static struct platform_driver sun4i_spdif_driver = { .driver = { .name = "sun4i-spdif", .of_match_table = sun4i_spdif_of_match, - .pm = &sun4i_spdif_pm, + .pm = pm_ptr(&sun4i_spdif_pm), }, .probe = sun4i_spdif_probe, .remove = sun4i_spdif_remove, diff --git a/sound/soc/sunxi/sun50i-dmic.c b/sound/soc/sunxi/sun50i-dmic.c index 3e751b5694fe..bab1e29c9988 100644 --- a/sound/soc/sunxi/sun50i-dmic.c +++ b/sound/soc/sunxi/sun50i-dmic.c @@ -415,15 +415,15 @@ static void sun50i_dmic_remove(struct platform_device *pdev) } static const struct dev_pm_ops sun50i_dmic_pm = { - SET_RUNTIME_PM_OPS(sun50i_dmic_runtime_suspend, - sun50i_dmic_runtime_resume, NULL) + RUNTIME_PM_OPS(sun50i_dmic_runtime_suspend, + sun50i_dmic_runtime_resume, NULL) }; static struct platform_driver sun50i_dmic_driver = { .driver = { .name = "sun50i-dmic", .of_match_table = sun50i_dmic_of_match, - .pm = &sun50i_dmic_pm, + .pm = pm_ptr(&sun50i_dmic_pm), }, .probe = sun50i_dmic_probe, .remove = sun50i_dmic_remove, diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 8c645e04d571..7b3496caa31e 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -248,12 +248,10 @@ static int sun8i_codec_runtime_resume(struct device *dev) struct sun8i_codec *scodec = dev_get_drvdata(dev); int ret; - if (scodec->clk_bus) { - ret = clk_prepare_enable(scodec->clk_bus); - if (ret) { - dev_err(dev, "Failed to enable the bus clock\n"); - return ret; - } + ret = clk_prepare_enable(scodec->clk_bus); + if (ret) { + dev_err(dev, "Failed to enable the bus clock\n"); + return ret; } regcache_cache_only(scodec->regmap, false); @@ -274,8 +272,7 @@ static int sun8i_codec_runtime_suspend(struct device *dev) regcache_cache_only(scodec->regmap, true); regcache_mark_dirty(scodec->regmap); - if (scodec->clk_bus) - clk_disable_unprepare(scodec->clk_bus); + clk_disable_unprepare(scodec->clk_bus); return 0; } @@ -1702,15 +1699,15 @@ static const struct of_device_id sun8i_codec_of_match[] = { MODULE_DEVICE_TABLE(of, sun8i_codec_of_match); static const struct dev_pm_ops sun8i_codec_pm_ops = { - SET_RUNTIME_PM_OPS(sun8i_codec_runtime_suspend, - sun8i_codec_runtime_resume, NULL) + RUNTIME_PM_OPS(sun8i_codec_runtime_suspend, + sun8i_codec_runtime_resume, NULL) }; static struct platform_driver sun8i_codec_driver = { .driver = { .name = "sun8i-codec", .of_match_table = sun8i_codec_of_match, - .pm = &sun8i_codec_pm_ops, + .pm = pm_ptr(&sun8i_codec_pm_ops), }, .probe = sun8i_codec_probe, .remove = sun8i_codec_remove, |