aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorAnssi Hannula <anssi.hannula@iki.fi>2015-12-13 13:49:58 -0500
committerTakashi Iwai <tiwai@suse.de>2015-12-14 04:13:17 -0500
commit42e3121d90f42e57f6dbd6083dff2f57b3ec7daa (patch)
tree57c53b919f92c3a88a2f815dd630a5eb18c40eb3 /sound
parent9f9499ae8e6415cefc4fe0a96ad0e27864353c89 (diff)
ALSA: usb-audio: Add a more accurate volume quirk for AudioQuest DragonFly
AudioQuest DragonFly DAC reports a volume control range of 0..50 (0x0000..0x0032) which in USB Audio means a range of 0 .. 0.2dB, which is obviously incorrect and would cause software using the dB information in e.g. volume sliders to have a massive volume difference in 100..102% range. Commit 2d1cb7f658fb ("ALSA: usb-audio: add dB range mapping for some devices") added a dB range mapping for it with range 0..50 dB. However, the actual volume mapping seems to be neither linear volume nor linear dB scale, but instead quite close to the cubic mapping e.g. alsamixer uses, with a range of approx. -53...0 dB. Replace the previous quirk with a custom dB mapping based on some basic output measurements, using a 10-item range TLV (which will still fit in alsa-lib MAX_TLV_RANGE_SIZE). Tested on AudioQuest DragonFly HW v1.2. The quirk is only applied if the range is 0..50, so if this gets fixed/changed in later HW revisions it will no longer be applied. v2: incorporated Takashi Iwai's suggestion for the quirk application method Signed-off-by: Anssi Hannula <anssi.hannula@iki.fi> Cc: <stable@vger.kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/usb/mixer.c2
-rw-r--r--sound/usb/mixer_maps.c12
-rw-r--r--sound/usb/mixer_quirks.c37
-rw-r--r--sound/usb/mixer_quirks.h4
4 files changed, 43 insertions, 12 deletions
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index f494dced3c11..4f85757009b3 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1354,6 +1354,8 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
1354 } 1354 }
1355 } 1355 }
1356 1356
1357 snd_usb_mixer_fu_apply_quirk(state->mixer, cval, unitid, kctl);
1358
1357 range = (cval->max - cval->min) / cval->res; 1359 range = (cval->max - cval->min) / cval->res;
1358 /* 1360 /*
1359 * Are there devices with volume range more than 255? I use a bit more 1361 * Are there devices with volume range more than 255? I use a bit more
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c
index 6a803eff87f7..ddca6547399b 100644
--- a/sound/usb/mixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -348,13 +348,6 @@ static struct usbmix_name_map bose_companion5_map[] = {
348 { 0 } /* terminator */ 348 { 0 } /* terminator */
349}; 349};
350 350
351/* Dragonfly DAC 1.2, the dB conversion factor is 1 instead of 256 */
352static struct usbmix_dB_map dragonfly_1_2_dB = {0, 5000};
353static struct usbmix_name_map dragonfly_1_2_map[] = {
354 { 7, NULL, .dB = &dragonfly_1_2_dB },
355 { 0 } /* terminator */
356};
357
358/* 351/*
359 * Control map entries 352 * Control map entries
360 */ 353 */
@@ -470,11 +463,6 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
470 .id = USB_ID(0x05a7, 0x1020), 463 .id = USB_ID(0x05a7, 0x1020),
471 .map = bose_companion5_map, 464 .map = bose_companion5_map,
472 }, 465 },
473 {
474 /* Dragonfly DAC 1.2 */
475 .id = USB_ID(0x21b4, 0x0081),
476 .map = dragonfly_1_2_map,
477 },
478 { 0 } /* terminator */ 466 { 0 } /* terminator */
479}; 467};
480 468
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index fe91184ce832..0ce888dceed0 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -37,6 +37,7 @@
37#include <sound/control.h> 37#include <sound/control.h>
38#include <sound/hwdep.h> 38#include <sound/hwdep.h>
39#include <sound/info.h> 39#include <sound/info.h>
40#include <sound/tlv.h>
40 41
41#include "usbaudio.h" 42#include "usbaudio.h"
42#include "mixer.h" 43#include "mixer.h"
@@ -1825,3 +1826,39 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
1825 } 1826 }
1826} 1827}
1827 1828
1829static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
1830 struct snd_kcontrol *kctl)
1831{
1832 /* Approximation using 10 ranges based on output measurement on hw v1.2.
1833 * This seems close to the cubic mapping e.g. alsamixer uses. */
1834 static const DECLARE_TLV_DB_RANGE(scale,
1835 0, 1, TLV_DB_MINMAX_ITEM(-5300, -4970),
1836 2, 5, TLV_DB_MINMAX_ITEM(-4710, -4160),
1837 6, 7, TLV_DB_MINMAX_ITEM(-3884, -3710),
1838 8, 14, TLV_DB_MINMAX_ITEM(-3443, -2560),
1839 15, 16, TLV_DB_MINMAX_ITEM(-2475, -2324),
1840 17, 19, TLV_DB_MINMAX_ITEM(-2228, -2031),
1841 20, 26, TLV_DB_MINMAX_ITEM(-1910, -1393),
1842 27, 31, TLV_DB_MINMAX_ITEM(-1322, -1032),
1843 32, 40, TLV_DB_MINMAX_ITEM(-968, -490),
1844 41, 50, TLV_DB_MINMAX_ITEM(-441, 0),
1845 );
1846
1847 usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n");
1848 kctl->tlv.p = scale;
1849 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
1850 kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
1851}
1852
1853void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
1854 struct usb_mixer_elem_info *cval, int unitid,
1855 struct snd_kcontrol *kctl)
1856{
1857 switch (mixer->chip->usb_id) {
1858 case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
1859 if (unitid == 7 && cval->min == 0 && cval->max == 50)
1860 snd_dragonfly_quirk_db_scale(mixer, kctl);
1861 break;
1862 }
1863}
1864
diff --git a/sound/usb/mixer_quirks.h b/sound/usb/mixer_quirks.h
index bdbfab093816..177c329cd4dd 100644
--- a/sound/usb/mixer_quirks.h
+++ b/sound/usb/mixer_quirks.h
@@ -9,5 +9,9 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
9void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer, 9void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
10 int unitid); 10 int unitid);
11 11
12void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
13 struct usb_mixer_elem_info *cval, int unitid,
14 struct snd_kcontrol *kctl);
15
12#endif /* SND_USB_MIXER_QUIRKS_H */ 16#endif /* SND_USB_MIXER_QUIRKS_H */
13 17