From patchwork Tue Aug 13 23:17:23 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lespiau, Damien" X-Patchwork-Id: 2844071 Return-Path: X-Original-To: patchwork-dri-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id DCCA39F239 for ; Tue, 13 Aug 2013 23:32:12 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EF18E204A3 for ; Tue, 13 Aug 2013 23:32:11 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id 0E39F20464 for ; Tue, 13 Aug 2013 23:32:11 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 05A90E74B9 for ; Tue, 13 Aug 2013 16:32:11 -0700 (PDT) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTP id 58A38E7DDF; Tue, 13 Aug 2013 16:17:43 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 13 Aug 2013 16:17:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.89,873,1367996400"; d="scan'208";a="385874517" Received: from unknown (HELO strange.amr.corp.intel.com) ([10.255.15.20]) by fmsmga002.fm.intel.com with ESMTP; 13 Aug 2013 16:17:41 -0700 From: Damien Lespiau To: dri-devel@lists.freedesktop.org Subject: [PATCH 07/12] video/hdmi: Introduce helpers for the HDMI vendor specific infoframe Date: Wed, 14 Aug 2013 00:17:23 +0100 Message-Id: <1376435848-14584-8-git-send-email-damien.lespiau@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1376435848-14584-1-git-send-email-damien.lespiau@intel.com> References: <1376435848-14584-1-git-send-email-damien.lespiau@intel.com> Cc: intel-gfx@lists.freedesktop.org X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org Errors-To: dri-devel-bounces+patchwork-dri-devel=patchwork.kernel.org@lists.freedesktop.org X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY 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 Provide the programming model than the other infoframe types. The generic _pack() function can't handle those yet as we need to move the vendor OUI in the generic hdmi_vendor_infoframe structure to know which kind of vendor infoframe we are dealing with. Signed-off-by: Damien Lespiau --- drivers/video/hdmi.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/hdmi.h | 25 ++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/drivers/video/hdmi.c b/drivers/video/hdmi.c index ac84215..2059f7b 100644 --- a/drivers/video/hdmi.c +++ b/drivers/video/hdmi.c @@ -286,6 +286,88 @@ ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, EXPORT_SYMBOL(hdmi_audio_infoframe_pack); /** + * hdmi_hdmi_infoframe_init() - initialize an HDMI vendor infoframe + * @frame: HDMI vendor infoframe + * + * Returns 0 on success or a negative error code on failure. + */ +int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame) +{ + memset(frame, 0, sizeof(*frame)); + + frame->type = HDMI_INFOFRAME_TYPE_VENDOR; + frame->version = 1; + frame->length = 5; /* we can hardcode the size for now as we don't + support neither 3D_Ext_Data nor 3D_Metadata_* */ + + /* 0 is a valid value for s3d_struct, so we use a special "not set" + * value */ + frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID; + + return 0; +} +EXPORT_SYMBOL(hdmi_hdmi_infoframe_init); + +/** + * hdmi_hmdi_infoframe_pack() - write a HDMI vendor infoframe to binary buffer + * @frame: HDMI infoframe + * @buffer: destination buffer + * @size: size of buffer + * + * Packs the information contained in the @frame structure into a binary + * representation that can be written into the corresponding controller + * registers. Also computes the checksum as required by section 5.3.5 of + * the HDMI 1.4 specification. + * + * Returns the number of bytes packed into the binary buffer or a negative + * error code on failure. + */ +ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame, + void *buffer, size_t size) +{ + u8 *ptr = buffer; + size_t length; + + /* empty info frame */ + if (frame->vic == 0 && frame->s3d_struct == HDMI_3D_STRUCTURE_INVALID) + return -EINVAL; + + /* only one of those can be supplied */ + if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) + return -EINVAL; + + length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; + + if (size < length) + return -ENOSPC; + + memset(buffer, 0, size); + + ptr[0] = frame->type; + ptr[1] = frame->version; + ptr[2] = frame->length; + ptr[3] = 0; /* checksum */ + + /* HDMI OUI */ + ptr[4] = 0x03; + ptr[5] = 0x0c; + ptr[6] = 0x00; + + if (frame->vic) { + ptr[7] = 0x1 << 5; /* video format */ + ptr[8] = frame->vic; + } else { + ptr[7] = 0x2 << 5; /* video format */ + ptr[8] = (frame->s3d_struct & 0xf) << 4; + } + + hdmi_infoframe_checksum(buffer, length); + + return length; +} +EXPORT_SYMBOL(hdmi_hdmi_infoframe_pack); + +/** * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary * buffer * @frame: HDMI vendor infoframe diff --git a/include/linux/hdmi.h b/include/linux/hdmi.h index b98340b..f5098a8 100644 --- a/include/linux/hdmi.h +++ b/include/linux/hdmi.h @@ -234,11 +234,36 @@ struct hdmi_vendor_infoframe { ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, void *buffer, size_t size); +enum hdmi_3d_structure { + HDMI_3D_STRUCTURE_INVALID = -1, + HDMI_3D_STRUCTURE_FRAME_PACKING = 0, + HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE, + HDMI_3D_STRUCTURE_LINE_ALTERNATIVE, + HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL, + HDMI_3D_STRUCTURE_L_DEPTH, + HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH, + HDMI_3D_STRUCTURE_TOP_BOTTOM, + HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF, +}; + +struct hdmi_hdmi_infoframe { + enum hdmi_infoframe_type type; + unsigned char version; + unsigned char length; + u8 vic; + enum hdmi_3d_structure s3d_struct; +}; + +int hdmi_hdmi_infoframe_init(struct hdmi_hdmi_infoframe *frame); +ssize_t hdmi_hdmi_infoframe_pack(struct hdmi_hdmi_infoframe *frame, + void *buffer, size_t size); + union hdmi_infoframe { struct hdmi_any_infoframe any; struct hdmi_avi_infoframe avi; struct hdmi_spd_infoframe spd; struct hdmi_vendor_infoframe vendor; + struct hdmi_hdmi_infoframe hdmi; struct hdmi_audio_infoframe audio; };