diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/platform/x86/x86-android-tablets.c | 69 |
1 files changed, 69 insertions, 0 deletions
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"); + +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 */ |