aboutsummaryrefslogtreecommitdiffstats
path: root/sound/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'sound/drivers')
-rw-r--r--sound/drivers/dummy.c126
1 files changed, 47 insertions, 79 deletions
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 64ef7f62851d..8dfe5d49eafc 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -172,47 +172,33 @@ typedef struct snd_card_dummy_pcm {
172static snd_card_t *snd_dummy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; 172static snd_card_t *snd_dummy_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
173 173
174 174
175static void snd_card_dummy_pcm_timer_start(snd_pcm_substream_t * substream) 175static inline void snd_card_dummy_pcm_timer_start(snd_card_dummy_pcm_t *dpcm)
176{ 176{
177 snd_pcm_runtime_t *runtime = substream->runtime;
178 snd_card_dummy_pcm_t *dpcm = runtime->private_data;
179
180 dpcm->timer.expires = 1 + jiffies; 177 dpcm->timer.expires = 1 + jiffies;
181 add_timer(&dpcm->timer); 178 add_timer(&dpcm->timer);
182} 179}
183 180
184static void snd_card_dummy_pcm_timer_stop(snd_pcm_substream_t * substream) 181static inline void snd_card_dummy_pcm_timer_stop(snd_card_dummy_pcm_t *dpcm)
185{ 182{
186 snd_pcm_runtime_t *runtime = substream->runtime;
187 snd_card_dummy_pcm_t *dpcm = runtime->private_data;
188
189 del_timer(&dpcm->timer); 183 del_timer(&dpcm->timer);
190} 184}
191 185
192static int snd_card_dummy_playback_trigger(snd_pcm_substream_t * substream, 186static int snd_card_dummy_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
193 int cmd)
194{ 187{
195 if (cmd == SNDRV_PCM_TRIGGER_START) { 188 snd_pcm_runtime_t *runtime = substream->runtime;
196 snd_card_dummy_pcm_timer_start(substream); 189 snd_dummy_card_pcm_t *dpcm = runtime->private_data;
197 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { 190 int err = 0;
198 snd_card_dummy_pcm_timer_stop(substream);
199 } else {
200 return -EINVAL;
201 }
202 return 0;
203}
204 191
205static int snd_card_dummy_capture_trigger(snd_pcm_substream_t * substream, 192 spin_lock(&dpcm->lock);
206 int cmd)
207{
208 if (cmd == SNDRV_PCM_TRIGGER_START) { 193 if (cmd == SNDRV_PCM_TRIGGER_START) {
209 snd_card_dummy_pcm_timer_start(substream); 194 snd_card_dummy_pcm_timer_start(dpcm);
210 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { 195 } else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
211 snd_card_dummy_pcm_timer_stop(substream); 196 snd_card_dummy_pcm_timer_stop(dpcm);
212 } else { 197 } else {
213 return -EINVAL; 198 err = -EINVAL;
214 } 199 }
215 return 0; 200 spin_unlock(&dpcm->lock);
201 return err;
216} 202}
217 203
218static int snd_card_dummy_pcm_prepare(snd_pcm_substream_t * substream) 204static int snd_card_dummy_pcm_prepare(snd_pcm_substream_t * substream)
@@ -235,42 +221,26 @@ static int snd_card_dummy_pcm_prepare(snd_pcm_substream_t * substream)
235 return 0; 221 return 0;
236} 222}
237 223
238static int snd_card_dummy_playback_prepare(snd_pcm_substream_t * substream)
239{
240 return snd_card_dummy_pcm_prepare(substream);
241}
242
243static int snd_card_dummy_capture_prepare(snd_pcm_substream_t * substream)
244{
245 return snd_card_dummy_pcm_prepare(substream);
246}
247
248static void snd_card_dummy_pcm_timer_function(unsigned long data) 224static void snd_card_dummy_pcm_timer_function(unsigned long data)
249{ 225{
250 snd_card_dummy_pcm_t *dpcm = (snd_card_dummy_pcm_t *)data; 226 snd_card_dummy_pcm_t *dpcm = (snd_card_dummy_pcm_t *)data;
251 227
228 spin_lock(&dpcm->lock);
252 dpcm->timer.expires = 1 + jiffies; 229 dpcm->timer.expires = 1 + jiffies;
253 add_timer(&dpcm->timer); 230 add_timer(&dpcm->timer);
254 spin_lock_irq(&dpcm->lock);
255 dpcm->pcm_irq_pos += dpcm->pcm_jiffie; 231 dpcm->pcm_irq_pos += dpcm->pcm_jiffie;
256 dpcm->pcm_buf_pos += dpcm->pcm_jiffie; 232 dpcm->pcm_buf_pos += dpcm->pcm_jiffie;
257 dpcm->pcm_buf_pos %= dpcm->pcm_size; 233 dpcm->pcm_buf_pos %= dpcm->pcm_size;
258 if (dpcm->pcm_irq_pos >= dpcm->pcm_count) { 234 if (dpcm->pcm_irq_pos >= dpcm->pcm_count) {
259 dpcm->pcm_irq_pos %= dpcm->pcm_count; 235 dpcm->pcm_irq_pos %= dpcm->pcm_count;
236 spin_unlock(&dpcm->lock);
260 snd_pcm_period_elapsed(dpcm->substream); 237 snd_pcm_period_elapsed(dpcm->substream);
238 spin_lock(&dpcm->lock);
261 } 239 }
262 spin_unlock_irq(&dpcm->lock); 240 spin_unlock(&dpcm->lock);
263} 241}
264 242
265static snd_pcm_uframes_t snd_card_dummy_playback_pointer(snd_pcm_substream_t * substream) 243static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(snd_pcm_substream_t * substream)
266{
267 snd_pcm_runtime_t *runtime = substream->runtime;
268 snd_card_dummy_pcm_t *dpcm = runtime->private_data;
269
270 return bytes_to_frames(runtime, dpcm->pcm_buf_pos);
271}
272
273static snd_pcm_uframes_t snd_card_dummy_capture_pointer(snd_pcm_substream_t * substream)
274{ 244{
275 snd_pcm_runtime_t *runtime = substream->runtime; 245 snd_pcm_runtime_t *runtime = substream->runtime;
276 snd_card_dummy_pcm_t *dpcm = runtime->private_data; 246 snd_card_dummy_pcm_t *dpcm = runtime->private_data;
@@ -316,8 +286,7 @@ static snd_pcm_hardware_t snd_card_dummy_capture =
316 286
317static void snd_card_dummy_runtime_free(snd_pcm_runtime_t *runtime) 287static void snd_card_dummy_runtime_free(snd_pcm_runtime_t *runtime)
318{ 288{
319 snd_card_dummy_pcm_t *dpcm = runtime->private_data; 289 kfree(runtime->private_data);
320 kfree(dpcm);
321} 290}
322 291
323static int snd_card_dummy_hw_params(snd_pcm_substream_t * substream, 292static int snd_card_dummy_hw_params(snd_pcm_substream_t * substream,
@@ -331,20 +300,29 @@ static int snd_card_dummy_hw_free(snd_pcm_substream_t * substream)
331 return snd_pcm_lib_free_pages(substream); 300 return snd_pcm_lib_free_pages(substream);
332} 301}
333 302
334static int snd_card_dummy_playback_open(snd_pcm_substream_t * substream) 303static snd_card_dummy_pcm_t *new_pcm_stream(snd_pcm_substream_t *substream)
335{ 304{
336 snd_pcm_runtime_t *runtime = substream->runtime;
337 snd_card_dummy_pcm_t *dpcm; 305 snd_card_dummy_pcm_t *dpcm;
338 int err;
339 306
340 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); 307 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
341 if (dpcm == NULL) 308 if (! dpcm)
342 return -ENOMEM; 309 return dpcm;
343 init_timer(&dpcm->timer); 310 init_timer(&dpcm->timer);
344 dpcm->timer.data = (unsigned long) dpcm; 311 dpcm->timer.data = (unsigned long) dpcm;
345 dpcm->timer.function = snd_card_dummy_pcm_timer_function; 312 dpcm->timer.function = snd_card_dummy_pcm_timer_function;
346 spin_lock_init(&dpcm->lock); 313 spin_lock_init(&dpcm->lock);
347 dpcm->substream = substream; 314 dpcm->substream = substream;
315 return dpcm;
316}
317
318static int snd_card_dummy_playback_open(snd_pcm_substream_t * substream)
319{
320 snd_pcm_runtime_t *runtime = substream->runtime;
321 snd_card_dummy_pcm_t *dpcm;
322 int err;
323
324 if ((dpcm = new_pcm_stream(substream)) == NULL)
325 return -ENOMEM;
348 runtime->private_data = dpcm; 326 runtime->private_data = dpcm;
349 runtime->private_free = snd_card_dummy_runtime_free; 327 runtime->private_free = snd_card_dummy_runtime_free;
350 runtime->hw = snd_card_dummy_playback; 328 runtime->hw = snd_card_dummy_playback;
@@ -368,14 +346,8 @@ static int snd_card_dummy_capture_open(snd_pcm_substream_t * substream)
368 snd_card_dummy_pcm_t *dpcm; 346 snd_card_dummy_pcm_t *dpcm;
369 int err; 347 int err;
370 348
371 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); 349 if ((dpcm = new_pcm_stream(substream)) == NULL)
372 if (dpcm == NULL)
373 return -ENOMEM; 350 return -ENOMEM;
374 init_timer(&dpcm->timer);
375 dpcm->timer.data = (unsigned long) dpcm;
376 dpcm->timer.function = snd_card_dummy_pcm_timer_function;
377 spin_lock_init(&dpcm->lock);
378 dpcm->substream = substream;
379 runtime->private_data = dpcm; 351 runtime->private_data = dpcm;
380 runtime->private_free = snd_card_dummy_runtime_free; 352 runtime->private_free = snd_card_dummy_runtime_free;
381 runtime->hw = snd_card_dummy_capture; 353 runtime->hw = snd_card_dummy_capture;
@@ -409,9 +381,9 @@ static snd_pcm_ops_t snd_card_dummy_playback_ops = {
409 .ioctl = snd_pcm_lib_ioctl, 381 .ioctl = snd_pcm_lib_ioctl,
410 .hw_params = snd_card_dummy_hw_params, 382 .hw_params = snd_card_dummy_hw_params,
411 .hw_free = snd_card_dummy_hw_free, 383 .hw_free = snd_card_dummy_hw_free,
412 .prepare = snd_card_dummy_playback_prepare, 384 .prepare = snd_card_dummy_pcm_prepare,
413 .trigger = snd_card_dummy_playback_trigger, 385 .trigger = snd_card_dummy_pcm_trigger,
414 .pointer = snd_card_dummy_playback_pointer, 386 .pointer = snd_card_dummy_pcm_pointer,
415}; 387};
416 388
417static snd_pcm_ops_t snd_card_dummy_capture_ops = { 389static snd_pcm_ops_t snd_card_dummy_capture_ops = {
@@ -420,9 +392,9 @@ static snd_pcm_ops_t snd_card_dummy_capture_ops = {
420 .ioctl = snd_pcm_lib_ioctl, 392 .ioctl = snd_pcm_lib_ioctl,
421 .hw_params = snd_card_dummy_hw_params, 393 .hw_params = snd_card_dummy_hw_params,
422 .hw_free = snd_card_dummy_hw_free, 394 .hw_free = snd_card_dummy_hw_free,
423 .prepare = snd_card_dummy_capture_prepare, 395 .prepare = snd_card_dummy_pcm_prepare,
424 .trigger = snd_card_dummy_capture_trigger, 396 .trigger = snd_card_dummy_pcm_trigger,
425 .pointer = snd_card_dummy_capture_pointer, 397 .pointer = snd_card_dummy_pcm_pointer,
426}; 398};
427 399
428static int __init snd_card_dummy_pcm(snd_card_dummy_t *dummy, int device, int substreams) 400static int __init snd_card_dummy_pcm(snd_card_dummy_t *dummy, int device, int substreams)
@@ -461,20 +433,18 @@ static int snd_dummy_volume_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t
461static int snd_dummy_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 433static int snd_dummy_volume_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
462{ 434{
463 snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol); 435 snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
464 unsigned long flags;
465 int addr = kcontrol->private_value; 436 int addr = kcontrol->private_value;
466 437
467 spin_lock_irqsave(&dummy->mixer_lock, flags); 438 spin_lock_irq(&dummy->mixer_lock);
468 ucontrol->value.integer.value[0] = dummy->mixer_volume[addr][0]; 439 ucontrol->value.integer.value[0] = dummy->mixer_volume[addr][0];
469 ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1]; 440 ucontrol->value.integer.value[1] = dummy->mixer_volume[addr][1];
470 spin_unlock_irqrestore(&dummy->mixer_lock, flags); 441 spin_unlock_irq(&dummy->mixer_lock);
471 return 0; 442 return 0;
472} 443}
473 444
474static int snd_dummy_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 445static int snd_dummy_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
475{ 446{
476 snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol); 447 snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
477 unsigned long flags;
478 int change, addr = kcontrol->private_value; 448 int change, addr = kcontrol->private_value;
479 int left, right; 449 int left, right;
480 450
@@ -488,12 +458,12 @@ static int snd_dummy_volume_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t
488 right = -50; 458 right = -50;
489 if (right > 100) 459 if (right > 100)
490 right = 100; 460 right = 100;
491 spin_lock_irqsave(&dummy->mixer_lock, flags); 461 spin_lock_irq(&dummy->mixer_lock);
492 change = dummy->mixer_volume[addr][0] != left || 462 change = dummy->mixer_volume[addr][0] != left ||
493 dummy->mixer_volume[addr][1] != right; 463 dummy->mixer_volume[addr][1] != right;
494 dummy->mixer_volume[addr][0] = left; 464 dummy->mixer_volume[addr][0] = left;
495 dummy->mixer_volume[addr][1] = right; 465 dummy->mixer_volume[addr][1] = right;
496 spin_unlock_irqrestore(&dummy->mixer_lock, flags); 466 spin_unlock_irq(&dummy->mixer_lock);
497 return change; 467 return change;
498} 468}
499 469
@@ -515,31 +485,29 @@ static int snd_dummy_capsrc_info(snd_kcontrol_t * kcontrol, snd_ctl_elem_info_t
515static int snd_dummy_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 485static int snd_dummy_capsrc_get(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
516{ 486{
517 snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol); 487 snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
518 unsigned long flags;
519 int addr = kcontrol->private_value; 488 int addr = kcontrol->private_value;
520 489
521 spin_lock_irqsave(&dummy->mixer_lock, flags); 490 spin_lock_irq(&dummy->mixer_lock);
522 ucontrol->value.integer.value[0] = dummy->capture_source[addr][0]; 491 ucontrol->value.integer.value[0] = dummy->capture_source[addr][0];
523 ucontrol->value.integer.value[1] = dummy->capture_source[addr][1]; 492 ucontrol->value.integer.value[1] = dummy->capture_source[addr][1];
524 spin_unlock_irqrestore(&dummy->mixer_lock, flags); 493 spin_unlock_irq(&dummy->mixer_lock);
525 return 0; 494 return 0;
526} 495}
527 496
528static int snd_dummy_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol) 497static int snd_dummy_capsrc_put(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
529{ 498{
530 snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol); 499 snd_card_dummy_t *dummy = snd_kcontrol_chip(kcontrol);
531 unsigned long flags;
532 int change, addr = kcontrol->private_value; 500 int change, addr = kcontrol->private_value;
533 int left, right; 501 int left, right;
534 502
535 left = ucontrol->value.integer.value[0] & 1; 503 left = ucontrol->value.integer.value[0] & 1;
536 right = ucontrol->value.integer.value[1] & 1; 504 right = ucontrol->value.integer.value[1] & 1;
537 spin_lock_irqsave(&dummy->mixer_lock, flags); 505 spin_lock_irq(&dummy->mixer_lock);
538 change = dummy->capture_source[addr][0] != left && 506 change = dummy->capture_source[addr][0] != left &&
539 dummy->capture_source[addr][1] != right; 507 dummy->capture_source[addr][1] != right;
540 dummy->capture_source[addr][0] = left; 508 dummy->capture_source[addr][0] = left;
541 dummy->capture_source[addr][1] = right; 509 dummy->capture_source[addr][1] = right;
542 spin_unlock_irqrestore(&dummy->mixer_lock, flags); 510 spin_unlock_irq(&dummy->mixer_lock);
543 return change; 511 return change;
544} 512}
545 513