|
@@ -37,6 +37,7 @@
|
|
|
#include <sound/control.h>
|
|
|
#include <sound/hwdep.h>
|
|
|
#include <sound/info.h>
|
|
|
+#include <sound/tlv.h>
|
|
|
|
|
|
#include "usbaudio.h"
|
|
|
#include "mixer.h"
|
|
@@ -1825,3 +1826,39 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
|
|
|
+ struct snd_kcontrol *kctl)
|
|
|
+{
|
|
|
+ /* Approximation using 10 ranges based on output measurement on hw v1.2.
|
|
|
+ * This seems close to the cubic mapping e.g. alsamixer uses. */
|
|
|
+ static const DECLARE_TLV_DB_RANGE(scale,
|
|
|
+ 0, 1, TLV_DB_MINMAX_ITEM(-5300, -4970),
|
|
|
+ 2, 5, TLV_DB_MINMAX_ITEM(-4710, -4160),
|
|
|
+ 6, 7, TLV_DB_MINMAX_ITEM(-3884, -3710),
|
|
|
+ 8, 14, TLV_DB_MINMAX_ITEM(-3443, -2560),
|
|
|
+ 15, 16, TLV_DB_MINMAX_ITEM(-2475, -2324),
|
|
|
+ 17, 19, TLV_DB_MINMAX_ITEM(-2228, -2031),
|
|
|
+ 20, 26, TLV_DB_MINMAX_ITEM(-1910, -1393),
|
|
|
+ 27, 31, TLV_DB_MINMAX_ITEM(-1322, -1032),
|
|
|
+ 32, 40, TLV_DB_MINMAX_ITEM(-968, -490),
|
|
|
+ 41, 50, TLV_DB_MINMAX_ITEM(-441, 0),
|
|
|
+ );
|
|
|
+
|
|
|
+ usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n");
|
|
|
+ kctl->tlv.p = scale;
|
|
|
+ kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
|
|
|
+ kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
|
|
|
+}
|
|
|
+
|
|
|
+void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
|
|
|
+ struct usb_mixer_elem_info *cval, int unitid,
|
|
|
+ struct snd_kcontrol *kctl)
|
|
|
+{
|
|
|
+ switch (mixer->chip->usb_id) {
|
|
|
+ case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
|
|
|
+ if (unitid == 7 && cval->min == 0 && cval->max == 50)
|
|
|
+ snd_dragonfly_quirk_db_scale(mixer, kctl);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|