Commit b01e9348 authored by Hans de Goede's avatar Hans de Goede Committed by Lee Jones

mfd: intel_soc_pmic: Differentiate between Bay and Cherry Trail CRC variants

Both Bay and Cherry Trail devices may be used together with a Crystal Cove
PMIC. Each platform has its own variant of the PMIC, which both use the
same ACPI HID, but they are not 100% compatible.

This commits makes the intel_soc_pmic_core code check the _HRV of the
ACPI-firmware-node and selects intel_soc_pmic_config_byt_crc resp.
intel_soc_pmic_config_cht_crc based on this.

This fixes the Bay Trail specific ACPI OpRegion code causing problems
on Cherry Trail devices. Specifically this was causing the external
microsd slot on a Dell Venue 8 5855 (Cherry Trail version) to not work
and the eMMC to become unreliable and throw lots of errors.

Fixes: 51652384 ("mfd: intel_soc_pmic: Core driver")
Reported-and-tested-by: default avatarrussianneuromancer <russianneuromancer@ya.ru>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: default avatarLee Jones <lee.jones@linaro.org>
parent 4d9ed62a
...@@ -467,12 +467,12 @@ config LPC_SCH ...@@ -467,12 +467,12 @@ config LPC_SCH
config INTEL_SOC_PMIC config INTEL_SOC_PMIC
bool "Support for Crystal Cove PMIC" bool "Support for Crystal Cove PMIC"
depends on HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK depends on ACPI && HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK
depends on X86 || COMPILE_TEST depends on X86 || COMPILE_TEST
select MFD_CORE select MFD_CORE
select REGMAP_I2C select REGMAP_I2C
select REGMAP_IRQ select REGMAP_IRQ
select I2C_DESIGNWARE_PLATFORM if ACPI select I2C_DESIGNWARE_PLATFORM
help help
Select this option to enable support for Crystal Cove PMIC Select this option to enable support for Crystal Cove PMIC
on some Intel SoC systems. The PMIC provides ADC, GPIO, on some Intel SoC systems. The PMIC provides ADC, GPIO,
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
* Author: Zhu, Lejun <lejun.zhu@linux.intel.com> * Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
*/ */
#include <linux/acpi.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/i2c.h> #include <linux/i2c.h>
...@@ -28,6 +29,10 @@ ...@@ -28,6 +29,10 @@
#include <linux/pwm.h> #include <linux/pwm.h>
#include "intel_soc_pmic_core.h" #include "intel_soc_pmic_core.h"
/* Crystal Cove PMIC shares same ACPI ID between different platforms */
#define BYT_CRC_HRV 2
#define CHT_CRC_HRV 3
/* Lookup table for the Panel Enable/Disable line as GPIO signals */ /* Lookup table for the Panel Enable/Disable line as GPIO signals */
static struct gpiod_lookup_table panel_gpio_table = { static struct gpiod_lookup_table panel_gpio_table = {
/* Intel GFX is consumer */ /* Intel GFX is consumer */
...@@ -48,16 +53,33 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c, ...@@ -48,16 +53,33 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *i2c_id) const struct i2c_device_id *i2c_id)
{ {
struct device *dev = &i2c->dev; struct device *dev = &i2c->dev;
const struct acpi_device_id *id;
struct intel_soc_pmic_config *config; struct intel_soc_pmic_config *config;
struct intel_soc_pmic *pmic; struct intel_soc_pmic *pmic;
unsigned long long hrv;
acpi_status status;
int ret; int ret;
id = acpi_match_device(dev->driver->acpi_match_table, dev); /*
if (!id || !id->driver_data) * There are 2 different Crystal Cove PMICs a Bay Trail and Cherry
* Trail version, use _HRV to differentiate between the 2.
*/
status = acpi_evaluate_integer(ACPI_HANDLE(dev), "_HRV", NULL, &hrv);
if (ACPI_FAILURE(status)) {
dev_err(dev, "Failed to get PMIC hardware revision\n");
return -ENODEV; return -ENODEV;
}
config = (struct intel_soc_pmic_config *)id->driver_data;
switch (hrv) {
case BYT_CRC_HRV:
config = &intel_soc_pmic_config_byt_crc;
break;
case CHT_CRC_HRV:
config = &intel_soc_pmic_config_cht_crc;
break;
default:
dev_warn(dev, "Unknown hardware rev %llu, assuming BYT\n", hrv);
config = &intel_soc_pmic_config_byt_crc;
}
pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
if (!pmic) if (!pmic)
...@@ -157,7 +179,7 @@ MODULE_DEVICE_TABLE(i2c, intel_soc_pmic_i2c_id); ...@@ -157,7 +179,7 @@ MODULE_DEVICE_TABLE(i2c, intel_soc_pmic_i2c_id);
#if defined(CONFIG_ACPI) #if defined(CONFIG_ACPI)
static const struct acpi_device_id intel_soc_pmic_acpi_match[] = { static const struct acpi_device_id intel_soc_pmic_acpi_match[] = {
{"INT33FD", (kernel_ulong_t)&intel_soc_pmic_config_byt_crc}, { "INT33FD" },
{ }, { },
}; };
MODULE_DEVICE_TABLE(acpi, intel_soc_pmic_acpi_match); MODULE_DEVICE_TABLE(acpi, intel_soc_pmic_acpi_match);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment