diff options
Diffstat (limited to 'include/linux/platform_data')
-rw-r--r-- | include/linux/platform_data/huawei-gaokun-ec.h | 79 | ||||
-rw-r--r-- | include/linux/platform_data/x86/intel_pmc_ipc.h | 94 |
2 files changed, 173 insertions, 0 deletions
diff --git a/include/linux/platform_data/huawei-gaokun-ec.h b/include/linux/platform_data/huawei-gaokun-ec.h new file mode 100644 index 000000000000..faa15d315128 --- /dev/null +++ b/include/linux/platform_data/huawei-gaokun-ec.h @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Huawei Matebook E Go Embedded Controller + * + * Copyright (C) 2024-2025 Pengyu Luo <mitltlatltl@gmail.com> + */ + +#ifndef __HUAWEI_GAOKUN_EC_H__ +#define __HUAWEI_GAOKUN_EC_H__ + +#define GAOKUN_UCSI_CCI_SIZE 4 +#define GAOKUN_UCSI_MSGI_SIZE 16 +#define GAOKUN_UCSI_READ_SIZE (GAOKUN_UCSI_CCI_SIZE + GAOKUN_UCSI_MSGI_SIZE) +#define GAOKUN_UCSI_WRITE_SIZE 24 /* 8B CTRL, 16B MSGO */ + +#define GAOKUN_UCSI_NO_PORT_UPDATE (-1) + +#define GAOKUN_SMART_CHARGE_DATA_SIZE 4 /* mode, delay, start, end */ + +/* -------------------------------------------------------------------------- */ + +struct gaokun_ec; +struct gaokun_ucsi_reg; +struct notifier_block; + +#define GAOKUN_MOD_NAME "huawei_gaokun_ec" +#define GAOKUN_DEV_PSY "psy" +#define GAOKUN_DEV_UCSI "ucsi" + +/* -------------------------------------------------------------------------- */ +/* Common API */ + +int gaokun_ec_register_notify(struct gaokun_ec *ec, + struct notifier_block *nb); +void gaokun_ec_unregister_notify(struct gaokun_ec *ec, + struct notifier_block *nb); + +int gaokun_ec_read(struct gaokun_ec *ec, const u8 *req, + size_t resp_len, u8 *resp); +int gaokun_ec_write(struct gaokun_ec *ec, const u8 *req); +int gaokun_ec_read_byte(struct gaokun_ec *ec, const u8 *req, u8 *byte); + +/* -------------------------------------------------------------------------- */ +/* API for PSY */ + +int gaokun_ec_psy_multi_read(struct gaokun_ec *ec, u8 reg, + size_t resp_len, u8 *resp); + +static inline int gaokun_ec_psy_read_byte(struct gaokun_ec *ec, + u8 reg, u8 *byte) +{ + return gaokun_ec_psy_multi_read(ec, reg, sizeof(*byte), byte); +} + +static inline int gaokun_ec_psy_read_word(struct gaokun_ec *ec, + u8 reg, u16 *word) +{ + return gaokun_ec_psy_multi_read(ec, reg, sizeof(*word), (u8 *)word); +} + +int gaokun_ec_psy_get_smart_charge(struct gaokun_ec *ec, + u8 resp[GAOKUN_SMART_CHARGE_DATA_SIZE]); +int gaokun_ec_psy_set_smart_charge(struct gaokun_ec *ec, + const u8 req[GAOKUN_SMART_CHARGE_DATA_SIZE]); + +int gaokun_ec_psy_get_smart_charge_enable(struct gaokun_ec *ec, bool *on); +int gaokun_ec_psy_set_smart_charge_enable(struct gaokun_ec *ec, bool on); + +/* -------------------------------------------------------------------------- */ +/* API for UCSI */ + +int gaokun_ec_ucsi_read(struct gaokun_ec *ec, u8 resp[GAOKUN_UCSI_READ_SIZE]); +int gaokun_ec_ucsi_write(struct gaokun_ec *ec, + const u8 req[GAOKUN_UCSI_WRITE_SIZE]); + +int gaokun_ec_ucsi_get_reg(struct gaokun_ec *ec, struct gaokun_ucsi_reg *ureg); +int gaokun_ec_ucsi_pan_ack(struct gaokun_ec *ec, int port_id); + +#endif /* __HUAWEI_GAOKUN_EC_H__ */ diff --git a/include/linux/platform_data/x86/intel_pmc_ipc.h b/include/linux/platform_data/x86/intel_pmc_ipc.h new file mode 100644 index 000000000000..6e603a8c075f --- /dev/null +++ b/include/linux/platform_data/x86/intel_pmc_ipc.h @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Intel Core SoC Power Management Controller Header File + * + * Copyright (c) 2025, Intel Corporation. + * All Rights Reserved. + * + */ +#ifndef INTEL_PMC_IPC_H +#define INTEL_PMC_IPC_H +#include <linux/acpi.h> + +#define IPC_SOC_REGISTER_ACCESS 0xAA +#define IPC_SOC_SUB_CMD_READ 0x00 +#define IPC_SOC_SUB_CMD_WRITE 0x01 +#define PMC_IPCS_PARAM_COUNT 7 +#define VALID_IPC_RESPONSE 5 + +struct pmc_ipc_cmd { + u32 cmd; + u32 sub_cmd; + u32 size; + u32 wbuf[4]; +}; + +struct pmc_ipc_rbuf { + u32 buf[4]; +}; + +/** + * intel_pmc_ipc() - PMC IPC Mailbox accessor + * @ipc_cmd: Prepared input command to send + * @rbuf: Allocated array for returned IPC data + * + * Return: 0 on success. Non-zero on mailbox error + */ +static inline int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, struct pmc_ipc_rbuf *rbuf) +{ + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object params[PMC_IPCS_PARAM_COUNT] = { + {.type = ACPI_TYPE_INTEGER,}, + {.type = ACPI_TYPE_INTEGER,}, + {.type = ACPI_TYPE_INTEGER,}, + {.type = ACPI_TYPE_INTEGER,}, + {.type = ACPI_TYPE_INTEGER,}, + {.type = ACPI_TYPE_INTEGER,}, + {.type = ACPI_TYPE_INTEGER,}, + }; + struct acpi_object_list arg_list = { PMC_IPCS_PARAM_COUNT, params }; + union acpi_object *obj; + int status; + + if (!ipc_cmd || !rbuf) + return -EINVAL; + + /* + * 0: IPC Command + * 1: IPC Sub Command + * 2: Size + * 3-6: Write Buffer for offset + */ + params[0].integer.value = ipc_cmd->cmd; + params[1].integer.value = ipc_cmd->sub_cmd; + params[2].integer.value = ipc_cmd->size; + params[3].integer.value = ipc_cmd->wbuf[0]; + params[4].integer.value = ipc_cmd->wbuf[1]; + params[5].integer.value = ipc_cmd->wbuf[2]; + params[6].integer.value = ipc_cmd->wbuf[3]; + + status = acpi_evaluate_object(NULL, "\\IPCS", &arg_list, &buffer); + if (ACPI_FAILURE(status)) + return -ENODEV; + + obj = buffer.pointer; + + if (obj && obj->type == ACPI_TYPE_PACKAGE && + obj->package.count == VALID_IPC_RESPONSE) { + const union acpi_object *objs = obj->package.elements; + + if ((u8)objs[0].integer.value != 0) + return -EINVAL; + + rbuf->buf[0] = objs[1].integer.value; + rbuf->buf[1] = objs[2].integer.value; + rbuf->buf[2] = objs[3].integer.value; + rbuf->buf[3] = objs[4].integer.value; + } else { + return -EINVAL; + } + + return 0; +} + +#endif /* INTEL_PMC_IPC_H */ |