vx222.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Driver for Digigram VX222 V2/Mic PCI soundcards
  4. *
  5. * Copyright (c) 2002 by Takashi Iwai <[email protected]>
  6. */
  7. #include <linux/init.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/pci.h>
  10. #include <linux/slab.h>
  11. #include <linux/module.h>
  12. #include <sound/core.h>
  13. #include <sound/initval.h>
  14. #include <sound/tlv.h>
  15. #include "vx222.h"
  16. #define CARD_NAME "VX222"
  17. MODULE_AUTHOR("Takashi Iwai <[email protected]>");
  18. MODULE_DESCRIPTION("Digigram VX222 V2/Mic");
  19. MODULE_LICENSE("GPL");
  20. static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
  21. static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
  22. static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
  23. static bool mic[SNDRV_CARDS]; /* microphone */
  24. static int ibl[SNDRV_CARDS]; /* microphone */
  25. module_param_array(index, int, NULL, 0444);
  26. MODULE_PARM_DESC(index, "Index value for Digigram " CARD_NAME " soundcard.");
  27. module_param_array(id, charp, NULL, 0444);
  28. MODULE_PARM_DESC(id, "ID string for Digigram " CARD_NAME " soundcard.");
  29. module_param_array(enable, bool, NULL, 0444);
  30. MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard.");
  31. module_param_array(mic, bool, NULL, 0444);
  32. MODULE_PARM_DESC(mic, "Enable Microphone.");
  33. module_param_array(ibl, int, NULL, 0444);
  34. MODULE_PARM_DESC(ibl, "Capture IBL size.");
  35. /*
  36. */
  37. enum {
  38. VX_PCI_VX222_OLD,
  39. VX_PCI_VX222_NEW
  40. };
  41. static const struct pci_device_id snd_vx222_ids[] = {
  42. { 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */
  43. { 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */
  44. { 0, }
  45. };
  46. MODULE_DEVICE_TABLE(pci, snd_vx222_ids);
  47. /*
  48. */
  49. static const DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0);
  50. static const DECLARE_TLV_DB_SCALE(db_scale_akm, -7350, 50, 0);
  51. static const struct snd_vx_hardware vx222_old_hw = {
  52. .name = "VX222/Old",
  53. .type = VX_TYPE_BOARD,
  54. /* hw specs */
  55. .num_codecs = 1,
  56. .num_ins = 1,
  57. .num_outs = 1,
  58. .output_level_max = VX_ANALOG_OUT_LEVEL_MAX,
  59. .output_level_db_scale = db_scale_old_vol,
  60. };
  61. static const struct snd_vx_hardware vx222_v2_hw = {
  62. .name = "VX222/v2",
  63. .type = VX_TYPE_V2,
  64. /* hw specs */
  65. .num_codecs = 1,
  66. .num_ins = 1,
  67. .num_outs = 1,
  68. .output_level_max = VX2_AKM_LEVEL_MAX,
  69. .output_level_db_scale = db_scale_akm,
  70. };
  71. static const struct snd_vx_hardware vx222_mic_hw = {
  72. .name = "VX222/Mic",
  73. .type = VX_TYPE_MIC,
  74. /* hw specs */
  75. .num_codecs = 1,
  76. .num_ins = 1,
  77. .num_outs = 1,
  78. .output_level_max = VX2_AKM_LEVEL_MAX,
  79. .output_level_db_scale = db_scale_akm,
  80. };
  81. /*
  82. */
  83. static int snd_vx222_create(struct snd_card *card, struct pci_dev *pci,
  84. const struct snd_vx_hardware *hw,
  85. struct snd_vx222 **rchip)
  86. {
  87. struct vx_core *chip;
  88. struct snd_vx222 *vx;
  89. int i, err;
  90. const struct snd_vx_ops *vx_ops;
  91. /* enable PCI device */
  92. err = pcim_enable_device(pci);
  93. if (err < 0)
  94. return err;
  95. pci_set_master(pci);
  96. vx_ops = hw->type == VX_TYPE_BOARD ? &vx222_old_ops : &vx222_ops;
  97. chip = snd_vx_create(card, hw, vx_ops,
  98. sizeof(struct snd_vx222) - sizeof(struct vx_core));
  99. if (!chip)
  100. return -ENOMEM;
  101. vx = to_vx222(chip);
  102. vx->pci = pci;
  103. err = pci_request_regions(pci, CARD_NAME);
  104. if (err < 0)
  105. return err;
  106. for (i = 0; i < 2; i++)
  107. vx->port[i] = pci_resource_start(pci, i + 1);
  108. if (devm_request_threaded_irq(&pci->dev, pci->irq, snd_vx_irq_handler,
  109. snd_vx_threaded_irq_handler, IRQF_SHARED,
  110. KBUILD_MODNAME, chip)) {
  111. dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
  112. return -EBUSY;
  113. }
  114. chip->irq = pci->irq;
  115. card->sync_irq = chip->irq;
  116. *rchip = vx;
  117. return 0;
  118. }
  119. static int snd_vx222_probe(struct pci_dev *pci,
  120. const struct pci_device_id *pci_id)
  121. {
  122. static int dev;
  123. struct snd_card *card;
  124. const struct snd_vx_hardware *hw;
  125. struct snd_vx222 *vx;
  126. int err;
  127. if (dev >= SNDRV_CARDS)
  128. return -ENODEV;
  129. if (!enable[dev]) {
  130. dev++;
  131. return -ENOENT;
  132. }
  133. err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
  134. 0, &card);
  135. if (err < 0)
  136. return err;
  137. switch ((int)pci_id->driver_data) {
  138. case VX_PCI_VX222_OLD:
  139. hw = &vx222_old_hw;
  140. break;
  141. case VX_PCI_VX222_NEW:
  142. default:
  143. if (mic[dev])
  144. hw = &vx222_mic_hw;
  145. else
  146. hw = &vx222_v2_hw;
  147. break;
  148. }
  149. err = snd_vx222_create(card, pci, hw, &vx);
  150. if (err < 0)
  151. return err;
  152. card->private_data = vx;
  153. vx->core.ibl.size = ibl[dev];
  154. sprintf(card->longname, "%s at 0x%lx & 0x%lx, irq %i",
  155. card->shortname, vx->port[0], vx->port[1], vx->core.irq);
  156. dev_dbg(card->dev, "%s at 0x%lx & 0x%lx, irq %i\n",
  157. card->shortname, vx->port[0], vx->port[1], vx->core.irq);
  158. #ifdef SND_VX_FW_LOADER
  159. vx->core.dev = &pci->dev;
  160. #endif
  161. err = snd_vx_setup_firmware(&vx->core);
  162. if (err < 0)
  163. return err;
  164. err = snd_card_register(card);
  165. if (err < 0)
  166. return err;
  167. pci_set_drvdata(pci, card);
  168. dev++;
  169. return 0;
  170. }
  171. #ifdef CONFIG_PM_SLEEP
  172. static int snd_vx222_suspend(struct device *dev)
  173. {
  174. struct snd_card *card = dev_get_drvdata(dev);
  175. struct snd_vx222 *vx = card->private_data;
  176. return snd_vx_suspend(&vx->core);
  177. }
  178. static int snd_vx222_resume(struct device *dev)
  179. {
  180. struct snd_card *card = dev_get_drvdata(dev);
  181. struct snd_vx222 *vx = card->private_data;
  182. return snd_vx_resume(&vx->core);
  183. }
  184. static SIMPLE_DEV_PM_OPS(snd_vx222_pm, snd_vx222_suspend, snd_vx222_resume);
  185. #define SND_VX222_PM_OPS &snd_vx222_pm
  186. #else
  187. #define SND_VX222_PM_OPS NULL
  188. #endif
  189. static struct pci_driver vx222_driver = {
  190. .name = KBUILD_MODNAME,
  191. .id_table = snd_vx222_ids,
  192. .probe = snd_vx222_probe,
  193. .driver = {
  194. .pm = SND_VX222_PM_OPS,
  195. },
  196. };
  197. module_pci_driver(vx222_driver);