aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/omap-mcbsp.c
diff options
context:
space:
mode:
authorPeter Ujfalusi <peter.ujfalusi@ti.com>2012-02-14 11:20:58 -0500
committerLiam Girdwood <lrg@ti.com>2012-03-12 09:34:19 -0400
commit45656b44f6d1968d838f3abcf3a264ee9fa2fc62 (patch)
treeaf489389d8565bdd83f756115239524814b902d9 /sound/soc/omap/omap-mcbsp.c
parent219f43164e8c611c6b8e7b628def9183098b430b (diff)
ASoC: omap-mcbsp: Create a single driver for McBSP
The OMAP McBSP driver stack used to contain two different drivers. One of them was used as kind low-level access to the IP, while the other driver was the ASoC DAI driver. There were global, shared structures, in different places, the McBSP instances are reffered with id numbers (sometimes 0 based, in other cases 1 based id numbers). Create one single driver for OMAP McBSP with name: omap-mcbsp. Convert the old omap-mcbsp driver initially to be a library for the omap-mcbsp DAI driver. With this change we can get rid of all global variables, structures. Further cleanup is coming... Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com> Tested-by: Grazvydas Ignotas <notasas@gmail.com> Tested-by: Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Jarkko Nikula <jarkko.nikula@bitmer.com> Signed-off-by: Liam Girdwood <lrg@ti.com>
Diffstat (limited to 'sound/soc/omap/omap-mcbsp.c')
-rw-r--r--sound/soc/omap/omap-mcbsp.c201
1 files changed, 96 insertions, 105 deletions
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index f1318c1d4e15..892400259494 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -56,36 +56,18 @@ enum {
56 OMAP_MCBSP_WORD_32, 56 OMAP_MCBSP_WORD_32,
57}; 57};
58 58
59struct omap_mcbsp_data {
60 unsigned int bus_id;
61 struct omap_mcbsp_reg_cfg regs;
62 unsigned int fmt;
63 /*
64 * Flags indicating is the bus already activated and configured by
65 * another substream
66 */
67 int active;
68 int configured;
69 unsigned int in_freq;
70 int clk_div;
71 int wlen;
72};
73
74static struct omap_mcbsp_data mcbsp_data[NUM_LINKS];
75
76/* 59/*
77 * Stream DMA parameters. DMA request line and port address are set runtime 60 * Stream DMA parameters. DMA request line and port address are set runtime
78 * since they are different between OMAP1 and later OMAPs 61 * since they are different between OMAP1 and later OMAPs
79 */ 62 */
80static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2];
81
82static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) 63static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
83{ 64{
84 struct snd_soc_pcm_runtime *rtd = substream->private_data; 65 struct snd_soc_pcm_runtime *rtd = substream->private_data;
85 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 66 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
86 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 67 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
68 struct omap_mcbsp_data *mcbsp_data = &mcbsp->mcbsp_data;
87 struct omap_pcm_dma_data *dma_data; 69 struct omap_pcm_dma_data *dma_data;
88 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id); 70 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp);
89 int words; 71 int words;
90 72
91 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 73 dma_data = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
@@ -107,9 +89,9 @@ static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
107 89
108 /* Configure McBSP internal buffer usage */ 90 /* Configure McBSP internal buffer usage */
109 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 91 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
110 omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, words); 92 omap_mcbsp_set_tx_threshold(mcbsp, words);
111 else 93 else
112 omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, words); 94 omap_mcbsp_set_rx_threshold(mcbsp, words);
113} 95}
114 96
115static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params, 97static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
@@ -119,12 +101,12 @@ static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
119 SNDRV_PCM_HW_PARAM_BUFFER_SIZE); 101 SNDRV_PCM_HW_PARAM_BUFFER_SIZE);
120 struct snd_interval *channels = hw_param_interval(params, 102 struct snd_interval *channels = hw_param_interval(params,
121 SNDRV_PCM_HW_PARAM_CHANNELS); 103 SNDRV_PCM_HW_PARAM_CHANNELS);
122 struct omap_mcbsp_data *mcbsp_data = rule->private; 104 struct omap_mcbsp *mcbsp = rule->private;
123 struct snd_interval frames; 105 struct snd_interval frames;
124 int size; 106 int size;
125 107
126 snd_interval_any(&frames); 108 snd_interval_any(&frames);
127 size = omap_mcbsp_get_fifo_size(mcbsp_data->bus_id); 109 size = omap_mcbsp_get_fifo_size(mcbsp);
128 110
129 frames.min = size / channels->min; 111 frames.min = size / channels->min;
130 frames.integer = 1; 112 frames.integer = 1;
@@ -134,12 +116,11 @@ static int omap_mcbsp_hwrule_min_buffersize(struct snd_pcm_hw_params *params,
134static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, 116static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
135 struct snd_soc_dai *cpu_dai) 117 struct snd_soc_dai *cpu_dai)
136{ 118{
137 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 119 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
138 int bus_id = mcbsp_data->bus_id;
139 int err = 0; 120 int err = 0;
140 121
141 if (!cpu_dai->active) 122 if (!cpu_dai->active)
142 err = omap_mcbsp_request(bus_id); 123 err = omap_mcbsp_request(mcbsp);
143 124
144 /* 125 /*
145 * OMAP3 McBSP FIFO is word structured. 126 * OMAP3 McBSP FIFO is word structured.
@@ -156,7 +137,7 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
156 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) 137 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words)
157 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) 138 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words)
158 */ 139 */
159 if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 140 if (mcbsp->pdata->buffer_size) {
160 /* 141 /*
161 * Rule for the buffer size. We should not allow 142 * Rule for the buffer size. We should not allow
162 * smaller buffer than the FIFO size to avoid underruns 143 * smaller buffer than the FIFO size to avoid underruns
@@ -164,7 +145,7 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
164 snd_pcm_hw_rule_add(substream->runtime, 0, 145 snd_pcm_hw_rule_add(substream->runtime, 0,
165 SNDRV_PCM_HW_PARAM_CHANNELS, 146 SNDRV_PCM_HW_PARAM_CHANNELS,
166 omap_mcbsp_hwrule_min_buffersize, 147 omap_mcbsp_hwrule_min_buffersize,
167 mcbsp_data, 148 mcbsp,
168 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1); 149 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, -1);
169 150
170 /* Make sure, that the period size is always even */ 151 /* Make sure, that the period size is always even */
@@ -178,10 +159,11 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
178static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream, 159static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
179 struct snd_soc_dai *cpu_dai) 160 struct snd_soc_dai *cpu_dai)
180{ 161{
181 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 162 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
163 struct omap_mcbsp_data *mcbsp_data = &mcbsp->mcbsp_data;
182 164
183 if (!cpu_dai->active) { 165 if (!cpu_dai->active) {
184 omap_mcbsp_free(mcbsp_data->bus_id); 166 omap_mcbsp_free(mcbsp);
185 mcbsp_data->configured = 0; 167 mcbsp_data->configured = 0;
186 } 168 }
187} 169}
@@ -189,7 +171,8 @@ static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
189static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd, 171static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
190 struct snd_soc_dai *cpu_dai) 172 struct snd_soc_dai *cpu_dai)
191{ 173{
192 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 174 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
175 struct omap_mcbsp_data *mcbsp_data = &mcbsp->mcbsp_data;
193 int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); 176 int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
194 177
195 switch (cmd) { 178 switch (cmd) {
@@ -197,13 +180,13 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
197 case SNDRV_PCM_TRIGGER_RESUME: 180 case SNDRV_PCM_TRIGGER_RESUME:
198 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 181 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
199 mcbsp_data->active++; 182 mcbsp_data->active++;
200 omap_mcbsp_start(mcbsp_data->bus_id, play, !play); 183 omap_mcbsp_start(mcbsp, play, !play);
201 break; 184 break;
202 185
203 case SNDRV_PCM_TRIGGER_STOP: 186 case SNDRV_PCM_TRIGGER_STOP:
204 case SNDRV_PCM_TRIGGER_SUSPEND: 187 case SNDRV_PCM_TRIGGER_SUSPEND:
205 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 188 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
206 omap_mcbsp_stop(mcbsp_data->bus_id, play, !play); 189 omap_mcbsp_stop(mcbsp, play, !play);
207 mcbsp_data->active--; 190 mcbsp_data->active--;
208 break; 191 break;
209 default: 192 default:
@@ -219,14 +202,14 @@ static snd_pcm_sframes_t omap_mcbsp_dai_delay(
219{ 202{
220 struct snd_soc_pcm_runtime *rtd = substream->private_data; 203 struct snd_soc_pcm_runtime *rtd = substream->private_data;
221 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 204 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
222 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 205 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
223 u16 fifo_use; 206 u16 fifo_use;
224 snd_pcm_sframes_t delay; 207 snd_pcm_sframes_t delay;
225 208
226 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 209 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
227 fifo_use = omap_mcbsp_get_tx_delay(mcbsp_data->bus_id); 210 fifo_use = omap_mcbsp_get_tx_delay(mcbsp);
228 else 211 else
229 fifo_use = omap_mcbsp_get_rx_delay(mcbsp_data->bus_id); 212 fifo_use = omap_mcbsp_get_rx_delay(mcbsp);
230 213
231 /* 214 /*
232 * Divide the used locations with the channel count to get the 215 * Divide the used locations with the channel count to get the
@@ -242,19 +225,20 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
242 struct snd_pcm_hw_params *params, 225 struct snd_pcm_hw_params *params,
243 struct snd_soc_dai *cpu_dai) 226 struct snd_soc_dai *cpu_dai)
244{ 227{
245 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 228 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
229 struct omap_mcbsp_data *mcbsp_data = &mcbsp->mcbsp_data;
246 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 230 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
247 struct omap_pcm_dma_data *dma_data; 231 struct omap_pcm_dma_data *dma_data;
248 int dma, bus_id = mcbsp_data->bus_id; 232 int dma;
249 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; 233 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
250 int pkt_size = 0; 234 int pkt_size = 0;
251 unsigned long port; 235 unsigned long port;
252 unsigned int format, div, framesize, master; 236 unsigned int format, div, framesize, master;
253 237
254 dma_data = &omap_mcbsp_dai_dma_params[cpu_dai->id][substream->stream]; 238 dma_data = &mcbsp_data->dma_data[substream->stream];
255 239
256 dma = omap_mcbsp_dma_ch_params(bus_id, substream->stream); 240 dma = omap_mcbsp_dma_ch_params(mcbsp, substream->stream);
257 port = omap_mcbsp_dma_reg_params(bus_id, substream->stream); 241 port = omap_mcbsp_dma_reg_params(mcbsp, substream->stream);
258 242
259 switch (params_format(params)) { 243 switch (params_format(params)) {
260 case SNDRV_PCM_FORMAT_S16_LE: 244 case SNDRV_PCM_FORMAT_S16_LE:
@@ -268,20 +252,20 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
268 default: 252 default:
269 return -EINVAL; 253 return -EINVAL;
270 } 254 }
271 if (cpu_is_omap34xx() || cpu_is_omap44xx()) { 255 if (mcbsp->pdata->buffer_size) {
272 dma_data->set_threshold = omap_mcbsp_set_threshold; 256 dma_data->set_threshold = omap_mcbsp_set_threshold;
273 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */ 257 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
274 if (omap_mcbsp_get_dma_op_mode(bus_id) == 258 if (omap_mcbsp_get_dma_op_mode(mcbsp) ==
275 MCBSP_DMA_MODE_THRESHOLD) { 259 MCBSP_DMA_MODE_THRESHOLD) {
276 int period_words, max_thrsh; 260 int period_words, max_thrsh;
277 261
278 period_words = params_period_bytes(params) / (wlen / 8); 262 period_words = params_period_bytes(params) / (wlen / 8);
279 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 263 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
280 max_thrsh = omap_mcbsp_get_max_tx_threshold( 264 max_thrsh = omap_mcbsp_get_max_tx_threshold(
281 mcbsp_data->bus_id); 265 mcbsp);
282 else 266 else
283 max_thrsh = omap_mcbsp_get_max_rx_threshold( 267 max_thrsh = omap_mcbsp_get_max_rx_threshold(
284 mcbsp_data->bus_id); 268 mcbsp);
285 /* 269 /*
286 * If the period contains less or equal number of words, 270 * If the period contains less or equal number of words,
287 * we are using the original threshold mode setup: 271 * we are using the original threshold mode setup:
@@ -398,7 +382,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
398 break; 382 break;
399 } 383 }
400 384
401 omap_mcbsp_config(bus_id, &mcbsp_data->regs); 385 omap_mcbsp_config(mcbsp, &mcbsp_data->regs);
402 mcbsp_data->wlen = wlen; 386 mcbsp_data->wlen = wlen;
403 mcbsp_data->configured = 1; 387 mcbsp_data->configured = 1;
404 388
@@ -412,7 +396,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
412static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, 396static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
413 unsigned int fmt) 397 unsigned int fmt)
414{ 398{
415 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 399 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
400 struct omap_mcbsp_data *mcbsp_data = &mcbsp->mcbsp_data;
416 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 401 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
417 bool inv_fs = false; 402 bool inv_fs = false;
418 403
@@ -514,7 +499,8 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
514static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai, 499static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
515 int div_id, int div) 500 int div_id, int div)
516{ 501{
517 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 502 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
503 struct omap_mcbsp_data *mcbsp_data = &mcbsp->mcbsp_data;
518 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 504 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
519 505
520 if (div_id != OMAP_MCBSP_CLKGDV) 506 if (div_id != OMAP_MCBSP_CLKGDV)
@@ -531,7 +517,8 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
531 int clk_id, unsigned int freq, 517 int clk_id, unsigned int freq,
532 int dir) 518 int dir)
533{ 519{
534 struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); 520 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
521 struct omap_mcbsp_data *mcbsp_data = &mcbsp->mcbsp_data;
535 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 522 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
536 int err = 0; 523 int err = 0;
537 524
@@ -547,7 +534,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
547 clk_id == OMAP_MCBSP_CLKR_SRC_CLKX || 534 clk_id == OMAP_MCBSP_CLKR_SRC_CLKX ||
548 clk_id == OMAP_MCBSP_FSR_SRC_FSR || 535 clk_id == OMAP_MCBSP_FSR_SRC_FSR ||
549 clk_id == OMAP_MCBSP_FSR_SRC_FSX) 536 clk_id == OMAP_MCBSP_FSR_SRC_FSX)
550 if (cpu_class_is_omap1() || mcbsp_data->bus_id != 0) 537 if (cpu_class_is_omap1() || cpu_dai->id != 1)
551 return -EINVAL; 538 return -EINVAL;
552 539
553 mcbsp_data->in_freq = freq; 540 mcbsp_data->in_freq = freq;
@@ -563,7 +550,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
563 err = -EINVAL; 550 err = -EINVAL;
564 break; 551 break;
565 } 552 }
566 err = omap2_mcbsp_set_clks_src(mcbsp_data->bus_id, 553 err = omap2_mcbsp_set_clks_src(mcbsp,
567 MCBSP_CLKS_PRCM_SRC); 554 MCBSP_CLKS_PRCM_SRC);
568 break; 555 break;
569 case OMAP_MCBSP_SYSCLK_CLKS_EXT: 556 case OMAP_MCBSP_SYSCLK_CLKS_EXT:
@@ -571,7 +558,7 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
571 err = 0; 558 err = 0;
572 break; 559 break;
573 } 560 }
574 err = omap2_mcbsp_set_clks_src(mcbsp_data->bus_id, 561 err = omap2_mcbsp_set_clks_src(mcbsp,
575 MCBSP_CLKS_PAD_SRC); 562 MCBSP_CLKS_PAD_SRC);
576 break; 563 break;
577 564
@@ -585,22 +572,22 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
585 case OMAP_MCBSP_CLKR_SRC_CLKR: 572 case OMAP_MCBSP_CLKR_SRC_CLKR:
586 if (cpu_class_is_omap1()) 573 if (cpu_class_is_omap1())
587 break; 574 break;
588 omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKR); 575 omap2_mcbsp1_mux_clkr_src(mcbsp, CLKR_SRC_CLKR);
589 break; 576 break;
590 case OMAP_MCBSP_CLKR_SRC_CLKX: 577 case OMAP_MCBSP_CLKR_SRC_CLKX:
591 if (cpu_class_is_omap1()) 578 if (cpu_class_is_omap1())
592 break; 579 break;
593 omap2_mcbsp1_mux_clkr_src(CLKR_SRC_CLKX); 580 omap2_mcbsp1_mux_clkr_src(mcbsp, CLKR_SRC_CLKX);
594 break; 581 break;
595 case OMAP_MCBSP_FSR_SRC_FSR: 582 case OMAP_MCBSP_FSR_SRC_FSR:
596 if (cpu_class_is_omap1()) 583 if (cpu_class_is_omap1())
597 break; 584 break;
598 omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSR); 585 omap2_mcbsp1_mux_fsr_src(mcbsp, FSR_SRC_FSR);
599 break; 586 break;
600 case OMAP_MCBSP_FSR_SRC_FSX: 587 case OMAP_MCBSP_FSR_SRC_FSX:
601 if (cpu_class_is_omap1()) 588 if (cpu_class_is_omap1())
602 break; 589 break;
603 omap2_mcbsp1_mux_fsr_src(FSR_SRC_FSX); 590 omap2_mcbsp1_mux_fsr_src(mcbsp, FSR_SRC_FSX);
604 break; 591 break;
605 default: 592 default:
606 err = -ENODEV; 593 err = -ENODEV;
@@ -620,15 +607,7 @@ static const struct snd_soc_dai_ops mcbsp_dai_ops = {
620 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, 607 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk,
621}; 608};
622 609
623static int mcbsp_dai_probe(struct snd_soc_dai *dai)
624{
625 mcbsp_data[dai->id].bus_id = dai->id;
626 snd_soc_dai_set_drvdata(dai, &mcbsp_data[dai->id].bus_id);
627 return 0;
628}
629
630static struct snd_soc_dai_driver omap_mcbsp_dai = { 610static struct snd_soc_dai_driver omap_mcbsp_dai = {
631 .probe = mcbsp_dai_probe,
632 .playback = { 611 .playback = {
633 .channels_min = 1, 612 .channels_min = 1,
634 .channels_max = 16, 613 .channels_max = 16,
@@ -659,11 +638,13 @@ static int omap_mcbsp_st_info_volsw(struct snd_kcontrol *kcontrol,
659 return 0; 638 return 0;
660} 639}
661 640
662#define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(id, channel) \ 641#define OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(channel) \
663static int \ 642static int \
664omap_mcbsp##id##_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \ 643omap_mcbsp_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
665 struct snd_ctl_elem_value *uc) \ 644 struct snd_ctl_elem_value *uc) \
666{ \ 645{ \
646 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
647 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \
667 struct soc_mixer_control *mc = \ 648 struct soc_mixer_control *mc = \
668 (struct soc_mixer_control *)kc->private_value; \ 649 (struct soc_mixer_control *)kc->private_value; \
669 int max = mc->max; \ 650 int max = mc->max; \
@@ -674,46 +655,44 @@ omap_mcbsp##id##_set_st_ch##channel##_volume(struct snd_kcontrol *kc, \
674 return -EINVAL; \ 655 return -EINVAL; \
675 \ 656 \
676 /* OMAP McBSP implementation uses index values 0..4 */ \ 657 /* OMAP McBSP implementation uses index values 0..4 */ \
677 return omap_st_set_chgain((id)-1, channel, val); \ 658 return omap_st_set_chgain(mcbsp, channel, val); \
678} 659}
679 660
680#define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(id, channel) \ 661#define OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(channel) \
681static int \ 662static int \
682omap_mcbsp##id##_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \ 663omap_mcbsp_get_st_ch##channel##_volume(struct snd_kcontrol *kc, \
683 struct snd_ctl_elem_value *uc) \ 664 struct snd_ctl_elem_value *uc) \
684{ \ 665{ \
666 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kc); \
667 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); \
685 s16 chgain; \ 668 s16 chgain; \
686 \ 669 \
687 if (omap_st_get_chgain((id)-1, channel, &chgain)) \ 670 if (omap_st_get_chgain(mcbsp, channel, &chgain)) \
688 return -EAGAIN; \ 671 return -EAGAIN; \
689 \ 672 \
690 uc->value.integer.value[0] = chgain; \ 673 uc->value.integer.value[0] = chgain; \
691 return 0; \ 674 return 0; \
692} 675}
693 676
694OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(2, 0) 677OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(0)
695OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(2, 1) 678OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(1)
696OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(3, 0) 679OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(0)
697OMAP_MCBSP_ST_SET_CHANNEL_VOLUME(3, 1) 680OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(1)
698OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(2, 0)
699OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(2, 1)
700OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(3, 0)
701OMAP_MCBSP_ST_GET_CHANNEL_VOLUME(3, 1)
702 681
703static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol, 682static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
704 struct snd_ctl_elem_value *ucontrol) 683 struct snd_ctl_elem_value *ucontrol)
705{ 684{
706 struct soc_mixer_control *mc = 685 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
707 (struct soc_mixer_control *)kcontrol->private_value; 686 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
708 u8 value = ucontrol->value.integer.value[0]; 687 u8 value = ucontrol->value.integer.value[0];
709 688
710 if (value == omap_st_is_enabled(mc->reg)) 689 if (value == omap_st_is_enabled(mcbsp))
711 return 0; 690 return 0;
712 691
713 if (value) 692 if (value)
714 omap_st_enable(mc->reg); 693 omap_st_enable(mcbsp);
715 else 694 else
716 omap_st_disable(mc->reg); 695 omap_st_disable(mcbsp);
717 696
718 return 1; 697 return 1;
719} 698}
@@ -721,10 +700,10 @@ static int omap_mcbsp_st_put_mode(struct snd_kcontrol *kcontrol,
721static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol, 700static int omap_mcbsp_st_get_mode(struct snd_kcontrol *kcontrol,
722 struct snd_ctl_elem_value *ucontrol) 701 struct snd_ctl_elem_value *ucontrol)
723{ 702{
724 struct soc_mixer_control *mc = 703 struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
725 (struct soc_mixer_control *)kcontrol->private_value; 704 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
726 705
727 ucontrol->value.integer.value[0] = omap_st_is_enabled(mc->reg); 706 ucontrol->value.integer.value[0] = omap_st_is_enabled(mcbsp);
728 return 0; 707 return 0;
729} 708}
730 709
@@ -733,12 +712,12 @@ static const struct snd_kcontrol_new omap_mcbsp2_st_controls[] = {
733 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), 712 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
734 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume", 713 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 0 Volume",
735 -32768, 32767, 714 -32768, 32767,
736 omap_mcbsp2_get_st_ch0_volume, 715 omap_mcbsp_get_st_ch0_volume,
737 omap_mcbsp2_set_st_ch0_volume), 716 omap_mcbsp_set_st_ch0_volume),
738 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume", 717 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP2 Sidetone Channel 1 Volume",
739 -32768, 32767, 718 -32768, 32767,
740 omap_mcbsp2_get_st_ch1_volume, 719 omap_mcbsp_get_st_ch1_volume,
741 omap_mcbsp2_set_st_ch1_volume), 720 omap_mcbsp_set_st_ch1_volume),
742}; 721};
743 722
744static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = { 723static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
@@ -746,25 +725,30 @@ static const struct snd_kcontrol_new omap_mcbsp3_st_controls[] = {
746 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode), 725 omap_mcbsp_st_get_mode, omap_mcbsp_st_put_mode),
747 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume", 726 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 0 Volume",
748 -32768, 32767, 727 -32768, 32767,
749 omap_mcbsp3_get_st_ch0_volume, 728 omap_mcbsp_get_st_ch0_volume,
750 omap_mcbsp3_set_st_ch0_volume), 729 omap_mcbsp_set_st_ch0_volume),
751 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume", 730 OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP3 Sidetone Channel 1 Volume",
752 -32768, 32767, 731 -32768, 32767,
753 omap_mcbsp3_get_st_ch1_volume, 732 omap_mcbsp_get_st_ch1_volume,
754 omap_mcbsp3_set_st_ch1_volume), 733 omap_mcbsp_set_st_ch1_volume),
755}; 734};
756 735
757int omap_mcbsp_st_add_controls(struct snd_soc_dai *dai) 736int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
758{ 737{
759 if (!cpu_is_omap34xx()) 738 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
739 struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
740
741 if (!mcbsp->st_data)
760 return -ENODEV; 742 return -ENODEV;
761 743
762 switch (dai->id) { 744 switch (cpu_dai->id) {
763 case 1: /* McBSP 2 */ 745 case 2: /* McBSP 2 */
764 return snd_soc_add_dai_controls(dai, omap_mcbsp2_st_controls, 746 return snd_soc_add_dai_controls(cpu_dai,
747 omap_mcbsp2_st_controls,
765 ARRAY_SIZE(omap_mcbsp2_st_controls)); 748 ARRAY_SIZE(omap_mcbsp2_st_controls));
766 case 2: /* McBSP 3 */ 749 case 3: /* McBSP 3 */
767 return snd_soc_add_dai_controls(dai, omap_mcbsp3_st_controls, 750 return snd_soc_add_dai_controls(cpu_dai,
751 omap_mcbsp3_st_controls,
768 ARRAY_SIZE(omap_mcbsp3_st_controls)); 752 ARRAY_SIZE(omap_mcbsp3_st_controls));
769 default: 753 default:
770 break; 754 break;
@@ -776,18 +760,25 @@ EXPORT_SYMBOL_GPL(omap_mcbsp_st_add_controls);
776 760
777static __devinit int asoc_mcbsp_probe(struct platform_device *pdev) 761static __devinit int asoc_mcbsp_probe(struct platform_device *pdev)
778{ 762{
779 return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai); 763 int ret;
764
765 ret = omap_mcbsp_probe(pdev);
766 if (!ret)
767 return snd_soc_register_dai(&pdev->dev, &omap_mcbsp_dai);
768
769 return ret;
780} 770}
781 771
782static int __devexit asoc_mcbsp_remove(struct platform_device *pdev) 772static int __devexit asoc_mcbsp_remove(struct platform_device *pdev)
783{ 773{
774 omap_mcbsp_remove(pdev);
784 snd_soc_unregister_dai(&pdev->dev); 775 snd_soc_unregister_dai(&pdev->dev);
785 return 0; 776 return 0;
786} 777}
787 778
788static struct platform_driver asoc_mcbsp_driver = { 779static struct platform_driver asoc_mcbsp_driver = {
789 .driver = { 780 .driver = {
790 .name = "omap-mcbsp-dai", 781 .name = "omap-mcbsp",
791 .owner = THIS_MODULE, 782 .owner = THIS_MODULE,
792 }, 783 },
793 784