On Wed, Feb 23, 2022 at 02:31:53PM +0100, Hans de Goede wrote: > The ACPI tables for the codec setup on the Lenovo Yoga Tablet 2 830/1050 > miss 2 things compared to their Windows (Lenovo Yoga Tablet 2 1051) > counterparts: > > 1. There is no CLKE ACPI method to enable output of the 32KHz PMU clock on > pin 6 of the SUS GPIO controller > > 2. The GPIOs used by the codec are not listed in the fwnode for the codec > > Add pinctrl code to set the SUS6 pin mux manually and a gpio-lookup table > for the GPIOs to work around both issues. With or without an addressed nit-pick, Reviewed-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx> > --- > drivers/platform/x86/x86-android-tablets.c | 69 ++++++++++++++++++++++ > 1 file changed, 69 insertions(+) > > diff --git a/drivers/platform/x86/x86-android-tablets.c b/drivers/platform/x86/x86-android-tablets.c > index c3d2b30dbe26..f446be72e539 100644 > --- a/drivers/platform/x86/x86-android-tablets.c > +++ b/drivers/platform/x86/x86-android-tablets.c > @@ -23,12 +23,15 @@ > #include <linux/irqdomain.h> > #include <linux/module.h> > #include <linux/mod_devicetable.h> > +#include <linux/pinctrl/consumer.h> > +#include <linux/pinctrl/machine.h> > #include <linux/platform_data/lp855x.h> > #include <linux/platform_device.h> > #include <linux/pm.h> > #include <linux/power/bq24190_charger.h> > #include <linux/rmi.h> > #include <linux/serdev.h> > +#include <linux/spi/spi.h> > #include <linux/string.h> > /* For gpio_get_desc() which is EXPORT_SYMBOL_GPL() */ > #include "../../gpio/gpiolib.h" > @@ -801,8 +804,22 @@ static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = { > }, > }; > > +#define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00" > + > +static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = { > + .dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, > + .table = { > + GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH), > + GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH), > + GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH), > + GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW), > + { } > + }, > +}; > + > static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = { > &lenovo_yoga_tab2_830_1050_int3496_gpios, > + &lenovo_yoga_tab2_830_1050_codec_gpios, > NULL > }; > > @@ -866,6 +883,49 @@ static int __init lenovo_yoga_tab2_830_1050_init_display(void) > return 0; > } > > +/* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */ > +static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map = > + PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk", > + "INT33FC:02", "pmu_clk2_grp", "pmu_clk"); To avoid typos in messages you may define "codec_32khz_clk" and reuse in all (three?) cases. > +static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl; > + > +static int __init lenovo_yoga_tab2_830_1050_init_codec(void) > +{ > + struct device *codec_dev; > + struct pinctrl *pinctrl; > + int ret; > + > + codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, > + LENOVO_YOGA_TAB2_830_1050_CODEC_NAME); > + if (!codec_dev) { > + pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME); > + return -ENODEV; > + } > + > + ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1); > + if (ret) > + goto err_put_device; > + > + pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk"); > + if (IS_ERR(pinctrl)) { > + ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n"); > + goto err_unregister_mappings; > + } > + > + /* We're done with the codec_dev now */ > + put_device(codec_dev); > + > + lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl; > + return 0; > + > +err_unregister_mappings: > + pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map); > +err_put_device: > + put_device(codec_dev); > + return ret; > +} > + > /* > * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off > * gets used as pm_power_off handler. This causes "poweroff" on these tablets > @@ -886,6 +946,10 @@ static int __init lenovo_yoga_tab2_830_1050_init(void) > if (ret) > return ret; > > + ret = lenovo_yoga_tab2_830_1050_init_codec(); > + if (ret) > + return ret; > + > pm_power_off = lenovo_yoga_tab2_830_1050_power_off; > return 0; > } > @@ -893,6 +957,11 @@ static int __init lenovo_yoga_tab2_830_1050_init(void) > static void lenovo_yoga_tab2_830_1050_exit(void) > { > pm_power_off = NULL; /* Just turn poweroff into halt on module unload */ > + > + if (lenovo_yoga_tab2_830_1050_codec_pinctrl) { > + pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl); > + pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map); > + } > } > > /* Nextbook Ares 8 tablets have an Android factory img with everything hardcoded */ > -- > 2.35.1 > -- With Best Regards, Andy Shevchenko