aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/tegra
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 16:37:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 16:37:37 -0400
commitdbf7b5915b39bfff548e4c6a3a753fc291a60e25 (patch)
tree55c457a22aa869d2ab558317877138369ae5f9bb /sound/soc/tegra
parentd14b7a419a664cd7c1c585c9e7fffee9e9051d53 (diff)
parentc1b623d9e4117d18d244e9b7fb30d2c27aeaf074 (diff)
Merge tag 'sound-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound update from Takashi Iwai: "This is a fairly quiet release in all sound area. Only a little bit of changes in the core side while most of changes are seen in the drivers. HD-audio: - A few new codec additions for Nvidia, Realtek and VIA - Intel Haswell audio support - Support for "phantom" jacks for consistent jack reporting - Major clean-ups in HDMI/DP driver codes - A workaround for inverted digital-mic pins with Realtek codecs - Removal of beep_mode=2 option ASoC: - Added the ability to add and remove DAPM paths dynamically, mostly for reparenting on clock changes - New machine drivers for Marvell Brownstone, ST-Ericsson Ux500 reference platform and ttc-dkp - New CPU drivers for Blackfin BF6xx SPORTs in I2S mode, Marvell MMP, Synopsis Designware I2S controllers, and SPEAr DMA and S/PDIF - New CODEC drivers for Dialog DA732x, ST STA529, ST-Ericsson AB8500, TI Isabelle and Wolfson Microelectronics WM5102 and WM5110 - DAPM fixes for the recent locking changes - Fix for _PRE and _POST widgets (which have been broken for a few releases now) - A couple of minor driver updates Misc - Conversion to new dev_pm_ops in platform and PCI drivers - LTC support and some fixes in PCXHR driver - A few fixes and PM support for ISA OPti9xx and WSS cards - Some TLV code cleanup - Move driver-specific headers from include/sound to local dirs" * tag 'sound-3.6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (212 commits) ASoC: dapm: Fix _PRE and _POST events for DAPM performance improvements ALSA: hda - add dock support for Thinkpad X230 Tablet ALSA: hda - Turn on PIN_OUT from hdmi playback prepare. ASoC imx-audmux: add MX31_AUDMUX_PORT7_SSI_PINS_7 define ASoC: littlemill: Add userspace control of the WM1250 I/O ASoC: wm8994: Update micdet for irqdomain conversion ALSA: hda - make sure alc268 does not OOPS on codec parse ALSA: hda - Add support for Realtek ALC282 ALSA: hda - Fix index number conflicts of phantom jacks ALSA: opti9xx: Fix section mismatch by PM support ALSA: snd-opti9xx: Implement suspend/resume ALSA: hda - Add new GPU codec ID to snd-hda ALSA: hda - Fix driver type of Haswell controller to AZX_DRIVER_SCH ALSA: hda - add Haswell HDMI codec id ALSA: hda - Add DeviceID for Haswell HDA ALSA: wss_lib: Fix resume on Yamaha OPL3-SAx ALSA: wss_lib: fix suspend/resume ALSA: es1938: replace TLV_DB_RANGE_HEAD with DECLARE_TLV_DB_RANGE ALSA: tlv: add DECLARE_TLV_DB_RANGE() ALSA: tlv: add DECLARE_TLV_CONTAINER() ...
Diffstat (limited to 'sound/soc/tegra')
-rw-r--r--sound/soc/tegra/Kconfig3
-rw-r--r--sound/soc/tegra/tegra20_i2s.c94
-rw-r--r--sound/soc/tegra/tegra20_i2s.h1
-rw-r--r--sound/soc/tegra/tegra20_spdif.c36
-rw-r--r--sound/soc/tegra/tegra20_spdif.h1
-rw-r--r--sound/soc/tegra/tegra30_i2s.c85
-rw-r--r--sound/soc/tegra/tegra30_i2s.h1
-rw-r--r--sound/soc/tegra/tegra_alc5632.c32
-rw-r--r--sound/soc/tegra/tegra_pcm.c115
-rw-r--r--sound/soc/tegra/tegra_pcm.h2
-rw-r--r--sound/soc/tegra/tegra_wm8753.c8
-rw-r--r--sound/soc/tegra/tegra_wm8903.c259
-rw-r--r--sound/soc/tegra/trimslice.c30
13 files changed, 335 insertions, 332 deletions
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index 76dc230f2bb0..02bcd308c189 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -1,7 +1,8 @@
1config SND_SOC_TEGRA 1config SND_SOC_TEGRA
2 tristate "SoC Audio for the Tegra System-on-Chip" 2 tristate "SoC Audio for the Tegra System-on-Chip"
3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA 3 depends on ARCH_TEGRA && (TEGRA_SYSTEM_DMA || TEGRA20_APB_DMA)
4 select REGMAP_MMIO 4 select REGMAP_MMIO
5 select SND_SOC_DMAENGINE_PCM if TEGRA20_APB_DMA
5 help 6 help
6 Say Y or M here if you want support for SoC audio on Tegra. 7 Say Y or M here if you want support for SoC audio on Tegra.
7 8
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 1647dbfe74b5..0832e8afd73c 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -46,18 +46,6 @@
46 46
47#define DRV_NAME "tegra20-i2s" 47#define DRV_NAME "tegra20-i2s"
48 48
49static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val)
50{
51 regmap_write(i2s->regmap, reg, val);
52}
53
54static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg)
55{
56 u32 val;
57 regmap_read(i2s->regmap, reg, &val);
58 return val;
59}
60
61static int tegra20_i2s_runtime_suspend(struct device *dev) 49static int tegra20_i2s_runtime_suspend(struct device *dev)
62{ 50{
63 struct tegra20_i2s *i2s = dev_get_drvdata(dev); 51 struct tegra20_i2s *i2s = dev_get_drvdata(dev);
@@ -85,6 +73,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
85 unsigned int fmt) 73 unsigned int fmt)
86{ 74{
87 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); 75 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
76 unsigned int mask, val;
88 77
89 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 78 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
90 case SND_SOC_DAIFMT_NB_NF: 79 case SND_SOC_DAIFMT_NB_NF:
@@ -93,10 +82,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
93 return -EINVAL; 82 return -EINVAL;
94 } 83 }
95 84
96 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE; 85 mask = TEGRA20_I2S_CTRL_MASTER_ENABLE;
97 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 86 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
98 case SND_SOC_DAIFMT_CBS_CFS: 87 case SND_SOC_DAIFMT_CBS_CFS:
99 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE; 88 val = TEGRA20_I2S_CTRL_MASTER_ENABLE;
100 break; 89 break;
101 case SND_SOC_DAIFMT_CBM_CFM: 90 case SND_SOC_DAIFMT_CBM_CFM:
102 break; 91 break;
@@ -104,33 +93,35 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
104 return -EINVAL; 93 return -EINVAL;
105 } 94 }
106 95
107 i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | 96 mask |= TEGRA20_I2S_CTRL_BIT_FORMAT_MASK |
108 TEGRA20_I2S_CTRL_LRCK_MASK); 97 TEGRA20_I2S_CTRL_LRCK_MASK;
109 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 98 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
110 case SND_SOC_DAIFMT_DSP_A: 99 case SND_SOC_DAIFMT_DSP_A:
111 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; 100 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
112 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 101 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
113 break; 102 break;
114 case SND_SOC_DAIFMT_DSP_B: 103 case SND_SOC_DAIFMT_DSP_B:
115 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; 104 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
116 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW; 105 val |= TEGRA20_I2S_CTRL_LRCK_R_LOW;
117 break; 106 break;
118 case SND_SOC_DAIFMT_I2S: 107 case SND_SOC_DAIFMT_I2S:
119 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; 108 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S;
120 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 109 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
121 break; 110 break;
122 case SND_SOC_DAIFMT_RIGHT_J: 111 case SND_SOC_DAIFMT_RIGHT_J:
123 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; 112 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM;
124 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 113 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
125 break; 114 break;
126 case SND_SOC_DAIFMT_LEFT_J: 115 case SND_SOC_DAIFMT_LEFT_J:
127 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; 116 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM;
128 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 117 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
129 break; 118 break;
130 default: 119 default:
131 return -EINVAL; 120 return -EINVAL;
132 } 121 }
133 122
123 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val);
124
134 return 0; 125 return 0;
135} 126}
136 127
@@ -138,29 +129,34 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
138 struct snd_pcm_hw_params *params, 129 struct snd_pcm_hw_params *params,
139 struct snd_soc_dai *dai) 130 struct snd_soc_dai *dai)
140{ 131{
141 struct device *dev = substream->pcm->card->dev; 132 struct device *dev = dai->dev;
142 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); 133 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
143 u32 reg; 134 unsigned int mask, val;
144 int ret, sample_size, srate, i2sclock, bitcnt; 135 int ret, sample_size, srate, i2sclock, bitcnt;
145 136
146 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK; 137 mask = TEGRA20_I2S_CTRL_BIT_SIZE_MASK;
147 switch (params_format(params)) { 138 switch (params_format(params)) {
148 case SNDRV_PCM_FORMAT_S16_LE: 139 case SNDRV_PCM_FORMAT_S16_LE:
149 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16; 140 val = TEGRA20_I2S_CTRL_BIT_SIZE_16;
150 sample_size = 16; 141 sample_size = 16;
151 break; 142 break;
152 case SNDRV_PCM_FORMAT_S24_LE: 143 case SNDRV_PCM_FORMAT_S24_LE:
153 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24; 144 val = TEGRA20_I2S_CTRL_BIT_SIZE_24;
154 sample_size = 24; 145 sample_size = 24;
155 break; 146 break;
156 case SNDRV_PCM_FORMAT_S32_LE: 147 case SNDRV_PCM_FORMAT_S32_LE:
157 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32; 148 val = TEGRA20_I2S_CTRL_BIT_SIZE_32;
158 sample_size = 32; 149 sample_size = 32;
159 break; 150 break;
160 default: 151 default:
161 return -EINVAL; 152 return -EINVAL;
162 } 153 }
163 154
155 mask |= TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK;
156 val |= TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
157
158 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val);
159
164 srate = params_rate(params); 160 srate = params_rate(params);
165 161
166 /* Final "* 2" required by Tegra hardware */ 162 /* Final "* 2" required by Tegra hardware */
@@ -175,42 +171,44 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
175 bitcnt = (i2sclock / (2 * srate)) - 1; 171 bitcnt = (i2sclock / (2 * srate)) - 1;
176 if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) 172 if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
177 return -EINVAL; 173 return -EINVAL;
178 reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; 174 val = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
179 175
180 if (i2sclock % (2 * srate)) 176 if (i2sclock % (2 * srate))
181 reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; 177 val |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE;
182 178
183 tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg); 179 regmap_write(i2s->regmap, TEGRA20_I2S_TIMING, val);
184 180
185 tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, 181 regmap_write(i2s->regmap, TEGRA20_I2S_FIFO_SCR,
186 TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | 182 TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
187 TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); 183 TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
188 184
189 return 0; 185 return 0;
190} 186}
191 187
192static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) 188static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s)
193{ 189{
194 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE; 190 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
195 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 191 TEGRA20_I2S_CTRL_FIFO1_ENABLE,
192 TEGRA20_I2S_CTRL_FIFO1_ENABLE);
196} 193}
197 194
198static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) 195static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s)
199{ 196{
200 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE; 197 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
201 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 198 TEGRA20_I2S_CTRL_FIFO1_ENABLE, 0);
202} 199}
203 200
204static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) 201static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s)
205{ 202{
206 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE; 203 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
207 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 204 TEGRA20_I2S_CTRL_FIFO2_ENABLE,
205 TEGRA20_I2S_CTRL_FIFO2_ENABLE);
208} 206}
209 207
210static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) 208static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s)
211{ 209{
212 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE; 210 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
213 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 211 TEGRA20_I2S_CTRL_FIFO2_ENABLE, 0);
214} 212}
215 213
216static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 214static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -261,12 +259,14 @@ static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = {
261static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { 259static const struct snd_soc_dai_driver tegra20_i2s_dai_template = {
262 .probe = tegra20_i2s_probe, 260 .probe = tegra20_i2s_probe,
263 .playback = { 261 .playback = {
262 .stream_name = "Playback",
264 .channels_min = 2, 263 .channels_min = 2,
265 .channels_max = 2, 264 .channels_max = 2,
266 .rates = SNDRV_PCM_RATE_8000_96000, 265 .rates = SNDRV_PCM_RATE_8000_96000,
267 .formats = SNDRV_PCM_FMTBIT_S16_LE, 266 .formats = SNDRV_PCM_FMTBIT_S16_LE,
268 }, 267 },
269 .capture = { 268 .capture = {
269 .stream_name = "Capture",
270 .channels_min = 2, 270 .channels_min = 2,
271 .channels_max = 2, 271 .channels_max = 2,
272 .rates = SNDRV_PCM_RATE_8000_96000, 272 .rates = SNDRV_PCM_RATE_8000_96000,
@@ -412,8 +412,6 @@ static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev)
412 i2s->playback_dma_data.width = 32; 412 i2s->playback_dma_data.width = 32;
413 i2s->playback_dma_data.req_sel = dma_ch; 413 i2s->playback_dma_data.req_sel = dma_ch;
414 414
415 i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
416
417 pm_runtime_enable(&pdev->dev); 415 pm_runtime_enable(&pdev->dev);
418 if (!pm_runtime_enabled(&pdev->dev)) { 416 if (!pm_runtime_enabled(&pdev->dev)) {
419 ret = tegra20_i2s_runtime_resume(&pdev->dev); 417 ret = tegra20_i2s_runtime_resume(&pdev->dev);
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h
index a57efc6a597e..c27069d24d77 100644
--- a/sound/soc/tegra/tegra20_i2s.h
+++ b/sound/soc/tegra/tegra20_i2s.h
@@ -158,7 +158,6 @@ struct tegra20_i2s {
158 struct tegra_pcm_dma_params capture_dma_data; 158 struct tegra_pcm_dma_params capture_dma_data;
159 struct tegra_pcm_dma_params playback_dma_data; 159 struct tegra_pcm_dma_params playback_dma_data;
160 struct regmap *regmap; 160 struct regmap *regmap;
161 u32 reg_ctrl;
162}; 161};
163 162
164#endif 163#endif
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index 2262e4fdec2a..3ebc8670ba00 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -37,19 +37,6 @@
37 37
38#define DRV_NAME "tegra20-spdif" 38#define DRV_NAME "tegra20-spdif"
39 39
40static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg,
41 u32 val)
42{
43 regmap_write(spdif->regmap, reg, val);
44}
45
46static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg)
47{
48 u32 val;
49 regmap_read(spdif->regmap, reg, &val);
50 return val;
51}
52
53static int tegra20_spdif_runtime_suspend(struct device *dev) 40static int tegra20_spdif_runtime_suspend(struct device *dev)
54{ 41{
55 struct tegra20_spdif *spdif = dev_get_drvdata(dev); 42 struct tegra20_spdif *spdif = dev_get_drvdata(dev);
@@ -77,21 +64,24 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
77 struct snd_pcm_hw_params *params, 64 struct snd_pcm_hw_params *params,
78 struct snd_soc_dai *dai) 65 struct snd_soc_dai *dai)
79{ 66{
80 struct device *dev = substream->pcm->card->dev; 67 struct device *dev = dai->dev;
81 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); 68 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
69 unsigned int mask, val;
82 int ret, spdifclock; 70 int ret, spdifclock;
83 71
84 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK; 72 mask = TEGRA20_SPDIF_CTRL_PACK |
85 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; 73 TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
86 switch (params_format(params)) { 74 switch (params_format(params)) {
87 case SNDRV_PCM_FORMAT_S16_LE: 75 case SNDRV_PCM_FORMAT_S16_LE:
88 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK; 76 val = TEGRA20_SPDIF_CTRL_PACK |
89 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; 77 TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
90 break; 78 break;
91 default: 79 default:
92 return -EINVAL; 80 return -EINVAL;
93 } 81 }
94 82
83 regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, mask, val);
84
95 switch (params_rate(params)) { 85 switch (params_rate(params)) {
96 case 32000: 86 case 32000:
97 spdifclock = 4096000; 87 spdifclock = 4096000;
@@ -129,14 +119,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
129 119
130static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif) 120static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif)
131{ 121{
132 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN; 122 regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL,
133 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); 123 TEGRA20_SPDIF_CTRL_TX_EN,
124 TEGRA20_SPDIF_CTRL_TX_EN);
134} 125}
135 126
136static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) 127static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif)
137{ 128{
138 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN; 129 regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL,
139 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); 130 TEGRA20_SPDIF_CTRL_TX_EN, 0);
140} 131}
141 132
142static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, 133static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -181,6 +172,7 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = {
181 .name = DRV_NAME, 172 .name = DRV_NAME,
182 .probe = tegra20_spdif_probe, 173 .probe = tegra20_spdif_probe,
183 .playback = { 174 .playback = {
175 .stream_name = "Playback",
184 .channels_min = 2, 176 .channels_min = 2,
185 .channels_max = 2, 177 .channels_max = 2,
186 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 178 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h
index ed756527efea..b48d699fd583 100644
--- a/sound/soc/tegra/tegra20_spdif.h
+++ b/sound/soc/tegra/tegra20_spdif.h
@@ -465,7 +465,6 @@ struct tegra20_spdif {
465 struct tegra_pcm_dma_params capture_dma_data; 465 struct tegra_pcm_dma_params capture_dma_data;
466 struct tegra_pcm_dma_params playback_dma_data; 466 struct tegra_pcm_dma_params playback_dma_data;
467 struct regmap *regmap; 467 struct regmap *regmap;
468 u32 reg_ctrl;
469}; 468};
470 469
471#endif 470#endif
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index d308faaae148..44184228d1f0 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -44,18 +44,6 @@
44 44
45#define DRV_NAME "tegra30-i2s" 45#define DRV_NAME "tegra30-i2s"
46 46
47static inline void tegra30_i2s_write(struct tegra30_i2s *i2s, u32 reg, u32 val)
48{
49 regmap_write(i2s->regmap, reg, val);
50}
51
52static inline u32 tegra30_i2s_read(struct tegra30_i2s *i2s, u32 reg)
53{
54 u32 val;
55 regmap_read(i2s->regmap, reg, &val);
56 return val;
57}
58
59static int tegra30_i2s_runtime_suspend(struct device *dev) 47static int tegra30_i2s_runtime_suspend(struct device *dev)
60{ 48{
61 struct tegra30_i2s *i2s = dev_get_drvdata(dev); 49 struct tegra30_i2s *i2s = dev_get_drvdata(dev);
@@ -128,6 +116,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
128 unsigned int fmt) 116 unsigned int fmt)
129{ 117{
130 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 118 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
119 unsigned int mask, val;
131 120
132 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 121 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
133 case SND_SOC_DAIFMT_NB_NF: 122 case SND_SOC_DAIFMT_NB_NF:
@@ -136,10 +125,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
136 return -EINVAL; 125 return -EINVAL;
137 } 126 }
138 127
139 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_MASTER_ENABLE; 128 mask = TEGRA30_I2S_CTRL_MASTER_ENABLE;
140 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 129 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
141 case SND_SOC_DAIFMT_CBS_CFS: 130 case SND_SOC_DAIFMT_CBS_CFS:
142 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_MASTER_ENABLE; 131 val = TEGRA30_I2S_CTRL_MASTER_ENABLE;
143 break; 132 break;
144 case SND_SOC_DAIFMT_CBM_CFM: 133 case SND_SOC_DAIFMT_CBM_CFM:
145 break; 134 break;
@@ -147,33 +136,37 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
147 return -EINVAL; 136 return -EINVAL;
148 } 137 }
149 138
150 i2s->reg_ctrl &= ~(TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | 139 mask |= TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK |
151 TEGRA30_I2S_CTRL_LRCK_MASK); 140 TEGRA30_I2S_CTRL_LRCK_MASK;
152 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 141 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
153 case SND_SOC_DAIFMT_DSP_A: 142 case SND_SOC_DAIFMT_DSP_A:
154 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; 143 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
155 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 144 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
156 break; 145 break;
157 case SND_SOC_DAIFMT_DSP_B: 146 case SND_SOC_DAIFMT_DSP_B:
158 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; 147 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
159 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_R_LOW; 148 val |= TEGRA30_I2S_CTRL_LRCK_R_LOW;
160 break; 149 break;
161 case SND_SOC_DAIFMT_I2S: 150 case SND_SOC_DAIFMT_I2S:
162 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 151 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
163 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 152 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
164 break; 153 break;
165 case SND_SOC_DAIFMT_RIGHT_J: 154 case SND_SOC_DAIFMT_RIGHT_J:
166 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 155 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
167 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 156 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
168 break; 157 break;
169 case SND_SOC_DAIFMT_LEFT_J: 158 case SND_SOC_DAIFMT_LEFT_J:
170 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 159 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
171 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 160 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
172 break; 161 break;
173 default: 162 default:
174 return -EINVAL; 163 return -EINVAL;
175 } 164 }
176 165
166 pm_runtime_get_sync(dai->dev);
167 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val);
168 pm_runtime_put(dai->dev);
169
177 return 0; 170 return 0;
178} 171}
179 172
@@ -181,24 +174,26 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
181 struct snd_pcm_hw_params *params, 174 struct snd_pcm_hw_params *params,
182 struct snd_soc_dai *dai) 175 struct snd_soc_dai *dai)
183{ 176{
184 struct device *dev = substream->pcm->card->dev; 177 struct device *dev = dai->dev;
185 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 178 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
186 u32 val; 179 unsigned int mask, val, reg;
187 int ret, sample_size, srate, i2sclock, bitcnt; 180 int ret, sample_size, srate, i2sclock, bitcnt;
188 181
189 if (params_channels(params) != 2) 182 if (params_channels(params) != 2)
190 return -EINVAL; 183 return -EINVAL;
191 184
192 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_BIT_SIZE_MASK; 185 mask = TEGRA30_I2S_CTRL_BIT_SIZE_MASK;
193 switch (params_format(params)) { 186 switch (params_format(params)) {
194 case SNDRV_PCM_FORMAT_S16_LE: 187 case SNDRV_PCM_FORMAT_S16_LE:
195 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_16; 188 val = TEGRA30_I2S_CTRL_BIT_SIZE_16;
196 sample_size = 16; 189 sample_size = 16;
197 break; 190 break;
198 default: 191 default:
199 return -EINVAL; 192 return -EINVAL;
200 } 193 }
201 194
195 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val);
196
202 srate = params_rate(params); 197 srate = params_rate(params);
203 198
204 /* Final "* 2" required by Tegra hardware */ 199 /* Final "* 2" required by Tegra hardware */
@@ -219,7 +214,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
219 if (i2sclock % (2 * srate)) 214 if (i2sclock % (2 * srate))
220 val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; 215 val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE;
221 216
222 tegra30_i2s_write(i2s, TEGRA30_I2S_TIMING, val); 217 regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val);
223 218
224 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | 219 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
225 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | 220 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
@@ -229,15 +224,17 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
229 224
230 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 225 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
231 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; 226 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX;
232 tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_RX_CTRL, val); 227 reg = TEGRA30_I2S_CIF_RX_CTRL;
233 } else { 228 } else {
234 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; 229 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
235 tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_TX_CTRL, val); 230 reg = TEGRA30_I2S_CIF_RX_CTRL;
236 } 231 }
237 232
233 regmap_write(i2s->regmap, reg, val);
234
238 val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | 235 val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) |
239 (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); 236 (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT);
240 tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val); 237 regmap_write(i2s->regmap, TEGRA30_I2S_OFFSET, val);
241 238
242 return 0; 239 return 0;
243} 240}
@@ -245,29 +242,31 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
245static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) 242static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s)
246{ 243{
247 tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); 244 tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif);
248 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; 245 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
249 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 246 TEGRA30_I2S_CTRL_XFER_EN_TX,
247 TEGRA30_I2S_CTRL_XFER_EN_TX);
250} 248}
251 249
252static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) 250static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s)
253{ 251{
254 tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); 252 tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif);
255 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; 253 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
256 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 254 TEGRA30_I2S_CTRL_XFER_EN_TX, 0);
257} 255}
258 256
259static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) 257static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s)
260{ 258{
261 tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); 259 tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif);
262 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_RX; 260 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
263 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 261 TEGRA30_I2S_CTRL_XFER_EN_RX,
262 TEGRA30_I2S_CTRL_XFER_EN_RX);
264} 263}
265 264
266static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) 265static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s)
267{ 266{
268 tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); 267 tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif);
269 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; 268 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
270 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 269 TEGRA30_I2S_CTRL_XFER_EN_RX, 0);
271} 270}
272 271
273static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 272static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -320,12 +319,14 @@ static struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
320static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { 319static const struct snd_soc_dai_driver tegra30_i2s_dai_template = {
321 .probe = tegra30_i2s_probe, 320 .probe = tegra30_i2s_probe,
322 .playback = { 321 .playback = {
322 .stream_name = "Playback",
323 .channels_min = 2, 323 .channels_min = 2,
324 .channels_max = 2, 324 .channels_max = 2,
325 .rates = SNDRV_PCM_RATE_8000_96000, 325 .rates = SNDRV_PCM_RATE_8000_96000,
326 .formats = SNDRV_PCM_FMTBIT_S16_LE, 326 .formats = SNDRV_PCM_FMTBIT_S16_LE,
327 }, 327 },
328 .capture = { 328 .capture = {
329 .stream_name = "Capture",
329 .channels_min = 2, 330 .channels_min = 2,
330 .channels_max = 2, 331 .channels_max = 2,
331 .rates = SNDRV_PCM_RATE_8000_96000, 332 .rates = SNDRV_PCM_RATE_8000_96000,
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h
index 91adf29c7a87..34dc47b9581c 100644
--- a/sound/soc/tegra/tegra30_i2s.h
+++ b/sound/soc/tegra/tegra30_i2s.h
@@ -236,7 +236,6 @@ struct tegra30_i2s {
236 enum tegra30_ahub_txcif playback_fifo_cif; 236 enum tegra30_ahub_txcif playback_fifo_cif;
237 struct tegra_pcm_dma_params playback_dma_data; 237 struct tegra_pcm_dma_params playback_dma_data;
238 struct regmap *regmap; 238 struct regmap *regmap;
239 u32 reg_ctrl;
240}; 239};
241 240
242#endif 241#endif
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 32de7006daf0..d684df294c0c 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver 2* tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver
3 * 3 *
4 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> 4 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
5 * Copyright (C) 2012 - NVIDIA, Inc. 5 * Copyright (C) 2012 - NVIDIA, Inc.
@@ -33,11 +33,8 @@
33 33
34#define DRV_NAME "tegra-alc5632" 34#define DRV_NAME "tegra-alc5632"
35 35
36#define GPIO_HP_DET BIT(0)
37
38struct tegra_alc5632 { 36struct tegra_alc5632 {
39 struct tegra_asoc_utils_data util_data; 37 struct tegra_asoc_utils_data util_data;
40 int gpio_requested;
41 int gpio_hp_det; 38 int gpio_hp_det;
42}; 39};
43 40
@@ -46,7 +43,7 @@ static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream,
46{ 43{
47 struct snd_soc_pcm_runtime *rtd = substream->private_data; 44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
48 struct snd_soc_dai *codec_dai = rtd->codec_dai; 45 struct snd_soc_dai *codec_dai = rtd->codec_dai;
49 struct snd_soc_codec *codec = rtd->codec; 46 struct snd_soc_codec *codec = codec_dai->codec;
50 struct snd_soc_card *card = codec->card; 47 struct snd_soc_card *card = codec->card;
51 struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); 48 struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card);
52 int srate, mclk; 49 int srate, mclk;
@@ -108,9 +105,9 @@ static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
108 105
109static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) 106static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
110{ 107{
111 struct snd_soc_codec *codec = rtd->codec; 108 struct snd_soc_dai *codec_dai = rtd->codec_dai;
109 struct snd_soc_codec *codec = codec_dai->codec;
112 struct snd_soc_dapm_context *dapm = &codec->dapm; 110 struct snd_soc_dapm_context *dapm = &codec->dapm;
113 struct device_node *np = codec->card->dev->of_node;
114 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); 111 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card);
115 112
116 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 113 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
@@ -119,14 +116,11 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
119 ARRAY_SIZE(tegra_alc5632_hs_jack_pins), 116 ARRAY_SIZE(tegra_alc5632_hs_jack_pins),
120 tegra_alc5632_hs_jack_pins); 117 tegra_alc5632_hs_jack_pins);
121 118
122 machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
123
124 if (gpio_is_valid(machine->gpio_hp_det)) { 119 if (gpio_is_valid(machine->gpio_hp_det)) {
125 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; 120 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
126 snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack, 121 snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack,
127 1, 122 1,
128 &tegra_alc5632_hp_jack_gpio); 123 &tegra_alc5632_hp_jack_gpio);
129 machine->gpio_requested |= GPIO_HP_DET;
130 } 124 }
131 125
132 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); 126 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
@@ -159,6 +153,7 @@ static struct snd_soc_card snd_soc_tegra_alc5632 = {
159 153
160static __devinit int tegra_alc5632_probe(struct platform_device *pdev) 154static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
161{ 155{
156 struct device_node *np = pdev->dev.of_node;
162 struct snd_soc_card *card = &snd_soc_tegra_alc5632; 157 struct snd_soc_card *card = &snd_soc_tegra_alc5632;
163 struct tegra_alc5632 *alc5632; 158 struct tegra_alc5632 *alc5632;
164 int ret; 159 int ret;
@@ -181,6 +176,10 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
181 goto err; 176 goto err;
182 } 177 }
183 178
179 alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
180 if (alc5632->gpio_hp_det == -ENODEV)
181 return -EPROBE_DEFER;
182
184 ret = snd_soc_of_parse_card_name(card, "nvidia,model"); 183 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
185 if (ret) 184 if (ret)
186 goto err; 185 goto err;
@@ -199,16 +198,16 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
199 goto err; 198 goto err;
200 } 199 }
201 200
202 tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle( 201 tegra_alc5632_dai.cpu_of_node = of_parse_phandle(
203 pdev->dev.of_node, "nvidia,i2s-controller", 0); 202 pdev->dev.of_node, "nvidia,i2s-controller", 0);
204 if (!tegra_alc5632_dai.cpu_dai_of_node) { 203 if (!tegra_alc5632_dai.cpu_of_node) {
205 dev_err(&pdev->dev, 204 dev_err(&pdev->dev,
206 "Property 'nvidia,i2s-controller' missing or invalid\n"); 205 "Property 'nvidia,i2s-controller' missing or invalid\n");
207 ret = -EINVAL; 206 ret = -EINVAL;
208 goto err; 207 goto err;
209 } 208 }
210 209
211 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_dai_of_node; 210 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_of_node;
212 211
213 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); 212 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
214 if (ret) 213 if (ret)
@@ -234,11 +233,8 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
234 struct snd_soc_card *card = platform_get_drvdata(pdev); 233 struct snd_soc_card *card = platform_get_drvdata(pdev);
235 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); 234 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card);
236 235
237 if (machine->gpio_requested & GPIO_HP_DET) 236 snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, 1,
238 snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, 237 &tegra_alc5632_hp_jack_gpio);
239 1,
240 &tegra_alc5632_hp_jack_gpio);
241 machine->gpio_requested = 0;
242 238
243 snd_soc_unregister_card(card); 239 snd_soc_unregister_card(card);
244 240
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 127348dc09b1..5658bcec1931 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -36,6 +36,7 @@
36#include <sound/pcm.h> 36#include <sound/pcm.h>
37#include <sound/pcm_params.h> 37#include <sound/pcm_params.h>
38#include <sound/soc.h> 38#include <sound/soc.h>
39#include <sound/dmaengine_pcm.h>
39 40
40#include "tegra_pcm.h" 41#include "tegra_pcm.h"
41 42
@@ -56,6 +57,7 @@ static const struct snd_pcm_hardware tegra_pcm_hardware = {
56 .fifo_size = 4, 57 .fifo_size = 4,
57}; 58};
58 59
60#if defined(CONFIG_TEGRA_SYSTEM_DMA)
59static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd) 61static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd)
60{ 62{
61 struct snd_pcm_substream *substream = prtd->substream; 63 struct snd_pcm_substream *substream = prtd->substream;
@@ -285,6 +287,119 @@ static struct snd_pcm_ops tegra_pcm_ops = {
285 .pointer = tegra_pcm_pointer, 287 .pointer = tegra_pcm_pointer,
286 .mmap = tegra_pcm_mmap, 288 .mmap = tegra_pcm_mmap,
287}; 289};
290#else
291static int tegra_pcm_open(struct snd_pcm_substream *substream)
292{
293 struct snd_soc_pcm_runtime *rtd = substream->private_data;
294 struct device *dev = rtd->platform->dev;
295 int ret;
296
297 /* Set HW params now that initialization is complete */
298 snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);
299
300 ret = snd_dmaengine_pcm_open(substream, NULL, NULL);
301 if (ret) {
302 dev_err(dev, "dmaengine pcm open failed with err %d\n", ret);
303 return ret;
304 }
305
306 return 0;
307}
308
309static int tegra_pcm_close(struct snd_pcm_substream *substream)
310{
311 snd_dmaengine_pcm_close(substream);
312 return 0;
313}
314
315static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
316 struct snd_pcm_hw_params *params)
317{
318 struct snd_soc_pcm_runtime *rtd = substream->private_data;
319 struct device *dev = rtd->platform->dev;
320 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
321 struct tegra_pcm_dma_params *dmap;
322 struct dma_slave_config slave_config;
323 int ret;
324
325 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
326
327 ret = snd_hwparams_to_dma_slave_config(substream, params,
328 &slave_config);
329 if (ret) {
330 dev_err(dev, "hw params config failed with err %d\n", ret);
331 return ret;
332 }
333
334 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
335 slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
336 slave_config.dst_addr = dmap->addr;
337 slave_config.src_maxburst = 0;
338 } else {
339 slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
340 slave_config.src_addr = dmap->addr;
341 slave_config.dst_maxburst = 0;
342 }
343 slave_config.slave_id = dmap->req_sel;
344
345 ret = dmaengine_slave_config(chan, &slave_config);
346 if (ret < 0) {
347 dev_err(dev, "dma slave config failed with err %d\n", ret);
348 return ret;
349 }
350
351 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
352 return 0;
353}
354
355static int tegra_pcm_hw_free(struct snd_pcm_substream *substream)
356{
357 snd_pcm_set_runtime_buffer(substream, NULL);
358 return 0;
359}
360
361static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
362{
363 switch (cmd) {
364 case SNDRV_PCM_TRIGGER_START:
365 case SNDRV_PCM_TRIGGER_RESUME:
366 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
367 return snd_dmaengine_pcm_trigger(substream,
368 SNDRV_PCM_TRIGGER_START);
369
370 case SNDRV_PCM_TRIGGER_STOP:
371 case SNDRV_PCM_TRIGGER_SUSPEND:
372 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
373 return snd_dmaengine_pcm_trigger(substream,
374 SNDRV_PCM_TRIGGER_STOP);
375 default:
376 return -EINVAL;
377 }
378 return 0;
379}
380
381static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
382 struct vm_area_struct *vma)
383{
384 struct snd_pcm_runtime *runtime = substream->runtime;
385
386 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
387 runtime->dma_area,
388 runtime->dma_addr,
389 runtime->dma_bytes);
390}
391
392static struct snd_pcm_ops tegra_pcm_ops = {
393 .open = tegra_pcm_open,
394 .close = tegra_pcm_close,
395 .ioctl = snd_pcm_lib_ioctl,
396 .hw_params = tegra_pcm_hw_params,
397 .hw_free = tegra_pcm_hw_free,
398 .trigger = tegra_pcm_trigger,
399 .pointer = snd_dmaengine_pcm_pointer,
400 .mmap = tegra_pcm_mmap,
401};
402#endif
288 403
289static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 404static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
290{ 405{
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index 985d418a35e7..a3a450352dcf 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -40,6 +40,7 @@ struct tegra_pcm_dma_params {
40 unsigned long req_sel; 40 unsigned long req_sel;
41}; 41};
42 42
43#if defined(CONFIG_TEGRA_SYSTEM_DMA)
43struct tegra_runtime_data { 44struct tegra_runtime_data {
44 struct snd_pcm_substream *substream; 45 struct snd_pcm_substream *substream;
45 spinlock_t lock; 46 spinlock_t lock;
@@ -51,6 +52,7 @@ struct tegra_runtime_data {
51 struct tegra_dma_req dma_req[2]; 52 struct tegra_dma_req dma_req[2];
52 struct tegra_dma_channel *dma_chan; 53 struct tegra_dma_channel *dma_chan;
53}; 54};
55#endif
54 56
55int tegra_pcm_platform_register(struct device *dev); 57int tegra_pcm_platform_register(struct device *dev);
56void tegra_pcm_platform_unregister(struct device *dev); 58void tegra_pcm_platform_unregister(struct device *dev);
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c
index 4e77026807a2..ea9166d5c4eb 100644
--- a/sound/soc/tegra/tegra_wm8753.c
+++ b/sound/soc/tegra/tegra_wm8753.c
@@ -57,7 +57,7 @@ static int tegra_wm8753_hw_params(struct snd_pcm_substream *substream,
57{ 57{
58 struct snd_soc_pcm_runtime *rtd = substream->private_data; 58 struct snd_soc_pcm_runtime *rtd = substream->private_data;
59 struct snd_soc_dai *codec_dai = rtd->codec_dai; 59 struct snd_soc_dai *codec_dai = rtd->codec_dai;
60 struct snd_soc_codec *codec = rtd->codec; 60 struct snd_soc_codec *codec = codec_dai->codec;
61 struct snd_soc_card *card = codec->card; 61 struct snd_soc_card *card = codec->card;
62 struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); 62 struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card);
63 int srate, mclk; 63 int srate, mclk;
@@ -157,9 +157,9 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
157 goto err; 157 goto err;
158 } 158 }
159 159
160 tegra_wm8753_dai.cpu_dai_of_node = of_parse_phandle( 160 tegra_wm8753_dai.cpu_of_node = of_parse_phandle(
161 pdev->dev.of_node, "nvidia,i2s-controller", 0); 161 pdev->dev.of_node, "nvidia,i2s-controller", 0);
162 if (!tegra_wm8753_dai.cpu_dai_of_node) { 162 if (!tegra_wm8753_dai.cpu_of_node) {
163 dev_err(&pdev->dev, 163 dev_err(&pdev->dev,
164 "Property 'nvidia,i2s-controller' missing or invalid\n"); 164 "Property 'nvidia,i2s-controller' missing or invalid\n");
165 ret = -EINVAL; 165 ret = -EINVAL;
@@ -167,7 +167,7 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
167 } 167 }
168 168
169 tegra_wm8753_dai.platform_of_node = 169 tegra_wm8753_dai.platform_of_node =
170 tegra_wm8753_dai.cpu_dai_of_node; 170 tegra_wm8753_dai.cpu_of_node;
171 171
172 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); 172 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
173 if (ret) 173 if (ret)
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 3b6da91188a9..0c5bb33d258e 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -28,8 +28,6 @@
28 * 28 *
29 */ 29 */
30 30
31#include <asm/mach-types.h>
32
33#include <linux/module.h> 31#include <linux/module.h>
34#include <linux/platform_device.h> 32#include <linux/platform_device.h>
35#include <linux/slab.h> 33#include <linux/slab.h>
@@ -50,16 +48,9 @@
50 48
51#define DRV_NAME "tegra-snd-wm8903" 49#define DRV_NAME "tegra-snd-wm8903"
52 50
53#define GPIO_SPKR_EN BIT(0)
54#define GPIO_HP_MUTE BIT(1)
55#define GPIO_INT_MIC_EN BIT(2)
56#define GPIO_EXT_MIC_EN BIT(3)
57#define GPIO_HP_DET BIT(4)
58
59struct tegra_wm8903 { 51struct tegra_wm8903 {
60 struct tegra_wm8903_platform_data pdata; 52 struct tegra_wm8903_platform_data pdata;
61 struct tegra_asoc_utils_data util_data; 53 struct tegra_asoc_utils_data util_data;
62 int gpio_requested;
63}; 54};
64 55
65static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, 56static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
@@ -67,8 +58,7 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
67{ 58{
68 struct snd_soc_pcm_runtime *rtd = substream->private_data; 59 struct snd_soc_pcm_runtime *rtd = substream->private_data;
69 struct snd_soc_dai *codec_dai = rtd->codec_dai; 60 struct snd_soc_dai *codec_dai = rtd->codec_dai;
70 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 61 struct snd_soc_codec *codec = codec_dai->codec;
71 struct snd_soc_codec *codec = rtd->codec;
72 struct snd_soc_card *card = codec->card; 62 struct snd_soc_card *card = codec->card;
73 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 63 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
74 int srate, mclk; 64 int srate, mclk;
@@ -95,24 +85,6 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
95 return err; 85 return err;
96 } 86 }
97 87
98 err = snd_soc_dai_set_fmt(codec_dai,
99 SND_SOC_DAIFMT_I2S |
100 SND_SOC_DAIFMT_NB_NF |
101 SND_SOC_DAIFMT_CBS_CFS);
102 if (err < 0) {
103 dev_err(card->dev, "codec_dai fmt not set\n");
104 return err;
105 }
106
107 err = snd_soc_dai_set_fmt(cpu_dai,
108 SND_SOC_DAIFMT_I2S |
109 SND_SOC_DAIFMT_NB_NF |
110 SND_SOC_DAIFMT_CBS_CFS);
111 if (err < 0) {
112 dev_err(card->dev, "cpu_dai fmt not set\n");
113 return err;
114 }
115
116 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 88 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
117 SND_SOC_CLOCK_IN); 89 SND_SOC_CLOCK_IN);
118 if (err < 0) { 90 if (err < 0) {
@@ -160,7 +132,7 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w,
160 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 132 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
161 struct tegra_wm8903_platform_data *pdata = &machine->pdata; 133 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
162 134
163 if (!(machine->gpio_requested & GPIO_SPKR_EN)) 135 if (!gpio_is_valid(pdata->gpio_spkr_en))
164 return 0; 136 return 0;
165 137
166 gpio_set_value_cansleep(pdata->gpio_spkr_en, 138 gpio_set_value_cansleep(pdata->gpio_spkr_en,
@@ -177,7 +149,7 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w,
177 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 149 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
178 struct tegra_wm8903_platform_data *pdata = &machine->pdata; 150 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
179 151
180 if (!(machine->gpio_requested & GPIO_HP_MUTE)) 152 if (!gpio_is_valid(pdata->gpio_hp_mute))
181 return 0; 153 return 0;
182 154
183 gpio_set_value_cansleep(pdata->gpio_hp_mute, 155 gpio_set_value_cansleep(pdata->gpio_hp_mute,
@@ -203,122 +175,18 @@ static const struct snd_soc_dapm_route harmony_audio_map[] = {
203 {"IN1L", NULL, "Mic Jack"}, 175 {"IN1L", NULL, "Mic Jack"},
204}; 176};
205 177
206static const struct snd_soc_dapm_route seaboard_audio_map[] = {
207 {"Headphone Jack", NULL, "HPOUTR"},
208 {"Headphone Jack", NULL, "HPOUTL"},
209 {"Int Spk", NULL, "ROP"},
210 {"Int Spk", NULL, "RON"},
211 {"Int Spk", NULL, "LOP"},
212 {"Int Spk", NULL, "LON"},
213 {"Mic Jack", NULL, "MICBIAS"},
214 {"IN1R", NULL, "Mic Jack"},
215};
216
217static const struct snd_soc_dapm_route kaen_audio_map[] = {
218 {"Headphone Jack", NULL, "HPOUTR"},
219 {"Headphone Jack", NULL, "HPOUTL"},
220 {"Int Spk", NULL, "ROP"},
221 {"Int Spk", NULL, "RON"},
222 {"Int Spk", NULL, "LOP"},
223 {"Int Spk", NULL, "LON"},
224 {"Mic Jack", NULL, "MICBIAS"},
225 {"IN2R", NULL, "Mic Jack"},
226};
227
228static const struct snd_soc_dapm_route aebl_audio_map[] = {
229 {"Headphone Jack", NULL, "HPOUTR"},
230 {"Headphone Jack", NULL, "HPOUTL"},
231 {"Int Spk", NULL, "LINEOUTR"},
232 {"Int Spk", NULL, "LINEOUTL"},
233 {"Mic Jack", NULL, "MICBIAS"},
234 {"IN1R", NULL, "Mic Jack"},
235};
236
237static const struct snd_kcontrol_new tegra_wm8903_controls[] = { 178static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
238 SOC_DAPM_PIN_SWITCH("Int Spk"), 179 SOC_DAPM_PIN_SWITCH("Int Spk"),
239}; 180};
240 181
241static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) 182static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
242{ 183{
243 struct snd_soc_codec *codec = rtd->codec; 184 struct snd_soc_dai *codec_dai = rtd->codec_dai;
185 struct snd_soc_codec *codec = codec_dai->codec;
244 struct snd_soc_dapm_context *dapm = &codec->dapm; 186 struct snd_soc_dapm_context *dapm = &codec->dapm;
245 struct snd_soc_card *card = codec->card; 187 struct snd_soc_card *card = codec->card;
246 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 188 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
247 struct tegra_wm8903_platform_data *pdata = &machine->pdata; 189 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
248 struct device_node *np = card->dev->of_node;
249 int ret;
250
251 if (card->dev->platform_data) {
252 memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
253 } else if (np) {
254 /*
255 * This part must be in init() rather than probe() in order to
256 * guarantee that the WM8903 has been probed, and hence its
257 * GPIO controller registered, which is a pre-condition for
258 * of_get_named_gpio() to be able to map the phandles in the
259 * properties to the controller node. Given this, all
260 * pdata handling is in init() for consistency.
261 */
262 pdata->gpio_spkr_en = of_get_named_gpio(np,
263 "nvidia,spkr-en-gpios", 0);
264 pdata->gpio_hp_mute = of_get_named_gpio(np,
265 "nvidia,hp-mute-gpios", 0);
266 pdata->gpio_hp_det = of_get_named_gpio(np,
267 "nvidia,hp-det-gpios", 0);
268 pdata->gpio_int_mic_en = of_get_named_gpio(np,
269 "nvidia,int-mic-en-gpios", 0);
270 pdata->gpio_ext_mic_en = of_get_named_gpio(np,
271 "nvidia,ext-mic-en-gpios", 0);
272 } else {
273 dev_err(card->dev, "No platform data supplied\n");
274 return -EINVAL;
275 }
276
277 if (gpio_is_valid(pdata->gpio_spkr_en)) {
278 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
279 if (ret) {
280 dev_err(card->dev, "cannot get spkr_en gpio\n");
281 return ret;
282 }
283 machine->gpio_requested |= GPIO_SPKR_EN;
284
285 gpio_direction_output(pdata->gpio_spkr_en, 0);
286 }
287
288 if (gpio_is_valid(pdata->gpio_hp_mute)) {
289 ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
290 if (ret) {
291 dev_err(card->dev, "cannot get hp_mute gpio\n");
292 return ret;
293 }
294 machine->gpio_requested |= GPIO_HP_MUTE;
295
296 gpio_direction_output(pdata->gpio_hp_mute, 1);
297 }
298
299 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
300 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
301 if (ret) {
302 dev_err(card->dev, "cannot get int_mic_en gpio\n");
303 return ret;
304 }
305 machine->gpio_requested |= GPIO_INT_MIC_EN;
306
307 /* Disable int mic; enable signal is active-high */
308 gpio_direction_output(pdata->gpio_int_mic_en, 0);
309 }
310
311 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
312 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
313 if (ret) {
314 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
315 return ret;
316 }
317 machine->gpio_requested |= GPIO_EXT_MIC_EN;
318
319 /* Enable ext mic; enable signal is active-low */
320 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
321 }
322 190
323 if (gpio_is_valid(pdata->gpio_hp_det)) { 191 if (gpio_is_valid(pdata->gpio_hp_det)) {
324 tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; 192 tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;
@@ -330,7 +198,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
330 snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, 198 snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
331 1, 199 1,
332 &tegra_wm8903_hp_jack_gpio); 200 &tegra_wm8903_hp_jack_gpio);
333 machine->gpio_requested |= GPIO_HP_DET;
334 } 201 }
335 202
336 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, 203 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
@@ -366,6 +233,9 @@ static struct snd_soc_dai_link tegra_wm8903_dai = {
366 .codec_dai_name = "wm8903-hifi", 233 .codec_dai_name = "wm8903-hifi",
367 .init = tegra_wm8903_init, 234 .init = tegra_wm8903_init,
368 .ops = &tegra_wm8903_ops, 235 .ops = &tegra_wm8903_ops,
236 .dai_fmt = SND_SOC_DAIFMT_I2S |
237 SND_SOC_DAIFMT_NB_NF |
238 SND_SOC_DAIFMT_CBS_CFS,
369}; 239};
370 240
371static struct snd_soc_card snd_soc_tegra_wm8903 = { 241static struct snd_soc_card snd_soc_tegra_wm8903 = {
@@ -385,8 +255,10 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = {
385 255
386static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) 256static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
387{ 257{
258 struct device_node *np = pdev->dev.of_node;
388 struct snd_soc_card *card = &snd_soc_tegra_wm8903; 259 struct snd_soc_card *card = &snd_soc_tegra_wm8903;
389 struct tegra_wm8903 *machine; 260 struct tegra_wm8903 *machine;
261 struct tegra_wm8903_platform_data *pdata;
390 int ret; 262 int ret;
391 263
392 if (!pdev->dev.platform_data && !pdev->dev.of_node) { 264 if (!pdev->dev.platform_data && !pdev->dev.of_node) {
@@ -401,12 +273,42 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
401 ret = -ENOMEM; 273 ret = -ENOMEM;
402 goto err; 274 goto err;
403 } 275 }
276 pdata = &machine->pdata;
404 277
405 card->dev = &pdev->dev; 278 card->dev = &pdev->dev;
406 platform_set_drvdata(pdev, card); 279 platform_set_drvdata(pdev, card);
407 snd_soc_card_set_drvdata(card, machine); 280 snd_soc_card_set_drvdata(card, machine);
408 281
409 if (pdev->dev.of_node) { 282 if (pdev->dev.platform_data) {
283 memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
284 } else if (np) {
285 pdata->gpio_spkr_en = of_get_named_gpio(np,
286 "nvidia,spkr-en-gpios", 0);
287 if (pdata->gpio_spkr_en == -ENODEV)
288 return -EPROBE_DEFER;
289
290 pdata->gpio_hp_mute = of_get_named_gpio(np,
291 "nvidia,hp-mute-gpios", 0);
292 if (pdata->gpio_hp_mute == -ENODEV)
293 return -EPROBE_DEFER;
294
295 pdata->gpio_hp_det = of_get_named_gpio(np,
296 "nvidia,hp-det-gpios", 0);
297 if (pdata->gpio_hp_det == -ENODEV)
298 return -EPROBE_DEFER;
299
300 pdata->gpio_int_mic_en = of_get_named_gpio(np,
301 "nvidia,int-mic-en-gpios", 0);
302 if (pdata->gpio_int_mic_en == -ENODEV)
303 return -EPROBE_DEFER;
304
305 pdata->gpio_ext_mic_en = of_get_named_gpio(np,
306 "nvidia,ext-mic-en-gpios", 0);
307 if (pdata->gpio_ext_mic_en == -ENODEV)
308 return -EPROBE_DEFER;
309 }
310
311 if (np) {
410 ret = snd_soc_of_parse_card_name(card, "nvidia,model"); 312 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
411 if (ret) 313 if (ret)
412 goto err; 314 goto err;
@@ -417,8 +319,8 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
417 goto err; 319 goto err;
418 320
419 tegra_wm8903_dai.codec_name = NULL; 321 tegra_wm8903_dai.codec_name = NULL;
420 tegra_wm8903_dai.codec_of_node = of_parse_phandle( 322 tegra_wm8903_dai.codec_of_node = of_parse_phandle(np,
421 pdev->dev.of_node, "nvidia,audio-codec", 0); 323 "nvidia,audio-codec", 0);
422 if (!tegra_wm8903_dai.codec_of_node) { 324 if (!tegra_wm8903_dai.codec_of_node) {
423 dev_err(&pdev->dev, 325 dev_err(&pdev->dev,
424 "Property 'nvidia,audio-codec' missing or invalid\n"); 326 "Property 'nvidia,audio-codec' missing or invalid\n");
@@ -427,9 +329,9 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
427 } 329 }
428 330
429 tegra_wm8903_dai.cpu_dai_name = NULL; 331 tegra_wm8903_dai.cpu_dai_name = NULL;
430 tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle( 332 tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np,
431 pdev->dev.of_node, "nvidia,i2s-controller", 0); 333 "nvidia,i2s-controller", 0);
432 if (!tegra_wm8903_dai.cpu_dai_of_node) { 334 if (!tegra_wm8903_dai.cpu_of_node) {
433 dev_err(&pdev->dev, 335 dev_err(&pdev->dev,
434 "Property 'nvidia,i2s-controller' missing or invalid\n"); 336 "Property 'nvidia,i2s-controller' missing or invalid\n");
435 ret = -EINVAL; 337 ret = -EINVAL;
@@ -438,20 +340,47 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
438 340
439 tegra_wm8903_dai.platform_name = NULL; 341 tegra_wm8903_dai.platform_name = NULL;
440 tegra_wm8903_dai.platform_of_node = 342 tegra_wm8903_dai.platform_of_node =
441 tegra_wm8903_dai.cpu_dai_of_node; 343 tegra_wm8903_dai.cpu_of_node;
442 } else { 344 } else {
443 if (machine_is_harmony()) { 345 card->dapm_routes = harmony_audio_map;
444 card->dapm_routes = harmony_audio_map; 346 card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
445 card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); 347 }
446 } else if (machine_is_seaboard()) { 348
447 card->dapm_routes = seaboard_audio_map; 349 if (gpio_is_valid(pdata->gpio_spkr_en)) {
448 card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map); 350 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_spkr_en,
449 } else if (machine_is_kaen()) { 351 GPIOF_OUT_INIT_LOW, "spkr_en");
450 card->dapm_routes = kaen_audio_map; 352 if (ret) {
451 card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map); 353 dev_err(card->dev, "cannot get spkr_en gpio\n");
452 } else { 354 return ret;
453 card->dapm_routes = aebl_audio_map; 355 }
454 card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map); 356 }
357
358 if (gpio_is_valid(pdata->gpio_hp_mute)) {
359 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute,
360 GPIOF_OUT_INIT_HIGH, "hp_mute");
361 if (ret) {
362 dev_err(card->dev, "cannot get hp_mute gpio\n");
363 return ret;
364 }
365 }
366
367 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
368 /* Disable int mic; enable signal is active-high */
369 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_int_mic_en,
370 GPIOF_OUT_INIT_LOW, "int_mic_en");
371 if (ret) {
372 dev_err(card->dev, "cannot get int_mic_en gpio\n");
373 return ret;
374 }
375 }
376
377 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
378 /* Enable ext mic; enable signal is active-low */
379 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_ext_mic_en,
380 GPIOF_OUT_INIT_LOW, "ext_mic_en");
381 if (ret) {
382 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
383 return ret;
455 } 384 }
456 } 385 }
457 386
@@ -478,21 +407,9 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
478{ 407{
479 struct snd_soc_card *card = platform_get_drvdata(pdev); 408 struct snd_soc_card *card = platform_get_drvdata(pdev);
480 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 409 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
481 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
482 410
483 if (machine->gpio_requested & GPIO_HP_DET) 411 snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 1,
484 snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 412 &tegra_wm8903_hp_jack_gpio);
485 1,
486 &tegra_wm8903_hp_jack_gpio);
487 if (machine->gpio_requested & GPIO_EXT_MIC_EN)
488 gpio_free(pdata->gpio_ext_mic_en);
489 if (machine->gpio_requested & GPIO_INT_MIC_EN)
490 gpio_free(pdata->gpio_int_mic_en);
491 if (machine->gpio_requested & GPIO_HP_MUTE)
492 gpio_free(pdata->gpio_hp_mute);
493 if (machine->gpio_requested & GPIO_SPKR_EN)
494 gpio_free(pdata->gpio_spkr_en);
495 machine->gpio_requested = 0;
496 413
497 snd_soc_unregister_card(card); 414 snd_soc_unregister_card(card);
498 415
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 4a8d5b672c9f..e69a4f7000d6 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -52,8 +52,7 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream,
52{ 52{
53 struct snd_soc_pcm_runtime *rtd = substream->private_data; 53 struct snd_soc_pcm_runtime *rtd = substream->private_data;
54 struct snd_soc_dai *codec_dai = rtd->codec_dai; 54 struct snd_soc_dai *codec_dai = rtd->codec_dai;
55 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 55 struct snd_soc_codec *codec = codec_dai->codec;
56 struct snd_soc_codec *codec = rtd->codec;
57 struct snd_soc_card *card = codec->card; 56 struct snd_soc_card *card = codec->card;
58 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card); 57 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card);
59 int srate, mclk; 58 int srate, mclk;
@@ -68,24 +67,6 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream,
68 return err; 67 return err;
69 } 68 }
70 69
71 err = snd_soc_dai_set_fmt(codec_dai,
72 SND_SOC_DAIFMT_I2S |
73 SND_SOC_DAIFMT_NB_NF |
74 SND_SOC_DAIFMT_CBS_CFS);
75 if (err < 0) {
76 dev_err(card->dev, "codec_dai fmt not set\n");
77 return err;
78 }
79
80 err = snd_soc_dai_set_fmt(cpu_dai,
81 SND_SOC_DAIFMT_I2S |
82 SND_SOC_DAIFMT_NB_NF |
83 SND_SOC_DAIFMT_CBS_CFS);
84 if (err < 0) {
85 dev_err(card->dev, "cpu_dai fmt not set\n");
86 return err;
87 }
88
89 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 70 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
90 SND_SOC_CLOCK_IN); 71 SND_SOC_CLOCK_IN);
91 if (err < 0) { 72 if (err < 0) {
@@ -121,6 +102,9 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
121 .cpu_dai_name = "tegra20-i2s.0", 102 .cpu_dai_name = "tegra20-i2s.0",
122 .codec_dai_name = "tlv320aic23-hifi", 103 .codec_dai_name = "tlv320aic23-hifi",
123 .ops = &trimslice_asoc_ops, 104 .ops = &trimslice_asoc_ops,
105 .dai_fmt = SND_SOC_DAIFMT_I2S |
106 SND_SOC_DAIFMT_NB_NF |
107 SND_SOC_DAIFMT_CBS_CFS,
124}; 108};
125 109
126static struct snd_soc_card snd_soc_trimslice = { 110static struct snd_soc_card snd_soc_trimslice = {
@@ -162,9 +146,9 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
162 } 146 }
163 147
164 trimslice_tlv320aic23_dai.cpu_dai_name = NULL; 148 trimslice_tlv320aic23_dai.cpu_dai_name = NULL;
165 trimslice_tlv320aic23_dai.cpu_dai_of_node = of_parse_phandle( 149 trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle(
166 pdev->dev.of_node, "nvidia,i2s-controller", 0); 150 pdev->dev.of_node, "nvidia,i2s-controller", 0);
167 if (!trimslice_tlv320aic23_dai.cpu_dai_of_node) { 151 if (!trimslice_tlv320aic23_dai.cpu_of_node) {
168 dev_err(&pdev->dev, 152 dev_err(&pdev->dev,
169 "Property 'nvidia,i2s-controller' missing or invalid\n"); 153 "Property 'nvidia,i2s-controller' missing or invalid\n");
170 ret = -EINVAL; 154 ret = -EINVAL;
@@ -173,7 +157,7 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
173 157
174 trimslice_tlv320aic23_dai.platform_name = NULL; 158 trimslice_tlv320aic23_dai.platform_name = NULL;
175 trimslice_tlv320aic23_dai.platform_of_node = 159 trimslice_tlv320aic23_dai.platform_of_node =
176 trimslice_tlv320aic23_dai.cpu_dai_of_node; 160 trimslice_tlv320aic23_dai.cpu_of_node;
177 } 161 }
178 162
179 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); 163 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);