diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-05-16 09:14:50 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-05-16 09:14:50 -0700 |
commit | ea5f6ad9ad9645733b72ab53a98e719b460d36a6 (patch) | |
tree | 50a136fcf2ccb4b843fe298b4a53eb20e73ab54e /tools/arch | |
parent | b426433c03a6eb547515edbe74ebb3a90b9979dd (diff) | |
parent | 2513563edc984c3cf05bca1244b46de06daa4755 (diff) |
Merge tag 'platform-drivers-x86-v6.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86
Pull x86 platform driver updates from Hans de Goede:
- New drivers/platform/arm64 directory for arm64 embedded-controller
drivers
- New drivers:
- Acer Aspire 1 embedded controllers (for arm64 models)
- ACPI quickstart PNP0C32 buttons
- Dell All-In-One backlight support (dell-uart-backlight)
- Lenovo WMI camera buttons
- Lenovo Yoga Tablet 2 Pro 1380F/L fast charging
- MeeGoPad ANX7428 Type-C Cross Switch (power sequencing only)
- MSI WMI sensors (fan speed sensors only for now)
- Asus WMI:
- 2024 ROG Mini-LED support
- MCU powersave support
- Vivobook GPU MUX support
- Misc. other improvements
- Ideapad laptop:
- Export FnLock LED as LED class device
- Switch platform profiles using thermal management key
- Intel drivers:
- IFS: various improvements
- PMC: Lunar Lake support
- SDSI: various improvements
- TPMI/ISST: various improvements
- tools: intel-speed-select: various improvements
- MS Surface drivers:
- Fan profile switching support
- Surface Pro thermal sensors support
- ThinkPad ACPI:
- Reworked hotkey support to use sparse keymaps
- Add support for new trackpoint-doubletap, Fn+N and Fn+G hotkeys
- WMI core:
- New WMI driver development guide
- x86 Android tablets:
- Lenovo Yoga Tablet 2 Pro 1380F/L support
- Xiaomi MiPad 2 status LED and bezel touch buttons backlight
support
- Miscellaneous cleanups / fixes / improvements
* tag 'platform-drivers-x86-v6.10-1' of git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86: (128 commits)
platform/x86: Add new MeeGoPad ANX7428 Type-C Cross Switch driver
devm-helpers: Fix a misspelled cancellation in the comments
tools arch x86: Add dell-uart-backlight-emulator
platform/x86: Add new Dell UART backlight driver
platform/x86: x86-android-tablets: Create LED device for Xiaomi Pad 2 bottom bezel touch buttons
platform/x86: x86-android-tablets: Xiaomi pad2 RGB LED fwnode updates
platform/x86: x86-android-tablets: Pass struct device to init()
platform/x86/amd: pmc: Add new ACPI ID AMDI000B
platform/x86/amd: pmf: Add new ACPI ID AMDI0105
platform/x86: p2sb: Don't init until unassigned resources have been assigned
platform/surface: aggregator: Log critical errors during SAM probing
platform/x86: ISST: Support SST-BF and SST-TF per level
platform/x86/fujitsu-laptop: Replace sprintf() with sysfs_emit()
tools/power/x86/intel-speed-select: v1.19 release
tools/power/x86/intel-speed-select: Display CPU as None for -1
tools/power/x86/intel-speed-select: SST BF/TF support per level
tools/power/x86/intel-speed-select: Increase number of CPUs displayed
tools/power/x86/intel-speed-select: Present all TRL levels for turbo-freq
tools/power/x86/intel-speed-select: Fix display for unsupported levels
tools/power/x86/intel-speed-select: Support multiple dies
...
Diffstat (limited to 'tools/arch')
5 files changed, 295 insertions, 42 deletions
diff --git a/tools/arch/x86/dell-uart-backlight-emulator/.gitignore b/tools/arch/x86/dell-uart-backlight-emulator/.gitignore new file mode 100644 index 000000000000..5c8cad8d72b9 --- /dev/null +++ b/tools/arch/x86/dell-uart-backlight-emulator/.gitignore @@ -0,0 +1 @@ +dell-uart-backlight-emulator diff --git a/tools/arch/x86/dell-uart-backlight-emulator/Makefile b/tools/arch/x86/dell-uart-backlight-emulator/Makefile new file mode 100644 index 000000000000..6ea1d9fd534b --- /dev/null +++ b/tools/arch/x86/dell-uart-backlight-emulator/Makefile @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: GPL-2.0 +# Makefile for Intel Software Defined Silicon provisioning tool + +dell-uart-backlight-emulator: dell-uart-backlight-emulator.c + +BINDIR ?= /usr/bin + +override CFLAGS += -O2 -Wall + +%: %.c + $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) + +.PHONY : clean +clean : + @rm -f dell-uart-backlight-emulator + +install : dell-uart-backlight-emulator + install -d $(DESTDIR)$(BINDIR) + install -m 755 -p dell-uart-backlight-emulator $(DESTDIR)$(BINDIR)/dell-uart-backlight-emulator diff --git a/tools/arch/x86/dell-uart-backlight-emulator/README b/tools/arch/x86/dell-uart-backlight-emulator/README new file mode 100644 index 000000000000..c0d8e52046ee --- /dev/null +++ b/tools/arch/x86/dell-uart-backlight-emulator/README @@ -0,0 +1,46 @@ +Emulator for DELL0501 UART attached backlight controller +-------------------------------------------------------- + +Dell All In One (AIO) models released after 2017 use a backlight controller +board connected to an UART. + +In DSDT this uart port will be defined as: + + Name (_HID, "DELL0501") + Name (_CID, EisaId ("PNP0501") + +With the DELL0501 indicating that we are dealing with an UART with +the backlight controller board attached. + +This small emulator allows testing +the drivers/platform/x86/dell/dell-uart-backlight.c driver without access +to an actual Dell All In One. + +This requires: +1. A (desktop) PC with a 16550 UART on the motherboard and a standard DB9 + connector connected to this UART. +2. A DB9 NULL modem cable. +3. A second DB9 serial port, this can e.g. be a USB to serial converter + with a DB9 connector plugged into the same desktop PC. +4. A DSDT overlay for the desktop PC replacing the _HID of the 16550 UART + ACPI Device() with "DELL0501" and adding a _CID of "PNP0501", see + DSDT.patch for an example of the necessary DSDT changes. + +With everything setup and the NULL modem cable connected between +the 2 serial ports run: + +./dell-uart-backlight-emulator <path-to-/dev/tty*S#-for-second-port> + +For example when using an USB to serial converter for the second port: + +./dell-uart-backlight-emulator /dev/ttyUSB0 + +And then (re)load the dell-uart-backlight driver: + +sudo rmmod dell-uart-backlight; sudo modprobe dell-uart-backlight dyndbg + +After this check "dmesg" to see if the driver correctly received +the firmware version string from the emulator. If this works there +should be a /sys/class/backlight/dell_uart_backlight/ directory now +and writes to the brightness or bl_power files should be reflected +by matching output from the emulator. diff --git a/tools/arch/x86/dell-uart-backlight-emulator/dell-uart-backlight-emulator.c b/tools/arch/x86/dell-uart-backlight-emulator/dell-uart-backlight-emulator.c new file mode 100644 index 000000000000..655b6c96d8cf --- /dev/null +++ b/tools/arch/x86/dell-uart-backlight-emulator/dell-uart-backlight-emulator.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Dell AIO Serial Backlight board emulator for testing + * the Linux dell-uart-backlight driver. + * + * Copyright (C) 2024 Hans de Goede <hansg@kernel.org> + */ +#include <errno.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/un.h> +#include <termios.h> +#include <unistd.h> + +int serial_fd; +int brightness = 50; + +static unsigned char dell_uart_checksum(unsigned char *buf, int len) +{ + unsigned char val = 0; + + while (len-- > 0) + val += buf[len]; + + return val ^ 0xff; +} + +/* read() will return -1 on SIGINT / SIGTERM causing the mainloop to cleanly exit */ +void signalhdlr(int signum) +{ +} + +int main(int argc, char *argv[]) +{ + struct sigaction sigact = { .sa_handler = signalhdlr }; + unsigned char buf[4], csum, response[32]; + const char *version_str = "PHI23-V321"; + struct termios tty, saved_tty; + int ret, idx, len = 0; + + if (argc != 2) { + fprintf(stderr, "Invalid or missing arguments\n"); + fprintf(stderr, "Usage: %s <serial-port>\n", argv[0]); + return 1; + } + + serial_fd = open(argv[1], O_RDWR | O_NOCTTY); + if (serial_fd == -1) { + fprintf(stderr, "Error opening %s: %s\n", argv[1], strerror(errno)); + return 1; + } + + ret = tcgetattr(serial_fd, &tty); + if (ret == -1) { + fprintf(stderr, "Error getting tcattr: %s\n", strerror(errno)); + goto out_close; + } + saved_tty = tty; + + cfsetspeed(&tty, 9600); + cfmakeraw(&tty); + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CRTSCTS; + tty.c_cflag |= CLOCAL | CREAD; + + ret = tcsetattr(serial_fd, TCSANOW, &tty); + if (ret == -1) { + fprintf(stderr, "Error setting tcattr: %s\n", strerror(errno)); + goto out_restore; + } + + sigaction(SIGINT, &sigact, 0); + sigaction(SIGTERM, &sigact, 0); + + idx = 0; + while (read(serial_fd, &buf[idx], 1) == 1) { + if (idx == 0) { + switch (buf[0]) { + /* 3 MSB bits: cmd-len + 01010 SOF marker */ + case 0x6a: len = 3; break; + case 0x8a: len = 4; break; + default: + fprintf(stderr, "Error unexpected first byte: 0x%02x\n", buf[0]); + continue; /* Try to sync up with sender */ + } + } + + /* Process msg when len bytes have been received */ + if (idx != (len - 1)) { + idx++; + continue; + } + + /* Reset idx for next command */ + idx = 0; + + csum = dell_uart_checksum(buf, len - 1); + if (buf[len - 1] != csum) { + fprintf(stderr, "Error checksum mismatch got 0x%02x expected 0x%02x\n", + buf[len - 1], csum); + continue; + } + + switch ((buf[0] << 8) | buf[1]) { + case 0x6a06: /* cmd = 0x06, get version */ + len = strlen(version_str); + strcpy((char *)&response[2], version_str); + printf("Get version, reply: %s\n", version_str); + break; + case 0x8a0b: /* cmd = 0x0b, set brightness */ + if (buf[2] > 100) { + fprintf(stderr, "Error invalid brightness param: %d\n", buf[2]); + continue; + } + + len = 0; + brightness = buf[2]; + printf("Set brightness %d\n", brightness); + break; + case 0x6a0c: /* cmd = 0x0c, get brightness */ + len = 1; + response[2] = brightness; + printf("Get brightness, reply: %d\n", brightness); + break; + case 0x8a0e: /* cmd = 0x0e, set backlight power */ + if (buf[2] != 0 && buf[2] != 1) { + fprintf(stderr, "Error invalid set power param: %d\n", buf[2]); + continue; + } + + len = 0; + printf("Set power %d\n", buf[2]); + break; + default: + fprintf(stderr, "Error unknown cmd 0x%04x\n", + (buf[0] << 8) | buf[1]); + continue; + } + + /* Respond with <total-len> <cmd> <data...> <csum> */ + response[0] = len + 3; /* response length in bytes */ + response[1] = buf[1]; /* ack cmd */ + csum = dell_uart_checksum(response, len + 2); + response[len + 2] = csum; + ret = write(serial_fd, response, response[0]); + if (ret != (response[0])) + fprintf(stderr, "Error writing %d bytes: %d\n", + response[0], ret); + } + + ret = 0; +out_restore: + tcsetattr(serial_fd, TCSANOW, &saved_tty); +out_close: + close(serial_fd); + return ret; +} diff --git a/tools/arch/x86/intel_sdsi/intel_sdsi.c b/tools/arch/x86/intel_sdsi/intel_sdsi.c index 2cd92761f171..766a5d26f534 100644 --- a/tools/arch/x86/intel_sdsi/intel_sdsi.c +++ b/tools/arch/x86/intel_sdsi/intel_sdsi.c @@ -43,7 +43,7 @@ #define METER_CERT_MAX_SIZE 4096 #define STATE_MAX_NUM_LICENSES 16 #define STATE_MAX_NUM_IN_BUNDLE (uint32_t)8 -#define METER_MAX_NUM_BUNDLES 8 +#define FEAT_LEN 5 /* 4 plus NUL terminator */ #define __round_mask(x, y) ((__typeof__(x))((y) - 1)) #define round_up(x, y) ((((x) - 1) | __round_mask(x, y)) + 1) @@ -154,11 +154,12 @@ struct bundle_encoding { }; struct meter_certificate { - uint32_t block_signature; - uint32_t counter_unit; + uint32_t signature; + uint32_t version; uint64_t ppin; + uint32_t counter_unit; uint32_t bundle_length; - uint32_t reserved; + uint64_t reserved; uint32_t mmrc_encoding; uint32_t mmrc_counter; }; @@ -167,6 +168,11 @@ struct bundle_encoding_counter { uint32_t encoding; uint32_t counter; }; +#define METER_BUNDLE_SIZE sizeof(struct bundle_encoding_counter) +#define BUNDLE_COUNT(length) ((length) / METER_BUNDLE_SIZE) +#define METER_MAX_NUM_BUNDLES \ + ((METER_CERT_MAX_SIZE - sizeof(struct meter_certificate)) / \ + sizeof(struct bundle_encoding_counter)) struct sdsi_dev { struct sdsi_regs regs; @@ -179,6 +185,7 @@ struct sdsi_dev { enum command { CMD_SOCKET_INFO, CMD_METER_CERT, + CMD_METER_CURRENT_CERT, CMD_STATE_CERT, CMD_PROV_AKC, CMD_PROV_CAP, @@ -316,24 +323,27 @@ static char *content_type(uint32_t type) } } -static void get_feature(uint32_t encoding, char *feature) +static void get_feature(uint32_t encoding, char feature[5]) { char *name = (char *)&encoding; + feature[4] = '\0'; feature[3] = name[0]; feature[2] = name[1]; feature[1] = name[2]; feature[0] = name[3]; } -static int sdsi_meter_cert_show(struct sdsi_dev *s) +static int sdsi_meter_cert_show(struct sdsi_dev *s, bool show_current) { char buf[METER_CERT_MAX_SIZE] = {0}; struct bundle_encoding_counter *bec; struct meter_certificate *mc; uint32_t count = 0; FILE *cert_ptr; + char *cert_fname; int ret, size; + char name[FEAT_LEN]; ret = sdsi_update_registers(s); if (ret) @@ -341,7 +351,6 @@ static int sdsi_meter_cert_show(struct sdsi_dev *s) if (!s->regs.en_features.sdsi) { fprintf(stderr, "SDSi feature is present but not enabled.\n"); - fprintf(stderr, " Unable to read meter certificate\n"); return -1; } @@ -356,15 +365,17 @@ static int sdsi_meter_cert_show(struct sdsi_dev *s) return ret; } - cert_ptr = fopen("meter_certificate", "r"); + cert_fname = show_current ? "meter_current" : "meter_certificate"; + cert_ptr = fopen(cert_fname, "r"); + if (!cert_ptr) { - perror("Could not open 'meter_certificate' file"); + fprintf(stderr, "Could not open '%s' file: %s", cert_fname, strerror(errno)); return -1; } size = fread(buf, 1, sizeof(buf), cert_ptr); if (!size) { - fprintf(stderr, "Could not read 'meter_certificate' file\n"); + fprintf(stderr, "Could not read '%s' file\n", cert_fname); fclose(cert_ptr); return -1; } @@ -375,32 +386,39 @@ static int sdsi_meter_cert_show(struct sdsi_dev *s) printf("\n"); printf("Meter certificate for device %s\n", s->dev_name); printf("\n"); - printf("Block Signature: 0x%x\n", mc->block_signature); - printf("Count Unit: %dms\n", mc->counter_unit); - printf("PPIN: 0x%lx\n", mc->ppin); - printf("Feature Bundle Length: %d\n", mc->bundle_length); - printf("MMRC encoding: %d\n", mc->mmrc_encoding); - printf("MMRC counter: %d\n", mc->mmrc_counter); - if (mc->bundle_length % 8) { + + get_feature(mc->signature, name); + printf("Signature: %s\n", name); + + printf("Version: %d\n", mc->version); + printf("Count Unit: %dms\n", mc->counter_unit); + printf("PPIN: 0x%lx\n", mc->ppin); + printf("Feature Bundle Length: %d\n", mc->bundle_length); + + get_feature(mc->mmrc_encoding, name); + printf("MMRC encoding: %s\n", name); + + printf("MMRC counter: %d\n", mc->mmrc_counter); + if (mc->bundle_length % METER_BUNDLE_SIZE) { fprintf(stderr, "Invalid bundle length\n"); return -1; } - if (mc->bundle_length > METER_MAX_NUM_BUNDLES * 8) { - fprintf(stderr, "More than %d bundles: %d\n", - METER_MAX_NUM_BUNDLES, mc->bundle_length / 8); + if (mc->bundle_length > METER_MAX_NUM_BUNDLES * METER_BUNDLE_SIZE) { + fprintf(stderr, "More than %ld bundles: actual %ld\n", + METER_MAX_NUM_BUNDLES, BUNDLE_COUNT(mc->bundle_length)); return -1; } - bec = (void *)(mc) + sizeof(mc); + bec = (struct bundle_encoding_counter *)(mc + 1); - printf("Number of Feature Counters: %d\n", mc->bundle_length / 8); - while (count++ < mc->bundle_length / 8) { - char feature[5]; + printf("Number of Feature Counters: %ld\n", BUNDLE_COUNT(mc->bundle_length)); + while (count < BUNDLE_COUNT(mc->bundle_length)) { + char feature[FEAT_LEN]; - feature[4] = '\0'; get_feature(bec[count].encoding, feature); printf(" %s: %d\n", feature, bec[count].counter); + ++count; } return 0; @@ -480,7 +498,7 @@ static int sdsi_state_cert_show(struct sdsi_dev *s) sizeof(*lki) + // size of the license key info offset; // offset to this blob content struct bundle_encoding *bundle = (void *)(lbc) + sizeof(*lbc); - char feature[5]; + char feature[FEAT_LEN]; uint32_t i; printf(" Blob %d:\n", count - 1); @@ -493,8 +511,6 @@ static int sdsi_state_cert_show(struct sdsi_dev *s) printf(" Blob revision ID: %u\n", lbc->rev_id); printf(" Number of Features: %u\n", lbc->num_bundles); - feature[4] = '\0'; - for (i = 0; i < min(lbc->num_bundles, STATE_MAX_NUM_IN_BUNDLE); i++) { get_feature(bundle[i].encoding, feature); printf(" Feature %d: %s\n", i, feature); @@ -725,7 +741,7 @@ static void sdsi_free_dev(struct sdsi_dev *s) static void usage(char *prog) { - printf("Usage: %s [-l] [-d DEVNO [-i] [-s] [-m] [-a FILE] [-c FILE]]\n", prog); + printf("Usage: %s [-l] [-d DEVNO [-i] [-s] [-m | -C] [-a FILE] [-c FILE]\n", prog); } static void show_help(void) @@ -734,8 +750,9 @@ static void show_help(void) printf(" %-18s\t%s\n", "-l, --list", "list available On Demand devices"); printf(" %-18s\t%s\n", "-d, --devno DEVNO", "On Demand device number"); printf(" %-18s\t%s\n", "-i, --info", "show socket information"); - printf(" %-18s\t%s\n", "-s, --state", "show state certificate"); - printf(" %-18s\t%s\n", "-m, --meter", "show meter certificate"); + printf(" %-18s\t%s\n", "-s, --state", "show state certificate data"); + printf(" %-18s\t%s\n", "-m, --meter", "show meter certificate data"); + printf(" %-18s\t%s\n", "-C, --meter_current", "show live unattested meter data"); printf(" %-18s\t%s\n", "-a, --akc FILE", "provision socket with AKC FILE"); printf(" %-18s\t%s\n", "-c, --cap FILE>", "provision socket with CAP FILE"); } @@ -751,21 +768,22 @@ int main(int argc, char *argv[]) int option_index = 0; static struct option long_options[] = { - {"akc", required_argument, 0, 'a'}, - {"cap", required_argument, 0, 'c'}, - {"devno", required_argument, 0, 'd'}, - {"help", no_argument, 0, 'h'}, - {"info", no_argument, 0, 'i'}, - {"list", no_argument, 0, 'l'}, - {"meter", no_argument, 0, 'm'}, - {"state", no_argument, 0, 's'}, - {0, 0, 0, 0 } + {"akc", required_argument, 0, 'a'}, + {"cap", required_argument, 0, 'c'}, + {"devno", required_argument, 0, 'd'}, + {"help", no_argument, 0, 'h'}, + {"info", no_argument, 0, 'i'}, + {"list", no_argument, 0, 'l'}, + {"meter", no_argument, 0, 'm'}, + {"meter_current", no_argument, 0, 'C'}, + {"state", no_argument, 0, 's'}, + {0, 0, 0, 0 } }; progname = argv[0]; - while ((opt = getopt_long_only(argc, argv, "+a:c:d:hilms", long_options, + while ((opt = getopt_long_only(argc, argv, "+a:c:d:hilmCs", long_options, &option_index)) != -1) { switch (opt) { case 'd': @@ -781,6 +799,9 @@ int main(int argc, char *argv[]) case 'm': command = CMD_METER_CERT; break; + case 'C': + command = CMD_METER_CURRENT_CERT; + break; case 's': command = CMD_STATE_CERT; break; @@ -819,7 +840,10 @@ int main(int argc, char *argv[]) ret = sdsi_read_reg(s); break; case CMD_METER_CERT: - ret = sdsi_meter_cert_show(s); + ret = sdsi_meter_cert_show(s, false); + break; + case CMD_METER_CURRENT_CERT: + ret = sdsi_meter_cert_show(s, true); break; case CMD_STATE_CERT: ret = sdsi_state_cert_show(s); |