s = ((conststruct scmi_sens_ipriv *)p)->priv; /* Set the number of sensors to be skipped/already read */
msg->id = cpu_to_le32(s->id);
msg->index = cpu_to_le32(desc_index);
}
/* * Pick the corresponding descriptor based on the axis_id embedded * in the reply since the list of axes supporting extended names * can be a subset of all the axes.
*/
a = &apriv->s->axis[axis_id];
strscpy(a->name, adesc->name, SCMI_MAX_STR_SIZE);
st->priv = ++adesc;
iter = ph->hops->iter_response_init(ph, &ops, s->num_axis,
SENSOR_AXIS_NAME_GET, sizeof(struct scmi_msg_sensor_axis_description_get),
&apriv); if (IS_ERR(iter)) return PTR_ERR(iter);
/* * Do not cause whole protocol initialization failure when failing to * get extended names for axes.
*/
ret = ph->hops->iter_response_run(iter); if (ret)
dev_warn(ph->dev, "Failed to get axes extended names for %s (ret:%d).\n",
s->name, ret);
s = &si->sensors[st->desc_index + st->loop_idx];
s->id = le32_to_cpu(sdesc->id);
attrl = le32_to_cpu(sdesc->attributes_low); /* common bitfields parsing */
s->async = SUPPORTS_ASYNC_READ(attrl);
s->num_trip_points = NUM_TRIP_POINTS(attrl); /** * only SCMIv3.0 specific bitfield below. * Such bitfields are assumed to be zeroed on non * relevant fw versions...assuming fw not buggy !
*/ if (si->notify_continuos_update_cmd)
s->update = SUPPORTS_UPDATE_NOTIFY(attrl);
s->timestamped = SUPPORTS_TIMESTAMP(attrl); if (s->timestamped)
s->tstamp_scale = S32_EXT(SENSOR_TSTAMP_EXP(attrl));
s->extended_scalar_attrs = SUPPORTS_EXTEND_ATTRS(attrl);
attrh = le32_to_cpu(sdesc->attributes_high); /* common bitfields parsing */
s->scale = S32_EXT(SENSOR_SCALE(attrh));
s->type = SENSOR_TYPE(attrh); /* Use pre-allocated pool wherever possible */
s->intervals.desc = s->intervals.prealloc_pool; if (si->version == SCMIv2_SENSOR_PROTOCOL) {
s->intervals.segmented = false;
s->intervals.count = 1; /* * Convert SCMIv2.0 update interval format to * SCMIv3.0 to be used as the common exposed * descriptor, accessible via common macros.
*/
s->intervals.desc[0] = (SENSOR_UPDATE_BASE(attrh) << 5) |
SENSOR_UPDATE_SCALE(attrh);
} else { /* * From SCMIv3.0 update intervals are retrieved * via a dedicated (optional) command. * Since the command is optional, on error carry * on without any update interval.
*/ if (scmi_sensor_update_intervals(ph, s))
dev_dbg(ph->dev, "Update Intervals not available for sensor ID:%d\n",
s->id);
} /** * only > SCMIv2.0 specific bitfield below. * Such bitfields are assumed to be zeroed on non * relevant fw versions...assuming fw not buggy !
*/
s->num_axis = min_t(unsignedint,
SUPPORTS_AXIS(attrh) ?
SENSOR_AXIS_NUMBER(attrh) : 0,
SCMI_MAX_NUM_SENSOR_AXIS);
strscpy(s->name, sdesc->name, SCMI_SHORT_NAME_MAX_SIZE);
/* * If supported overwrite short name with the extended * one; on error just carry on and use already provided * short name.
*/ if (PROTOCOL_REV_MAJOR(si->version) >= 0x3 &&
SUPPORTS_EXTENDED_NAMES(attrl))
ph->hops->extended_name_get(ph, SENSOR_NAME_GET, s->id,
NULL, s->name, SCMI_MAX_STR_SIZE);
if (s->extended_scalar_attrs) {
s->sensor_power = le32_to_cpu(sdesc->power);
dsize += sizeof(sdesc->power);
/* Only for sensors reporting scalar values */ if (s->num_axis == 0) { unsignedint sres = le32_to_cpu(sdesc->resolution);
ret = ph->xops->do_xfer(ph, t); if (!ret) { struct scmi_sensor_info *s = si->sensors + sensor_id;
s->sensor_config = sensor_config;
}
ph->xops->xfer_put(ph, t); return ret;
}
/** * scmi_sensor_reading_get - Read scalar sensor value * @ph: Protocol handle * @sensor_id: Sensor ID * @value: The 64bit value sensor reading * * This function returns a single 64 bit reading value representing the sensor * value; if the platform SCMI Protocol implementation and the sensor support * multiple axis and timestamped-reads, this just returns the first axis while * dropping the timestamp value. * Use instead the @scmi_sensor_reading_get_timestamped to retrieve the array of * timestamped multi-axis values. * * Return: 0 on Success
*/ staticint scmi_sensor_reading_get(conststruct scmi_protocol_handle *ph,
u32 sensor_id, u64 *value)
{ int ret; struct scmi_xfer *t; struct scmi_msg_sensor_reading_get *sensor; struct scmi_sensor_info *s; struct sensors_info *si = ph->get_priv(ph);
if (sensor_id >= si->num_sensors) return -EINVAL;
ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET, sizeof(*sensor), 0, &t); if (ret) return ret;
sensor = t->tx.buf;
sensor->id = cpu_to_le32(sensor_id);
s = si->sensors + sensor_id; if (s->async) {
sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
ret = ph->xops->do_xfer_with_response(ph, t); if (!ret) { struct scmi_resp_sensor_reading_complete *resp;
resp = t->rx.buf; if (le32_to_cpu(resp->id) == sensor_id)
*value =
get_unaligned_le64(&resp->readings_low); else
ret = -EPROTO;
}
} else {
sensor->flags = cpu_to_le32(0);
ret = ph->xops->do_xfer(ph, t); if (!ret)
*value = get_unaligned_le64(t->rx.buf);
}
/** * scmi_sensor_reading_get_timestamped - Read multiple-axis timestamped values * @ph: Protocol handle * @sensor_id: Sensor ID * @count: The length of the provided @readings array * @readings: An array of elements each representing a timestamped per-axis * reading of type @struct scmi_sensor_reading. * Returned readings are ordered as the @axis descriptors array * included in @struct scmi_sensor_info and the max number of * returned elements is min(@count, @num_axis); ideally the provided * array should be of length @count equal to @num_axis. * * Return: 0 on Success
*/ staticint
scmi_sensor_reading_get_timestamped(conststruct scmi_protocol_handle *ph,
u32 sensor_id, u8 count, struct scmi_sensor_reading *readings)
{ int ret; struct scmi_xfer *t; struct scmi_msg_sensor_reading_get *sensor; struct scmi_sensor_info *s; struct sensors_info *si = ph->get_priv(ph);
ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET, sizeof(*sensor), 0, &t); if (ret) return ret;
sensor = t->tx.buf;
sensor->id = cpu_to_le32(sensor_id); if (s->async) {
sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
ret = ph->xops->do_xfer_with_response(ph, t); if (!ret) { int i; struct scmi_resp_sensor_reading_complete_v3 *resp;
resp = t->rx.buf; /* Retrieve only the number of requested axis anyway */ if (le32_to_cpu(resp->id) == sensor_id) for (i = 0; i < count; i++)
scmi_parse_sensor_readings(&readings[i],
&resp->readings[i]); else
ret = -EPROTO;
}
} else {
sensor->flags = cpu_to_le32(0);
ret = ph->xops->do_xfer(ph, t); if (!ret) { int i; struct scmi_sensor_reading_resp *resp_readings;
resp_readings = t->rx.buf; for (i = 0; i < count; i++)
scmi_parse_sensor_readings(&readings[i],
&resp_readings[i]);
}
}
switch (evt_id) { case SCMI_EVENT_SENSOR_TRIP_POINT_EVENT:
ret = scmi_sensor_trip_point_notify(ph, src_id, enable); break; case SCMI_EVENT_SENSOR_UPDATE:
ret = scmi_sensor_continuous_update_notify(ph, src_id, enable); break; default:
ret = -EINVAL; break;
}
/* payld_sz is variable for this event */
r->sensor_id = le32_to_cpu(p->sensor_id); if (r->sensor_id >= sinfo->num_sensors) break;
r->timestamp = timestamp;
r->agent_id = le32_to_cpu(p->agent_id);
s = &sinfo->sensors[r->sensor_id]; /* * The generated report r (@struct scmi_sensor_update_report) * was pre-allocated to contain up to SCMI_MAX_NUM_SENSOR_AXIS * readings: here it is filled with the effective @num_axis * readings defined for this sensor or 1 for scalar sensors.
*/
r->readings_count = s->num_axis ?: 1; for (i = 0; i < r->readings_count; i++)
scmi_parse_sensor_readings(&r->readings[i],
&p->readings[i]);
*src_id = r->sensor_id;
rep = r; break;
} default: break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.