1942 lines · 51.7 KB · C
RawDownload
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) *//* * cec - HDMI Consumer Electronics Control message functions * * Copyright 2016 Cisco Systems, Inc. and/or its affiliates. All rights reserved. */ #ifndef _CEC_UAPI_FUNCS_H#define _CEC_UAPI_FUNCS_H #include <linux/cec.h> /* One Touch Play Feature */static inline void cec_msg_active_source(struct cec_msg *msg, __u16 phys_addr){	msg->len = 4;	msg->msg[0] |= 0xf; /* broadcast */	msg->msg[1] = CEC_MSG_ACTIVE_SOURCE;	msg->msg[2] = phys_addr >> 8;	msg->msg[3] = phys_addr & 0xff;} static inline void cec_ops_active_source(const struct cec_msg *msg,					 __u16 *phys_addr){	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];} static inline void cec_msg_image_view_on(struct cec_msg *msg){	msg->len = 2;	msg->msg[1] = CEC_MSG_IMAGE_VIEW_ON;} static inline void cec_msg_text_view_on(struct cec_msg *msg){	msg->len = 2;	msg->msg[1] = CEC_MSG_TEXT_VIEW_ON;}  /* Routing Control Feature */static inline void cec_msg_inactive_source(struct cec_msg *msg,					   __u16 phys_addr){	msg->len = 4;	msg->msg[1] = CEC_MSG_INACTIVE_SOURCE;	msg->msg[2] = phys_addr >> 8;	msg->msg[3] = phys_addr & 0xff;} static inline void cec_ops_inactive_source(const struct cec_msg *msg,					   __u16 *phys_addr){	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];} static inline void cec_msg_request_active_source(struct cec_msg *msg,						 int reply){	msg->len = 2;	msg->msg[0] |= 0xf; /* broadcast */	msg->msg[1] = CEC_MSG_REQUEST_ACTIVE_SOURCE;	msg->reply = reply ? CEC_MSG_ACTIVE_SOURCE : 0;} static inline void cec_msg_routing_information(struct cec_msg *msg,					       __u16 phys_addr){	msg->len = 4;	msg->msg[0] |= 0xf; /* broadcast */	msg->msg[1] = CEC_MSG_ROUTING_INFORMATION;	msg->msg[2] = phys_addr >> 8;	msg->msg[3] = phys_addr & 0xff;} static inline void cec_ops_routing_information(const struct cec_msg *msg,					       __u16 *phys_addr){	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];} static inline void cec_msg_routing_change(struct cec_msg *msg,					  int reply,					  __u16 orig_phys_addr,					  __u16 new_phys_addr){	msg->len = 6;	msg->msg[0] |= 0xf; /* broadcast */	msg->msg[1] = CEC_MSG_ROUTING_CHANGE;	msg->msg[2] = orig_phys_addr >> 8;	msg->msg[3] = orig_phys_addr & 0xff;	msg->msg[4] = new_phys_addr >> 8;	msg->msg[5] = new_phys_addr & 0xff;	msg->reply = reply ? CEC_MSG_ROUTING_INFORMATION : 0;} static inline void cec_ops_routing_change(const struct cec_msg *msg,					  __u16 *orig_phys_addr,					  __u16 *new_phys_addr){	*orig_phys_addr = (msg->msg[2] << 8) | msg->msg[3];	*new_phys_addr = (msg->msg[4] << 8) | msg->msg[5];} static inline void cec_msg_set_stream_path(struct cec_msg *msg, __u16 phys_addr){	msg->len = 4;	msg->msg[0] |= 0xf; /* broadcast */	msg->msg[1] = CEC_MSG_SET_STREAM_PATH;	msg->msg[2] = phys_addr >> 8;	msg->msg[3] = phys_addr & 0xff;} static inline void cec_ops_set_stream_path(const struct cec_msg *msg,					   __u16 *phys_addr){	*phys_addr = (msg->msg[2] << 8) | msg->msg[3];}  /* Standby Feature */static inline void cec_msg_standby(struct cec_msg *msg){	msg->len = 2;	msg->msg[1] = CEC_MSG_STANDBY;}  /* One Touch Record Feature */static inline void cec_msg_record_off(struct cec_msg *msg, int reply){	msg->len = 2;	msg->msg[1] = CEC_MSG_RECORD_OFF;	msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0;} struct cec_op_arib_data {	__u16 transport_id;	__u16 service_id;	__u16 orig_network_id;}; struct cec_op_atsc_data {	__u16 transport_id;	__u16 program_number;}; struct cec_op_dvb_data {	__u16 transport_id;	__u16 service_id;	__u16 orig_network_id;}; struct cec_op_channel_data {	__u8 channel_number_fmt;	__u16 major;	__u16 minor;}; struct cec_op_digital_service_id {	__u8 service_id_method;	__u8 dig_bcast_system;	union {		struct cec_op_arib_data arib;		struct cec_op_atsc_data atsc;		struct cec_op_dvb_data dvb;		struct cec_op_channel_data channel;	};}; struct cec_op_record_src {	__u8 type;	union {		struct cec_op_digital_service_id digital;		struct {			__u8 ana_bcast_type;			__u16 ana_freq;			__u8 bcast_system;		} analog;		struct {			__u8 plug;		} ext_plug;		struct {			__u16 phys_addr;		} ext_phys_addr;	};}; static inline void cec_set_digital_service_id(__u8 *msg,	      const struct cec_op_digital_service_id *digital){	*msg++ = (digital->service_id_method << 7) | digital->dig_bcast_system;	if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {		*msg++ = (digital->channel.channel_number_fmt << 2) |			 (digital->channel.major >> 8);		*msg++ = digital->channel.major & 0xff;		*msg++ = digital->channel.minor >> 8;		*msg++ = digital->channel.minor & 0xff;		*msg++ = 0;		*msg++ = 0;		return;	}	switch (digital->dig_bcast_system) {	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_GEN:	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_CABLE:	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_SAT:	case CEC_OP_DIG_SERVICE_BCAST_SYSTEM_ATSC_T:		*msg++ = digital->atsc.transport_id >> 8;		*msg++ = digital->atsc.transport_id & 0xff;		*msg++ = digital->atsc.program_number >> 8;		*msg++ = digital->atsc.program_number & 0xff;		*msg++ = 0;		*msg++ = 0;		break;	default:		*msg++ = digital->dvb.transport_id >> 8;		*msg++ = digital->dvb.transport_id & 0xff;		*msg++ = digital->dvb.service_id >> 8;		*msg++ = digital->dvb.service_id & 0xff;		*msg++ = digital->dvb.orig_network_id >> 8;		*msg++ = digital->dvb.orig_network_id & 0xff;		break;	}} static inline void cec_get_digital_service_id(const __u8 *msg,	      struct cec_op_digital_service_id *digital){	digital->service_id_method = msg[0] >> 7;	digital->dig_bcast_system = msg[0] & 0x7f;	if (digital->service_id_method == CEC_OP_SERVICE_ID_METHOD_BY_CHANNEL) {		digital->channel.channel_number_fmt = msg[1] >> 2;		digital->channel.major = ((msg[1] & 3) << 6) | msg[2];		digital->channel.minor = (msg[3] << 8) | msg[4];		return;	}	digital->dvb.transport_id = (msg[1] << 8) | msg[2];	digital->dvb.service_id = (msg[3] << 8) | msg[4];	digital->dvb.orig_network_id = (msg[5] << 8) | msg[6];} static inline void cec_msg_record_on_own(struct cec_msg *msg){	msg->len = 3;	msg->msg[1] = CEC_MSG_RECORD_ON;	msg->msg[2] = CEC_OP_RECORD_SRC_OWN;} static inline void cec_msg_record_on_digital(struct cec_msg *msg,			     const struct cec_op_digital_service_id *digital){	msg->len = 10;	msg->msg[1] = CEC_MSG_RECORD_ON;	msg->msg[2] = CEC_OP_RECORD_SRC_DIGITAL;	cec_set_digital_service_id(msg->msg + 3, digital);} static inline void cec_msg_record_on_analog(struct cec_msg *msg,					    __u8 ana_bcast_type,					    __u16 ana_freq,					    __u8 bcast_system){	msg->len = 7;	msg->msg[1] = CEC_MSG_RECORD_ON;	msg->msg[2] = CEC_OP_RECORD_SRC_ANALOG;	msg->msg[3] = ana_bcast_type;	msg->msg[4] = ana_freq >> 8;	msg->msg[5] = ana_freq & 0xff;	msg->msg[6] = bcast_system;} static inline void cec_msg_record_on_plug(struct cec_msg *msg,					  __u8 plug){	msg->len = 4;	msg->msg[1] = CEC_MSG_RECORD_ON;	msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PLUG;	msg->msg[3] = plug;} static inline void cec_msg_record_on_phys_addr(struct cec_msg *msg,					       __u16 phys_addr){	msg->len = 5;	msg->msg[1] = CEC_MSG_RECORD_ON;	msg->msg[2] = CEC_OP_RECORD_SRC_EXT_PHYS_ADDR;	msg->msg[3] = phys_addr >> 8;	msg->msg[4] = phys_addr & 0xff;} static inline void cec_msg_record_on(struct cec_msg *msg,				     int reply,				     const struct cec_op_record_src *rec_src){	switch (rec_src->type) {	case CEC_OP_RECORD_SRC_OWN:		cec_msg_record_on_own(msg);		break;	case CEC_OP_RECORD_SRC_DIGITAL:		cec_msg_record_on_digital(msg, &rec_src->digital);		break;	case CEC_OP_RECORD_SRC_ANALOG:		cec_msg_record_on_analog(msg,					 rec_src->analog.ana_bcast_type,					 rec_src->analog.ana_freq,					 rec_src->analog.bcast_system);		break;	case CEC_OP_RECORD_SRC_EXT_PLUG:		cec_msg_record_on_plug(msg, rec_src->ext_plug.plug);		break;	case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:		cec_msg_record_on_phys_addr(msg,					    rec_src->ext_phys_addr.phys_addr);		break;	}	msg->reply = reply ? CEC_MSG_RECORD_STATUS : 0;} static inline void cec_ops_record_on(const struct cec_msg *msg,				     struct cec_op_record_src *rec_src){	rec_src->type = msg->msg[2];	switch (rec_src->type) {	case CEC_OP_RECORD_SRC_OWN:		break;	case CEC_OP_RECORD_SRC_DIGITAL:		cec_get_digital_service_id(msg->msg + 3, &rec_src->digital);		break;	case CEC_OP_RECORD_SRC_ANALOG:		rec_src->analog.ana_bcast_type = msg->msg[3];		rec_src->analog.ana_freq =			(msg->msg[4] << 8) | msg->msg[5];		rec_src->analog.bcast_system = msg->msg[6];		break;	case CEC_OP_RECORD_SRC_EXT_PLUG:		rec_src->ext_plug.plug = msg->msg[3];		break;	case CEC_OP_RECORD_SRC_EXT_PHYS_ADDR:		rec_src->ext_phys_addr.phys_addr =			(msg->msg[3] << 8) | msg->msg[4];		break;	}} static inline void cec_msg_record_status(struct cec_msg *msg, __u8 rec_status){	msg->len = 3;	msg->msg[1] = CEC_MSG_RECORD_STATUS;	msg->msg[2] = rec_status;} static inline void cec_ops_record_status(const struct cec_msg *msg,					 __u8 *rec_status){	*rec_status = msg->msg[2];} static inline void cec_msg_record_tv_screen(struct cec_msg *msg,					    int reply){	msg->len = 2;	msg->msg[1] = CEC_MSG_RECORD_TV_SCREEN;	msg->reply = reply ? CEC_MSG_RECORD_ON : 0;}  /* Timer Programming Feature */static inline void cec_msg_timer_status(struct cec_msg *msg,					__u8 timer_overlap_warning,					__u8 media_info,					__u8 prog_info,					__u8 prog_error,					__u8 duration_hr,					__u8 duration_min){	msg->len = 3;	msg->msg[1] = CEC_MSG_TIMER_STATUS;	msg->msg[2] = (timer_overlap_warning << 7) |		(media_info << 5) |		(prog_info ? 0x10 : 0) |		(prog_info ? prog_info : prog_error);	if (prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE ||	    prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE ||	    prog_error == CEC_OP_PROG_ERROR_DUPLICATE) {		msg->len += 2;		msg->msg[3] = ((duration_hr / 10) << 4) | (duration_hr % 10);		msg->msg[4] = ((duration_min / 10) << 4) | (duration_min % 10);	}} static inline void cec_ops_timer_status(const struct cec_msg *msg,					__u8 *timer_overlap_warning,					__u8 *media_info,					__u8 *prog_info,					__u8 *prog_error,					__u8 *duration_hr,					__u8 *duration_min){	*timer_overlap_warning = msg->msg[2] >> 7;	*media_info = (msg->msg[2] >> 5) & 3;	if (msg->msg[2] & 0x10) {		*prog_info = msg->msg[2] & 0xf;		*prog_error = 0;	} else {		*prog_info = 0;		*prog_error = msg->msg[2] & 0xf;	}	if (*prog_info == CEC_OP_PROG_INFO_NOT_ENOUGH_SPACE ||	    *prog_info == CEC_OP_PROG_INFO_MIGHT_NOT_BE_ENOUGH_SPACE ||	    *prog_error == CEC_OP_PROG_ERROR_DUPLICATE) {		*duration_hr = (msg->msg[3] >> 4) * 10 + (msg->msg[3] & 0xf);		*duration_min = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);	} else {		*duration_hr = *duration_min = 0;	}} static inline void cec_msg_timer_cleared_status(struct cec_msg *msg,						__u8 timer_cleared_status){	msg->len = 3;	msg->msg[1] = CEC_MSG_TIMER_CLEARED_STATUS;	msg->msg[2] = timer_cleared_status;} static inline void cec_ops_timer_cleared_status(const struct cec_msg *msg,						__u8 *timer_cleared_status){	*timer_cleared_status = msg->msg[2];} static inline void cec_msg_clear_analogue_timer(struct cec_msg *msg,						int reply,						__u8 day,						__u8 month,						__u8 start_hr,						__u8 start_min,						__u8 duration_hr,						__u8 duration_min,						__u8 recording_seq,						__u8 ana_bcast_type,						__u16 ana_freq,						__u8 bcast_system){	msg->len = 13;	msg->msg[1] = CEC_MSG_CLEAR_ANALOGUE_TIMER;	msg->msg[2] = day;	msg->msg[3] = month;	/* Hours and minutes are in BCD format */	msg->msg[4] = ((start_hr / 10) << 4) | (start_hr % 10);	msg->msg[5] = ((start_min / 10) << 4) | (start_min % 10);	msg->msg[6] = ((duration_hr / 10) << 4) | (duration_hr % 10);	msg->msg[7] = ((duration_min / 10) << 4) | (duration_min % 10);	msg->msg[8] = recording_seq;	msg->msg[9] = ana_bcast_type;	msg->msg[10] = ana_freq >> 8;	msg->msg[11] = ana_freq & 0xff;	msg->msg[12] = bcast_system;	msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;} static inline void cec_ops_clear_analogue_timer(const struct cec_msg *msg,						__u8 *day,						__u8 *month,						__u8 *start_hr,						__u8 *start_min,						__u8 *duration_hr,						__u8 *duration_min,						__u8 *recording_seq,						__u8 *ana_bcast_type,						__u16 *ana_freq,						__u8 *bcast_system){	*day = msg->msg[2];	*month = msg->msg[3];	/* Hours and minutes are in BCD format */	*start_hr = (msg->msg[4] >> 4) * 10 + (msg->msg[4] & 0xf);	*start_min = (msg->msg[5] >> 4) * 10 + (msg->msg[5] & 0xf);	*duration_hr = (msg->msg[6] >> 4) * 10 + (msg->msg[6] & 0xf);	*duration_min = (msg->msg[7] >> 4) * 10 + (msg->msg[7] & 0xf);	*recording_seq = msg->msg[8];	*ana_bcast_type = msg->msg[9];	*ana_freq = (msg->msg[10] << 8) | msg->msg[11];	*bcast_system = msg->msg[12];} static inline void cec_msg_clear_digital_timer(struct cec_msg *msg,				int reply,				__u8 day,				__u8 month,				__u8 start_hr,				__u8 start_min,				__u8 duration_hr,				__u8 duration_min,				__u8 recording_seq,				const struct cec_op_digital_service_id *digital){	msg->len = 16;	msg->reply = reply ? CEC_MSG_TIMER_CLEARED_STATUS : 0;

Lines 1–500 of 1942.