aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiam Girdwood <liam.r.girdwood@linux.intel.com>2014-02-20 16:48:47 -0500
committerMark Brown <broonie@linaro.org>2014-02-21 21:22:27 -0500
commit90931b9eaed9aaf772784a93da320cf10713effa (patch)
treec21c87a92dae5083227cc03ac1081ac118e7b6f1
parent5e4482fcb119d61f4bef226c442634cdd2618b31 (diff)
ASoC: Intel: Add Haswell Machine support
Add support for Haswell based machines with SST DSP audio. Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/intel/Kconfig11
-rw-r--r--sound/soc/intel/Makefile5
-rw-r--r--sound/soc/intel/haswell.c241
3 files changed, 257 insertions, 0 deletions
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index 4f1ac8f82862..ce5a6928e601 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -26,3 +26,14 @@ config SND_SOC_INTEL_SST_ACPI
26 26
27config SND_SOC_INTEL_HASWELL 27config SND_SOC_INTEL_HASWELL
28 tristate 28 tristate
29
30config SND_SOC_INTEL_HASWELL_MACH
31 tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint"
32 depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS
33 select SND_SOC_INTEL_HASWELL
34 select SND_SOC_RT5640
35 help
36 This adds support for the Lynxpoint Audio DSP on Intel(R) Haswell
37 Ultrabook platforms.
38 Say Y if you have such a device
39 If unsure select "N". \ No newline at end of file
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile
index 4c08b215fbeb..1c188150accb 100644
--- a/sound/soc/intel/Makefile
+++ b/sound/soc/intel/Makefile
@@ -16,3 +16,8 @@ snd-soc-sst-haswell-pcm-objs := \
16 sst-haswell-ipc.o sst-haswell-pcm.o sst-haswell-dsp.o 16 sst-haswell-ipc.o sst-haswell-pcm.o sst-haswell-dsp.o
17 17
18obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += snd-soc-sst-haswell-pcm.o 18obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += snd-soc-sst-haswell-pcm.o
19
20# Machine support
21snd-soc-sst-haswell-objs := haswell.o
22
23obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
diff --git a/sound/soc/intel/haswell.c b/sound/soc/intel/haswell.c
new file mode 100644
index 000000000000..0d61197661d8
--- /dev/null
+++ b/sound/soc/intel/haswell.c
@@ -0,0 +1,241 @@
1/*
2 * Intel Haswell Lynxpoint SST Audio
3 *
4 * Copyright (C) 2013, Intel Corporation. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/platform_device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/pcm_params.h>
23
24#include "sst-dsp.h"
25#include "sst-haswell-ipc.h"
26
27#include "../codecs/rt5640.h"
28
29/* Haswell ULT platforms have a Headphone and Mic jack */
30static const struct snd_soc_dapm_widget haswell_widgets[] = {
31 SND_SOC_DAPM_HP("Headphones", NULL),
32 SND_SOC_DAPM_MIC("Mic", NULL),
33};
34
35static const struct snd_soc_dapm_route haswell_rt5640_map[] = {
36
37 {"Headphones", NULL, "HPOR"},
38 {"Headphones", NULL, "HPOL"},
39 {"IN2P", NULL, "Mic"},
40
41 /* CODEC BE connections */
42 {"SSP0 CODEC IN", NULL, "AIF1 Capture"},
43 {"AIF1 Playback", NULL, "SSP0 CODEC OUT"},
44};
45
46static int haswell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
47 struct snd_pcm_hw_params *params)
48{
49 struct snd_interval *rate = hw_param_interval(params,
50 SNDRV_PCM_HW_PARAM_RATE);
51 struct snd_interval *channels = hw_param_interval(params,
52 SNDRV_PCM_HW_PARAM_CHANNELS);
53
54 /* The ADSP will covert the FE rate to 48k, stereo */
55 rate->min = rate->max = 48000;
56 channels->min = channels->max = 2;
57
58 /* set SSP0 to 16 bit */
59 snd_mask_set(&params->masks[SNDRV_PCM_HW_PARAM_FORMAT -
60 SNDRV_PCM_HW_PARAM_FIRST_MASK],
61 SNDRV_PCM_FORMAT_S16_LE);
62 return 0;
63}
64
65static int haswell_rt5640_hw_params(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params *params)
67{
68 struct snd_soc_pcm_runtime *rtd = substream->private_data;
69 struct snd_soc_dai *codec_dai = rtd->codec_dai;
70 int ret;
71
72 /* Set codec DAI configuration */
73 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
74 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
75 if (ret < 0) {
76 dev_err(rtd->dev, "can't set codec DAI configuration\n");
77 return ret;
78 }
79
80 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_MCLK, 12288000,
81 SND_SOC_CLOCK_IN);
82
83 if (ret < 0) {
84 dev_err(rtd->dev, "can't set codec sysclk configuration\n");
85 return ret;
86 }
87
88 /* set correct codec filter for DAI format and clock config */
89 snd_soc_update_bits(rtd->codec, 0x83, 0xffff, 0x8000);
90
91 return ret;
92}
93
94static struct snd_soc_ops haswell_rt5640_ops = {
95 .hw_params = haswell_rt5640_hw_params,
96};
97
98static int haswell_rtd_init(struct snd_soc_pcm_runtime *rtd)
99{
100 struct snd_soc_codec *codec = rtd->codec;
101 struct snd_soc_dapm_context *dapm = &codec->dapm;
102 struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
103 struct sst_hsw *haswell = pdata->dsp;
104 int ret;
105
106 /* Set ADSP SSP port settings */
107 ret = sst_hsw_device_set_config(haswell, SST_HSW_DEVICE_SSP_0,
108 SST_HSW_DEVICE_MCLK_FREQ_24_MHZ,
109 SST_HSW_DEVICE_CLOCK_MASTER, 9);
110 if (ret < 0) {
111 dev_err(rtd->dev, "failed to set device config\n");
112 return ret;
113 }
114
115 /* always connected */
116 snd_soc_dapm_enable_pin(dapm, "Headphones");
117 snd_soc_dapm_enable_pin(dapm, "Mic");
118
119 return 0;
120}
121
122static struct snd_soc_dai_link haswell_rt5640_dais[] = {
123 /* Front End DAI links */
124 {
125 .name = "System",
126 .stream_name = "System Playback",
127 .cpu_dai_name = "System Pin",
128 .platform_name = "haswell-pcm-audio",
129 .dynamic = 1,
130 .codec_name = "snd-soc-dummy",
131 .codec_dai_name = "snd-soc-dummy-dai",
132 .init = haswell_rtd_init,
133 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
134 .dpcm_playback = 1,
135 },
136 {
137 .name = "Offload0",
138 .stream_name = "Offload0 Playback",
139 .cpu_dai_name = "Offload0 Pin",
140 .platform_name = "haswell-pcm-audio",
141 .dynamic = 1,
142 .codec_name = "snd-soc-dummy",
143 .codec_dai_name = "snd-soc-dummy-dai",
144 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
145 .dpcm_playback = 1,
146 },
147 {
148 .name = "Offload1",
149 .stream_name = "Offload1 Playback",
150 .cpu_dai_name = "Offload1 Pin",
151 .platform_name = "haswell-pcm-audio",
152 .dynamic = 1,
153 .codec_name = "snd-soc-dummy",
154 .codec_dai_name = "snd-soc-dummy-dai",
155 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
156 .dpcm_playback = 1,
157 },
158 {
159 .name = "Loopback",
160 .stream_name = "Loopback",
161 .cpu_dai_name = "Loopback Pin",
162 .platform_name = "haswell-pcm-audio",
163 .dynamic = 0,
164 .codec_name = "snd-soc-dummy",
165 .codec_dai_name = "snd-soc-dummy-dai",
166 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
167 .dpcm_capture = 1,
168 },
169 {
170 .name = "Capture",
171 .stream_name = "Capture",
172 .cpu_dai_name = "Capture Pin",
173 .platform_name = "haswell-pcm-audio",
174 .dynamic = 1,
175 .codec_name = "snd-soc-dummy",
176 .codec_dai_name = "snd-soc-dummy-dai",
177 .trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
178 .dpcm_capture = 1,
179 },
180
181 /* Back End DAI links */
182 {
183 /* SSP0 - Codec */
184 .name = "Codec",
185 .be_id = 0,
186 .cpu_dai_name = "snd-soc-dummy-dai",
187 .platform_name = "snd-soc-dummy",
188 .no_pcm = 1,
189 .codec_name = "i2c-INT33CA:00",
190 .codec_dai_name = "rt5640-aif1",
191 .ignore_suspend = 1,
192 .ignore_pmdown_time = 1,
193 .be_hw_params_fixup = haswell_ssp0_fixup,
194 .ops = &haswell_rt5640_ops,
195 .dpcm_playback = 1,
196 .dpcm_capture = 1,
197 },
198};
199
200/* audio machine driver for Haswell Lynxpoint DSP + RT5640 */
201static struct snd_soc_card haswell_rt5640 = {
202 .name = "haswell-rt5640",
203 .owner = THIS_MODULE,
204 .dai_link = haswell_rt5640_dais,
205 .num_links = ARRAY_SIZE(haswell_rt5640_dais),
206 .dapm_widgets = haswell_widgets,
207 .num_dapm_widgets = ARRAY_SIZE(haswell_widgets),
208 .dapm_routes = haswell_rt5640_map,
209 .num_dapm_routes = ARRAY_SIZE(haswell_rt5640_map),
210 .fully_routed = true,
211};
212
213static int haswell_audio_probe(struct platform_device *pdev)
214{
215 haswell_rt5640.dev = &pdev->dev;
216
217 return snd_soc_register_card(&haswell_rt5640);
218}
219
220static int haswell_audio_remove(struct platform_device *pdev)
221{
222 snd_soc_unregister_card(&haswell_rt5640);
223 return 0;
224}
225
226static struct platform_driver haswell_audio = {
227 .probe = haswell_audio_probe,
228 .remove = haswell_audio_remove,
229 .driver = {
230 .name = "haswell-audio",
231 .owner = THIS_MODULE,
232 },
233};
234
235module_platform_driver(haswell_audio)
236
237/* Module information */
238MODULE_AUTHOR("Liam Girdwood, Xingchao Wang");
239MODULE_DESCRIPTION("Intel SST Audio for Haswell Lynxpoint");
240MODULE_LICENSE("GPL v2");
241MODULE_ALIAS("platform:haswell-audio");