vxp_mixer.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Driver for Digigram VXpocket soundcards
  4. *
  5. * VX-pocket mixer
  6. *
  7. * Copyright (c) 2002 by Takashi Iwai <tiwai@suse.de>
  8. */
  9. #include <sound/core.h>
  10. #include <sound/control.h>
  11. #include <sound/tlv.h>
  12. #include "vxpocket.h"
  13. #define MIC_LEVEL_MIN 0
  14. #define MIC_LEVEL_MAX 8
  15. /*
  16. * mic level control (for VXPocket)
  17. */
  18. static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
  19. {
  20. uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  21. uinfo->count = 1;
  22. uinfo->value.integer.min = 0;
  23. uinfo->value.integer.max = MIC_LEVEL_MAX;
  24. return 0;
  25. }
  26. static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  27. {
  28. struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
  29. struct snd_vxpocket *chip = to_vxpocket(_chip);
  30. ucontrol->value.integer.value[0] = chip->mic_level;
  31. return 0;
  32. }
  33. static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  34. {
  35. struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
  36. struct snd_vxpocket *chip = to_vxpocket(_chip);
  37. unsigned int val = ucontrol->value.integer.value[0];
  38. if (val > MIC_LEVEL_MAX)
  39. return -EINVAL;
  40. mutex_lock(&_chip->mixer_mutex);
  41. if (chip->mic_level != ucontrol->value.integer.value[0]) {
  42. vx_set_mic_level(_chip, ucontrol->value.integer.value[0]);
  43. chip->mic_level = ucontrol->value.integer.value[0];
  44. mutex_unlock(&_chip->mixer_mutex);
  45. return 1;
  46. }
  47. mutex_unlock(&_chip->mixer_mutex);
  48. return 0;
  49. }
  50. static const DECLARE_TLV_DB_SCALE(db_scale_mic, -21, 3, 0);
  51. static const struct snd_kcontrol_new vx_control_mic_level = {
  52. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  53. .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
  54. SNDRV_CTL_ELEM_ACCESS_TLV_READ),
  55. .name = "Mic Capture Volume",
  56. .info = vx_mic_level_info,
  57. .get = vx_mic_level_get,
  58. .put = vx_mic_level_put,
  59. .tlv = { .p = db_scale_mic },
  60. };
  61. /*
  62. * mic boost level control (for VXP440)
  63. */
  64. #define vx_mic_boost_info snd_ctl_boolean_mono_info
  65. static int vx_mic_boost_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  66. {
  67. struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
  68. struct snd_vxpocket *chip = to_vxpocket(_chip);
  69. ucontrol->value.integer.value[0] = chip->mic_level;
  70. return 0;
  71. }
  72. static int vx_mic_boost_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
  73. {
  74. struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
  75. struct snd_vxpocket *chip = to_vxpocket(_chip);
  76. int val = !!ucontrol->value.integer.value[0];
  77. mutex_lock(&_chip->mixer_mutex);
  78. if (chip->mic_level != val) {
  79. vx_set_mic_boost(_chip, val);
  80. chip->mic_level = val;
  81. mutex_unlock(&_chip->mixer_mutex);
  82. return 1;
  83. }
  84. mutex_unlock(&_chip->mixer_mutex);
  85. return 0;
  86. }
  87. static const struct snd_kcontrol_new vx_control_mic_boost = {
  88. .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
  89. .name = "Mic Boost",
  90. .info = vx_mic_boost_info,
  91. .get = vx_mic_boost_get,
  92. .put = vx_mic_boost_put,
  93. };
  94. int vxp_add_mic_controls(struct vx_core *_chip)
  95. {
  96. struct snd_vxpocket *chip = to_vxpocket(_chip);
  97. int err;
  98. /* mute input levels */
  99. chip->mic_level = 0;
  100. switch (_chip->type) {
  101. case VX_TYPE_VXPOCKET:
  102. vx_set_mic_level(_chip, 0);
  103. break;
  104. case VX_TYPE_VXP440:
  105. vx_set_mic_boost(_chip, 0);
  106. break;
  107. }
  108. /* mic level */
  109. switch (_chip->type) {
  110. case VX_TYPE_VXPOCKET:
  111. err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip));
  112. if (err < 0)
  113. return err;
  114. break;
  115. case VX_TYPE_VXP440:
  116. err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_boost, chip));
  117. if (err < 0)
  118. return err;
  119. break;
  120. }
  121. return 0;
  122. }