]> Git Repo - linux.git/blob - drivers/platform/x86/x86-android-tablets/lenovo.c
i2c: Fix conditional for substituting empty ACPI functions
[linux.git] / drivers / platform / x86 / x86-android-tablets / lenovo.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Board info for Lenovo X86 tablets which ship with Android as the factory image
4  * and which have broken DSDT tables. The factory kernels shipped on these
5  * devices typically have a bunch of things hardcoded, rather than specified
6  * in their DSDT.
7  *
8  * Copyright (C) 2021-2023 Hans de Goede <[email protected]>
9  */
10
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12
13 #include <linux/efi.h>
14 #include <linux/gpio/machine.h>
15 #include <linux/mfd/arizona/pdata.h>
16 #include <linux/mfd/arizona/registers.h>
17 #include <linux/mfd/intel_soc_pmic.h>
18 #include <linux/pinctrl/consumer.h>
19 #include <linux/pinctrl/machine.h>
20 #include <linux/platform_data/lp855x.h>
21 #include <linux/platform_device.h>
22 #include <linux/power/bq24190_charger.h>
23 #include <linux/reboot.h>
24 #include <linux/rmi.h>
25 #include <linux/spi/spi.h>
26
27 #include "shared-psy-info.h"
28 #include "x86-android-tablets.h"
29
30 /*
31  * Various Lenovo models use a TI LP8557 LED backlight controller with its PWM
32  * input connected to a PWM output coming from the LCD panel's controller.
33  * The Android kernels have a hack in the i915 driver to write a non-standard
34  * panel specific DSI register to set the duty-cycle of the LCD's PWM output.
35  *
36  * To avoid having to have a similar hack in the mainline kernel program the
37  * LP8557 to directly set the level and use the lp855x_bl driver for control.
38  *
39  * The LP8557 can either be configured to multiply its PWM input and
40  * the I2C register set level (requiring both to be at 100% for 100% output);
41  * or to only take the I2C register set level into account.
42  *
43  * Multiplying the 2 levels is useful because this will turn off the backlight
44  * when the panel goes off and turns off its PWM output.
45  *
46  * But on some models the panel's PWM output defaults to a duty-cycle of
47  * much less then 100%, severely limiting max brightness. In this case
48  * the LP8557 should be configured to only take the I2C register into
49  * account and the i915 driver must turn off the panel and the backlight
50  * separately using e.g. VBT MIPI sequences to turn off the backlight.
51  */
52 static struct lp855x_platform_data lenovo_lp8557_pwm_and_reg_pdata = {
53         .device_control = 0x86,
54         .initial_brightness = 128,
55 };
56
57 static struct lp855x_platform_data lenovo_lp8557_reg_only_pdata = {
58         .device_control = 0x85,
59         .initial_brightness = 128,
60 };
61
62 /* Lenovo Yoga Book X90F / X90L's Android factory img has everything hardcoded */
63
64 static const struct property_entry lenovo_yb1_x90_wacom_props[] = {
65         PROPERTY_ENTRY_U32("hid-descr-addr", 0x0001),
66         PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 150),
67         { }
68 };
69
70 static const struct software_node lenovo_yb1_x90_wacom_node = {
71         .properties = lenovo_yb1_x90_wacom_props,
72 };
73
74 /*
75  * The HiDeep IST940E touchscreen comes up in I2C-HID mode. The native protocol
76  * reports ABS_MT_PRESSURE and ABS_MT_TOUCH_MAJOR which are not reported in HID
77  * mode, so using native mode is preferred.
78  * It could alternatively be used in HID mode by changing the properties to:
79  *      PROPERTY_ENTRY_U32("hid-descr-addr", 0x0020),
80  *      PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
81  * and changing board_info.type to "hid-over-i2c".
82  */
83 static const struct property_entry lenovo_yb1_x90_hideep_ts_props[] = {
84         PROPERTY_ENTRY_U32("touchscreen-size-x", 1200),
85         PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
86         PROPERTY_ENTRY_U32("touchscreen-max-pressure", 16384),
87         PROPERTY_ENTRY_BOOL("hideep,force-native-protocol"),
88         { }
89 };
90
91 static const struct software_node lenovo_yb1_x90_hideep_ts_node = {
92         .properties = lenovo_yb1_x90_hideep_ts_props,
93 };
94
95 static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst = {
96         {
97                 /* BQ27542 fuel-gauge */
98                 .board_info = {
99                         .type = "bq27542",
100                         .addr = 0x55,
101                         .dev_name = "bq27542",
102                         .swnode = &fg_bq25890_supply_node,
103                 },
104                 .adapter_path = "\\_SB_.PCI0.I2C1",
105         }, {
106                 /* Goodix Touchscreen in keyboard half */
107                 .board_info = {
108                         .type = "GDIX1001:00",
109                         .addr = 0x14,
110                         .dev_name = "goodix_ts",
111                 },
112                 .adapter_path = "\\_SB_.PCI0.I2C2",
113                 .irq_data = {
114                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
115                         .chip = "INT33FF:01",
116                         .index = 56,
117                         .trigger = ACPI_EDGE_SENSITIVE,
118                         .polarity = ACPI_ACTIVE_LOW,
119                         .con_id = "goodix_ts_irq",
120                         .free_gpio = true,
121                 },
122         }, {
123                 /* Wacom Digitizer in keyboard half */
124                 .board_info = {
125                         .type = "hid-over-i2c",
126                         .addr = 0x09,
127                         .dev_name = "wacom",
128                         .swnode = &lenovo_yb1_x90_wacom_node,
129                 },
130                 .adapter_path = "\\_SB_.PCI0.I2C4",
131                 .irq_data = {
132                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
133                         .chip = "INT33FF:01",
134                         .index = 49,
135                         .trigger = ACPI_LEVEL_SENSITIVE,
136                         .polarity = ACPI_ACTIVE_LOW,
137                         .con_id = "wacom_irq",
138                 },
139         }, {
140                 /* LP8557 Backlight controller */
141                 .board_info = {
142                         .type = "lp8557",
143                         .addr = 0x2c,
144                         .dev_name = "lp8557",
145                         .platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
146                 },
147                 .adapter_path = "\\_SB_.PCI0.I2C4",
148         }, {
149                 /* HiDeep IST940E Touchscreen in display half */
150                 .board_info = {
151                         .type = "hideep_ts",
152                         .addr = 0x6c,
153                         .dev_name = "hideep_ts",
154                         .swnode = &lenovo_yb1_x90_hideep_ts_node,
155                 },
156                 .adapter_path = "\\_SB_.PCI0.I2C6",
157                 .irq_data = {
158                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
159                         .chip = "INT33FF:03",
160                         .index = 77,
161                         .trigger = ACPI_LEVEL_SENSITIVE,
162                         .polarity = ACPI_ACTIVE_LOW,
163                         .con_id = "hideep_ts_irq",
164                 },
165         },
166 };
167
168 static const struct platform_device_info lenovo_yb1_x90_pdevs[] __initconst = {
169         {
170                 .name = "yogabook-touch-kbd-digitizer-switch",
171                 .id = PLATFORM_DEVID_NONE,
172         },
173 };
174
175 /*
176  * DSDT says UART path is "\\_SB.PCIO.URT1" with a letter 'O' instead of
177  * the number '0' add the link manually.
178  */
179 static const struct x86_serdev_info lenovo_yb1_x90_serdevs[] __initconst = {
180         {
181                 .ctrl_hid = "8086228A",
182                 .ctrl_uid = "1",
183                 .ctrl_devname = "serial0",
184                 .serdev_hid = "BCM2E1A",
185         },
186 };
187
188 static const struct x86_gpio_button lenovo_yb1_x90_lid __initconst = {
189         .button = {
190                 .code = SW_LID,
191                 .active_low = true,
192                 .desc = "lid_sw",
193                 .type = EV_SW,
194                 .wakeup = true,
195                 .debounce_interval = 50,
196         },
197         .chip = "INT33FF:02",
198         .pin = 19,
199 };
200
201 static struct gpiod_lookup_table lenovo_yb1_x90_goodix_gpios = {
202         .dev_id = "i2c-goodix_ts",
203         .table = {
204                 GPIO_LOOKUP("INT33FF:01", 53, "reset", GPIO_ACTIVE_HIGH),
205                 GPIO_LOOKUP("INT33FF:01", 56, "irq", GPIO_ACTIVE_HIGH),
206                 { }
207         },
208 };
209
210 static struct gpiod_lookup_table lenovo_yb1_x90_hideep_gpios = {
211         .dev_id = "i2c-hideep_ts",
212         .table = {
213                 GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
214                 { }
215         },
216 };
217
218 static struct gpiod_lookup_table lenovo_yb1_x90_wacom_gpios = {
219         .dev_id = "i2c-wacom",
220         .table = {
221                 GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_LOW),
222                 { }
223         },
224 };
225
226 static struct gpiod_lookup_table * const lenovo_yb1_x90_gpios[] = {
227         &lenovo_yb1_x90_hideep_gpios,
228         &lenovo_yb1_x90_goodix_gpios,
229         &lenovo_yb1_x90_wacom_gpios,
230         NULL
231 };
232
233 static int __init lenovo_yb1_x90_init(struct device *dev)
234 {
235         /* Enable the regulators used by the touchscreens */
236
237         /* Vprog3B 3.0V used by the goodix touchscreen in the keyboard half */
238         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
239
240         /* Vprog4D 3.0V used by the HiDeep touchscreen in the display half */
241         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9f, 0x02, 0xff);
242
243         /* Vprog5A 1.8V used by the HiDeep touchscreen in the display half */
244         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
245
246         /* Vprog5B 1.8V used by the goodix touchscreen in the keyboard half */
247         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa1, 0x02, 0xff);
248
249         return 0;
250 }
251
252 const struct x86_dev_info lenovo_yogabook_x90_info __initconst = {
253         .i2c_client_info = lenovo_yb1_x90_i2c_clients,
254         .i2c_client_count = ARRAY_SIZE(lenovo_yb1_x90_i2c_clients),
255         .pdev_info = lenovo_yb1_x90_pdevs,
256         .pdev_count = ARRAY_SIZE(lenovo_yb1_x90_pdevs),
257         .serdev_info = lenovo_yb1_x90_serdevs,
258         .serdev_count = ARRAY_SIZE(lenovo_yb1_x90_serdevs),
259         .gpio_button = &lenovo_yb1_x90_lid,
260         .gpio_button_count = 1,
261         .gpiod_lookup_tables = lenovo_yb1_x90_gpios,
262         .init = lenovo_yb1_x90_init,
263 };
264
265 /* Lenovo Yoga Book X91F/L Windows tablet needs manual instantiation of the fg client */
266 static const struct x86_i2c_client_info lenovo_yogabook_x91_i2c_clients[] __initconst = {
267         {
268                 /* BQ27542 fuel-gauge */
269                 .board_info = {
270                         .type = "bq27542",
271                         .addr = 0x55,
272                         .dev_name = "bq27542",
273                         .swnode = &fg_bq25890_supply_node,
274                 },
275                 .adapter_path = "\\_SB_.PCI0.I2C1",
276         },
277 };
278
279 const struct x86_dev_info lenovo_yogabook_x91_info __initconst = {
280         .i2c_client_info = lenovo_yogabook_x91_i2c_clients,
281         .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x91_i2c_clients),
282 };
283
284 /* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */
285 static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
286         PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1),
287         PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
288         PROPERTY_ENTRY_BOOL("omit-battery-class"),
289         PROPERTY_ENTRY_BOOL("disable-reset"),
290         { }
291 };
292
293 static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
294         .properties = lenovo_yoga_tab2_830_1050_bq24190_props,
295 };
296
297 static const struct x86_gpio_button lenovo_yoga_tab2_830_1050_lid __initconst = {
298         .button = {
299                 .code = SW_LID,
300                 .active_low = true,
301                 .desc = "lid_sw",
302                 .type = EV_SW,
303                 .wakeup = true,
304                 .debounce_interval = 50,
305         },
306         .chip = "INT33FC:02",
307         .pin = 26,
308 };
309
310 /* This gets filled by lenovo_yoga_tab2_830_1050_init() */
311 static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
312
313 static struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initdata = {
314         {
315                 /*
316                  * This must be the first entry because lenovo_yoga_tab2_830_1050_init()
317                  * may update its swnode. LSM303DA accelerometer + magnetometer.
318                  */
319                 .board_info = {
320                         .type = "lsm303d",
321                         .addr = 0x1d,
322                         .dev_name = "lsm303d",
323                 },
324                 .adapter_path = "\\_SB_.I2C5",
325         }, {
326                 /* AL3320A ambient light sensor */
327                 .board_info = {
328                         .type = "al3320a",
329                         .addr = 0x1c,
330                         .dev_name = "al3320a",
331                 },
332                 .adapter_path = "\\_SB_.I2C5",
333         }, {
334                 /* bq24292i battery charger */
335                 .board_info = {
336                         .type = "bq24190",
337                         .addr = 0x6b,
338                         .dev_name = "bq24292i",
339                         .swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
340                         .platform_data = &bq24190_pdata,
341                 },
342                 .adapter_path = "\\_SB_.I2C1",
343                 .irq_data = {
344                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
345                         .chip = "INT33FC:02",
346                         .index = 2,
347                         .trigger = ACPI_EDGE_SENSITIVE,
348                         .polarity = ACPI_ACTIVE_HIGH,
349                         .con_id = "bq24292i_irq",
350                 },
351         }, {
352                 /* BQ27541 fuel-gauge */
353                 .board_info = {
354                         .type = "bq27541",
355                         .addr = 0x55,
356                         .dev_name = "bq27541",
357                         .swnode = &fg_bq24190_supply_node,
358                 },
359                 .adapter_path = "\\_SB_.I2C1",
360         }, {
361                 /* Synaptics RMI touchscreen */
362                 .board_info = {
363                         .type = "rmi4_i2c",
364                         .addr = 0x38,
365                         .dev_name = "rmi4_i2c",
366                         .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
367                 },
368                 .adapter_path = "\\_SB_.I2C6",
369                 .irq_data = {
370                         .type = X86_ACPI_IRQ_TYPE_APIC,
371                         .index = 0x45,
372                         .trigger = ACPI_EDGE_SENSITIVE,
373                         .polarity = ACPI_ACTIVE_HIGH,
374                 },
375         }, {
376                 /* LP8557 Backlight controller */
377                 .board_info = {
378                         .type = "lp8557",
379                         .addr = 0x2c,
380                         .dev_name = "lp8557",
381                         .platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
382                 },
383                 .adapter_path = "\\_SB_.I2C3",
384         },
385 };
386
387 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
388         .dev_id = "intel-int3496",
389         .table = {
390                 GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
391                 GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
392                 { }
393         },
394 };
395
396 #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
397
398 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
399         .dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
400         .table = {
401                 GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH),
402                 GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH),
403                 GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
404                 GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW),
405                 { }
406         },
407 };
408
409 static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
410         &lenovo_yoga_tab2_830_1050_int3496_gpios,
411         &lenovo_yoga_tab2_830_1050_codec_gpios,
412         NULL
413 };
414
415 static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev);
416 static void lenovo_yoga_tab2_830_1050_exit(void);
417
418 const struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initconst = {
419         .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
420         .i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients),
421         .pdev_info = int3496_pdevs,
422         .pdev_count = 1,
423         .gpio_button = &lenovo_yoga_tab2_830_1050_lid,
424         .gpio_button_count = 1,
425         .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
426         .bat_swnode = &generic_lipo_hv_4v35_battery_node,
427         .modules = bq24190_modules,
428         .init = lenovo_yoga_tab2_830_1050_init,
429         .exit = lenovo_yoga_tab2_830_1050_exit,
430 };
431
432 /*
433  * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
434  * mainboard, but the 830 uses a portrait LCD panel with a landscape touchscreen,
435  * requiring the touchscreen driver to adjust the touch-coords to match the LCD.
436  * And requiring the accelerometer to have a mount-matrix set to correct for
437  * the 90° rotation of the LCD vs the frame.
438  */
439 static const char * const lenovo_yoga_tab2_830_lms303d_mount_matrix[] = {
440         "0", "1", "0",
441         "-1", "0", "0",
442         "0", "0", "1"
443 };
444
445 static const struct property_entry lenovo_yoga_tab2_830_lms303d_props[] = {
446         PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_830_lms303d_mount_matrix),
447         { }
448 };
449
450 static const struct software_node lenovo_yoga_tab2_830_lms303d_node = {
451         .properties = lenovo_yoga_tab2_830_lms303d_props,
452 };
453
454 static int __init lenovo_yoga_tab2_830_1050_init_touchscreen(void)
455 {
456         struct gpio_desc *gpiod;
457         int ret;
458
459         /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
460         ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, "yoga_bootstrap",
461                                            false, GPIOD_ASIS, &gpiod);
462         if (ret)
463                 return ret;
464
465         ret = gpiod_get_value_cansleep(gpiod);
466         if (ret) {
467                 pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
468         } else {
469                 pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
470                 lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
471                 lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
472                 lenovo_yoga_tab2_830_1050_i2c_clients[0].board_info.swnode =
473                         &lenovo_yoga_tab2_830_lms303d_node;
474         }
475
476         return 0;
477 }
478
479 /* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
480 static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
481         PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
482                           "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
483
484 static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
485 static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
486
487 static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
488 {
489         struct device *codec_dev;
490         struct pinctrl *pinctrl;
491         int ret;
492
493         codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
494                                             LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
495         if (!codec_dev) {
496                 pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
497                 return -ENODEV;
498         }
499
500         ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
501         if (ret)
502                 goto err_put_device;
503
504         pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
505         if (IS_ERR(pinctrl)) {
506                 ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
507                 goto err_unregister_mappings;
508         }
509
510         /* We're done with the codec_dev now */
511         put_device(codec_dev);
512
513         lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
514         return 0;
515
516 err_unregister_mappings:
517         pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
518 err_put_device:
519         put_device(codec_dev);
520         return ret;
521 }
522
523 /*
524  * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off
525  * gets used as pm_power_off handler. This causes "poweroff" on these tablets
526  * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice*
527  * followed by a normal 3 second press to recover. Avoid this by doing an EFI
528  * poweroff instead.
529  */
530 static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
531 {
532         efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
533
534         return NOTIFY_DONE;
535 }
536
537 static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev)
538 {
539         int ret;
540
541         ret = lenovo_yoga_tab2_830_1050_init_touchscreen();
542         if (ret)
543                 return ret;
544
545         ret = lenovo_yoga_tab2_830_1050_init_codec();
546         if (ret)
547                 return ret;
548
549         /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
550         lenovo_yoga_tab2_830_1050_sys_off_handler =
551                 register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
552                                          lenovo_yoga_tab2_830_1050_power_off, NULL);
553         if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
554                 return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
555
556         return 0;
557 }
558
559 static void lenovo_yoga_tab2_830_1050_exit(void)
560 {
561         unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
562
563         if (lenovo_yoga_tab2_830_1050_codec_pinctrl) {
564                 pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
565                 pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
566         }
567 }
568
569 /*
570  * Lenovo Yoga Tablet 2 Pro 1380F/L
571  *
572  * The Lenovo Yoga Tablet 2 Pro 1380F/L mostly has the same design as the 830F/L
573  * and the 1050F/L so this re-uses some of the handling for that from above.
574  */
575 static const char * const lc824206xa_chg_det_psy[] = { "lc824206xa-charger-detect" };
576
577 static const struct property_entry lenovo_yoga_tab2_1380_bq24190_props[] = {
578         PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lc824206xa_chg_det_psy),
579         PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
580         PROPERTY_ENTRY_BOOL("omit-battery-class"),
581         PROPERTY_ENTRY_BOOL("disable-reset"),
582         { }
583 };
584
585 static const struct software_node lenovo_yoga_tab2_1380_bq24190_node = {
586         .properties = lenovo_yoga_tab2_1380_bq24190_props,
587 };
588
589 /* For enabling the bq24190 5V boost based on id-pin */
590 static struct regulator_consumer_supply lc824206xa_consumer = {
591         .supply = "vbus",
592         .dev_name = "i2c-lc824206xa",
593 };
594
595 static const struct regulator_init_data lenovo_yoga_tab2_1380_bq24190_vbus_init_data = {
596         .constraints = {
597                 .name = "bq24190_vbus",
598                 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
599         },
600         .consumer_supplies = &lc824206xa_consumer,
601         .num_consumer_supplies = 1,
602 };
603
604 struct bq24190_platform_data lenovo_yoga_tab2_1380_bq24190_pdata = {
605         .regulator_init_data = &lenovo_yoga_tab2_1380_bq24190_vbus_init_data,
606 };
607
608 static const struct property_entry lenovo_yoga_tab2_1380_lc824206xa_props[] = {
609         PROPERTY_ENTRY_BOOL("onnn,enable-miclr-for-dcp"),
610         { }
611 };
612
613 static const struct software_node lenovo_yoga_tab2_1380_lc824206xa_node = {
614         .properties = lenovo_yoga_tab2_1380_lc824206xa_props,
615 };
616
617 static const char * const lenovo_yoga_tab2_1380_lms303d_mount_matrix[] = {
618         "0", "-1", "0",
619         "-1", "0", "0",
620         "0", "0", "1"
621 };
622
623 static const struct property_entry lenovo_yoga_tab2_1380_lms303d_props[] = {
624         PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_1380_lms303d_mount_matrix),
625         { }
626 };
627
628 static const struct software_node lenovo_yoga_tab2_1380_lms303d_node = {
629         .properties = lenovo_yoga_tab2_1380_lms303d_props,
630 };
631
632 static const struct x86_i2c_client_info lenovo_yoga_tab2_1380_i2c_clients[] __initconst = {
633         {
634                 /* BQ27541 fuel-gauge */
635                 .board_info = {
636                         .type = "bq27541",
637                         .addr = 0x55,
638                         .dev_name = "bq27541",
639                         .swnode = &fg_bq24190_supply_node,
640                 },
641                 .adapter_path = "\\_SB_.I2C1",
642         }, {
643                 /* bq24292i battery charger */
644                 .board_info = {
645                         .type = "bq24190",
646                         .addr = 0x6b,
647                         .dev_name = "bq24292i",
648                         .swnode = &lenovo_yoga_tab2_1380_bq24190_node,
649                         .platform_data = &lenovo_yoga_tab2_1380_bq24190_pdata,
650                 },
651                 .adapter_path = "\\_SB_.I2C1",
652                 .irq_data = {
653                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
654                         .chip = "INT33FC:02",
655                         .index = 2,
656                         .trigger = ACPI_EDGE_SENSITIVE,
657                         .polarity = ACPI_ACTIVE_HIGH,
658                         .con_id = "bq24292i_irq",
659                 },
660         }, {
661                 /* LP8557 Backlight controller */
662                 .board_info = {
663                         .type = "lp8557",
664                         .addr = 0x2c,
665                         .dev_name = "lp8557",
666                         .platform_data = &lenovo_lp8557_pwm_and_reg_pdata,
667                 },
668                 .adapter_path = "\\_SB_.I2C3",
669         }, {
670                 /* LC824206XA Micro USB Switch */
671                 .board_info = {
672                         .type = "lc824206xa",
673                         .addr = 0x48,
674                         .dev_name = "lc824206xa",
675                         .swnode = &lenovo_yoga_tab2_1380_lc824206xa_node,
676                 },
677                 .adapter_path = "\\_SB_.I2C3",
678                 .irq_data = {
679                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
680                         .chip = "INT33FC:02",
681                         .index = 1,
682                         .trigger = ACPI_LEVEL_SENSITIVE,
683                         .polarity = ACPI_ACTIVE_LOW,
684                         .con_id = "lc824206xa_irq",
685                 },
686         }, {
687                 /* AL3320A ambient light sensor */
688                 .board_info = {
689                         .type = "al3320a",
690                         .addr = 0x1c,
691                         .dev_name = "al3320a",
692                 },
693                 .adapter_path = "\\_SB_.I2C5",
694         }, {
695                 /* LSM303DA accelerometer + magnetometer */
696                 .board_info = {
697                         .type = "lsm303d",
698                         .addr = 0x1d,
699                         .dev_name = "lsm303d",
700                         .swnode = &lenovo_yoga_tab2_1380_lms303d_node,
701                 },
702                 .adapter_path = "\\_SB_.I2C5",
703         }, {
704                 /* Synaptics RMI touchscreen */
705                 .board_info = {
706                         .type = "rmi4_i2c",
707                         .addr = 0x38,
708                         .dev_name = "rmi4_i2c",
709                         .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
710                 },
711                 .adapter_path = "\\_SB_.I2C6",
712                 .irq_data = {
713                         .type = X86_ACPI_IRQ_TYPE_APIC,
714                         .index = 0x45,
715                         .trigger = ACPI_EDGE_SENSITIVE,
716                         .polarity = ACPI_ACTIVE_HIGH,
717                 },
718         }
719 };
720
721 static const struct platform_device_info lenovo_yoga_tab2_1380_pdevs[] __initconst = {
722         {
723                 /* For the Tablet 2 Pro 1380's custom fast charging driver */
724                 .name = "lenovo-yoga-tab2-pro-1380-fastcharger",
725                 .id = PLATFORM_DEVID_NONE,
726         },
727 };
728
729 const char * const lenovo_yoga_tab2_1380_modules[] __initconst = {
730         "bq24190_charger",            /* For the Vbus regulator for lc824206xa */
731         NULL
732 };
733
734 static int __init lenovo_yoga_tab2_1380_init(struct device *dev)
735 {
736         int ret;
737
738         /* To verify that the DMI matching works vs the 830 / 1050 models */
739         pr_info("detected Lenovo Yoga Tablet 2 Pro 1380F/L\n");
740
741         ret = lenovo_yoga_tab2_830_1050_init_codec();
742         if (ret)
743                 return ret;
744
745         /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
746         lenovo_yoga_tab2_830_1050_sys_off_handler =
747                 register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
748                                          lenovo_yoga_tab2_830_1050_power_off, NULL);
749         if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
750                 return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
751
752         return 0;
753 }
754
755 static struct gpiod_lookup_table lenovo_yoga_tab2_1380_fc_gpios = {
756         .dev_id = "serial0-0",
757         .table = {
758                 GPIO_LOOKUP("INT33FC:00", 57, "uart3_txd", GPIO_ACTIVE_HIGH),
759                 GPIO_LOOKUP("INT33FC:00", 61, "uart3_rxd", GPIO_ACTIVE_HIGH),
760                 { }
761         },
762 };
763
764 static struct gpiod_lookup_table * const lenovo_yoga_tab2_1380_gpios[] = {
765         &lenovo_yoga_tab2_830_1050_codec_gpios,
766         &lenovo_yoga_tab2_1380_fc_gpios,
767         NULL
768 };
769
770 const struct x86_dev_info lenovo_yoga_tab2_1380_info __initconst = {
771         .i2c_client_info = lenovo_yoga_tab2_1380_i2c_clients,
772         .i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_i2c_clients),
773         .pdev_info = lenovo_yoga_tab2_1380_pdevs,
774         .pdev_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_pdevs),
775         .gpio_button = &lenovo_yoga_tab2_830_1050_lid,
776         .gpio_button_count = 1,
777         .gpiod_lookup_tables = lenovo_yoga_tab2_1380_gpios,
778         .bat_swnode = &generic_lipo_hv_4v35_battery_node,
779         .modules = lenovo_yoga_tab2_1380_modules,
780         .init = lenovo_yoga_tab2_1380_init,
781         .exit = lenovo_yoga_tab2_830_1050_exit,
782 };
783
784 /* Lenovo Yoga Tab 3 Pro YT3-X90F */
785
786 /*
787  * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers,
788  * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c.
789  */
790 static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };
791 static const char * const bq25890_1_psy[] = { "bq25890-charger-1" };
792
793 static const struct property_entry fg_bq25890_1_supply_props[] = {
794         PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),
795         { }
796 };
797
798 static const struct software_node fg_bq25890_1_supply_node = {
799         .properties = fg_bq25890_1_supply_props,
800 };
801
802 /* bq25892 charger settings for the flat lipo battery behind the screen */
803 static const struct property_entry lenovo_yt3_bq25892_0_props[] = {
804         PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers),
805         PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40),
806         PROPERTY_ENTRY_BOOL("linux,skip-reset"),
807         /* Values taken from Android Factory Image */
808         PROPERTY_ENTRY_U32("ti,charge-current", 2048000),
809         PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
810         PROPERTY_ENTRY_U32("ti,termination-current", 128000),
811         PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
812         PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000),
813         PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
814         PROPERTY_ENTRY_U32("ti,boost-max-current", 500000),
815         PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
816         { }
817 };
818
819 static const struct software_node lenovo_yt3_bq25892_0_node = {
820         .properties = lenovo_yt3_bq25892_0_props,
821 };
822
823 static const struct property_entry lenovo_yt3_hideep_ts_props[] = {
824         PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
825         PROPERTY_ENTRY_U32("touchscreen-size-y", 2560),
826         PROPERTY_ENTRY_U32("touchscreen-max-pressure", 255),
827         { }
828 };
829
830 static const struct software_node lenovo_yt3_hideep_ts_node = {
831         .properties = lenovo_yt3_hideep_ts_props,
832 };
833
834 static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
835         {
836                 /* bq27500 fuel-gauge for the flat lipo battery behind the screen */
837                 .board_info = {
838                         .type = "bq27500",
839                         .addr = 0x55,
840                         .dev_name = "bq27500_0",
841                         .swnode = &fg_bq25890_supply_node,
842                 },
843                 .adapter_path = "\\_SB_.PCI0.I2C1",
844         }, {
845                 /* bq25892 charger for the flat lipo battery behind the screen */
846                 .board_info = {
847                         .type = "bq25892",
848                         .addr = 0x6b,
849                         .dev_name = "bq25892_0",
850                         .swnode = &lenovo_yt3_bq25892_0_node,
851                 },
852                 .adapter_path = "\\_SB_.PCI0.I2C1",
853                 .irq_data = {
854                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
855                         .chip = "INT33FF:01",
856                         .index = 5,
857                         .trigger = ACPI_EDGE_SENSITIVE,
858                         .polarity = ACPI_ACTIVE_LOW,
859                         .con_id = "bq25892_0_irq",
860                 },
861         }, {
862                 /* bq27500 fuel-gauge for the round li-ion cells in the hinge */
863                 .board_info = {
864                         .type = "bq27500",
865                         .addr = 0x55,
866                         .dev_name = "bq27500_1",
867                         .swnode = &fg_bq25890_1_supply_node,
868                 },
869                 .adapter_path = "\\_SB_.PCI0.I2C2",
870         }, {
871                 /* HiDeep IST520E Touchscreen */
872                 .board_info = {
873                         .type = "hideep_ts",
874                         .addr = 0x6c,
875                         .dev_name = "hideep_ts",
876                         .swnode = &lenovo_yt3_hideep_ts_node,
877                 },
878                 .adapter_path = "\\_SB_.PCI0.I2C6",
879                 .irq_data = {
880                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
881                         .chip = "INT33FF:03",
882                         .index = 77,
883                         .trigger = ACPI_LEVEL_SENSITIVE,
884                         .polarity = ACPI_ACTIVE_LOW,
885                         .con_id = "hideep_ts_irq",
886                 },
887         }, {
888                 /* LP8557 Backlight controller */
889                 .board_info = {
890                         .type = "lp8557",
891                         .addr = 0x2c,
892                         .dev_name = "lp8557",
893                         .platform_data = &lenovo_lp8557_reg_only_pdata,
894                 },
895                 .adapter_path = "\\_SB_.PCI0.I2C1",
896         }
897 };
898
899 /*
900  * The AOSP 3.5 mm Headset: Accessory Specification gives the following values:
901  * Function A Play/Pause:           0 ohm
902  * Function D Voice assistant:    135 ohm
903  * Function B Volume Up           240 ohm
904  * Function C Volume Down         470 ohm
905  * Minimum Mic DC resistance     1000 ohm
906  * Minimum Ear speaker impedance   16 ohm
907  * Note the first max value below must be less then the min. speaker impedance,
908  * to allow CTIA/OMTP detection to work. The other max values are the closest
909  * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances.
910  */
911 static const struct arizona_micd_range arizona_micd_aosp_ranges[] = {
912         { .max =  11, .key = KEY_PLAYPAUSE },
913         { .max = 186, .key = KEY_VOICECOMMAND },
914         { .max = 348, .key = KEY_VOLUMEUP },
915         { .max = 752, .key = KEY_VOLUMEDOWN },
916 };
917
918 /* YT3 WM5102 arizona_micd_config comes from Android kernel sources */
919 static struct arizona_micd_config lenovo_yt3_wm5102_micd_config[] = {
920         { 0, 1, 0 },
921         { ARIZONA_ACCDET_SRC, 2, 1 },
922 };
923
924 static struct arizona_pdata lenovo_yt3_wm5102_pdata = {
925         .irq_flags = IRQF_TRIGGER_LOW,
926         .micd_detect_debounce = 200,
927         .micd_ranges = arizona_micd_aosp_ranges,
928         .num_micd_ranges = ARRAY_SIZE(arizona_micd_aosp_ranges),
929         .hpdet_channel = ARIZONA_ACCDET_MODE_HPL,
930
931         /* Below settings come from Android kernel sources */
932         .micd_bias_start_time = 1,
933         .micd_rate = 6,
934         .micd_configs = lenovo_yt3_wm5102_micd_config,
935         .num_micd_configs = ARRAY_SIZE(lenovo_yt3_wm5102_micd_config),
936         .micbias = {
937                 [0] = { /* MICBIAS1 */
938                         .mV = 2800,
939                         .ext_cap = 1,
940                         .discharge = 1,
941                         .soft_start = 0,
942                         .bypass = 0,
943                 },
944                 [1] = { /* MICBIAS2 */
945                         .mV = 2800,
946                         .ext_cap = 1,
947                         .discharge = 1,
948                         .soft_start = 0,
949                         .bypass = 0,
950                 },
951                 [2] = { /* MICBIAS2 */
952                         .mV = 2800,
953                         .ext_cap = 1,
954                         .discharge = 1,
955                         .soft_start = 0,
956                         .bypass = 0,
957                 },
958         },
959 };
960
961 static const struct x86_spi_dev_info lenovo_yt3_spi_devs[] __initconst = {
962         {
963                 /* WM5102 codec */
964                 .board_info = {
965                         .modalias = "wm5102",
966                         .platform_data = &lenovo_yt3_wm5102_pdata,
967                         .max_speed_hz = 5000000,
968                 },
969                 .ctrl_path = "\\_SB_.PCI0.SPI1",
970                 .irq_data = {
971                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
972                         .chip = "INT33FF:00",
973                         .index = 91,
974                         .trigger = ACPI_LEVEL_SENSITIVE,
975                         .polarity = ACPI_ACTIVE_LOW,
976                         .con_id = "wm5102_irq",
977                 },
978         }
979 };
980
981 static int __init lenovo_yt3_init(struct device *dev)
982 {
983         int ret;
984
985         /*
986          * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins
987          * connected to GPIOs, rather then having them hardwired to the correct
988          * values as is normally done.
989          *
990          * The bq25890_charger driver controls these through I2C, but this only
991          * works if not overridden by the pins. Set these pins here:
992          * 1. Set /CE to 1 to allow charging.
993          * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of
994          *    the main "bq25892_1" charger is used when necessary.
995          */
996
997         /* /CE pin */
998         ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, "bq25892_0_ce",
999                                            true, GPIOD_OUT_HIGH, NULL);
1000         if (ret < 0)
1001                 return ret;
1002
1003         /* OTG pin */
1004         ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, "bq25892_0_otg",
1005                                            false, GPIOD_OUT_LOW, NULL);
1006         if (ret < 0)
1007                 return ret;
1008
1009         /* Enable the regulators used by the touchscreen */
1010         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
1011         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
1012
1013         return 0;
1014 }
1015
1016 static struct gpiod_lookup_table lenovo_yt3_hideep_gpios = {
1017         .dev_id = "i2c-hideep_ts",
1018         .table = {
1019                 GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
1020                 { }
1021         },
1022 };
1023
1024 static struct gpiod_lookup_table lenovo_yt3_wm5102_gpios = {
1025         .dev_id = "spi1.0",
1026         .table = {
1027                 GPIO_LOOKUP("INT33FF:00", 75, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
1028                 GPIO_LOOKUP("INT33FF:00", 81, "wlf,ldoena", GPIO_ACTIVE_HIGH),
1029                 GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_HIGH),
1030                 GPIO_LOOKUP("arizona", 2, "wlf,micd-pol", GPIO_ACTIVE_HIGH),
1031                 { }
1032         },
1033 };
1034
1035 static struct gpiod_lookup_table * const lenovo_yt3_gpios[] = {
1036         &lenovo_yt3_hideep_gpios,
1037         &lenovo_yt3_wm5102_gpios,
1038         NULL
1039 };
1040
1041 const struct x86_dev_info lenovo_yt3_info __initconst = {
1042         .i2c_client_info = lenovo_yt3_i2c_clients,
1043         .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients),
1044         .spi_dev_info = lenovo_yt3_spi_devs,
1045         .spi_dev_count = ARRAY_SIZE(lenovo_yt3_spi_devs),
1046         .gpiod_lookup_tables = lenovo_yt3_gpios,
1047         .init = lenovo_yt3_init,
1048 };
This page took 0.108406 seconds and 4 git commands to generate.