Home | History | Annotate | Line # | Download | only in linux
hdmi.h revision 1.10
      1  1.10  riastrad /*	$NetBSD: hdmi.h,v 1.10 2021/12/19 11:38:04 riastradh Exp $	*/
      2   1.1  riastrad 
      3   1.1  riastrad /*-
      4   1.1  riastrad  * Copyright (c) 2014 The NetBSD Foundation, Inc.
      5   1.1  riastrad  * All rights reserved.
      6   1.1  riastrad  *
      7   1.1  riastrad  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1  riastrad  * by Taylor R. Campbell.
      9   1.1  riastrad  *
     10   1.1  riastrad  * Redistribution and use in source and binary forms, with or without
     11   1.1  riastrad  * modification, are permitted provided that the following conditions
     12   1.1  riastrad  * are met:
     13   1.1  riastrad  * 1. Redistributions of source code must retain the above copyright
     14   1.1  riastrad  *    notice, this list of conditions and the following disclaimer.
     15   1.1  riastrad  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1  riastrad  *    notice, this list of conditions and the following disclaimer in the
     17   1.1  riastrad  *    documentation and/or other materials provided with the distribution.
     18   1.1  riastrad  *
     19   1.1  riastrad  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1  riastrad  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1  riastrad  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1  riastrad  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1  riastrad  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1  riastrad  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1  riastrad  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1  riastrad  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1  riastrad  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1  riastrad  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1  riastrad  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1  riastrad  */
     31   1.1  riastrad 
     32   1.1  riastrad #ifndef	_LINUX_HDMI_H_
     33   1.1  riastrad #define	_LINUX_HDMI_H_
     34   1.1  riastrad 
     35   1.1  riastrad #include <sys/types.h>
     36   1.1  riastrad #include <sys/param.h>
     37   1.1  riastrad #include <sys/errno.h>
     38   1.1  riastrad #include <sys/systm.h>
     39   1.1  riastrad 
     40   1.1  riastrad enum hdmi_3d_structure {
     41   1.1  riastrad         HDMI_3D_STRUCTURE_INVALID		= -1,
     42   1.1  riastrad         HDMI_3D_STRUCTURE_FRAME_PACKING		= 0,
     43   1.1  riastrad         HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE	= 1,
     44   1.1  riastrad         HDMI_3D_STRUCTURE_LINE_ALTERNATIVE	= 2,
     45   1.1  riastrad         HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL	= 3,
     46   1.1  riastrad         HDMI_3D_STRUCTURE_L_DEPTH		= 4,
     47   1.1  riastrad         HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH	= 5,
     48   1.1  riastrad         HDMI_3D_STRUCTURE_TOP_AND_BOTTOM	= 6,
     49   1.1  riastrad         HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF	= 8,
     50   1.1  riastrad };
     51   1.1  riastrad 
     52   1.1  riastrad enum hdmi_active_aspect {
     53   1.1  riastrad         HDMI_ACTIVE_ASPECT_16_9_TOP		= 2,
     54   1.1  riastrad         HDMI_ACTIVE_ASPECT_14_9_TOP		= 3,
     55   1.1  riastrad         HDMI_ACTIVE_ASPECT_16_9_CENTER		= 4,
     56   1.1  riastrad         HDMI_ACTIVE_ASPECT_PICTURE		= 8,
     57   1.1  riastrad         HDMI_ACTIVE_ASPECT_4_3			= 9,
     58   1.1  riastrad         HDMI_ACTIVE_ASPECT_16_9			= 10,
     59   1.1  riastrad         HDMI_ACTIVE_ASPECT_14_9			= 11,
     60   1.1  riastrad         HDMI_ACTIVE_ASPECT_4_3_SP_14_9		= 13,
     61   1.1  riastrad         HDMI_ACTIVE_ASPECT_16_9_SP_14_9		= 14,
     62   1.1  riastrad         HDMI_ACTIVE_ASPECT_16_9_SP_4_3		= 15,
     63   1.1  riastrad };
     64   1.1  riastrad 
     65   1.2  riastrad enum hdmi_audio_coding_type {
     66   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_STREAM		= 0,
     67   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_PCM		= 1,
     68   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_AC3		= 2,
     69   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_MPEG1		= 3,
     70   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_MP3		= 4,
     71   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_MPEG2		= 5,
     72   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_AAC_LC		= 6,
     73   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_DTS		= 7,
     74   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_ATRAC		= 8,
     75   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_DSD		= 9,
     76   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_EAC3		= 10,
     77   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_DTS_HD		= 11,
     78   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_MLP		= 12,
     79   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_DST		= 13,
     80   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_WMA_PRO		= 14,
     81   1.2  riastrad };
     82   1.2  riastrad 
     83   1.2  riastrad enum hdmi_audio_coding_type_ext {
     84   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_EXT_STREAM	= 0,
     85   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC	= 1,
     86   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2	= 2,
     87   1.2  riastrad 	HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND = 3,
     88   1.2  riastrad };
     89   1.2  riastrad 
     90   1.2  riastrad enum hdmi_audio_sample_frequency {
     91   1.2  riastrad 	HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM	= 0,
     92   1.2  riastrad 	HDMI_AUDIO_SAMPLE_FREQUENCY_32000	= 1,
     93   1.2  riastrad 	HDMI_AUDIO_SAMPLE_FREQUENCY_44100	= 2,
     94   1.2  riastrad 	HDMI_AUDIO_SAMPLE_FREQUENCY_48000	= 3,
     95   1.2  riastrad 	HDMI_AUDIO_SAMPLE_FREQUENCY_88200	= 4,
     96   1.2  riastrad 	HDMI_AUDIO_SAMPLE_FREQUENCY_96000	= 5,
     97   1.2  riastrad 	HDMI_AUDIO_SAMPLE_FREQUENCY_176400	= 6,
     98   1.2  riastrad 	HDMI_AUDIO_SAMPLE_FREQUENCY_192000	= 7,
     99   1.2  riastrad };
    100   1.2  riastrad 
    101   1.2  riastrad enum hdmi_audio_sample_size {
    102   1.2  riastrad 	HDMI_AUDIO_SAMPLE_SIZE_STREAM		= 0,
    103   1.2  riastrad 	HDMI_AUDIO_SAMPLE_SIZE_16		= 1,
    104   1.2  riastrad 	HDMI_AUDIO_SAMPLE_SIZE_20		= 2,
    105   1.2  riastrad 	HDMI_AUDIO_SAMPLE_SIZE_24		= 3,
    106   1.2  riastrad };
    107   1.2  riastrad 
    108   1.1  riastrad enum hdmi_colorimetry {
    109   1.1  riastrad 	HDMI_COLORIMETRY_NONE			= 0,
    110   1.1  riastrad 	HDMI_COLORIMETRY_ITU_601		= 1,
    111   1.1  riastrad 	HDMI_COLORIMETRY_ITU_709		= 2,
    112   1.1  riastrad 	HDMI_COLORIMETRY_EXTENDED		= 3,
    113   1.1  riastrad };
    114   1.1  riastrad 
    115   1.1  riastrad enum hdmi_colorspace {
    116   1.1  riastrad 	HDMI_COLORSPACE_RGB			= 0,
    117   1.1  riastrad 	HDMI_COLORSPACE_YUV422			= 1,
    118   1.1  riastrad 	HDMI_COLORSPACE_YUV444			= 2,
    119   1.1  riastrad };
    120   1.1  riastrad 
    121   1.1  riastrad enum hdmi_content_type {
    122   1.7  riastrad 	HDMI_CONTENT_TYPE_GRAPHICS		= 0,
    123   1.1  riastrad 	HDMI_CONTENT_TYPE_PHOTO			= 1,
    124   1.1  riastrad 	HDMI_CONTENT_TYPE_CINEMA		= 2,
    125   1.1  riastrad 	HDMI_CONTENT_TYPE_GAME			= 3,
    126   1.1  riastrad };
    127   1.1  riastrad 
    128   1.1  riastrad enum hdmi_extended_colorimetry {
    129   1.1  riastrad 	HDMI_EXTENDED_COLORIMETRY_XV_YCC_601	= 0,
    130   1.1  riastrad 	HDMI_EXTENDED_COLORIMETRY_XV_YCC_709	= 1,
    131   1.1  riastrad 	HDMI_EXTENDED_COLORIMETRY_S_YCC_601	= 2,
    132   1.1  riastrad 	HDMI_EXTENDED_COLORIMETRY_ADOBE_YCC_601	= 3,
    133   1.1  riastrad 	HDMI_EXTENDED_COLORIMETRY_ADOBE_RGB	= 4,
    134   1.1  riastrad };
    135   1.1  riastrad 
    136   1.1  riastrad enum hdmi_nups {
    137   1.1  riastrad 	HDMI_NUPS_UNKNOWN			= 0,
    138   1.1  riastrad 	HDMI_NUPS_HORIZONTAL			= 1,
    139   1.1  riastrad 	HDMI_NUPS_VERTICAL			= 2,
    140   1.1  riastrad 	HDMI_NUPS_BOTH				= 3,
    141   1.1  riastrad };
    142   1.1  riastrad 
    143   1.1  riastrad enum hdmi_picture_aspect {
    144   1.1  riastrad 	HDMI_PICTURE_ASPECT_NONE		= 0,
    145   1.1  riastrad 	HDMI_PICTURE_ASPECT_4_3			= 1,
    146   1.1  riastrad 	HDMI_PICTURE_ASPECT_16_9		= 2,
    147   1.7  riastrad 	HDMI_PICTURE_ASPECT_64_27		= 3,
    148   1.7  riastrad 	HDMI_PICTURE_ASPECT_256_135		= 4,
    149   1.7  riastrad 	HDMI_PICTURE_ASPECT_RESERVED		= 5,
    150   1.1  riastrad };
    151   1.1  riastrad 
    152   1.1  riastrad enum hdmi_quantization_range {
    153   1.1  riastrad 	HDMI_QUANTIZATION_RANGE_DEFAULT		= 0,
    154   1.1  riastrad 	HDMI_QUANTIZATION_RANGE_LIMITED		= 1,
    155   1.1  riastrad 	HDMI_QUANTIZATION_RANGE_FULL		= 2,
    156   1.1  riastrad };
    157   1.1  riastrad 
    158   1.1  riastrad enum hdmi_scan_mode {
    159   1.1  riastrad 	HDMI_SCAN_MODE_NONE			= 0,
    160   1.1  riastrad 	HDMI_SCAN_MODE_OVERSCAN			= 1,
    161   1.1  riastrad 	HDMI_SCAN_MODE_UNDERSCAN		= 2,
    162   1.1  riastrad };
    163   1.1  riastrad 
    164   1.1  riastrad enum hdmi_ycc_quantization_range {
    165   1.1  riastrad 	HDMI_YCC_QUANTIZATION_RANGE_LIMITED	= 0,
    166   1.1  riastrad 	HDMI_YCC_QUANTIZATION_RANGE_FULL	= 1,
    167   1.1  riastrad };
    168   1.1  riastrad 
    169  1.10  riastrad enum hdmi_packet_type {
    170  1.10  riastrad         HDMI_PACKET_TYPE_NULL = 0x00,
    171  1.10  riastrad         HDMI_PACKET_TYPE_AUDIO_CLOCK_REGEN	= 0x01,
    172  1.10  riastrad         HDMI_PACKET_TYPE_AUDIO_SAMPLE		= 0x02,
    173  1.10  riastrad         HDMI_PACKET_TYPE_GENERAL_CONTROL	= 0x03,
    174  1.10  riastrad         HDMI_PACKET_TYPE_ACP			= 0x04,
    175  1.10  riastrad         HDMI_PACKET_TYPE_ISRC1			= 0x05,
    176  1.10  riastrad         HDMI_PACKET_TYPE_ISRC2			= 0x06,
    177  1.10  riastrad         HDMI_PACKET_TYPE_ONE_BIT_AUDIO_SAMPLE	= 0x07,
    178  1.10  riastrad         HDMI_PACKET_TYPE_DST_AUDIO		= 0x08,
    179  1.10  riastrad         HDMI_PACKET_TYPE_HBR_AUDIO_STREAM	= 0x09,
    180  1.10  riastrad         HDMI_PACKET_TYPE_GAMUT_METADATA		= 0x0a,
    181  1.10  riastrad };
    182  1.10  riastrad 
    183   1.1  riastrad enum hdmi_infoframe_type {
    184   1.1  riastrad 	HDMI_INFOFRAME_TYPE_VENDOR		= 0x81,
    185   1.1  riastrad 	HDMI_INFOFRAME_TYPE_AVI			= 0x82,
    186   1.1  riastrad 	HDMI_INFOFRAME_TYPE_SPD			= 0x83,
    187   1.1  riastrad 	HDMI_INFOFRAME_TYPE_AUDIO		= 0x84,
    188  1.10  riastrad 	HDMI_INFOFRAME_TYPE_DRM			= 0x87,
    189   1.1  riastrad };
    190   1.1  riastrad 
    191   1.9  riastrad enum hdmi_eotf {
    192   1.9  riastrad 	HDMI_EOTF_TRADITIONAL_GAMMA_SDR,
    193   1.9  riastrad 	HDMI_EOTF_TRADITIONAL_GAMMA_HDR,
    194   1.9  riastrad 	HDMI_EOTF_SMPTE_ST2084,
    195   1.9  riastrad 	HDMI_EOTF_BT_2100_HLG,
    196   1.9  riastrad };
    197   1.9  riastrad 
    198   1.9  riastrad enum hdmi_metadata_type {
    199   1.9  riastrad 	HDMI_STATIC_METADATA_TYPE1 = 1,
    200   1.9  riastrad };
    201   1.9  riastrad 
    202   1.1  riastrad #define	HDMI_INFOFRAME_SIZE(TYPE)					      \
    203   1.1  riastrad 	(HDMI_INFOFRAME_HEADER_SIZE + HDMI_##TYPE##_INFOFRAME_SIZE)
    204   1.1  riastrad 
    205   1.1  riastrad #define	HDMI_INFOFRAME_HEADER_SIZE	4
    206   1.1  riastrad struct hdmi_infoframe_header {
    207   1.1  riastrad 	enum hdmi_infoframe_type	type;
    208   1.1  riastrad 	uint8_t				version;
    209   1.1  riastrad 	uint8_t				length;
    210   1.1  riastrad 	/* checksum */
    211   1.1  riastrad };
    212   1.1  riastrad 
    213   1.9  riastrad struct hdmi_type1 {
    214   1.9  riastrad 	enum hdmi_eotf eotf;
    215   1.9  riastrad 	enum hdmi_metadata_type metadata_type;
    216   1.9  riastrad 	uint16_t min_cll;
    217   1.9  riastrad 	uint16_t max_cll;
    218   1.9  riastrad 	uint16_t max_fall;
    219   1.9  riastrad };
    220   1.9  riastrad 
    221   1.9  riastrad struct hdr_sink_metadata {
    222   1.9  riastrad 	struct hdmi_type1 hdmi_type1;
    223   1.9  riastrad };
    224   1.9  riastrad 
    225   1.9  riastrad struct hdmi_drm_infoframe {
    226   1.9  riastrad 	enum hdmi_eotf eotf;
    227   1.9  riastrad 	enum hdmi_metadata_type metadata_type;
    228   1.9  riastrad 	struct {
    229   1.9  riastrad 		uint16_t x, y;
    230   1.9  riastrad 	} display_primaries[3];
    231   1.9  riastrad 	struct {
    232   1.9  riastrad 		uint16_t x, y;
    233   1.9  riastrad 	} white_point;
    234   1.9  riastrad 	uint16_t max_display_mastering_luminance;
    235   1.9  riastrad 	uint16_t min_display_mastering_luminance;
    236   1.9  riastrad 	uint16_t max_cll;
    237   1.9  riastrad 	uint16_t max_fall;
    238   1.9  riastrad };
    239   1.9  riastrad 
    240   1.1  riastrad static inline void
    241   1.1  riastrad hdmi_infoframe_header_init(struct hdmi_infoframe_header *header,
    242   1.1  riastrad     enum hdmi_infoframe_type type, uint8_t vers, uint8_t length)
    243   1.1  riastrad {
    244   1.1  riastrad 
    245   1.1  riastrad 	header->type = type;
    246   1.1  riastrad 	header->version = vers;
    247   1.1  riastrad 	header->length = length;
    248   1.1  riastrad }
    249   1.1  riastrad 
    250   1.1  riastrad static inline int
    251   1.1  riastrad hdmi_infoframe_header_pack(const struct hdmi_infoframe_header *header,
    252   1.1  riastrad     uint8_t length, void *buf, size_t size)
    253   1.1  riastrad {
    254   1.1  riastrad 	uint8_t *const p = buf;
    255   1.1  riastrad 
    256   1.5  riastrad 	if (length < HDMI_INFOFRAME_HEADER_SIZE)
    257   1.5  riastrad 		return -ENOSPC;
    258   1.5  riastrad 	if (size < length)
    259   1.1  riastrad 		return -ENOSPC;
    260   1.1  riastrad 
    261   1.1  riastrad 	p[0] = header->type;
    262   1.1  riastrad 	p[1] = header->version;
    263   1.4  riastrad 	p[2] = (length - HDMI_INFOFRAME_HEADER_SIZE);
    264   1.1  riastrad 	p[3] = 0;		/* checksum */
    265   1.1  riastrad 
    266   1.1  riastrad 	return HDMI_INFOFRAME_HEADER_SIZE;
    267   1.1  riastrad }
    268   1.1  riastrad 
    269   1.1  riastrad static inline void
    270   1.1  riastrad hdmi_infoframe_checksum(void *buf, size_t length)
    271   1.1  riastrad {
    272   1.1  riastrad 	uint8_t *p = buf;
    273   1.1  riastrad 	uint8_t checksum = 0;
    274   1.1  riastrad 
    275   1.1  riastrad 	while (length--)
    276   1.6  jmcneill 		checksum += *p++;
    277   1.1  riastrad 
    278   1.1  riastrad 	p = buf;
    279   1.1  riastrad 	p[3] = (256 - checksum);
    280   1.1  riastrad }
    281   1.1  riastrad 
    282   1.2  riastrad #define	HDMI_AUDIO_INFOFRAME_SIZE	10
    283   1.2  riastrad struct hdmi_audio_infoframe {
    284   1.2  riastrad 	struct hdmi_infoframe_header	header;
    285   1.2  riastrad 	uint8_t				channels;
    286   1.2  riastrad 	enum hdmi_audio_coding_type	coding_type;
    287   1.2  riastrad 	enum hdmi_audio_sample_size	sample_size;
    288   1.2  riastrad 	enum hdmi_audio_sample_frequency sample_frequency;
    289   1.2  riastrad 	enum hdmi_audio_coding_type_ext	coding_type_ext;
    290   1.2  riastrad 	uint8_t				channel_allocation;
    291   1.2  riastrad 	uint8_t				level_shift_value;
    292   1.2  riastrad 	bool				downmix_inhibit;
    293   1.2  riastrad };
    294   1.2  riastrad 
    295   1.2  riastrad static inline int
    296   1.2  riastrad hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
    297   1.2  riastrad {
    298   1.2  riastrad 	static const struct hdmi_audio_infoframe zero_frame;
    299   1.2  riastrad 
    300   1.2  riastrad 	*frame = zero_frame;
    301   1.2  riastrad 
    302   1.2  riastrad 	hdmi_infoframe_header_init(&frame->header, HDMI_INFOFRAME_TYPE_AUDIO,
    303   1.2  riastrad 	    1, HDMI_AUDIO_INFOFRAME_SIZE);
    304   1.2  riastrad 
    305   1.2  riastrad 	return 0;
    306   1.2  riastrad }
    307   1.2  riastrad 
    308   1.2  riastrad static inline ssize_t
    309   1.2  riastrad hdmi_audio_infoframe_pack(const struct hdmi_audio_infoframe *frame, void *buf,
    310   1.2  riastrad     size_t size)
    311   1.2  riastrad {
    312   1.2  riastrad 	const size_t length = HDMI_INFOFRAME_HEADER_SIZE +
    313   1.2  riastrad 	    HDMI_AUDIO_INFOFRAME_SIZE;
    314   1.2  riastrad 	uint8_t channels = 0;
    315   1.2  riastrad 	uint8_t *p = buf;
    316   1.2  riastrad 	int ret;
    317   1.2  riastrad 
    318   1.2  riastrad 	KASSERT(frame->header.length == HDMI_AUDIO_INFOFRAME_SIZE);
    319   1.2  riastrad 
    320   1.4  riastrad 	ret = hdmi_infoframe_header_pack(&frame->header, length, p, size);
    321   1.2  riastrad 	if (ret < 0)
    322   1.2  riastrad 		return ret;
    323   1.3  riastrad 	KASSERT(ret == HDMI_INFOFRAME_HEADER_SIZE);
    324   1.2  riastrad 	p += HDMI_INFOFRAME_HEADER_SIZE;
    325   1.2  riastrad 	size -= HDMI_INFOFRAME_HEADER_SIZE;
    326   1.2  riastrad 
    327   1.2  riastrad 	if (frame->channels >= 2)
    328   1.2  riastrad 		channels = frame->channels - 1;
    329   1.2  riastrad 
    330   1.2  riastrad 	p[0] = __SHIFTIN(frame->coding_type, __BITS(7,4));
    331   1.2  riastrad 	p[0] |= __SHIFTIN(channels, __BITS(2,0));
    332   1.2  riastrad 
    333   1.2  riastrad 	p[1] = __SHIFTIN(frame->sample_frequency, __BITS(4,2));
    334   1.2  riastrad 	p[1] |= __SHIFTIN(frame->sample_size, __BITS(1,0));
    335   1.2  riastrad 
    336   1.2  riastrad 	p[2] = __SHIFTIN(frame->coding_type_ext, __BITS(5,0));
    337   1.2  riastrad 
    338   1.2  riastrad 	p[3] = __SHIFTIN(frame->level_shift_value, __BITS(6, 3));
    339   1.2  riastrad 
    340   1.2  riastrad 	p[4] = __SHIFTIN(frame->downmix_inhibit? 1 : 0, __BIT(7));
    341   1.2  riastrad 
    342   1.6  jmcneill 	/* PB6 to PB10 are reserved */
    343   1.6  jmcneill 	p[5] = 0;
    344   1.6  jmcneill 	p[6] = 0;
    345   1.6  jmcneill 	p[7] = 0;
    346   1.6  jmcneill 	p[8] = 0;
    347   1.6  jmcneill 	p[9] = 0;
    348   1.6  jmcneill 
    349   1.2  riastrad 	CTASSERT(HDMI_AUDIO_INFOFRAME_SIZE == 10);
    350   1.2  riastrad 
    351   1.2  riastrad 	hdmi_infoframe_checksum(buf, length);
    352   1.2  riastrad 
    353   1.2  riastrad 	return length;
    354   1.2  riastrad }
    355   1.2  riastrad 
    356   1.1  riastrad #define	HDMI_AVI_INFOFRAME_SIZE		13
    357   1.1  riastrad struct hdmi_avi_infoframe {
    358   1.1  riastrad 	struct hdmi_infoframe_header	header;
    359   1.1  riastrad 	enum hdmi_colorspace		colorspace;
    360   1.1  riastrad 	enum hdmi_scan_mode		scan_mode;
    361   1.1  riastrad 	enum hdmi_colorimetry		colorimetry;
    362   1.1  riastrad 	enum hdmi_picture_aspect	picture_aspect;
    363   1.1  riastrad 	enum hdmi_active_aspect		active_aspect;
    364   1.1  riastrad 	bool				itc;
    365   1.1  riastrad 	enum hdmi_extended_colorimetry	extended_colorimetry;
    366   1.1  riastrad 	enum hdmi_quantization_range	quantization_range;
    367   1.1  riastrad 	enum hdmi_nups			nups;
    368   1.1  riastrad 	uint8_t				video_code;
    369   1.1  riastrad 	enum hdmi_ycc_quantization_range ycc_quantization_range;
    370   1.1  riastrad 	enum hdmi_content_type		content_type;
    371   1.1  riastrad 	uint8_t				pixel_repeat;
    372   1.1  riastrad 	uint16_t			top_bar;
    373   1.1  riastrad 	uint16_t			bottom_bar;
    374   1.1  riastrad 	uint16_t			left_bar;
    375   1.1  riastrad 	uint16_t			right_bar;
    376   1.1  riastrad };
    377   1.1  riastrad 
    378   1.1  riastrad static inline int
    379   1.1  riastrad hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
    380   1.1  riastrad {
    381   1.1  riastrad 	static const struct hdmi_avi_infoframe zero_frame;
    382   1.1  riastrad 
    383   1.1  riastrad 	*frame = zero_frame;
    384   1.1  riastrad 
    385   1.1  riastrad 	hdmi_infoframe_header_init(&frame->header, HDMI_INFOFRAME_TYPE_AVI, 2,
    386   1.1  riastrad 	    HDMI_AVI_INFOFRAME_SIZE);
    387   1.1  riastrad 
    388   1.1  riastrad 	return 0;
    389   1.1  riastrad }
    390   1.1  riastrad 
    391   1.1  riastrad static inline ssize_t
    392   1.1  riastrad hdmi_avi_infoframe_pack(const struct hdmi_avi_infoframe *frame, void *buf,
    393   1.1  riastrad     size_t size)
    394   1.1  riastrad {
    395   1.1  riastrad 	const size_t length = HDMI_INFOFRAME_HEADER_SIZE +
    396   1.1  riastrad 	    HDMI_AVI_INFOFRAME_SIZE;
    397   1.1  riastrad 	uint8_t *p = buf;
    398   1.1  riastrad 	int ret;
    399   1.1  riastrad 
    400   1.1  riastrad 	KASSERT(frame->header.length == HDMI_AVI_INFOFRAME_SIZE);
    401   1.1  riastrad 
    402   1.4  riastrad 	ret = hdmi_infoframe_header_pack(&frame->header, length, p, size);
    403   1.1  riastrad 	if (ret < 0)
    404   1.1  riastrad 		return ret;
    405   1.3  riastrad 	KASSERT(ret == HDMI_INFOFRAME_HEADER_SIZE);
    406   1.1  riastrad 	p += HDMI_INFOFRAME_HEADER_SIZE;
    407   1.1  riastrad 	size -= HDMI_INFOFRAME_HEADER_SIZE;
    408   1.1  riastrad 
    409   1.1  riastrad 	p[0] = __SHIFTIN(frame->colorspace, __BITS(6,5));
    410   1.1  riastrad 	p[0] |= __SHIFTIN(frame->active_aspect & 0xf? 1 : 0, __BIT(4));
    411   1.1  riastrad 	p[0] |= __SHIFTIN(frame->top_bar || frame->bottom_bar, __BIT(3));
    412   1.1  riastrad 	p[0] |= __SHIFTIN(frame->left_bar || frame->right_bar, __BIT(2));
    413   1.1  riastrad 	p[0] |= __SHIFTIN(frame->scan_mode, __BITS(1,0));
    414   1.1  riastrad 
    415   1.1  riastrad 	p[1] = __SHIFTIN(frame->colorimetry, __BITS(7,6));
    416   1.1  riastrad 	p[1] |= __SHIFTIN(frame->picture_aspect, __BITS(5,4));
    417   1.1  riastrad 	p[1] |= __SHIFTIN(frame->active_aspect, __BITS(3,0));
    418   1.1  riastrad 
    419   1.1  riastrad 	p[2] = __SHIFTIN(frame->itc? 1 : 0, __BIT(7));
    420   1.1  riastrad 	p[2] |= __SHIFTIN(frame->extended_colorimetry, __BITS(6,4));
    421   1.1  riastrad 	p[2] |= __SHIFTIN(frame->quantization_range, __BITS(3,2));
    422   1.1  riastrad 	p[2] |= __SHIFTIN(frame->nups, __BITS(1,0));
    423   1.1  riastrad 
    424   1.1  riastrad 	p[3] = frame->video_code;
    425   1.1  riastrad 
    426   1.1  riastrad 	p[4] = __SHIFTIN(frame->ycc_quantization_range, __BITS(7,6));
    427   1.1  riastrad 	p[4] |= __SHIFTIN(frame->content_type, __BITS(5,4));
    428   1.1  riastrad 	p[4] |= __SHIFTIN(frame->pixel_repeat, __BITS(3,0));
    429   1.1  riastrad 
    430   1.1  riastrad 	le16enc(&p[5], frame->top_bar);
    431   1.1  riastrad 	le16enc(&p[7], frame->bottom_bar);
    432   1.1  riastrad 	le16enc(&p[9], frame->left_bar);
    433   1.1  riastrad 	le16enc(&p[11], frame->right_bar);
    434   1.1  riastrad 	CTASSERT(HDMI_AVI_INFOFRAME_SIZE == 13);
    435   1.1  riastrad 
    436   1.1  riastrad 	hdmi_infoframe_checksum(buf, length);
    437   1.1  riastrad 
    438   1.1  riastrad 	return length;
    439   1.1  riastrad }
    440   1.1  riastrad 
    441   1.1  riastrad #define	HDMI_SPD_INFOFRAME_SIZE		25
    442   1.1  riastrad struct hdmi_spd_infoframe {
    443   1.1  riastrad 	struct hdmi_infoframe_header	header;
    444   1.1  riastrad 	char				vendor[8];
    445   1.1  riastrad 	char				product[16];
    446   1.1  riastrad 	enum hdmi_spd_sdi {
    447   1.1  riastrad 	        HDMI_SPD_SDI_UNKNOWN	= 0,
    448   1.1  riastrad 		HDMI_SPD_SDI_DSTB	= 1,
    449   1.1  riastrad 		HDMI_SPD_SDI_DVDP	= 2,
    450   1.1  riastrad 		HDMI_SPD_SDI_DVHS	= 3,
    451   1.1  riastrad 		HDMI_SPD_SDI_HDDVR	= 4,
    452   1.1  riastrad 		HDMI_SPD_SDI_DVC	= 5,
    453   1.1  riastrad 		HDMI_SPD_SDI_DSC	= 6,
    454   1.1  riastrad 		HDMI_SPD_SDI_VCD	= 7,
    455   1.1  riastrad 		HDMI_SPD_SDI_GAME	= 8,
    456   1.1  riastrad 		HDMI_SPD_SDI_PC		= 9,
    457   1.1  riastrad 		HDMI_SPD_SDI_BD		= 10,
    458   1.1  riastrad 		HDMI_SPD_SDI_SACD	= 11,
    459   1.1  riastrad 		HDMI_SPD_SDI_HDDVD	= 12,
    460   1.1  riastrad 		HDMI_SPD_SDI_PMP	= 13,
    461   1.1  riastrad 	}				sdi;
    462   1.1  riastrad };
    463   1.1  riastrad 
    464   1.1  riastrad static inline int
    465   1.1  riastrad hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, const char *vendor,
    466   1.1  riastrad     const char *product)
    467   1.1  riastrad {
    468   1.1  riastrad 	static const struct hdmi_spd_infoframe zero_frame;
    469   1.1  riastrad 
    470   1.1  riastrad 	*frame = zero_frame;
    471   1.1  riastrad 
    472   1.1  riastrad 	hdmi_infoframe_header_init(&frame->header, HDMI_INFOFRAME_TYPE_SPD,
    473   1.1  riastrad 	    1, HDMI_SPD_INFOFRAME_SIZE);
    474   1.1  riastrad 
    475   1.1  riastrad 	(void)strlcpy(frame->vendor, vendor, sizeof(frame->vendor));
    476   1.1  riastrad 	(void)strlcpy(frame->product, product, sizeof(frame->product));
    477   1.1  riastrad 
    478   1.1  riastrad 	return 0;
    479   1.1  riastrad }
    480   1.1  riastrad 
    481   1.1  riastrad static inline ssize_t
    482   1.1  riastrad hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buf,
    483   1.1  riastrad     size_t size)
    484   1.1  riastrad {
    485   1.1  riastrad 	const size_t length = HDMI_INFOFRAME_HEADER_SIZE +
    486   1.1  riastrad 	    HDMI_SPD_INFOFRAME_SIZE;
    487   1.1  riastrad 	uint8_t *p = buf;
    488   1.1  riastrad 	int ret;
    489   1.1  riastrad 
    490   1.1  riastrad 	KASSERT(frame->header.length == HDMI_SPD_INFOFRAME_SIZE);
    491   1.1  riastrad 
    492   1.4  riastrad 	ret = hdmi_infoframe_header_pack(&frame->header, length, p, size);
    493   1.1  riastrad 	if (ret < 0)
    494   1.1  riastrad 		return ret;
    495   1.3  riastrad 	KASSERT(ret == HDMI_INFOFRAME_HEADER_SIZE);
    496   1.1  riastrad 	p += HDMI_INFOFRAME_HEADER_SIZE;
    497   1.1  riastrad 	size -= HDMI_INFOFRAME_HEADER_SIZE;
    498   1.1  riastrad 
    499   1.1  riastrad 	(void)memcpy(&p[0], frame->vendor, 8);
    500   1.1  riastrad 	(void)memcpy(&p[8], frame->product, 16);
    501   1.1  riastrad 	p[24] = frame->sdi;
    502   1.1  riastrad 
    503   1.1  riastrad 	hdmi_infoframe_checksum(buf, length);
    504   1.1  riastrad 
    505   1.1  riastrad 	return length;
    506   1.1  riastrad }
    507   1.1  riastrad 
    508   1.7  riastrad #define	HDMI_IEEE_OUI		0x000c03
    509   1.7  riastrad #define	HDMI_FORUM_IEEE_OUI	0xc45dd8
    510   1.1  riastrad 
    511   1.1  riastrad struct hdmi_vendor_infoframe {
    512   1.1  riastrad 	struct hdmi_infoframe_header	header;
    513   1.1  riastrad 	uint32_t			oui;
    514   1.1  riastrad 	uint8_t				vic;
    515   1.1  riastrad 	enum hdmi_3d_structure		s3d_struct;
    516   1.1  riastrad 	unsigned			s3d_ext_data;
    517   1.1  riastrad };
    518   1.1  riastrad 
    519   1.1  riastrad union hdmi_vendor_any_infoframe {
    520   1.1  riastrad 	struct {
    521   1.1  riastrad 		struct hdmi_infoframe_header	header;
    522   1.1  riastrad 		uint32_t			oui;
    523   1.1  riastrad 	}				any;
    524   1.1  riastrad 	struct hdmi_vendor_infoframe	hdmi;
    525   1.1  riastrad };
    526   1.1  riastrad 
    527   1.1  riastrad static inline int
    528   1.1  riastrad hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame)
    529   1.1  riastrad {
    530   1.1  riastrad 	static const struct hdmi_vendor_infoframe zero_frame;
    531   1.1  riastrad 
    532   1.1  riastrad 	*frame = zero_frame;
    533   1.1  riastrad 
    534   1.1  riastrad 	hdmi_infoframe_header_init(&frame->header, HDMI_INFOFRAME_TYPE_VENDOR,
    535   1.1  riastrad 	    1, 0 /* depends on s3d_struct */);
    536   1.1  riastrad 
    537   1.1  riastrad 	frame->oui = HDMI_IEEE_OUI;
    538   1.1  riastrad 	frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID;
    539   1.1  riastrad 
    540   1.1  riastrad 	return 0;
    541   1.1  riastrad }
    542   1.1  riastrad 
    543   1.1  riastrad static inline int
    544   1.1  riastrad hdmi_vendor_infoframe_pack(const struct hdmi_vendor_infoframe *frame,
    545   1.1  riastrad     void *buf, size_t size)
    546   1.1  riastrad {
    547   1.1  riastrad 	uint8_t *p = buf;
    548   1.1  riastrad 	size_t length;
    549   1.1  riastrad 	int ret;
    550   1.1  riastrad 
    551   1.1  riastrad 	/* Exactly one must be supplied.  */
    552   1.1  riastrad 	if ((frame->vic == 0) ==
    553   1.1  riastrad 	    (frame->s3d_struct == HDMI_3D_STRUCTURE_INVALID))
    554   1.1  riastrad 		return -EINVAL;
    555   1.1  riastrad 
    556   1.1  riastrad 	length = HDMI_INFOFRAME_HEADER_SIZE + 6;
    557   1.1  riastrad 	if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
    558   1.1  riastrad 		length += 1;
    559   1.1  riastrad 
    560   1.4  riastrad 	ret = hdmi_infoframe_header_pack(&frame->header, length, p, size);
    561   1.1  riastrad 	if (ret < 0)
    562   1.1  riastrad 		return ret;
    563   1.3  riastrad 	KASSERT(ret == HDMI_INFOFRAME_HEADER_SIZE);
    564   1.1  riastrad 	p += HDMI_INFOFRAME_HEADER_SIZE;
    565   1.1  riastrad 	size -= HDMI_INFOFRAME_HEADER_SIZE;
    566   1.1  riastrad 
    567   1.1  riastrad 	p[0] = 0x03;
    568   1.1  riastrad 	p[1] = 0x0c;
    569   1.1  riastrad 	p[2] = 0x00;
    570   1.1  riastrad 
    571   1.1  riastrad 	if (frame->vic == 0) {
    572   1.1  riastrad 		p[3] = __SHIFTIN(0x2, __BITS(6,5));
    573   1.1  riastrad 		p[4] = __SHIFTIN(frame->s3d_struct, __BITS(7,4));
    574   1.1  riastrad 		if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
    575   1.1  riastrad 			p[9] = __SHIFTIN(frame->s3d_ext_data, __BITS(7,4));
    576   1.1  riastrad 	} else {
    577   1.1  riastrad 		p[3] = __SHIFTIN(0x1, __BITS(6,5));
    578   1.1  riastrad 		p[4] = frame->vic;
    579   1.1  riastrad 	}
    580   1.1  riastrad 
    581   1.1  riastrad 	hdmi_infoframe_checksum(buf, length);
    582   1.1  riastrad 
    583   1.1  riastrad 	return length;
    584   1.1  riastrad }
    585   1.1  riastrad 
    586   1.1  riastrad union hdmi_infoframe {
    587   1.1  riastrad 	struct hdmi_infoframe_header	any;
    588   1.1  riastrad 	struct hdmi_avi_infoframe	avi;
    589   1.1  riastrad 	struct hdmi_spd_infoframe	spd;
    590   1.1  riastrad 	union hdmi_vendor_any_infoframe	vendor;
    591   1.1  riastrad };
    592   1.1  riastrad 
    593   1.1  riastrad static inline ssize_t
    594   1.1  riastrad hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buf, size_t size)
    595   1.1  riastrad {
    596   1.1  riastrad 
    597   1.1  riastrad 	switch (frame->any.type) {
    598   1.1  riastrad 	case HDMI_INFOFRAME_TYPE_AVI:
    599   1.1  riastrad 		return hdmi_avi_infoframe_pack(&frame->avi, buf, size);
    600   1.1  riastrad 	case HDMI_INFOFRAME_TYPE_SPD:
    601   1.1  riastrad 		return hdmi_spd_infoframe_pack(&frame->spd, buf, size);
    602   1.1  riastrad 	case HDMI_INFOFRAME_TYPE_VENDOR:
    603   1.1  riastrad 		return hdmi_vendor_infoframe_pack(&frame->vendor.hdmi, buf,
    604   1.1  riastrad 		    size);
    605   1.1  riastrad 	default:
    606   1.1  riastrad 		return -EINVAL;
    607   1.1  riastrad 	}
    608   1.1  riastrad }
    609   1.1  riastrad 
    610   1.9  riastrad static inline int
    611   1.9  riastrad hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame)
    612   1.9  riastrad {
    613   1.9  riastrad 	panic("TODO");
    614   1.9  riastrad 	return 0;
    615   1.9  riastrad }
    616   1.8  riastrad 
    617  1.10  riastrad static inline void
    618  1.10  riastrad hdmi_infoframe_log(const char *level, struct device *device,
    619  1.10  riastrad     const union hdmi_infoframe *frame)
    620  1.10  riastrad {
    621  1.10  riastrad 	/* XXX */
    622  1.10  riastrad }
    623  1.10  riastrad 
    624   1.1  riastrad #endif	/* _LINUX_HDMI_H_ */
    625