sb8.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Driver for SoundBlaster 1.0/2.0/Pro soundcards and compatible
  4. * Copyright (c) by Jaroslav Kysela <[email protected]>
  5. */
  6. #include <linux/init.h>
  7. #include <linux/err.h>
  8. #include <linux/isa.h>
  9. #include <linux/ioport.h>
  10. #include <linux/module.h>
  11. #include <sound/core.h>
  12. #include <sound/sb.h>
  13. #include <sound/opl3.h>
  14. #include <sound/initval.h>
  15. MODULE_AUTHOR("Jaroslav Kysela <[email protected]>");
  16. MODULE_DESCRIPTION("Sound Blaster 1.0/2.0/Pro");
  17. MODULE_LICENSE("GPL");
  18. static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
  19. static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
  20. static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
  21. static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
  22. static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* 5,7,9,10 */
  23. static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* 1,3 */
  24. module_param_array(index, int, NULL, 0444);
  25. MODULE_PARM_DESC(index, "Index value for Sound Blaster soundcard.");
  26. module_param_array(id, charp, NULL, 0444);
  27. MODULE_PARM_DESC(id, "ID string for Sound Blaster soundcard.");
  28. module_param_array(enable, bool, NULL, 0444);
  29. MODULE_PARM_DESC(enable, "Enable Sound Blaster soundcard.");
  30. module_param_hw_array(port, long, ioport, NULL, 0444);
  31. MODULE_PARM_DESC(port, "Port # for SB8 driver.");
  32. module_param_hw_array(irq, int, irq, NULL, 0444);
  33. MODULE_PARM_DESC(irq, "IRQ # for SB8 driver.");
  34. module_param_hw_array(dma8, int, dma, NULL, 0444);
  35. MODULE_PARM_DESC(dma8, "8-bit DMA # for SB8 driver.");
  36. struct snd_sb8 {
  37. struct resource *fm_res; /* used to block FM i/o region for legacy cards */
  38. struct snd_sb *chip;
  39. };
  40. static irqreturn_t snd_sb8_interrupt(int irq, void *dev_id)
  41. {
  42. struct snd_sb *chip = dev_id;
  43. if (chip->open & SB_OPEN_PCM) {
  44. return snd_sb8dsp_interrupt(chip);
  45. } else {
  46. return snd_sb8dsp_midi_interrupt(chip);
  47. }
  48. }
  49. static int snd_sb8_match(struct device *pdev, unsigned int dev)
  50. {
  51. if (!enable[dev])
  52. return 0;
  53. if (irq[dev] == SNDRV_AUTO_IRQ) {
  54. dev_err(pdev, "please specify irq\n");
  55. return 0;
  56. }
  57. if (dma8[dev] == SNDRV_AUTO_DMA) {
  58. dev_err(pdev, "please specify dma8\n");
  59. return 0;
  60. }
  61. return 1;
  62. }
  63. static int snd_sb8_probe(struct device *pdev, unsigned int dev)
  64. {
  65. struct snd_sb *chip;
  66. struct snd_card *card;
  67. struct snd_sb8 *acard;
  68. struct snd_opl3 *opl3;
  69. int err;
  70. err = snd_devm_card_new(pdev, index[dev], id[dev], THIS_MODULE,
  71. sizeof(struct snd_sb8), &card);
  72. if (err < 0)
  73. return err;
  74. acard = card->private_data;
  75. /*
  76. * Block the 0x388 port to avoid PnP conflicts.
  77. * No need to check this value after request_region,
  78. * as we never do anything with it.
  79. */
  80. acard->fm_res = devm_request_region(card->dev, 0x388, 4,
  81. "SoundBlaster FM");
  82. if (port[dev] != SNDRV_AUTO_PORT) {
  83. err = snd_sbdsp_create(card, port[dev], irq[dev],
  84. snd_sb8_interrupt, dma8[dev],
  85. -1, SB_HW_AUTO, &chip);
  86. if (err < 0)
  87. return err;
  88. } else {
  89. /* auto-probe legacy ports */
  90. static const unsigned long possible_ports[] = {
  91. 0x220, 0x240, 0x260,
  92. };
  93. int i;
  94. for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
  95. err = snd_sbdsp_create(card, possible_ports[i],
  96. irq[dev],
  97. snd_sb8_interrupt,
  98. dma8[dev],
  99. -1,
  100. SB_HW_AUTO,
  101. &chip);
  102. if (err >= 0) {
  103. port[dev] = possible_ports[i];
  104. break;
  105. }
  106. }
  107. if (i >= ARRAY_SIZE(possible_ports))
  108. return -EINVAL;
  109. }
  110. acard->chip = chip;
  111. if (chip->hardware >= SB_HW_16) {
  112. if (chip->hardware == SB_HW_ALS100)
  113. snd_printk(KERN_WARNING "ALS100 chip detected at 0x%lx, try snd-als100 module\n",
  114. port[dev]);
  115. else
  116. snd_printk(KERN_WARNING "SB 16 chip detected at 0x%lx, try snd-sb16 module\n",
  117. port[dev]);
  118. return -ENODEV;
  119. }
  120. err = snd_sb8dsp_pcm(chip, 0);
  121. if (err < 0)
  122. return err;
  123. err = snd_sbmixer_new(chip);
  124. if (err < 0)
  125. return err;
  126. if (chip->hardware == SB_HW_10 || chip->hardware == SB_HW_20) {
  127. err = snd_opl3_create(card, chip->port + 8, 0,
  128. OPL3_HW_AUTO, 1, &opl3);
  129. if (err < 0)
  130. snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx\n", chip->port + 8);
  131. } else {
  132. err = snd_opl3_create(card, chip->port, chip->port + 2,
  133. OPL3_HW_AUTO, 1, &opl3);
  134. if (err < 0) {
  135. snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx-0x%lx\n",
  136. chip->port, chip->port + 2);
  137. }
  138. }
  139. if (err >= 0) {
  140. err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
  141. if (err < 0)
  142. return err;
  143. }
  144. err = snd_sb8dsp_midi(chip, 0);
  145. if (err < 0)
  146. return err;
  147. strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8");
  148. strcpy(card->shortname, chip->name);
  149. sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
  150. chip->name,
  151. chip->port,
  152. irq[dev], dma8[dev]);
  153. err = snd_card_register(card);
  154. if (err < 0)
  155. return err;
  156. dev_set_drvdata(pdev, card);
  157. return 0;
  158. }
  159. #ifdef CONFIG_PM
  160. static int snd_sb8_suspend(struct device *dev, unsigned int n,
  161. pm_message_t state)
  162. {
  163. struct snd_card *card = dev_get_drvdata(dev);
  164. struct snd_sb8 *acard = card->private_data;
  165. struct snd_sb *chip = acard->chip;
  166. snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
  167. snd_sbmixer_suspend(chip);
  168. return 0;
  169. }
  170. static int snd_sb8_resume(struct device *dev, unsigned int n)
  171. {
  172. struct snd_card *card = dev_get_drvdata(dev);
  173. struct snd_sb8 *acard = card->private_data;
  174. struct snd_sb *chip = acard->chip;
  175. snd_sbdsp_reset(chip);
  176. snd_sbmixer_resume(chip);
  177. snd_power_change_state(card, SNDRV_CTL_POWER_D0);
  178. return 0;
  179. }
  180. #endif
  181. #define DEV_NAME "sb8"
  182. static struct isa_driver snd_sb8_driver = {
  183. .match = snd_sb8_match,
  184. .probe = snd_sb8_probe,
  185. #ifdef CONFIG_PM
  186. .suspend = snd_sb8_suspend,
  187. .resume = snd_sb8_resume,
  188. #endif
  189. .driver = {
  190. .name = DEV_NAME
  191. },
  192. };
  193. module_isa_driver(snd_sb8_driver, SNDRV_CARDS);