Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright 2019 Google LLC
  4 *
  5 * Sysfs properties to view and modify EC-controlled features on Wilco devices.
  6 * The entries will appear under /sys/bus/platform/devices/GOOG000C:00/
  7 *
  8 * See Documentation/ABI/testing/sysfs-platform-wilco-ec for more information.
  9 */
 10
 11#include <linux/platform_data/wilco-ec.h>
 12#include <linux/sysfs.h>
 13
 14#define CMD_KB_CMOS			0x7C
 15#define SUB_CMD_KB_CMOS_AUTO_ON		0x03
 16
 17struct boot_on_ac_request {
 18	u8 cmd;			/* Always CMD_KB_CMOS */
 19	u8 reserved1;
 20	u8 sub_cmd;		/* Always SUB_CMD_KB_CMOS_AUTO_ON */
 21	u8 reserved3to5[3];
 22	u8 val;			/* Either 0 or 1 */
 23	u8 reserved7;
 24} __packed;
 25
 26#define CMD_EC_INFO			0x38
 27enum get_ec_info_op {
 28	CMD_GET_EC_LABEL	= 0,
 29	CMD_GET_EC_REV		= 1,
 30	CMD_GET_EC_MODEL	= 2,
 31	CMD_GET_EC_BUILD_DATE	= 3,
 32};
 33
 34struct get_ec_info_req {
 35	u8 cmd;			/* Always CMD_EC_INFO */
 36	u8 reserved;
 37	u8 op;			/* One of enum get_ec_info_op */
 38} __packed;
 39
 40struct get_ec_info_resp {
 41	u8 reserved[2];
 42	char value[9]; /* __nonstring: might not be null terminated */
 43} __packed;
 44
 45static ssize_t boot_on_ac_store(struct device *dev,
 46				struct device_attribute *attr,
 47				const char *buf, size_t count)
 48{
 49	struct wilco_ec_device *ec = dev_get_drvdata(dev);
 50	struct boot_on_ac_request rq;
 51	struct wilco_ec_message msg;
 52	int ret;
 53	u8 val;
 54
 55	ret = kstrtou8(buf, 10, &val);
 56	if (ret < 0)
 57		return ret;
 58	if (val > 1)
 59		return -EINVAL;
 60
 61	memset(&rq, 0, sizeof(rq));
 62	rq.cmd = CMD_KB_CMOS;
 63	rq.sub_cmd = SUB_CMD_KB_CMOS_AUTO_ON;
 64	rq.val = val;
 65
 66	memset(&msg, 0, sizeof(msg));
 67	msg.type = WILCO_EC_MSG_LEGACY;
 68	msg.request_data = &rq;
 69	msg.request_size = sizeof(rq);
 70	ret = wilco_ec_mailbox(ec, &msg);
 71	if (ret < 0)
 72		return ret;
 73
 74	return count;
 75}
 76
 77static DEVICE_ATTR_WO(boot_on_ac);
 78
 79static ssize_t get_info(struct device *dev, char *buf, enum get_ec_info_op op)
 80{
 81	struct wilco_ec_device *ec = dev_get_drvdata(dev);
 82	struct get_ec_info_req req = { .cmd = CMD_EC_INFO, .op = op };
 83	struct get_ec_info_resp resp;
 84	int ret;
 85
 86	struct wilco_ec_message msg = {
 87		.type = WILCO_EC_MSG_LEGACY,
 88		.request_data = &req,
 89		.request_size = sizeof(req),
 90		.response_data = &resp,
 91		.response_size = sizeof(resp),
 92	};
 93
 94	ret = wilco_ec_mailbox(ec, &msg);
 95	if (ret < 0)
 96		return ret;
 97
 98	return scnprintf(buf, PAGE_SIZE, "%.*s\n", (int)sizeof(resp.value),
 99			 (char *)&resp.value);
100}
101
102static ssize_t version_show(struct device *dev, struct device_attribute *attr,
103			  char *buf)
104{
105	return get_info(dev, buf, CMD_GET_EC_LABEL);
106}
107
108static DEVICE_ATTR_RO(version);
109
110static ssize_t build_revision_show(struct device *dev,
111				   struct device_attribute *attr, char *buf)
112{
113	return get_info(dev, buf, CMD_GET_EC_REV);
114}
115
116static DEVICE_ATTR_RO(build_revision);
117
118static ssize_t build_date_show(struct device *dev,
119			       struct device_attribute *attr, char *buf)
120{
121	return get_info(dev, buf, CMD_GET_EC_BUILD_DATE);
122}
123
124static DEVICE_ATTR_RO(build_date);
125
126static ssize_t model_number_show(struct device *dev,
127				 struct device_attribute *attr, char *buf)
128{
129	return get_info(dev, buf, CMD_GET_EC_MODEL);
130}
131
132static DEVICE_ATTR_RO(model_number);
133
134
135static struct attribute *wilco_dev_attrs[] = {
136	&dev_attr_boot_on_ac.attr,
137	&dev_attr_build_date.attr,
138	&dev_attr_build_revision.attr,
139	&dev_attr_model_number.attr,
140	&dev_attr_version.attr,
141	NULL,
142};
143
144static struct attribute_group wilco_dev_attr_group = {
145	.attrs = wilco_dev_attrs,
146};
147
148int wilco_ec_add_sysfs(struct wilco_ec_device *ec)
149{
150	return sysfs_create_group(&ec->dev->kobj, &wilco_dev_attr_group);
151}
152
153void wilco_ec_remove_sysfs(struct wilco_ec_device *ec)
154{
155	sysfs_remove_group(&ec->dev->kobj, &wilco_dev_attr_group);
156}