]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
ASoC: tegra-alt: Support for no-codec case on Jetson-CV
authorSameer Pujar <spujar@nvidia.com>
Sun, 9 Aug 2015 05:12:51 +0000 (10:42 +0530)
committermobile promotions <svcmobile_promotions@nvidia.com>
Mon, 10 Aug 2015 18:56:03 +0000 (11:56 -0700)
This change is to handle the case when jetson-cv platform,
does not have audio codec connected. In this case the AV
playback usecases on other output devices or on primary
should be still fine.

Bug 1670783
Bug 200118114

Change-Id: Ifc4c6de950081e84789c25588735b050dc22bb00
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Reviewed-on: http://git-master/r/780780
Reviewed-by: Ravindra Lokhande <rlokhande@nvidia.com>
Reviewed-by: Dara Ramesh <dramesh@nvidia.com>
sound/soc/tegra-alt/tegra_t210ref_mobile_rt565x_alt.c

index 9370aa11f05be1331448f1d8141e30ecf9ab5dbb..73dbbc07291a6730c7d4bb83299ac6903a3cb9a1 100644 (file)
@@ -67,20 +67,21 @@ struct tegra_t210ref {
        struct regulator *spk_reg;
        struct regulator *dmic_reg;
        struct snd_soc_card *pcard;
+       int is_codec_dummy;
 };
 
 static struct snd_soc_jack tegra_t210ref_hp_jack;
 
 static struct snd_soc_jack_gpio tegra_t210ref_hp_jack_gpio = {
-        .name = "headphone detect",
-        .report = SND_JACK_HEADPHONE,
-        .debounce_time = 150,
-        .invert = 1,
+       .name = "headphone detect",
+       .report = SND_JACK_HEADPHONE,
+       .debounce_time = 150,
+       .invert = 1,
 };
 
 #ifdef CONFIG_SWITCH
 static struct switch_dev tegra_t210ref_headset_switch = {
-        .name = "h2w",
+       .name = "h2w",
 };
 
 static int tegra_t210ref_startup(struct snd_pcm_substream *substream)
@@ -103,6 +104,10 @@ static int tegra_t210ref_jack_notifier(struct notifier_block *self,
        enum headset_state state = BIT_NO_HEADSET;
        unsigned char status_jack = 0;
        int idx = 0;
+       struct tegra_asoc_platform_data *pdata = machine->pdata;
+
+       if (!gpio_is_valid(pdata->gpio_hp_det))
+               return NOTIFY_OK;
 
        idx = tegra_machine_get_codec_dai_link_idx("rt565x-playback");
        /* check if idx has valid number */
@@ -180,6 +185,9 @@ static int tegra_t210ref_dai_init(struct snd_soc_pcm_runtime *rtd,
        unsigned int idx, mclk, clk_out_rate;
        int err;
 
+       if (machine->is_codec_dummy)
+               return 0;
+
        switch (rate) {
        case 11025:
        case 22050:
@@ -537,44 +545,53 @@ static struct snd_soc_card snd_soc_tegra_t210ref = {
        .fully_routed = true,
 };
 
-static int tegra_t210ref_driver_probe(struct platform_device *pdev)
+static void replace_codec_link(struct platform_device *pdev,
+       struct snd_soc_dai_link *links)
 {
+       int i;
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+       struct tegra_t210ref *machine = snd_soc_card_get_drvdata(card);
        struct device_node *np = pdev->dev.of_node;
-       struct snd_soc_card *card = &snd_soc_tegra_t210ref;
-       struct tegra_t210ref *machine;
-       struct snd_soc_dai_link *tegra_machine_dai_links = NULL;
-       struct snd_soc_dai_link *tegra_t210ref_codec_links = NULL;
-       struct snd_soc_codec_conf *tegra_machine_codec_conf = NULL;
-       struct snd_soc_codec_conf *tegra_t210ref_codec_conf = NULL;
-       struct tegra_asoc_platform_data *pdata = NULL;
-       struct snd_soc_codec *codec = NULL;
-       int ret = 0, i, idx;
 
-       if (!np) {
-               dev_err(&pdev->dev, "No device tree node for t210ref driver");
-               return -ENODEV;
-       }
+       for (i = 0; i < machine->num_codec_links; i++) {
+               if (links[i].name &&
+                       (strstr(links[i].name, "rt565x-playback"))) {
+                       links[i].init = NULL;
 
-       machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_t210ref),
-                              GFP_KERNEL);
-       if (!machine) {
-               dev_err(&pdev->dev, "Can't allocate tegra_t210ref struct\n");
-               ret = -ENOMEM;
-               goto err;
+                       links[i].codec_of_node =
+                               of_parse_phandle(np, "nvidia,dummy-codec-dai",
+                                       0);
+
+                       machine->is_codec_dummy = 1;
+
+                       if (of_property_read_string(np,
+                               "nvidia,dummy-codec-dai-name",
+                               &links[i].codec_dai_name)) {
+                               dev_err(&pdev->dev, "Property 'dummy-codec-dai\
+                                       -name' missing or invalid\n");
+                       }
+               }
        }
 
-       card->dev = &pdev->dev;
-       platform_set_drvdata(pdev, card);
-       snd_soc_card_set_drvdata(card, machine);
+       return;
+}
 
-       ret = snd_soc_of_parse_card_name(card, "nvidia,model");
-       if (ret)
-               goto err;
+static void dai_link_setup(struct platform_device *pdev, int dummy)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+       struct tegra_t210ref *machine = snd_soc_card_get_drvdata(card);
+       struct snd_soc_codec_conf *tegra_machine_codec_conf = NULL;
+       struct snd_soc_codec_conf *tegra_t210ref_codec_conf = NULL;
+       struct snd_soc_dai_link *tegra_machine_dai_links = NULL;
+       struct snd_soc_dai_link *tegra_t210ref_codec_links = NULL;
+       struct tegra_asoc_platform_data *pdata = machine->pdata;
+       int i;
 
-       ret = snd_soc_of_parse_audio_routing(card,
-                               "nvidia,audio-routing");
-       if (ret)
-               goto err;
+       if (dummy) {
+               tegra_machine_remove_dai_link();
+               tegra_machine_remove_codec_conf();
+               pdata->gpio_hp_det = -1;
+       }
 
        /* set new codec links and conf */
        tegra_t210ref_codec_links = tegra_machine_new_codec_links(pdev,
@@ -583,6 +600,20 @@ static int tegra_t210ref_driver_probe(struct platform_device *pdev)
        if (!tegra_t210ref_codec_links)
                goto err_alloc_dai_link;
 
+       /* set codec init */
+       for (i = 0; i < machine->num_codec_links; i++) {
+               if (tegra_t210ref_codec_links[i].name) {
+                       if (strstr(tegra_t210ref_codec_links[i].name,
+                               "rt565x-playback"))
+                               tegra_t210ref_codec_links[i].init =
+                                       tegra_t210ref_init;
+               }
+       }
+
+       /* overwrite codec link */
+       if (dummy)
+               replace_codec_link(pdev, tegra_t210ref_codec_links);
+
        tegra_t210ref_codec_conf = tegra_machine_new_codec_conf(pdev,
                tegra_t210ref_codec_conf,
                &machine->num_codec_links);
@@ -597,15 +628,6 @@ static int tegra_t210ref_driver_probe(struct platform_device *pdev)
        if (!tegra_machine_codec_conf)
                goto err_alloc_dai_link;
 
-       /* set codec init */
-       for (i = 0; i < machine->num_codec_links; i++) {
-               if (tegra_t210ref_codec_links[i].name) {
-                       if (strstr(tegra_t210ref_codec_links[i].name,
-                               "rt565x-playback"))
-                               tegra_t210ref_codec_links[i].init = tegra_t210ref_init;
-               }
-       }
-
        /* set ADMAIF dai_ops */
        for (i = TEGRA210_DAI_LINK_ADMAIF1;
                i <= TEGRA210_DAI_LINK_ADMAIF10; i++)
@@ -635,6 +657,51 @@ static int tegra_t210ref_driver_probe(struct platform_device *pdev)
                        machine->num_codec_links);
        tegra_machine_codec_conf = tegra_machine_get_codec_conf();
        card->codec_conf = tegra_machine_codec_conf;
+       return;
+
+err_alloc_dai_link:
+       tegra_machine_remove_dai_link();
+       tegra_machine_remove_codec_conf();
+}
+
+static int tegra_t210ref_driver_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct snd_soc_card *card = &snd_soc_tegra_t210ref;
+       struct tegra_t210ref *machine;
+       struct tegra_asoc_platform_data *pdata = NULL;
+       struct snd_soc_codec *codec = NULL;
+       int ret = 0, idx;
+
+       if (!np) {
+               dev_err(&pdev->dev, "No device tree node for t210ref driver");
+               return -ENODEV;
+       }
+
+       machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_t210ref),
+                              GFP_KERNEL);
+       if (!machine) {
+               dev_err(&pdev->dev, "Can't allocate tegra_t210ref struct\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       card->dev = &pdev->dev;
+       platform_set_drvdata(pdev, card);
+       snd_soc_card_set_drvdata(card, machine);
+       machine->is_codec_dummy = 0;
+
+       ret = snd_soc_of_parse_card_name(card, "nvidia,model");
+       if (ret)
+               goto err;
+
+       ret = snd_soc_of_parse_audio_routing(card,
+                               "nvidia,audio-routing");
+       if (ret)
+               goto err;
+
+
+       dai_link_setup(pdev, 0);
 
 #ifdef CONFIG_SWITCH
        /* Addd h2w swith class support */
@@ -672,19 +739,22 @@ static int tegra_t210ref_driver_probe(struct platform_device *pdev)
 
        ret = snd_soc_register_card(card);
        if (ret) {
-               dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
-                       ret);
-               goto err_alloc_dai_link;
+               dai_link_setup(pdev, 1);
+               ret = snd_soc_register_card(card);
+
+               if (ret) {
+                       dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+                               ret);
+                       goto err_alloc_dai_link;
+               }
        }
 
        idx = tegra_machine_get_codec_dai_link_idx("rt565x-playback");
        /* check if idx has valid number */
-       if (idx == -EINVAL) {
+       if (idx == -EINVAL)
                dev_warn(&pdev->dev, "codec link not defined - codec not part of sound card");
-       }
-       else {
+       else
                codec = card->rtd[idx].codec;
-       }
 
        return 0;