1 // SPDX-License-Identifier: GPL-2.0
3 * System Control and Management Interface (SCMI) Sensor Protocol
5 * Copyright (C) 2018-2022 ARM Ltd.
8 #define pr_fmt(fmt) "SCMI Notifications SENSOR - " fmt
10 #include <linux/bitfield.h>
11 #include <linux/module.h>
12 #include <linux/scmi_protocol.h>
14 #include "protocols.h"
17 /* Updated only after ALL the mandatory features for that version are merged */
18 #define SCMI_PROTOCOL_SUPPORTED_VERSION 0x30001
20 #define SCMI_MAX_NUM_SENSOR_AXIS 63
21 #define SCMIv2_SENSOR_PROTOCOL 0x10000
23 enum scmi_sensor_protocol_cmd
{
24 SENSOR_DESCRIPTION_GET
= 0x3,
25 SENSOR_TRIP_POINT_NOTIFY
= 0x4,
26 SENSOR_TRIP_POINT_CONFIG
= 0x5,
27 SENSOR_READING_GET
= 0x6,
28 SENSOR_AXIS_DESCRIPTION_GET
= 0x7,
29 SENSOR_LIST_UPDATE_INTERVALS
= 0x8,
30 SENSOR_CONFIG_GET
= 0x9,
31 SENSOR_CONFIG_SET
= 0xA,
32 SENSOR_CONTINUOUS_UPDATE_NOTIFY
= 0xB,
33 SENSOR_NAME_GET
= 0xC,
34 SENSOR_AXIS_NAME_GET
= 0xD,
37 struct scmi_msg_resp_sensor_attributes
{
46 /* v3 attributes_low macros */
47 #define SUPPORTS_UPDATE_NOTIFY(x) FIELD_GET(BIT(30), (x))
48 #define SENSOR_TSTAMP_EXP(x) FIELD_GET(GENMASK(14, 10), (x))
49 #define SUPPORTS_TIMESTAMP(x) FIELD_GET(BIT(9), (x))
50 #define SUPPORTS_EXTEND_ATTRS(x) FIELD_GET(BIT(8), (x))
52 /* v2 attributes_high macros */
53 #define SENSOR_UPDATE_BASE(x) FIELD_GET(GENMASK(31, 27), (x))
54 #define SENSOR_UPDATE_SCALE(x) FIELD_GET(GENMASK(26, 22), (x))
56 /* v3 attributes_high macros */
57 #define SENSOR_AXIS_NUMBER(x) FIELD_GET(GENMASK(21, 16), (x))
58 #define SUPPORTS_AXIS(x) FIELD_GET(BIT(8), (x))
60 /* v3 resolution macros */
61 #define SENSOR_RES(x) FIELD_GET(GENMASK(26, 0), (x))
62 #define SENSOR_RES_EXP(x) FIELD_GET(GENMASK(31, 27), (x))
64 struct scmi_msg_resp_attrs
{
66 __le32 min_range_high
;
68 __le32 max_range_high
;
71 struct scmi_msg_sensor_description
{
75 struct scmi_msg_resp_sensor_description
{
78 struct scmi_sensor_descriptor
{
80 __le32 attributes_low
;
81 /* Common attributes_low macros */
82 #define SUPPORTS_ASYNC_READ(x) FIELD_GET(BIT(31), (x))
83 #define SUPPORTS_EXTENDED_NAMES(x) FIELD_GET(BIT(29), (x))
84 #define NUM_TRIP_POINTS(x) FIELD_GET(GENMASK(7, 0), (x))
85 __le32 attributes_high
;
86 /* Common attributes_high macros */
87 #define SENSOR_SCALE(x) FIELD_GET(GENMASK(15, 11), (x))
88 #define SENSOR_SCALE_SIGN BIT(4)
89 #define SENSOR_SCALE_EXTEND GENMASK(31, 5)
90 #define SENSOR_TYPE(x) FIELD_GET(GENMASK(7, 0), (x))
91 u8 name
[SCMI_SHORT_NAME_MAX_SIZE
];
92 /* only for version > 2.0 */
95 struct scmi_msg_resp_attrs scalar_attrs
;
99 /* Base scmi_sensor_descriptor size excluding extended attrs after name */
100 #define SCMI_MSG_RESP_SENS_DESCR_BASE_SZ 28
102 /* Sign extend to a full s32 */
107 if (__v & SENSOR_SCALE_SIGN) \
108 __v |= SENSOR_SCALE_EXTEND; \
112 struct scmi_msg_sensor_axis_description_get
{
114 __le32 axis_desc_index
;
117 struct scmi_msg_resp_sensor_axis_description
{
118 __le32 num_axis_flags
;
119 #define NUM_AXIS_RETURNED(x) FIELD_GET(GENMASK(5, 0), (x))
120 #define NUM_AXIS_REMAINING(x) FIELD_GET(GENMASK(31, 26), (x))
121 struct scmi_axis_descriptor
{
123 __le32 attributes_low
;
124 #define SUPPORTS_EXTENDED_AXIS_NAMES(x) FIELD_GET(BIT(9), (x))
125 __le32 attributes_high
;
126 u8 name
[SCMI_SHORT_NAME_MAX_SIZE
];
128 struct scmi_msg_resp_attrs attrs
;
132 struct scmi_msg_resp_sensor_axis_names_description
{
133 __le32 num_axis_flags
;
134 struct scmi_sensor_axis_name_descriptor
{
136 u8 name
[SCMI_MAX_STR_SIZE
];
140 /* Base scmi_axis_descriptor size excluding extended attrs after name */
141 #define SCMI_MSG_RESP_AXIS_DESCR_BASE_SZ 28
143 struct scmi_msg_sensor_list_update_intervals
{
148 struct scmi_msg_resp_sensor_list_update_intervals
{
149 __le32 num_intervals_flags
;
150 #define NUM_INTERVALS_RETURNED(x) FIELD_GET(GENMASK(11, 0), (x))
151 #define SEGMENTED_INTVL_FORMAT(x) FIELD_GET(BIT(12), (x))
152 #define NUM_INTERVALS_REMAINING(x) FIELD_GET(GENMASK(31, 16), (x))
156 struct scmi_msg_sensor_request_notify
{
158 __le32 event_control
;
159 #define SENSOR_NOTIFY_ALL BIT(0)
162 struct scmi_msg_set_sensor_trip_point
{
164 __le32 event_control
;
165 #define SENSOR_TP_EVENT_MASK (0x3)
166 #define SENSOR_TP_DISABLED 0x0
167 #define SENSOR_TP_POSITIVE 0x1
168 #define SENSOR_TP_NEGATIVE 0x2
169 #define SENSOR_TP_BOTH 0x3
170 #define SENSOR_TP_ID(x) (((x) & 0xff) << 4)
175 struct scmi_msg_sensor_config_set
{
177 __le32 sensor_config
;
180 struct scmi_msg_sensor_reading_get
{
183 #define SENSOR_READ_ASYNC BIT(0)
186 struct scmi_resp_sensor_reading_complete
{
189 __le32 readings_high
;
192 struct scmi_sensor_reading_resp
{
193 __le32 sensor_value_low
;
194 __le32 sensor_value_high
;
195 __le32 timestamp_low
;
196 __le32 timestamp_high
;
199 struct scmi_resp_sensor_reading_complete_v3
{
201 struct scmi_sensor_reading_resp readings
[];
204 struct scmi_sensor_trip_notify_payld
{
207 __le32 trip_point_desc
;
210 struct scmi_sensor_update_notify_payld
{
213 struct scmi_sensor_reading_resp readings
[];
216 struct sensors_info
{
218 bool notify_trip_point_cmd
;
219 bool notify_continuos_update_cmd
;
224 struct scmi_sensor_info
*sensors
;
227 static int scmi_sensor_attributes_get(const struct scmi_protocol_handle
*ph
,
228 struct sensors_info
*si
)
232 struct scmi_msg_resp_sensor_attributes
*attr
;
234 ret
= ph
->xops
->xfer_get_init(ph
, PROTOCOL_ATTRIBUTES
,
235 0, sizeof(*attr
), &t
);
241 ret
= ph
->xops
->do_xfer(ph
, t
);
243 si
->num_sensors
= le16_to_cpu(attr
->num_sensors
);
244 si
->max_requests
= attr
->max_requests
;
245 si
->reg_addr
= le32_to_cpu(attr
->reg_addr_low
) |
246 (u64
)le32_to_cpu(attr
->reg_addr_high
) << 32;
247 si
->reg_size
= le32_to_cpu(attr
->reg_size
);
250 ph
->xops
->xfer_put(ph
, t
);
253 if (!ph
->hops
->protocol_msg_check(ph
,
254 SENSOR_TRIP_POINT_NOTIFY
, NULL
))
255 si
->notify_trip_point_cmd
= true;
257 if (!ph
->hops
->protocol_msg_check(ph
,
258 SENSOR_CONTINUOUS_UPDATE_NOTIFY
,
260 si
->notify_continuos_update_cmd
= true;
266 static inline void scmi_parse_range_attrs(struct scmi_range_attrs
*out
,
267 const struct scmi_msg_resp_attrs
*in
)
269 out
->min_range
= get_unaligned_le64((void *)&in
->min_range_low
);
270 out
->max_range
= get_unaligned_le64((void *)&in
->max_range_low
);
273 struct scmi_sens_ipriv
{
278 static void iter_intervals_prepare_message(void *message
,
279 unsigned int desc_index
,
282 struct scmi_msg_sensor_list_update_intervals
*msg
= message
;
283 const struct scmi_sensor_info
*s
;
285 s
= ((const struct scmi_sens_ipriv
*)p
)->priv
;
286 /* Set the number of sensors to be skipped/already read */
287 msg
->id
= cpu_to_le32(s
->id
);
288 msg
->index
= cpu_to_le32(desc_index
);
291 static int iter_intervals_update_state(struct scmi_iterator_state
*st
,
292 const void *response
, void *p
)
295 struct scmi_sensor_info
*s
= ((struct scmi_sens_ipriv
*)p
)->priv
;
296 struct device
*dev
= ((struct scmi_sens_ipriv
*)p
)->dev
;
297 const struct scmi_msg_resp_sensor_list_update_intervals
*r
= response
;
299 flags
= le32_to_cpu(r
->num_intervals_flags
);
300 st
->num_returned
= NUM_INTERVALS_RETURNED(flags
);
301 st
->num_remaining
= NUM_INTERVALS_REMAINING(flags
);
304 * Max intervals is not declared previously anywhere so we
305 * assume it's returned+remaining on first call.
307 if (!st
->max_resources
) {
308 s
->intervals
.segmented
= SEGMENTED_INTVL_FORMAT(flags
);
309 s
->intervals
.count
= st
->num_returned
+ st
->num_remaining
;
310 /* segmented intervals are reported in one triplet */
311 if (s
->intervals
.segmented
&&
312 (st
->num_remaining
|| st
->num_returned
!= 3)) {
314 "Sensor ID:%d advertises an invalid segmented interval (%d)\n",
315 s
->id
, s
->intervals
.count
);
316 s
->intervals
.segmented
= false;
317 s
->intervals
.count
= 0;
320 /* Direct allocation when exceeding pre-allocated */
321 if (s
->intervals
.count
>= SCMI_MAX_PREALLOC_POOL
) {
325 sizeof(*s
->intervals
.desc
),
327 if (!s
->intervals
.desc
) {
328 s
->intervals
.segmented
= false;
329 s
->intervals
.count
= 0;
334 st
->max_resources
= s
->intervals
.count
;
341 iter_intervals_process_response(const struct scmi_protocol_handle
*ph
,
342 const void *response
,
343 struct scmi_iterator_state
*st
, void *p
)
345 const struct scmi_msg_resp_sensor_list_update_intervals
*r
= response
;
346 struct scmi_sensor_info
*s
= ((struct scmi_sens_ipriv
*)p
)->priv
;
348 s
->intervals
.desc
[st
->desc_index
+ st
->loop_idx
] =
349 le32_to_cpu(r
->intervals
[st
->loop_idx
]);
354 static int scmi_sensor_update_intervals(const struct scmi_protocol_handle
*ph
,
355 struct scmi_sensor_info
*s
)
358 struct scmi_iterator_ops ops
= {
359 .prepare_message
= iter_intervals_prepare_message
,
360 .update_state
= iter_intervals_update_state
,
361 .process_response
= iter_intervals_process_response
,
363 struct scmi_sens_ipriv upriv
= {
368 iter
= ph
->hops
->iter_response_init(ph
, &ops
, s
->intervals
.count
,
369 SENSOR_LIST_UPDATE_INTERVALS
,
370 sizeof(struct scmi_msg_sensor_list_update_intervals
),
373 return PTR_ERR(iter
);
375 return ph
->hops
->iter_response_run(iter
);
379 bool any_axes_support_extended_names
;
380 struct scmi_sensor_info
*s
;
383 static void iter_axes_desc_prepare_message(void *message
,
384 const unsigned int desc_index
,
387 struct scmi_msg_sensor_axis_description_get
*msg
= message
;
388 const struct scmi_apriv
*apriv
= priv
;
390 /* Set the number of sensors to be skipped/already read */
391 msg
->id
= cpu_to_le32(apriv
->s
->id
);
392 msg
->axis_desc_index
= cpu_to_le32(desc_index
);
396 iter_axes_desc_update_state(struct scmi_iterator_state
*st
,
397 const void *response
, void *priv
)
400 const struct scmi_msg_resp_sensor_axis_description
*r
= response
;
402 flags
= le32_to_cpu(r
->num_axis_flags
);
403 st
->num_returned
= NUM_AXIS_RETURNED(flags
);
404 st
->num_remaining
= NUM_AXIS_REMAINING(flags
);
405 st
->priv
= (void *)&r
->desc
[0];
411 iter_axes_desc_process_response(const struct scmi_protocol_handle
*ph
,
412 const void *response
,
413 struct scmi_iterator_state
*st
, void *priv
)
416 struct scmi_sensor_axis_info
*a
;
417 size_t dsize
= SCMI_MSG_RESP_AXIS_DESCR_BASE_SZ
;
418 struct scmi_apriv
*apriv
= priv
;
419 const struct scmi_axis_descriptor
*adesc
= st
->priv
;
421 attrl
= le32_to_cpu(adesc
->attributes_low
);
422 if (SUPPORTS_EXTENDED_AXIS_NAMES(attrl
))
423 apriv
->any_axes_support_extended_names
= true;
425 a
= &apriv
->s
->axis
[st
->desc_index
+ st
->loop_idx
];
426 a
->id
= le32_to_cpu(adesc
->id
);
427 a
->extended_attrs
= SUPPORTS_EXTEND_ATTRS(attrl
);
429 attrh
= le32_to_cpu(adesc
->attributes_high
);
430 a
->scale
= S32_EXT(SENSOR_SCALE(attrh
));
431 a
->type
= SENSOR_TYPE(attrh
);
432 strscpy(a
->name
, adesc
->name
, SCMI_SHORT_NAME_MAX_SIZE
);
434 if (a
->extended_attrs
) {
435 unsigned int ares
= le32_to_cpu(adesc
->resolution
);
437 a
->resolution
= SENSOR_RES(ares
);
438 a
->exponent
= S32_EXT(SENSOR_RES_EXP(ares
));
439 dsize
+= sizeof(adesc
->resolution
);
441 scmi_parse_range_attrs(&a
->attrs
, &adesc
->attrs
);
442 dsize
+= sizeof(adesc
->attrs
);
444 st
->priv
= ((u8
*)adesc
+ dsize
);
450 iter_axes_extended_name_update_state(struct scmi_iterator_state
*st
,
451 const void *response
, void *priv
)
454 const struct scmi_msg_resp_sensor_axis_names_description
*r
= response
;
456 flags
= le32_to_cpu(r
->num_axis_flags
);
457 st
->num_returned
= NUM_AXIS_RETURNED(flags
);
458 st
->num_remaining
= NUM_AXIS_REMAINING(flags
);
459 st
->priv
= (void *)&r
->desc
[0];
465 iter_axes_extended_name_process_response(const struct scmi_protocol_handle
*ph
,
466 const void *response
,
467 struct scmi_iterator_state
*st
,
470 struct scmi_sensor_axis_info
*a
;
471 const struct scmi_apriv
*apriv
= priv
;
472 struct scmi_sensor_axis_name_descriptor
*adesc
= st
->priv
;
473 u32 axis_id
= le32_to_cpu(adesc
->axis_id
);
475 if (axis_id
>= st
->max_resources
)
479 * Pick the corresponding descriptor based on the axis_id embedded
480 * in the reply since the list of axes supporting extended names
481 * can be a subset of all the axes.
483 a
= &apriv
->s
->axis
[axis_id
];
484 strscpy(a
->name
, adesc
->name
, SCMI_MAX_STR_SIZE
);
491 scmi_sensor_axis_extended_names_get(const struct scmi_protocol_handle
*ph
,
492 struct scmi_sensor_info
*s
)
496 struct scmi_iterator_ops ops
= {
497 .prepare_message
= iter_axes_desc_prepare_message
,
498 .update_state
= iter_axes_extended_name_update_state
,
499 .process_response
= iter_axes_extended_name_process_response
,
501 struct scmi_apriv apriv
= {
502 .any_axes_support_extended_names
= false,
506 iter
= ph
->hops
->iter_response_init(ph
, &ops
, s
->num_axis
,
507 SENSOR_AXIS_NAME_GET
,
508 sizeof(struct scmi_msg_sensor_axis_description_get
),
511 return PTR_ERR(iter
);
514 * Do not cause whole protocol initialization failure when failing to
515 * get extended names for axes.
517 ret
= ph
->hops
->iter_response_run(iter
);
520 "Failed to get axes extended names for %s (ret:%d).\n",
526 static int scmi_sensor_axis_description(const struct scmi_protocol_handle
*ph
,
527 struct scmi_sensor_info
*s
,
532 struct scmi_iterator_ops ops
= {
533 .prepare_message
= iter_axes_desc_prepare_message
,
534 .update_state
= iter_axes_desc_update_state
,
535 .process_response
= iter_axes_desc_process_response
,
537 struct scmi_apriv apriv
= {
538 .any_axes_support_extended_names
= false,
542 s
->axis
= devm_kcalloc(ph
->dev
, s
->num_axis
,
543 sizeof(*s
->axis
), GFP_KERNEL
);
547 iter
= ph
->hops
->iter_response_init(ph
, &ops
, s
->num_axis
,
548 SENSOR_AXIS_DESCRIPTION_GET
,
549 sizeof(struct scmi_msg_sensor_axis_description_get
),
552 return PTR_ERR(iter
);
554 ret
= ph
->hops
->iter_response_run(iter
);
558 if (PROTOCOL_REV_MAJOR(version
) >= 0x3 &&
559 apriv
.any_axes_support_extended_names
)
560 ret
= scmi_sensor_axis_extended_names_get(ph
, s
);
565 static void iter_sens_descr_prepare_message(void *message
,
566 unsigned int desc_index
,
569 struct scmi_msg_sensor_description
*msg
= message
;
571 msg
->desc_index
= cpu_to_le32(desc_index
);
574 static int iter_sens_descr_update_state(struct scmi_iterator_state
*st
,
575 const void *response
, void *priv
)
577 const struct scmi_msg_resp_sensor_description
*r
= response
;
579 st
->num_returned
= le16_to_cpu(r
->num_returned
);
580 st
->num_remaining
= le16_to_cpu(r
->num_remaining
);
581 st
->priv
= (void *)&r
->desc
[0];
587 iter_sens_descr_process_response(const struct scmi_protocol_handle
*ph
,
588 const void *response
,
589 struct scmi_iterator_state
*st
, void *priv
)
594 size_t dsize
= SCMI_MSG_RESP_SENS_DESCR_BASE_SZ
;
595 struct scmi_sensor_info
*s
;
596 struct sensors_info
*si
= priv
;
597 const struct scmi_sensor_descriptor
*sdesc
= st
->priv
;
599 s
= &si
->sensors
[st
->desc_index
+ st
->loop_idx
];
600 s
->id
= le32_to_cpu(sdesc
->id
);
602 attrl
= le32_to_cpu(sdesc
->attributes_low
);
603 /* common bitfields parsing */
604 s
->async
= SUPPORTS_ASYNC_READ(attrl
);
605 s
->num_trip_points
= NUM_TRIP_POINTS(attrl
);
607 * only SCMIv3.0 specific bitfield below.
608 * Such bitfields are assumed to be zeroed on non
609 * relevant fw versions...assuming fw not buggy !
611 if (si
->notify_continuos_update_cmd
)
612 s
->update
= SUPPORTS_UPDATE_NOTIFY(attrl
);
613 s
->timestamped
= SUPPORTS_TIMESTAMP(attrl
);
615 s
->tstamp_scale
= S32_EXT(SENSOR_TSTAMP_EXP(attrl
));
616 s
->extended_scalar_attrs
= SUPPORTS_EXTEND_ATTRS(attrl
);
618 attrh
= le32_to_cpu(sdesc
->attributes_high
);
619 /* common bitfields parsing */
620 s
->scale
= S32_EXT(SENSOR_SCALE(attrh
));
621 s
->type
= SENSOR_TYPE(attrh
);
622 /* Use pre-allocated pool wherever possible */
623 s
->intervals
.desc
= s
->intervals
.prealloc_pool
;
624 if (si
->version
== SCMIv2_SENSOR_PROTOCOL
) {
625 s
->intervals
.segmented
= false;
626 s
->intervals
.count
= 1;
628 * Convert SCMIv2.0 update interval format to
629 * SCMIv3.0 to be used as the common exposed
630 * descriptor, accessible via common macros.
632 s
->intervals
.desc
[0] = (SENSOR_UPDATE_BASE(attrh
) << 5) |
633 SENSOR_UPDATE_SCALE(attrh
);
636 * From SCMIv3.0 update intervals are retrieved
637 * via a dedicated (optional) command.
638 * Since the command is optional, on error carry
639 * on without any update interval.
641 if (scmi_sensor_update_intervals(ph
, s
))
643 "Update Intervals not available for sensor ID:%d\n",
647 * only > SCMIv2.0 specific bitfield below.
648 * Such bitfields are assumed to be zeroed on non
649 * relevant fw versions...assuming fw not buggy !
651 s
->num_axis
= min_t(unsigned int,
652 SUPPORTS_AXIS(attrh
) ?
653 SENSOR_AXIS_NUMBER(attrh
) : 0,
654 SCMI_MAX_NUM_SENSOR_AXIS
);
655 strscpy(s
->name
, sdesc
->name
, SCMI_SHORT_NAME_MAX_SIZE
);
658 * If supported overwrite short name with the extended
659 * one; on error just carry on and use already provided
662 if (PROTOCOL_REV_MAJOR(si
->version
) >= 0x3 &&
663 SUPPORTS_EXTENDED_NAMES(attrl
))
664 ph
->hops
->extended_name_get(ph
, SENSOR_NAME_GET
, s
->id
,
665 NULL
, s
->name
, SCMI_MAX_STR_SIZE
);
667 if (s
->extended_scalar_attrs
) {
668 s
->sensor_power
= le32_to_cpu(sdesc
->power
);
669 dsize
+= sizeof(sdesc
->power
);
671 /* Only for sensors reporting scalar values */
672 if (s
->num_axis
== 0) {
673 unsigned int sres
= le32_to_cpu(sdesc
->resolution
);
675 s
->resolution
= SENSOR_RES(sres
);
676 s
->exponent
= S32_EXT(SENSOR_RES_EXP(sres
));
677 dsize
+= sizeof(sdesc
->resolution
);
679 scmi_parse_range_attrs(&s
->scalar_attrs
,
680 &sdesc
->scalar_attrs
);
681 dsize
+= sizeof(sdesc
->scalar_attrs
);
686 ret
= scmi_sensor_axis_description(ph
, s
, si
->version
);
688 st
->priv
= ((u8
*)sdesc
+ dsize
);
693 static int scmi_sensor_description_get(const struct scmi_protocol_handle
*ph
,
694 struct sensors_info
*si
)
697 struct scmi_iterator_ops ops
= {
698 .prepare_message
= iter_sens_descr_prepare_message
,
699 .update_state
= iter_sens_descr_update_state
,
700 .process_response
= iter_sens_descr_process_response
,
703 iter
= ph
->hops
->iter_response_init(ph
, &ops
, si
->num_sensors
,
704 SENSOR_DESCRIPTION_GET
,
707 return PTR_ERR(iter
);
709 return ph
->hops
->iter_response_run(iter
);
713 scmi_sensor_request_notify(const struct scmi_protocol_handle
*ph
, u32 sensor_id
,
714 u8 message_id
, bool enable
)
717 u32 evt_cntl
= enable
? SENSOR_NOTIFY_ALL
: 0;
719 struct scmi_msg_sensor_request_notify
*cfg
;
721 ret
= ph
->xops
->xfer_get_init(ph
, message_id
, sizeof(*cfg
), 0, &t
);
726 cfg
->id
= cpu_to_le32(sensor_id
);
727 cfg
->event_control
= cpu_to_le32(evt_cntl
);
729 ret
= ph
->xops
->do_xfer(ph
, t
);
731 ph
->xops
->xfer_put(ph
, t
);
735 static int scmi_sensor_trip_point_notify(const struct scmi_protocol_handle
*ph
,
736 u32 sensor_id
, bool enable
)
738 return scmi_sensor_request_notify(ph
, sensor_id
,
739 SENSOR_TRIP_POINT_NOTIFY
,
744 scmi_sensor_continuous_update_notify(const struct scmi_protocol_handle
*ph
,
745 u32 sensor_id
, bool enable
)
747 return scmi_sensor_request_notify(ph
, sensor_id
,
748 SENSOR_CONTINUOUS_UPDATE_NOTIFY
,
753 scmi_sensor_trip_point_config(const struct scmi_protocol_handle
*ph
,
754 u32 sensor_id
, u8 trip_id
, u64 trip_value
)
757 u32 evt_cntl
= SENSOR_TP_BOTH
;
759 struct scmi_msg_set_sensor_trip_point
*trip
;
761 ret
= ph
->xops
->xfer_get_init(ph
, SENSOR_TRIP_POINT_CONFIG
,
762 sizeof(*trip
), 0, &t
);
767 trip
->id
= cpu_to_le32(sensor_id
);
768 trip
->event_control
= cpu_to_le32(evt_cntl
| SENSOR_TP_ID(trip_id
));
769 trip
->value_low
= cpu_to_le32(trip_value
& 0xffffffff);
770 trip
->value_high
= cpu_to_le32(trip_value
>> 32);
772 ret
= ph
->xops
->do_xfer(ph
, t
);
774 ph
->xops
->xfer_put(ph
, t
);
778 static int scmi_sensor_config_get(const struct scmi_protocol_handle
*ph
,
779 u32 sensor_id
, u32
*sensor_config
)
783 struct sensors_info
*si
= ph
->get_priv(ph
);
785 if (sensor_id
>= si
->num_sensors
)
788 ret
= ph
->xops
->xfer_get_init(ph
, SENSOR_CONFIG_GET
,
789 sizeof(__le32
), sizeof(__le32
), &t
);
793 put_unaligned_le32(sensor_id
, t
->tx
.buf
);
794 ret
= ph
->xops
->do_xfer(ph
, t
);
796 struct scmi_sensor_info
*s
= si
->sensors
+ sensor_id
;
798 *sensor_config
= get_unaligned_le64(t
->rx
.buf
);
799 s
->sensor_config
= *sensor_config
;
802 ph
->xops
->xfer_put(ph
, t
);
806 static int scmi_sensor_config_set(const struct scmi_protocol_handle
*ph
,
807 u32 sensor_id
, u32 sensor_config
)
811 struct scmi_msg_sensor_config_set
*msg
;
812 struct sensors_info
*si
= ph
->get_priv(ph
);
814 if (sensor_id
>= si
->num_sensors
)
817 ret
= ph
->xops
->xfer_get_init(ph
, SENSOR_CONFIG_SET
,
818 sizeof(*msg
), 0, &t
);
823 msg
->id
= cpu_to_le32(sensor_id
);
824 msg
->sensor_config
= cpu_to_le32(sensor_config
);
826 ret
= ph
->xops
->do_xfer(ph
, t
);
828 struct scmi_sensor_info
*s
= si
->sensors
+ sensor_id
;
830 s
->sensor_config
= sensor_config
;
833 ph
->xops
->xfer_put(ph
, t
);
838 * scmi_sensor_reading_get - Read scalar sensor value
839 * @ph: Protocol handle
840 * @sensor_id: Sensor ID
841 * @value: The 64bit value sensor reading
843 * This function returns a single 64 bit reading value representing the sensor
844 * value; if the platform SCMI Protocol implementation and the sensor support
845 * multiple axis and timestamped-reads, this just returns the first axis while
846 * dropping the timestamp value.
847 * Use instead the @scmi_sensor_reading_get_timestamped to retrieve the array of
848 * timestamped multi-axis values.
850 * Return: 0 on Success
852 static int scmi_sensor_reading_get(const struct scmi_protocol_handle
*ph
,
853 u32 sensor_id
, u64
*value
)
857 struct scmi_msg_sensor_reading_get
*sensor
;
858 struct scmi_sensor_info
*s
;
859 struct sensors_info
*si
= ph
->get_priv(ph
);
861 if (sensor_id
>= si
->num_sensors
)
864 ret
= ph
->xops
->xfer_get_init(ph
, SENSOR_READING_GET
,
865 sizeof(*sensor
), 0, &t
);
870 sensor
->id
= cpu_to_le32(sensor_id
);
871 s
= si
->sensors
+ sensor_id
;
873 sensor
->flags
= cpu_to_le32(SENSOR_READ_ASYNC
);
874 ret
= ph
->xops
->do_xfer_with_response(ph
, t
);
876 struct scmi_resp_sensor_reading_complete
*resp
;
879 if (le32_to_cpu(resp
->id
) == sensor_id
)
881 get_unaligned_le64(&resp
->readings_low
);
886 sensor
->flags
= cpu_to_le32(0);
887 ret
= ph
->xops
->do_xfer(ph
, t
);
889 *value
= get_unaligned_le64(t
->rx
.buf
);
892 ph
->xops
->xfer_put(ph
, t
);
897 scmi_parse_sensor_readings(struct scmi_sensor_reading
*out
,
898 const struct scmi_sensor_reading_resp
*in
)
900 out
->value
= get_unaligned_le64((void *)&in
->sensor_value_low
);
901 out
->timestamp
= get_unaligned_le64((void *)&in
->timestamp_low
);
905 * scmi_sensor_reading_get_timestamped - Read multiple-axis timestamped values
906 * @ph: Protocol handle
907 * @sensor_id: Sensor ID
908 * @count: The length of the provided @readings array
909 * @readings: An array of elements each representing a timestamped per-axis
910 * reading of type @struct scmi_sensor_reading.
911 * Returned readings are ordered as the @axis descriptors array
912 * included in @struct scmi_sensor_info and the max number of
913 * returned elements is min(@count, @num_axis); ideally the provided
914 * array should be of length @count equal to @num_axis.
916 * Return: 0 on Success
919 scmi_sensor_reading_get_timestamped(const struct scmi_protocol_handle
*ph
,
920 u32 sensor_id
, u8 count
,
921 struct scmi_sensor_reading
*readings
)
925 struct scmi_msg_sensor_reading_get
*sensor
;
926 struct scmi_sensor_info
*s
;
927 struct sensors_info
*si
= ph
->get_priv(ph
);
929 if (sensor_id
>= si
->num_sensors
)
932 s
= si
->sensors
+ sensor_id
;
933 if (!count
|| !readings
||
934 (!s
->num_axis
&& count
> 1) || (s
->num_axis
&& count
> s
->num_axis
))
937 ret
= ph
->xops
->xfer_get_init(ph
, SENSOR_READING_GET
,
938 sizeof(*sensor
), 0, &t
);
943 sensor
->id
= cpu_to_le32(sensor_id
);
945 sensor
->flags
= cpu_to_le32(SENSOR_READ_ASYNC
);
946 ret
= ph
->xops
->do_xfer_with_response(ph
, t
);
949 struct scmi_resp_sensor_reading_complete_v3
*resp
;
952 /* Retrieve only the number of requested axis anyway */
953 if (le32_to_cpu(resp
->id
) == sensor_id
)
954 for (i
= 0; i
< count
; i
++)
955 scmi_parse_sensor_readings(&readings
[i
],
961 sensor
->flags
= cpu_to_le32(0);
962 ret
= ph
->xops
->do_xfer(ph
, t
);
965 struct scmi_sensor_reading_resp
*resp_readings
;
967 resp_readings
= t
->rx
.buf
;
968 for (i
= 0; i
< count
; i
++)
969 scmi_parse_sensor_readings(&readings
[i
],
974 ph
->xops
->xfer_put(ph
, t
);
978 static const struct scmi_sensor_info
*
979 scmi_sensor_info_get(const struct scmi_protocol_handle
*ph
, u32 sensor_id
)
981 struct sensors_info
*si
= ph
->get_priv(ph
);
983 if (sensor_id
>= si
->num_sensors
)
986 return si
->sensors
+ sensor_id
;
989 static int scmi_sensor_count_get(const struct scmi_protocol_handle
*ph
)
991 struct sensors_info
*si
= ph
->get_priv(ph
);
993 return si
->num_sensors
;
996 static const struct scmi_sensor_proto_ops sensor_proto_ops
= {
997 .count_get
= scmi_sensor_count_get
,
998 .info_get
= scmi_sensor_info_get
,
999 .trip_point_config
= scmi_sensor_trip_point_config
,
1000 .reading_get
= scmi_sensor_reading_get
,
1001 .reading_get_timestamped
= scmi_sensor_reading_get_timestamped
,
1002 .config_get
= scmi_sensor_config_get
,
1003 .config_set
= scmi_sensor_config_set
,
1006 static bool scmi_sensor_notify_supported(const struct scmi_protocol_handle
*ph
,
1007 u8 evt_id
, u32 src_id
)
1009 bool supported
= false;
1010 const struct scmi_sensor_info
*s
;
1011 struct sensors_info
*sinfo
= ph
->get_priv(ph
);
1013 s
= scmi_sensor_info_get(ph
, src_id
);
1017 if (evt_id
== SCMI_EVENT_SENSOR_TRIP_POINT_EVENT
)
1018 supported
= sinfo
->notify_trip_point_cmd
;
1019 else if (evt_id
== SCMI_EVENT_SENSOR_UPDATE
)
1020 supported
= s
->update
;
1025 static int scmi_sensor_set_notify_enabled(const struct scmi_protocol_handle
*ph
,
1026 u8 evt_id
, u32 src_id
, bool enable
)
1031 case SCMI_EVENT_SENSOR_TRIP_POINT_EVENT
:
1032 ret
= scmi_sensor_trip_point_notify(ph
, src_id
, enable
);
1034 case SCMI_EVENT_SENSOR_UPDATE
:
1035 ret
= scmi_sensor_continuous_update_notify(ph
, src_id
, enable
);
1043 pr_debug("FAIL_ENABLED - evt[%X] dom[%d] - ret:%d\n",
1044 evt_id
, src_id
, ret
);
1050 scmi_sensor_fill_custom_report(const struct scmi_protocol_handle
*ph
,
1051 u8 evt_id
, ktime_t timestamp
,
1052 const void *payld
, size_t payld_sz
,
1053 void *report
, u32
*src_id
)
1058 case SCMI_EVENT_SENSOR_TRIP_POINT_EVENT
:
1060 const struct scmi_sensor_trip_notify_payld
*p
= payld
;
1061 struct scmi_sensor_trip_point_report
*r
= report
;
1063 if (sizeof(*p
) != payld_sz
)
1066 r
->timestamp
= timestamp
;
1067 r
->agent_id
= le32_to_cpu(p
->agent_id
);
1068 r
->sensor_id
= le32_to_cpu(p
->sensor_id
);
1069 r
->trip_point_desc
= le32_to_cpu(p
->trip_point_desc
);
1070 *src_id
= r
->sensor_id
;
1074 case SCMI_EVENT_SENSOR_UPDATE
:
1077 struct scmi_sensor_info
*s
;
1078 const struct scmi_sensor_update_notify_payld
*p
= payld
;
1079 struct scmi_sensor_update_report
*r
= report
;
1080 struct sensors_info
*sinfo
= ph
->get_priv(ph
);
1082 /* payld_sz is variable for this event */
1083 r
->sensor_id
= le32_to_cpu(p
->sensor_id
);
1084 if (r
->sensor_id
>= sinfo
->num_sensors
)
1086 r
->timestamp
= timestamp
;
1087 r
->agent_id
= le32_to_cpu(p
->agent_id
);
1088 s
= &sinfo
->sensors
[r
->sensor_id
];
1090 * The generated report r (@struct scmi_sensor_update_report)
1091 * was pre-allocated to contain up to SCMI_MAX_NUM_SENSOR_AXIS
1092 * readings: here it is filled with the effective @num_axis
1093 * readings defined for this sensor or 1 for scalar sensors.
1095 r
->readings_count
= s
->num_axis
?: 1;
1096 for (i
= 0; i
< r
->readings_count
; i
++)
1097 scmi_parse_sensor_readings(&r
->readings
[i
],
1099 *src_id
= r
->sensor_id
;
1110 static int scmi_sensor_get_num_sources(const struct scmi_protocol_handle
*ph
)
1112 struct sensors_info
*si
= ph
->get_priv(ph
);
1114 return si
->num_sensors
;
1117 static const struct scmi_event sensor_events
[] = {
1119 .id
= SCMI_EVENT_SENSOR_TRIP_POINT_EVENT
,
1120 .max_payld_sz
= sizeof(struct scmi_sensor_trip_notify_payld
),
1121 .max_report_sz
= sizeof(struct scmi_sensor_trip_point_report
),
1124 .id
= SCMI_EVENT_SENSOR_UPDATE
,
1126 sizeof(struct scmi_sensor_update_notify_payld
) +
1127 SCMI_MAX_NUM_SENSOR_AXIS
*
1128 sizeof(struct scmi_sensor_reading_resp
),
1129 .max_report_sz
= sizeof(struct scmi_sensor_update_report
) +
1130 SCMI_MAX_NUM_SENSOR_AXIS
*
1131 sizeof(struct scmi_sensor_reading
),
1135 static const struct scmi_event_ops sensor_event_ops
= {
1136 .is_notify_supported
= scmi_sensor_notify_supported
,
1137 .get_num_sources
= scmi_sensor_get_num_sources
,
1138 .set_notify_enabled
= scmi_sensor_set_notify_enabled
,
1139 .fill_custom_report
= scmi_sensor_fill_custom_report
,
1142 static const struct scmi_protocol_events sensor_protocol_events
= {
1143 .queue_sz
= SCMI_PROTO_QUEUE_SZ
,
1144 .ops
= &sensor_event_ops
,
1145 .evts
= sensor_events
,
1146 .num_events
= ARRAY_SIZE(sensor_events
),
1149 static int scmi_sensors_protocol_init(const struct scmi_protocol_handle
*ph
)
1153 struct sensors_info
*sinfo
;
1155 ret
= ph
->xops
->version_get(ph
, &version
);
1159 dev_dbg(ph
->dev
, "Sensor Version %d.%d\n",
1160 PROTOCOL_REV_MAJOR(version
), PROTOCOL_REV_MINOR(version
));
1162 sinfo
= devm_kzalloc(ph
->dev
, sizeof(*sinfo
), GFP_KERNEL
);
1165 sinfo
->version
= version
;
1167 ret
= scmi_sensor_attributes_get(ph
, sinfo
);
1170 sinfo
->sensors
= devm_kcalloc(ph
->dev
, sinfo
->num_sensors
,
1171 sizeof(*sinfo
->sensors
), GFP_KERNEL
);
1172 if (!sinfo
->sensors
)
1175 ret
= scmi_sensor_description_get(ph
, sinfo
);
1179 return ph
->set_priv(ph
, sinfo
, version
);
1182 static const struct scmi_protocol scmi_sensors
= {
1183 .id
= SCMI_PROTOCOL_SENSOR
,
1184 .owner
= THIS_MODULE
,
1185 .instance_init
= &scmi_sensors_protocol_init
,
1186 .ops
= &sensor_proto_ops
,
1187 .events
= &sensor_protocol_events
,
1188 .supported_version
= SCMI_PROTOCOL_SUPPORTED_VERSION
,
1191 DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(sensors
, scmi_sensors
)