diff options
-rw-r--r-- | sound/drivers/dummy.c | 37 |
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."); | |||
87 | module_param(fake_buffer, bool, 0444); | 87 | module_param(fake_buffer, bool, 0444); |
88 | MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations."); | 88 | MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations."); |
89 | #ifdef CONFIG_HIGH_RES_TIMERS | 89 | #ifdef CONFIG_HIGH_RES_TIMERS |
90 | module_param(hrtimer, bool, 0444); | 90 | module_param(hrtimer, bool, 0644); |
91 | MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source."); | 91 | MODULE_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 | |||
112 | struct dummy_model { | 115 | struct 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 | ||
233 | struct dummy_systimer_pcm { | 235 | struct 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 | ||
368 | struct dummy_hrtimer_pcm { | 372 | struct 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 | ||
493 | static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 499 | static 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 | ||
508 | static int dummy_pcm_prepare(struct snd_pcm_substream *substream) | 512 | static 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 | ||
515 | static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream) | 517 | static 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 | ||
522 | static struct snd_pcm_hardware dummy_pcm_hardware = { | 522 | static 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 | ||
603 | static int dummy_pcm_close(struct snd_pcm_substream *substream) | 605 | static 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 | ||