Message ID | 20231014205314.59333-5-hdegoede@redhat.com (mailing list archive) |
---|---|
State | Handled Elsewhere, archived |
Headers | show |
Series | spi/ACPI: Add support for SPI WM5102 coded on Lenovo YT3-X90 | expand |
Hi, On 10/14/23 22:53, Hans de Goede wrote: > The SPI attached WM5102 codec on the Lenovo Yoga Tab 3 Pro YT3-X90F > is not described in the ACPI tables. > > Add info to instantiate the SPI device for the codec manually. > > Signed-off-by: Hans de Goede <hdegoede@redhat.com> > --- > .../platform/x86/x86-android-tablets/lenovo.c | 99 +++++++++++++++++++ > 1 file changed, 99 insertions(+) > > diff --git a/drivers/platform/x86/x86-android-tablets/lenovo.c b/drivers/platform/x86/x86-android-tablets/lenovo.c > index 585f10a57810..d5d815940ce1 100644 > --- a/drivers/platform/x86/x86-android-tablets/lenovo.c > +++ b/drivers/platform/x86/x86-android-tablets/lenovo.c > @@ -12,6 +12,8 @@ > > #include <linux/efi.h> > #include <linux/gpio/machine.h> > +#include <linux/mfd/arizona/pdata.h> > +#include <linux/mfd/arizona/registers.h> > #include <linux/mfd/intel_soc_pmic.h> > #include <linux/pinctrl/consumer.h> > #include <linux/pinctrl/machine.h> > @@ -677,6 +679,89 @@ static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = { > } > }; > > +/* > + * The AOSP 3.5 mm Headset: Accessory Specification gives the following values: > + * Function A Play/Pause: 0 ohm > + * Function D Voice assistant: 135 ohm > + * Function B Volume Up 240 ohm > + * Function C Volume Down 470 ohm > + * Minimum Mic DC resistance 1000 ohm > + * Minimum Ear speaker impedance 16 ohm > + * Note the first max value below must be less then the min. speaker impedance, > + * to allow CTIA/OMTP detection to work. The other max values are the closest > + * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances. > + */ > +static const struct arizona_micd_range arizona_micd_aosp_ranges[] = { > + { .max = 11, .key = KEY_PLAYPAUSE }, > + { .max = 186, .key = KEY_VOICECOMMAND }, > + { .max = 348, .key = KEY_VOLUMEUP }, > + { .max = 752, .key = KEY_VOLUMEDOWN }, > +}; > + > +/* YT3 WM5102 arizona_micd_config comes from Android kernel sources */ > +static struct arizona_micd_config lenovo_yt3_wm5102_micd_config[]={ > + { 0, 1, 0 }, > + { ARIZONA_ACCDET_SRC, 2, 1 }, > +}; > + > +static struct arizona_pdata lenovo_yt3_wm5102_pdata = { > + .irq_flags = IRQF_TRIGGER_LOW, > + .micd_detect_debounce = 200, > + .micd_ranges = arizona_micd_aosp_ranges, > + .num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges), > + .hpdet_channel = ARIZONA_ACCDET_MODE_HPL, > + > + /* Below settings come from Android kernel sources */ > + .micd_bias_start_time = 1, > + .micd_rate = 6, > + .micd_force_micbias = 1, > + .micd_configs = lenovo_yt3_wm5102_micd_config, > + .num_micd_configs = ARRAY_SIZE(lenovo_yt3_wm5102_micd_config), > + .micbias={ > + [0]={ /*MICBIAS1*/ > + .mV =2800 , > + .ext_cap=1, > + .discharge =1 , > + .soft_start =0, > + .bypass =0, > + }, Note I messed up the indentation here (spaces instead of tabs) when copy pasting this from one terminal to another, I'll go and fix this up locally. Regards, Hans > + [1]={ /*MICBIAS2*/ > + .mV =2800 , > + .ext_cap=1, > + .discharge =1 , > + .soft_start =0, > + .bypass =0, > + }, > + [2]={ /*MICBIAS3*/ > + .mV =2800 , > + .ext_cap=1, > + .discharge =1 , > + .soft_start =0, > + .bypass =0, > + }, > + }, > +}; > + > +static const struct x86_spi_dev_info lenovo_yt3_spi_devs[] __initconst = { > + { > + /* WM5102 codec */ > + .board_info = { > + .modalias = "wm5102", > + .platform_data = &lenovo_yt3_wm5102_pdata, > + .max_speed_hz = 5000000, > + }, > + .ctrl_path = "\\_SB_.PCI0.SPI1", > + .irq_data = { > + .type = X86_ACPI_IRQ_TYPE_GPIOINT, > + .chip = "INT33FF:00", > + .index = 91, > + .trigger = ACPI_LEVEL_SENSITIVE, > + .polarity = ACPI_ACTIVE_LOW, > + .con_id = "wm5102_irq", > + }, > + } > +}; > + > static int __init lenovo_yt3_init(void) > { > int ret; > @@ -720,14 +805,28 @@ static struct gpiod_lookup_table lenovo_yt3_hideep_gpios = { > }, > }; > > +static struct gpiod_lookup_table lenovo_yt3_wm5102_gpios = { > + .dev_id = "spi1.0", > + .table = { > + GPIO_LOOKUP("INT33FF:00", 75, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH), > + GPIO_LOOKUP("INT33FF:00", 81, "wlf,ldoena", GPIO_ACTIVE_HIGH), > + GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_HIGH), > + GPIO_LOOKUP("arizona", 2, "wlf,micd-pol", GPIO_ACTIVE_HIGH), > + { } > + }, > +}; > + > static struct gpiod_lookup_table * const lenovo_yt3_gpios[] = { > &lenovo_yt3_hideep_gpios, > + &lenovo_yt3_wm5102_gpios, > NULL > }; > > const struct x86_dev_info lenovo_yt3_info __initconst = { > .i2c_client_info = lenovo_yt3_i2c_clients, > .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients), > + .spi_dev_info = lenovo_yt3_spi_devs, > + .spi_dev_count = ARRAY_SIZE(lenovo_yt3_spi_devs), > .gpiod_lookup_tables = lenovo_yt3_gpios, > .init = lenovo_yt3_init, > };
On Sun, Oct 15, 2023 at 11:15:47AM +0200, Hans de Goede wrote: > On 10/14/23 22:53, Hans de Goede wrote: > > + .micbias={ > > + [0]={ /*MICBIAS1*/ Talking about spaces, how about .micbias = { [0] = { / *MICBIAS1 */ .mV = 2800 , .ext_cap = 1, .discharge = 1 , .soft_start = 0, .bypass = 0, > > + .mV =2800 , > > + .ext_cap=1, > > + .discharge =1 , > > + .soft_start =0, > > + .bypass =0, > > + }, > > Note I messed up the indentation here (spaces instead of tabs) > when copy pasting this from one terminal to another, > I'll go and fix this up locally.
Hi, On 10/16/23 10:13, Andy Shevchenko wrote: > On Sun, Oct 15, 2023 at 11:15:47AM +0200, Hans de Goede wrote: >> On 10/14/23 22:53, Hans de Goede wrote: > >>> + .micbias={ >>> + [0]={ /*MICBIAS1*/ > > Talking about spaces, how about > > .micbias = { > [0] = { / *MICBIAS1 */ > .mV = 2800 , > .ext_cap = 1, > .discharge = 1 , > .soft_start = 0, > .bypass = 0, Ack, I already have it like this locally now. Also using only tabs, there is plenty of width to just indent the "[0] = { ..." with a tab too. Regards, Hans
On Sat, Oct 14, 2023 at 10:53:14PM +0200, Hans de Goede wrote: > + .micd_force_micbias = 1, > + .micd_configs = lenovo_yt3_wm5102_micd_config, > + .num_micd_configs = ARRAY_SIZE(lenovo_yt3_wm5102_micd_config), > + .micbias={ > + [0]={ /*MICBIAS1*/ > + .mV =2800 , > + .ext_cap=1, The indentation of this section seems weird - .micbias is indented and the lack of spaces around =s is odd. There's also an extra space before the , consistently on the mV lines.
Hi, On 10/16/23 16:47, Mark Brown wrote: > On Sat, Oct 14, 2023 at 10:53:14PM +0200, Hans de Goede wrote: > >> + .micd_force_micbias = 1, >> + .micd_configs = lenovo_yt3_wm5102_micd_config, >> + .num_micd_configs = ARRAY_SIZE(lenovo_yt3_wm5102_micd_config), >> + .micbias={ >> + [0]={ /*MICBIAS1*/ >> + .mV =2800 , >> + .ext_cap=1, > > The indentation of this section seems weird - .micbias is indented and > the lack of spaces around =s is odd. There's also an extra space before > the , consistently on the mV lines. Right this is a copy and paste fail on my side, I've fixed this up locally already, so this will be fixed in the next version. Regards, Hans
diff --git a/drivers/platform/x86/x86-android-tablets/lenovo.c b/drivers/platform/x86/x86-android-tablets/lenovo.c index 585f10a57810..d5d815940ce1 100644 --- a/drivers/platform/x86/x86-android-tablets/lenovo.c +++ b/drivers/platform/x86/x86-android-tablets/lenovo.c @@ -12,6 +12,8 @@ #include <linux/efi.h> #include <linux/gpio/machine.h> +#include <linux/mfd/arizona/pdata.h> +#include <linux/mfd/arizona/registers.h> #include <linux/mfd/intel_soc_pmic.h> #include <linux/pinctrl/consumer.h> #include <linux/pinctrl/machine.h> @@ -677,6 +679,89 @@ static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = { } }; +/* + * The AOSP 3.5 mm Headset: Accessory Specification gives the following values: + * Function A Play/Pause: 0 ohm + * Function D Voice assistant: 135 ohm + * Function B Volume Up 240 ohm + * Function C Volume Down 470 ohm + * Minimum Mic DC resistance 1000 ohm + * Minimum Ear speaker impedance 16 ohm + * Note the first max value below must be less then the min. speaker impedance, + * to allow CTIA/OMTP detection to work. The other max values are the closest + * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances. + */ +static const struct arizona_micd_range arizona_micd_aosp_ranges[] = { + { .max = 11, .key = KEY_PLAYPAUSE }, + { .max = 186, .key = KEY_VOICECOMMAND }, + { .max = 348, .key = KEY_VOLUMEUP }, + { .max = 752, .key = KEY_VOLUMEDOWN }, +}; + +/* YT3 WM5102 arizona_micd_config comes from Android kernel sources */ +static struct arizona_micd_config lenovo_yt3_wm5102_micd_config[]={ + { 0, 1, 0 }, + { ARIZONA_ACCDET_SRC, 2, 1 }, +}; + +static struct arizona_pdata lenovo_yt3_wm5102_pdata = { + .irq_flags = IRQF_TRIGGER_LOW, + .micd_detect_debounce = 200, + .micd_ranges = arizona_micd_aosp_ranges, + .num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges), + .hpdet_channel = ARIZONA_ACCDET_MODE_HPL, + + /* Below settings come from Android kernel sources */ + .micd_bias_start_time = 1, + .micd_rate = 6, + .micd_force_micbias = 1, + .micd_configs = lenovo_yt3_wm5102_micd_config, + .num_micd_configs = ARRAY_SIZE(lenovo_yt3_wm5102_micd_config), + .micbias={ + [0]={ /*MICBIAS1*/ + .mV =2800 , + .ext_cap=1, + .discharge =1 , + .soft_start =0, + .bypass =0, + }, + [1]={ /*MICBIAS2*/ + .mV =2800 , + .ext_cap=1, + .discharge =1 , + .soft_start =0, + .bypass =0, + }, + [2]={ /*MICBIAS3*/ + .mV =2800 , + .ext_cap=1, + .discharge =1 , + .soft_start =0, + .bypass =0, + }, + }, +}; + +static const struct x86_spi_dev_info lenovo_yt3_spi_devs[] __initconst = { + { + /* WM5102 codec */ + .board_info = { + .modalias = "wm5102", + .platform_data = &lenovo_yt3_wm5102_pdata, + .max_speed_hz = 5000000, + }, + .ctrl_path = "\\_SB_.PCI0.SPI1", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_GPIOINT, + .chip = "INT33FF:00", + .index = 91, + .trigger = ACPI_LEVEL_SENSITIVE, + .polarity = ACPI_ACTIVE_LOW, + .con_id = "wm5102_irq", + }, + } +}; + static int __init lenovo_yt3_init(void) { int ret; @@ -720,14 +805,28 @@ static struct gpiod_lookup_table lenovo_yt3_hideep_gpios = { }, }; +static struct gpiod_lookup_table lenovo_yt3_wm5102_gpios = { + .dev_id = "spi1.0", + .table = { + GPIO_LOOKUP("INT33FF:00", 75, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("INT33FF:00", 81, "wlf,ldoena", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_HIGH), + GPIO_LOOKUP("arizona", 2, "wlf,micd-pol", GPIO_ACTIVE_HIGH), + { } + }, +}; + static struct gpiod_lookup_table * const lenovo_yt3_gpios[] = { &lenovo_yt3_hideep_gpios, + &lenovo_yt3_wm5102_gpios, NULL }; const struct x86_dev_info lenovo_yt3_info __initconst = { .i2c_client_info = lenovo_yt3_i2c_clients, .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients), + .spi_dev_info = lenovo_yt3_spi_devs, + .spi_dev_count = ARRAY_SIZE(lenovo_yt3_spi_devs), .gpiod_lookup_tables = lenovo_yt3_gpios, .init = lenovo_yt3_init, };
The SPI attached WM5102 codec on the Lenovo Yoga Tab 3 Pro YT3-X90F is not described in the ACPI tables. Add info to instantiate the SPI device for the codec manually. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- .../platform/x86/x86-android-tablets/lenovo.c | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+)