timer.c 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (c) by Lee Revell <[email protected]>
  4. * Clemens Ladisch <[email protected]>
  5. * Routines for control of EMU10K1 chips
  6. *
  7. * BUGS:
  8. * --
  9. *
  10. * TODO:
  11. * --
  12. */
  13. #include <linux/time.h>
  14. #include <sound/core.h>
  15. #include <sound/emu10k1.h>
  16. static int snd_emu10k1_timer_start(struct snd_timer *timer)
  17. {
  18. struct snd_emu10k1 *emu;
  19. unsigned long flags;
  20. unsigned int delay;
  21. emu = snd_timer_chip(timer);
  22. delay = timer->sticks - 1;
  23. if (delay < 5 ) /* minimum time is 5 ticks */
  24. delay = 5;
  25. spin_lock_irqsave(&emu->reg_lock, flags);
  26. snd_emu10k1_intr_enable(emu, INTE_INTERVALTIMERENB);
  27. outw(delay & TIMER_RATE_MASK, emu->port + TIMER);
  28. spin_unlock_irqrestore(&emu->reg_lock, flags);
  29. return 0;
  30. }
  31. static int snd_emu10k1_timer_stop(struct snd_timer *timer)
  32. {
  33. struct snd_emu10k1 *emu;
  34. unsigned long flags;
  35. emu = snd_timer_chip(timer);
  36. spin_lock_irqsave(&emu->reg_lock, flags);
  37. snd_emu10k1_intr_disable(emu, INTE_INTERVALTIMERENB);
  38. spin_unlock_irqrestore(&emu->reg_lock, flags);
  39. return 0;
  40. }
  41. static int snd_emu10k1_timer_precise_resolution(struct snd_timer *timer,
  42. unsigned long *num, unsigned long *den)
  43. {
  44. *num = 1;
  45. *den = 48000;
  46. return 0;
  47. }
  48. static const struct snd_timer_hardware snd_emu10k1_timer_hw = {
  49. .flags = SNDRV_TIMER_HW_AUTO,
  50. .resolution = 20833, /* 1 sample @ 48KHZ = 20.833...us */
  51. .ticks = 1024,
  52. .start = snd_emu10k1_timer_start,
  53. .stop = snd_emu10k1_timer_stop,
  54. .precise_resolution = snd_emu10k1_timer_precise_resolution,
  55. };
  56. int snd_emu10k1_timer(struct snd_emu10k1 *emu, int device)
  57. {
  58. struct snd_timer *timer = NULL;
  59. struct snd_timer_id tid;
  60. int err;
  61. tid.dev_class = SNDRV_TIMER_CLASS_CARD;
  62. tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
  63. tid.card = emu->card->number;
  64. tid.device = device;
  65. tid.subdevice = 0;
  66. err = snd_timer_new(emu->card, "EMU10K1", &tid, &timer);
  67. if (err >= 0) {
  68. strcpy(timer->name, "EMU10K1 timer");
  69. timer->private_data = emu;
  70. timer->hw = snd_emu10k1_timer_hw;
  71. }
  72. emu->timer = timer;
  73. return err;
  74. }