0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) "SCMI Notifications SENSOR - " fmt
0009
0010 #include <linux/bitfield.h>
0011 #include <linux/module.h>
0012 #include <linux/scmi_protocol.h>
0013
0014 #include "protocols.h"
0015 #include "notify.h"
0016
0017 #define SCMI_MAX_NUM_SENSOR_AXIS 63
0018 #define SCMIv2_SENSOR_PROTOCOL 0x10000
0019
0020 enum scmi_sensor_protocol_cmd {
0021 SENSOR_DESCRIPTION_GET = 0x3,
0022 SENSOR_TRIP_POINT_NOTIFY = 0x4,
0023 SENSOR_TRIP_POINT_CONFIG = 0x5,
0024 SENSOR_READING_GET = 0x6,
0025 SENSOR_AXIS_DESCRIPTION_GET = 0x7,
0026 SENSOR_LIST_UPDATE_INTERVALS = 0x8,
0027 SENSOR_CONFIG_GET = 0x9,
0028 SENSOR_CONFIG_SET = 0xA,
0029 SENSOR_CONTINUOUS_UPDATE_NOTIFY = 0xB,
0030 SENSOR_NAME_GET = 0xC,
0031 SENSOR_AXIS_NAME_GET = 0xD,
0032 };
0033
0034 struct scmi_msg_resp_sensor_attributes {
0035 __le16 num_sensors;
0036 u8 max_requests;
0037 u8 reserved;
0038 __le32 reg_addr_low;
0039 __le32 reg_addr_high;
0040 __le32 reg_size;
0041 };
0042
0043
0044 #define SUPPORTS_UPDATE_NOTIFY(x) FIELD_GET(BIT(30), (x))
0045 #define SENSOR_TSTAMP_EXP(x) FIELD_GET(GENMASK(14, 10), (x))
0046 #define SUPPORTS_TIMESTAMP(x) FIELD_GET(BIT(9), (x))
0047 #define SUPPORTS_EXTEND_ATTRS(x) FIELD_GET(BIT(8), (x))
0048
0049
0050 #define SENSOR_UPDATE_BASE(x) FIELD_GET(GENMASK(31, 27), (x))
0051 #define SENSOR_UPDATE_SCALE(x) FIELD_GET(GENMASK(26, 22), (x))
0052
0053
0054 #define SENSOR_AXIS_NUMBER(x) FIELD_GET(GENMASK(21, 16), (x))
0055 #define SUPPORTS_AXIS(x) FIELD_GET(BIT(8), (x))
0056
0057
0058 #define SENSOR_RES(x) FIELD_GET(GENMASK(26, 0), (x))
0059 #define SENSOR_RES_EXP(x) FIELD_GET(GENMASK(31, 27), (x))
0060
0061 struct scmi_msg_resp_attrs {
0062 __le32 min_range_low;
0063 __le32 min_range_high;
0064 __le32 max_range_low;
0065 __le32 max_range_high;
0066 };
0067
0068 struct scmi_msg_sensor_description {
0069 __le32 desc_index;
0070 };
0071
0072 struct scmi_msg_resp_sensor_description {
0073 __le16 num_returned;
0074 __le16 num_remaining;
0075 struct scmi_sensor_descriptor {
0076 __le32 id;
0077 __le32 attributes_low;
0078
0079 #define SUPPORTS_ASYNC_READ(x) FIELD_GET(BIT(31), (x))
0080 #define SUPPORTS_EXTENDED_NAMES(x) FIELD_GET(BIT(29), (x))
0081 #define NUM_TRIP_POINTS(x) FIELD_GET(GENMASK(7, 0), (x))
0082 __le32 attributes_high;
0083
0084 #define SENSOR_SCALE(x) FIELD_GET(GENMASK(15, 11), (x))
0085 #define SENSOR_SCALE_SIGN BIT(4)
0086 #define SENSOR_SCALE_EXTEND GENMASK(31, 5)
0087 #define SENSOR_TYPE(x) FIELD_GET(GENMASK(7, 0), (x))
0088 u8 name[SCMI_SHORT_NAME_MAX_SIZE];
0089
0090 __le32 power;
0091 __le32 resolution;
0092 struct scmi_msg_resp_attrs scalar_attrs;
0093 } desc[];
0094 };
0095
0096
0097 #define SCMI_MSG_RESP_SENS_DESCR_BASE_SZ 28
0098
0099
0100 #define S32_EXT(v) \
0101 ({ \
0102 int __v = (v); \
0103 \
0104 if (__v & SENSOR_SCALE_SIGN) \
0105 __v |= SENSOR_SCALE_EXTEND; \
0106 __v; \
0107 })
0108
0109 struct scmi_msg_sensor_axis_description_get {
0110 __le32 id;
0111 __le32 axis_desc_index;
0112 };
0113
0114 struct scmi_msg_resp_sensor_axis_description {
0115 __le32 num_axis_flags;
0116 #define NUM_AXIS_RETURNED(x) FIELD_GET(GENMASK(5, 0), (x))
0117 #define NUM_AXIS_REMAINING(x) FIELD_GET(GENMASK(31, 26), (x))
0118 struct scmi_axis_descriptor {
0119 __le32 id;
0120 __le32 attributes_low;
0121 #define SUPPORTS_EXTENDED_AXIS_NAMES(x) FIELD_GET(BIT(9), (x))
0122 __le32 attributes_high;
0123 u8 name[SCMI_SHORT_NAME_MAX_SIZE];
0124 __le32 resolution;
0125 struct scmi_msg_resp_attrs attrs;
0126 } desc[];
0127 };
0128
0129 struct scmi_msg_resp_sensor_axis_names_description {
0130 __le32 num_axis_flags;
0131 struct scmi_sensor_axis_name_descriptor {
0132 __le32 axis_id;
0133 u8 name[SCMI_MAX_STR_SIZE];
0134 } desc[];
0135 };
0136
0137
0138 #define SCMI_MSG_RESP_AXIS_DESCR_BASE_SZ 28
0139
0140 struct scmi_msg_sensor_list_update_intervals {
0141 __le32 id;
0142 __le32 index;
0143 };
0144
0145 struct scmi_msg_resp_sensor_list_update_intervals {
0146 __le32 num_intervals_flags;
0147 #define NUM_INTERVALS_RETURNED(x) FIELD_GET(GENMASK(11, 0), (x))
0148 #define SEGMENTED_INTVL_FORMAT(x) FIELD_GET(BIT(12), (x))
0149 #define NUM_INTERVALS_REMAINING(x) FIELD_GET(GENMASK(31, 16), (x))
0150 __le32 intervals[];
0151 };
0152
0153 struct scmi_msg_sensor_request_notify {
0154 __le32 id;
0155 __le32 event_control;
0156 #define SENSOR_NOTIFY_ALL BIT(0)
0157 };
0158
0159 struct scmi_msg_set_sensor_trip_point {
0160 __le32 id;
0161 __le32 event_control;
0162 #define SENSOR_TP_EVENT_MASK (0x3)
0163 #define SENSOR_TP_DISABLED 0x0
0164 #define SENSOR_TP_POSITIVE 0x1
0165 #define SENSOR_TP_NEGATIVE 0x2
0166 #define SENSOR_TP_BOTH 0x3
0167 #define SENSOR_TP_ID(x) (((x) & 0xff) << 4)
0168 __le32 value_low;
0169 __le32 value_high;
0170 };
0171
0172 struct scmi_msg_sensor_config_set {
0173 __le32 id;
0174 __le32 sensor_config;
0175 };
0176
0177 struct scmi_msg_sensor_reading_get {
0178 __le32 id;
0179 __le32 flags;
0180 #define SENSOR_READ_ASYNC BIT(0)
0181 };
0182
0183 struct scmi_resp_sensor_reading_complete {
0184 __le32 id;
0185 __le32 readings_low;
0186 __le32 readings_high;
0187 };
0188
0189 struct scmi_sensor_reading_resp {
0190 __le32 sensor_value_low;
0191 __le32 sensor_value_high;
0192 __le32 timestamp_low;
0193 __le32 timestamp_high;
0194 };
0195
0196 struct scmi_resp_sensor_reading_complete_v3 {
0197 __le32 id;
0198 struct scmi_sensor_reading_resp readings[];
0199 };
0200
0201 struct scmi_sensor_trip_notify_payld {
0202 __le32 agent_id;
0203 __le32 sensor_id;
0204 __le32 trip_point_desc;
0205 };
0206
0207 struct scmi_sensor_update_notify_payld {
0208 __le32 agent_id;
0209 __le32 sensor_id;
0210 struct scmi_sensor_reading_resp readings[];
0211 };
0212
0213 struct sensors_info {
0214 u32 version;
0215 int num_sensors;
0216 int max_requests;
0217 u64 reg_addr;
0218 u32 reg_size;
0219 struct scmi_sensor_info *sensors;
0220 };
0221
0222 static int scmi_sensor_attributes_get(const struct scmi_protocol_handle *ph,
0223 struct sensors_info *si)
0224 {
0225 int ret;
0226 struct scmi_xfer *t;
0227 struct scmi_msg_resp_sensor_attributes *attr;
0228
0229 ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES,
0230 0, sizeof(*attr), &t);
0231 if (ret)
0232 return ret;
0233
0234 attr = t->rx.buf;
0235
0236 ret = ph->xops->do_xfer(ph, t);
0237 if (!ret) {
0238 si->num_sensors = le16_to_cpu(attr->num_sensors);
0239 si->max_requests = attr->max_requests;
0240 si->reg_addr = le32_to_cpu(attr->reg_addr_low) |
0241 (u64)le32_to_cpu(attr->reg_addr_high) << 32;
0242 si->reg_size = le32_to_cpu(attr->reg_size);
0243 }
0244
0245 ph->xops->xfer_put(ph, t);
0246 return ret;
0247 }
0248
0249 static inline void scmi_parse_range_attrs(struct scmi_range_attrs *out,
0250 const struct scmi_msg_resp_attrs *in)
0251 {
0252 out->min_range = get_unaligned_le64((void *)&in->min_range_low);
0253 out->max_range = get_unaligned_le64((void *)&in->max_range_low);
0254 }
0255
0256 struct scmi_sens_ipriv {
0257 void *priv;
0258 struct device *dev;
0259 };
0260
0261 static void iter_intervals_prepare_message(void *message,
0262 unsigned int desc_index,
0263 const void *p)
0264 {
0265 struct scmi_msg_sensor_list_update_intervals *msg = message;
0266 const struct scmi_sensor_info *s;
0267
0268 s = ((const struct scmi_sens_ipriv *)p)->priv;
0269
0270 msg->id = cpu_to_le32(s->id);
0271 msg->index = cpu_to_le32(desc_index);
0272 }
0273
0274 static int iter_intervals_update_state(struct scmi_iterator_state *st,
0275 const void *response, void *p)
0276 {
0277 u32 flags;
0278 struct scmi_sensor_info *s = ((struct scmi_sens_ipriv *)p)->priv;
0279 struct device *dev = ((struct scmi_sens_ipriv *)p)->dev;
0280 const struct scmi_msg_resp_sensor_list_update_intervals *r = response;
0281
0282 flags = le32_to_cpu(r->num_intervals_flags);
0283 st->num_returned = NUM_INTERVALS_RETURNED(flags);
0284 st->num_remaining = NUM_INTERVALS_REMAINING(flags);
0285
0286
0287
0288
0289
0290 if (!st->max_resources) {
0291 s->intervals.segmented = SEGMENTED_INTVL_FORMAT(flags);
0292 s->intervals.count = st->num_returned + st->num_remaining;
0293
0294 if (s->intervals.segmented &&
0295 (st->num_remaining || st->num_returned != 3)) {
0296 dev_err(dev,
0297 "Sensor ID:%d advertises an invalid segmented interval (%d)\n",
0298 s->id, s->intervals.count);
0299 s->intervals.segmented = false;
0300 s->intervals.count = 0;
0301 return -EINVAL;
0302 }
0303
0304 if (s->intervals.count >= SCMI_MAX_PREALLOC_POOL) {
0305 s->intervals.desc =
0306 devm_kcalloc(dev,
0307 s->intervals.count,
0308 sizeof(*s->intervals.desc),
0309 GFP_KERNEL);
0310 if (!s->intervals.desc) {
0311 s->intervals.segmented = false;
0312 s->intervals.count = 0;
0313 return -ENOMEM;
0314 }
0315 }
0316
0317 st->max_resources = s->intervals.count;
0318 }
0319
0320 return 0;
0321 }
0322
0323 static int
0324 iter_intervals_process_response(const struct scmi_protocol_handle *ph,
0325 const void *response,
0326 struct scmi_iterator_state *st, void *p)
0327 {
0328 const struct scmi_msg_resp_sensor_list_update_intervals *r = response;
0329 struct scmi_sensor_info *s = ((struct scmi_sens_ipriv *)p)->priv;
0330
0331 s->intervals.desc[st->desc_index + st->loop_idx] =
0332 le32_to_cpu(r->intervals[st->loop_idx]);
0333
0334 return 0;
0335 }
0336
0337 static int scmi_sensor_update_intervals(const struct scmi_protocol_handle *ph,
0338 struct scmi_sensor_info *s)
0339 {
0340 void *iter;
0341 struct scmi_iterator_ops ops = {
0342 .prepare_message = iter_intervals_prepare_message,
0343 .update_state = iter_intervals_update_state,
0344 .process_response = iter_intervals_process_response,
0345 };
0346 struct scmi_sens_ipriv upriv = {
0347 .priv = s,
0348 .dev = ph->dev,
0349 };
0350
0351 iter = ph->hops->iter_response_init(ph, &ops, s->intervals.count,
0352 SENSOR_LIST_UPDATE_INTERVALS,
0353 sizeof(struct scmi_msg_sensor_list_update_intervals),
0354 &upriv);
0355 if (IS_ERR(iter))
0356 return PTR_ERR(iter);
0357
0358 return ph->hops->iter_response_run(iter);
0359 }
0360
0361 struct scmi_apriv {
0362 bool any_axes_support_extended_names;
0363 struct scmi_sensor_info *s;
0364 };
0365
0366 static void iter_axes_desc_prepare_message(void *message,
0367 const unsigned int desc_index,
0368 const void *priv)
0369 {
0370 struct scmi_msg_sensor_axis_description_get *msg = message;
0371 const struct scmi_apriv *apriv = priv;
0372
0373
0374 msg->id = cpu_to_le32(apriv->s->id);
0375 msg->axis_desc_index = cpu_to_le32(desc_index);
0376 }
0377
0378 static int
0379 iter_axes_desc_update_state(struct scmi_iterator_state *st,
0380 const void *response, void *priv)
0381 {
0382 u32 flags;
0383 const struct scmi_msg_resp_sensor_axis_description *r = response;
0384
0385 flags = le32_to_cpu(r->num_axis_flags);
0386 st->num_returned = NUM_AXIS_RETURNED(flags);
0387 st->num_remaining = NUM_AXIS_REMAINING(flags);
0388 st->priv = (void *)&r->desc[0];
0389
0390 return 0;
0391 }
0392
0393 static int
0394 iter_axes_desc_process_response(const struct scmi_protocol_handle *ph,
0395 const void *response,
0396 struct scmi_iterator_state *st, void *priv)
0397 {
0398 u32 attrh, attrl;
0399 struct scmi_sensor_axis_info *a;
0400 size_t dsize = SCMI_MSG_RESP_AXIS_DESCR_BASE_SZ;
0401 struct scmi_apriv *apriv = priv;
0402 const struct scmi_axis_descriptor *adesc = st->priv;
0403
0404 attrl = le32_to_cpu(adesc->attributes_low);
0405 if (SUPPORTS_EXTENDED_AXIS_NAMES(attrl))
0406 apriv->any_axes_support_extended_names = true;
0407
0408 a = &apriv->s->axis[st->desc_index + st->loop_idx];
0409 a->id = le32_to_cpu(adesc->id);
0410 a->extended_attrs = SUPPORTS_EXTEND_ATTRS(attrl);
0411
0412 attrh = le32_to_cpu(adesc->attributes_high);
0413 a->scale = S32_EXT(SENSOR_SCALE(attrh));
0414 a->type = SENSOR_TYPE(attrh);
0415 strscpy(a->name, adesc->name, SCMI_SHORT_NAME_MAX_SIZE);
0416
0417 if (a->extended_attrs) {
0418 unsigned int ares = le32_to_cpu(adesc->resolution);
0419
0420 a->resolution = SENSOR_RES(ares);
0421 a->exponent = S32_EXT(SENSOR_RES_EXP(ares));
0422 dsize += sizeof(adesc->resolution);
0423
0424 scmi_parse_range_attrs(&a->attrs, &adesc->attrs);
0425 dsize += sizeof(adesc->attrs);
0426 }
0427 st->priv = ((u8 *)adesc + dsize);
0428
0429 return 0;
0430 }
0431
0432 static int
0433 iter_axes_extended_name_update_state(struct scmi_iterator_state *st,
0434 const void *response, void *priv)
0435 {
0436 u32 flags;
0437 const struct scmi_msg_resp_sensor_axis_names_description *r = response;
0438
0439 flags = le32_to_cpu(r->num_axis_flags);
0440 st->num_returned = NUM_AXIS_RETURNED(flags);
0441 st->num_remaining = NUM_AXIS_REMAINING(flags);
0442 st->priv = (void *)&r->desc[0];
0443
0444 return 0;
0445 }
0446
0447 static int
0448 iter_axes_extended_name_process_response(const struct scmi_protocol_handle *ph,
0449 const void *response,
0450 struct scmi_iterator_state *st,
0451 void *priv)
0452 {
0453 struct scmi_sensor_axis_info *a;
0454 const struct scmi_apriv *apriv = priv;
0455 struct scmi_sensor_axis_name_descriptor *adesc = st->priv;
0456 u32 axis_id = le32_to_cpu(adesc->axis_id);
0457
0458 if (axis_id >= st->max_resources)
0459 return -EPROTO;
0460
0461
0462
0463
0464
0465
0466 a = &apriv->s->axis[axis_id];
0467 strscpy(a->name, adesc->name, SCMI_MAX_STR_SIZE);
0468 st->priv = ++adesc;
0469
0470 return 0;
0471 }
0472
0473 static int
0474 scmi_sensor_axis_extended_names_get(const struct scmi_protocol_handle *ph,
0475 struct scmi_sensor_info *s)
0476 {
0477 int ret;
0478 void *iter;
0479 struct scmi_iterator_ops ops = {
0480 .prepare_message = iter_axes_desc_prepare_message,
0481 .update_state = iter_axes_extended_name_update_state,
0482 .process_response = iter_axes_extended_name_process_response,
0483 };
0484 struct scmi_apriv apriv = {
0485 .any_axes_support_extended_names = false,
0486 .s = s,
0487 };
0488
0489 iter = ph->hops->iter_response_init(ph, &ops, s->num_axis,
0490 SENSOR_AXIS_NAME_GET,
0491 sizeof(struct scmi_msg_sensor_axis_description_get),
0492 &apriv);
0493 if (IS_ERR(iter))
0494 return PTR_ERR(iter);
0495
0496
0497
0498
0499
0500 ret = ph->hops->iter_response_run(iter);
0501 if (ret)
0502 dev_warn(ph->dev,
0503 "Failed to get axes extended names for %s (ret:%d).\n",
0504 s->name, ret);
0505
0506 return 0;
0507 }
0508
0509 static int scmi_sensor_axis_description(const struct scmi_protocol_handle *ph,
0510 struct scmi_sensor_info *s,
0511 u32 version)
0512 {
0513 int ret;
0514 void *iter;
0515 struct scmi_iterator_ops ops = {
0516 .prepare_message = iter_axes_desc_prepare_message,
0517 .update_state = iter_axes_desc_update_state,
0518 .process_response = iter_axes_desc_process_response,
0519 };
0520 struct scmi_apriv apriv = {
0521 .any_axes_support_extended_names = false,
0522 .s = s,
0523 };
0524
0525 s->axis = devm_kcalloc(ph->dev, s->num_axis,
0526 sizeof(*s->axis), GFP_KERNEL);
0527 if (!s->axis)
0528 return -ENOMEM;
0529
0530 iter = ph->hops->iter_response_init(ph, &ops, s->num_axis,
0531 SENSOR_AXIS_DESCRIPTION_GET,
0532 sizeof(struct scmi_msg_sensor_axis_description_get),
0533 &apriv);
0534 if (IS_ERR(iter))
0535 return PTR_ERR(iter);
0536
0537 ret = ph->hops->iter_response_run(iter);
0538 if (ret)
0539 return ret;
0540
0541 if (PROTOCOL_REV_MAJOR(version) >= 0x3 &&
0542 apriv.any_axes_support_extended_names)
0543 ret = scmi_sensor_axis_extended_names_get(ph, s);
0544
0545 return ret;
0546 }
0547
0548 static void iter_sens_descr_prepare_message(void *message,
0549 unsigned int desc_index,
0550 const void *priv)
0551 {
0552 struct scmi_msg_sensor_description *msg = message;
0553
0554 msg->desc_index = cpu_to_le32(desc_index);
0555 }
0556
0557 static int iter_sens_descr_update_state(struct scmi_iterator_state *st,
0558 const void *response, void *priv)
0559 {
0560 const struct scmi_msg_resp_sensor_description *r = response;
0561
0562 st->num_returned = le16_to_cpu(r->num_returned);
0563 st->num_remaining = le16_to_cpu(r->num_remaining);
0564 st->priv = (void *)&r->desc[0];
0565
0566 return 0;
0567 }
0568
0569 static int
0570 iter_sens_descr_process_response(const struct scmi_protocol_handle *ph,
0571 const void *response,
0572 struct scmi_iterator_state *st, void *priv)
0573
0574 {
0575 int ret = 0;
0576 u32 attrh, attrl;
0577 size_t dsize = SCMI_MSG_RESP_SENS_DESCR_BASE_SZ;
0578 struct scmi_sensor_info *s;
0579 struct sensors_info *si = priv;
0580 const struct scmi_sensor_descriptor *sdesc = st->priv;
0581
0582 s = &si->sensors[st->desc_index + st->loop_idx];
0583 s->id = le32_to_cpu(sdesc->id);
0584
0585 attrl = le32_to_cpu(sdesc->attributes_low);
0586
0587 s->async = SUPPORTS_ASYNC_READ(attrl);
0588 s->num_trip_points = NUM_TRIP_POINTS(attrl);
0589
0590
0591
0592
0593
0594 s->update = SUPPORTS_UPDATE_NOTIFY(attrl);
0595 s->timestamped = SUPPORTS_TIMESTAMP(attrl);
0596 if (s->timestamped)
0597 s->tstamp_scale = S32_EXT(SENSOR_TSTAMP_EXP(attrl));
0598 s->extended_scalar_attrs = SUPPORTS_EXTEND_ATTRS(attrl);
0599
0600 attrh = le32_to_cpu(sdesc->attributes_high);
0601
0602 s->scale = S32_EXT(SENSOR_SCALE(attrh));
0603 s->type = SENSOR_TYPE(attrh);
0604
0605 s->intervals.desc = s->intervals.prealloc_pool;
0606 if (si->version == SCMIv2_SENSOR_PROTOCOL) {
0607 s->intervals.segmented = false;
0608 s->intervals.count = 1;
0609
0610
0611
0612
0613
0614 s->intervals.desc[0] = (SENSOR_UPDATE_BASE(attrh) << 5) |
0615 SENSOR_UPDATE_SCALE(attrh);
0616 } else {
0617
0618
0619
0620
0621
0622
0623 if (scmi_sensor_update_intervals(ph, s))
0624 dev_dbg(ph->dev,
0625 "Update Intervals not available for sensor ID:%d\n",
0626 s->id);
0627 }
0628
0629
0630
0631
0632
0633 s->num_axis = min_t(unsigned int,
0634 SUPPORTS_AXIS(attrh) ?
0635 SENSOR_AXIS_NUMBER(attrh) : 0,
0636 SCMI_MAX_NUM_SENSOR_AXIS);
0637 strscpy(s->name, sdesc->name, SCMI_SHORT_NAME_MAX_SIZE);
0638
0639
0640
0641
0642
0643
0644 if (PROTOCOL_REV_MAJOR(si->version) >= 0x3 &&
0645 SUPPORTS_EXTENDED_NAMES(attrl))
0646 ph->hops->extended_name_get(ph, SENSOR_NAME_GET, s->id,
0647 s->name, SCMI_MAX_STR_SIZE);
0648
0649 if (s->extended_scalar_attrs) {
0650 s->sensor_power = le32_to_cpu(sdesc->power);
0651 dsize += sizeof(sdesc->power);
0652
0653
0654 if (s->num_axis == 0) {
0655 unsigned int sres = le32_to_cpu(sdesc->resolution);
0656
0657 s->resolution = SENSOR_RES(sres);
0658 s->exponent = S32_EXT(SENSOR_RES_EXP(sres));
0659 dsize += sizeof(sdesc->resolution);
0660
0661 scmi_parse_range_attrs(&s->scalar_attrs,
0662 &sdesc->scalar_attrs);
0663 dsize += sizeof(sdesc->scalar_attrs);
0664 }
0665 }
0666
0667 if (s->num_axis > 0)
0668 ret = scmi_sensor_axis_description(ph, s, si->version);
0669
0670 st->priv = ((u8 *)sdesc + dsize);
0671
0672 return ret;
0673 }
0674
0675 static int scmi_sensor_description_get(const struct scmi_protocol_handle *ph,
0676 struct sensors_info *si)
0677 {
0678 void *iter;
0679 struct scmi_iterator_ops ops = {
0680 .prepare_message = iter_sens_descr_prepare_message,
0681 .update_state = iter_sens_descr_update_state,
0682 .process_response = iter_sens_descr_process_response,
0683 };
0684
0685 iter = ph->hops->iter_response_init(ph, &ops, si->num_sensors,
0686 SENSOR_DESCRIPTION_GET,
0687 sizeof(__le32), si);
0688 if (IS_ERR(iter))
0689 return PTR_ERR(iter);
0690
0691 return ph->hops->iter_response_run(iter);
0692 }
0693
0694 static inline int
0695 scmi_sensor_request_notify(const struct scmi_protocol_handle *ph, u32 sensor_id,
0696 u8 message_id, bool enable)
0697 {
0698 int ret;
0699 u32 evt_cntl = enable ? SENSOR_NOTIFY_ALL : 0;
0700 struct scmi_xfer *t;
0701 struct scmi_msg_sensor_request_notify *cfg;
0702
0703 ret = ph->xops->xfer_get_init(ph, message_id, sizeof(*cfg), 0, &t);
0704 if (ret)
0705 return ret;
0706
0707 cfg = t->tx.buf;
0708 cfg->id = cpu_to_le32(sensor_id);
0709 cfg->event_control = cpu_to_le32(evt_cntl);
0710
0711 ret = ph->xops->do_xfer(ph, t);
0712
0713 ph->xops->xfer_put(ph, t);
0714 return ret;
0715 }
0716
0717 static int scmi_sensor_trip_point_notify(const struct scmi_protocol_handle *ph,
0718 u32 sensor_id, bool enable)
0719 {
0720 return scmi_sensor_request_notify(ph, sensor_id,
0721 SENSOR_TRIP_POINT_NOTIFY,
0722 enable);
0723 }
0724
0725 static int
0726 scmi_sensor_continuous_update_notify(const struct scmi_protocol_handle *ph,
0727 u32 sensor_id, bool enable)
0728 {
0729 return scmi_sensor_request_notify(ph, sensor_id,
0730 SENSOR_CONTINUOUS_UPDATE_NOTIFY,
0731 enable);
0732 }
0733
0734 static int
0735 scmi_sensor_trip_point_config(const struct scmi_protocol_handle *ph,
0736 u32 sensor_id, u8 trip_id, u64 trip_value)
0737 {
0738 int ret;
0739 u32 evt_cntl = SENSOR_TP_BOTH;
0740 struct scmi_xfer *t;
0741 struct scmi_msg_set_sensor_trip_point *trip;
0742
0743 ret = ph->xops->xfer_get_init(ph, SENSOR_TRIP_POINT_CONFIG,
0744 sizeof(*trip), 0, &t);
0745 if (ret)
0746 return ret;
0747
0748 trip = t->tx.buf;
0749 trip->id = cpu_to_le32(sensor_id);
0750 trip->event_control = cpu_to_le32(evt_cntl | SENSOR_TP_ID(trip_id));
0751 trip->value_low = cpu_to_le32(trip_value & 0xffffffff);
0752 trip->value_high = cpu_to_le32(trip_value >> 32);
0753
0754 ret = ph->xops->do_xfer(ph, t);
0755
0756 ph->xops->xfer_put(ph, t);
0757 return ret;
0758 }
0759
0760 static int scmi_sensor_config_get(const struct scmi_protocol_handle *ph,
0761 u32 sensor_id, u32 *sensor_config)
0762 {
0763 int ret;
0764 struct scmi_xfer *t;
0765 struct sensors_info *si = ph->get_priv(ph);
0766
0767 if (sensor_id >= si->num_sensors)
0768 return -EINVAL;
0769
0770 ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_GET,
0771 sizeof(__le32), sizeof(__le32), &t);
0772 if (ret)
0773 return ret;
0774
0775 put_unaligned_le32(sensor_id, t->tx.buf);
0776 ret = ph->xops->do_xfer(ph, t);
0777 if (!ret) {
0778 struct scmi_sensor_info *s = si->sensors + sensor_id;
0779
0780 *sensor_config = get_unaligned_le64(t->rx.buf);
0781 s->sensor_config = *sensor_config;
0782 }
0783
0784 ph->xops->xfer_put(ph, t);
0785 return ret;
0786 }
0787
0788 static int scmi_sensor_config_set(const struct scmi_protocol_handle *ph,
0789 u32 sensor_id, u32 sensor_config)
0790 {
0791 int ret;
0792 struct scmi_xfer *t;
0793 struct scmi_msg_sensor_config_set *msg;
0794 struct sensors_info *si = ph->get_priv(ph);
0795
0796 if (sensor_id >= si->num_sensors)
0797 return -EINVAL;
0798
0799 ret = ph->xops->xfer_get_init(ph, SENSOR_CONFIG_SET,
0800 sizeof(*msg), 0, &t);
0801 if (ret)
0802 return ret;
0803
0804 msg = t->tx.buf;
0805 msg->id = cpu_to_le32(sensor_id);
0806 msg->sensor_config = cpu_to_le32(sensor_config);
0807
0808 ret = ph->xops->do_xfer(ph, t);
0809 if (!ret) {
0810 struct scmi_sensor_info *s = si->sensors + sensor_id;
0811
0812 s->sensor_config = sensor_config;
0813 }
0814
0815 ph->xops->xfer_put(ph, t);
0816 return ret;
0817 }
0818
0819
0820
0821
0822
0823
0824
0825
0826
0827
0828
0829
0830
0831
0832
0833
0834 static int scmi_sensor_reading_get(const struct scmi_protocol_handle *ph,
0835 u32 sensor_id, u64 *value)
0836 {
0837 int ret;
0838 struct scmi_xfer *t;
0839 struct scmi_msg_sensor_reading_get *sensor;
0840 struct scmi_sensor_info *s;
0841 struct sensors_info *si = ph->get_priv(ph);
0842
0843 if (sensor_id >= si->num_sensors)
0844 return -EINVAL;
0845
0846 ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET,
0847 sizeof(*sensor), 0, &t);
0848 if (ret)
0849 return ret;
0850
0851 sensor = t->tx.buf;
0852 sensor->id = cpu_to_le32(sensor_id);
0853 s = si->sensors + sensor_id;
0854 if (s->async) {
0855 sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
0856 ret = ph->xops->do_xfer_with_response(ph, t);
0857 if (!ret) {
0858 struct scmi_resp_sensor_reading_complete *resp;
0859
0860 resp = t->rx.buf;
0861 if (le32_to_cpu(resp->id) == sensor_id)
0862 *value =
0863 get_unaligned_le64(&resp->readings_low);
0864 else
0865 ret = -EPROTO;
0866 }
0867 } else {
0868 sensor->flags = cpu_to_le32(0);
0869 ret = ph->xops->do_xfer(ph, t);
0870 if (!ret)
0871 *value = get_unaligned_le64(t->rx.buf);
0872 }
0873
0874 ph->xops->xfer_put(ph, t);
0875 return ret;
0876 }
0877
0878 static inline void
0879 scmi_parse_sensor_readings(struct scmi_sensor_reading *out,
0880 const struct scmi_sensor_reading_resp *in)
0881 {
0882 out->value = get_unaligned_le64((void *)&in->sensor_value_low);
0883 out->timestamp = get_unaligned_le64((void *)&in->timestamp_low);
0884 }
0885
0886
0887
0888
0889
0890
0891
0892
0893
0894
0895
0896
0897
0898
0899
0900 static int
0901 scmi_sensor_reading_get_timestamped(const struct scmi_protocol_handle *ph,
0902 u32 sensor_id, u8 count,
0903 struct scmi_sensor_reading *readings)
0904 {
0905 int ret;
0906 struct scmi_xfer *t;
0907 struct scmi_msg_sensor_reading_get *sensor;
0908 struct scmi_sensor_info *s;
0909 struct sensors_info *si = ph->get_priv(ph);
0910
0911 if (sensor_id >= si->num_sensors)
0912 return -EINVAL;
0913
0914 s = si->sensors + sensor_id;
0915 if (!count || !readings ||
0916 (!s->num_axis && count > 1) || (s->num_axis && count > s->num_axis))
0917 return -EINVAL;
0918
0919 ret = ph->xops->xfer_get_init(ph, SENSOR_READING_GET,
0920 sizeof(*sensor), 0, &t);
0921 if (ret)
0922 return ret;
0923
0924 sensor = t->tx.buf;
0925 sensor->id = cpu_to_le32(sensor_id);
0926 if (s->async) {
0927 sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
0928 ret = ph->xops->do_xfer_with_response(ph, t);
0929 if (!ret) {
0930 int i;
0931 struct scmi_resp_sensor_reading_complete_v3 *resp;
0932
0933 resp = t->rx.buf;
0934
0935 if (le32_to_cpu(resp->id) == sensor_id)
0936 for (i = 0; i < count; i++)
0937 scmi_parse_sensor_readings(&readings[i],
0938 &resp->readings[i]);
0939 else
0940 ret = -EPROTO;
0941 }
0942 } else {
0943 sensor->flags = cpu_to_le32(0);
0944 ret = ph->xops->do_xfer(ph, t);
0945 if (!ret) {
0946 int i;
0947 struct scmi_sensor_reading_resp *resp_readings;
0948
0949 resp_readings = t->rx.buf;
0950 for (i = 0; i < count; i++)
0951 scmi_parse_sensor_readings(&readings[i],
0952 &resp_readings[i]);
0953 }
0954 }
0955
0956 ph->xops->xfer_put(ph, t);
0957 return ret;
0958 }
0959
0960 static const struct scmi_sensor_info *
0961 scmi_sensor_info_get(const struct scmi_protocol_handle *ph, u32 sensor_id)
0962 {
0963 struct sensors_info *si = ph->get_priv(ph);
0964
0965 if (sensor_id >= si->num_sensors)
0966 return NULL;
0967
0968 return si->sensors + sensor_id;
0969 }
0970
0971 static int scmi_sensor_count_get(const struct scmi_protocol_handle *ph)
0972 {
0973 struct sensors_info *si = ph->get_priv(ph);
0974
0975 return si->num_sensors;
0976 }
0977
0978 static const struct scmi_sensor_proto_ops sensor_proto_ops = {
0979 .count_get = scmi_sensor_count_get,
0980 .info_get = scmi_sensor_info_get,
0981 .trip_point_config = scmi_sensor_trip_point_config,
0982 .reading_get = scmi_sensor_reading_get,
0983 .reading_get_timestamped = scmi_sensor_reading_get_timestamped,
0984 .config_get = scmi_sensor_config_get,
0985 .config_set = scmi_sensor_config_set,
0986 };
0987
0988 static int scmi_sensor_set_notify_enabled(const struct scmi_protocol_handle *ph,
0989 u8 evt_id, u32 src_id, bool enable)
0990 {
0991 int ret;
0992
0993 switch (evt_id) {
0994 case SCMI_EVENT_SENSOR_TRIP_POINT_EVENT:
0995 ret = scmi_sensor_trip_point_notify(ph, src_id, enable);
0996 break;
0997 case SCMI_EVENT_SENSOR_UPDATE:
0998 ret = scmi_sensor_continuous_update_notify(ph, src_id, enable);
0999 break;
1000 default:
1001 ret = -EINVAL;
1002 break;
1003 }
1004
1005 if (ret)
1006 pr_debug("FAIL_ENABLED - evt[%X] dom[%d] - ret:%d\n",
1007 evt_id, src_id, ret);
1008
1009 return ret;
1010 }
1011
1012 static void *
1013 scmi_sensor_fill_custom_report(const struct scmi_protocol_handle *ph,
1014 u8 evt_id, ktime_t timestamp,
1015 const void *payld, size_t payld_sz,
1016 void *report, u32 *src_id)
1017 {
1018 void *rep = NULL;
1019
1020 switch (evt_id) {
1021 case SCMI_EVENT_SENSOR_TRIP_POINT_EVENT:
1022 {
1023 const struct scmi_sensor_trip_notify_payld *p = payld;
1024 struct scmi_sensor_trip_point_report *r = report;
1025
1026 if (sizeof(*p) != payld_sz)
1027 break;
1028
1029 r->timestamp = timestamp;
1030 r->agent_id = le32_to_cpu(p->agent_id);
1031 r->sensor_id = le32_to_cpu(p->sensor_id);
1032 r->trip_point_desc = le32_to_cpu(p->trip_point_desc);
1033 *src_id = r->sensor_id;
1034 rep = r;
1035 break;
1036 }
1037 case SCMI_EVENT_SENSOR_UPDATE:
1038 {
1039 int i;
1040 struct scmi_sensor_info *s;
1041 const struct scmi_sensor_update_notify_payld *p = payld;
1042 struct scmi_sensor_update_report *r = report;
1043 struct sensors_info *sinfo = ph->get_priv(ph);
1044
1045
1046 r->sensor_id = le32_to_cpu(p->sensor_id);
1047 if (r->sensor_id >= sinfo->num_sensors)
1048 break;
1049 r->timestamp = timestamp;
1050 r->agent_id = le32_to_cpu(p->agent_id);
1051 s = &sinfo->sensors[r->sensor_id];
1052
1053
1054
1055
1056
1057
1058 r->readings_count = s->num_axis ?: 1;
1059 for (i = 0; i < r->readings_count; i++)
1060 scmi_parse_sensor_readings(&r->readings[i],
1061 &p->readings[i]);
1062 *src_id = r->sensor_id;
1063 rep = r;
1064 break;
1065 }
1066 default:
1067 break;
1068 }
1069
1070 return rep;
1071 }
1072
1073 static int scmi_sensor_get_num_sources(const struct scmi_protocol_handle *ph)
1074 {
1075 struct sensors_info *si = ph->get_priv(ph);
1076
1077 return si->num_sensors;
1078 }
1079
1080 static const struct scmi_event sensor_events[] = {
1081 {
1082 .id = SCMI_EVENT_SENSOR_TRIP_POINT_EVENT,
1083 .max_payld_sz = sizeof(struct scmi_sensor_trip_notify_payld),
1084 .max_report_sz = sizeof(struct scmi_sensor_trip_point_report),
1085 },
1086 {
1087 .id = SCMI_EVENT_SENSOR_UPDATE,
1088 .max_payld_sz =
1089 sizeof(struct scmi_sensor_update_notify_payld) +
1090 SCMI_MAX_NUM_SENSOR_AXIS *
1091 sizeof(struct scmi_sensor_reading_resp),
1092 .max_report_sz = sizeof(struct scmi_sensor_update_report) +
1093 SCMI_MAX_NUM_SENSOR_AXIS *
1094 sizeof(struct scmi_sensor_reading),
1095 },
1096 };
1097
1098 static const struct scmi_event_ops sensor_event_ops = {
1099 .get_num_sources = scmi_sensor_get_num_sources,
1100 .set_notify_enabled = scmi_sensor_set_notify_enabled,
1101 .fill_custom_report = scmi_sensor_fill_custom_report,
1102 };
1103
1104 static const struct scmi_protocol_events sensor_protocol_events = {
1105 .queue_sz = SCMI_PROTO_QUEUE_SZ,
1106 .ops = &sensor_event_ops,
1107 .evts = sensor_events,
1108 .num_events = ARRAY_SIZE(sensor_events),
1109 };
1110
1111 static int scmi_sensors_protocol_init(const struct scmi_protocol_handle *ph)
1112 {
1113 u32 version;
1114 int ret;
1115 struct sensors_info *sinfo;
1116
1117 ret = ph->xops->version_get(ph, &version);
1118 if (ret)
1119 return ret;
1120
1121 dev_dbg(ph->dev, "Sensor Version %d.%d\n",
1122 PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
1123
1124 sinfo = devm_kzalloc(ph->dev, sizeof(*sinfo), GFP_KERNEL);
1125 if (!sinfo)
1126 return -ENOMEM;
1127 sinfo->version = version;
1128
1129 ret = scmi_sensor_attributes_get(ph, sinfo);
1130 if (ret)
1131 return ret;
1132 sinfo->sensors = devm_kcalloc(ph->dev, sinfo->num_sensors,
1133 sizeof(*sinfo->sensors), GFP_KERNEL);
1134 if (!sinfo->sensors)
1135 return -ENOMEM;
1136
1137 ret = scmi_sensor_description_get(ph, sinfo);
1138 if (ret)
1139 return ret;
1140
1141 return ph->set_priv(ph, sinfo);
1142 }
1143
1144 static const struct scmi_protocol scmi_sensors = {
1145 .id = SCMI_PROTOCOL_SENSOR,
1146 .owner = THIS_MODULE,
1147 .instance_init = &scmi_sensors_protocol_init,
1148 .ops = &sensor_proto_ops,
1149 .events = &sensor_protocol_events,
1150 };
1151
1152 DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(sensors, scmi_sensors)