From patchwork Thu Aug 19 06:14:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: You-Sheng Yang X-Patchwork-Id: 1518455 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Gqvg56Wm3z9t18; Thu, 19 Aug 2021 16:16:49 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mGbM6-0001DC-PO; Thu, 19 Aug 2021 06:16:46 +0000 Received: from mail-pg1-f179.google.com ([209.85.215.179]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mGbKN-0008Qi-9q for kernel-team@lists.ubuntu.com; Thu, 19 Aug 2021 06:14:59 +0000 Received: by mail-pg1-f179.google.com with SMTP id o2so4882779pgr.9 for ; Wed, 18 Aug 2021 23:14:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xfQx4wwzxLVhlZB8eC98g325cL4y00ZvNUi7+4Q7KYg=; b=JKbsEFQZWRfYfMm1Rg0iZ+PDb4qM4bu1XUu1qrE5v6DbuCJBs34yz1Yi1MN2tYi9TV jm8us8/AZTk/2KVq94CR1M8t5gvlLOwmNzPJ/QeK/wzvXAhJeINM2Hq2gaa6C9kkA1l9 wywKnp5lqqJVz9S9EDvr4vIQBuU1ns6ZC9j9D14gVQM5qymj2Wkr4mlhBWyjwDThdJj+ U+kq8XaaFgGuw/MV4v2jdMGnasoIDF/tU0kXcz8wvMNk2K8HoPGPm6DpSJc1nloNOnAs 0bUqz6tvOV3LagVQmb5pPGt4hZzfPD8XCPNPxSI9isXRbNrpoCAMHUCbZ9kkNqkVcjj3 Ctog== X-Gm-Message-State: AOAM531N9Fw1xceX4gJMgS0CmNXJ7g6IMl9q4aQptO6MZWCscBMniRSt nca849EDQv1+AW0e+THFQ2A1d/Ej6fNgFg== X-Google-Smtp-Source: ABdhPJxVJIzPLlj2aXgTjUtjyOajmE81bYTKCMDYTYjDQeyXA+afsTuCrksOMTwnA/Ur1kUtzuvVIg== X-Received: by 2002:aa7:9254:0:b029:3c9:268e:ae68 with SMTP id 20-20020aa792540000b02903c9268eae68mr13113554pfp.58.1629353696651; Wed, 18 Aug 2021 23:14:56 -0700 (PDT) Received: from localhost (114-47-140-65.dynamic-ip.hinet.net. [114.47.140.65]) by smtp.gmail.com with ESMTPSA id e3sm1836651pfi.189.2021.08.18.23.14.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 18 Aug 2021 23:14:56 -0700 (PDT) From: You-Sheng Yang To: kernel-team@lists.ubuntu.com Subject: [PATCH 15/30][SRU][OEM-5.13][I][U] ALSA: hda/cs8409: Avoid re-setting the same page as the last access Date: Thu, 19 Aug 2021 14:14:11 +0800 Message-Id: <20210819061427.900601-16-vicamo.yang@canonical.com> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210819061427.900601-1-vicamo.yang@canonical.com> References: <20210819061427.900601-1-vicamo.yang@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.215.179; envelope-from=vicamo@gmail.com; helo=mail-pg1-f179.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Lucas Tanure BugLink: https://bugs.launchpad.net/bugs/1939541 Signed-off-by: Lucas Tanure Signed-off-by: Vitaly Rodionov Link: https://lore.kernel.org/r/20210811185654.6837-16-vitalyr@opensource.cirrus.com Signed-off-by: Takashi Iwai (cherry picked from commit 8de4e5a6680df739f2368628e738d08820320484) Signed-off-by: You-Sheng Yang --- sound/pci/hda/patch_cs8409.c | 124 +++++++++++++++++++---------------- sound/pci/hda/patch_cs8409.h | 2 + 2 files changed, 71 insertions(+), 55 deletions(-) diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c index e683349ebd50..bb3c6ef5eab6 100644 --- a/sound/pci/hda/patch_cs8409.c +++ b/sound/pci/hda/patch_cs8409.c @@ -170,18 +170,37 @@ static void cs8409_set_i2c_dev_addr(struct hda_codec *codec, unsigned int addr) } } +/** + * cs8409_i2c_set_page - CS8409 I2C set page register. + * @codec: the codec instance + * @i2c_reg: Page register + * + * Returns negative on error. + */ +static int cs8409_i2c_set_page(struct hda_codec *codec, unsigned int i2c_reg) +{ + struct cs8409_spec *spec = codec->spec; + + if (spec->paged && (spec->last_page != (i2c_reg >> 8))) { + cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); + if (cs8409_i2c_wait_complete(codec) < 0) + return -EIO; + spec->last_page = i2c_reg >> 8; + } + + return 0; +} + /** * cs8409_i2c_read - CS8409 I2C Read. * @codec: the codec instance * @i2c_address: I2C Address * @i2c_reg: Register to read - * @paged: Is a paged transaction * * CS8409 I2C Read. * Returns negative on error, otherwise returns read value in bits 0-7. */ -static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg, - unsigned int paged) +static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg) { struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; @@ -193,13 +212,10 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un cs8409_enable_i2c_clock(codec); cs8409_set_i2c_dev_addr(codec, i2c_address); - if (paged) { - cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); - if (cs8409_i2c_wait_complete(codec) < 0) { - codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); - return -EIO; - } + if (cs8409_i2c_set_page(codec, i2c_reg)) { + codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; } i2c_reg_data = (i2c_reg << 8) & 0x0ffff; @@ -222,13 +238,12 @@ static int cs8409_i2c_read(struct hda_codec *codec, unsigned int i2c_address, un * @i2c_address: I2C Address * @i2c_reg: Register to write to * @i2c_data: Data to write - * @paged: Is a paged transaction * * CS8409 I2C Write. * Returns negative on error, otherwise returns 0. */ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, unsigned int i2c_reg, - unsigned int i2c_data, unsigned int paged) + unsigned int i2c_data) { struct cs8409_spec *spec = codec->spec; unsigned int i2c_reg_data; @@ -239,13 +254,10 @@ static int cs8409_i2c_write(struct hda_codec *codec, unsigned int i2c_address, u cs8409_enable_i2c_clock(codec); cs8409_set_i2c_dev_addr(codec, i2c_address); - if (paged) { - cs8409_vendor_coef_set(codec, CS8409_I2C_QWRITE, i2c_reg >> 8); - if (cs8409_i2c_wait_complete(codec) < 0) { - codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", - __func__, i2c_address, i2c_reg); - return -EIO; - } + if (cs8409_i2c_set_page(codec, i2c_reg)) { + codec_err(codec, "%s() Paged Transaction Failed 0x%02x : 0x%04x\n", + __func__, i2c_address, i2c_reg); + return -EIO; } i2c_reg_data = ((i2c_reg << 8) & 0x0ff00) | (i2c_data & 0x0ff); @@ -325,14 +337,14 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va if (chs & BIT(0)) { 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); + -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK); } if (chs & BIT(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); + -(spec->vol[ofs]) & CS8409_CS42L42_REG_HS_VOL_MASK); } mutex_unlock(&spec->cs8409_i2c_mux); break; @@ -341,7 +353,7 @@ int cs8409_cs42l42_volume_put(struct snd_kcontrol *kctrl, struct snd_ctl_elem_va if (chs & BIT(0)) { 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); + spec->vol[ofs] & CS8409_CS42L42_REG_AMIC_VOL_MASK); } mutex_unlock(&spec->cs8409_i2c_mux); break; @@ -367,14 +379,15 @@ static void cs8409_cs42l42_reset(struct hda_codec *codec) usleep_range(10000, 15000); spec->cs42l42_suspended = 0; + spec->last_page = 0; mutex_lock(&spec->cs8409_i2c_mux); /* Clear interrupts, by reading interrupt status registers */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1309, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130A, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130F, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1309); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130A); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130F); mutex_unlock(&spec->cs8409_i2c_mux); @@ -391,20 +404,20 @@ static void cs8409_cs42l42_enable_jack_detect(struct hda_codec *codec) * Additionally set HSBIAS_SENSE_EN for some variants. */ if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_BULLSEYE) - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x0020); else - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b70, 0x00a0); /* Clear WAKE# */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C1, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C1); /* Wait ~2.5ms */ usleep_range(2500, 3000); /* Set mode WAKE# output follows the combination logic directly */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b71, 0x00C0); /* Clear interrupts status */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); /* Enable interrupt */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3); mutex_unlock(&spec->cs8409_i2c_mux); } @@ -417,20 +430,20 @@ static void cs8409_cs42l42_run_jack_detect(struct hda_codec *codec) mutex_lock(&spec->cs8409_i2c_mux); /* Clear interrupts */ - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xFF, 1); - cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); - - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFD, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80, 1); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1b77); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xFF); + cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); + + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1102, 0x87); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1f06, 0x86); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1b74, 0x07); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFD); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0x80); /* Wait ~110ms*/ usleep_range(110000, 200000); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77, 1); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x111f, 0x77); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1120, 0xc0); /* Wait ~10ms */ usleep_range(10000, 25000); @@ -446,7 +459,7 @@ static void cs8409_cs42l42_reg_setup(struct hda_codec *codec) mutex_lock(&spec->cs8409_i2c_mux); for (; seq->addr; seq++) - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, seq->addr, seq->reg, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, seq->addr, seq->reg); mutex_unlock(&spec->cs8409_i2c_mux); @@ -480,9 +493,9 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) mutex_lock(&spec->cs8409_i2c_mux); /* Read jack detect status registers */ - reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308, 1); - reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124, 1); - reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f, 1); + reg_cdc_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1308); + reg_hs_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x1124); + reg_ts_status = cs8409_i2c_read(codec, CS42L42_I2C_ADDR, 0x130f); mutex_unlock(&spec->cs8409_i2c_mux); @@ -495,7 +508,7 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) mutex_lock(&spec->cs8409_i2c_mux); /* Disable HSDET_AUTO_DONE */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x131b, 0xFF); mutex_unlock(&spec->cs8409_i2c_mux); type = ((reg_hs_status & CS42L42_HSTYPE_MASK) + 1); @@ -522,7 +535,7 @@ static void cs8409_jack_unsol_event(struct hda_codec *codec, unsigned int res) mutex_lock(&spec->cs8409_i2c_mux); /* Re-Enable Tip Sense Interrupt */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1320, 0xF3); mutex_unlock(&spec->cs8409_i2c_mux); } else { @@ -589,7 +602,7 @@ static int cs8409_suspend(struct hda_codec *codec) mutex_lock(&spec->cs8409_i2c_mux); /* Power down CS42L42 ASP/EQ/MIX/HP */ - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x1101, 0xfe); mutex_unlock(&spec->cs8409_i2c_mux); spec->cs42l42_suspended = 1; @@ -652,7 +665,7 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) if (codec->fixup_id == CS8409_WARLOCK || codec->fixup_id == CS8409_CYBORG) { /* FULL_SCALE_VOL = 0 for Warlock / Cyborg */ mutex_lock(&spec->cs8409_i2c_mux); - cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01, 1); + cs8409_i2c_write(codec, CS42L42_I2C_ADDR, 0x2001, 0x01); mutex_unlock(&spec->cs8409_i2c_mux); /* DMIC1_MO=00b, DMIC1/2_SR=1 */ cs8409_vendor_coef_set(codec, 0x09, 0x0003); @@ -661,11 +674,11 @@ static void cs8409_cs42l42_hw_init(struct hda_codec *codec) /* Restore Volumes after Resume */ 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); + -(spec->vol[1]) & CS8409_CS42L42_REG_HS_VOL_MASK); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_HS_VOL_CHB, - -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK, 1); + -(spec->vol[2]) & CS8409_CS42L42_REG_HS_VOL_MASK); cs8409_i2c_write(codec, CS42L42_I2C_ADDR, CS8409_CS42L42_REG_AMIC_VOL, - spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK, 1); + spec->vol[0] & CS8409_CS42L42_REG_AMIC_VOL_MASK); mutex_unlock(&spec->cs8409_i2c_mux); cs8409_cs42l42_enable_jack_detect(codec); @@ -771,6 +784,7 @@ void cs8409_cs42l42_fixups(struct hda_codec *codec, const struct hda_fixup *fix, spec->cs42l42_hp_jack_in = 0; spec->cs42l42_mic_jack_in = 0; spec->cs42l42_suspended = 1; + spec->paged = 1; /* Basic initial sequence for specific hw configuration */ snd_hda_sequence_write(codec, cs8409_cs42l42_init_verbs); diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h index c2c208218e34..ee66fd0c01dc 100644 --- a/sound/pci/hda/patch_cs8409.h +++ b/sound/pci/hda/patch_cs8409.h @@ -283,6 +283,8 @@ struct cs8409_spec { unsigned int i2c_clck_enabled; unsigned int dev_addr; struct delayed_work i2c_clk_work; + unsigned int paged; + unsigned int last_page; /* verb exec op override */ int (*exec_verb)(struct hdac_device *dev, unsigned int cmd, unsigned int flags,