~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/tegra/tegra_wm9712.c

Version: ~ [ linux-5.9.1 ] ~ [ linux-5.8.16 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.72 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.152 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.202 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.240 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.240 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * tegra20_wm9712.c - Tegra machine ASoC driver for boards using WM9712 codec.
  4  *
  5  * Copyright 2012 Lucas Stach <dev@lynxeye.de>
  6  *
  7  * Partly based on code copyright/by:
  8  * Copyright 2011,2012 Toradex Inc.
  9  */
 10 
 11 #include <linux/module.h>
 12 #include <linux/platform_device.h>
 13 #include <linux/slab.h>
 14 #include <linux/gpio.h>
 15 #include <linux/of_gpio.h>
 16 
 17 #include <sound/core.h>
 18 #include <sound/jack.h>
 19 #include <sound/pcm.h>
 20 #include <sound/pcm_params.h>
 21 #include <sound/soc.h>
 22 
 23 #include "tegra_asoc_utils.h"
 24 
 25 #define DRV_NAME "tegra-snd-wm9712"
 26 
 27 struct tegra_wm9712 {
 28         struct platform_device *codec;
 29         struct tegra_asoc_utils_data util_data;
 30 };
 31 
 32 static const struct snd_soc_dapm_widget tegra_wm9712_dapm_widgets[] = {
 33         SND_SOC_DAPM_HP("Headphone", NULL),
 34         SND_SOC_DAPM_LINE("LineIn", NULL),
 35         SND_SOC_DAPM_MIC("Mic", NULL),
 36 };
 37 
 38 static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd)
 39 {
 40         return snd_soc_dapm_force_enable_pin(&rtd->card->dapm, "Mic Bias");
 41 }
 42 
 43 SND_SOC_DAILINK_DEFS(hifi,
 44         DAILINK_COMP_ARRAY(COMP_EMPTY()),
 45         DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
 46         DAILINK_COMP_ARRAY(COMP_EMPTY()));
 47 
 48 static struct snd_soc_dai_link tegra_wm9712_dai = {
 49         .name = "AC97 HiFi",
 50         .stream_name = "AC97 HiFi",
 51         .init = tegra_wm9712_init,
 52         SND_SOC_DAILINK_REG(hifi),
 53 };
 54 
 55 static struct snd_soc_card snd_soc_tegra_wm9712 = {
 56         .name = "tegra-wm9712",
 57         .owner = THIS_MODULE,
 58         .dai_link = &tegra_wm9712_dai,
 59         .num_links = 1,
 60 
 61         .dapm_widgets = tegra_wm9712_dapm_widgets,
 62         .num_dapm_widgets = ARRAY_SIZE(tegra_wm9712_dapm_widgets),
 63         .fully_routed = true,
 64 };
 65 
 66 static int tegra_wm9712_driver_probe(struct platform_device *pdev)
 67 {
 68         struct device_node *np = pdev->dev.of_node;
 69         struct snd_soc_card *card = &snd_soc_tegra_wm9712;
 70         struct tegra_wm9712 *machine;
 71         int ret;
 72 
 73         machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm9712),
 74                                GFP_KERNEL);
 75         if (!machine)
 76                 return -ENOMEM;
 77 
 78         card->dev = &pdev->dev;
 79         snd_soc_card_set_drvdata(card, machine);
 80 
 81         machine->codec = platform_device_alloc("wm9712-codec", -1);
 82         if (!machine->codec) {
 83                 dev_err(&pdev->dev, "Can't allocate wm9712 platform device\n");
 84                 return -ENOMEM;
 85         }
 86 
 87         ret = platform_device_add(machine->codec);
 88         if (ret)
 89                 goto codec_put;
 90 
 91         ret = snd_soc_of_parse_card_name(card, "nvidia,model");
 92         if (ret)
 93                 goto codec_unregister;
 94 
 95         ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
 96         if (ret)
 97                 goto codec_unregister;
 98 
 99         tegra_wm9712_dai.cpus->of_node = of_parse_phandle(np,
100                                        "nvidia,ac97-controller", 0);
101         if (!tegra_wm9712_dai.cpus->of_node) {
102                 dev_err(&pdev->dev,
103                         "Property 'nvidia,ac97-controller' missing or invalid\n");
104                 ret = -EINVAL;
105                 goto codec_unregister;
106         }
107 
108         tegra_wm9712_dai.platforms->of_node = tegra_wm9712_dai.cpus->of_node;
109 
110         ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
111         if (ret)
112                 goto codec_unregister;
113 
114         ret = tegra_asoc_utils_set_ac97_rate(&machine->util_data);
115         if (ret)
116                 goto asoc_utils_fini;
117 
118         ret = snd_soc_register_card(card);
119         if (ret) {
120                 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
121                         ret);
122                 goto asoc_utils_fini;
123         }
124 
125         return 0;
126 
127 asoc_utils_fini:
128         tegra_asoc_utils_fini(&machine->util_data);
129 codec_unregister:
130         platform_device_del(machine->codec);
131 codec_put:
132         platform_device_put(machine->codec);
133         return ret;
134 }
135 
136 static int tegra_wm9712_driver_remove(struct platform_device *pdev)
137 {
138         struct snd_soc_card *card = platform_get_drvdata(pdev);
139         struct tegra_wm9712 *machine = snd_soc_card_get_drvdata(card);
140 
141         snd_soc_unregister_card(card);
142 
143         tegra_asoc_utils_fini(&machine->util_data);
144 
145         platform_device_unregister(machine->codec);
146 
147         return 0;
148 }
149 
150 static const struct of_device_id tegra_wm9712_of_match[] = {
151         { .compatible = "nvidia,tegra-audio-wm9712", },
152         {},
153 };
154 
155 static struct platform_driver tegra_wm9712_driver = {
156         .driver = {
157                 .name = DRV_NAME,
158                 .pm = &snd_soc_pm_ops,
159                 .of_match_table = tegra_wm9712_of_match,
160         },
161         .probe = tegra_wm9712_driver_probe,
162         .remove = tegra_wm9712_driver_remove,
163 };
164 module_platform_driver(tegra_wm9712_driver);
165 
166 MODULE_AUTHOR("Lucas Stach");
167 MODULE_DESCRIPTION("Tegra+WM9712 machine ASoC driver");
168 MODULE_LICENSE("GPL v2");
169 MODULE_ALIAS("platform:" DRV_NAME);
170 MODULE_DEVICE_TABLE(of, tegra_wm9712_of_match);
171 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp