Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp7029093pxv; Fri, 30 Jul 2021 08:22:08 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzmOI2JpyJGDhcH5eo+tga83vdOoSCUBaE7qUWGjWexOjLtIqZdOXxB/udR/VnYabEuqjY0 X-Received: by 2002:a17:906:388b:: with SMTP id q11mr2990508ejd.113.1627658528464; Fri, 30 Jul 2021 08:22:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627658528; cv=none; d=google.com; s=arc-20160816; b=hqpYs82C4qrcSOoBSFM50j9gI+BEJ43NhO4WJRq0EmwjhvtN8kl5CVEyDkyUfD3lgp P2cpfucDjdhTKvxpC1Ok5cffi13P6MpV5kvjomepIiorvuSscVlzbBP98/w4C0j+t6P0 YQ5pCk7QxXV3X3MZIjjy05FldwdoHu/7xJBfH49fe4ZM61acba00C1EmeeXjadqjE37I O2NgsaDEn1iZ7vZxO0PA5MfJZJigciis3aXa2OpTK8uXArt3B+rIRbNC72bFI7Oq8Yyz EFUNXcOdF6sPCH44cXqHLsBFrCOBBPhKnylC9/DPIZ/CVxl+JX5BfBwEUjKNL39Lr8UV 9JVA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=jcwnYwwAbgxy9esPuv1XX+/Ga/4UwxSjPTcSU4qpyIg=; b=Q+rNu3qvXdfCbPaGJMS1IKNO6Y0JPoUEAZm8v37yFgwr8tF1Y1vIPwwrF/DPaU5Cle la0KNTEz1GKVz8b+5MTHwnEmiIVEl1mknJEiznTHEWWKjSAVFNQj/TzlQXmJ9dlsnqls TDk7xF9IMoERCa4jWZJ8VrheP3kI+Im/EOr2xH6LLodfjcgmQfnNTbYbpwLriRs7UpUK hN+kT0ODe1lMULzYZoUX0n5M0xpbi0+DUE2sW/HEHqDFVBtk7y1C9mXcslGaTlhPjG7z KkG3ygsLRicDkIABnVVCKUxV6jgZ0AUrZLCnlIvnHB8X6qib96z0hBBeGMAAgQVtkaRB ECxg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cirrus.com header.s=PODMain02222019 header.b="FWxl4IJ/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=cirrus.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id c88si1202659edd.240.2021.07.30.08.21.45; Fri, 30 Jul 2021 08:22:08 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@cirrus.com header.s=PODMain02222019 header.b="FWxl4IJ/"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=cirrus.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239840AbhG3PTz (ORCPT + 99 others); Fri, 30 Jul 2021 11:19:55 -0400 Received: from mx0a-001ae601.pphosted.com ([67.231.149.25]:8672 "EHLO mx0b-001ae601.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S239664AbhG3PTf (ORCPT ); Fri, 30 Jul 2021 11:19:35 -0400 Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.16.1.2/8.16.1.2) with SMTP id 16UELBKe004490; Fri, 30 Jul 2021 10:19:19 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=jcwnYwwAbgxy9esPuv1XX+/Ga/4UwxSjPTcSU4qpyIg=; b=FWxl4IJ/cu7Q9s5c1T24BoKYuUbtsfu55FfjOZaJBIrLDApqDuyUaXPYOZS6UN297pRZ 3z7gllcsJNf5JpFP3ESreV9u+Kf5ADd+0Nskv9NvSqIfSUQ4HE9Wd8Xe94Dea1fSGM4Y 7mxHjt+p6v+N95uiyv6oFjITnYCGfP9EErTUrXB9+zkWNvBbr5tgj87ywA8a2hiZ+i+B sbiy7SR9cGt8+YzgYA08HYuU8P4EA2dbZPULd6KneJDQ0ClcitTb5BbiceE1LfbeML3B Q53CHRdsXsQ8f/Rz8v9Hyea0QA3/sZc4/MMKi2tZeak5nyt7RkR/rEBT7lce+qPR6/Tx uw== Received: from ediex02.ad.cirrus.com ([87.246.76.36]) by mx0a-001ae601.pphosted.com with ESMTP id 3a41wd181m-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT); Fri, 30 Jul 2021 10:19:19 -0500 Received: from EDIEX01.ad.cirrus.com (198.61.84.80) by EDIEX02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.4; Fri, 30 Jul 2021 16:19:09 +0100 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by EDIEX01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.1.2242.4 via Frontend Transport; Fri, 30 Jul 2021 16:19:09 +0100 Received: from vitaly-Inspiron-5415.ad.cirrus.com (unknown [198.90.238.32]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 58D5F2BA; Fri, 30 Jul 2021 15:19:09 +0000 (UTC) From: Vitaly Rodionov To: Jaroslav Kysela , Takashi Iwai CC: , , , Lucas Tanure Subject: [PATCH v3 12/27] ALSA: hda/cs8409: Generalize volume controls Date: Fri, 30 Jul 2021 16:18:29 +0100 Message-ID: <20210730151844.7873-13-vitalyr@opensource.cirrus.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> References: <20210730151844.7873-1-vitalyr@opensource.cirrus.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-Proofpoint-GUID: EpLTeiBCemHUKEkfsr92aDtPr_-5rccP X-Proofpoint-ORIG-GUID: EpLTeiBCemHUKEkfsr92aDtPr_-5rccP X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 impostorscore=0 spamscore=0 clxscore=1015 mlxscore=0 mlxlogscore=999 lowpriorityscore=0 malwarescore=0 phishscore=0 bulkscore=0 suspectscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107300102 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lucas Tanure Use amp offsets as indexes for saved volumes. Remove dependencies on NID inside volume control functions. Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov --- Changes in v2: - No changes Changes in v3: - No changes sound/pci/hda/patch_cs8409-tables.c | 37 +++++++ sound/pci/hda/patch_cs8409.c | 165 +++++++++------------------- sound/pci/hda/patch_cs8409.h | 27 +++-- 3 files changed, 105 insertions(+), 124 deletions(-) diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c index 07d3ae28c105..b03ddef2a25f 100644 --- a/sound/pci/hda/patch_cs8409-tables.c +++ b/sound/pci/hda/patch_cs8409-tables.c @@ -10,6 +10,43 @@ #include "patch_cs8409.h" +/****************************************************************************** + * CS42L42 Specific Data + * + ******************************************************************************/ + +static const DECLARE_TLV_DB_SCALE(cs42l42_dac_db_scale, + CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1); + +static const DECLARE_TLV_DB_SCALE(cs42l42_adc_db_scale, + CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1); + +const struct snd_kcontrol_new cs42l42_dac_volume_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .index = 0, + .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .info = cs8409_cs42l42_volume_info, + .get = cs8409_cs42l42_volume_get, + .put = cs8409_cs42l42_volume_put, + .tlv = { .p = cs42l42_dac_db_scale }, + .private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_TRANSMITTER_A, 3, 0, + HDA_OUTPUT, CS42L42_VOL_DAC) | HDA_AMP_VAL_MIN_MUTE +}; + +const struct snd_kcontrol_new cs42l42_adc_volume_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .index = 0, + .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), + .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .info = cs8409_cs42l42_volume_info, + .get = cs8409_cs42l42_volume_get, + .put = cs8409_cs42l42_volume_put, + .tlv = { .p = cs42l42_adc_db_scale }, + .private_value = HDA_COMPOSE_AMP_VAL_OFS(CS8409_PIN_ASP1_RECEIVER_A, 1, 0, + HDA_INPUT, CS42L42_VOL_ADC) | HDA_AMP_VAL_MIN_MUTE +}; + /* Dell Inspiron platforms * with cs8409 bridge and cs42l42 codec */ diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index 0b13bcecd778..08205c19698c 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -208,162 +208,97 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u return 0; } -static int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) +int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo) { - u16 nid = get_amp_nid(kctrl); + unsigned int ofs = get_amp_offset(kctrl); u8 chs = get_amp_channels(kctrl); - switch (nid) { - case CS8409_CS42L42_HP_PIN_NID: - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = chs == 3 ? 2 : 1; + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->value.integer.step = 1; + uinfo->count = chs == 3 ? 2 : 1; + + switch (ofs) { + case CS42L42_VOL_DAC: uinfo->value.integer.min = CS8409_CS42L42_HP_VOL_REAL_MIN; uinfo->value.integer.max = CS8409_CS42L42_HP_VOL_REAL_MAX; break; - case CS8409_CS42L42_AMIC_PIN_NID: - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = chs == 3 ? 2 : 1; + case CS42L42_VOL_ADC: uinfo->value.integer.min = CS8409_CS42L42_AMIC_VOL_REAL_MIN; uinfo->value.integer.max = CS8409_CS42L42_AMIC_VOL_REAL_MAX; break; default: break; } - return 0; -} -static void cs8409_cs42l42_update_volume(struct hda_codec *codec) -{ - struct cs8409_spec *spec = codec->spec; - int data; - - mutex_lock(&spec->cs8409_i2c_mux); - data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHA, 1); - if (data >= 0) - spec->cs42l42_hp_volume[0] = -data; - else - spec->cs42l42_hp_volume[0] = CS8409_CS42L42_HP_VOL_REAL_MIN; - data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHB, 1); - if (data >= 0) - spec->cs42l42_hp_volume[1] = -data; - else - spec->cs42l42_hp_volume[1] = CS8409_CS42L42_HP_VOL_REAL_MIN; - data = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOLUME, 1); - if (data >= 0) - spec->cs42l42_hs_mic_volume[0] = -data; - else - spec->cs42l42_hs_mic_volume[0] = CS8409_CS42L42_AMIC_VOL_REAL_MIN; - mutex_unlock(&spec->cs8409_i2c_mux); - spec->cs42l42_volume_init = 1; + return 0; } -static int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) +int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) { struct hda_codec *codec = snd_kcontrol_chip(kctrl); struct cs8409_spec *spec = codec->spec; - hda_nid_t nid = get_amp_nid(kctrl); int chs = get_amp_channels(kctrl); + unsigned int ofs = get_amp_offset(kctrl); long *valp = uctrl->value.integer.value; - if (!spec->cs42l42_volume_init) { - snd_hda_power_up(codec); - cs8409_cs42l42_update_volume(codec); - snd_hda_power_down(codec); - } - switch (nid) { - case CS8409_CS42L42_HP_PIN_NID: + switch (ofs) { + case CS42L42_VOL_DAC: if (chs & BIT(0)) - *valp++ = spec->cs42l42_hp_volume[0]; + *valp++ = spec->vol[ofs]; if (chs & BIT(1)) - *valp++ = spec->cs42l42_hp_volume[1]; + *valp = spec->vol[ofs+1]; break; - case CS8409_CS42L42_AMIC_PIN_NID: + case CS42L42_VOL_ADC: if (chs & BIT(0)) - *valp++ = spec->cs42l42_hs_mic_volume[0]; + *valp = spec->vol[ofs]; break; default: break; } + return 0; } -static int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) +int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl) { struct hda_codec *codec = snd_kcontrol_chip(kctrl); struct cs8409_spec *spec = codec->spec; - hda_nid_t nid = get_amp_nid(kctrl); int chs = get_amp_channels(kctrl); + unsigned int ofs = get_amp_offset(kctrl); long *valp = uctrl->value.integer.value; - int change = 0; - char vol; - snd_hda_power_up(codec); - switch (nid) { - case CS8409_CS42L42_HP_PIN_NID: + switch (ofs) { + case CS42L42_VOL_DAC: mutex_lock(&spec->cs8409_i2c_mux); if (chs & BIT(0)) { - vol = -(*valp); - change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_HS_VOLUME_CHA, vol, 1); - valp++; + spec->vol[ofs] = *valp; + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA, + -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); } if (chs & BIT(1)) { - vol = -(*valp); - change |= cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_HS_VOLUME_CHB, vol, 1); + ofs++; + valp++; + spec->vol[ofs] = *valp; + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, + -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); } mutex_unlock(&spec->cs8409_i2c_mux); break; - case CS8409_CS42L42_AMIC_PIN_NID: + case CS42L42_VOL_ADC: mutex_lock(&spec->cs8409_i2c_mux); if (chs & BIT(0)) { - change = cs8409_i2c_write(codec, CS42L42_I2C_ADDR, - CS8409_CS42L42_REG_AMIC_VOLUME, (char)*valp, 1); - valp++; + spec->vol[ofs] = *valp; + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, + spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1); } mutex_unlock(&spec->cs8409_i2c_mux); break; default: break; } - cs8409_cs42l42_update_volume(codec); - snd_hda_power_down(codec); - return change; -} - -static const DECLARE_TLV_DB_SCALE(cs8409_cs42l42_hp_db_scale, - CS8409_CS42L42_HP_VOL_REAL_MIN * 100, 100, 1); - -static const DECLARE_TLV_DB_SCALE(cs8409_cs42l42_amic_db_scale, - CS8409_CS42L42_AMIC_VOL_REAL_MIN * 100, 100, 1); - -static const struct snd_kcontrol_new cs8409_cs42l42_hp_volume_mixer = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .index = 0, - .name = "Headphone Playback Volume", - .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .info = cs8409_cs42l42_volume_info, - .get = cs8409_cs42l42_volume_get, - .put = cs8409_cs42l42_volume_put, - .tlv = { .p = cs8409_cs42l42_hp_db_scale }, - .private_value = HDA_COMPOSE_AMP_VAL(CS8409_CS42L42_HP_PIN_NID, 3, 0, HDA_OUTPUT) | - HDA_AMP_VAL_MIN_MUTE -}; -static const struct snd_kcontrol_new cs8409_cs42l42_amic_volume_mixer = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .index = 0, - .name = "Mic Capture Volume", - .subdevice = (HDA_SUBDEV_AMP_FLAG | HDA_SUBDEV_NID_FLAG), - .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .info = cs8409_cs42l42_volume_info, - .get = cs8409_cs42l42_volume_get, - .put = cs8409_cs42l42_volume_put, - .tlv = { .p = cs8409_cs42l42_amic_db_scale }, - .private_value = HDA_COMPOSE_AMP_VAL(CS8409_CS42L42_AMIC_PIN_NID, 1, 0, HDA_INPUT) | - HDA_AMP_VAL_MIN_MUTE -}; + return 0; +} /* Assert/release RTS# line to CS42L42 */ static void cs8409_cs42l42_reset(struct hda_codec *codec) @@ -657,18 +592,14 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) } /* Restore Volumes after Resume */ - if (spec->cs42l42_volume_init) { - mutex_lock(&spec->cs8409_i2c_mux); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHA, - -spec->cs42l42_hp_volume[0], 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOLUME_CHB, - -spec->cs42l42_hp_volume[1], 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOLUME, - spec->cs42l42_hs_mic_volume[0], 1); - mutex_unlock(&spec->cs8409_i2c_mux); - } - - cs8409_cs42l42_update_volume(codec); + mutex_lock(&spec->cs8409_i2c_mux); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHA, + -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, + -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, + spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1); + mutex_unlock(&spec->cs8409_i2c_mux); cs8409_cs42l42_enable_jack_detect(codec); @@ -811,8 +742,10 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, /* Set initial DMIC volume to -26 dB */ snd_hda_codec_amp_init_stereo(codec, CS8409_CS42L42_DMIC_ADC_PIN_NID, HDA_INPUT, 0, 0xff, 0x19); - snd_hda_gen_add_kctl(&spec->gen, NULL, &cs8409_cs42l42_hp_volume_mixer); - snd_hda_gen_add_kctl(&spec->gen, NULL, &cs8409_cs42l42_amic_volume_mixer); + snd_hda_gen_add_kctl(&spec->gen, "Headphone Playback Volume", + &cs42l42_dac_volume_mixer); + snd_hda_gen_add_kctl(&spec->gen, "Mic Capture Volume", + &cs42l42_adc_volume_mixer); /* Disable Unsolicited Response during boot */ cs8409_enable_ur(codec, 0); cs8409_cs42l42_hw_init(codec); diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index 0f2084b6ec8e..bf0e8a4cc4cc 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -215,16 +215,17 @@ enum cs8409_coefficient_index_registers { /* CS42L42 Specific Definitions */ -#define CS42L42_HP_CH (2U) -#define CS42L42_HS_MIC_CH (1U) +#define CS42L42_VOLUMES (4U) #define CS8409_CS42L42_HP_VOL_REAL_MIN (-63) #define CS8409_CS42L42_HP_VOL_REAL_MAX (0) #define CS8409_CS42L42_AMIC_VOL_REAL_MIN (-97) #define CS8409_CS42L42_AMIC_VOL_REAL_MAX (12) -#define CS8409_CS42L42_REG_HS_VOLUME_CHA (0x2301) -#define CS8409_CS42L42_REG_HS_VOLUME_CHB (0x2303) -#define CS8409_CS42L42_REG_AMIC_VOLUME (0x1D03) +#define CS8409_CS42L42_REG_HS_VOL_CHA (0x2301) +#define CS8409_CS42L42_REG_HS_VOL_CHB (0x2303) +#define CS8409_CS42L42_REG_HS_VOL_MASK (0x003F) +#define CS8409_CS42L42_REG_AMIC_VOL (0x1D03) +#define CS8409_CS42L42_REG_AMIC_VOL_MASK (0x00FF) #define CS42L42_HSDET_AUTO_DONE (0x02) #define CS42L42_HSTYPE_MASK (0x03) #define CS42L42_JACK_INSERTED (0x0C) @@ -248,6 +249,11 @@ enum { CS8409_FIXUPS, }; +enum { + CS42L42_VOL_ADC, + CS42L42_VOL_DAC, +}; + struct cs8409_i2c_param { unsigned int addr; unsigned int reg; @@ -268,10 +274,8 @@ struct cs8409_spec { unsigned int cs42l42_hp_jack_in:1; unsigned int cs42l42_mic_jack_in:1; - unsigned int cs42l42_volume_init:1; unsigned int cs42l42_suspended:1; - char cs42l42_hp_volume[CS42L42_HP_CH]; - char cs42l42_hs_mic_volume[CS42L42_HS_MIC_CH]; + s8 vol[CS42L42_VOLUMES]; struct mutex cs8409_i2c_mux; @@ -280,6 +284,13 @@ struct cs8409_spec { unsigned int *res); }; +extern const struct snd_kcontrol_new cs42l42_dac_volume_mixer; +extern const struct snd_kcontrol_new cs42l42_adc_volume_mixer; + +int cs8409_cs42l42_volume_info(struct snd_kcontrol *kctrl, struct snd_ctl_elem_info *uinfo); +int cs8409_cs42l42_volume_get(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl); +int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *uctrl); + extern const struct snd_pci_quirk cs8409_fixup_tbl[]; extern const struct hda_model_fixup cs8409_models[]; extern const struct hda_fixup cs8409_fixups[]; -- 2.25.1