Received: by 2002:ac0:aa62:0:0:0:0:0 with SMTP id w31-v6csp1947160ima; Thu, 25 Oct 2018 07:25:00 -0700 (PDT) X-Google-Smtp-Source: AJdET5fHqhevjFmYCD48ZBTFvMhBM8ew6KyJb5MuR/6yPbAI4VFKSaew0hm+ipbmILzaTPltTg7i X-Received: by 2002:a63:c112:: with SMTP id w18-v6mr1700884pgf.429.1540477500835; Thu, 25 Oct 2018 07:25:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1540477500; cv=none; d=google.com; s=arc-20160816; b=miWC+Mi0aONF9W9WsiVEPLcRWhH03Y1FaJ9Z01ScXhjKTY2//C/es3TDCcjcJijyG6 LKhRWvWxcmPSLTXyqZKmj9rjZZ6JXhBOqIMBta6ptgJdQFU46ULzl2p83GmadiX/rtEt 2A9rJaJlR89I0gZ5B4oCMYRxgfgxqd/Unt7r8HFC+bBA0InNF1bBsDXa1o2UQwj7/kzZ AppvsRbv/o6n5PhI+bNt9Ymi4xMAKhbIkPnWoEDoeb/nTWUy0XRg11vqZv+qt2SpNY+F IImOAEHiuq8QDx8AW3bGp3OsnUWPDb5ujy5TXJwvhqe7LU0Rk6LAtWGGt6qw3N/65nEA 3TTQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=17b8OUVmap2qVUsI6nQWVLQ/q84pLWKsyZZk0Rs+7+Y=; b=r+YtDefWcGe15wfAsnZktznFnhYcJnTefUi6ZuyBFRyUzNPPKpoR/JOwUdPkBQ9qRu P4IPyZ2ZOQph7UE204LYCXAjIdedCBHPm4n7iaUxHrvRRnGPh2BXEfV+FWzON8xo/LuI UvG2WxwfnqHkwCctOLRDZtO2Ao2GpDS3o5QXGcXhdvHcouWkgLBJS+CSbwrnoPxGCEoc 68uwgdKvKT8lUMtnft07VhoEQFVrCcf767lZDobBp+I0VXfZ00KOFHIZKoKrOsZva1e0 LJgwYqAOzHDic0FMpOKbgV9LU1MS/DxarQRvZOz52WrTL4ITLv3krzcYvpugzySqtRLq 2HHg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=SmUcruxd; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 65-v6si5724474pfl.220.2018.10.25.07.24.18; Thu, 25 Oct 2018 07:25:00 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=SmUcruxd; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731265AbeJYWxy (ORCPT + 99 others); Thu, 25 Oct 2018 18:53:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:36568 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730386AbeJYWxx (ORCPT ); Thu, 25 Oct 2018 18:53:53 -0400 Received: from sasha-vm.mshome.net (unknown [167.98.65.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 872DF2147A; Thu, 25 Oct 2018 14:20:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1540477254; bh=Byhz7nX39/f+AmWT+fqogC1cAKyNTyJW2rwSHlSsjO4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SmUcruxdwzuZM1prNcTMH1XWF8MO17Oeue1TuPtnsrXJkenPY7dPv2lP9xof2gAaG JdXxs/7ZVtfbgi9+WIywkCrmxJBmEdh8zMRWfw7kUzBCQBl7OJKmH7RUFQeNjWQdbZ fh0oQherOxBgqD5TKLxQLRiz0Z2FLAoIgRGFO/wY= From: Sasha Levin To: stable@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Anssi Hannula , Takashi Iwai , Sasha Levin Subject: [PATCH AUTOSEL 3.18 79/98] ALSA: usb-audio: Add a more accurate volume quirk for AudioQuest DragonFly Date: Thu, 25 Oct 2018 10:18:34 -0400 Message-Id: <20181025141853.214051-79-sashal@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181025141853.214051-1-sashal@kernel.org> References: <20181025141853.214051-1-sashal@kernel.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Anssi Hannula [ Upstream commit 42e3121d90f42e57f6dbd6083dff2f57b3ec7daa ] 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 Cc: Signed-off-by: Takashi Iwai Signed-off-by: Sasha Levin --- sound/usb/mixer.c | 2 ++ sound/usb/mixer_maps.c | 12 ------------ sound/usb/mixer_quirks.c | 37 +++++++++++++++++++++++++++++++++++++ sound/usb/mixer_quirks.h | 4 ++++ 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 8d90cc5faf88..44812e4a4890 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1347,6 +1347,8 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, } } + snd_usb_mixer_fu_apply_quirk(state->mixer, cval, unitid, kctl); + range = (cval->max - cval->min) / cval->res; /* * 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 2f075cd27344..f0f526ca86e5 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c @@ -343,13 +343,6 @@ static struct usbmix_name_map bose_companion5_map[] = { { 0 } /* terminator */ }; -/* Dragonfly DAC 1.2, the dB conversion factor is 1 instead of 256 */ -static struct usbmix_dB_map dragonfly_1_2_dB = {0, 5000}; -static struct usbmix_name_map dragonfly_1_2_map[] = { - { 7, NULL, .dB = &dragonfly_1_2_dB }, - { 0 } /* terminator */ -}; - /* * Dell usb dock with ALC4020 codec had a firmware problem where it got * screwed up when zero volume is passed; just skip it as a workaround @@ -478,11 +471,6 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { .id = USB_ID(0x05a7, 0x1020), .map = bose_companion5_map, }, - { - /* Dragonfly DAC 1.2 */ - .id = USB_ID(0x21b4, 0x0081), - .map = dragonfly_1_2_map, - }, { 0 } /* terminator */ }; diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 524366f9d32d..05df7a75a2ea 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -37,6 +37,7 @@ #include #include #include +#include #include "usbaudio.h" #include "mixer.h" @@ -1711,3 +1712,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; + } +} + 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, void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer, int unitid); +void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer, + struct usb_mixer_elem_info *cval, int unitid, + struct snd_kcontrol *kctl); + #endif /* SND_USB_MIXER_QUIRKS_H */ -- 2.17.1