blob: d3c4652e473c0c01d3cd21d9f6733b291dbdc4b5 [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +01002
3#include <types.h>
4#include <console/console.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07005#include <acpi/acpigen.h>
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +01006#include <device/device.h>
7#include <device/pnp.h>
8#include <string.h>
9#include "lenovo.h"
10#include "drivers/i2c/at24rf08c/lenovo.h"
11
12static const char tablet_numbers[][5] = {
13 /* X60t. */
14 "6363", "6364", "6365", "6366",
15 "6367", "6368", "7762", "7763",
16 "7764", "7767", "7768", "7769",
Alex Davidbb03aaa2015-05-14 20:09:18 -040017 /* X200t. */
18 "7448", "7449", "7450", "7453",
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010019 /* X201t. */
20 "0053", "0831", "2985", "3093",
21 "3113", "3144", "3239", "4184",
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010022 "2263", "2266",
23};
24
25int
26drivers_lenovo_is_wacom_present(void)
27{
28 const char *pn;
29 int i;
30 static int result = -1;
Elyes HAOUAS372917d2018-05-02 22:00:38 +020031 struct device *superio;
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010032 u8 sioid;
33
34 if (result != -1)
35 return result;
36
Julius Wernercd49cce2019-03-05 16:53:33 -080037 if (CONFIG(DIGITIZER_PRESENT)) {
Elyes Haouas3c1a1092023-08-26 16:47:33 +020038 printk(BIOS_INFO, "Digitizer state forced as present\n");
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010039 return (result = 1);
40 }
41
Julius Wernercd49cce2019-03-05 16:53:33 -080042 if (CONFIG(DIGITIZER_ABSENT)) {
Elyes Haouas3c1a1092023-08-26 16:47:33 +020043 printk(BIOS_INFO, "Digitizer state forced as absent\n");
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010044 return (result = 0);
45 }
46
47 superio = dev_find_slot_pnp (0x164e, 3);
48 if (!superio) {
Elyes Haouas3c1a1092023-08-26 16:47:33 +020049 printk(BIOS_INFO, "No Super I/O, skipping wacom\n");
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010050 return (result = 0);
51 }
52
53 /* Probe ID. */
54 sioid = pnp_read_config(superio, 0x20);
55 if (sioid == 0xff) {
Elyes Haouas3c1a1092023-08-26 16:47:33 +020056 printk(BIOS_INFO, "Super I/O probe failed, skipping wacom\n");
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010057 return (result = 0);
58 }
59
60 pn = lenovo_mainboard_partnumber();
61 if (!pn)
62 return (result = 0);
63 printk (BIOS_DEBUG, "Lenovo P/N is %s\n", pn);
64 for (i = 0; i < ARRAY_SIZE (tablet_numbers); i++)
65 if (memcmp (tablet_numbers[i], pn, 4) == 0) {
Elyes Haouas3c1a1092023-08-26 16:47:33 +020066 printk(BIOS_DEBUG, "Lenovo P/N %s is a tablet\n", pn);
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010067 return (result = 1);
68 }
Elyes Haouas3c1a1092023-08-26 16:47:33 +020069 printk(BIOS_DEBUG, "Lenovo P/N %s is not a tablet\n", pn);
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010070 return (result = 0);
71}
72
73void
74drivers_lenovo_serial_ports_ssdt_generate(const char *scope,
75 int have_dock_serial)
76{
Vladimir Serbinenkobcb3abe2014-11-04 21:17:30 +010077 acpigen_write_scope(scope);
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010078
79 if (drivers_lenovo_is_wacom_present()) {
Vladimir Serbinenko663be6e2014-11-05 21:29:45 +010080 acpigen_write_device("DTR");
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010081
Vladimir Serbinenkobcb3abe2014-11-04 21:17:30 +010082 acpigen_write_name("_HID");
83 acpigen_emit_eisaid("WACF004");
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010084
Vladimir Serbinenkobcb3abe2014-11-04 21:17:30 +010085 acpigen_write_name("_CRS");
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010086
Vladimir Serbinenko9acc1e82014-11-09 03:37:28 +010087 acpigen_write_resourcetemplate_header();
88 acpigen_write_io16(0x200, 0x200, 1, 8, 1);
89 acpigen_write_irq((1 << 5));
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010090
Vladimir Serbinenko9acc1e82014-11-09 03:37:28 +010091 acpigen_write_resourcetemplate_footer();
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010092
Patrick Rudolphb1181c32017-08-13 11:04:04 +020093 acpigen_write_STA(0xf);
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010094
Vladimir Serbinenkobcb3abe2014-11-04 21:17:30 +010095 acpigen_pop_len();
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +010096 }
97
98 if (have_dock_serial) {
Vladimir Serbinenko663be6e2014-11-05 21:29:45 +010099 acpigen_write_device("COMA");
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +0100100
Vladimir Serbinenkobcb3abe2014-11-04 21:17:30 +0100101 acpigen_write_name("_HID");
102 acpigen_emit_eisaid("PNP0501");
103 acpigen_write_name("_UID");
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +0100104 /* Byte */
Vladimir Serbinenkobcb3abe2014-11-04 21:17:30 +0100105 acpigen_write_byte(0x2);
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +0100106
Vladimir Serbinenkobcb3abe2014-11-04 21:17:30 +0100107 acpigen_write_name("_CRS");
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +0100108
Vladimir Serbinenko9acc1e82014-11-09 03:37:28 +0100109 acpigen_write_resourcetemplate_header();
110 acpigen_write_io16(0x3f8, 0x3f8, 1, 8, 1);
111 acpigen_write_irq(1 << 4);
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +0100112
Vladimir Serbinenko9acc1e82014-11-09 03:37:28 +0100113 acpigen_write_resourcetemplate_footer();
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +0100114
Patrick Rudolphb1181c32017-08-13 11:04:04 +0200115 acpigen_write_STA(0xf);
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +0100116
Vladimir Serbinenkobcb3abe2014-11-04 21:17:30 +0100117 acpigen_pop_len();
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +0100118 }
119
Vladimir Serbinenkobcb3abe2014-11-04 21:17:30 +0100120 acpigen_pop_len();
Vladimir Serbinenkof2b3cd62014-02-15 17:00:46 +0100121}