summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/drivers/dummy.c37
1 files changed, 19 insertions, 18 deletions
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index bde33308f0d6..c0f8f613f1f1 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -87,7 +87,7 @@ MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
87module_param(fake_buffer, bool, 0444); 87module_param(fake_buffer, bool, 0444);
88MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations."); 88MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations.");
89#ifdef CONFIG_HIGH_RES_TIMERS 89#ifdef CONFIG_HIGH_RES_TIMERS
90module_param(hrtimer, bool, 0444); 90module_param(hrtimer, bool, 0644);
91MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source."); 91MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source.");
92#endif 92#endif
93 93
@@ -109,6 +109,9 @@ struct dummy_timer_ops {
109 snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *); 109 snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
110}; 110};
111 111
112#define get_dummy_ops(substream) \
113 (*(const struct dummy_timer_ops **)(substream)->runtime->private_data)
114
112struct dummy_model { 115struct dummy_model {
113 const char *name; 116 const char *name;
114 int (*playback_constraints)(struct snd_pcm_runtime *runtime); 117 int (*playback_constraints)(struct snd_pcm_runtime *runtime);
@@ -137,7 +140,6 @@ struct snd_dummy {
137 int iobox; 140 int iobox;
138 struct snd_kcontrol *cd_volume_ctl; 141 struct snd_kcontrol *cd_volume_ctl;
139 struct snd_kcontrol *cd_switch_ctl; 142 struct snd_kcontrol *cd_switch_ctl;
140 const struct dummy_timer_ops *timer_ops;
141}; 143};
142 144
143/* 145/*
@@ -231,6 +233,8 @@ static struct dummy_model *dummy_models[] = {
231 */ 233 */
232 234
233struct dummy_systimer_pcm { 235struct dummy_systimer_pcm {
236 /* ops must be the first item */
237 const struct dummy_timer_ops *timer_ops;
234 spinlock_t lock; 238 spinlock_t lock;
235 struct timer_list timer; 239 struct timer_list timer;
236 unsigned long base_time; 240 unsigned long base_time;
@@ -366,6 +370,8 @@ static const struct dummy_timer_ops dummy_systimer_ops = {
366 */ 370 */
367 371
368struct dummy_hrtimer_pcm { 372struct dummy_hrtimer_pcm {
373 /* ops must be the first item */
374 const struct dummy_timer_ops *timer_ops;
369 ktime_t base_time; 375 ktime_t base_time;
370 ktime_t period_time; 376 ktime_t period_time;
371 atomic_t running; 377 atomic_t running;
@@ -492,31 +498,25 @@ static const struct dummy_timer_ops dummy_hrtimer_ops = {
492 498
493static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 499static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
494{ 500{
495 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
496
497 switch (cmd) { 501 switch (cmd) {
498 case SNDRV_PCM_TRIGGER_START: 502 case SNDRV_PCM_TRIGGER_START:
499 case SNDRV_PCM_TRIGGER_RESUME: 503 case SNDRV_PCM_TRIGGER_RESUME:
500 return dummy->timer_ops->start(substream); 504 return get_dummy_ops(substream)->start(substream);
501 case SNDRV_PCM_TRIGGER_STOP: 505 case SNDRV_PCM_TRIGGER_STOP:
502 case SNDRV_PCM_TRIGGER_SUSPEND: 506 case SNDRV_PCM_TRIGGER_SUSPEND:
503 return dummy->timer_ops->stop(substream); 507 return get_dummy_ops(substream)->stop(substream);
504 } 508 }
505 return -EINVAL; 509 return -EINVAL;
506} 510}
507 511
508static int dummy_pcm_prepare(struct snd_pcm_substream *substream) 512static int dummy_pcm_prepare(struct snd_pcm_substream *substream)
509{ 513{
510 struct snd_dummy *dummy = snd_pcm_substream_chip(substream); 514 return get_dummy_ops(substream)->prepare(substream);
511
512 return dummy->timer_ops->prepare(substream);
513} 515}
514 516
515static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream) 517static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream)
516{ 518{
517 struct snd_dummy *dummy = snd_pcm_substream_chip(substream); 519 return get_dummy_ops(substream)->pointer(substream);
518
519 return dummy->timer_ops->pointer(substream);
520} 520}
521 521
522static struct snd_pcm_hardware dummy_pcm_hardware = { 522static struct snd_pcm_hardware dummy_pcm_hardware = {
@@ -562,17 +562,19 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
562 struct snd_dummy *dummy = snd_pcm_substream_chip(substream); 562 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
563 struct dummy_model *model = dummy->model; 563 struct dummy_model *model = dummy->model;
564 struct snd_pcm_runtime *runtime = substream->runtime; 564 struct snd_pcm_runtime *runtime = substream->runtime;
565 const struct dummy_timer_ops *ops;
565 int err; 566 int err;
566 567
567 dummy->timer_ops = &dummy_systimer_ops; 568 ops = &dummy_systimer_ops;
568#ifdef CONFIG_HIGH_RES_TIMERS 569#ifdef CONFIG_HIGH_RES_TIMERS
569 if (hrtimer) 570 if (hrtimer)
570 dummy->timer_ops = &dummy_hrtimer_ops; 571 ops = &dummy_hrtimer_ops;
571#endif 572#endif
572 573
573 err = dummy->timer_ops->create(substream); 574 err = ops->create(substream);
574 if (err < 0) 575 if (err < 0)
575 return err; 576 return err;
577 get_dummy_ops(substream) = ops;
576 578
577 runtime->hw = dummy->pcm_hw; 579 runtime->hw = dummy->pcm_hw;
578 if (substream->pcm->device & 1) { 580 if (substream->pcm->device & 1) {
@@ -594,7 +596,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
594 err = model->capture_constraints(substream->runtime); 596 err = model->capture_constraints(substream->runtime);
595 } 597 }
596 if (err < 0) { 598 if (err < 0) {
597 dummy->timer_ops->free(substream); 599 get_dummy_ops(substream)->free(substream);
598 return err; 600 return err;
599 } 601 }
600 return 0; 602 return 0;
@@ -602,8 +604,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
602 604
603static int dummy_pcm_close(struct snd_pcm_substream *substream) 605static int dummy_pcm_close(struct snd_pcm_substream *substream)
604{ 606{
605 struct snd_dummy *dummy = snd_pcm_substream_chip(substream); 607 get_dummy_ops(substream)->free(substream);
606 dummy->timer_ops->free(substream);
607 return 0; 608 return 0;
608} 609}
609 610