From nobody Sun Nov 24 17:08:08 2024 Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B5121AC426; Mon, 4 Nov 2024 09:32:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.47.23.249 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730712763; cv=none; b=Yo6eVodp8Aguzr4Psp81Orz/Waj096tWMaEm6EvHGvII1/BbZ9A/OaFYMoxaqkCLL2NB57If3RU3BX35SW1Z201VYLxMH5SHVl7sL5uWXLLVY2Ro+pwQHmppiyYt2MpFv0EVD14QOhHZuyjpcTlu6Gx2Z3qP8ZRvoVfxa2MXvUk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730712763; c=relaxed/simple; bh=YrPeAGM72B4im9n2LWIlfOccFPNaMDZoG7WOUqq5xCE=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=acipQlRruF9L/fYwuPvxafmgMQQizDECuMYs0sINNSdrgPU0EgUP3dhetKq4yDxGHR1xWqNVsJBjmXDD0bJcEew5vzTbvGir4eTs/dVsMMN76Z3OGtt0+DxRSa1HTLRSbXCmA/rW6lJm+V23wYQIU7PuDCzbrenthupbizy4K4E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com; spf=pass smtp.mailfrom=ti.com; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b=JrTHWThQ; arc=none smtp.client-ip=198.47.23.249 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ti.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="JrTHWThQ" Received: from lelv0265.itg.ti.com ([10.180.67.224]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 4A49WBV0040202; Mon, 4 Nov 2024 03:32:11 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1730712731; bh=1LqjV96+Ep/yVZK4X3DwCLmpiX7hOrSFNgBB40/oAe8=; h=From:To:CC:Subject:Date; b=JrTHWThQUYjglRd2x0AgsNwMezhHSjl32Rx66ZNVBRj5ljV2GPoHe1D3bd0jl3vQ8 Kmhisc+I4qaOFgkhBCX2klvKv3gNathTm8i/RzWEjPiE3k1P5ZwH/6Jzv9KjIBQrOA HUGBj9KLr2lAk6GELOAGcLnw4cxABr3F/APxOhH4= Received: from DFLE103.ent.ti.com (dfle103.ent.ti.com [10.64.6.24]) by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 4A49WBfm014005 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 4 Nov 2024 03:32:11 -0600 Received: from DFLE109.ent.ti.com (10.64.6.30) by DFLE103.ent.ti.com (10.64.6.24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23; Mon, 4 Nov 2024 03:32:10 -0600 Received: from lelvsmtp5.itg.ti.com (10.180.75.250) by DFLE109.ent.ti.com (10.64.6.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2507.23 via Frontend Transport; Mon, 4 Nov 2024 03:32:10 -0600 Received: from lelvsmtp5.itg.ti.com ([10.250.165.138]) by lelvsmtp5.itg.ti.com (8.15.2/8.15.2) with ESMTP id 4A49W2pe083213; Mon, 4 Nov 2024 03:32:03 -0600 From: Baojun Xu To: CC: , , , , , , , <13916275206@139.com>, , , , , , , , , , Subject: [PATCH v4] ALSA: hda/tas2781: Add speaker id check for ASUS projects Date: Mon, 4 Nov 2024 17:31:38 +0800 Message-ID: <20241104093138.4819-1-baojun.xu@ti.com> X-Mailer: git-send-email 2.43.0.windows.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-C2ProcessedOrg: 333ef613-75bf-4e12-a4b1-8e3623f5dcea Content-Type: text/plain; charset="utf-8" Add speaker id check by gpio in ACPI for ASUS projects. In other vendors, speaker id was checked by BIOS, and was applied in last bit of subsys id, so we can load corresponding firmware binary file for its speaker by subsys id. But in ASUS project, the firmware binary name will be appended an extra number to tell the speakers from different vendors. And this single digit come from gpio level of speaker id in BIOS. Signed-off-by: Baojun Xu --- v4: - Change strncasecmp() to strncmp(). - Add error debug message print for "add driver gpio". - Put error information (PTR_ERR) to ret for get gpio. - Change %01d to %d in snprintf(). v3: - Change strstr() to strncasecmp() for compare subsystem id. - Remove result check after devm_acpi_dev_add_driver_gpios(). - Remove spk_id > 1 check, as result of gpiod_get_value(), must be 0 or 1, or negative if error happend. - Change scnprintf() to snprintf(), as didn't care the length. - Remove changes which not relative current patch. v2: - Change ASUS id from 0x10430000 to "1043". - Move gpio setting to tas2781_read_acpi() from probe. - Remove interrupt gpio in acpi_gpio_mapping. - Add sub and physdev in tas2781_read_acpi() for subsys id read. - Add debug log for get acpi resource failed. - Return error if get resource or subsys id failed. - Return error if get gpio fail for speaker id with ASUS projects. - Change fixed buffer lengh to sizeof(). - Change bits calculator to lower_16_bits(). - Remove unnecessary empty line in tas2781_hda_i2c_probe(). --- include/sound/tas2781.h | 3 ++ sound/pci/hda/tas2781_hda_i2c.c | 64 +++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index 8cd6da0480b7..621ae485d3cb 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -107,6 +107,8 @@ #define TASDEVICE_CMD_DELAY 0x3 #define TASDEVICE_CMD_FIELD_W 0x4 =20 +#define TAS2781_ASUS_ID "1043" + enum audio_device { TAS2563, TAS2781, @@ -156,6 +158,7 @@ struct tasdevice_priv { struct tasdevice_rca rcabin; struct calidata cali_data; struct tasdevice_fw *fmw; + struct gpio_desc *speaker_id; struct gpio_desc *reset; struct mutex codec_lock; struct regmap *regmap; diff --git a/sound/pci/hda/tas2781_hda_i2c.c b/sound/pci/hda/tas2781_hda_i2= c.c index 370d847517f9..f9c10e30a8d8 100644 --- a/sound/pci/hda/tas2781_hda_i2c.c +++ b/sound/pci/hda/tas2781_hda_i2c.c @@ -110,10 +110,19 @@ static int tas2781_get_i2c_res(struct acpi_resource *= ares, void *data) return 1; } =20 +static const struct acpi_gpio_params speakerid_gpios =3D { 0, 0, false }; + +static const struct acpi_gpio_mapping tas2781_speaker_id_gpios[] =3D { + { "speakerid-gpios", &speakerid_gpios, 1 }, + { } +}; + static int tas2781_read_acpi(struct tasdevice_priv *p, const char *hid) { struct acpi_device *adev; + struct device *physdev; LIST_HEAD(resources); + const char *sub; int ret; =20 adev =3D acpi_dev_get_first_match_dev(hid, NULL, -1); @@ -123,18 +132,44 @@ static int tas2781_read_acpi(struct tasdevice_priv *p= , const char *hid) return -ENODEV; } =20 - ret =3D acpi_dev_get_resources(adev, &resources, tas2781_get_i2c_res, p); - if (ret < 0) - goto err; + physdev =3D get_device(acpi_get_first_physical_node(adev)); + ret =3D acpi_dev_get_resources(adev, &resources, tas2781_get_i2c_res, p); + if (ret < 0) { + dev_err(p->dev, "Failed to get ACPI resource.\n"); + goto err; + } + sub =3D acpi_get_subsystem_id(ACPI_HANDLE(physdev)); + if (IS_ERR(sub)) { + dev_err(p->dev, "Failed to get SUBSYS ID.\n"); + goto err; + } + // Speaker id was needed for ASUS projects. + if (!strncmp(sub, TAS2781_ASUS_ID, sizeof(TAS2781_ASUS_ID))) { + ret =3D devm_acpi_dev_add_driver_gpios(p->dev, + tas2781_speaker_id_gpios); + if (ret < 0) + dev_err(p->dev, "Failed to add driver gpio %d.\n", + ret); + p->speaker_id =3D devm_gpiod_get(p->dev, "speakerid", GPIOD_IN); + if (IS_ERR(p->speaker_id)) { + dev_err(p->dev, "Failed to get Speaker id.\n"); + ret =3D PTR_ERR(p->speaker_id); + goto err; + } + } else { + p->speaker_id =3D NULL; + } =20 acpi_dev_free_resource_list(&resources); strscpy(p->dev_name, hid, sizeof(p->dev_name)); + put_device(physdev); acpi_dev_put(adev); =20 return 0; =20 err: dev_err(p->dev, "read acpi error, ret: %d\n", ret); + put_device(physdev); acpi_dev_put(adev); =20 return ret; @@ -615,7 +650,7 @@ static void tasdev_fw_ready(const struct firmware *fmw,= void *context) struct tasdevice_priv *tas_priv =3D context; struct tas2781_hda *tas_hda =3D dev_get_drvdata(tas_priv->dev); struct hda_codec *codec =3D tas_priv->codec; - int i, ret; + int i, ret, spk_id; =20 pm_runtime_get_sync(tas_priv->dev); mutex_lock(&tas_priv->codec_lock); @@ -648,8 +683,25 @@ static void tasdev_fw_ready(const struct firmware *fmw= , void *context) tasdevice_dsp_remove(tas_priv); =20 tas_priv->fw_state =3D TASDEVICE_DSP_FW_PENDING; - scnprintf(tas_priv->coef_binaryname, 64, "TAS2XXX%04X.bin", - codec->core.subsystem_id & 0xffff); + if (tas_priv->speaker_id !=3D NULL) { + // Speaker id need to be checked for ASUS only. + spk_id =3D gpiod_get_value(tas_priv->speaker_id); + if (spk_id < 0) { + // Speaker id is not valid, use default. + dev_dbg(tas_priv->dev, "Wrong spk_id =3D %d\n", spk_id); + spk_id =3D 0; + } + snprintf(tas_priv->coef_binaryname, + sizeof(tas_priv->coef_binaryname), + "TAS2XXX%04X%d.bin", + lower_16_bits(codec->core.subsystem_id), + spk_id); + } else { + snprintf(tas_priv->coef_binaryname, + sizeof(tas_priv->coef_binaryname), + "TAS2XXX%04X.bin", + lower_16_bits(codec->core.subsystem_id)); + } ret =3D tasdevice_dsp_parser(tas_priv); if (ret) { dev_err(tas_priv->dev, "dspfw load %s error\n", --=20 2.43.0