]> Git Repo - linux.git/blob - drivers/platform/x86/x86-android-tablets/lenovo.c
Merge tag 'amd-drm-next-6.5-2023-06-09' of https://gitlab.freedesktop.org/agd5f/linux...
[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/intel_soc_pmic.h>
16 #include <linux/pinctrl/consumer.h>
17 #include <linux/pinctrl/machine.h>
18 #include <linux/platform_data/lp855x.h>
19 #include <linux/platform_device.h>
20 #include <linux/reboot.h>
21 #include <linux/rmi.h>
22 #include <linux/spi/spi.h>
23
24 #include "shared-psy-info.h"
25 #include "x86-android-tablets.h"
26
27 /*
28  * Various Lenovo models use a TI LP8557 LED backlight controller with its PWM
29  * input connected to a PWM output coming from the LCD panel's controller.
30  * The Android kernels have a hack in the i915 driver to write a non-standard
31  * panel specific DSI register to set the duty-cycle of the LCD's PWM output.
32  *
33  * To avoid having to have a similar hack in the mainline kernel program the
34  * LP8557 to directly set the level and use the lp855x_bl driver for control.
35  */
36 static struct lp855x_platform_data lenovo_lp8557_pdata = {
37         .device_control = 0x86,
38         .initial_brightness = 128,
39 };
40
41 /* Lenovo Yoga Book X90F / X90L's Android factory img has everything hardcoded */
42
43 static const struct property_entry lenovo_yb1_x90_wacom_props[] = {
44         PROPERTY_ENTRY_U32("hid-descr-addr", 0x0001),
45         PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 150),
46         { }
47 };
48
49 static const struct software_node lenovo_yb1_x90_wacom_node = {
50         .properties = lenovo_yb1_x90_wacom_props,
51 };
52
53 /*
54  * The HiDeep IST940E touchscreen comes up in I2C-HID mode. The native protocol
55  * reports ABS_MT_PRESSURE and ABS_MT_TOUCH_MAJOR which are not reported in HID
56  * mode, so using native mode is preferred.
57  * It could alternatively be used in HID mode by changing the properties to:
58  *      PROPERTY_ENTRY_U32("hid-descr-addr", 0x0020),
59  *      PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120),
60  * and changing board_info.type to "hid-over-i2c".
61  */
62 static const struct property_entry lenovo_yb1_x90_hideep_ts_props[] = {
63         PROPERTY_ENTRY_U32("touchscreen-size-x", 1200),
64         PROPERTY_ENTRY_U32("touchscreen-size-y", 1920),
65         PROPERTY_ENTRY_U32("touchscreen-max-pressure", 16384),
66         PROPERTY_ENTRY_BOOL("hideep,force-native-protocol"),
67         { }
68 };
69
70 static const struct software_node lenovo_yb1_x90_hideep_ts_node = {
71         .properties = lenovo_yb1_x90_hideep_ts_props,
72 };
73
74 static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst = {
75         {
76                 /* BQ27542 fuel-gauge */
77                 .board_info = {
78                         .type = "bq27542",
79                         .addr = 0x55,
80                         .dev_name = "bq27542",
81                         .swnode = &fg_bq25890_supply_node,
82                 },
83                 .adapter_path = "\\_SB_.PCI0.I2C1",
84         }, {
85                 /* Goodix Touchscreen in keyboard half */
86                 .board_info = {
87                         .type = "GDIX1001:00",
88                         .addr = 0x14,
89                         .dev_name = "goodix_ts",
90                 },
91                 .adapter_path = "\\_SB_.PCI0.I2C2",
92                 .irq_data = {
93                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
94                         .chip = "INT33FF:01",
95                         .index = 56,
96                         .trigger = ACPI_EDGE_SENSITIVE,
97                         .polarity = ACPI_ACTIVE_LOW,
98                 },
99         }, {
100                 /* Wacom Digitizer in keyboard half */
101                 .board_info = {
102                         .type = "hid-over-i2c",
103                         .addr = 0x09,
104                         .dev_name = "wacom",
105                         .swnode = &lenovo_yb1_x90_wacom_node,
106                 },
107                 .adapter_path = "\\_SB_.PCI0.I2C4",
108                 .irq_data = {
109                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
110                         .chip = "INT33FF:01",
111                         .index = 49,
112                         .trigger = ACPI_LEVEL_SENSITIVE,
113                         .polarity = ACPI_ACTIVE_LOW,
114                 },
115         }, {
116                 /* LP8557 Backlight controller */
117                 .board_info = {
118                         .type = "lp8557",
119                         .addr = 0x2c,
120                         .dev_name = "lp8557",
121                         .platform_data = &lenovo_lp8557_pdata,
122                 },
123                 .adapter_path = "\\_SB_.PCI0.I2C4",
124         }, {
125                 /* HiDeep IST940E Touchscreen in display half */
126                 .board_info = {
127                         .type = "hideep_ts",
128                         .addr = 0x6c,
129                         .dev_name = "hideep_ts",
130                         .swnode = &lenovo_yb1_x90_hideep_ts_node,
131                 },
132                 .adapter_path = "\\_SB_.PCI0.I2C6",
133                 .irq_data = {
134                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
135                         .chip = "INT33FF:03",
136                         .index = 77,
137                         .trigger = ACPI_LEVEL_SENSITIVE,
138                         .polarity = ACPI_ACTIVE_LOW,
139                 },
140         },
141 };
142
143 static const struct platform_device_info lenovo_yb1_x90_pdevs[] __initconst = {
144         {
145                 .name = "yogabook-touch-kbd-digitizer-switch",
146                 .id = PLATFORM_DEVID_NONE,
147         },
148 };
149
150 static struct gpiod_lookup_table lenovo_yb1_x90_goodix_gpios = {
151         .dev_id = "i2c-goodix_ts",
152         .table = {
153                 GPIO_LOOKUP("INT33FF:01", 53, "reset", GPIO_ACTIVE_HIGH),
154                 GPIO_LOOKUP("INT33FF:01", 56, "irq", GPIO_ACTIVE_HIGH),
155                 { }
156         },
157 };
158
159 static struct gpiod_lookup_table lenovo_yb1_x90_hideep_gpios = {
160         .dev_id = "i2c-hideep_ts",
161         .table = {
162                 GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
163                 { }
164         },
165 };
166
167 static struct gpiod_lookup_table lenovo_yb1_x90_wacom_gpios = {
168         .dev_id = "i2c-wacom",
169         .table = {
170                 GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_LOW),
171                 { }
172         },
173 };
174
175 static struct gpiod_lookup_table * const lenovo_yb1_x90_gpios[] = {
176         &lenovo_yb1_x90_hideep_gpios,
177         &lenovo_yb1_x90_goodix_gpios,
178         &lenovo_yb1_x90_wacom_gpios,
179         NULL
180 };
181
182 static int __init lenovo_yb1_x90_init(void)
183 {
184         /* Enable the regulators used by the touchscreens */
185
186         /* Vprog3B 3.0V used by the goodix touchscreen in the keyboard half */
187         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
188
189         /* Vprog4D 3.0V used by the HiDeep touchscreen in the display half */
190         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9f, 0x02, 0xff);
191
192         /* Vprog5A 1.8V used by the HiDeep touchscreen in the display half */
193         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
194
195         /* Vprog5B 1.8V used by the goodix touchscreen in the keyboard half */
196         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa1, 0x02, 0xff);
197
198         return 0;
199 }
200
201 const struct x86_dev_info lenovo_yogabook_x90_info __initconst = {
202         .i2c_client_info = lenovo_yb1_x90_i2c_clients,
203         .i2c_client_count = ARRAY_SIZE(lenovo_yb1_x90_i2c_clients),
204         .pdev_info = lenovo_yb1_x90_pdevs,
205         .pdev_count = ARRAY_SIZE(lenovo_yb1_x90_pdevs),
206         .gpiod_lookup_tables = lenovo_yb1_x90_gpios,
207         .init = lenovo_yb1_x90_init,
208 };
209
210 /* Lenovo Yoga Book X91F/L Windows tablet needs manual instantiation of the fg client */
211 static const struct x86_i2c_client_info lenovo_yogabook_x91_i2c_clients[] __initconst = {
212         {
213                 /* BQ27542 fuel-gauge */
214                 .board_info = {
215                         .type = "bq27542",
216                         .addr = 0x55,
217                         .dev_name = "bq27542",
218                         .swnode = &fg_bq25890_supply_node,
219                 },
220                 .adapter_path = "\\_SB_.PCI0.I2C1",
221         },
222 };
223
224 const struct x86_dev_info lenovo_yogabook_x91_info __initconst = {
225         .i2c_client_info = lenovo_yogabook_x91_i2c_clients,
226         .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x91_i2c_clients),
227 };
228
229 /* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */
230 static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = {
231         PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1),
232         PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node),
233         PROPERTY_ENTRY_BOOL("omit-battery-class"),
234         PROPERTY_ENTRY_BOOL("disable-reset"),
235         { }
236 };
237
238 static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = {
239         .properties = lenovo_yoga_tab2_830_1050_bq24190_props,
240 };
241
242 static struct x86_gpio_button lenovo_yoga_tab2_830_1050_lid = {
243         .button = {
244                 .code = SW_LID,
245                 .active_low = true,
246                 .desc = "lid_sw",
247                 .type = EV_SW,
248                 .wakeup = true,
249                 .debounce_interval = 50,
250         },
251         .chip = "INT33FC:02",
252         .pin = 26,
253 };
254
255 /* This gets filled by lenovo_yoga_tab2_830_1050_init() */
256 static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { };
257
258 static struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initdata = {
259         {
260                 /*
261                  * This must be the first entry because lenovo_yoga_tab2_830_1050_init()
262                  * may update its swnode. LSM303DA accelerometer + magnetometer.
263                  */
264                 .board_info = {
265                         .type = "lsm303d",
266                         .addr = 0x1d,
267                         .dev_name = "lsm303d",
268                 },
269                 .adapter_path = "\\_SB_.I2C5",
270         }, {
271                 /* bq24292i battery charger */
272                 .board_info = {
273                         .type = "bq24190",
274                         .addr = 0x6b,
275                         .dev_name = "bq24292i",
276                         .swnode = &lenovo_yoga_tab2_830_1050_bq24190_node,
277                         .platform_data = &bq24190_pdata,
278                 },
279                 .adapter_path = "\\_SB_.I2C1",
280                 .irq_data = {
281                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
282                         .chip = "INT33FC:02",
283                         .index = 2,
284                         .trigger = ACPI_EDGE_SENSITIVE,
285                         .polarity = ACPI_ACTIVE_HIGH,
286                 },
287         }, {
288                 /* BQ27541 fuel-gauge */
289                 .board_info = {
290                         .type = "bq27541",
291                         .addr = 0x55,
292                         .dev_name = "bq27541",
293                         .swnode = &fg_bq24190_supply_node,
294                 },
295                 .adapter_path = "\\_SB_.I2C1",
296         }, {
297                 /* Synaptics RMI touchscreen */
298                 .board_info = {
299                         .type = "rmi4_i2c",
300                         .addr = 0x38,
301                         .dev_name = "rmi4_i2c",
302                         .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata,
303                 },
304                 .adapter_path = "\\_SB_.I2C6",
305                 .irq_data = {
306                         .type = X86_ACPI_IRQ_TYPE_APIC,
307                         .index = 0x45,
308                         .trigger = ACPI_EDGE_SENSITIVE,
309                         .polarity = ACPI_ACTIVE_HIGH,
310                 },
311         }, {
312                 /* LP8557 Backlight controller */
313                 .board_info = {
314                         .type = "lp8557",
315                         .addr = 0x2c,
316                         .dev_name = "lp8557",
317                         .platform_data = &lenovo_lp8557_pdata,
318                 },
319                 .adapter_path = "\\_SB_.I2C3",
320         },
321 };
322
323 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = {
324         .dev_id = "intel-int3496",
325         .table = {
326                 GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW),
327                 GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH),
328                 { }
329         },
330 };
331
332 #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00"
333
334 static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = {
335         .dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME,
336         .table = {
337                 GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH),
338                 GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH),
339                 GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH),
340                 GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW),
341                 { }
342         },
343 };
344
345 static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = {
346         &lenovo_yoga_tab2_830_1050_int3496_gpios,
347         &lenovo_yoga_tab2_830_1050_codec_gpios,
348         NULL
349 };
350
351 static int __init lenovo_yoga_tab2_830_1050_init(void);
352 static void lenovo_yoga_tab2_830_1050_exit(void);
353
354 const struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initconst = {
355         .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients,
356         .i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients),
357         .pdev_info = int3496_pdevs,
358         .pdev_count = 1,
359         .gpio_button = &lenovo_yoga_tab2_830_1050_lid,
360         .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios,
361         .bat_swnode = &generic_lipo_hv_4v35_battery_node,
362         .modules = bq24190_modules,
363         .init = lenovo_yoga_tab2_830_1050_init,
364         .exit = lenovo_yoga_tab2_830_1050_exit,
365 };
366
367 /*
368  * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same
369  * mainboard, but the 830 uses a portrait LCD panel with a landscape touchscreen,
370  * requiring the touchscreen driver to adjust the touch-coords to match the LCD.
371  * And requiring the accelerometer to have a mount-matrix set to correct for
372  * the 90° rotation of the LCD vs the frame.
373  */
374 static const char * const lenovo_yoga_tab2_830_lms303d_mount_matrix[] = {
375         "0", "1", "0",
376         "-1", "0", "0",
377         "0", "0", "1"
378 };
379
380 static const struct property_entry lenovo_yoga_tab2_830_lms303d_props[] = {
381         PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", lenovo_yoga_tab2_830_lms303d_mount_matrix),
382         { }
383 };
384
385 static const struct software_node lenovo_yoga_tab2_830_lms303d_node = {
386         .properties = lenovo_yoga_tab2_830_lms303d_props,
387 };
388
389 static int __init lenovo_yoga_tab2_830_1050_init_touchscreen(void)
390 {
391         struct gpio_desc *gpiod;
392         int ret;
393
394         /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */
395         ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod);
396         if (ret)
397                 return ret;
398
399         ret = gpiod_get_value_cansleep(gpiod);
400         if (ret) {
401                 pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n");
402         } else {
403                 pr_info("detected Lenovo Yoga Tablet 2 830F/L\n");
404                 lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true;
405                 lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true;
406                 lenovo_yoga_tab2_830_1050_i2c_clients[0].board_info.swnode =
407                         &lenovo_yoga_tab2_830_lms303d_node;
408         }
409
410         return 0;
411 }
412
413 /* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */
414 static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map =
415         PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk",
416                           "INT33FC:02", "pmu_clk2_grp", "pmu_clk");
417
418 static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl;
419 static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler;
420
421 static int __init lenovo_yoga_tab2_830_1050_init_codec(void)
422 {
423         struct device *codec_dev;
424         struct pinctrl *pinctrl;
425         int ret;
426
427         codec_dev = bus_find_device_by_name(&spi_bus_type, NULL,
428                                             LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
429         if (!codec_dev) {
430                 pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME);
431                 return -ENODEV;
432         }
433
434         ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1);
435         if (ret)
436                 goto err_put_device;
437
438         pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk");
439         if (IS_ERR(pinctrl)) {
440                 ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n");
441                 goto err_unregister_mappings;
442         }
443
444         /* We're done with the codec_dev now */
445         put_device(codec_dev);
446
447         lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl;
448         return 0;
449
450 err_unregister_mappings:
451         pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
452 err_put_device:
453         put_device(codec_dev);
454         return ret;
455 }
456
457 /*
458  * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off
459  * gets used as pm_power_off handler. This causes "poweroff" on these tablets
460  * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice*
461  * followed by a normal 3 second press to recover. Avoid this by doing an EFI
462  * poweroff instead.
463  */
464 static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data)
465 {
466         efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
467
468         return NOTIFY_DONE;
469 }
470
471 static int __init lenovo_yoga_tab2_830_1050_init(void)
472 {
473         int ret;
474
475         ret = lenovo_yoga_tab2_830_1050_init_touchscreen();
476         if (ret)
477                 return ret;
478
479         ret = lenovo_yoga_tab2_830_1050_init_codec();
480         if (ret)
481                 return ret;
482
483         /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */
484         lenovo_yoga_tab2_830_1050_sys_off_handler =
485                 register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1,
486                                          lenovo_yoga_tab2_830_1050_power_off, NULL);
487         if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler))
488                 return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler);
489
490         return 0;
491 }
492
493 static void lenovo_yoga_tab2_830_1050_exit(void)
494 {
495         unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler);
496
497         if (lenovo_yoga_tab2_830_1050_codec_pinctrl) {
498                 pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl);
499                 pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map);
500         }
501 }
502
503 /* Lenovo Yoga Tab 3 Pro YT3-X90F */
504
505 /*
506  * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers,
507  * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c.
508  */
509 static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" };
510 static const char * const bq25890_1_psy[] = { "bq25890-charger-1" };
511
512 static const struct property_entry fg_bq25890_1_supply_props[] = {
513         PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy),
514         { }
515 };
516
517 static const struct software_node fg_bq25890_1_supply_node = {
518         .properties = fg_bq25890_1_supply_props,
519 };
520
521 /* bq25892 charger settings for the flat lipo battery behind the screen */
522 static const struct property_entry lenovo_yt3_bq25892_0_props[] = {
523         PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers),
524         PROPERTY_ENTRY_STRING("linux,power-supply-name", "bq25892-second-chrg"),
525         PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40),
526         PROPERTY_ENTRY_BOOL("linux,skip-reset"),
527         /* Values taken from Android Factory Image */
528         PROPERTY_ENTRY_U32("ti,charge-current", 2048000),
529         PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
530         PROPERTY_ENTRY_U32("ti,termination-current", 128000),
531         PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
532         PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000),
533         PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
534         PROPERTY_ENTRY_U32("ti,boost-max-current", 500000),
535         PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
536         { }
537 };
538
539 static const struct software_node lenovo_yt3_bq25892_0_node = {
540         .properties = lenovo_yt3_bq25892_0_props,
541 };
542
543 static const struct property_entry lenovo_yt3_hideep_ts_props[] = {
544         PROPERTY_ENTRY_U32("touchscreen-size-x", 1600),
545         PROPERTY_ENTRY_U32("touchscreen-size-y", 2560),
546         PROPERTY_ENTRY_U32("touchscreen-max-pressure", 255),
547         { }
548 };
549
550 static const struct software_node lenovo_yt3_hideep_ts_node = {
551         .properties = lenovo_yt3_hideep_ts_props,
552 };
553
554 static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = {
555         {
556                 /* bq27500 fuel-gauge for the flat lipo battery behind the screen */
557                 .board_info = {
558                         .type = "bq27500",
559                         .addr = 0x55,
560                         .dev_name = "bq27500_0",
561                         .swnode = &fg_bq25890_supply_node,
562                 },
563                 .adapter_path = "\\_SB_.PCI0.I2C1",
564         }, {
565                 /* bq25892 charger for the flat lipo battery behind the screen */
566                 .board_info = {
567                         .type = "bq25892",
568                         .addr = 0x6b,
569                         .dev_name = "bq25892_0",
570                         .swnode = &lenovo_yt3_bq25892_0_node,
571                 },
572                 .adapter_path = "\\_SB_.PCI0.I2C1",
573                 .irq_data = {
574                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
575                         .chip = "INT33FF:01",
576                         .index = 5,
577                         .trigger = ACPI_EDGE_SENSITIVE,
578                         .polarity = ACPI_ACTIVE_LOW,
579                 },
580         }, {
581                 /* bq27500 fuel-gauge for the round li-ion cells in the hinge */
582                 .board_info = {
583                         .type = "bq27500",
584                         .addr = 0x55,
585                         .dev_name = "bq27500_1",
586                         .swnode = &fg_bq25890_1_supply_node,
587                 },
588                 .adapter_path = "\\_SB_.PCI0.I2C2",
589         }, {
590                 /* HiDeep IST520E Touchscreen */
591                 .board_info = {
592                         .type = "hideep_ts",
593                         .addr = 0x6c,
594                         .dev_name = "hideep_ts",
595                         .swnode = &lenovo_yt3_hideep_ts_node,
596                 },
597                 .adapter_path = "\\_SB_.PCI0.I2C6",
598                 .irq_data = {
599                         .type = X86_ACPI_IRQ_TYPE_GPIOINT,
600                         .chip = "INT33FF:03",
601                         .index = 77,
602                         .trigger = ACPI_LEVEL_SENSITIVE,
603                         .polarity = ACPI_ACTIVE_LOW,
604                 },
605         }, {
606                 /* LP8557 Backlight controller */
607                 .board_info = {
608                         .type = "lp8557",
609                         .addr = 0x2c,
610                         .dev_name = "lp8557",
611                         .platform_data = &lenovo_lp8557_pdata,
612                 },
613                 .adapter_path = "\\_SB_.PCI0.I2C1",
614         }
615 };
616
617 static int __init lenovo_yt3_init(void)
618 {
619         struct gpio_desc *gpiod;
620         int ret;
621
622         /*
623          * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins
624          * connected to GPIOs, rather then having them hardwired to the correct
625          * values as is normally done.
626          *
627          * The bq25890_charger driver controls these through I2C, but this only
628          * works if not overridden by the pins. Set these pins here:
629          * 1. Set /CE to 0 to allow charging.
630          * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of
631          *    the main "bq25892_1" charger is used when necessary.
632          */
633
634         /* /CE pin */
635         ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, &gpiod);
636         if (ret < 0)
637                 return ret;
638
639         /*
640          * The gpio_desc returned by x86_android_tablet_get_gpiod() is a "raw"
641          * gpio_desc, that is there is no way to pass lookup-flags like
642          * GPIO_ACTIVE_LOW. Set the GPIO to 0 here to enable charging since
643          * the /CE pin is active-low, but not marked as such in the gpio_desc.
644          */
645         gpiod_set_value(gpiod, 0);
646
647         /* OTG pin */
648         ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, &gpiod);
649         if (ret < 0)
650                 return ret;
651
652         gpiod_set_value(gpiod, 0);
653
654         /* Enable the regulators used by the touchscreen */
655         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0x9b, 0x02, 0xff);
656         intel_soc_pmic_exec_mipi_pmic_seq_element(0x6e, 0xa0, 0x02, 0xff);
657
658         return 0;
659 }
660
661 static struct gpiod_lookup_table lenovo_yt3_hideep_gpios = {
662         .dev_id = "i2c-hideep_ts",
663         .table = {
664                 GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW),
665                 { }
666         },
667 };
668
669 static struct gpiod_lookup_table * const lenovo_yt3_gpios[] = {
670         &lenovo_yt3_hideep_gpios,
671         NULL
672 };
673
674 const struct x86_dev_info lenovo_yt3_info __initconst = {
675         .i2c_client_info = lenovo_yt3_i2c_clients,
676         .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients),
677         .gpiod_lookup_tables = lenovo_yt3_gpios,
678         .init = lenovo_yt3_init,
679 };
This page took 0.075877 seconds and 4 git commands to generate.