config X86_ANDROID_TABLETS
tristate "X86 Android tablet support"
- depends on I2C && SPI && SERIAL_DEV_BUS && ACPI && EFI && GPIOLIB && PMIC_OPREGION
+ depends on I2C && SPI && SERIAL_DEV_BUS
+ depends on GPIOLIB && PMIC_OPREGION
+ depends on ACPI && EFI && PCI
select NEW_LEDS
select LEDS_CLASS
help
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/acpi.h>
+#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/irq.h>
#include <linux/module.h>
+#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/serdev.h>
#include <linux/string.h>
return i2c_acpi_find_adapter_by_handle(handle);
}
+static __init int match_parent(struct device *dev, const void *data)
+{
+ return dev->parent == data;
+}
+
+static struct i2c_adapter *
+get_i2c_adap_by_pci_parent(const struct x86_i2c_client_info *client_info)
+{
+ struct i2c_adapter *adap = NULL;
+ struct device *pdev, *adap_dev;
+
+ pdev = bus_find_device_by_name(&pci_bus_type, NULL, client_info->adapter_path);
+ if (!pdev) {
+ pr_err("Error could not find %s PCI device\n", client_info->adapter_path);
+ return NULL;
+ }
+
+ adap_dev = bus_find_device(&i2c_bus_type, NULL, pdev, match_parent);
+ if (adap_dev) {
+ adap = i2c_verify_adapter(adap_dev);
+ if (!adap)
+ put_device(adap_dev);
+ }
+
+ put_device(pdev);
+
+ return adap;
+}
+
static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info,
int idx)
{
if (board_info.irq < 0)
return board_info.irq;
- adap = get_i2c_adap_by_handle(client_info);
+ if (dev_info->use_pci_devname)
+ adap = get_i2c_adap_by_pci_parent(client_info);
+ else
+ adap = get_i2c_adap_by_handle(client_info);
+
if (!adap) {
pr_err("error could not get %s adapter\n", client_info->adapter_path);
return -ENODEV;