[RFC 1/6] cec: add new driver for cec support.

Hans Verkuil hverkuil at xs4all.nl
Mon Jan 12 03:48:05 PST 2015


On 12/23/2014 03:32 PM, Kamil Debski wrote:
> From: Hans Verkuil <hansverk at cisco.com>
> 
> Add the CEC framework.
> 
> Signed-off-by: Hans Verkuil <hansverk at cisco.com>
> [k.debski at samsung.com: Merged CEC Updates commit by Hans Verkuil]
> [k.debski at samsung.com: Merged Update author commit by Hans Verkuil]
> [k.debski at samsung.com: change kthread handling when setting logical
> address]
> [k.debski at samsung.com: code cleanup]
> Signed-off-by: Kamil Debski <k.debski at samsung.com>
> ---
>  cec-rfc.txt              |  319 ++++++++++++++
>  cec.txt                  |   40 ++
>  drivers/media/Kconfig    |    5 +
>  drivers/media/Makefile   |    2 +
>  drivers/media/cec.c      | 1048 ++++++++++++++++++++++++++++++++++++++++++++++
>  include/media/cec.h      |  129 ++++++
>  include/uapi/linux/cec.h |  222 ++++++++++
>  7 files changed, 1765 insertions(+)
>  create mode 100644 cec-rfc.txt
>  create mode 100644 cec.txt
>  create mode 100644 drivers/media/cec.c
>  create mode 100644 include/media/cec.h
>  create mode 100644 include/uapi/linux/cec.h
> 

...

> diff --git a/include/uapi/linux/cec.h b/include/uapi/linux/cec.h
> new file mode 100644
> index 0000000..a2c78d7
> --- /dev/null
> +++ b/include/uapi/linux/cec.h
> @@ -0,0 +1,222 @@
> +#ifndef _CEC_H
> +#define _CEC_H
> +
> +#include <linux/types.h>
> +
> +struct cec_msg {
> +	__u32 len;
> +	__u8  msg[16];
> +	__u32 status;
> +	/* If non-zero, then wait for a reply with this opcode.
> +	   If there was an error when sending the msg or FeatureAbort
> +	   was returned, then reply is set to 0.
> +	   If reply is non-zero upon return, then len/msg are set to
> +	   the received message.
> +	   If reply is zero upon return and status has the CEC_TX_STATUS_FEATURE_ABORT
> +	   bit set, then len/msg are set to the received feature abort message.
> +	   If reply is zero upon return and status has the CEC_TX_STATUS_REPLY_TIMEOUT
> +	   bit set, then no reply was seen at all.
> +	   This field is ignored with CEC_RECEIVE.
> +	   If reply is non-zero for CEC_TRANSMIT and the message is a broadcast,
> +	   then -EINVAL is returned.
> +	   if reply is non-zero, then timeout is set to 1000 (the required maximum
> +	   response time).
> +	 */
> +	__u8  reply;
> +	/* timeout (in ms) is used to timeout CEC_RECEIVE.
> +	   Set to 0 if you want to wait forever. */
> +	__u32 timeout;
> +	struct timespec ts;
> +};
> +
> +static inline __u8 cec_msg_initiator(const struct cec_msg *msg)
> +{
> +	return msg->msg[0] >> 4;
> +}
> +
> +static inline __u8 cec_msg_destination(const struct cec_msg *msg)
> +{
> +	return msg->msg[0] & 0xf;
> +}
> +
> +static inline bool cec_msg_is_broadcast(const struct cec_msg *msg)
> +{
> +	return (msg->msg[0] & 0xf) == 0xf;
> +}
> +
> +/* cec status field */
> +#define CEC_TX_STATUS_OK            (0)
> +#define CEC_TX_STATUS_ARB_LOST      (1 << 0)
> +#define CEC_TX_STATUS_RETRY_TIMEOUT (1 << 1)
> +#define CEC_TX_STATUS_FEATURE_ABORT (1 << 2)
> +#define CEC_TX_STATUS_REPLY_TIMEOUT (1 << 3)
> +#define CEC_RX_STATUS_READY         (0)
> +
> +#define CEC_LOG_ADDR_INVALID 0xff
> +
> +// The maximum number of logical addresses one device can be assigned to.
> +// The CEC 2.0 spec allows for only 2 logical addresses at the moment. The
> +// Analog Devices CEC hardware supports 3. So let's go wild and go for 4.
> +#define CEC_MAX_LOG_ADDRS 4
> +
> +// "You are in a maze of twisty little defines, all alike"
> +// What were they thinking of when they came up with this mess...
> +
> +// The "Primary Device Type"
> +#define CEC_PRIM_DEVTYPE_TV		0
> +#define CEC_PRIM_DEVTYPE_RECORD		1
> +#define CEC_PRIM_DEVTYPE_TUNER		3
> +#define CEC_PRIM_DEVTYPE_PLAYBACK	4
> +#define CEC_PRIM_DEVTYPE_AUDIOSYSTEM	5
> +#define CEC_PRIM_DEVTYPE_SWITCH		6
> +#define CEC_PRIM_DEVTYPE_VIDEOPROC	7
> +
> +// The "All Device Types" flags (CEC 2.0)
> +#define CEC_FL_ALL_DEVTYPE_TV		(1 << 7)
> +#define CEC_FL_ALL_DEVTYPE_RECORD	(1 << 6)
> +#define CEC_FL_ALL_DEVTYPE_TUNER	(1 << 5)
> +#define CEC_FL_ALL_DEVTYPE_PLAYBACK	(1 << 4)
> +#define CEC_FL_ALL_DEVTYPE_AUDIOSYSTEM	(1 << 3)
> +#define CEC_FL_ALL_DEVTYPE_SWITCH	(1 << 2)
> +// And if you wondering what happened to VIDEOPROC devices: those should
> +// be mapped to a SWITCH.
> +
> +// The logical address types that the CEC device wants to claim
> +#define CEC_LOG_ADDR_TYPE_TV		0
> +#define CEC_LOG_ADDR_TYPE_RECORD	1
> +#define CEC_LOG_ADDR_TYPE_TUNER		2
> +#define CEC_LOG_ADDR_TYPE_PLAYBACK	3
> +#define CEC_LOG_ADDR_TYPE_AUDIOSYSTEM	4
> +#define CEC_LOG_ADDR_TYPE_SPECIFIC	5
> +#define CEC_LOG_ADDR_TYPE_UNREGISTERED	6
> +// Switches should use UNREGISTERED.
> +// Video processors should use SPECIFIC.
> +
> +// The CEC version
> +#define CEC_VERSION_1_4B		5
> +#define CEC_VERSION_2_0			6
> +
> +struct cec_event {
> +	__u32 event;
> +	struct timespec ts;
> +};
> +
> +/* Userspace has to configure the adapter state (enable/disable) */
> +#define CEC_CAP_STATE		(1 << 0)
> +/* Userspace has to configure the physical address */
> +#define CEC_CAP_PHYS_ADDR	(1 << 1)
> +/* Userspace has to configure the logical addresses */
> +#define CEC_CAP_LOG_ADDRS	(1 << 2)
> +/* Userspace can transmit messages */
> +#define CEC_CAP_TRANSMIT	(1 << 3)
> +/* Userspace can receive messages */
> +#define CEC_CAP_RECEIVE		(1 << 4)
> +
> +struct cec_caps {
> +	__u32 available_log_addrs;
> +	__u32 capabilities;
> +};
> +
> +struct cec_log_addrs {
> +	__u8 cec_version;
> +	__u8 num_log_addrs;
> +	__u8 primary_device_type[CEC_MAX_LOG_ADDRS];
> +	__u8 log_addr_type[CEC_MAX_LOG_ADDRS];
> +	__u8 log_addr[CEC_MAX_LOG_ADDRS];
> +
> +	/* CEC 2.0 */
> +	__u8 all_device_types;
> +	__u8 features[CEC_MAX_LOG_ADDRS][12];
> +};
> +
> +/* Commands */
> +
> +/* Standby Feature */
> +#define CEC_OP_STANDBY			0x36
> +
> +/* System Information Feature */
> +#define CEC_OP_CEC_VERSION		0x9e
> +#define CEC_OP_GET_CEC_VERSION		0x9f
> +#define CEC_OP_GIVE_PHYS_ADDR		0x83
> +#define CEC_OP_GET_MENU_LANG		0x91
> +#define CEC_OP_REPORT_PHYS_ADDR		0x84
> +#define CEC_OP_SET_MENU_LANG		0x32
> +
> +/* One Touch Play Feature */
> +#define CEC_OP_ACTIVE_SOURCE		0x82
> +#define CEC_OP_REQUEST_ACTIVE_SOURCE	0x85
> +#define CEC_OP_IMAGE_VIEW_ON		0x04
> +#define CEC_OP_TEXT_VIEW_ON		0x0d
> +
> +/* Vendor Specific Commands Feature */
> +#define CEC_OP_DEVICE_VENDOR_ID		0x87
> +#define CEC_OP_GIVE_DEVICE_VENDOR_ID	0x8c
> +#define CEC_OP_VENDOR_CMD		0x89
> +#define CEC_OP_VENDOR_CMD_WITH_ID	0xa0
> +#define CEC_OP_VENDOR_REMOTE_BTN_DOWN	0x8a
> +#define CEC_OP_VENDOR_REMOTE_BTN_UP	0x8b
> +
> +/* OSD Display Feature */
> +#define CEC_OP_SET_OSD_STRING		0x64
> +#define CEC_OP_GIVE_OSD_NAME		0x46
> +#define CEC_OP_SET_OSD_NAME		0x47
> +
> +/* Power Status Feature */
> +#define CEC_OP_GIVE_DEVICE_POWER_STATUS	0x8f
> +#define CEC_OP_REPORT_POWER_STATUS	0x90
> +
> +/* General Protocol Messages */
> +#define CEC_OP_FEATURE_ABORT		0x00
> +#define CEC_OP_ABORT			0xff
> +
> +/* Capability Discovery and Control Feature */
> +#define CEC_OP_CDC_MSG			0xf8
> +#define CDC_OP_HPD_SET_STATE		0x10
> +#define CDC_OP_HPD_REPORT_STATE		0x11

Obviously the full set of CEC commands should be defined here. While working on
this I only added the commands that I needed for testing (core commands), but
the final version of this header should have the full list.

Regards,

	Hans

> +
> +/* ioctls */
> +
> +#define CEC_EVENT_READY		1
> +#define CEC_EVENT_DISCONNECT	2
> +
> +/* issue a CEC command */
> +#define CEC_G_CAPS		_IOWR('a', 0, struct cec_caps)
> +#define CEC_TRANSMIT		_IOWR('a', 1, struct cec_msg)
> +#define CEC_RECEIVE		_IOWR('a', 2, struct cec_msg)
> +
> +/*
> +   Configure the CEC adapter. It sets the device type and which
> +   logical types it will try to claim. It will return which
> +   logical addresses it could actually claim.
> +   An error is returned if the adapter is disabled or if there
> +   is no physical address assigned.
> + */
> +
> +#define CEC_G_ADAP_LOG_ADDRS	_IOR('a', 3, struct cec_log_addrs)
> +#define CEC_S_ADAP_LOG_ADDRS	_IOWR('a', 4, struct cec_log_addrs)
> +
> +/*
> +   Enable/disable the adapter. The Set state ioctl may not
> +   be available if that is handled internally.
> + */
> +#define CEC_G_ADAP_STATE	_IOR('a', 5, __u32)
> +#define CEC_S_ADAP_STATE	_IOW('a', 6, __u32)
> +
> +/*
> +   phys_addr is either 0 (if this is the CEC root device)
> +   or a valid physical address obtained from the sink's EDID
> +   as read by this CEC device (if this is a source device)
> +   or a physical address obtained and modified from a sink
> +   EDID and used for a sink CEC device.
> +   If nothing is connected, then phys_addr is 0xffff.
> +   See HDMI 1.4b, section 8.7 (Physical Address).
> +
> +   The Set ioctl may not be available if that is handled
> +   internally.
> + */
> +#define CEC_G_ADAP_PHYS_ADDR	_IOR('a', 7, __u16)
> +#define CEC_S_ADAP_PHYS_ADDR	_IOW('a', 8, __u16)
> +
> +#define CEC_G_EVENT		_IOWR('a', 9, struct cec_event)
> +
> +#endif
> 



More information about the dri-devel mailing list