Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: codecs: va-macro: Rework version checking

Open-code some of the registers to make the checks anywhere near human-
readable. Error out if the version is unsupported or if the VA macro
isn't supposed to be present within this LPASS instance (since we can
check for that now).

Note that previously v2.0 and v2.1 assignments were swapped, but v2.1
does not even seem to exist (as opposed to v2.0.1) and there is no
difference in SW handling anyway.

[Prasad Kumpatla: fixed a spelling error and resolved a checkpatch
warning related to return value handling]

Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Jingyi Wang <jingyi.wang@oss.qualcomm.com>
Signed-off-by: Prasad Kumpatla <prasad.kumpatla@oss.qualcomm.com>
Link: https://patch.msgid.link/20251015-knp-audio-v2-v3-1-e0e3e4167d87@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Konrad Dybcio and committed by
Mark Brown
281c9737 6621b0f1

+62 -26
+62 -26
sound/soc/codecs/lpass-va-macro.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 // Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. 3 3 4 + #include <linux/bitfield.h> 4 5 #include <linux/clk.h> 5 6 #include <linux/clk-provider.h> 6 7 #include <linux/init.h> ··· 65 64 #define CDC_VA_TOP_CSR_I2S_CLK (0x00A8) 66 65 #define CDC_VA_TOP_CSR_I2S_RESET (0x00AC) 67 66 #define CDC_VA_TOP_CSR_CORE_ID_0 (0x00C0) 67 + #define CORE_ID_0_REV_MAJ GENMASK(7, 0) 68 68 #define CDC_VA_TOP_CSR_CORE_ID_1 (0x00C4) 69 + #define CORE_ID_1_HAS_WSAMACRO BIT(3) 70 + #define CORE_ID_1_HAS_RXMACRO BIT(2) 71 + #define CORE_ID_1_HAS_TXMACRO BIT(1) 72 + #define CORE_ID_1_HAS_VAMACRO BIT(0) 69 73 #define CDC_VA_TOP_CSR_CORE_ID_2 (0x00C8) 74 + #define CORE_ID_2_REV_MIN GENMASK(7, 4) 75 + #define CORE_ID_2_REV_STEP GENMASK(3, 0) 70 76 #define CDC_VA_TOP_CSR_CORE_ID_3 (0x00CC) 71 77 #define CDC_VA_TOP_CSR_SWR_MIC_CTL0 (0x00D0) 72 78 #define CDC_VA_TOP_CSR_SWR_MIC_CTL1 (0x00D4) ··· 1470 1462 return dmic_sample_rate; 1471 1463 } 1472 1464 1473 - static void va_macro_set_lpass_codec_version(struct va_macro *va) 1465 + static int va_macro_set_lpass_codec_version(struct va_macro *va) 1474 1466 { 1475 - int core_id_0 = 0, core_id_1 = 0, core_id_2 = 0; 1476 1467 int version = LPASS_CODEC_VERSION_UNKNOWN; 1468 + u32 maj, min, step; 1469 + u32 val; 1477 1470 1478 - regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_0, &core_id_0); 1479 - regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_1, &core_id_1); 1480 - regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_2, &core_id_2); 1471 + regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_0, &val); 1472 + maj = FIELD_GET(CORE_ID_0_REV_MAJ, val); 1481 1473 1482 - if ((core_id_0 == 0x01) && (core_id_1 == 0x0F)) 1474 + regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_1, &val); 1475 + if (!FIELD_GET(CORE_ID_1_HAS_VAMACRO, val)) { 1476 + dev_err(va->dev, "This is not a VA macro instance\n"); 1477 + return -ENODEV; 1478 + } 1479 + 1480 + regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_2, &val); 1481 + min = FIELD_GET(CORE_ID_2_REV_MIN, val); 1482 + step = FIELD_GET(CORE_ID_2_REV_STEP, val); 1483 + 1484 + if (maj == 1) { 1483 1485 version = LPASS_CODEC_VERSION_2_0; 1484 - if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && core_id_2 == 0x01) 1485 - version = LPASS_CODEC_VERSION_2_0; 1486 - if ((core_id_0 == 0x02) && (core_id_1 == 0x0E)) 1487 - version = LPASS_CODEC_VERSION_2_1; 1488 - if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x50 || core_id_2 == 0x51)) 1489 - version = LPASS_CODEC_VERSION_2_5; 1490 - if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x60 || core_id_2 == 0x61)) 1491 - version = LPASS_CODEC_VERSION_2_6; 1492 - if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x70 || core_id_2 == 0x71)) 1493 - version = LPASS_CODEC_VERSION_2_7; 1494 - if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x80 || core_id_2 == 0x81)) 1495 - version = LPASS_CODEC_VERSION_2_8; 1496 - if ((core_id_0 == 0x02) && (core_id_1 == 0x0F) && (core_id_2 == 0x90 || core_id_2 == 0x91)) 1497 - version = LPASS_CODEC_VERSION_2_9; 1486 + } else if (maj == 2) { 1487 + switch (min) { 1488 + case 0: 1489 + version = LPASS_CODEC_VERSION_2_0; 1490 + break; 1491 + case 5: 1492 + version = LPASS_CODEC_VERSION_2_5; 1493 + break; 1494 + case 6: 1495 + version = LPASS_CODEC_VERSION_2_6; 1496 + break; 1497 + case 7: 1498 + version = LPASS_CODEC_VERSION_2_7; 1499 + break; 1500 + case 8: 1501 + version = LPASS_CODEC_VERSION_2_8; 1502 + break; 1503 + case 9: 1504 + version = LPASS_CODEC_VERSION_2_9; 1505 + break; 1506 + default: 1507 + break; 1508 + } 1509 + } 1498 1510 1499 - if (version == LPASS_CODEC_VERSION_UNKNOWN) 1500 - dev_warn(va->dev, "Unknown Codec version, ID: %02x / %02x / %02x\n", 1501 - core_id_0, core_id_1, core_id_2); 1511 + if (version == LPASS_CODEC_VERSION_UNKNOWN) { 1512 + dev_err(va->dev, "VA Macro v%u.%u.%u is not supported\n", 1513 + maj, min, step); 1514 + return -EOPNOTSUPP; 1515 + } 1502 1516 1503 1517 lpass_macro_set_codec_version(version); 1504 1518 1505 1519 dev_dbg(va->dev, "LPASS Codec Version %s\n", lpass_macro_get_codec_version_string(version)); 1520 + 1521 + return 0; 1506 1522 } 1507 1523 1508 1524 static int va_macro_probe(struct platform_device *pdev) ··· 1626 1594 * old version of codecs do not have a reliable way to determine the 1627 1595 * version from registers, get them from soc specific data 1628 1596 */ 1629 - if (data->version) 1597 + if (data->version) { 1630 1598 lpass_macro_set_codec_version(data->version); 1631 - else /* read version from register */ 1632 - va_macro_set_lpass_codec_version(va); 1599 + } else { 1600 + /* read version from register */ 1601 + ret = va_macro_set_lpass_codec_version(va); 1602 + if (ret) 1603 + return ret; 1604 + } 1633 1605 1634 1606 if (va->has_swr_master) { 1635 1607 /* Set default CLK div to 1 */