/* * ACPI DSDT table doesn't have correct PCI interrupt routing information * for some devices, so here we have a kernel workaround to fix this issue. * The workaround can be easily removed by not appending "vlv2" paramerter * to kernel command line. */ static int __init vlv2_pci_irq_fixup(void) { /* HACK: intel_mid_identify_cpu() is not set yet */ /* More hack: do cpuid instruction. This will be done here (helper is_valleyview) for now * as temp w/a until reworked function is provided from Bin Gao. */ if (is_valleyview()) { pr_info("VLV2: fix up PCI interrupt routing\n"); pcibios_enable_irq = vlv2_pci_enable_irq; } return 0; }
static int snd_cht_mc_probe(struct platform_device *pdev) { struct snd_soc_card *card = snd_soc_cards[0].soc_card; struct snd_soc_acpi_mach *mach; struct cht_mc_private *drv; const char *i2c_name = NULL; bool found = false; bool is_bytcr = false; int dai_index = 0; int ret_val = 0; int i; drv = devm_kzalloc(&pdev->dev, sizeof(*drv), GFP_KERNEL); if (!drv) return -ENOMEM; mach = (&pdev->dev)->platform_data; for (i = 0; i < ARRAY_SIZE(snd_soc_cards); i++) { if (acpi_dev_found(snd_soc_cards[i].codec_id) && (!strncmp(snd_soc_cards[i].codec_id, mach->id, 8))) { dev_dbg(&pdev->dev, "found codec %s\n", snd_soc_cards[i].codec_id); card = snd_soc_cards[i].soc_card; drv->acpi_card = &snd_soc_cards[i]; found = true; break; } } if (!found) { dev_err(&pdev->dev, "No matching HID found in supported list\n"); return -ENODEV; } card->dev = &pdev->dev; sprintf(drv->codec_name, "i2c-%s:00", drv->acpi_card->codec_id); /* set correct codec name */ for (i = 0; i < ARRAY_SIZE(cht_dailink); i++) if (!strcmp(card->dai_link[i].codec_name, "i2c-10EC5645:00")) { card->dai_link[i].codec_name = drv->codec_name; dai_index = i; } /* fixup codec name based on HID */ i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); if (i2c_name) { snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name), "%s%s", "i2c-", i2c_name); cht_dailink[dai_index].codec_name = cht_rt5645_codec_name; } /* * swap SSP0 if bytcr is detected * (will be overridden if DMI quirk is detected) */ if (is_valleyview()) { if (mach->mach_params.acpi_ipc_irq_index == 0) is_bytcr = true; } if (is_bytcr) { /* * Baytrail CR platforms may have CHAN package in BIOS, try * to find relevant routing quirk based as done on Windows * platforms. We have to read the information directly from the * BIOS, at this stage the card is not created and the links * with the codec driver/pdata are non-existent */ struct acpi_chan_package chan_package; /* format specified: 2 64-bit integers */ struct acpi_buffer format = {sizeof("NN"), "NN"}; struct acpi_buffer state = {0, NULL}; struct snd_soc_acpi_package_context pkg_ctx; bool pkg_found = false; state.length = sizeof(chan_package); state.pointer = &chan_package; pkg_ctx.name = "CHAN"; pkg_ctx.length = 2; pkg_ctx.format = &format; pkg_ctx.state = &state; pkg_ctx.data_valid = false; pkg_found = snd_soc_acpi_find_package_from_hid(mach->id, &pkg_ctx); if (pkg_found) { if (chan_package.aif_value == 1) { dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n"); cht_rt5645_quirk |= CHT_RT5645_SSP0_AIF1; } else if (chan_package.aif_value == 2) { dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n"); cht_rt5645_quirk |= CHT_RT5645_SSP0_AIF2; } else { dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n"); pkg_found = false; } } if (!pkg_found) { /* no BIOS indications, assume SSP0-AIF2 connection */ cht_rt5645_quirk |= CHT_RT5645_SSP0_AIF2; } } /* check quirks before creating card */ dmi_check_system(cht_rt5645_quirk_table); log_quirks(&pdev->dev); if ((cht_rt5645_quirk & CHT_RT5645_SSP2_AIF2) || (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) { /* fixup codec aif name */ snprintf(cht_rt5645_codec_aif_name, sizeof(cht_rt5645_codec_aif_name), "%s", "rt5645-aif2"); cht_dailink[dai_index].codec_dai_name = cht_rt5645_codec_aif_name; } if ((cht_rt5645_quirk & CHT_RT5645_SSP0_AIF1) || (cht_rt5645_quirk & CHT_RT5645_SSP0_AIF2)) { /* fixup cpu dai name name */ snprintf(cht_rt5645_cpu_dai_name, sizeof(cht_rt5645_cpu_dai_name), "%s", "ssp0-port"); cht_dailink[dai_index].cpu_dai_name = cht_rt5645_cpu_dai_name; } drv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); if (IS_ERR(drv->mclk)) { dev_err(&pdev->dev, "Failed to get MCLK from pmc_plt_clk_3: %ld\n", PTR_ERR(drv->mclk)); return PTR_ERR(drv->mclk); } snd_soc_card_set_drvdata(card, drv); ret_val = devm_snd_soc_register_card(&pdev->dev, card); if (ret_val) { dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret_val); return ret_val; } platform_set_drvdata(pdev, card); return ret_val; }