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

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

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ 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,
 26         },
 27         {
 28                 .pin = "Headset Mic",
 29                 .mask = SND_JACK_MICROPHONE,
 30         },
 31         {
 32                 .pin = "Line Out",
 33                 .mask = SND_JACK_LINEOUT,
 34         },
 35 };
 36 
 37 static int lowland_wm5100_init(struct snd_soc_pcm_runtime *rtd)
 38 {
 39         struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
 40         int ret;
 41 
 42         ret = snd_soc_component_set_sysclk(component, WM5100_CLK_SYSCLK,
 43                                        WM5100_CLKSRC_MCLK1, MCLK1_RATE,
 44                                        SND_SOC_CLOCK_IN);
 45         if (ret < 0) {
 46                 pr_err("Failed to set SYSCLK clock source: %d\n", ret);
 47                 return ret;
 48         }
 49 
 50         /* Clock OPCLK, used by the other audio components. */
 51         ret = snd_soc_component_set_sysclk(component, WM5100_CLK_OPCLK, 0,
 52                                        CLKOUT_RATE, 0);
 53         if (ret < 0) {
 54                 pr_err("Failed to set OPCLK rate: %d\n", ret);
 55                 return ret;
 56         }
 57 
 58         ret = snd_soc_card_jack_new_pins(rtd->card, "Headset",
 59                                          SND_JACK_LINEOUT | SND_JACK_HEADSET |
 60                                          SND_JACK_BTN_0,
 61                                          &lowland_headset, lowland_headset_pins,
 62                                          ARRAY_SIZE(lowland_headset_pins));
 63         if (ret)
 64                 return ret;
 65 
 66         wm5100_detect(component, &lowland_headset);
 67 
 68         return 0;
 69 }
 70 
 71 static int lowland_wm9081_init(struct snd_soc_pcm_runtime *rtd)
 72 {
 73         struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
 74 
 75         snd_soc_dapm_nc_pin(&rtd->card->dapm, "LINEOUT");
 76 
 77         /* At any time the WM9081 is active it will have this clock */
 78         return snd_soc_component_set_sysclk(component, WM9081_SYSCLK_MCLK, 0,
 79                                         CLKOUT_RATE, 0);
 80 }
 81 
 82 static const struct snd_soc_pcm_stream sub_params = {
 83         .formats = SNDRV_PCM_FMTBIT_S32_LE,
 84         .rate_min = 44100,
 85         .rate_max = 44100,
 86         .channels_min = 2,
 87         .channels_max = 2,
 88 };
 89 
 90 SND_SOC_DAILINK_DEFS(cpu,
 91         DAILINK_COMP_ARRAY(COMP_CPU("samsung-i2s.0")),
 92         DAILINK_COMP_ARRAY(COMP_CODEC("wm5100.1-001a", "wm5100-aif1")),
 93         DAILINK_COMP_ARRAY(COMP_PLATFORM("samsung-i2s.0")));
 94 
 95 SND_SOC_DAILINK_DEFS(baseband,
 96         DAILINK_COMP_ARRAY(COMP_CPU("wm5100-aif2")),
 97         DAILINK_COMP_ARRAY(COMP_CODEC("wm1250-ev1.1-0027", "wm1250-ev1")));
 98 
 99 SND_SOC_DAILINK_DEFS(speaker,
100         DAILINK_COMP_ARRAY(COMP_CPU("wm5100-aif3")),
101         DAILINK_COMP_ARRAY(COMP_CODEC("wm9081.1-006c", "wm9081-hifi")));
102 
103 static struct snd_soc_dai_link lowland_dai[] = {
104         {
105                 .name = "CPU",
106                 .stream_name = "CPU",
107                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
108                                 SND_SOC_DAIFMT_CBM_CFM,
109                 .init = lowland_wm5100_init,
110                 SND_SOC_DAILINK_REG(cpu),
111         },
112         {
113                 .name = "Baseband",
114                 .stream_name = "Baseband",
115                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
116                                 SND_SOC_DAIFMT_CBM_CFM,
117                 .ignore_suspend = 1,
118                 SND_SOC_DAILINK_REG(baseband),
119         },
120         {
121                 .name = "Sub Speaker",
122                 .stream_name = "Sub Speaker",
123                 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
124                                 SND_SOC_DAIFMT_CBM_CFM,
125                 .ignore_suspend = 1,
126                 .c2c_params = &sub_params,
127                 .num_c2c_params = 1,
128                 .init = lowland_wm9081_init,
129                 SND_SOC_DAILINK_REG(speaker),
130         },
131 };
132 
133 static struct snd_soc_codec_conf lowland_codec_conf[] = {
134         {
135                 .dlc = COMP_CODEC_CONF("wm9081.1-006c"),
136                 .name_prefix = "Sub",
137         },
138 };
139 
140 static const struct snd_kcontrol_new controls[] = {
141         SOC_DAPM_PIN_SWITCH("Main Speaker"),
142         SOC_DAPM_PIN_SWITCH("Main DMIC"),
143         SOC_DAPM_PIN_SWITCH("Main AMIC"),
144         SOC_DAPM_PIN_SWITCH("WM1250 Input"),
145         SOC_DAPM_PIN_SWITCH("WM1250 Output"),
146         SOC_DAPM_PIN_SWITCH("Headphone"),
147         SOC_DAPM_PIN_SWITCH("Line Out"),
148 };
149 
150 static const struct snd_soc_dapm_widget widgets[] = {
151         SND_SOC_DAPM_HP("Headphone", NULL),
152         SND_SOC_DAPM_MIC("Headset Mic", NULL),
153         SND_SOC_DAPM_LINE("Line Out", NULL),
154 
155         SND_SOC_DAPM_SPK("Main Speaker", NULL),
156 
157         SND_SOC_DAPM_MIC("Main AMIC", NULL),
158         SND_SOC_DAPM_MIC("Main DMIC", NULL),
159 };
160 
161 static const struct snd_soc_dapm_route audio_paths[] = {
162         { "Sub IN1", NULL, "HPOUT2L" },
163         { "Sub IN2", NULL, "HPOUT2R" },
164 
165         { "Main Speaker", NULL, "Sub SPKN" },
166         { "Main Speaker", NULL, "Sub SPKP" },
167         { "Main Speaker", NULL, "SPKDAT1" },
168 };
169 
170 static struct snd_soc_card lowland = {
171         .name = "Lowland",
172         .owner = THIS_MODULE,
173         .dai_link = lowland_dai,
174         .num_links = ARRAY_SIZE(lowland_dai),
175         .codec_conf = lowland_codec_conf,
176         .num_configs = ARRAY_SIZE(lowland_codec_conf),
177 
178         .controls = controls,
179         .num_controls = ARRAY_SIZE(controls),
180         .dapm_widgets = widgets,
181         .num_dapm_widgets = ARRAY_SIZE(widgets),
182         .dapm_routes = audio_paths,
183         .num_dapm_routes = ARRAY_SIZE(audio_paths),
184 };
185 
186 static int lowland_probe(struct platform_device *pdev)
187 {
188         struct snd_soc_card *card = &lowland;
189         int ret;
190 
191         card->dev = &pdev->dev;
192 
193         ret = devm_snd_soc_register_card(&pdev->dev, card);
194         if (ret)
195                 dev_err_probe(&pdev->dev, ret, "snd_soc_register_card() failed\n");
196 
197         return ret;
198 }
199 
200 static struct platform_driver lowland_driver = {
201         .driver = {
202                 .name = "lowland",
203                 .pm = &snd_soc_pm_ops,
204         },
205         .probe = lowland_probe,
206 };
207 
208 module_platform_driver(lowland_driver);
209 
210 MODULE_DESCRIPTION("Lowland audio support");
211 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
212 MODULE_LICENSE("GPL");
213 MODULE_ALIAS("platform:lowland");
214 

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php