sparcspkr.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * Driver for PC-speaker like devices found on various Sparc systems.
  3. *
  4. * Copyright (c) 2002 Vojtech Pavlik
  5. * Copyright (c) 2002 David S. Miller (davem@redhat.com)
  6. */
  7. #include <linux/config.h>
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/init.h>
  11. #include <linux/input.h>
  12. #include <asm/io.h>
  13. #include <asm/ebus.h>
  14. #ifdef CONFIG_SPARC64
  15. #include <asm/isa.h>
  16. #endif
  17. MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
  18. MODULE_DESCRIPTION("PC Speaker beeper driver");
  19. MODULE_LICENSE("GPL");
  20. static unsigned long beep_iobase;
  21. static char *sparcspkr_isa_name = "Sparc ISA Speaker";
  22. static char *sparcspkr_ebus_name = "Sparc EBUS Speaker";
  23. static char *sparcspkr_phys = "sparc/input0";
  24. static struct input_dev sparcspkr_dev;
  25. DEFINE_SPINLOCK(beep_lock);
  26. static void __init init_sparcspkr_struct(void)
  27. {
  28. sparcspkr_dev.evbit[0] = BIT(EV_SND);
  29. sparcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
  30. sparcspkr_dev.phys = sparcspkr_phys;
  31. sparcspkr_dev.id.bustype = BUS_ISA;
  32. sparcspkr_dev.id.vendor = 0x001f;
  33. sparcspkr_dev.id.product = 0x0001;
  34. sparcspkr_dev.id.version = 0x0100;
  35. }
  36. static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
  37. {
  38. unsigned int count = 0;
  39. unsigned long flags;
  40. if (type != EV_SND)
  41. return -1;
  42. switch (code) {
  43. case SND_BELL: if (value) value = 1000;
  44. case SND_TONE: break;
  45. default: return -1;
  46. }
  47. if (value > 20 && value < 32767)
  48. count = 1193182 / value;
  49. spin_lock_irqsave(&beep_lock, flags);
  50. /* EBUS speaker only has on/off state, the frequency does not
  51. * appear to be programmable.
  52. */
  53. if (count) {
  54. if (beep_iobase & 0x2UL)
  55. outb(1, beep_iobase);
  56. else
  57. outl(1, beep_iobase);
  58. } else {
  59. if (beep_iobase & 0x2UL)
  60. outb(0, beep_iobase);
  61. else
  62. outl(0, beep_iobase);
  63. }
  64. spin_unlock_irqrestore(&beep_lock, flags);
  65. return 0;
  66. }
  67. static int __init init_ebus_beep(struct linux_ebus_device *edev)
  68. {
  69. beep_iobase = edev->resource[0].start;
  70. init_sparcspkr_struct();
  71. sparcspkr_dev.name = sparcspkr_ebus_name;
  72. sparcspkr_dev.event = ebus_spkr_event;
  73. input_register_device(&sparcspkr_dev);
  74. printk(KERN_INFO "input: %s\n", sparcspkr_ebus_name);
  75. return 0;
  76. }
  77. #ifdef CONFIG_SPARC64
  78. static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
  79. {
  80. unsigned int count = 0;
  81. unsigned long flags;
  82. if (type != EV_SND)
  83. return -1;
  84. switch (code) {
  85. case SND_BELL: if (value) value = 1000;
  86. case SND_TONE: break;
  87. default: return -1;
  88. }
  89. if (value > 20 && value < 32767)
  90. count = 1193182 / value;
  91. spin_lock_irqsave(&beep_lock, flags);
  92. if (count) {
  93. /* enable counter 2 */
  94. outb(inb(beep_iobase + 0x61) | 3, beep_iobase + 0x61);
  95. /* set command for counter 2, 2 byte write */
  96. outb(0xB6, beep_iobase + 0x43);
  97. /* select desired HZ */
  98. outb(count & 0xff, beep_iobase + 0x42);
  99. outb((count >> 8) & 0xff, beep_iobase + 0x42);
  100. } else {
  101. /* disable counter 2 */
  102. outb(inb_p(beep_iobase + 0x61) & 0xFC, beep_iobase + 0x61);
  103. }
  104. spin_unlock_irqrestore(&beep_lock, flags);
  105. return 0;
  106. }
  107. static int __init init_isa_beep(struct sparc_isa_device *isa_dev)
  108. {
  109. beep_iobase = isa_dev->resource.start;
  110. init_sparcspkr_struct();
  111. sparcspkr_dev.name = sparcspkr_isa_name;
  112. sparcspkr_dev.event = isa_spkr_event;
  113. sparcspkr_dev.id.bustype = BUS_ISA;
  114. input_register_device(&sparcspkr_dev);
  115. printk(KERN_INFO "input: %s\n", sparcspkr_isa_name);
  116. return 0;
  117. }
  118. #endif
  119. static int __init sparcspkr_init(void)
  120. {
  121. struct linux_ebus *ebus;
  122. struct linux_ebus_device *edev = NULL;
  123. #ifdef CONFIG_SPARC64
  124. struct sparc_isa_bridge *isa_br;
  125. struct sparc_isa_device *isa_dev;
  126. #endif
  127. for_each_ebus(ebus) {
  128. for_each_ebusdev(edev, ebus) {
  129. if (!strcmp(edev->prom_name, "beep"))
  130. return init_ebus_beep(edev);
  131. }
  132. }
  133. #ifdef CONFIG_SPARC64
  134. for_each_isa(isa_br) {
  135. for_each_isadev(isa_dev, isa_br) {
  136. /* A hack, the beep device's base lives in
  137. * the DMA isa node.
  138. */
  139. if (!strcmp(isa_dev->prom_name, "dma"))
  140. return init_isa_beep(isa_dev);
  141. }
  142. }
  143. #endif
  144. return -ENODEV;
  145. }
  146. static void __exit sparcspkr_exit(void)
  147. {
  148. input_unregister_device(&sparcspkr_dev);
  149. }
  150. module_init(sparcspkr_init);
  151. module_exit(sparcspkr_exit);