From patchwork Mon Sep 7 13:44:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hans Verkuil (hansverk)" X-Patchwork-Id: 7135261 Return-Path: X-Original-To: patchwork-linux-media@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 62DF4BEEC1 for ; Mon, 7 Sep 2015 13:45:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4252020776 for ; Mon, 7 Sep 2015 13:45:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9E731207FB for ; Mon, 7 Sep 2015 13:45:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751661AbbIGNpj (ORCPT ); Mon, 7 Sep 2015 09:45:39 -0400 Received: from aer-iport-3.cisco.com ([173.38.203.53]:43409 "EHLO aer-iport-3.cisco.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751234AbbIGNpO (ORCPT ); Mon, 7 Sep 2015 09:45:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=8085; q=dns/txt; s=iport; t=1441633514; x=1442843114; h=from:to:cc:subject:date:message-id; bh=kXUv5Oeu3kMOBmyxRQ8wpth81LbGWIgqlogIWLnjz7I=; b=gXmi5GxQMvdLBDR+ceGydnPeMM2cMrYx1ZDRRY8kleupYNfii+SopBr2 iw2oDIpvA7P71yMc5FEPPipz1ktQIzwVOHj9+sR15OCFZuONmXDxre8j+ jgKf8IPJcsSIAuwBNXmjI7IxlDFxJo/qU0pNoSJGfgDW9wzWppRhNCxUo Q=; X-IronPort-AV: E=Sophos;i="5.17,485,1437436800"; d="scan'208";a="604960045" Received: from aer-iport-nat.cisco.com (HELO aer-core-4.cisco.com) ([173.38.203.22]) by aer-iport-3.cisco.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Sep 2015 13:45:10 +0000 Received: from cobaltpc1.rd.cisco.com ([10.47.79.60]) by aer-core-4.cisco.com (8.14.5/8.14.5) with ESMTP id t87Dj5rl020142; Mon, 7 Sep 2015 13:45:09 GMT From: Hans Verkuil To: linux-media@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, m.szyprowski@samsung.com, kyungmin.park@samsung.com, thomas@tommie-lie.de, sean@mess.org, dmitry.torokhov@gmail.com, linux-input@vger.kernel.org, linux-samsung-soc@vger.kernel.org, lars@opdenkamp.eu, kamil@wypas.org, linux@arm.linux.org.uk, Hans Verkuil , Hans Verkuil Subject: [PATCHv9 08/15] cec.txt: add CEC framework documentation Date: Mon, 7 Sep 2015 15:44:37 +0200 Message-Id: <3d11b9aa9a69cc3cdb7a6b4e0da1e07b4620c620.1441633456.git.hansverk@cisco.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: References: In-Reply-To: References: Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Spam-Status: No, score=-14.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY, USER_IN_DEF_DKIM_WL autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Document the new HDMI CEC framework. Signed-off-by: Hans Verkuil [k.debski@samsung.com: add DocBook documentation by Hans Verkuil, with Signed-off-by: Kamil Debski Signed-off-by: Hans Verkuil --- Documentation/cec.txt | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 Documentation/cec.txt diff --git a/Documentation/cec.txt b/Documentation/cec.txt new file mode 100644 index 0000000..b298249 --- /dev/null +++ b/Documentation/cec.txt @@ -0,0 +1,166 @@ +CEC Kernel Support +================== + +The CEC framework provides a unified kernel interface for use with HDMI CEC +hardware. It is designed to handle a multiple variants of hardware. Adding to +the flexibility of the framework it enables to set which parts of the CEC +protocol processing is handled by the hardware, by the driver and by the +userspace application. + + +The CEC Protocol +---------------- + +The CEC protocol enables consumer electronic devices to communicate with each +other through the HDMI connection. The protocol uses logical addresses in the +communication. The logical address is strictly connected with the functionality +provided by the device. The TV acting as the communication hub is always +assigned address 0. The physical address is determined by the physical +connection between devices. + +The protocol enables control of compatible devices with a single remote. +Synchronous power on/standby, instant playback with changing the content source +on the TV. + +The Kernel Interface +==================== + +CEC Adapter +----------- + +#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 + +/* The "Primary Device Type" */ +#define CEC_OP_PRIM_DEVTYPE_TV 0 +#define CEC_OP_PRIM_DEVTYPE_RECORD 1 +#define CEC_OP_PRIM_DEVTYPE_TUNER 3 +#define CEC_OP_PRIM_DEVTYPE_PLAYBACK 4 +#define CEC_OP_PRIM_DEVTYPE_AUDIOSYSTEM 5 +#define CEC_OP_PRIM_DEVTYPE_SWITCH 6 +#define CEC_OP_PRIM_DEVTYPE_VIDEOPROC 7 + +/* The "All Device Types" flags (CEC 2.0) */ +#define CEC_OP_ALL_DEVTYPE_TV (1 << 7) +#define CEC_OP_ALL_DEVTYPE_RECORD (1 << 6) +#define CEC_OP_ALL_DEVTYPE_TUNER (1 << 5) +#define CEC_OP_ALL_DEVTYPE_PLAYBACK (1 << 4) +#define CEC_OP_ALL_DEVTYPE_AUDIOSYSTEM (1 << 3) +#define CEC_OP_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_OP_CEC_VERSION_1_3A 4 +#define CEC_OP_CEC_VERSION_1_4 5 +#define CEC_OP_CEC_VERSION_2_0 6 + +struct cec_adapter { + /* internal fields removed */ + + u16 phys_addr; + u32 capabilities; + u8 version; + u8 num_log_addrs; + u8 prim_device[CEC_MAX_LOG_ADDRS]; + u8 log_addr_type[CEC_MAX_LOG_ADDRS]; + u8 log_addr[CEC_MAX_LOG_ADDRS]; + + int (*adap_enable)(struct cec_adapter *adap, bool enable); + int (*adap_log_addr)(struct cec_adapter *adap, u8 logical_addr); + int (*adap_transmit)(struct cec_adapter *adap, struct cec_msg *msg); + void (*adap_transmit_timed_out)(struct cec_adapter *adap); + + void (*claimed_log_addr)(struct cec_adapter *adap, u8 idx); + int (*received)(struct cec_adapter *adap, struct cec_msg *msg); +}; + +int cec_create_adapter(struct cec_adapter *adap, u32 caps); +void cec_delete_adapter(struct cec_adapter *adap); +int cec_transmit_msg(struct cec_adapter *adap, struct cec_data *data, bool block); + +/* Called by the adapter */ +void cec_transmit_done(struct cec_adapter *adap, u32 status); +void cec_received_msg(struct cec_adapter *adap, struct cec_msg *msg); + +int cec_receive_msg(struct cec_adapter *adap, struct cec_msg *msg, bool block); +int cec_claim_log_addrs(struct cec_adapter *adap, struct cec_log_addrs *log_addrs, bool block); + +The device type defines are defined by the CEC standard. + +The cec_adapter structure represents the adapter. It has a number of +operations that have to be implemented in the driver: adap_enable() enables +or disables the physical adapter, adap_log_addr() tells the driver which +logical address should be configured. This may be called multiple times +to configure multiple logical addresses. Calling adap_enable(false) or +adap_log_addr(CEC_LOG_ADDR_INVALID) will clear all configured logical +addresses. + +The adap_transmit op will setup the hardware to send out the given CEC message. +This will return without waiting for the transmission to finish. The +adap_transmit_timed_out() function is called when the current transmission timed +out and the hardware needs to be informed of this (the hardware should go back +from transmitter to receiver mode). + +The adapter driver will also call into the adapter: it should call +cec_transmit_done() when a cec transfer was finalized and cec_received_msg() +when a new message was received. + +When a message is received the received() op is called. + +The driver has to call cec_create_adapter to initialize the structure. If +the 'caps' argument is non-zero, then it will also create a /dev/cecX +device node to allow userspace to interact with the CEC device. Userspace +can request those capabilities with the CEC_G_CAPS ioctl. + +In order for a CEC adapter to be configured it needs a physical address. +This is normally assigned by the driver. It is either 0.0.0.0 for a TV (aka +video receiver) or it is derived from the EDID that the source received +from the sink. This is normally set by the driver before enabling the CEC +adapter, or it is set from userspace in the case of CEC USB dongles (although +embedded systems might also want to set this manually). + +After enabling the CEC adapter it has to be configured. + +The userspace has to inform the CEC adapter of which type of device it requests +the adapter to identify itself. After this information is set by userspace, the +CEC framework will attempt to to find and claim a logical addresses matching the +requested device type. If none are found, then it will fall back to logical +address Unregistered (15). To clear the logical addresses list from the list the +userspace application should set the num_log_addrs field of struct cec_log_addr +to 0. + +The type of device is set from the userspace with the CEC_S_ADAP_LOG_ADDRS. In +addition, claiming logical addresses can be initiated from the kernel side by +calling the cec_claim_log_addrs function. + +Before the addresses are claimed it is possible to send and receive messages. +Sending all messages is possible as it is up to the userspace to the source +and destination addresses in the message payload. However, only broadcast +messages can be received until a regular logical address is claimed. + +When a CEC message is received the CEC framework will take care of the CEC +core messages CEC_MSG_GET_CEC_VERSION, CEC_MSG_GIVE_PHYS_ADDR and CEC_MSG_ABORT. +Then it will call the received() op (if set), and finally it will queue it +for handling by userspace if create_devnode was true, or send back +FEATURE_ABORT if create_devnode was false. + +Drivers can also use the cec_transmit_msg() call to transmit a message. This +can either be fire-and-forget (the CEC framework will queue up messages in a +transmit queue), or a blocking wait until there is either an error or a +reply to the message.