aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Medhurst <tixy@linaro.org>2015-04-21 17:04:40 +0100
committerJon Medhurst <tixy@linaro.org>2015-10-19 13:03:09 +0100
commit9a9af5034b505dc301093464f64c0a1988553897 (patch)
treea5e0509979e3563f4fa0ee647868a778a5d01225
parent1bd5fd49013be625f40117dbe60934ab41fb226d (diff)
firmware: arm_scpi: Add support for getting sensors and values
Signed-off-by: Jon Medhurst <tixy@linaro.org>
-rw-r--r--drivers/firmware/arm_scpi.c59
-rw-r--r--include/linux/scpi_protocol.h2
2 files changed, 61 insertions, 0 deletions
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
index 5e3898f24b96..71c56c0b513a 100644
--- a/drivers/firmware/arm_scpi.c
+++ b/drivers/firmware/arm_scpi.c
@@ -219,6 +219,21 @@ struct dvfs_set {
u8 index;
} __packed;
+struct sensor_capabilities {
+ __le16 sensors;
+} __packed;
+
+struct sensor_info {
+ __le16 id;
+ u8 class;
+ u8 triggers;
+ u8 name[20];
+} __packed;
+
+struct sensor_value {
+ __le32 value;
+} __packed;
+
static struct scpi_drvinfo *scpi_info;
static int scpi_linux_errmap[SCPI_ERR_MAX] = {
@@ -481,6 +496,48 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain)
return info;
}
+static int scpi_sensor_get_id(char *name)
+{
+ struct sensor_capabilities caps;
+ u16 sensors, sensor_id;
+ int ret;
+
+ ret = scpi_send_message(SCPI_CMD_SENSOR_CAPABILITIES,
+ NULL, 0, &caps, sizeof(caps));
+ if (ret)
+ return ret;
+ sensors = le16_to_cpu(caps.sensors);
+
+ for (sensor_id = 0; sensor_id < sensors; sensor_id++) {
+
+ struct sensor_info info;
+ __le16 le_sensor_id = cpu_to_le16(sensor_id);
+ ret = scpi_send_message(SCPI_CMD_SENSOR_INFO, &le_sensor_id,
+ sizeof(le_sensor_id), &info, sizeof(info));
+ if (ret)
+ return ret;
+
+ if (strcmp(name, info.name) == 0)
+ return sensor_id;
+ }
+
+ return -ENODEV;
+}
+
+static int scpi_sensor_get_value(u16 sensor_id, u32 *value)
+{
+ struct sensor_value val;
+ __le16 le_sensor_id = cpu_to_le16(sensor_id);
+ int ret;
+
+ ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &le_sensor_id,
+ sizeof(le_sensor_id), &val, sizeof(val));
+ if (ret == 0)
+ *value = le32_to_cpu(val.value);
+
+ return ret;
+}
+
static struct scpi_ops scpi_ops = {
.get_version = scpi_get_version,
.clk_get_range = scpi_clk_get_range,
@@ -489,6 +546,8 @@ static struct scpi_ops scpi_ops = {
.dvfs_get_idx = scpi_dvfs_get_idx,
.dvfs_set_idx = scpi_dvfs_set_idx,
.dvfs_get_info = scpi_dvfs_get_info,
+ .sensor_get_id = scpi_sensor_get_id,
+ .sensor_get_value = scpi_sensor_get_value,
};
struct scpi_ops *get_scpi_ops(void)
diff --git a/include/linux/scpi_protocol.h b/include/linux/scpi_protocol.h
index e7169cd54e19..9ac852801b11 100644
--- a/include/linux/scpi_protocol.h
+++ b/include/linux/scpi_protocol.h
@@ -52,6 +52,8 @@ struct scpi_ops {
int (*dvfs_get_idx)(u8);
int (*dvfs_set_idx)(u8, u8);
struct scpi_dvfs_info *(*dvfs_get_info)(u8);
+ int (*sensor_get_id)(char *);
+ int (*sensor_get_value)(u16, u32 *);
};
#if IS_ENABLED(CONFIG_ARM_SCPI_PROTOCOL)