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

TOMOYO Linux Cross Reference
Linux/sound/soc/samsung/lowland.c

Version: ~ [ linux-6.3-rc3 ] ~ [ linux-6.2.7 ] ~ [ linux-6.1.20 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.103 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.175 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.237 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.278 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.310 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.302 ] ~ [ 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.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0+
  2 //
  3 // Lowland audio support
  4 //
  5 // Copyright 2011 Wolfson Microelectronics
  6 
  7 #include <sound/soc.h>
  8 #include <sound/soc-dapm.h>
  9 #include <sound/jack.h>
 10 #include <linux/gpio.h>
 11 #include <linux/module.h>
 12 
 13 #include "../codecs/wm5100.h"
 14 #include "../codecs/wm9081.h"
 15 
 16 #define MCLK1_RATE (44100 * 512)
 17 #define CLKOUT_RATE (44100 * 256)
 18 
 19 static struct snd_soc_jack lowland_headset;
 20 
 21 /* Headset jack detection DAPM pins */
 22 static struct snd_soc_jack_pin lowland_headset_pins[] = {
 23         {
 24                 .pin = "Headphone",
 25                 .mask = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
 26         },
 27         {
 28                 .pin = "Headset Mic",
 29                 .mask = SND_JACK_MICROPHONE,
 30         },
 31 };
 32 
 33 static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
 34 {
 35         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
 36         int ret;
 37 
 38         ret = snd_soc_component_set_sysclk(component, WM5100_CLK_SYSCLK,
 39                                        WM5100_CLKSRC_MCLK1, MCLK1_RATE,
 40                                        SND_SOC_CLOCK_IN);
 41         if (ret < 0) {
 42                 pr_err("Failed to set SYSCLK clock source: %d\n", ret);
 43                 return ret;
 44         }
 45 
 46         /* Clock OPCLK, used by the other audio components. */
 47         ret = snd_soc_component_set_sysclk(component, WM5100_CLK_OPCLK, 0,
 48                                        CLKOUT_RATE, 0);
 49         if (ret < 0) {
 50                 pr_err("Failed to set OPCLK rate: %d\n", ret);
 51                 return ret;
 52         }
 53 
 54         ret = snd_soc_card_jack_new(rtd->card, "Headset", SND_JACK_LINEOUT |
 55                                     SND_JACK_HEADSET | SND_JACK_BTN_0,
 56                                     &lowland_headset, lowland_headset_pins,
 57                                     ARRAY_SIZE(lowland_headset_pins));
 58         if (ret)
 59                 return ret;
 60 
 61         wm5100_detect(component, &lowland_headset);
 62 
 63         return 0;
 64 }
 65 
 66 static int lowland_wm9081_init(struct snd_soc_pcm_runtime *rtd)
 67 {
 68         struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
 69 
 70         snd_soc_dapm_nc_pin(&rtd->card->dapm, "LINEOUT");
 71 
 72         /* At any time the WM9081 is active it will have this clock */
 73         return snd_soc_component_set_sysclk(component, WM9081_SYSCLK_MCLK, 0,
 74                                         CLKOUT_RATE, 0);
 75 }
 76 
 77 static const struct snd_soc_pcm_stream sub_params = {
 78         .formats = SNDRV_PCM_FMTBIT_S32_LE,
 79         .rate_min = 44100,
 80         .rate_max = 44100,
 81         .channels_min = 2,
 82         .channels_max = 2,
 83 };
 84 
 85 SND_SOC_DAILINK_DEFS(cpu,
 86         DAILINK_COMP_ARRAY(COMP_CPU("samsung-i2s.0")),
 87         DAILINK_COMP_ARRAY(COMP_CODEC("wm5100.1-001a", "wm5100-aif1")),
 88         DAILINK_COMP_ARRAY(COMP_PLATFORM("samsung-i2s.0")));
 89 
 90 SND_SOC_DAILINK_DEFS(baseband,
 91         DAILINK_COMP_ARRAY(COMP_CPU("wm5100-aif2")),
 92         DAILINK_COMP_ARRAY(COMP_CODEC("wm1250-ev1.1-0027", "wm1250-ev1")));
 93 
 94 SND_SOC_DAILINK_DEFS(speaker,
 95         DAILINK_COMP_ARRAY(COMP_CPU("wm5100-aif3")),
 96         DAILINK_COMP_ARRAY(COMP_CODEC("wm9081.1-006c", "wm9081-hifi")));
 97 
 98 static struct snd_soc_dai_link lowland_dai[] = {
 99         {
100                 .name = "CPU",
101                 .stream_name = "CPU",
102                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
103                                 SND_SOC_DAIFMT_CBM_CFM,
104                 .init = lowland_wm5100_init,
105                 SND_SOC_DAILINK_REG(cpu),
106         },
107         {
108                 .name = "Baseband",
109                 .stream_name = "Baseband",
110                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
111                                 SND_SOC_DAIFMT_CBM_CFM,
112                 .ignore_suspend = 1,
113                 SND_SOC_DAILINK_REG(baseband),
114         },
115         {
116                 .name = "Sub Speaker",
117                 .stream_name = "Sub Speaker",
118                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
119                                 SND_SOC_DAIFMT_CBM_CFM,
120                 .ignore_suspend = 1,
121                 .params = &sub_params,
122                 .init = lowland_wm9081_init,
123                 SND_SOC_DAILINK_REG(speaker),
124         },
125 };
126 
127 static struct snd_soc_codec_conf lowland_codec_conf[] = {
128         {
129                 .dlc = COMP_CODEC_CONF("wm9081.1-006c"),
130                 .name_prefix = "Sub",
131         },
132 };
133 
134 static const struct snd_kcontrol_new controls[] = {
135         SOC_DAPM_PIN_SWITCH("Main Speaker"),
136         SOC_DAPM_PIN_SWITCH("Main DMIC"),
137         SOC_DAPM_PIN_SWITCH("Main AMIC"),
138         SOC_DAPM_PIN_SWITCH("WM1250 Input"),
139         SOC_DAPM_PIN_SWITCH("WM1250 Output"),
140         SOC_DAPM_PIN_SWITCH("Headphone"),
141 };
142 
143 static struct snd_soc_dapm_widget widgets[] = {
144         SND_SOC_DAPM_HP("Headphone", NULL),
145         SND_SOC_DAPM_MIC("Headset Mic", NULL),
146 
147         SND_SOC_DAPM_SPK("Main Speaker", NULL),
148 
149         SND_SOC_DAPM_MIC("Main AMIC", NULL),
150         SND_SOC_DAPM_MIC("Main DMIC", NULL),
151 };
152 
153 static struct snd_soc_dapm_route audio_paths[] = {
154         { "Sub IN1", NULL, "HPOUT2L" },
155         { "Sub IN2", NULL, "HPOUT2R" },
156 
157         { "Main Speaker", NULL, "Sub SPKN" },
158         { "Main Speaker", NULL, "Sub SPKP" },
159         { "Main Speaker", NULL, "SPKDAT1" },
160 };
161 
162 static struct snd_soc_card lowland = {
163         .name = "Lowland",
164         .owner = THIS_MODULE,
165         .dai_link = lowland_dai,
166         .num_links = ARRAY_SIZE(lowland_dai),
167         .codec_conf = lowland_codec_conf,
168         .num_configs = ARRAY_SIZE(lowland_codec_conf),
169 
170         .controls = controls,
171         .num_controls = ARRAY_SIZE(controls),
172         .dapm_widgets = widgets,
173         .num_dapm_widgets = ARRAY_SIZE(widgets),
174         .dapm_routes = audio_paths,
175         .num_dapm_routes = ARRAY_SIZE(audio_paths),
176 };
177 
178 static int lowland_probe(struct platform_device *pdev)
179 {
180         struct snd_soc_card *card = &lowland;
181         int ret;
182 
183         card->dev = &pdev->dev;
184 
185         ret = devm_snd_soc_register_card(&pdev->dev, card);
186         if (ret && ret != -EPROBE_DEFER)
187                 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
188                         ret);
189 
190         return ret;
191 }
192 
193 static struct platform_driver lowland_driver = {
194         .driver = {
195                 .name = "lowland",
196                 .pm = &snd_soc_pm_ops,
197         },
198         .probe = lowland_probe,
199 };
200 
201 module_platform_driver(lowland_driver);
202 
203 MODULE_DESCRIPTION("Lowland audio support");
204 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
205 MODULE_LICENSE("GPL");
206 MODULE_ALIAS("platform:lowland");
207 

~ [ 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