Commit eab541aa authored by Hans de Goede's avatar Hans de Goede

Merge remote-tracking branch 'pdx86/platform-drivers-x86-android-tablets' into review-hans

parents 4106a70d eee9cd5d
...@@ -437,6 +437,11 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, ...@@ -437,6 +437,11 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
if (!handler) if (!handler)
return AE_OK; return AE_OK;
if (acpi_gpio_in_ignore_list(ignore_interrupt, dev_name(chip->parent), pin)) {
dev_info(chip->parent, "Ignoring interrupt on pin %u\n", pin);
return AE_OK;
}
desc = acpi_request_own_gpiod(chip, agpio, 0, "ACPI:Event"); desc = acpi_request_own_gpiod(chip, agpio, 0, "ACPI:Event");
if (IS_ERR(desc)) { if (IS_ERR(desc)) {
dev_err(chip->parent, dev_err(chip->parent,
...@@ -461,11 +466,6 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, ...@@ -461,11 +466,6 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares,
goto fail_unlock_irq; goto fail_unlock_irq;
} }
if (acpi_gpio_in_ignore_list(ignore_interrupt, dev_name(chip->parent), pin)) {
dev_info(chip->parent, "Ignoring interrupt on pin %u\n", pin);
return AE_OK;
}
event = kzalloc(sizeof(*event), GFP_KERNEL); event = kzalloc(sizeof(*event), GFP_KERNEL);
if (!event) if (!event)
goto fail_unlock_irq; goto fail_unlock_irq;
...@@ -1654,6 +1654,26 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { ...@@ -1654,6 +1654,26 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = {
.ignore_wake = "SYNA1202:00@16", .ignore_wake = "SYNA1202:00@16",
}, },
}, },
{
/*
* On the Peaq C1010 2-in-1 INT33FC:00 pin 3 is connected to
* a "dolby" button. At the ACPI level an _AEI event-handler
* is connected which sets an ACPI variable to 1 on both
* edges. This variable can be polled + cleared to 0 using
* WMI. But since the variable is set on both edges the WMI
* interface is pretty useless even when polling.
* So instead the x86-android-tablets code instantiates
* a gpio-keys platform device for it.
* Ignore the _AEI handler for the pin, so that it is not busy.
*/
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"),
DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"),
},
.driver_data = &(struct acpi_gpiolib_dmi_quirk) {
.ignore_interrupt = "INT33FC:00@3",
},
},
{} /* Terminating entry */ {} /* Terminating entry */
}; };
......
...@@ -303,6 +303,7 @@ static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = ...@@ -303,6 +303,7 @@ static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst =
.index = 28, .index = 28,
.trigger = ACPI_EDGE_SENSITIVE, .trigger = ACPI_EDGE_SENSITIVE,
.polarity = ACPI_ACTIVE_LOW, .polarity = ACPI_ACTIVE_LOW,
.con_id = "atmel_mxt_ts_irq",
}, },
}, },
}; };
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/gpio/driver.h> #include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h> #include <linux/gpio/machine.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -21,33 +21,54 @@ ...@@ -21,33 +21,54 @@
#include <linux/string.h> #include <linux/string.h>
#include "x86-android-tablets.h" #include "x86-android-tablets.h"
/* For gpiochip_get_desc() which is EXPORT_SYMBOL_GPL() */
#include "../../../gpio/gpiolib.h"
#include "../../../gpio/gpiolib-acpi.h"
static int gpiochip_find_match_label(struct gpio_chip *gc, void *data) static struct platform_device *x86_android_tablet_device;
{
return gc->label && !strcmp(gc->label, data);
}
int x86_android_tablet_get_gpiod(const char *label, int pin, struct gpio_desc **desc) /*
* This helper allows getting a gpio_desc *before* the actual device consuming
* the GPIO has been instantiated. This function _must_ only be used to handle
* this special case such as e.g. :
*
* 1. Getting an IRQ from a GPIO for i2c_board_info.irq which is passed to
* i2c_client_new() to instantiate i2c_client-s; or
* 2. Calling desc_to_gpio() to get an old style GPIO number for gpio_keys
* platform_data which still uses old style GPIO numbers.
*
* Since the consuming device has not been instatiated yet a dynamic lookup
* is generated using the special x86_android_tablet dev for dev_id.
*
* For normal GPIO lookups a standard static gpiod_lookup_table _must_ be used.
*/
int x86_android_tablet_get_gpiod(const char *chip, int pin, const char *con_id,
bool active_low, enum gpiod_flags dflags,
struct gpio_desc **desc)
{ {
struct gpiod_lookup_table *lookup;
struct gpio_desc *gpiod; struct gpio_desc *gpiod;
struct gpio_chip *chip;
chip = gpiochip_find((void *)label, gpiochip_find_match_label); lookup = kzalloc(struct_size(lookup, table, 2), GFP_KERNEL);
if (!chip) { if (!lookup)
pr_err("error cannot find GPIO chip %s\n", label); return -ENOMEM;
return -ENODEV;
} lookup->dev_id = KBUILD_MODNAME;
lookup->table[0].key = chip;
lookup->table[0].chip_hwnum = pin;
lookup->table[0].con_id = con_id;
lookup->table[0].flags = active_low ? GPIO_ACTIVE_LOW : GPIO_ACTIVE_HIGH;
gpiod_add_lookup_table(lookup);
gpiod = devm_gpiod_get(&x86_android_tablet_device->dev, con_id, dflags);
gpiod_remove_lookup_table(lookup);
kfree(lookup);
gpiod = gpiochip_get_desc(chip, pin);
if (IS_ERR(gpiod)) { if (IS_ERR(gpiod)) {
pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), label, pin); pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), chip, pin);
return PTR_ERR(gpiod); return PTR_ERR(gpiod);
} }
if (desc)
*desc = gpiod; *desc = gpiod;
return 0; return 0;
} }
...@@ -77,7 +98,8 @@ int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data) ...@@ -77,7 +98,8 @@ int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data)
return irq; return irq;
case X86_ACPI_IRQ_TYPE_GPIOINT: case X86_ACPI_IRQ_TYPE_GPIOINT:
/* Like acpi_dev_gpio_irq_get(), but without parsing ACPI resources */ /* Like acpi_dev_gpio_irq_get(), but without parsing ACPI resources */
ret = x86_android_tablet_get_gpiod(data->chip, data->index, &gpiod); ret = x86_android_tablet_get_gpiod(data->chip, data->index, data->con_id,
false, GPIOD_ASIS, &gpiod);
if (ret) if (ret)
return ret; return ret;
...@@ -224,7 +246,7 @@ static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int ...@@ -224,7 +246,7 @@ static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int
return ret; return ret;
} }
static void x86_android_tablet_cleanup(void) static void x86_android_tablet_remove(struct platform_device *pdev)
{ {
int i; int i;
...@@ -255,11 +277,10 @@ static void x86_android_tablet_cleanup(void) ...@@ -255,11 +277,10 @@ static void x86_android_tablet_cleanup(void)
software_node_unregister(bat_swnode); software_node_unregister(bat_swnode);
} }
static __init int x86_android_tablet_init(void) static __init int x86_android_tablet_probe(struct platform_device *pdev)
{ {
const struct x86_dev_info *dev_info; const struct x86_dev_info *dev_info;
const struct dmi_system_id *id; const struct dmi_system_id *id;
struct gpio_chip *chip;
int i, ret = 0; int i, ret = 0;
id = dmi_first_match(x86_android_tablet_ids); id = dmi_first_match(x86_android_tablet_ids);
...@@ -267,20 +288,8 @@ static __init int x86_android_tablet_init(void) ...@@ -267,20 +288,8 @@ static __init int x86_android_tablet_init(void)
return -ENODEV; return -ENODEV;
dev_info = id->driver_data; dev_info = id->driver_data;
/* Allow x86_android_tablet_device use before probe() exits */
/* x86_android_tablet_device = pdev;
* The broken DSDTs on these devices often also include broken
* _AEI (ACPI Event Interrupt) handlers, disable these.
*/
if (dev_info->invalid_aei_gpiochip) {
chip = gpiochip_find(dev_info->invalid_aei_gpiochip,
gpiochip_find_match_label);
if (!chip) {
pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip);
return -ENODEV;
}
acpi_gpiochip_free_interrupts(chip);
}
/* /*
* Since this runs from module_init() it cannot use -EPROBE_DEFER, * Since this runs from module_init() it cannot use -EPROBE_DEFER,
...@@ -303,7 +312,7 @@ static __init int x86_android_tablet_init(void) ...@@ -303,7 +312,7 @@ static __init int x86_android_tablet_init(void)
if (dev_info->init) { if (dev_info->init) {
ret = dev_info->init(); ret = dev_info->init();
if (ret < 0) { if (ret < 0) {
x86_android_tablet_cleanup(); x86_android_tablet_remove(pdev);
return ret; return ret;
} }
exit_handler = dev_info->exit; exit_handler = dev_info->exit;
...@@ -311,7 +320,7 @@ static __init int x86_android_tablet_init(void) ...@@ -311,7 +320,7 @@ static __init int x86_android_tablet_init(void)
i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL); i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL);
if (!i2c_clients) { if (!i2c_clients) {
x86_android_tablet_cleanup(); x86_android_tablet_remove(pdev);
return -ENOMEM; return -ENOMEM;
} }
...@@ -319,7 +328,7 @@ static __init int x86_android_tablet_init(void) ...@@ -319,7 +328,7 @@ static __init int x86_android_tablet_init(void)
for (i = 0; i < i2c_client_count; i++) { for (i = 0; i < i2c_client_count; i++) {
ret = x86_instantiate_i2c_client(dev_info, i); ret = x86_instantiate_i2c_client(dev_info, i);
if (ret < 0) { if (ret < 0) {
x86_android_tablet_cleanup(); x86_android_tablet_remove(pdev);
return ret; return ret;
} }
} }
...@@ -327,7 +336,7 @@ static __init int x86_android_tablet_init(void) ...@@ -327,7 +336,7 @@ static __init int x86_android_tablet_init(void)
/* + 1 to make space for (optional) gpio_keys_button pdev */ /* + 1 to make space for (optional) gpio_keys_button pdev */
pdevs = kcalloc(dev_info->pdev_count + 1, sizeof(*pdevs), GFP_KERNEL); pdevs = kcalloc(dev_info->pdev_count + 1, sizeof(*pdevs), GFP_KERNEL);
if (!pdevs) { if (!pdevs) {
x86_android_tablet_cleanup(); x86_android_tablet_remove(pdev);
return -ENOMEM; return -ENOMEM;
} }
...@@ -335,14 +344,14 @@ static __init int x86_android_tablet_init(void) ...@@ -335,14 +344,14 @@ static __init int x86_android_tablet_init(void)
for (i = 0; i < pdev_count; i++) { for (i = 0; i < pdev_count; i++) {
pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]); pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]);
if (IS_ERR(pdevs[i])) { if (IS_ERR(pdevs[i])) {
x86_android_tablet_cleanup(); x86_android_tablet_remove(pdev);
return PTR_ERR(pdevs[i]); return PTR_ERR(pdevs[i]);
} }
} }
serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL); serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL);
if (!serdevs) { if (!serdevs) {
x86_android_tablet_cleanup(); x86_android_tablet_remove(pdev);
return -ENOMEM; return -ENOMEM;
} }
...@@ -350,7 +359,7 @@ static __init int x86_android_tablet_init(void) ...@@ -350,7 +359,7 @@ static __init int x86_android_tablet_init(void)
for (i = 0; i < serdev_count; i++) { for (i = 0; i < serdev_count; i++) {
ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i); ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i);
if (ret < 0) { if (ret < 0) {
x86_android_tablet_cleanup(); x86_android_tablet_remove(pdev);
return ret; return ret;
} }
} }
...@@ -361,30 +370,34 @@ static __init int x86_android_tablet_init(void) ...@@ -361,30 +370,34 @@ static __init int x86_android_tablet_init(void)
buttons = kcalloc(dev_info->gpio_button_count, sizeof(*buttons), GFP_KERNEL); buttons = kcalloc(dev_info->gpio_button_count, sizeof(*buttons), GFP_KERNEL);
if (!buttons) { if (!buttons) {
x86_android_tablet_cleanup(); x86_android_tablet_remove(pdev);
return -ENOMEM; return -ENOMEM;
} }
for (i = 0; i < dev_info->gpio_button_count; i++) { for (i = 0; i < dev_info->gpio_button_count; i++) {
ret = x86_android_tablet_get_gpiod(dev_info->gpio_button[i].chip, ret = x86_android_tablet_get_gpiod(dev_info->gpio_button[i].chip,
dev_info->gpio_button[i].pin, &gpiod); dev_info->gpio_button[i].pin,
dev_info->gpio_button[i].button.desc,
false, GPIOD_IN, &gpiod);
if (ret < 0) { if (ret < 0) {
x86_android_tablet_cleanup(); x86_android_tablet_remove(pdev);
return ret; return ret;
} }
buttons[i] = dev_info->gpio_button[i].button; buttons[i] = dev_info->gpio_button[i].button;
buttons[i].gpio = desc_to_gpio(gpiod); buttons[i].gpio = desc_to_gpio(gpiod);
/* Release gpiod so that gpio-keys can request it */
devm_gpiod_put(&x86_android_tablet_device->dev, gpiod);
} }
pdata.buttons = buttons; pdata.buttons = buttons;
pdata.nbuttons = dev_info->gpio_button_count; pdata.nbuttons = dev_info->gpio_button_count;
pdevs[pdev_count] = platform_device_register_data(NULL, "gpio-keys", pdevs[pdev_count] = platform_device_register_data(&pdev->dev, "gpio-keys",
PLATFORM_DEVID_AUTO, PLATFORM_DEVID_AUTO,
&pdata, sizeof(pdata)); &pdata, sizeof(pdata));
if (IS_ERR(pdevs[pdev_count])) { if (IS_ERR(pdevs[pdev_count])) {
x86_android_tablet_cleanup(); x86_android_tablet_remove(pdev);
return PTR_ERR(pdevs[pdev_count]); return PTR_ERR(pdevs[pdev_count]);
} }
pdev_count++; pdev_count++;
...@@ -393,8 +406,29 @@ static __init int x86_android_tablet_init(void) ...@@ -393,8 +406,29 @@ static __init int x86_android_tablet_init(void)
return 0; return 0;
} }
static struct platform_driver x86_android_tablet_driver = {
.driver = {
.name = KBUILD_MODNAME,
},
.remove_new = x86_android_tablet_remove,
};
static int __init x86_android_tablet_init(void)
{
x86_android_tablet_device = platform_create_bundle(&x86_android_tablet_driver,
x86_android_tablet_probe,
NULL, 0, NULL, 0);
return PTR_ERR_OR_ZERO(x86_android_tablet_device);
}
module_init(x86_android_tablet_init); module_init(x86_android_tablet_init);
module_exit(x86_android_tablet_cleanup);
static void __exit x86_android_tablet_exit(void)
{
platform_device_unregister(x86_android_tablet_device);
platform_driver_unregister(&x86_android_tablet_driver);
}
module_exit(x86_android_tablet_exit);
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver"); MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver");
......
...@@ -95,6 +95,7 @@ static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst ...@@ -95,6 +95,7 @@ static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst
.index = 56, .index = 56,
.trigger = ACPI_EDGE_SENSITIVE, .trigger = ACPI_EDGE_SENSITIVE,
.polarity = ACPI_ACTIVE_LOW, .polarity = ACPI_ACTIVE_LOW,
.con_id = "goodix_ts_irq",
}, },
}, { }, {
/* Wacom Digitizer in keyboard half */ /* Wacom Digitizer in keyboard half */
...@@ -111,6 +112,7 @@ static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst ...@@ -111,6 +112,7 @@ static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst
.index = 49, .index = 49,
.trigger = ACPI_LEVEL_SENSITIVE, .trigger = ACPI_LEVEL_SENSITIVE,
.polarity = ACPI_ACTIVE_LOW, .polarity = ACPI_ACTIVE_LOW,
.con_id = "wacom_irq",
}, },
}, { }, {
/* LP8557 Backlight controller */ /* LP8557 Backlight controller */
...@@ -136,6 +138,7 @@ static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst ...@@ -136,6 +138,7 @@ static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst
.index = 77, .index = 77,
.trigger = ACPI_LEVEL_SENSITIVE, .trigger = ACPI_LEVEL_SENSITIVE,
.polarity = ACPI_ACTIVE_LOW, .polarity = ACPI_ACTIVE_LOW,
.con_id = "hideep_ts_irq",
}, },
}, },
}; };
...@@ -321,6 +324,7 @@ static struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __init ...@@ -321,6 +324,7 @@ static struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __init
.index = 2, .index = 2,
.trigger = ACPI_EDGE_SENSITIVE, .trigger = ACPI_EDGE_SENSITIVE,
.polarity = ACPI_ACTIVE_HIGH, .polarity = ACPI_ACTIVE_HIGH,
.con_id = "bq24292i_irq",
}, },
}, { }, {
/* BQ27541 fuel-gauge */ /* BQ27541 fuel-gauge */
...@@ -431,7 +435,8 @@ static int __init lenovo_yoga_tab2_830_1050_init_touchscreen(void) ...@@ -431,7 +435,8 @@ static int __init lenovo_yoga_tab2_830_1050_init_touchscreen(void)
int ret; int ret;
/* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */ /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod); ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, "yoga_bootstrap",
false, GPIOD_IN, &gpiod);
if (ret) if (ret)
return ret; return ret;
...@@ -560,7 +565,6 @@ static const struct software_node fg_bq25890_1_supply_node = { ...@@ -560,7 +565,6 @@ static const struct software_node fg_bq25890_1_supply_node = {
/* bq25892 charger settings for the flat lipo battery behind the screen */ /* bq25892 charger settings for the flat lipo battery behind the screen */
static const struct property_entry lenovo_yt3_bq25892_0_props[] = { static const struct property_entry lenovo_yt3_bq25892_0_props[] = {
PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers), PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers),
PROPERTY_ENTRY_STRING("linux,power-supply-name", "bq25892-second-chrg"),
PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40), PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40),
PROPERTY_ENTRY_BOOL("linux,skip-reset"), PROPERTY_ENTRY_BOOL("linux,skip-reset"),
/* Values taken from Android Factory Image */ /* Values taken from Android Factory Image */
...@@ -615,6 +619,7 @@ static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = { ...@@ -615,6 +619,7 @@ static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
.index = 5, .index = 5,
.trigger = ACPI_EDGE_SENSITIVE, .trigger = ACPI_EDGE_SENSITIVE,
.polarity = ACPI_ACTIVE_LOW, .polarity = ACPI_ACTIVE_LOW,
.con_id = "bq25892_0_irq",
}, },
}, { }, {
/* bq27500 fuel-gauge for the round li-ion cells in the hinge */ /* bq27500 fuel-gauge for the round li-ion cells in the hinge */
...@@ -640,6 +645,7 @@ static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = { ...@@ -640,6 +645,7 @@ static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
.index = 77, .index = 77,
.trigger = ACPI_LEVEL_SENSITIVE, .trigger = ACPI_LEVEL_SENSITIVE,
.polarity = ACPI_ACTIVE_LOW, .polarity = ACPI_ACTIVE_LOW,
.con_id = "hideep_ts_irq",
}, },
}, { }, {
/* LP8557 Backlight controller */ /* LP8557 Backlight controller */
...@@ -655,7 +661,6 @@ static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = { ...@@ -655,7 +661,6 @@ static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
static int __init lenovo_yt3_init(void) static int __init lenovo_yt3_init(void)
{ {
struct gpio_desc *gpiod;
int ret; int ret;
/* /*
...@@ -665,31 +670,23 @@ static int __init lenovo_yt3_init(void) ...@@ -665,31 +670,23 @@ static int __init lenovo_yt3_init(void)
* *
* The bq25890_charger driver controls these through I2C, but this only * The bq25890_charger driver controls these through I2C, but this only
* works if not overridden by the pins. Set these pins here: * works if not overridden by the pins. Set these pins here:
* 1. Set /CE to 0 to allow charging. * 1. Set /CE to 1 to allow charging.
* 2. Set OTG to 0 disable V5 boost output since the 5V boost output of * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of
* the main "bq25892_1" charger is used when necessary. * the main "bq25892_1" charger is used when necessary.
*/ */
/* /CE pin */ /* /CE pin */
ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, &gpiod); ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, "bq25892_0_ce",
true, GPIOD_OUT_HIGH, NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
/*
* The gpio_desc returned by x86_android_tablet_get_gpiod() is a "raw"
* gpio_desc, that is there is no way to pass lookup-flags like
* GPIO_ACTIVE_LOW. Set the GPIO to 0 here to enable charging since
* the /CE pin is active-low, but not marked as such in the gpio_desc.
*/
gpiod_set_value(gpiod, 0);
/* OTG pin */ /* OTG pin */
ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, &gpiod); ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, "bq25892_0_otg",
false, GPIOD_OUT_LOW, NULL);
if (ret < 0) if (ret < 0)
return ret; return ret;
gpiod_set_value(gpiod, 0);
/* Enable the regulators used by the touchscreen */ /* Enable the regulators used by the touchscreen */
intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff); intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff); intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
......
...@@ -47,6 +47,7 @@ static const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst = ...@@ -47,6 +47,7 @@ static const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst =
.index = 3, .index = 3,
.trigger = ACPI_EDGE_SENSITIVE, .trigger = ACPI_EDGE_SENSITIVE,
.polarity = ACPI_ACTIVE_LOW, .polarity = ACPI_ACTIVE_LOW,
.con_id = "NVT-ts_irq",
}, },
}, { }, {
/* BMA250E accelerometer */ /* BMA250E accelerometer */
...@@ -62,6 +63,7 @@ static const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst = ...@@ -62,6 +63,7 @@ static const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst =
.index = 25, .index = 25,
.trigger = ACPI_LEVEL_SENSITIVE, .trigger = ACPI_LEVEL_SENSITIVE,
.polarity = ACPI_ACTIVE_HIGH, .polarity = ACPI_ACTIVE_HIGH,
.con_id = "bma250e_irq",
}, },
}, },
}; };
...@@ -174,6 +176,7 @@ static const struct x86_i2c_client_info chuwi_hi8_i2c_clients[] __initconst = { ...@@ -174,6 +176,7 @@ static const struct x86_i2c_client_info chuwi_hi8_i2c_clients[] __initconst = {
.index = 23, .index = 23,
.trigger = ACPI_LEVEL_SENSITIVE, .trigger = ACPI_LEVEL_SENSITIVE,
.polarity = ACPI_ACTIVE_HIGH, .polarity = ACPI_ACTIVE_HIGH,
.con_id = "bma250e_irq",
}, },
}, },
}; };
...@@ -312,6 +315,7 @@ static const struct x86_i2c_client_info medion_lifetab_s10346_i2c_clients[] __in ...@@ -312,6 +315,7 @@ static const struct x86_i2c_client_info medion_lifetab_s10346_i2c_clients[] __in
.index = 23, .index = 23,
.trigger = ACPI_EDGE_SENSITIVE, .trigger = ACPI_EDGE_SENSITIVE,
.polarity = ACPI_ACTIVE_HIGH, .polarity = ACPI_ACTIVE_HIGH,
.con_id = "kxtj21009_irq",
}, },
}, { }, {
/* goodix touchscreen */ /* goodix touchscreen */
...@@ -402,6 +406,7 @@ static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst ...@@ -402,6 +406,7 @@ static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst
.index = 3, .index = 3,
.trigger = ACPI_EDGE_SENSITIVE, .trigger = ACPI_EDGE_SENSITIVE,
.polarity = ACPI_ACTIVE_LOW, .polarity = ACPI_ACTIVE_LOW,
.con_id = "ft5416_irq",
}, },
}, },
}; };
...@@ -460,6 +465,7 @@ static const struct x86_i2c_client_info nextbook_ares8a_i2c_clients[] __initcons ...@@ -460,6 +465,7 @@ static const struct x86_i2c_client_info nextbook_ares8a_i2c_clients[] __initcons
.index = 17, .index = 17,
.trigger = ACPI_EDGE_SENSITIVE, .trigger = ACPI_EDGE_SENSITIVE,
.polarity = ACPI_ACTIVE_LOW, .polarity = ACPI_ACTIVE_LOW,
.con_id = "ft5416_irq",
}, },
}, },
}; };
...@@ -505,11 +511,6 @@ static const struct x86_gpio_button peaq_c1010_button __initconst = { ...@@ -505,11 +511,6 @@ static const struct x86_gpio_button peaq_c1010_button __initconst = {
const struct x86_dev_info peaq_c1010_info __initconst = { const struct x86_dev_info peaq_c1010_info __initconst = {
.gpio_button = &peaq_c1010_button, .gpio_button = &peaq_c1010_button,
.gpio_button_count = 1, .gpio_button_count = 1,
/*
* Move the ACPI event handler used by the broken WMI interface out of
* the way. This is the only event handler on INT33FC:00.
*/
.invalid_aei_gpiochip = "INT33FC:00",
}; };
/* /*
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#ifndef __PDX86_X86_ANDROID_TABLETS_H #ifndef __PDX86_X86_ANDROID_TABLETS_H
#define __PDX86_X86_ANDROID_TABLETS_H #define __PDX86_X86_ANDROID_TABLETS_H
#include <linux/gpio/consumer.h>
#include <linux/gpio_keys.h> #include <linux/gpio_keys.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/irqdomain_defs.h> #include <linux/irqdomain_defs.h>
...@@ -37,6 +38,7 @@ struct x86_acpi_irq_data { ...@@ -37,6 +38,7 @@ struct x86_acpi_irq_data {
int index; int index;
int trigger; /* ACPI_EDGE_SENSITIVE / ACPI_LEVEL_SENSITIVE */ int trigger; /* ACPI_EDGE_SENSITIVE / ACPI_LEVEL_SENSITIVE */
int polarity; /* ACPI_ACTIVE_HIGH / ACPI_ACTIVE_LOW / ACPI_ACTIVE_BOTH */ int polarity; /* ACPI_ACTIVE_HIGH / ACPI_ACTIVE_LOW / ACPI_ACTIVE_BOTH */
const char *con_id;
}; };
/* Structs to describe devices to instantiate */ /* Structs to describe devices to instantiate */
...@@ -66,7 +68,6 @@ struct x86_gpio_button { ...@@ -66,7 +68,6 @@ struct x86_gpio_button {
}; };
struct x86_dev_info { struct x86_dev_info {
char *invalid_aei_gpiochip;
const char * const *modules; const char * const *modules;
const struct software_node *bat_swnode; const struct software_node *bat_swnode;
struct gpiod_lookup_table * const *gpiod_lookup_tables; struct gpiod_lookup_table * const *gpiod_lookup_tables;
...@@ -82,7 +83,9 @@ struct x86_dev_info { ...@@ -82,7 +83,9 @@ struct x86_dev_info {
void (*exit)(void); void (*exit)(void);
}; };
int x86_android_tablet_get_gpiod(const char *label, int pin, struct gpio_desc **desc); int x86_android_tablet_get_gpiod(const char *chip, int pin, const char *con_id,
bool active_low, enum gpiod_flags dflags,
struct gpio_desc **desc);
int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data); int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data);
/* /*
......
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