xref: /aosp_15_r20/external/coreboot/src/drivers/lenovo/wacom.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <types.h>
4 #include <console/console.h>
5 #include <acpi/acpigen.h>
6 #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 
12 static const char tablet_numbers[][5] = {
13 	/* X60t. */
14 	"6363", "6364", "6365", "6366",
15 	"6367", "6368", "7762", "7763",
16 	"7764", "7767", "7768", "7769",
17 	/* X200t. */
18 	"7448", "7449", "7450", "7453",
19 	/* X201t. */
20 	"0053", "0831", "2985", "3093",
21 	"3113", "3144", "3239", "4184",
22 	"2263", "2266",
23 };
24 
25 int
drivers_lenovo_is_wacom_present(void)26 drivers_lenovo_is_wacom_present(void)
27 {
28 	const char *pn;
29 	int i;
30 	static int result = -1;
31 	struct device *superio;
32 	u8 sioid;
33 
34 	if (result != -1)
35 		return result;
36 
37 	if (CONFIG(DIGITIZER_PRESENT)) {
38 		printk(BIOS_INFO, "Digitizer state forced as present\n");
39 		return (result = 1);
40 	}
41 
42 	if (CONFIG(DIGITIZER_ABSENT)) {
43 		printk(BIOS_INFO, "Digitizer state forced as absent\n");
44 		return (result = 0);
45 	}
46 
47 	superio = dev_find_slot_pnp(0x164e, 3);
48 	if (!superio) {
49 		printk(BIOS_INFO, "No Super I/O, skipping wacom\n");
50 		return (result = 0);
51 	}
52 
53 	/* Probe ID. */
54 	sioid = pnp_read_config(superio, 0x20);
55 	if (sioid == 0xff) {
56 		printk(BIOS_INFO, "Super I/O probe failed, skipping wacom\n");
57 		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) {
66 			printk(BIOS_DEBUG, "Lenovo P/N %s is a tablet\n", pn);
67 			return (result = 1);
68 		}
69 	printk(BIOS_DEBUG, "Lenovo P/N %s is not a tablet\n", pn);
70 	return (result = 0);
71 }
72 
73 void
drivers_lenovo_serial_ports_ssdt_generate(const char * scope,int have_dock_serial)74 drivers_lenovo_serial_ports_ssdt_generate(const char *scope,
75 					  int have_dock_serial)
76 {
77 	acpigen_write_scope(scope);
78 
79 	if (drivers_lenovo_is_wacom_present()) {
80 		acpigen_write_device("DTR");
81 
82 		acpigen_write_name("_HID");
83 		acpigen_emit_eisaid("WACF004");
84 
85 		acpigen_write_name("_CRS");
86 
87 		acpigen_write_resourcetemplate_header();
88 		acpigen_write_io16(0x200, 0x200, 1, 8, 1);
89 		acpigen_write_irq((1 << 5));
90 
91 		acpigen_write_resourcetemplate_footer();
92 
93 		acpigen_write_STA(0xf);
94 
95 		acpigen_pop_len();
96 	}
97 
98 	if (have_dock_serial) {
99 		acpigen_write_device("COMA");
100 
101 		acpigen_write_name("_HID");
102 		acpigen_emit_eisaid("PNP0501");
103 		acpigen_write_name("_UID");
104 		/* Byte */
105 		acpigen_write_byte(0x2);
106 
107 		acpigen_write_name("_CRS");
108 
109 		acpigen_write_resourcetemplate_header();
110 		acpigen_write_io16(0x3f8, 0x3f8, 1, 8, 1);
111 		acpigen_write_irq(1 << 4);
112 
113 		acpigen_write_resourcetemplate_footer();
114 
115 		acpigen_write_STA(0xf);
116 
117 		acpigen_pop_len();
118 	}
119 
120 	acpigen_pop_len();
121 }
122