ASoC: Intel: sst: Support LPE0F28 ACPI HID
authorHans de Goede <hdegoede@redhat.com>
Fri, 25 Oct 2024 09:02:21 +0000 (11:02 +0200)
committerMark Brown <broonie@kernel.org>
Fri, 25 Oct 2024 13:10:11 +0000 (14:10 +0100)
Some old Bay Trail tablets which shipped with Android as factory OS
have the SST/LPE audio engine described by an ACPI device with a
HID (Hardware-ID) of LPE0F28 instead of 80860F28.

Add support for this. Note this uses a new sst_res_info for just
the LPE0F28 case because it has a different layout for the IO-mem ACPI
resources then the 80860F28.

An example of a tablet which needs this is the Vexia EDU ATLA 10 tablet,
which has been distributed to schools in the Spanish AndalucĂ­a region.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Link: https://patch.msgid.link/20241025090221.52198-1-hdegoede@redhat.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/hda/intel-dsp-config.c
sound/soc/intel/atom/sst/sst_acpi.c

index f018bd77986243f48182616875c6d742e91b8c39..9f849e05ce79f8fa073893fd6f5295dd8a57b284 100644 (file)
@@ -721,6 +721,10 @@ static const struct config_entry acpi_config_table[] = {
 #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \
     IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
 /* BayTrail */
+       {
+               .flags = FLAG_SST_OR_SOF_BYT,
+               .acpi_hid = "LPE0F28",
+       },
        {
                .flags = FLAG_SST_OR_SOF_BYT,
                .acpi_hid = "80860F28",
index 9956dc63db749918e93bb05d774efb261f3f433a..f4c4774249ee4b2efa5dd72f342f6554b5014064 100644 (file)
@@ -125,6 +125,28 @@ static const struct sst_res_info bytcr_res_info = {
        .acpi_ipc_irq_index = 0
 };
 
+/* For "LPE0F28" ACPI device found on some Android factory OS models */
+static const struct sst_res_info lpe8086_res_info = {
+       .shim_offset = 0x140000,
+       .shim_size = 0x000100,
+       .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR,
+       .ssp0_offset = 0xa0000,
+       .ssp0_size = 0x1000,
+       .dma0_offset = 0x98000,
+       .dma0_size = 0x4000,
+       .dma1_offset = 0x9c000,
+       .dma1_size = 0x4000,
+       .iram_offset = 0x0c0000,
+       .iram_size = 0x14000,
+       .dram_offset = 0x100000,
+       .dram_size = 0x28000,
+       .mbox_offset = 0x144000,
+       .mbox_size = 0x1000,
+       .acpi_lpe_res_index = 1,
+       .acpi_ddr_index = 0,
+       .acpi_ipc_irq_index = 0
+};
+
 static struct sst_platform_info byt_rvp_platform_data = {
        .probe_data = &byt_fwparse_info,
        .ipc_info = &byt_ipc_info,
@@ -268,10 +290,38 @@ static int sst_acpi_probe(struct platform_device *pdev)
                mach->pdata = &chv_platform_data;
        pdata = mach->pdata;
 
-       ret = kstrtouint(id->id, 16, &dev_id);
-       if (ret < 0) {
-               dev_err(dev, "Unique device id conversion error: %d\n", ret);
-               return ret;
+       if (!strcmp(id->id, "LPE0F28")) {
+               struct resource *rsrc;
+
+               /* Use regular BYT SST PCI VID:PID */
+               dev_id = 0x80860F28;
+               byt_rvp_platform_data.res_info = &lpe8086_res_info;
+
+               /*
+                * The "LPE0F28" ACPI device has separate IO-mem resources for:
+                * DDR, SHIM, MBOX, IRAM, DRAM, CFG
+                * None of which covers the entire LPE base address range.
+                * lpe8086_res_info.acpi_lpe_res_index points to the SHIM.
+                * Patch this to cover the entire base address range as expected
+                * by sst_platform_get_resources().
+                */
+               rsrc = platform_get_resource(pdev, IORESOURCE_MEM,
+                                            pdata->res_info->acpi_lpe_res_index);
+               if (!rsrc) {
+                       dev_err(ctx->dev, "Invalid SHIM base\n");
+                       return -EIO;
+               }
+               rsrc->start -= pdata->res_info->shim_offset;
+               rsrc->end = rsrc->start + 0x200000 - 1;
+       } else {
+               ret = kstrtouint(id->id, 16, &dev_id);
+               if (ret < 0) {
+                       dev_err(dev, "Unique device id conversion error: %d\n", ret);
+                       return ret;
+               }
+
+               if (soc_intel_is_byt_cr(pdev))
+                       byt_rvp_platform_data.res_info = &bytcr_res_info;
        }
 
        dev_dbg(dev, "ACPI device id: %x\n", dev_id);
@@ -280,11 +330,6 @@ static int sst_acpi_probe(struct platform_device *pdev)
        if (ret < 0)
                return ret;
 
-       if (soc_intel_is_byt_cr(pdev)) {
-               /* override resource info */
-               byt_rvp_platform_data.res_info = &bytcr_res_info;
-       }
-
        /* update machine parameters */
        mach->mach_params.acpi_ipc_irq_index =
                pdata->res_info->acpi_ipc_irq_index;
@@ -344,6 +389,7 @@ static void sst_acpi_remove(struct platform_device *pdev)
 }
 
 static const struct acpi_device_id sst_acpi_ids[] = {
+       { "LPE0F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
        { "80860F28", (unsigned long)&snd_soc_acpi_intel_baytrail_machines},
        { "808622A8", (unsigned long)&snd_soc_acpi_intel_cherrytrail_machines},
        { },