Merge remote-tracking branches 'asoc/topic/headers', 'asoc/topic/intel', 'asoc/topic...
[firefly-linux-kernel-4.4.55.git] / sound / soc / jz4740 / qi_lb60.c
index 82b5f37cd2c78ab16be9eda44b751201d8b9f09d..5cb91f9e86261b03afcb70583cd83f17ec3e4729 100644 (file)
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 
-#define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29)
-#define QI_LB60_AMP_GPIO JZ_GPIO_PORTD(4)
+struct qi_lb60 {
+       struct gpio_desc *snd_gpio;
+       struct gpio_desc *amp_gpio;
+};
 
 static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget,
                             struct snd_kcontrol *ctrl, int event)
 {
+       struct qi_lb60 *qi_lb60 = snd_soc_card_get_drvdata(widget->dapm->card);
        int on = !SND_SOC_DAPM_EVENT_OFF(event);
 
-       gpio_set_value(QI_LB60_SND_GPIO, on);
-       gpio_set_value(QI_LB60_AMP_GPIO, on);
+       gpiod_set_value_cansleep(qi_lb60->snd_gpio, on);
+       gpiod_set_value_cansleep(qi_lb60->amp_gpio, on);
 
        return 0;
 }
@@ -46,29 +49,6 @@ static const struct snd_soc_dapm_route qi_lb60_routes[] = {
        {"Speaker", NULL, "ROUT"},
 };
 
-#define QI_LB60_DAIFMT (SND_SOC_DAIFMT_I2S | \
-                       SND_SOC_DAIFMT_NB_NF | \
-                       SND_SOC_DAIFMT_CBM_CFM)
-
-static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_codec *codec = rtd->codec;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-       struct snd_soc_dapm_context *dapm = &codec->dapm;
-       int ret;
-
-       snd_soc_dapm_nc_pin(dapm, "LIN");
-       snd_soc_dapm_nc_pin(dapm, "RIN");
-
-       ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT);
-       if (ret < 0) {
-               dev_err(codec->dev, "Failed to set cpu dai format: %d\n", ret);
-               return ret;
-       }
-
-       return 0;
-}
-
 static struct snd_soc_dai_link qi_lb60_dai = {
        .name = "jz4740",
        .stream_name = "jz4740",
@@ -76,10 +56,11 @@ static struct snd_soc_dai_link qi_lb60_dai = {
        .platform_name = "jz4740-i2s",
        .codec_dai_name = "jz4740-hifi",
        .codec_name = "jz4740-codec",
-       .init = qi_lb60_codec_init,
+       .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
+               SND_SOC_DAIFMT_CBM_CFM,
 };
 
-static struct snd_soc_card qi_lb60 = {
+static struct snd_soc_card qi_lb60_card = {
        .name = "QI LB60",
        .owner = THIS_MODULE,
        .dai_link = &qi_lb60_dai,
@@ -89,40 +70,38 @@ static struct snd_soc_card qi_lb60 = {
        .num_dapm_widgets = ARRAY_SIZE(qi_lb60_widgets),
        .dapm_routes = qi_lb60_routes,
        .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes),
-};
-
-static const struct gpio qi_lb60_gpios[] = {
-       { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" },
-       { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" },
+       .fully_routed = true,
 };
 
 static int qi_lb60_probe(struct platform_device *pdev)
 {
-       struct snd_soc_card *card = &qi_lb60;
+       struct qi_lb60 *qi_lb60;
+       struct snd_soc_card *card = &qi_lb60_card;
        int ret;
 
-       ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
+       qi_lb60 = devm_kzalloc(&pdev->dev, sizeof(*qi_lb60), GFP_KERNEL);
+       if (!qi_lb60)
+               return -ENOMEM;
+
+       qi_lb60->snd_gpio = devm_gpiod_get(&pdev->dev, "snd");
+       if (IS_ERR(qi_lb60->snd_gpio))
+               return PTR_ERR(qi_lb60->snd_gpio);
+       ret = gpiod_direction_output(qi_lb60->snd_gpio, 0);
        if (ret)
                return ret;
 
-       card->dev = &pdev->dev;
+       qi_lb60->amp_gpio = devm_gpiod_get(&pdev->dev, "amp");
+       if (IS_ERR(qi_lb60->amp_gpio))
+               return PTR_ERR(qi_lb60->amp_gpio);
+       ret = gpiod_direction_output(qi_lb60->amp_gpio, 0);
+       if (ret)
+               return ret;
 
-       ret = snd_soc_register_card(card);
-       if (ret) {
-               dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
-                       ret);
-               gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
-       }
-       return ret;
-}
+       card->dev = &pdev->dev;
 
-static int qi_lb60_remove(struct platform_device *pdev)
-{
-       struct snd_soc_card *card = platform_get_drvdata(pdev);
+       snd_soc_card_set_drvdata(card, qi_lb60);
 
-       snd_soc_unregister_card(card);
-       gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios));
-       return 0;
+       return devm_snd_soc_register_card(&pdev->dev, card);
 }
 
 static struct platform_driver qi_lb60_driver = {
@@ -131,7 +110,6 @@ static struct platform_driver qi_lb60_driver = {
                .owner  = THIS_MODULE,
        },
        .probe          = qi_lb60_probe,
-       .remove         = qi_lb60_remove,
 };
 
 module_platform_driver(qi_lb60_driver);