1*f1d7ae31SEmmanuel Vadot /* 2*f1d7ae31SEmmanuel Vadot * Copyright (C) 2012 Avionic Design GmbH 3*f1d7ae31SEmmanuel Vadot * 4*f1d7ae31SEmmanuel Vadot * Permission is hereby granted, free of charge, to any person obtaining a 5*f1d7ae31SEmmanuel Vadot * copy of this software and associated documentation files (the "Software"), 6*f1d7ae31SEmmanuel Vadot * to deal in the Software without restriction, including without limitation 7*f1d7ae31SEmmanuel Vadot * the rights to use, copy, modify, merge, publish, distribute, sub license, 8*f1d7ae31SEmmanuel Vadot * and/or sell copies of the Software, and to permit persons to whom the 9*f1d7ae31SEmmanuel Vadot * Software is furnished to do so, subject to the following conditions: 10*f1d7ae31SEmmanuel Vadot * 11*f1d7ae31SEmmanuel Vadot * The above copyright notice and this permission notice (including the 12*f1d7ae31SEmmanuel Vadot * next paragraph) shall be included in all copies or substantial portions 13*f1d7ae31SEmmanuel Vadot * of the Software. 14*f1d7ae31SEmmanuel Vadot * 15*f1d7ae31SEmmanuel Vadot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16*f1d7ae31SEmmanuel Vadot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17*f1d7ae31SEmmanuel Vadot * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18*f1d7ae31SEmmanuel Vadot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19*f1d7ae31SEmmanuel Vadot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20*f1d7ae31SEmmanuel Vadot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21*f1d7ae31SEmmanuel Vadot * DEALINGS IN THE SOFTWARE. 22*f1d7ae31SEmmanuel Vadot */ 23*f1d7ae31SEmmanuel Vadot 24*f1d7ae31SEmmanuel Vadot #ifdef __FreeBSD__ 25*f1d7ae31SEmmanuel Vadot #include <sys/cdefs.h> 26*f1d7ae31SEmmanuel Vadot #include <sys/param.h> 27*f1d7ae31SEmmanuel Vadot #include <sys/module.h> 28*f1d7ae31SEmmanuel Vadot #endif 29*f1d7ae31SEmmanuel Vadot 30*f1d7ae31SEmmanuel Vadot #include <linux/bitops.h> 31*f1d7ae31SEmmanuel Vadot #include <linux/bug.h> 32*f1d7ae31SEmmanuel Vadot #include <linux/errno.h> 33*f1d7ae31SEmmanuel Vadot #include <linux/export.h> 34*f1d7ae31SEmmanuel Vadot #include <linux/hdmi.h> 35*f1d7ae31SEmmanuel Vadot #include <linux/string.h> 36*f1d7ae31SEmmanuel Vadot #include <linux/device.h> 37*f1d7ae31SEmmanuel Vadot 38*f1d7ae31SEmmanuel Vadot #define hdmi_log(fmt, ...) dev_printk(level, dev, fmt, ##__VA_ARGS__) 39*f1d7ae31SEmmanuel Vadot 40*f1d7ae31SEmmanuel Vadot static u8 hdmi_infoframe_checksum(const u8 *ptr, size_t size) 41*f1d7ae31SEmmanuel Vadot { 42*f1d7ae31SEmmanuel Vadot u8 csum = 0; 43*f1d7ae31SEmmanuel Vadot size_t i; 44*f1d7ae31SEmmanuel Vadot 45*f1d7ae31SEmmanuel Vadot /* compute checksum */ 46*f1d7ae31SEmmanuel Vadot for (i = 0; i < size; i++) 47*f1d7ae31SEmmanuel Vadot csum += ptr[i]; 48*f1d7ae31SEmmanuel Vadot 49*f1d7ae31SEmmanuel Vadot return 256 - csum; 50*f1d7ae31SEmmanuel Vadot } 51*f1d7ae31SEmmanuel Vadot 52*f1d7ae31SEmmanuel Vadot static void hdmi_infoframe_set_checksum(void *buffer, size_t size) 53*f1d7ae31SEmmanuel Vadot { 54*f1d7ae31SEmmanuel Vadot u8 *ptr = buffer; 55*f1d7ae31SEmmanuel Vadot 56*f1d7ae31SEmmanuel Vadot ptr[3] = hdmi_infoframe_checksum(buffer, size); 57*f1d7ae31SEmmanuel Vadot } 58*f1d7ae31SEmmanuel Vadot 59*f1d7ae31SEmmanuel Vadot /** 60*f1d7ae31SEmmanuel Vadot * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe 61*f1d7ae31SEmmanuel Vadot * @frame: HDMI AVI infoframe 62*f1d7ae31SEmmanuel Vadot */ 63*f1d7ae31SEmmanuel Vadot void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame) 64*f1d7ae31SEmmanuel Vadot { 65*f1d7ae31SEmmanuel Vadot memset(frame, 0, sizeof(*frame)); 66*f1d7ae31SEmmanuel Vadot 67*f1d7ae31SEmmanuel Vadot frame->type = HDMI_INFOFRAME_TYPE_AVI; 68*f1d7ae31SEmmanuel Vadot frame->version = 2; 69*f1d7ae31SEmmanuel Vadot frame->length = HDMI_AVI_INFOFRAME_SIZE; 70*f1d7ae31SEmmanuel Vadot } 71*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_avi_infoframe_init); 72*f1d7ae31SEmmanuel Vadot 73*f1d7ae31SEmmanuel Vadot static int hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe *frame) 74*f1d7ae31SEmmanuel Vadot { 75*f1d7ae31SEmmanuel Vadot if (frame->type != HDMI_INFOFRAME_TYPE_AVI || 76*f1d7ae31SEmmanuel Vadot frame->version != 2 || 77*f1d7ae31SEmmanuel Vadot frame->length != HDMI_AVI_INFOFRAME_SIZE) 78*f1d7ae31SEmmanuel Vadot return -EINVAL; 79*f1d7ae31SEmmanuel Vadot 80*f1d7ae31SEmmanuel Vadot if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9) 81*f1d7ae31SEmmanuel Vadot return -EINVAL; 82*f1d7ae31SEmmanuel Vadot 83*f1d7ae31SEmmanuel Vadot return 0; 84*f1d7ae31SEmmanuel Vadot } 85*f1d7ae31SEmmanuel Vadot 86*f1d7ae31SEmmanuel Vadot /** 87*f1d7ae31SEmmanuel Vadot * hdmi_avi_infoframe_check() - check a HDMI AVI infoframe 88*f1d7ae31SEmmanuel Vadot * @frame: HDMI AVI infoframe 89*f1d7ae31SEmmanuel Vadot * 90*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 91*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields. 92*f1d7ae31SEmmanuel Vadot * 93*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 94*f1d7ae31SEmmanuel Vadot */ 95*f1d7ae31SEmmanuel Vadot int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame) 96*f1d7ae31SEmmanuel Vadot { 97*f1d7ae31SEmmanuel Vadot return hdmi_avi_infoframe_check_only(frame); 98*f1d7ae31SEmmanuel Vadot } 99*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_avi_infoframe_check); 100*f1d7ae31SEmmanuel Vadot 101*f1d7ae31SEmmanuel Vadot /** 102*f1d7ae31SEmmanuel Vadot * hdmi_avi_infoframe_pack_only() - write HDMI AVI infoframe to binary buffer 103*f1d7ae31SEmmanuel Vadot * @frame: HDMI AVI infoframe 104*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 105*f1d7ae31SEmmanuel Vadot * @size: size of buffer 106*f1d7ae31SEmmanuel Vadot * 107*f1d7ae31SEmmanuel Vadot * Packs the information contained in the @frame structure into a binary 108*f1d7ae31SEmmanuel Vadot * representation that can be written into the corresponding controller 109*f1d7ae31SEmmanuel Vadot * registers. Also computes the checksum as required by section 5.3.5 of 110*f1d7ae31SEmmanuel Vadot * the HDMI 1.4 specification. 111*f1d7ae31SEmmanuel Vadot * 112*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 113*f1d7ae31SEmmanuel Vadot * error code on failure. 114*f1d7ae31SEmmanuel Vadot */ 115*f1d7ae31SEmmanuel Vadot ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame, 116*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 117*f1d7ae31SEmmanuel Vadot { 118*f1d7ae31SEmmanuel Vadot u8 *ptr = buffer; 119*f1d7ae31SEmmanuel Vadot size_t length; 120*f1d7ae31SEmmanuel Vadot int ret; 121*f1d7ae31SEmmanuel Vadot 122*f1d7ae31SEmmanuel Vadot ret = hdmi_avi_infoframe_check_only(frame); 123*f1d7ae31SEmmanuel Vadot if (ret) 124*f1d7ae31SEmmanuel Vadot return ret; 125*f1d7ae31SEmmanuel Vadot 126*f1d7ae31SEmmanuel Vadot length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; 127*f1d7ae31SEmmanuel Vadot 128*f1d7ae31SEmmanuel Vadot if (size < length) 129*f1d7ae31SEmmanuel Vadot return -ENOSPC; 130*f1d7ae31SEmmanuel Vadot 131*f1d7ae31SEmmanuel Vadot memset(buffer, 0, size); 132*f1d7ae31SEmmanuel Vadot 133*f1d7ae31SEmmanuel Vadot ptr[0] = frame->type; 134*f1d7ae31SEmmanuel Vadot ptr[1] = frame->version; 135*f1d7ae31SEmmanuel Vadot ptr[2] = frame->length; 136*f1d7ae31SEmmanuel Vadot ptr[3] = 0; /* checksum */ 137*f1d7ae31SEmmanuel Vadot 138*f1d7ae31SEmmanuel Vadot /* start infoframe payload */ 139*f1d7ae31SEmmanuel Vadot ptr += HDMI_INFOFRAME_HEADER_SIZE; 140*f1d7ae31SEmmanuel Vadot 141*f1d7ae31SEmmanuel Vadot ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3); 142*f1d7ae31SEmmanuel Vadot 143*f1d7ae31SEmmanuel Vadot /* 144*f1d7ae31SEmmanuel Vadot * Data byte 1, bit 4 has to be set if we provide the active format 145*f1d7ae31SEmmanuel Vadot * aspect ratio 146*f1d7ae31SEmmanuel Vadot */ 147*f1d7ae31SEmmanuel Vadot if (frame->active_aspect & 0xf) 148*f1d7ae31SEmmanuel Vadot ptr[0] |= BIT(4); 149*f1d7ae31SEmmanuel Vadot 150*f1d7ae31SEmmanuel Vadot /* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */ 151*f1d7ae31SEmmanuel Vadot if (frame->top_bar || frame->bottom_bar) 152*f1d7ae31SEmmanuel Vadot ptr[0] |= BIT(3); 153*f1d7ae31SEmmanuel Vadot 154*f1d7ae31SEmmanuel Vadot if (frame->left_bar || frame->right_bar) 155*f1d7ae31SEmmanuel Vadot ptr[0] |= BIT(2); 156*f1d7ae31SEmmanuel Vadot 157*f1d7ae31SEmmanuel Vadot ptr[1] = ((frame->colorimetry & 0x3) << 6) | 158*f1d7ae31SEmmanuel Vadot ((frame->picture_aspect & 0x3) << 4) | 159*f1d7ae31SEmmanuel Vadot (frame->active_aspect & 0xf); 160*f1d7ae31SEmmanuel Vadot 161*f1d7ae31SEmmanuel Vadot ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) | 162*f1d7ae31SEmmanuel Vadot ((frame->quantization_range & 0x3) << 2) | 163*f1d7ae31SEmmanuel Vadot (frame->nups & 0x3); 164*f1d7ae31SEmmanuel Vadot 165*f1d7ae31SEmmanuel Vadot if (frame->itc) 166*f1d7ae31SEmmanuel Vadot ptr[2] |= BIT(7); 167*f1d7ae31SEmmanuel Vadot 168*f1d7ae31SEmmanuel Vadot ptr[3] = frame->video_code & 0x7f; 169*f1d7ae31SEmmanuel Vadot 170*f1d7ae31SEmmanuel Vadot ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) | 171*f1d7ae31SEmmanuel Vadot ((frame->content_type & 0x3) << 4) | 172*f1d7ae31SEmmanuel Vadot (frame->pixel_repeat & 0xf); 173*f1d7ae31SEmmanuel Vadot 174*f1d7ae31SEmmanuel Vadot ptr[5] = frame->top_bar & 0xff; 175*f1d7ae31SEmmanuel Vadot ptr[6] = (frame->top_bar >> 8) & 0xff; 176*f1d7ae31SEmmanuel Vadot ptr[7] = frame->bottom_bar & 0xff; 177*f1d7ae31SEmmanuel Vadot ptr[8] = (frame->bottom_bar >> 8) & 0xff; 178*f1d7ae31SEmmanuel Vadot ptr[9] = frame->left_bar & 0xff; 179*f1d7ae31SEmmanuel Vadot ptr[10] = (frame->left_bar >> 8) & 0xff; 180*f1d7ae31SEmmanuel Vadot ptr[11] = frame->right_bar & 0xff; 181*f1d7ae31SEmmanuel Vadot ptr[12] = (frame->right_bar >> 8) & 0xff; 182*f1d7ae31SEmmanuel Vadot 183*f1d7ae31SEmmanuel Vadot hdmi_infoframe_set_checksum(buffer, length); 184*f1d7ae31SEmmanuel Vadot 185*f1d7ae31SEmmanuel Vadot return length; 186*f1d7ae31SEmmanuel Vadot } 187*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_avi_infoframe_pack_only); 188*f1d7ae31SEmmanuel Vadot 189*f1d7ae31SEmmanuel Vadot /** 190*f1d7ae31SEmmanuel Vadot * hdmi_avi_infoframe_pack() - check a HDMI AVI infoframe, 191*f1d7ae31SEmmanuel Vadot * and write it to binary buffer 192*f1d7ae31SEmmanuel Vadot * @frame: HDMI AVI infoframe 193*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 194*f1d7ae31SEmmanuel Vadot * @size: size of buffer 195*f1d7ae31SEmmanuel Vadot * 196*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 197*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields, after which it packs the information 198*f1d7ae31SEmmanuel Vadot * contained in the @frame structure into a binary representation that 199*f1d7ae31SEmmanuel Vadot * can be written into the corresponding controller registers. This function 200*f1d7ae31SEmmanuel Vadot * also computes the checksum as required by section 5.3.5 of the HDMI 1.4 201*f1d7ae31SEmmanuel Vadot * specification. 202*f1d7ae31SEmmanuel Vadot * 203*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 204*f1d7ae31SEmmanuel Vadot * error code on failure. 205*f1d7ae31SEmmanuel Vadot */ 206*f1d7ae31SEmmanuel Vadot ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, 207*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 208*f1d7ae31SEmmanuel Vadot { 209*f1d7ae31SEmmanuel Vadot int ret; 210*f1d7ae31SEmmanuel Vadot 211*f1d7ae31SEmmanuel Vadot ret = hdmi_avi_infoframe_check(frame); 212*f1d7ae31SEmmanuel Vadot if (ret) 213*f1d7ae31SEmmanuel Vadot return ret; 214*f1d7ae31SEmmanuel Vadot 215*f1d7ae31SEmmanuel Vadot return hdmi_avi_infoframe_pack_only(frame, buffer, size); 216*f1d7ae31SEmmanuel Vadot } 217*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_avi_infoframe_pack); 218*f1d7ae31SEmmanuel Vadot 219*f1d7ae31SEmmanuel Vadot /** 220*f1d7ae31SEmmanuel Vadot * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe 221*f1d7ae31SEmmanuel Vadot * @frame: HDMI SPD infoframe 222*f1d7ae31SEmmanuel Vadot * @vendor: vendor string 223*f1d7ae31SEmmanuel Vadot * @product: product string 224*f1d7ae31SEmmanuel Vadot * 225*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 226*f1d7ae31SEmmanuel Vadot */ 227*f1d7ae31SEmmanuel Vadot int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, 228*f1d7ae31SEmmanuel Vadot const char *vendor, const char *product) 229*f1d7ae31SEmmanuel Vadot { 230*f1d7ae31SEmmanuel Vadot size_t len; 231*f1d7ae31SEmmanuel Vadot 232*f1d7ae31SEmmanuel Vadot memset(frame, 0, sizeof(*frame)); 233*f1d7ae31SEmmanuel Vadot 234*f1d7ae31SEmmanuel Vadot frame->type = HDMI_INFOFRAME_TYPE_SPD; 235*f1d7ae31SEmmanuel Vadot frame->version = 1; 236*f1d7ae31SEmmanuel Vadot frame->length = HDMI_SPD_INFOFRAME_SIZE; 237*f1d7ae31SEmmanuel Vadot 238*f1d7ae31SEmmanuel Vadot len = strlen(vendor); 239*f1d7ae31SEmmanuel Vadot memcpy(frame->vendor, vendor, min(len, sizeof(frame->vendor))); 240*f1d7ae31SEmmanuel Vadot len = strlen(product); 241*f1d7ae31SEmmanuel Vadot memcpy(frame->product, product, min(len, sizeof(frame->product))); 242*f1d7ae31SEmmanuel Vadot 243*f1d7ae31SEmmanuel Vadot return 0; 244*f1d7ae31SEmmanuel Vadot } 245*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_spd_infoframe_init); 246*f1d7ae31SEmmanuel Vadot 247*f1d7ae31SEmmanuel Vadot static int hdmi_spd_infoframe_check_only(const struct hdmi_spd_infoframe *frame) 248*f1d7ae31SEmmanuel Vadot { 249*f1d7ae31SEmmanuel Vadot if (frame->type != HDMI_INFOFRAME_TYPE_SPD || 250*f1d7ae31SEmmanuel Vadot frame->version != 1 || 251*f1d7ae31SEmmanuel Vadot frame->length != HDMI_SPD_INFOFRAME_SIZE) 252*f1d7ae31SEmmanuel Vadot return -EINVAL; 253*f1d7ae31SEmmanuel Vadot 254*f1d7ae31SEmmanuel Vadot return 0; 255*f1d7ae31SEmmanuel Vadot } 256*f1d7ae31SEmmanuel Vadot 257*f1d7ae31SEmmanuel Vadot /** 258*f1d7ae31SEmmanuel Vadot * hdmi_spd_infoframe_check() - check a HDMI SPD infoframe 259*f1d7ae31SEmmanuel Vadot * @frame: HDMI SPD infoframe 260*f1d7ae31SEmmanuel Vadot * 261*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 262*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields. 263*f1d7ae31SEmmanuel Vadot * 264*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 265*f1d7ae31SEmmanuel Vadot */ 266*f1d7ae31SEmmanuel Vadot int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame) 267*f1d7ae31SEmmanuel Vadot { 268*f1d7ae31SEmmanuel Vadot return hdmi_spd_infoframe_check_only(frame); 269*f1d7ae31SEmmanuel Vadot } 270*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_spd_infoframe_check); 271*f1d7ae31SEmmanuel Vadot 272*f1d7ae31SEmmanuel Vadot /** 273*f1d7ae31SEmmanuel Vadot * hdmi_spd_infoframe_pack_only() - write HDMI SPD infoframe to binary buffer 274*f1d7ae31SEmmanuel Vadot * @frame: HDMI SPD infoframe 275*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 276*f1d7ae31SEmmanuel Vadot * @size: size of buffer 277*f1d7ae31SEmmanuel Vadot * 278*f1d7ae31SEmmanuel Vadot * Packs the information contained in the @frame structure into a binary 279*f1d7ae31SEmmanuel Vadot * representation that can be written into the corresponding controller 280*f1d7ae31SEmmanuel Vadot * registers. Also computes the checksum as required by section 5.3.5 of 281*f1d7ae31SEmmanuel Vadot * the HDMI 1.4 specification. 282*f1d7ae31SEmmanuel Vadot * 283*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 284*f1d7ae31SEmmanuel Vadot * error code on failure. 285*f1d7ae31SEmmanuel Vadot */ 286*f1d7ae31SEmmanuel Vadot ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame, 287*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 288*f1d7ae31SEmmanuel Vadot { 289*f1d7ae31SEmmanuel Vadot u8 *ptr = buffer; 290*f1d7ae31SEmmanuel Vadot size_t length; 291*f1d7ae31SEmmanuel Vadot int ret; 292*f1d7ae31SEmmanuel Vadot 293*f1d7ae31SEmmanuel Vadot ret = hdmi_spd_infoframe_check_only(frame); 294*f1d7ae31SEmmanuel Vadot if (ret) 295*f1d7ae31SEmmanuel Vadot return ret; 296*f1d7ae31SEmmanuel Vadot 297*f1d7ae31SEmmanuel Vadot length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; 298*f1d7ae31SEmmanuel Vadot 299*f1d7ae31SEmmanuel Vadot if (size < length) 300*f1d7ae31SEmmanuel Vadot return -ENOSPC; 301*f1d7ae31SEmmanuel Vadot 302*f1d7ae31SEmmanuel Vadot memset(buffer, 0, size); 303*f1d7ae31SEmmanuel Vadot 304*f1d7ae31SEmmanuel Vadot ptr[0] = frame->type; 305*f1d7ae31SEmmanuel Vadot ptr[1] = frame->version; 306*f1d7ae31SEmmanuel Vadot ptr[2] = frame->length; 307*f1d7ae31SEmmanuel Vadot ptr[3] = 0; /* checksum */ 308*f1d7ae31SEmmanuel Vadot 309*f1d7ae31SEmmanuel Vadot /* start infoframe payload */ 310*f1d7ae31SEmmanuel Vadot ptr += HDMI_INFOFRAME_HEADER_SIZE; 311*f1d7ae31SEmmanuel Vadot 312*f1d7ae31SEmmanuel Vadot memcpy(ptr, frame->vendor, sizeof(frame->vendor)); 313*f1d7ae31SEmmanuel Vadot memcpy(ptr + 8, frame->product, sizeof(frame->product)); 314*f1d7ae31SEmmanuel Vadot 315*f1d7ae31SEmmanuel Vadot ptr[24] = frame->sdi; 316*f1d7ae31SEmmanuel Vadot 317*f1d7ae31SEmmanuel Vadot hdmi_infoframe_set_checksum(buffer, length); 318*f1d7ae31SEmmanuel Vadot 319*f1d7ae31SEmmanuel Vadot return length; 320*f1d7ae31SEmmanuel Vadot } 321*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_spd_infoframe_pack_only); 322*f1d7ae31SEmmanuel Vadot 323*f1d7ae31SEmmanuel Vadot /** 324*f1d7ae31SEmmanuel Vadot * hdmi_spd_infoframe_pack() - check a HDMI SPD infoframe, 325*f1d7ae31SEmmanuel Vadot * and write it to binary buffer 326*f1d7ae31SEmmanuel Vadot * @frame: HDMI SPD infoframe 327*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 328*f1d7ae31SEmmanuel Vadot * @size: size of buffer 329*f1d7ae31SEmmanuel Vadot * 330*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 331*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields, after which it packs the information 332*f1d7ae31SEmmanuel Vadot * contained in the @frame structure into a binary representation that 333*f1d7ae31SEmmanuel Vadot * can be written into the corresponding controller registers. This function 334*f1d7ae31SEmmanuel Vadot * also computes the checksum as required by section 5.3.5 of the HDMI 1.4 335*f1d7ae31SEmmanuel Vadot * specification. 336*f1d7ae31SEmmanuel Vadot * 337*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 338*f1d7ae31SEmmanuel Vadot * error code on failure. 339*f1d7ae31SEmmanuel Vadot */ 340*f1d7ae31SEmmanuel Vadot ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, 341*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 342*f1d7ae31SEmmanuel Vadot { 343*f1d7ae31SEmmanuel Vadot int ret; 344*f1d7ae31SEmmanuel Vadot 345*f1d7ae31SEmmanuel Vadot ret = hdmi_spd_infoframe_check(frame); 346*f1d7ae31SEmmanuel Vadot if (ret) 347*f1d7ae31SEmmanuel Vadot return ret; 348*f1d7ae31SEmmanuel Vadot 349*f1d7ae31SEmmanuel Vadot return hdmi_spd_infoframe_pack_only(frame, buffer, size); 350*f1d7ae31SEmmanuel Vadot } 351*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_spd_infoframe_pack); 352*f1d7ae31SEmmanuel Vadot 353*f1d7ae31SEmmanuel Vadot /** 354*f1d7ae31SEmmanuel Vadot * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe 355*f1d7ae31SEmmanuel Vadot * @frame: HDMI audio infoframe 356*f1d7ae31SEmmanuel Vadot * 357*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 358*f1d7ae31SEmmanuel Vadot */ 359*f1d7ae31SEmmanuel Vadot int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame) 360*f1d7ae31SEmmanuel Vadot { 361*f1d7ae31SEmmanuel Vadot memset(frame, 0, sizeof(*frame)); 362*f1d7ae31SEmmanuel Vadot 363*f1d7ae31SEmmanuel Vadot frame->type = HDMI_INFOFRAME_TYPE_AUDIO; 364*f1d7ae31SEmmanuel Vadot frame->version = 1; 365*f1d7ae31SEmmanuel Vadot frame->length = HDMI_AUDIO_INFOFRAME_SIZE; 366*f1d7ae31SEmmanuel Vadot 367*f1d7ae31SEmmanuel Vadot return 0; 368*f1d7ae31SEmmanuel Vadot } 369*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_audio_infoframe_init); 370*f1d7ae31SEmmanuel Vadot 371*f1d7ae31SEmmanuel Vadot static int hdmi_audio_infoframe_check_only(const struct hdmi_audio_infoframe *frame) 372*f1d7ae31SEmmanuel Vadot { 373*f1d7ae31SEmmanuel Vadot if (frame->type != HDMI_INFOFRAME_TYPE_AUDIO || 374*f1d7ae31SEmmanuel Vadot frame->version != 1 || 375*f1d7ae31SEmmanuel Vadot frame->length != HDMI_AUDIO_INFOFRAME_SIZE) 376*f1d7ae31SEmmanuel Vadot return -EINVAL; 377*f1d7ae31SEmmanuel Vadot 378*f1d7ae31SEmmanuel Vadot return 0; 379*f1d7ae31SEmmanuel Vadot } 380*f1d7ae31SEmmanuel Vadot 381*f1d7ae31SEmmanuel Vadot /** 382*f1d7ae31SEmmanuel Vadot * hdmi_audio_infoframe_check() - check a HDMI audio infoframe 383*f1d7ae31SEmmanuel Vadot * @frame: HDMI audio infoframe 384*f1d7ae31SEmmanuel Vadot * 385*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 386*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields. 387*f1d7ae31SEmmanuel Vadot * 388*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 389*f1d7ae31SEmmanuel Vadot */ 390*f1d7ae31SEmmanuel Vadot int hdmi_audio_infoframe_check(struct hdmi_audio_infoframe *frame) 391*f1d7ae31SEmmanuel Vadot { 392*f1d7ae31SEmmanuel Vadot return hdmi_audio_infoframe_check_only(frame); 393*f1d7ae31SEmmanuel Vadot } 394*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_audio_infoframe_check); 395*f1d7ae31SEmmanuel Vadot 396*f1d7ae31SEmmanuel Vadot /** 397*f1d7ae31SEmmanuel Vadot * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary buffer 398*f1d7ae31SEmmanuel Vadot * @frame: HDMI audio infoframe 399*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 400*f1d7ae31SEmmanuel Vadot * @size: size of buffer 401*f1d7ae31SEmmanuel Vadot * 402*f1d7ae31SEmmanuel Vadot * Packs the information contained in the @frame structure into a binary 403*f1d7ae31SEmmanuel Vadot * representation that can be written into the corresponding controller 404*f1d7ae31SEmmanuel Vadot * registers. Also computes the checksum as required by section 5.3.5 of 405*f1d7ae31SEmmanuel Vadot * the HDMI 1.4 specification. 406*f1d7ae31SEmmanuel Vadot * 407*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 408*f1d7ae31SEmmanuel Vadot * error code on failure. 409*f1d7ae31SEmmanuel Vadot */ 410*f1d7ae31SEmmanuel Vadot ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame, 411*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 412*f1d7ae31SEmmanuel Vadot { 413*f1d7ae31SEmmanuel Vadot unsigned char channels; 414*f1d7ae31SEmmanuel Vadot u8 *ptr = buffer; 415*f1d7ae31SEmmanuel Vadot size_t length; 416*f1d7ae31SEmmanuel Vadot int ret; 417*f1d7ae31SEmmanuel Vadot 418*f1d7ae31SEmmanuel Vadot ret = hdmi_audio_infoframe_check_only(frame); 419*f1d7ae31SEmmanuel Vadot if (ret) 420*f1d7ae31SEmmanuel Vadot return ret; 421*f1d7ae31SEmmanuel Vadot 422*f1d7ae31SEmmanuel Vadot length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; 423*f1d7ae31SEmmanuel Vadot 424*f1d7ae31SEmmanuel Vadot if (size < length) 425*f1d7ae31SEmmanuel Vadot return -ENOSPC; 426*f1d7ae31SEmmanuel Vadot 427*f1d7ae31SEmmanuel Vadot memset(buffer, 0, size); 428*f1d7ae31SEmmanuel Vadot 429*f1d7ae31SEmmanuel Vadot if (frame->channels >= 2) 430*f1d7ae31SEmmanuel Vadot channels = frame->channels - 1; 431*f1d7ae31SEmmanuel Vadot else 432*f1d7ae31SEmmanuel Vadot channels = 0; 433*f1d7ae31SEmmanuel Vadot 434*f1d7ae31SEmmanuel Vadot ptr[0] = frame->type; 435*f1d7ae31SEmmanuel Vadot ptr[1] = frame->version; 436*f1d7ae31SEmmanuel Vadot ptr[2] = frame->length; 437*f1d7ae31SEmmanuel Vadot ptr[3] = 0; /* checksum */ 438*f1d7ae31SEmmanuel Vadot 439*f1d7ae31SEmmanuel Vadot /* start infoframe payload */ 440*f1d7ae31SEmmanuel Vadot ptr += HDMI_INFOFRAME_HEADER_SIZE; 441*f1d7ae31SEmmanuel Vadot 442*f1d7ae31SEmmanuel Vadot ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7); 443*f1d7ae31SEmmanuel Vadot ptr[1] = ((frame->sample_frequency & 0x7) << 2) | 444*f1d7ae31SEmmanuel Vadot (frame->sample_size & 0x3); 445*f1d7ae31SEmmanuel Vadot ptr[2] = frame->coding_type_ext & 0x1f; 446*f1d7ae31SEmmanuel Vadot ptr[3] = frame->channel_allocation; 447*f1d7ae31SEmmanuel Vadot ptr[4] = (frame->level_shift_value & 0xf) << 3; 448*f1d7ae31SEmmanuel Vadot 449*f1d7ae31SEmmanuel Vadot if (frame->downmix_inhibit) 450*f1d7ae31SEmmanuel Vadot ptr[4] |= BIT(7); 451*f1d7ae31SEmmanuel Vadot 452*f1d7ae31SEmmanuel Vadot hdmi_infoframe_set_checksum(buffer, length); 453*f1d7ae31SEmmanuel Vadot 454*f1d7ae31SEmmanuel Vadot return length; 455*f1d7ae31SEmmanuel Vadot } 456*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_audio_infoframe_pack_only); 457*f1d7ae31SEmmanuel Vadot 458*f1d7ae31SEmmanuel Vadot /** 459*f1d7ae31SEmmanuel Vadot * hdmi_audio_infoframe_pack() - check a HDMI Audio infoframe, 460*f1d7ae31SEmmanuel Vadot * and write it to binary buffer 461*f1d7ae31SEmmanuel Vadot * @frame: HDMI Audio infoframe 462*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 463*f1d7ae31SEmmanuel Vadot * @size: size of buffer 464*f1d7ae31SEmmanuel Vadot * 465*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 466*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields, after which it packs the information 467*f1d7ae31SEmmanuel Vadot * contained in the @frame structure into a binary representation that 468*f1d7ae31SEmmanuel Vadot * can be written into the corresponding controller registers. This function 469*f1d7ae31SEmmanuel Vadot * also computes the checksum as required by section 5.3.5 of the HDMI 1.4 470*f1d7ae31SEmmanuel Vadot * specification. 471*f1d7ae31SEmmanuel Vadot * 472*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 473*f1d7ae31SEmmanuel Vadot * error code on failure. 474*f1d7ae31SEmmanuel Vadot */ 475*f1d7ae31SEmmanuel Vadot ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, 476*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 477*f1d7ae31SEmmanuel Vadot { 478*f1d7ae31SEmmanuel Vadot int ret; 479*f1d7ae31SEmmanuel Vadot 480*f1d7ae31SEmmanuel Vadot ret = hdmi_audio_infoframe_check(frame); 481*f1d7ae31SEmmanuel Vadot if (ret) 482*f1d7ae31SEmmanuel Vadot return ret; 483*f1d7ae31SEmmanuel Vadot 484*f1d7ae31SEmmanuel Vadot return hdmi_audio_infoframe_pack_only(frame, buffer, size); 485*f1d7ae31SEmmanuel Vadot } 486*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_audio_infoframe_pack); 487*f1d7ae31SEmmanuel Vadot 488*f1d7ae31SEmmanuel Vadot /** 489*f1d7ae31SEmmanuel Vadot * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe 490*f1d7ae31SEmmanuel Vadot * @frame: HDMI vendor infoframe 491*f1d7ae31SEmmanuel Vadot * 492*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 493*f1d7ae31SEmmanuel Vadot */ 494*f1d7ae31SEmmanuel Vadot int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame) 495*f1d7ae31SEmmanuel Vadot { 496*f1d7ae31SEmmanuel Vadot memset(frame, 0, sizeof(*frame)); 497*f1d7ae31SEmmanuel Vadot 498*f1d7ae31SEmmanuel Vadot frame->type = HDMI_INFOFRAME_TYPE_VENDOR; 499*f1d7ae31SEmmanuel Vadot frame->version = 1; 500*f1d7ae31SEmmanuel Vadot 501*f1d7ae31SEmmanuel Vadot frame->oui = HDMI_IEEE_OUI; 502*f1d7ae31SEmmanuel Vadot 503*f1d7ae31SEmmanuel Vadot /* 504*f1d7ae31SEmmanuel Vadot * 0 is a valid value for s3d_struct, so we use a special "not set" 505*f1d7ae31SEmmanuel Vadot * value 506*f1d7ae31SEmmanuel Vadot */ 507*f1d7ae31SEmmanuel Vadot frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID; 508*f1d7ae31SEmmanuel Vadot frame->length = HDMI_VENDOR_INFOFRAME_SIZE; 509*f1d7ae31SEmmanuel Vadot 510*f1d7ae31SEmmanuel Vadot return 0; 511*f1d7ae31SEmmanuel Vadot } 512*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_vendor_infoframe_init); 513*f1d7ae31SEmmanuel Vadot 514*f1d7ae31SEmmanuel Vadot static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *frame) 515*f1d7ae31SEmmanuel Vadot { 516*f1d7ae31SEmmanuel Vadot /* for side by side (half) we also need to provide 3D_Ext_Data */ 517*f1d7ae31SEmmanuel Vadot if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) 518*f1d7ae31SEmmanuel Vadot return 6; 519*f1d7ae31SEmmanuel Vadot else if (frame->vic != 0 || frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) 520*f1d7ae31SEmmanuel Vadot return 5; 521*f1d7ae31SEmmanuel Vadot else 522*f1d7ae31SEmmanuel Vadot return 4; 523*f1d7ae31SEmmanuel Vadot } 524*f1d7ae31SEmmanuel Vadot 525*f1d7ae31SEmmanuel Vadot static int hdmi_vendor_infoframe_check_only(const struct hdmi_vendor_infoframe *frame) 526*f1d7ae31SEmmanuel Vadot { 527*f1d7ae31SEmmanuel Vadot if (frame->type != HDMI_INFOFRAME_TYPE_VENDOR || 528*f1d7ae31SEmmanuel Vadot frame->version != 1 || 529*f1d7ae31SEmmanuel Vadot frame->oui != HDMI_IEEE_OUI) 530*f1d7ae31SEmmanuel Vadot return -EINVAL; 531*f1d7ae31SEmmanuel Vadot 532*f1d7ae31SEmmanuel Vadot /* only one of those can be supplied */ 533*f1d7ae31SEmmanuel Vadot if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) 534*f1d7ae31SEmmanuel Vadot return -EINVAL; 535*f1d7ae31SEmmanuel Vadot 536*f1d7ae31SEmmanuel Vadot if (frame->length != hdmi_vendor_infoframe_length(frame)) 537*f1d7ae31SEmmanuel Vadot return -EINVAL; 538*f1d7ae31SEmmanuel Vadot 539*f1d7ae31SEmmanuel Vadot return 0; 540*f1d7ae31SEmmanuel Vadot } 541*f1d7ae31SEmmanuel Vadot 542*f1d7ae31SEmmanuel Vadot /** 543*f1d7ae31SEmmanuel Vadot * hdmi_vendor_infoframe_check() - check a HDMI vendor infoframe 544*f1d7ae31SEmmanuel Vadot * @frame: HDMI infoframe 545*f1d7ae31SEmmanuel Vadot * 546*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 547*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields. 548*f1d7ae31SEmmanuel Vadot * 549*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 550*f1d7ae31SEmmanuel Vadot */ 551*f1d7ae31SEmmanuel Vadot int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame) 552*f1d7ae31SEmmanuel Vadot { 553*f1d7ae31SEmmanuel Vadot frame->length = hdmi_vendor_infoframe_length(frame); 554*f1d7ae31SEmmanuel Vadot 555*f1d7ae31SEmmanuel Vadot return hdmi_vendor_infoframe_check_only(frame); 556*f1d7ae31SEmmanuel Vadot } 557*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_vendor_infoframe_check); 558*f1d7ae31SEmmanuel Vadot 559*f1d7ae31SEmmanuel Vadot /** 560*f1d7ae31SEmmanuel Vadot * hdmi_vendor_infoframe_pack_only() - write a HDMI vendor infoframe to binary buffer 561*f1d7ae31SEmmanuel Vadot * @frame: HDMI infoframe 562*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 563*f1d7ae31SEmmanuel Vadot * @size: size of buffer 564*f1d7ae31SEmmanuel Vadot * 565*f1d7ae31SEmmanuel Vadot * Packs the information contained in the @frame structure into a binary 566*f1d7ae31SEmmanuel Vadot * representation that can be written into the corresponding controller 567*f1d7ae31SEmmanuel Vadot * registers. Also computes the checksum as required by section 5.3.5 of 568*f1d7ae31SEmmanuel Vadot * the HDMI 1.4 specification. 569*f1d7ae31SEmmanuel Vadot * 570*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 571*f1d7ae31SEmmanuel Vadot * error code on failure. 572*f1d7ae31SEmmanuel Vadot */ 573*f1d7ae31SEmmanuel Vadot ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame, 574*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 575*f1d7ae31SEmmanuel Vadot { 576*f1d7ae31SEmmanuel Vadot u8 *ptr = buffer; 577*f1d7ae31SEmmanuel Vadot size_t length; 578*f1d7ae31SEmmanuel Vadot int ret; 579*f1d7ae31SEmmanuel Vadot 580*f1d7ae31SEmmanuel Vadot ret = hdmi_vendor_infoframe_check_only(frame); 581*f1d7ae31SEmmanuel Vadot if (ret) 582*f1d7ae31SEmmanuel Vadot return ret; 583*f1d7ae31SEmmanuel Vadot 584*f1d7ae31SEmmanuel Vadot length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; 585*f1d7ae31SEmmanuel Vadot 586*f1d7ae31SEmmanuel Vadot if (size < length) 587*f1d7ae31SEmmanuel Vadot return -ENOSPC; 588*f1d7ae31SEmmanuel Vadot 589*f1d7ae31SEmmanuel Vadot memset(buffer, 0, size); 590*f1d7ae31SEmmanuel Vadot 591*f1d7ae31SEmmanuel Vadot ptr[0] = frame->type; 592*f1d7ae31SEmmanuel Vadot ptr[1] = frame->version; 593*f1d7ae31SEmmanuel Vadot ptr[2] = frame->length; 594*f1d7ae31SEmmanuel Vadot ptr[3] = 0; /* checksum */ 595*f1d7ae31SEmmanuel Vadot 596*f1d7ae31SEmmanuel Vadot /* HDMI OUI */ 597*f1d7ae31SEmmanuel Vadot ptr[4] = 0x03; 598*f1d7ae31SEmmanuel Vadot ptr[5] = 0x0c; 599*f1d7ae31SEmmanuel Vadot ptr[6] = 0x00; 600*f1d7ae31SEmmanuel Vadot 601*f1d7ae31SEmmanuel Vadot if (frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) { 602*f1d7ae31SEmmanuel Vadot ptr[7] = 0x2 << 5; /* video format */ 603*f1d7ae31SEmmanuel Vadot ptr[8] = (frame->s3d_struct & 0xf) << 4; 604*f1d7ae31SEmmanuel Vadot if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) 605*f1d7ae31SEmmanuel Vadot ptr[9] = (frame->s3d_ext_data & 0xf) << 4; 606*f1d7ae31SEmmanuel Vadot } else if (frame->vic) { 607*f1d7ae31SEmmanuel Vadot ptr[7] = 0x1 << 5; /* video format */ 608*f1d7ae31SEmmanuel Vadot ptr[8] = frame->vic; 609*f1d7ae31SEmmanuel Vadot } else { 610*f1d7ae31SEmmanuel Vadot ptr[7] = 0x0 << 5; /* video format */ 611*f1d7ae31SEmmanuel Vadot } 612*f1d7ae31SEmmanuel Vadot 613*f1d7ae31SEmmanuel Vadot hdmi_infoframe_set_checksum(buffer, length); 614*f1d7ae31SEmmanuel Vadot 615*f1d7ae31SEmmanuel Vadot return length; 616*f1d7ae31SEmmanuel Vadot } 617*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_vendor_infoframe_pack_only); 618*f1d7ae31SEmmanuel Vadot 619*f1d7ae31SEmmanuel Vadot /** 620*f1d7ae31SEmmanuel Vadot * hdmi_vendor_infoframe_pack() - check a HDMI Vendor infoframe, 621*f1d7ae31SEmmanuel Vadot * and write it to binary buffer 622*f1d7ae31SEmmanuel Vadot * @frame: HDMI Vendor infoframe 623*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 624*f1d7ae31SEmmanuel Vadot * @size: size of buffer 625*f1d7ae31SEmmanuel Vadot * 626*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 627*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields, after which it packs the information 628*f1d7ae31SEmmanuel Vadot * contained in the @frame structure into a binary representation that 629*f1d7ae31SEmmanuel Vadot * can be written into the corresponding controller registers. This function 630*f1d7ae31SEmmanuel Vadot * also computes the checksum as required by section 5.3.5 of the HDMI 1.4 631*f1d7ae31SEmmanuel Vadot * specification. 632*f1d7ae31SEmmanuel Vadot * 633*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 634*f1d7ae31SEmmanuel Vadot * error code on failure. 635*f1d7ae31SEmmanuel Vadot */ 636*f1d7ae31SEmmanuel Vadot ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, 637*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 638*f1d7ae31SEmmanuel Vadot { 639*f1d7ae31SEmmanuel Vadot int ret; 640*f1d7ae31SEmmanuel Vadot 641*f1d7ae31SEmmanuel Vadot ret = hdmi_vendor_infoframe_check(frame); 642*f1d7ae31SEmmanuel Vadot if (ret) 643*f1d7ae31SEmmanuel Vadot return ret; 644*f1d7ae31SEmmanuel Vadot 645*f1d7ae31SEmmanuel Vadot return hdmi_vendor_infoframe_pack_only(frame, buffer, size); 646*f1d7ae31SEmmanuel Vadot } 647*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_vendor_infoframe_pack); 648*f1d7ae31SEmmanuel Vadot 649*f1d7ae31SEmmanuel Vadot static int 650*f1d7ae31SEmmanuel Vadot hdmi_vendor_any_infoframe_check_only(const union hdmi_vendor_any_infoframe *frame) 651*f1d7ae31SEmmanuel Vadot { 652*f1d7ae31SEmmanuel Vadot if (frame->any.type != HDMI_INFOFRAME_TYPE_VENDOR || 653*f1d7ae31SEmmanuel Vadot frame->any.version != 1) 654*f1d7ae31SEmmanuel Vadot return -EINVAL; 655*f1d7ae31SEmmanuel Vadot 656*f1d7ae31SEmmanuel Vadot return 0; 657*f1d7ae31SEmmanuel Vadot } 658*f1d7ae31SEmmanuel Vadot 659*f1d7ae31SEmmanuel Vadot /** 660*f1d7ae31SEmmanuel Vadot * hdmi_drm_infoframe_init() - initialize an HDMI Dynaminc Range and 661*f1d7ae31SEmmanuel Vadot * mastering infoframe 662*f1d7ae31SEmmanuel Vadot * @frame: HDMI DRM infoframe 663*f1d7ae31SEmmanuel Vadot * 664*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 665*f1d7ae31SEmmanuel Vadot */ 666*f1d7ae31SEmmanuel Vadot int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame) 667*f1d7ae31SEmmanuel Vadot { 668*f1d7ae31SEmmanuel Vadot memset(frame, 0, sizeof(*frame)); 669*f1d7ae31SEmmanuel Vadot 670*f1d7ae31SEmmanuel Vadot frame->type = HDMI_INFOFRAME_TYPE_DRM; 671*f1d7ae31SEmmanuel Vadot frame->version = 1; 672*f1d7ae31SEmmanuel Vadot frame->length = HDMI_DRM_INFOFRAME_SIZE; 673*f1d7ae31SEmmanuel Vadot 674*f1d7ae31SEmmanuel Vadot return 0; 675*f1d7ae31SEmmanuel Vadot } 676*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_drm_infoframe_init); 677*f1d7ae31SEmmanuel Vadot 678*f1d7ae31SEmmanuel Vadot static int hdmi_drm_infoframe_check_only(const struct hdmi_drm_infoframe *frame) 679*f1d7ae31SEmmanuel Vadot { 680*f1d7ae31SEmmanuel Vadot if (frame->type != HDMI_INFOFRAME_TYPE_DRM || 681*f1d7ae31SEmmanuel Vadot frame->version != 1) 682*f1d7ae31SEmmanuel Vadot return -EINVAL; 683*f1d7ae31SEmmanuel Vadot 684*f1d7ae31SEmmanuel Vadot if (frame->length != HDMI_DRM_INFOFRAME_SIZE) 685*f1d7ae31SEmmanuel Vadot return -EINVAL; 686*f1d7ae31SEmmanuel Vadot 687*f1d7ae31SEmmanuel Vadot return 0; 688*f1d7ae31SEmmanuel Vadot } 689*f1d7ae31SEmmanuel Vadot 690*f1d7ae31SEmmanuel Vadot /** 691*f1d7ae31SEmmanuel Vadot * hdmi_drm_infoframe_check() - check a HDMI DRM infoframe 692*f1d7ae31SEmmanuel Vadot * @frame: HDMI DRM infoframe 693*f1d7ae31SEmmanuel Vadot * 694*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent. 695*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 696*f1d7ae31SEmmanuel Vadot */ 697*f1d7ae31SEmmanuel Vadot int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame) 698*f1d7ae31SEmmanuel Vadot { 699*f1d7ae31SEmmanuel Vadot return hdmi_drm_infoframe_check_only(frame); 700*f1d7ae31SEmmanuel Vadot } 701*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_drm_infoframe_check); 702*f1d7ae31SEmmanuel Vadot 703*f1d7ae31SEmmanuel Vadot /** 704*f1d7ae31SEmmanuel Vadot * hdmi_drm_infoframe_pack_only() - write HDMI DRM infoframe to binary buffer 705*f1d7ae31SEmmanuel Vadot * @frame: HDMI DRM infoframe 706*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 707*f1d7ae31SEmmanuel Vadot * @size: size of buffer 708*f1d7ae31SEmmanuel Vadot * 709*f1d7ae31SEmmanuel Vadot * Packs the information contained in the @frame structure into a binary 710*f1d7ae31SEmmanuel Vadot * representation that can be written into the corresponding controller 711*f1d7ae31SEmmanuel Vadot * registers. Also computes the checksum as required by section 5.3.5 of 712*f1d7ae31SEmmanuel Vadot * the HDMI 1.4 specification. 713*f1d7ae31SEmmanuel Vadot * 714*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 715*f1d7ae31SEmmanuel Vadot * error code on failure. 716*f1d7ae31SEmmanuel Vadot */ 717*f1d7ae31SEmmanuel Vadot ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame, 718*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 719*f1d7ae31SEmmanuel Vadot { 720*f1d7ae31SEmmanuel Vadot u8 *ptr = buffer; 721*f1d7ae31SEmmanuel Vadot size_t length; 722*f1d7ae31SEmmanuel Vadot int i; 723*f1d7ae31SEmmanuel Vadot 724*f1d7ae31SEmmanuel Vadot length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; 725*f1d7ae31SEmmanuel Vadot 726*f1d7ae31SEmmanuel Vadot if (size < length) 727*f1d7ae31SEmmanuel Vadot return -ENOSPC; 728*f1d7ae31SEmmanuel Vadot 729*f1d7ae31SEmmanuel Vadot memset(buffer, 0, size); 730*f1d7ae31SEmmanuel Vadot 731*f1d7ae31SEmmanuel Vadot ptr[0] = frame->type; 732*f1d7ae31SEmmanuel Vadot ptr[1] = frame->version; 733*f1d7ae31SEmmanuel Vadot ptr[2] = frame->length; 734*f1d7ae31SEmmanuel Vadot ptr[3] = 0; /* checksum */ 735*f1d7ae31SEmmanuel Vadot 736*f1d7ae31SEmmanuel Vadot /* start infoframe payload */ 737*f1d7ae31SEmmanuel Vadot ptr += HDMI_INFOFRAME_HEADER_SIZE; 738*f1d7ae31SEmmanuel Vadot 739*f1d7ae31SEmmanuel Vadot *ptr++ = frame->eotf; 740*f1d7ae31SEmmanuel Vadot *ptr++ = frame->metadata_type; 741*f1d7ae31SEmmanuel Vadot 742*f1d7ae31SEmmanuel Vadot for (i = 0; i < 3; i++) { 743*f1d7ae31SEmmanuel Vadot *ptr++ = frame->display_primaries[i].x; 744*f1d7ae31SEmmanuel Vadot *ptr++ = frame->display_primaries[i].x >> 8; 745*f1d7ae31SEmmanuel Vadot *ptr++ = frame->display_primaries[i].y; 746*f1d7ae31SEmmanuel Vadot *ptr++ = frame->display_primaries[i].y >> 8; 747*f1d7ae31SEmmanuel Vadot } 748*f1d7ae31SEmmanuel Vadot 749*f1d7ae31SEmmanuel Vadot *ptr++ = frame->white_point.x; 750*f1d7ae31SEmmanuel Vadot *ptr++ = frame->white_point.x >> 8; 751*f1d7ae31SEmmanuel Vadot 752*f1d7ae31SEmmanuel Vadot *ptr++ = frame->white_point.y; 753*f1d7ae31SEmmanuel Vadot *ptr++ = frame->white_point.y >> 8; 754*f1d7ae31SEmmanuel Vadot 755*f1d7ae31SEmmanuel Vadot *ptr++ = frame->max_display_mastering_luminance; 756*f1d7ae31SEmmanuel Vadot *ptr++ = frame->max_display_mastering_luminance >> 8; 757*f1d7ae31SEmmanuel Vadot 758*f1d7ae31SEmmanuel Vadot *ptr++ = frame->min_display_mastering_luminance; 759*f1d7ae31SEmmanuel Vadot *ptr++ = frame->min_display_mastering_luminance >> 8; 760*f1d7ae31SEmmanuel Vadot 761*f1d7ae31SEmmanuel Vadot *ptr++ = frame->max_cll; 762*f1d7ae31SEmmanuel Vadot *ptr++ = frame->max_cll >> 8; 763*f1d7ae31SEmmanuel Vadot 764*f1d7ae31SEmmanuel Vadot *ptr++ = frame->max_fall; 765*f1d7ae31SEmmanuel Vadot *ptr++ = frame->max_fall >> 8; 766*f1d7ae31SEmmanuel Vadot 767*f1d7ae31SEmmanuel Vadot hdmi_infoframe_set_checksum(buffer, length); 768*f1d7ae31SEmmanuel Vadot 769*f1d7ae31SEmmanuel Vadot return length; 770*f1d7ae31SEmmanuel Vadot } 771*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_drm_infoframe_pack_only); 772*f1d7ae31SEmmanuel Vadot 773*f1d7ae31SEmmanuel Vadot /** 774*f1d7ae31SEmmanuel Vadot * hdmi_drm_infoframe_pack() - check a HDMI DRM infoframe, 775*f1d7ae31SEmmanuel Vadot * and write it to binary buffer 776*f1d7ae31SEmmanuel Vadot * @frame: HDMI DRM infoframe 777*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 778*f1d7ae31SEmmanuel Vadot * @size: size of buffer 779*f1d7ae31SEmmanuel Vadot * 780*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 781*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields, after which it packs the information 782*f1d7ae31SEmmanuel Vadot * contained in the @frame structure into a binary representation that 783*f1d7ae31SEmmanuel Vadot * can be written into the corresponding controller registers. This function 784*f1d7ae31SEmmanuel Vadot * also computes the checksum as required by section 5.3.5 of the HDMI 1.4 785*f1d7ae31SEmmanuel Vadot * specification. 786*f1d7ae31SEmmanuel Vadot * 787*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 788*f1d7ae31SEmmanuel Vadot * error code on failure. 789*f1d7ae31SEmmanuel Vadot */ 790*f1d7ae31SEmmanuel Vadot ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, 791*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 792*f1d7ae31SEmmanuel Vadot { 793*f1d7ae31SEmmanuel Vadot int ret; 794*f1d7ae31SEmmanuel Vadot 795*f1d7ae31SEmmanuel Vadot ret = hdmi_drm_infoframe_check(frame); 796*f1d7ae31SEmmanuel Vadot if (ret) 797*f1d7ae31SEmmanuel Vadot return ret; 798*f1d7ae31SEmmanuel Vadot 799*f1d7ae31SEmmanuel Vadot return hdmi_drm_infoframe_pack_only(frame, buffer, size); 800*f1d7ae31SEmmanuel Vadot } 801*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_drm_infoframe_pack); 802*f1d7ae31SEmmanuel Vadot 803*f1d7ae31SEmmanuel Vadot /* 804*f1d7ae31SEmmanuel Vadot * hdmi_vendor_any_infoframe_check() - check a vendor infoframe 805*f1d7ae31SEmmanuel Vadot */ 806*f1d7ae31SEmmanuel Vadot static int 807*f1d7ae31SEmmanuel Vadot hdmi_vendor_any_infoframe_check(union hdmi_vendor_any_infoframe *frame) 808*f1d7ae31SEmmanuel Vadot { 809*f1d7ae31SEmmanuel Vadot int ret; 810*f1d7ae31SEmmanuel Vadot 811*f1d7ae31SEmmanuel Vadot ret = hdmi_vendor_any_infoframe_check_only(frame); 812*f1d7ae31SEmmanuel Vadot if (ret) 813*f1d7ae31SEmmanuel Vadot return ret; 814*f1d7ae31SEmmanuel Vadot 815*f1d7ae31SEmmanuel Vadot /* we only know about HDMI vendor infoframes */ 816*f1d7ae31SEmmanuel Vadot if (frame->any.oui != HDMI_IEEE_OUI) 817*f1d7ae31SEmmanuel Vadot return -EINVAL; 818*f1d7ae31SEmmanuel Vadot 819*f1d7ae31SEmmanuel Vadot return hdmi_vendor_infoframe_check(&frame->hdmi); 820*f1d7ae31SEmmanuel Vadot } 821*f1d7ae31SEmmanuel Vadot 822*f1d7ae31SEmmanuel Vadot /* 823*f1d7ae31SEmmanuel Vadot * hdmi_vendor_any_infoframe_pack_only() - write a vendor infoframe to binary buffer 824*f1d7ae31SEmmanuel Vadot */ 825*f1d7ae31SEmmanuel Vadot static ssize_t 826*f1d7ae31SEmmanuel Vadot hdmi_vendor_any_infoframe_pack_only(const union hdmi_vendor_any_infoframe *frame, 827*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 828*f1d7ae31SEmmanuel Vadot { 829*f1d7ae31SEmmanuel Vadot int ret; 830*f1d7ae31SEmmanuel Vadot 831*f1d7ae31SEmmanuel Vadot ret = hdmi_vendor_any_infoframe_check_only(frame); 832*f1d7ae31SEmmanuel Vadot if (ret) 833*f1d7ae31SEmmanuel Vadot return ret; 834*f1d7ae31SEmmanuel Vadot 835*f1d7ae31SEmmanuel Vadot /* we only know about HDMI vendor infoframes */ 836*f1d7ae31SEmmanuel Vadot if (frame->any.oui != HDMI_IEEE_OUI) 837*f1d7ae31SEmmanuel Vadot return -EINVAL; 838*f1d7ae31SEmmanuel Vadot 839*f1d7ae31SEmmanuel Vadot return hdmi_vendor_infoframe_pack_only(&frame->hdmi, buffer, size); 840*f1d7ae31SEmmanuel Vadot } 841*f1d7ae31SEmmanuel Vadot 842*f1d7ae31SEmmanuel Vadot /* 843*f1d7ae31SEmmanuel Vadot * hdmi_vendor_any_infoframe_pack() - check a vendor infoframe, 844*f1d7ae31SEmmanuel Vadot * and write it to binary buffer 845*f1d7ae31SEmmanuel Vadot */ 846*f1d7ae31SEmmanuel Vadot static ssize_t 847*f1d7ae31SEmmanuel Vadot hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame, 848*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 849*f1d7ae31SEmmanuel Vadot { 850*f1d7ae31SEmmanuel Vadot int ret; 851*f1d7ae31SEmmanuel Vadot 852*f1d7ae31SEmmanuel Vadot ret = hdmi_vendor_any_infoframe_check(frame); 853*f1d7ae31SEmmanuel Vadot if (ret) 854*f1d7ae31SEmmanuel Vadot return ret; 855*f1d7ae31SEmmanuel Vadot 856*f1d7ae31SEmmanuel Vadot return hdmi_vendor_any_infoframe_pack_only(frame, buffer, size); 857*f1d7ae31SEmmanuel Vadot } 858*f1d7ae31SEmmanuel Vadot 859*f1d7ae31SEmmanuel Vadot /** 860*f1d7ae31SEmmanuel Vadot * hdmi_infoframe_check() - check a HDMI infoframe 861*f1d7ae31SEmmanuel Vadot * @frame: HDMI infoframe 862*f1d7ae31SEmmanuel Vadot * 863*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 864*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields. 865*f1d7ae31SEmmanuel Vadot * 866*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 867*f1d7ae31SEmmanuel Vadot */ 868*f1d7ae31SEmmanuel Vadot int 869*f1d7ae31SEmmanuel Vadot hdmi_infoframe_check(union hdmi_infoframe *frame) 870*f1d7ae31SEmmanuel Vadot { 871*f1d7ae31SEmmanuel Vadot switch (frame->any.type) { 872*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AVI: 873*f1d7ae31SEmmanuel Vadot return hdmi_avi_infoframe_check(&frame->avi); 874*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_SPD: 875*f1d7ae31SEmmanuel Vadot return hdmi_spd_infoframe_check(&frame->spd); 876*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AUDIO: 877*f1d7ae31SEmmanuel Vadot return hdmi_audio_infoframe_check(&frame->audio); 878*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_VENDOR: 879*f1d7ae31SEmmanuel Vadot return hdmi_vendor_any_infoframe_check(&frame->vendor); 880*f1d7ae31SEmmanuel Vadot default: 881*f1d7ae31SEmmanuel Vadot WARN(1, "Bad infoframe type %d\n", frame->any.type); 882*f1d7ae31SEmmanuel Vadot return -EINVAL; 883*f1d7ae31SEmmanuel Vadot } 884*f1d7ae31SEmmanuel Vadot } 885*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_infoframe_check); 886*f1d7ae31SEmmanuel Vadot 887*f1d7ae31SEmmanuel Vadot /** 888*f1d7ae31SEmmanuel Vadot * hdmi_infoframe_pack_only() - write a HDMI infoframe to binary buffer 889*f1d7ae31SEmmanuel Vadot * @frame: HDMI infoframe 890*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 891*f1d7ae31SEmmanuel Vadot * @size: size of buffer 892*f1d7ae31SEmmanuel Vadot * 893*f1d7ae31SEmmanuel Vadot * Packs the information contained in the @frame structure into a binary 894*f1d7ae31SEmmanuel Vadot * representation that can be written into the corresponding controller 895*f1d7ae31SEmmanuel Vadot * registers. Also computes the checksum as required by section 5.3.5 of 896*f1d7ae31SEmmanuel Vadot * the HDMI 1.4 specification. 897*f1d7ae31SEmmanuel Vadot * 898*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 899*f1d7ae31SEmmanuel Vadot * error code on failure. 900*f1d7ae31SEmmanuel Vadot */ 901*f1d7ae31SEmmanuel Vadot ssize_t 902*f1d7ae31SEmmanuel Vadot hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t size) 903*f1d7ae31SEmmanuel Vadot { 904*f1d7ae31SEmmanuel Vadot ssize_t length; 905*f1d7ae31SEmmanuel Vadot 906*f1d7ae31SEmmanuel Vadot switch (frame->any.type) { 907*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AVI: 908*f1d7ae31SEmmanuel Vadot length = hdmi_avi_infoframe_pack_only(&frame->avi, 909*f1d7ae31SEmmanuel Vadot buffer, size); 910*f1d7ae31SEmmanuel Vadot break; 911*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_DRM: 912*f1d7ae31SEmmanuel Vadot length = hdmi_drm_infoframe_pack_only(&frame->drm, 913*f1d7ae31SEmmanuel Vadot buffer, size); 914*f1d7ae31SEmmanuel Vadot break; 915*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_SPD: 916*f1d7ae31SEmmanuel Vadot length = hdmi_spd_infoframe_pack_only(&frame->spd, 917*f1d7ae31SEmmanuel Vadot buffer, size); 918*f1d7ae31SEmmanuel Vadot break; 919*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AUDIO: 920*f1d7ae31SEmmanuel Vadot length = hdmi_audio_infoframe_pack_only(&frame->audio, 921*f1d7ae31SEmmanuel Vadot buffer, size); 922*f1d7ae31SEmmanuel Vadot break; 923*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_VENDOR: 924*f1d7ae31SEmmanuel Vadot length = hdmi_vendor_any_infoframe_pack_only(&frame->vendor, 925*f1d7ae31SEmmanuel Vadot buffer, size); 926*f1d7ae31SEmmanuel Vadot break; 927*f1d7ae31SEmmanuel Vadot default: 928*f1d7ae31SEmmanuel Vadot WARN(1, "Bad infoframe type %d\n", frame->any.type); 929*f1d7ae31SEmmanuel Vadot length = -EINVAL; 930*f1d7ae31SEmmanuel Vadot } 931*f1d7ae31SEmmanuel Vadot 932*f1d7ae31SEmmanuel Vadot return length; 933*f1d7ae31SEmmanuel Vadot } 934*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_infoframe_pack_only); 935*f1d7ae31SEmmanuel Vadot 936*f1d7ae31SEmmanuel Vadot /** 937*f1d7ae31SEmmanuel Vadot * hdmi_infoframe_pack() - check a HDMI infoframe, 938*f1d7ae31SEmmanuel Vadot * and write it to binary buffer 939*f1d7ae31SEmmanuel Vadot * @frame: HDMI infoframe 940*f1d7ae31SEmmanuel Vadot * @buffer: destination buffer 941*f1d7ae31SEmmanuel Vadot * @size: size of buffer 942*f1d7ae31SEmmanuel Vadot * 943*f1d7ae31SEmmanuel Vadot * Validates that the infoframe is consistent and updates derived fields 944*f1d7ae31SEmmanuel Vadot * (eg. length) based on other fields, after which it packs the information 945*f1d7ae31SEmmanuel Vadot * contained in the @frame structure into a binary representation that 946*f1d7ae31SEmmanuel Vadot * can be written into the corresponding controller registers. This function 947*f1d7ae31SEmmanuel Vadot * also computes the checksum as required by section 5.3.5 of the HDMI 1.4 948*f1d7ae31SEmmanuel Vadot * specification. 949*f1d7ae31SEmmanuel Vadot * 950*f1d7ae31SEmmanuel Vadot * Returns the number of bytes packed into the binary buffer or a negative 951*f1d7ae31SEmmanuel Vadot * error code on failure. 952*f1d7ae31SEmmanuel Vadot */ 953*f1d7ae31SEmmanuel Vadot ssize_t 954*f1d7ae31SEmmanuel Vadot hdmi_infoframe_pack(union hdmi_infoframe *frame, 955*f1d7ae31SEmmanuel Vadot void *buffer, size_t size) 956*f1d7ae31SEmmanuel Vadot { 957*f1d7ae31SEmmanuel Vadot ssize_t length; 958*f1d7ae31SEmmanuel Vadot 959*f1d7ae31SEmmanuel Vadot switch (frame->any.type) { 960*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AVI: 961*f1d7ae31SEmmanuel Vadot length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size); 962*f1d7ae31SEmmanuel Vadot break; 963*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_DRM: 964*f1d7ae31SEmmanuel Vadot length = hdmi_drm_infoframe_pack(&frame->drm, buffer, size); 965*f1d7ae31SEmmanuel Vadot break; 966*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_SPD: 967*f1d7ae31SEmmanuel Vadot length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size); 968*f1d7ae31SEmmanuel Vadot break; 969*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AUDIO: 970*f1d7ae31SEmmanuel Vadot length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size); 971*f1d7ae31SEmmanuel Vadot break; 972*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_VENDOR: 973*f1d7ae31SEmmanuel Vadot length = hdmi_vendor_any_infoframe_pack(&frame->vendor, 974*f1d7ae31SEmmanuel Vadot buffer, size); 975*f1d7ae31SEmmanuel Vadot break; 976*f1d7ae31SEmmanuel Vadot default: 977*f1d7ae31SEmmanuel Vadot WARN(1, "Bad infoframe type %d\n", frame->any.type); 978*f1d7ae31SEmmanuel Vadot length = -EINVAL; 979*f1d7ae31SEmmanuel Vadot } 980*f1d7ae31SEmmanuel Vadot 981*f1d7ae31SEmmanuel Vadot return length; 982*f1d7ae31SEmmanuel Vadot } 983*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_infoframe_pack); 984*f1d7ae31SEmmanuel Vadot 985*f1d7ae31SEmmanuel Vadot static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type) 986*f1d7ae31SEmmanuel Vadot { 987*f1d7ae31SEmmanuel Vadot if (type < 0x80 || type > 0x9f) 988*f1d7ae31SEmmanuel Vadot return "Invalid"; 989*f1d7ae31SEmmanuel Vadot switch (type) { 990*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_VENDOR: 991*f1d7ae31SEmmanuel Vadot return "Vendor"; 992*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AVI: 993*f1d7ae31SEmmanuel Vadot return "Auxiliary Video Information (AVI)"; 994*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_SPD: 995*f1d7ae31SEmmanuel Vadot return "Source Product Description (SPD)"; 996*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AUDIO: 997*f1d7ae31SEmmanuel Vadot return "Audio"; 998*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_DRM: 999*f1d7ae31SEmmanuel Vadot return "Dynamic Range and Mastering"; 1000*f1d7ae31SEmmanuel Vadot } 1001*f1d7ae31SEmmanuel Vadot return "Reserved"; 1002*f1d7ae31SEmmanuel Vadot } 1003*f1d7ae31SEmmanuel Vadot 1004*f1d7ae31SEmmanuel Vadot static void hdmi_infoframe_log_header(const char *level, 1005*f1d7ae31SEmmanuel Vadot struct device *dev, 1006*f1d7ae31SEmmanuel Vadot const struct hdmi_any_infoframe *frame) 1007*f1d7ae31SEmmanuel Vadot { 1008*f1d7ae31SEmmanuel Vadot hdmi_log("HDMI infoframe: %s, version %u, length %u\n", 1009*f1d7ae31SEmmanuel Vadot hdmi_infoframe_type_get_name(frame->type), 1010*f1d7ae31SEmmanuel Vadot frame->version, frame->length); 1011*f1d7ae31SEmmanuel Vadot } 1012*f1d7ae31SEmmanuel Vadot 1013*f1d7ae31SEmmanuel Vadot static const char *hdmi_colorspace_get_name(enum hdmi_colorspace colorspace) 1014*f1d7ae31SEmmanuel Vadot { 1015*f1d7ae31SEmmanuel Vadot switch (colorspace) { 1016*f1d7ae31SEmmanuel Vadot case HDMI_COLORSPACE_RGB: 1017*f1d7ae31SEmmanuel Vadot return "RGB"; 1018*f1d7ae31SEmmanuel Vadot case HDMI_COLORSPACE_YUV422: 1019*f1d7ae31SEmmanuel Vadot return "YCbCr 4:2:2"; 1020*f1d7ae31SEmmanuel Vadot case HDMI_COLORSPACE_YUV444: 1021*f1d7ae31SEmmanuel Vadot return "YCbCr 4:4:4"; 1022*f1d7ae31SEmmanuel Vadot case HDMI_COLORSPACE_YUV420: 1023*f1d7ae31SEmmanuel Vadot return "YCbCr 4:2:0"; 1024*f1d7ae31SEmmanuel Vadot case HDMI_COLORSPACE_RESERVED4: 1025*f1d7ae31SEmmanuel Vadot return "Reserved (4)"; 1026*f1d7ae31SEmmanuel Vadot case HDMI_COLORSPACE_RESERVED5: 1027*f1d7ae31SEmmanuel Vadot return "Reserved (5)"; 1028*f1d7ae31SEmmanuel Vadot case HDMI_COLORSPACE_RESERVED6: 1029*f1d7ae31SEmmanuel Vadot return "Reserved (6)"; 1030*f1d7ae31SEmmanuel Vadot case HDMI_COLORSPACE_IDO_DEFINED: 1031*f1d7ae31SEmmanuel Vadot return "IDO Defined"; 1032*f1d7ae31SEmmanuel Vadot } 1033*f1d7ae31SEmmanuel Vadot return "Invalid"; 1034*f1d7ae31SEmmanuel Vadot } 1035*f1d7ae31SEmmanuel Vadot 1036*f1d7ae31SEmmanuel Vadot static const char *hdmi_scan_mode_get_name(enum hdmi_scan_mode scan_mode) 1037*f1d7ae31SEmmanuel Vadot { 1038*f1d7ae31SEmmanuel Vadot switch (scan_mode) { 1039*f1d7ae31SEmmanuel Vadot case HDMI_SCAN_MODE_NONE: 1040*f1d7ae31SEmmanuel Vadot return "No Data"; 1041*f1d7ae31SEmmanuel Vadot case HDMI_SCAN_MODE_OVERSCAN: 1042*f1d7ae31SEmmanuel Vadot return "Overscan"; 1043*f1d7ae31SEmmanuel Vadot case HDMI_SCAN_MODE_UNDERSCAN: 1044*f1d7ae31SEmmanuel Vadot return "Underscan"; 1045*f1d7ae31SEmmanuel Vadot case HDMI_SCAN_MODE_RESERVED: 1046*f1d7ae31SEmmanuel Vadot return "Reserved"; 1047*f1d7ae31SEmmanuel Vadot } 1048*f1d7ae31SEmmanuel Vadot return "Invalid"; 1049*f1d7ae31SEmmanuel Vadot } 1050*f1d7ae31SEmmanuel Vadot 1051*f1d7ae31SEmmanuel Vadot static const char *hdmi_colorimetry_get_name(enum hdmi_colorimetry colorimetry) 1052*f1d7ae31SEmmanuel Vadot { 1053*f1d7ae31SEmmanuel Vadot switch (colorimetry) { 1054*f1d7ae31SEmmanuel Vadot case HDMI_COLORIMETRY_NONE: 1055*f1d7ae31SEmmanuel Vadot return "No Data"; 1056*f1d7ae31SEmmanuel Vadot case HDMI_COLORIMETRY_ITU_601: 1057*f1d7ae31SEmmanuel Vadot return "ITU601"; 1058*f1d7ae31SEmmanuel Vadot case HDMI_COLORIMETRY_ITU_709: 1059*f1d7ae31SEmmanuel Vadot return "ITU709"; 1060*f1d7ae31SEmmanuel Vadot case HDMI_COLORIMETRY_EXTENDED: 1061*f1d7ae31SEmmanuel Vadot return "Extended"; 1062*f1d7ae31SEmmanuel Vadot } 1063*f1d7ae31SEmmanuel Vadot return "Invalid"; 1064*f1d7ae31SEmmanuel Vadot } 1065*f1d7ae31SEmmanuel Vadot 1066*f1d7ae31SEmmanuel Vadot static const char * 1067*f1d7ae31SEmmanuel Vadot hdmi_picture_aspect_get_name(enum hdmi_picture_aspect picture_aspect) 1068*f1d7ae31SEmmanuel Vadot { 1069*f1d7ae31SEmmanuel Vadot switch (picture_aspect) { 1070*f1d7ae31SEmmanuel Vadot case HDMI_PICTURE_ASPECT_NONE: 1071*f1d7ae31SEmmanuel Vadot return "No Data"; 1072*f1d7ae31SEmmanuel Vadot case HDMI_PICTURE_ASPECT_4_3: 1073*f1d7ae31SEmmanuel Vadot return "4:3"; 1074*f1d7ae31SEmmanuel Vadot case HDMI_PICTURE_ASPECT_16_9: 1075*f1d7ae31SEmmanuel Vadot return "16:9"; 1076*f1d7ae31SEmmanuel Vadot case HDMI_PICTURE_ASPECT_64_27: 1077*f1d7ae31SEmmanuel Vadot return "64:27"; 1078*f1d7ae31SEmmanuel Vadot case HDMI_PICTURE_ASPECT_256_135: 1079*f1d7ae31SEmmanuel Vadot return "256:135"; 1080*f1d7ae31SEmmanuel Vadot case HDMI_PICTURE_ASPECT_RESERVED: 1081*f1d7ae31SEmmanuel Vadot return "Reserved"; 1082*f1d7ae31SEmmanuel Vadot } 1083*f1d7ae31SEmmanuel Vadot return "Invalid"; 1084*f1d7ae31SEmmanuel Vadot } 1085*f1d7ae31SEmmanuel Vadot 1086*f1d7ae31SEmmanuel Vadot static const char * 1087*f1d7ae31SEmmanuel Vadot hdmi_active_aspect_get_name(enum hdmi_active_aspect active_aspect) 1088*f1d7ae31SEmmanuel Vadot { 1089*f1d7ae31SEmmanuel Vadot if (active_aspect < 0 || active_aspect > 0xf) 1090*f1d7ae31SEmmanuel Vadot return "Invalid"; 1091*f1d7ae31SEmmanuel Vadot 1092*f1d7ae31SEmmanuel Vadot switch (active_aspect) { 1093*f1d7ae31SEmmanuel Vadot case HDMI_ACTIVE_ASPECT_16_9_TOP: 1094*f1d7ae31SEmmanuel Vadot return "16:9 Top"; 1095*f1d7ae31SEmmanuel Vadot case HDMI_ACTIVE_ASPECT_14_9_TOP: 1096*f1d7ae31SEmmanuel Vadot return "14:9 Top"; 1097*f1d7ae31SEmmanuel Vadot case HDMI_ACTIVE_ASPECT_16_9_CENTER: 1098*f1d7ae31SEmmanuel Vadot return "16:9 Center"; 1099*f1d7ae31SEmmanuel Vadot case HDMI_ACTIVE_ASPECT_PICTURE: 1100*f1d7ae31SEmmanuel Vadot return "Same as Picture"; 1101*f1d7ae31SEmmanuel Vadot case HDMI_ACTIVE_ASPECT_4_3: 1102*f1d7ae31SEmmanuel Vadot return "4:3"; 1103*f1d7ae31SEmmanuel Vadot case HDMI_ACTIVE_ASPECT_16_9: 1104*f1d7ae31SEmmanuel Vadot return "16:9"; 1105*f1d7ae31SEmmanuel Vadot case HDMI_ACTIVE_ASPECT_14_9: 1106*f1d7ae31SEmmanuel Vadot return "14:9"; 1107*f1d7ae31SEmmanuel Vadot case HDMI_ACTIVE_ASPECT_4_3_SP_14_9: 1108*f1d7ae31SEmmanuel Vadot return "4:3 SP 14:9"; 1109*f1d7ae31SEmmanuel Vadot case HDMI_ACTIVE_ASPECT_16_9_SP_14_9: 1110*f1d7ae31SEmmanuel Vadot return "16:9 SP 14:9"; 1111*f1d7ae31SEmmanuel Vadot case HDMI_ACTIVE_ASPECT_16_9_SP_4_3: 1112*f1d7ae31SEmmanuel Vadot return "16:9 SP 4:3"; 1113*f1d7ae31SEmmanuel Vadot } 1114*f1d7ae31SEmmanuel Vadot return "Reserved"; 1115*f1d7ae31SEmmanuel Vadot } 1116*f1d7ae31SEmmanuel Vadot 1117*f1d7ae31SEmmanuel Vadot static const char * 1118*f1d7ae31SEmmanuel Vadot hdmi_extended_colorimetry_get_name(enum hdmi_extended_colorimetry ext_col) 1119*f1d7ae31SEmmanuel Vadot { 1120*f1d7ae31SEmmanuel Vadot switch (ext_col) { 1121*f1d7ae31SEmmanuel Vadot case HDMI_EXTENDED_COLORIMETRY_XV_YCC_601: 1122*f1d7ae31SEmmanuel Vadot return "xvYCC 601"; 1123*f1d7ae31SEmmanuel Vadot case HDMI_EXTENDED_COLORIMETRY_XV_YCC_709: 1124*f1d7ae31SEmmanuel Vadot return "xvYCC 709"; 1125*f1d7ae31SEmmanuel Vadot case HDMI_EXTENDED_COLORIMETRY_S_YCC_601: 1126*f1d7ae31SEmmanuel Vadot return "sYCC 601"; 1127*f1d7ae31SEmmanuel Vadot case HDMI_EXTENDED_COLORIMETRY_OPYCC_601: 1128*f1d7ae31SEmmanuel Vadot return "opYCC 601"; 1129*f1d7ae31SEmmanuel Vadot case HDMI_EXTENDED_COLORIMETRY_OPRGB: 1130*f1d7ae31SEmmanuel Vadot return "opRGB"; 1131*f1d7ae31SEmmanuel Vadot case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM: 1132*f1d7ae31SEmmanuel Vadot return "BT.2020 Constant Luminance"; 1133*f1d7ae31SEmmanuel Vadot case HDMI_EXTENDED_COLORIMETRY_BT2020: 1134*f1d7ae31SEmmanuel Vadot return "BT.2020"; 1135*f1d7ae31SEmmanuel Vadot case HDMI_EXTENDED_COLORIMETRY_RESERVED: 1136*f1d7ae31SEmmanuel Vadot return "Reserved"; 1137*f1d7ae31SEmmanuel Vadot } 1138*f1d7ae31SEmmanuel Vadot return "Invalid"; 1139*f1d7ae31SEmmanuel Vadot } 1140*f1d7ae31SEmmanuel Vadot 1141*f1d7ae31SEmmanuel Vadot static const char * 1142*f1d7ae31SEmmanuel Vadot hdmi_quantization_range_get_name(enum hdmi_quantization_range qrange) 1143*f1d7ae31SEmmanuel Vadot { 1144*f1d7ae31SEmmanuel Vadot switch (qrange) { 1145*f1d7ae31SEmmanuel Vadot case HDMI_QUANTIZATION_RANGE_DEFAULT: 1146*f1d7ae31SEmmanuel Vadot return "Default"; 1147*f1d7ae31SEmmanuel Vadot case HDMI_QUANTIZATION_RANGE_LIMITED: 1148*f1d7ae31SEmmanuel Vadot return "Limited"; 1149*f1d7ae31SEmmanuel Vadot case HDMI_QUANTIZATION_RANGE_FULL: 1150*f1d7ae31SEmmanuel Vadot return "Full"; 1151*f1d7ae31SEmmanuel Vadot case HDMI_QUANTIZATION_RANGE_RESERVED: 1152*f1d7ae31SEmmanuel Vadot return "Reserved"; 1153*f1d7ae31SEmmanuel Vadot } 1154*f1d7ae31SEmmanuel Vadot return "Invalid"; 1155*f1d7ae31SEmmanuel Vadot } 1156*f1d7ae31SEmmanuel Vadot 1157*f1d7ae31SEmmanuel Vadot static const char *hdmi_nups_get_name(enum hdmi_nups nups) 1158*f1d7ae31SEmmanuel Vadot { 1159*f1d7ae31SEmmanuel Vadot switch (nups) { 1160*f1d7ae31SEmmanuel Vadot case HDMI_NUPS_UNKNOWN: 1161*f1d7ae31SEmmanuel Vadot return "Unknown Non-uniform Scaling"; 1162*f1d7ae31SEmmanuel Vadot case HDMI_NUPS_HORIZONTAL: 1163*f1d7ae31SEmmanuel Vadot return "Horizontally Scaled"; 1164*f1d7ae31SEmmanuel Vadot case HDMI_NUPS_VERTICAL: 1165*f1d7ae31SEmmanuel Vadot return "Vertically Scaled"; 1166*f1d7ae31SEmmanuel Vadot case HDMI_NUPS_BOTH: 1167*f1d7ae31SEmmanuel Vadot return "Horizontally and Vertically Scaled"; 1168*f1d7ae31SEmmanuel Vadot } 1169*f1d7ae31SEmmanuel Vadot return "Invalid"; 1170*f1d7ae31SEmmanuel Vadot } 1171*f1d7ae31SEmmanuel Vadot 1172*f1d7ae31SEmmanuel Vadot static const char * 1173*f1d7ae31SEmmanuel Vadot hdmi_ycc_quantization_range_get_name(enum hdmi_ycc_quantization_range qrange) 1174*f1d7ae31SEmmanuel Vadot { 1175*f1d7ae31SEmmanuel Vadot switch (qrange) { 1176*f1d7ae31SEmmanuel Vadot case HDMI_YCC_QUANTIZATION_RANGE_LIMITED: 1177*f1d7ae31SEmmanuel Vadot return "Limited"; 1178*f1d7ae31SEmmanuel Vadot case HDMI_YCC_QUANTIZATION_RANGE_FULL: 1179*f1d7ae31SEmmanuel Vadot return "Full"; 1180*f1d7ae31SEmmanuel Vadot } 1181*f1d7ae31SEmmanuel Vadot return "Invalid"; 1182*f1d7ae31SEmmanuel Vadot } 1183*f1d7ae31SEmmanuel Vadot 1184*f1d7ae31SEmmanuel Vadot static const char * 1185*f1d7ae31SEmmanuel Vadot hdmi_content_type_get_name(enum hdmi_content_type content_type) 1186*f1d7ae31SEmmanuel Vadot { 1187*f1d7ae31SEmmanuel Vadot switch (content_type) { 1188*f1d7ae31SEmmanuel Vadot case HDMI_CONTENT_TYPE_GRAPHICS: 1189*f1d7ae31SEmmanuel Vadot return "Graphics"; 1190*f1d7ae31SEmmanuel Vadot case HDMI_CONTENT_TYPE_PHOTO: 1191*f1d7ae31SEmmanuel Vadot return "Photo"; 1192*f1d7ae31SEmmanuel Vadot case HDMI_CONTENT_TYPE_CINEMA: 1193*f1d7ae31SEmmanuel Vadot return "Cinema"; 1194*f1d7ae31SEmmanuel Vadot case HDMI_CONTENT_TYPE_GAME: 1195*f1d7ae31SEmmanuel Vadot return "Game"; 1196*f1d7ae31SEmmanuel Vadot } 1197*f1d7ae31SEmmanuel Vadot return "Invalid"; 1198*f1d7ae31SEmmanuel Vadot } 1199*f1d7ae31SEmmanuel Vadot 1200*f1d7ae31SEmmanuel Vadot static void hdmi_avi_infoframe_log(const char *level, 1201*f1d7ae31SEmmanuel Vadot struct device *dev, 1202*f1d7ae31SEmmanuel Vadot const struct hdmi_avi_infoframe *frame) 1203*f1d7ae31SEmmanuel Vadot { 1204*f1d7ae31SEmmanuel Vadot hdmi_infoframe_log_header(level, dev, 1205*f1d7ae31SEmmanuel Vadot (const struct hdmi_any_infoframe *)frame); 1206*f1d7ae31SEmmanuel Vadot 1207*f1d7ae31SEmmanuel Vadot hdmi_log(" colorspace: %s\n", 1208*f1d7ae31SEmmanuel Vadot hdmi_colorspace_get_name(frame->colorspace)); 1209*f1d7ae31SEmmanuel Vadot hdmi_log(" scan mode: %s\n", 1210*f1d7ae31SEmmanuel Vadot hdmi_scan_mode_get_name(frame->scan_mode)); 1211*f1d7ae31SEmmanuel Vadot hdmi_log(" colorimetry: %s\n", 1212*f1d7ae31SEmmanuel Vadot hdmi_colorimetry_get_name(frame->colorimetry)); 1213*f1d7ae31SEmmanuel Vadot hdmi_log(" picture aspect: %s\n", 1214*f1d7ae31SEmmanuel Vadot hdmi_picture_aspect_get_name(frame->picture_aspect)); 1215*f1d7ae31SEmmanuel Vadot hdmi_log(" active aspect: %s\n", 1216*f1d7ae31SEmmanuel Vadot hdmi_active_aspect_get_name(frame->active_aspect)); 1217*f1d7ae31SEmmanuel Vadot hdmi_log(" itc: %s\n", frame->itc ? "IT Content" : "No Data"); 1218*f1d7ae31SEmmanuel Vadot hdmi_log(" extended colorimetry: %s\n", 1219*f1d7ae31SEmmanuel Vadot hdmi_extended_colorimetry_get_name(frame->extended_colorimetry)); 1220*f1d7ae31SEmmanuel Vadot hdmi_log(" quantization range: %s\n", 1221*f1d7ae31SEmmanuel Vadot hdmi_quantization_range_get_name(frame->quantization_range)); 1222*f1d7ae31SEmmanuel Vadot hdmi_log(" nups: %s\n", hdmi_nups_get_name(frame->nups)); 1223*f1d7ae31SEmmanuel Vadot hdmi_log(" video code: %u\n", frame->video_code); 1224*f1d7ae31SEmmanuel Vadot hdmi_log(" ycc quantization range: %s\n", 1225*f1d7ae31SEmmanuel Vadot hdmi_ycc_quantization_range_get_name(frame->ycc_quantization_range)); 1226*f1d7ae31SEmmanuel Vadot hdmi_log(" hdmi content type: %s\n", 1227*f1d7ae31SEmmanuel Vadot hdmi_content_type_get_name(frame->content_type)); 1228*f1d7ae31SEmmanuel Vadot hdmi_log(" pixel repeat: %u\n", frame->pixel_repeat); 1229*f1d7ae31SEmmanuel Vadot hdmi_log(" bar top %u, bottom %u, left %u, right %u\n", 1230*f1d7ae31SEmmanuel Vadot frame->top_bar, frame->bottom_bar, 1231*f1d7ae31SEmmanuel Vadot frame->left_bar, frame->right_bar); 1232*f1d7ae31SEmmanuel Vadot } 1233*f1d7ae31SEmmanuel Vadot 1234*f1d7ae31SEmmanuel Vadot static const char *hdmi_spd_sdi_get_name(enum hdmi_spd_sdi sdi) 1235*f1d7ae31SEmmanuel Vadot { 1236*f1d7ae31SEmmanuel Vadot if (sdi < 0 || sdi > 0xff) 1237*f1d7ae31SEmmanuel Vadot return "Invalid"; 1238*f1d7ae31SEmmanuel Vadot switch (sdi) { 1239*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_UNKNOWN: 1240*f1d7ae31SEmmanuel Vadot return "Unknown"; 1241*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_DSTB: 1242*f1d7ae31SEmmanuel Vadot return "Digital STB"; 1243*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_DVDP: 1244*f1d7ae31SEmmanuel Vadot return "DVD Player"; 1245*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_DVHS: 1246*f1d7ae31SEmmanuel Vadot return "D-VHS"; 1247*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_HDDVR: 1248*f1d7ae31SEmmanuel Vadot return "HDD Videorecorder"; 1249*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_DVC: 1250*f1d7ae31SEmmanuel Vadot return "DVC"; 1251*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_DSC: 1252*f1d7ae31SEmmanuel Vadot return "DSC"; 1253*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_VCD: 1254*f1d7ae31SEmmanuel Vadot return "Video CD"; 1255*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_GAME: 1256*f1d7ae31SEmmanuel Vadot return "Game"; 1257*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_PC: 1258*f1d7ae31SEmmanuel Vadot return "PC General"; 1259*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_BD: 1260*f1d7ae31SEmmanuel Vadot return "Blu-Ray Disc (BD)"; 1261*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_SACD: 1262*f1d7ae31SEmmanuel Vadot return "Super Audio CD"; 1263*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_HDDVD: 1264*f1d7ae31SEmmanuel Vadot return "HD DVD"; 1265*f1d7ae31SEmmanuel Vadot case HDMI_SPD_SDI_PMP: 1266*f1d7ae31SEmmanuel Vadot return "PMP"; 1267*f1d7ae31SEmmanuel Vadot } 1268*f1d7ae31SEmmanuel Vadot return "Reserved"; 1269*f1d7ae31SEmmanuel Vadot } 1270*f1d7ae31SEmmanuel Vadot 1271*f1d7ae31SEmmanuel Vadot static void hdmi_spd_infoframe_log(const char *level, 1272*f1d7ae31SEmmanuel Vadot struct device *dev, 1273*f1d7ae31SEmmanuel Vadot const struct hdmi_spd_infoframe *frame) 1274*f1d7ae31SEmmanuel Vadot { 1275*f1d7ae31SEmmanuel Vadot u8 buf[17]; 1276*f1d7ae31SEmmanuel Vadot 1277*f1d7ae31SEmmanuel Vadot hdmi_infoframe_log_header(level, dev, 1278*f1d7ae31SEmmanuel Vadot (const struct hdmi_any_infoframe *)frame); 1279*f1d7ae31SEmmanuel Vadot 1280*f1d7ae31SEmmanuel Vadot memset(buf, 0, sizeof(buf)); 1281*f1d7ae31SEmmanuel Vadot 1282*f1d7ae31SEmmanuel Vadot strncpy(buf, frame->vendor, 8); 1283*f1d7ae31SEmmanuel Vadot hdmi_log(" vendor: %s\n", buf); 1284*f1d7ae31SEmmanuel Vadot strncpy(buf, frame->product, 16); 1285*f1d7ae31SEmmanuel Vadot hdmi_log(" product: %s\n", buf); 1286*f1d7ae31SEmmanuel Vadot hdmi_log(" source device information: %s (0x%x)\n", 1287*f1d7ae31SEmmanuel Vadot hdmi_spd_sdi_get_name(frame->sdi), frame->sdi); 1288*f1d7ae31SEmmanuel Vadot } 1289*f1d7ae31SEmmanuel Vadot 1290*f1d7ae31SEmmanuel Vadot static const char * 1291*f1d7ae31SEmmanuel Vadot hdmi_audio_coding_type_get_name(enum hdmi_audio_coding_type coding_type) 1292*f1d7ae31SEmmanuel Vadot { 1293*f1d7ae31SEmmanuel Vadot switch (coding_type) { 1294*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_STREAM: 1295*f1d7ae31SEmmanuel Vadot return "Refer to Stream Header"; 1296*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_PCM: 1297*f1d7ae31SEmmanuel Vadot return "PCM"; 1298*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_AC3: 1299*f1d7ae31SEmmanuel Vadot return "AC-3"; 1300*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_MPEG1: 1301*f1d7ae31SEmmanuel Vadot return "MPEG1"; 1302*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_MP3: 1303*f1d7ae31SEmmanuel Vadot return "MP3"; 1304*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_MPEG2: 1305*f1d7ae31SEmmanuel Vadot return "MPEG2"; 1306*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_AAC_LC: 1307*f1d7ae31SEmmanuel Vadot return "AAC"; 1308*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_DTS: 1309*f1d7ae31SEmmanuel Vadot return "DTS"; 1310*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_ATRAC: 1311*f1d7ae31SEmmanuel Vadot return "ATRAC"; 1312*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_DSD: 1313*f1d7ae31SEmmanuel Vadot return "One Bit Audio"; 1314*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EAC3: 1315*f1d7ae31SEmmanuel Vadot return "Dolby Digital +"; 1316*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_DTS_HD: 1317*f1d7ae31SEmmanuel Vadot return "DTS-HD"; 1318*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_MLP: 1319*f1d7ae31SEmmanuel Vadot return "MAT (MLP)"; 1320*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_DST: 1321*f1d7ae31SEmmanuel Vadot return "DST"; 1322*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_WMA_PRO: 1323*f1d7ae31SEmmanuel Vadot return "WMA PRO"; 1324*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_CXT: 1325*f1d7ae31SEmmanuel Vadot return "Refer to CXT"; 1326*f1d7ae31SEmmanuel Vadot } 1327*f1d7ae31SEmmanuel Vadot return "Invalid"; 1328*f1d7ae31SEmmanuel Vadot } 1329*f1d7ae31SEmmanuel Vadot 1330*f1d7ae31SEmmanuel Vadot static const char * 1331*f1d7ae31SEmmanuel Vadot hdmi_audio_sample_size_get_name(enum hdmi_audio_sample_size sample_size) 1332*f1d7ae31SEmmanuel Vadot { 1333*f1d7ae31SEmmanuel Vadot switch (sample_size) { 1334*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_SIZE_STREAM: 1335*f1d7ae31SEmmanuel Vadot return "Refer to Stream Header"; 1336*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_SIZE_16: 1337*f1d7ae31SEmmanuel Vadot return "16 bit"; 1338*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_SIZE_20: 1339*f1d7ae31SEmmanuel Vadot return "20 bit"; 1340*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_SIZE_24: 1341*f1d7ae31SEmmanuel Vadot return "24 bit"; 1342*f1d7ae31SEmmanuel Vadot } 1343*f1d7ae31SEmmanuel Vadot return "Invalid"; 1344*f1d7ae31SEmmanuel Vadot } 1345*f1d7ae31SEmmanuel Vadot 1346*f1d7ae31SEmmanuel Vadot static const char * 1347*f1d7ae31SEmmanuel Vadot hdmi_audio_sample_frequency_get_name(enum hdmi_audio_sample_frequency freq) 1348*f1d7ae31SEmmanuel Vadot { 1349*f1d7ae31SEmmanuel Vadot switch (freq) { 1350*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM: 1351*f1d7ae31SEmmanuel Vadot return "Refer to Stream Header"; 1352*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_FREQUENCY_32000: 1353*f1d7ae31SEmmanuel Vadot return "32 kHz"; 1354*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_FREQUENCY_44100: 1355*f1d7ae31SEmmanuel Vadot return "44.1 kHz (CD)"; 1356*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_FREQUENCY_48000: 1357*f1d7ae31SEmmanuel Vadot return "48 kHz"; 1358*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_FREQUENCY_88200: 1359*f1d7ae31SEmmanuel Vadot return "88.2 kHz"; 1360*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_FREQUENCY_96000: 1361*f1d7ae31SEmmanuel Vadot return "96 kHz"; 1362*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_FREQUENCY_176400: 1363*f1d7ae31SEmmanuel Vadot return "176.4 kHz"; 1364*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_SAMPLE_FREQUENCY_192000: 1365*f1d7ae31SEmmanuel Vadot return "192 kHz"; 1366*f1d7ae31SEmmanuel Vadot } 1367*f1d7ae31SEmmanuel Vadot return "Invalid"; 1368*f1d7ae31SEmmanuel Vadot } 1369*f1d7ae31SEmmanuel Vadot 1370*f1d7ae31SEmmanuel Vadot static const char * 1371*f1d7ae31SEmmanuel Vadot hdmi_audio_coding_type_ext_get_name(enum hdmi_audio_coding_type_ext ctx) 1372*f1d7ae31SEmmanuel Vadot { 1373*f1d7ae31SEmmanuel Vadot if (ctx < 0 || ctx > 0x1f) 1374*f1d7ae31SEmmanuel Vadot return "Invalid"; 1375*f1d7ae31SEmmanuel Vadot 1376*f1d7ae31SEmmanuel Vadot switch (ctx) { 1377*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EXT_CT: 1378*f1d7ae31SEmmanuel Vadot return "Refer to CT"; 1379*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC: 1380*f1d7ae31SEmmanuel Vadot return "HE AAC"; 1381*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2: 1382*f1d7ae31SEmmanuel Vadot return "HE AAC v2"; 1383*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND: 1384*f1d7ae31SEmmanuel Vadot return "MPEG SURROUND"; 1385*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC: 1386*f1d7ae31SEmmanuel Vadot return "MPEG-4 HE AAC"; 1387*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_V2: 1388*f1d7ae31SEmmanuel Vadot return "MPEG-4 HE AAC v2"; 1389*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC: 1390*f1d7ae31SEmmanuel Vadot return "MPEG-4 AAC LC"; 1391*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EXT_DRA: 1392*f1d7ae31SEmmanuel Vadot return "DRA"; 1393*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_SURROUND: 1394*f1d7ae31SEmmanuel Vadot return "MPEG-4 HE AAC + MPEG Surround"; 1395*f1d7ae31SEmmanuel Vadot case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC_SURROUND: 1396*f1d7ae31SEmmanuel Vadot return "MPEG-4 AAC LC + MPEG Surround"; 1397*f1d7ae31SEmmanuel Vadot } 1398*f1d7ae31SEmmanuel Vadot return "Reserved"; 1399*f1d7ae31SEmmanuel Vadot } 1400*f1d7ae31SEmmanuel Vadot 1401*f1d7ae31SEmmanuel Vadot static void hdmi_audio_infoframe_log(const char *level, 1402*f1d7ae31SEmmanuel Vadot struct device *dev, 1403*f1d7ae31SEmmanuel Vadot const struct hdmi_audio_infoframe *frame) 1404*f1d7ae31SEmmanuel Vadot { 1405*f1d7ae31SEmmanuel Vadot hdmi_infoframe_log_header(level, dev, 1406*f1d7ae31SEmmanuel Vadot (const struct hdmi_any_infoframe *)frame); 1407*f1d7ae31SEmmanuel Vadot 1408*f1d7ae31SEmmanuel Vadot if (frame->channels) 1409*f1d7ae31SEmmanuel Vadot hdmi_log(" channels: %u\n", frame->channels - 1); 1410*f1d7ae31SEmmanuel Vadot else 1411*f1d7ae31SEmmanuel Vadot hdmi_log(" channels: Refer to stream header\n"); 1412*f1d7ae31SEmmanuel Vadot hdmi_log(" coding type: %s\n", 1413*f1d7ae31SEmmanuel Vadot hdmi_audio_coding_type_get_name(frame->coding_type)); 1414*f1d7ae31SEmmanuel Vadot hdmi_log(" sample size: %s\n", 1415*f1d7ae31SEmmanuel Vadot hdmi_audio_sample_size_get_name(frame->sample_size)); 1416*f1d7ae31SEmmanuel Vadot hdmi_log(" sample frequency: %s\n", 1417*f1d7ae31SEmmanuel Vadot hdmi_audio_sample_frequency_get_name(frame->sample_frequency)); 1418*f1d7ae31SEmmanuel Vadot hdmi_log(" coding type ext: %s\n", 1419*f1d7ae31SEmmanuel Vadot hdmi_audio_coding_type_ext_get_name(frame->coding_type_ext)); 1420*f1d7ae31SEmmanuel Vadot hdmi_log(" channel allocation: 0x%x\n", 1421*f1d7ae31SEmmanuel Vadot frame->channel_allocation); 1422*f1d7ae31SEmmanuel Vadot hdmi_log(" level shift value: %u dB\n", 1423*f1d7ae31SEmmanuel Vadot frame->level_shift_value); 1424*f1d7ae31SEmmanuel Vadot hdmi_log(" downmix inhibit: %s\n", 1425*f1d7ae31SEmmanuel Vadot frame->downmix_inhibit ? "Yes" : "No"); 1426*f1d7ae31SEmmanuel Vadot } 1427*f1d7ae31SEmmanuel Vadot 1428*f1d7ae31SEmmanuel Vadot static void hdmi_drm_infoframe_log(const char *level, 1429*f1d7ae31SEmmanuel Vadot struct device *dev, 1430*f1d7ae31SEmmanuel Vadot const struct hdmi_drm_infoframe *frame) 1431*f1d7ae31SEmmanuel Vadot { 1432*f1d7ae31SEmmanuel Vadot int i; 1433*f1d7ae31SEmmanuel Vadot 1434*f1d7ae31SEmmanuel Vadot hdmi_infoframe_log_header(level, dev, 1435*f1d7ae31SEmmanuel Vadot (struct hdmi_any_infoframe *)frame); 1436*f1d7ae31SEmmanuel Vadot hdmi_log("length: %d\n", frame->length); 1437*f1d7ae31SEmmanuel Vadot hdmi_log("metadata type: %d\n", frame->metadata_type); 1438*f1d7ae31SEmmanuel Vadot hdmi_log("eotf: %d\n", frame->eotf); 1439*f1d7ae31SEmmanuel Vadot for (i = 0; i < 3; i++) { 1440*f1d7ae31SEmmanuel Vadot hdmi_log("x[%d]: %d\n", i, frame->display_primaries[i].x); 1441*f1d7ae31SEmmanuel Vadot hdmi_log("y[%d]: %d\n", i, frame->display_primaries[i].y); 1442*f1d7ae31SEmmanuel Vadot } 1443*f1d7ae31SEmmanuel Vadot 1444*f1d7ae31SEmmanuel Vadot hdmi_log("white point x: %d\n", frame->white_point.x); 1445*f1d7ae31SEmmanuel Vadot hdmi_log("white point y: %d\n", frame->white_point.y); 1446*f1d7ae31SEmmanuel Vadot 1447*f1d7ae31SEmmanuel Vadot hdmi_log("max_display_mastering_luminance: %d\n", 1448*f1d7ae31SEmmanuel Vadot frame->max_display_mastering_luminance); 1449*f1d7ae31SEmmanuel Vadot hdmi_log("min_display_mastering_luminance: %d\n", 1450*f1d7ae31SEmmanuel Vadot frame->min_display_mastering_luminance); 1451*f1d7ae31SEmmanuel Vadot 1452*f1d7ae31SEmmanuel Vadot hdmi_log("max_cll: %d\n", frame->max_cll); 1453*f1d7ae31SEmmanuel Vadot hdmi_log("max_fall: %d\n", frame->max_fall); 1454*f1d7ae31SEmmanuel Vadot } 1455*f1d7ae31SEmmanuel Vadot 1456*f1d7ae31SEmmanuel Vadot static const char * 1457*f1d7ae31SEmmanuel Vadot hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct) 1458*f1d7ae31SEmmanuel Vadot { 1459*f1d7ae31SEmmanuel Vadot if (s3d_struct < 0 || s3d_struct > 0xf) 1460*f1d7ae31SEmmanuel Vadot return "Invalid"; 1461*f1d7ae31SEmmanuel Vadot 1462*f1d7ae31SEmmanuel Vadot switch (s3d_struct) { 1463*f1d7ae31SEmmanuel Vadot case HDMI_3D_STRUCTURE_FRAME_PACKING: 1464*f1d7ae31SEmmanuel Vadot return "Frame Packing"; 1465*f1d7ae31SEmmanuel Vadot case HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE: 1466*f1d7ae31SEmmanuel Vadot return "Field Alternative"; 1467*f1d7ae31SEmmanuel Vadot case HDMI_3D_STRUCTURE_LINE_ALTERNATIVE: 1468*f1d7ae31SEmmanuel Vadot return "Line Alternative"; 1469*f1d7ae31SEmmanuel Vadot case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL: 1470*f1d7ae31SEmmanuel Vadot return "Side-by-side (Full)"; 1471*f1d7ae31SEmmanuel Vadot case HDMI_3D_STRUCTURE_L_DEPTH: 1472*f1d7ae31SEmmanuel Vadot return "L + Depth"; 1473*f1d7ae31SEmmanuel Vadot case HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH: 1474*f1d7ae31SEmmanuel Vadot return "L + Depth + Graphics + Graphics-depth"; 1475*f1d7ae31SEmmanuel Vadot case HDMI_3D_STRUCTURE_TOP_AND_BOTTOM: 1476*f1d7ae31SEmmanuel Vadot return "Top-and-Bottom"; 1477*f1d7ae31SEmmanuel Vadot case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF: 1478*f1d7ae31SEmmanuel Vadot return "Side-by-side (Half)"; 1479*f1d7ae31SEmmanuel Vadot default: 1480*f1d7ae31SEmmanuel Vadot break; 1481*f1d7ae31SEmmanuel Vadot } 1482*f1d7ae31SEmmanuel Vadot return "Reserved"; 1483*f1d7ae31SEmmanuel Vadot } 1484*f1d7ae31SEmmanuel Vadot 1485*f1d7ae31SEmmanuel Vadot static void 1486*f1d7ae31SEmmanuel Vadot hdmi_vendor_any_infoframe_log(const char *level, 1487*f1d7ae31SEmmanuel Vadot struct device *dev, 1488*f1d7ae31SEmmanuel Vadot const union hdmi_vendor_any_infoframe *frame) 1489*f1d7ae31SEmmanuel Vadot { 1490*f1d7ae31SEmmanuel Vadot const struct hdmi_vendor_infoframe *hvf = &frame->hdmi; 1491*f1d7ae31SEmmanuel Vadot 1492*f1d7ae31SEmmanuel Vadot hdmi_infoframe_log_header(level, dev, 1493*f1d7ae31SEmmanuel Vadot (const struct hdmi_any_infoframe *)frame); 1494*f1d7ae31SEmmanuel Vadot 1495*f1d7ae31SEmmanuel Vadot if (frame->any.oui != HDMI_IEEE_OUI) { 1496*f1d7ae31SEmmanuel Vadot hdmi_log(" not a HDMI vendor infoframe\n"); 1497*f1d7ae31SEmmanuel Vadot return; 1498*f1d7ae31SEmmanuel Vadot } 1499*f1d7ae31SEmmanuel Vadot if (hvf->vic == 0 && hvf->s3d_struct == HDMI_3D_STRUCTURE_INVALID) { 1500*f1d7ae31SEmmanuel Vadot hdmi_log(" empty frame\n"); 1501*f1d7ae31SEmmanuel Vadot return; 1502*f1d7ae31SEmmanuel Vadot } 1503*f1d7ae31SEmmanuel Vadot 1504*f1d7ae31SEmmanuel Vadot if (hvf->vic) 1505*f1d7ae31SEmmanuel Vadot hdmi_log(" HDMI VIC: %u\n", hvf->vic); 1506*f1d7ae31SEmmanuel Vadot if (hvf->s3d_struct != HDMI_3D_STRUCTURE_INVALID) { 1507*f1d7ae31SEmmanuel Vadot hdmi_log(" 3D structure: %s\n", 1508*f1d7ae31SEmmanuel Vadot hdmi_3d_structure_get_name(hvf->s3d_struct)); 1509*f1d7ae31SEmmanuel Vadot if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) 1510*f1d7ae31SEmmanuel Vadot hdmi_log(" 3D extension data: %d\n", 1511*f1d7ae31SEmmanuel Vadot hvf->s3d_ext_data); 1512*f1d7ae31SEmmanuel Vadot } 1513*f1d7ae31SEmmanuel Vadot } 1514*f1d7ae31SEmmanuel Vadot 1515*f1d7ae31SEmmanuel Vadot /** 1516*f1d7ae31SEmmanuel Vadot * hdmi_infoframe_log() - log info of HDMI infoframe 1517*f1d7ae31SEmmanuel Vadot * @level: logging level 1518*f1d7ae31SEmmanuel Vadot * @dev: device 1519*f1d7ae31SEmmanuel Vadot * @frame: HDMI infoframe 1520*f1d7ae31SEmmanuel Vadot */ 1521*f1d7ae31SEmmanuel Vadot void hdmi_infoframe_log(const char *level, 1522*f1d7ae31SEmmanuel Vadot struct device *dev, 1523*f1d7ae31SEmmanuel Vadot const union hdmi_infoframe *frame) 1524*f1d7ae31SEmmanuel Vadot { 1525*f1d7ae31SEmmanuel Vadot switch (frame->any.type) { 1526*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AVI: 1527*f1d7ae31SEmmanuel Vadot hdmi_avi_infoframe_log(level, dev, &frame->avi); 1528*f1d7ae31SEmmanuel Vadot break; 1529*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_SPD: 1530*f1d7ae31SEmmanuel Vadot hdmi_spd_infoframe_log(level, dev, &frame->spd); 1531*f1d7ae31SEmmanuel Vadot break; 1532*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AUDIO: 1533*f1d7ae31SEmmanuel Vadot hdmi_audio_infoframe_log(level, dev, &frame->audio); 1534*f1d7ae31SEmmanuel Vadot break; 1535*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_VENDOR: 1536*f1d7ae31SEmmanuel Vadot hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor); 1537*f1d7ae31SEmmanuel Vadot break; 1538*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_DRM: 1539*f1d7ae31SEmmanuel Vadot hdmi_drm_infoframe_log(level, dev, &frame->drm); 1540*f1d7ae31SEmmanuel Vadot break; 1541*f1d7ae31SEmmanuel Vadot } 1542*f1d7ae31SEmmanuel Vadot } 1543*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_infoframe_log); 1544*f1d7ae31SEmmanuel Vadot 1545*f1d7ae31SEmmanuel Vadot /** 1546*f1d7ae31SEmmanuel Vadot * hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe 1547*f1d7ae31SEmmanuel Vadot * @frame: HDMI AVI infoframe 1548*f1d7ae31SEmmanuel Vadot * @buffer: source buffer 1549*f1d7ae31SEmmanuel Vadot * @size: size of buffer 1550*f1d7ae31SEmmanuel Vadot * 1551*f1d7ae31SEmmanuel Vadot * Unpacks the information contained in binary @buffer into a structured 1552*f1d7ae31SEmmanuel Vadot * @frame of the HDMI Auxiliary Video (AVI) information frame. 1553*f1d7ae31SEmmanuel Vadot * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 1554*f1d7ae31SEmmanuel Vadot * specification. 1555*f1d7ae31SEmmanuel Vadot * 1556*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 1557*f1d7ae31SEmmanuel Vadot */ 1558*f1d7ae31SEmmanuel Vadot static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame, 1559*f1d7ae31SEmmanuel Vadot const void *buffer, size_t size) 1560*f1d7ae31SEmmanuel Vadot { 1561*f1d7ae31SEmmanuel Vadot const u8 *ptr = buffer; 1562*f1d7ae31SEmmanuel Vadot 1563*f1d7ae31SEmmanuel Vadot if (size < HDMI_INFOFRAME_SIZE(AVI)) 1564*f1d7ae31SEmmanuel Vadot return -EINVAL; 1565*f1d7ae31SEmmanuel Vadot 1566*f1d7ae31SEmmanuel Vadot if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI || 1567*f1d7ae31SEmmanuel Vadot ptr[1] != 2 || 1568*f1d7ae31SEmmanuel Vadot ptr[2] != HDMI_AVI_INFOFRAME_SIZE) 1569*f1d7ae31SEmmanuel Vadot return -EINVAL; 1570*f1d7ae31SEmmanuel Vadot 1571*f1d7ae31SEmmanuel Vadot if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0) 1572*f1d7ae31SEmmanuel Vadot return -EINVAL; 1573*f1d7ae31SEmmanuel Vadot 1574*f1d7ae31SEmmanuel Vadot hdmi_avi_infoframe_init(frame); 1575*f1d7ae31SEmmanuel Vadot 1576*f1d7ae31SEmmanuel Vadot ptr += HDMI_INFOFRAME_HEADER_SIZE; 1577*f1d7ae31SEmmanuel Vadot 1578*f1d7ae31SEmmanuel Vadot frame->colorspace = (ptr[0] >> 5) & 0x3; 1579*f1d7ae31SEmmanuel Vadot if (ptr[0] & 0x10) 1580*f1d7ae31SEmmanuel Vadot frame->active_aspect = ptr[1] & 0xf; 1581*f1d7ae31SEmmanuel Vadot if (ptr[0] & 0x8) { 1582*f1d7ae31SEmmanuel Vadot frame->top_bar = (ptr[6] << 8) | ptr[5]; 1583*f1d7ae31SEmmanuel Vadot frame->bottom_bar = (ptr[8] << 8) | ptr[7]; 1584*f1d7ae31SEmmanuel Vadot } 1585*f1d7ae31SEmmanuel Vadot if (ptr[0] & 0x4) { 1586*f1d7ae31SEmmanuel Vadot frame->left_bar = (ptr[10] << 8) | ptr[9]; 1587*f1d7ae31SEmmanuel Vadot frame->right_bar = (ptr[12] << 8) | ptr[11]; 1588*f1d7ae31SEmmanuel Vadot } 1589*f1d7ae31SEmmanuel Vadot frame->scan_mode = ptr[0] & 0x3; 1590*f1d7ae31SEmmanuel Vadot 1591*f1d7ae31SEmmanuel Vadot frame->colorimetry = (ptr[1] >> 6) & 0x3; 1592*f1d7ae31SEmmanuel Vadot frame->picture_aspect = (ptr[1] >> 4) & 0x3; 1593*f1d7ae31SEmmanuel Vadot frame->active_aspect = ptr[1] & 0xf; 1594*f1d7ae31SEmmanuel Vadot 1595*f1d7ae31SEmmanuel Vadot frame->itc = ptr[2] & 0x80 ? true : false; 1596*f1d7ae31SEmmanuel Vadot frame->extended_colorimetry = (ptr[2] >> 4) & 0x7; 1597*f1d7ae31SEmmanuel Vadot frame->quantization_range = (ptr[2] >> 2) & 0x3; 1598*f1d7ae31SEmmanuel Vadot frame->nups = ptr[2] & 0x3; 1599*f1d7ae31SEmmanuel Vadot 1600*f1d7ae31SEmmanuel Vadot frame->video_code = ptr[3] & 0x7f; 1601*f1d7ae31SEmmanuel Vadot frame->ycc_quantization_range = (ptr[4] >> 6) & 0x3; 1602*f1d7ae31SEmmanuel Vadot frame->content_type = (ptr[4] >> 4) & 0x3; 1603*f1d7ae31SEmmanuel Vadot 1604*f1d7ae31SEmmanuel Vadot frame->pixel_repeat = ptr[4] & 0xf; 1605*f1d7ae31SEmmanuel Vadot 1606*f1d7ae31SEmmanuel Vadot return 0; 1607*f1d7ae31SEmmanuel Vadot } 1608*f1d7ae31SEmmanuel Vadot 1609*f1d7ae31SEmmanuel Vadot /** 1610*f1d7ae31SEmmanuel Vadot * hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe 1611*f1d7ae31SEmmanuel Vadot * @frame: HDMI SPD infoframe 1612*f1d7ae31SEmmanuel Vadot * @buffer: source buffer 1613*f1d7ae31SEmmanuel Vadot * @size: size of buffer 1614*f1d7ae31SEmmanuel Vadot * 1615*f1d7ae31SEmmanuel Vadot * Unpacks the information contained in binary @buffer into a structured 1616*f1d7ae31SEmmanuel Vadot * @frame of the HDMI Source Product Description (SPD) information frame. 1617*f1d7ae31SEmmanuel Vadot * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 1618*f1d7ae31SEmmanuel Vadot * specification. 1619*f1d7ae31SEmmanuel Vadot * 1620*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 1621*f1d7ae31SEmmanuel Vadot */ 1622*f1d7ae31SEmmanuel Vadot static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame, 1623*f1d7ae31SEmmanuel Vadot const void *buffer, size_t size) 1624*f1d7ae31SEmmanuel Vadot { 1625*f1d7ae31SEmmanuel Vadot const u8 *ptr = buffer; 1626*f1d7ae31SEmmanuel Vadot int ret; 1627*f1d7ae31SEmmanuel Vadot 1628*f1d7ae31SEmmanuel Vadot if (size < HDMI_INFOFRAME_SIZE(SPD)) 1629*f1d7ae31SEmmanuel Vadot return -EINVAL; 1630*f1d7ae31SEmmanuel Vadot 1631*f1d7ae31SEmmanuel Vadot if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD || 1632*f1d7ae31SEmmanuel Vadot ptr[1] != 1 || 1633*f1d7ae31SEmmanuel Vadot ptr[2] != HDMI_SPD_INFOFRAME_SIZE) { 1634*f1d7ae31SEmmanuel Vadot return -EINVAL; 1635*f1d7ae31SEmmanuel Vadot } 1636*f1d7ae31SEmmanuel Vadot 1637*f1d7ae31SEmmanuel Vadot if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(SPD)) != 0) 1638*f1d7ae31SEmmanuel Vadot return -EINVAL; 1639*f1d7ae31SEmmanuel Vadot 1640*f1d7ae31SEmmanuel Vadot ptr += HDMI_INFOFRAME_HEADER_SIZE; 1641*f1d7ae31SEmmanuel Vadot 1642*f1d7ae31SEmmanuel Vadot ret = hdmi_spd_infoframe_init(frame, ptr, ptr + 8); 1643*f1d7ae31SEmmanuel Vadot if (ret) 1644*f1d7ae31SEmmanuel Vadot return ret; 1645*f1d7ae31SEmmanuel Vadot 1646*f1d7ae31SEmmanuel Vadot frame->sdi = ptr[24]; 1647*f1d7ae31SEmmanuel Vadot 1648*f1d7ae31SEmmanuel Vadot return 0; 1649*f1d7ae31SEmmanuel Vadot } 1650*f1d7ae31SEmmanuel Vadot 1651*f1d7ae31SEmmanuel Vadot /** 1652*f1d7ae31SEmmanuel Vadot * hdmi_audio_infoframe_unpack() - unpack binary buffer to a HDMI AUDIO infoframe 1653*f1d7ae31SEmmanuel Vadot * @frame: HDMI Audio infoframe 1654*f1d7ae31SEmmanuel Vadot * @buffer: source buffer 1655*f1d7ae31SEmmanuel Vadot * @size: size of buffer 1656*f1d7ae31SEmmanuel Vadot * 1657*f1d7ae31SEmmanuel Vadot * Unpacks the information contained in binary @buffer into a structured 1658*f1d7ae31SEmmanuel Vadot * @frame of the HDMI Audio information frame. 1659*f1d7ae31SEmmanuel Vadot * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 1660*f1d7ae31SEmmanuel Vadot * specification. 1661*f1d7ae31SEmmanuel Vadot * 1662*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 1663*f1d7ae31SEmmanuel Vadot */ 1664*f1d7ae31SEmmanuel Vadot static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame, 1665*f1d7ae31SEmmanuel Vadot const void *buffer, size_t size) 1666*f1d7ae31SEmmanuel Vadot { 1667*f1d7ae31SEmmanuel Vadot const u8 *ptr = buffer; 1668*f1d7ae31SEmmanuel Vadot int ret; 1669*f1d7ae31SEmmanuel Vadot 1670*f1d7ae31SEmmanuel Vadot if (size < HDMI_INFOFRAME_SIZE(AUDIO)) 1671*f1d7ae31SEmmanuel Vadot return -EINVAL; 1672*f1d7ae31SEmmanuel Vadot 1673*f1d7ae31SEmmanuel Vadot if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO || 1674*f1d7ae31SEmmanuel Vadot ptr[1] != 1 || 1675*f1d7ae31SEmmanuel Vadot ptr[2] != HDMI_AUDIO_INFOFRAME_SIZE) { 1676*f1d7ae31SEmmanuel Vadot return -EINVAL; 1677*f1d7ae31SEmmanuel Vadot } 1678*f1d7ae31SEmmanuel Vadot 1679*f1d7ae31SEmmanuel Vadot if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AUDIO)) != 0) 1680*f1d7ae31SEmmanuel Vadot return -EINVAL; 1681*f1d7ae31SEmmanuel Vadot 1682*f1d7ae31SEmmanuel Vadot ret = hdmi_audio_infoframe_init(frame); 1683*f1d7ae31SEmmanuel Vadot if (ret) 1684*f1d7ae31SEmmanuel Vadot return ret; 1685*f1d7ae31SEmmanuel Vadot 1686*f1d7ae31SEmmanuel Vadot ptr += HDMI_INFOFRAME_HEADER_SIZE; 1687*f1d7ae31SEmmanuel Vadot 1688*f1d7ae31SEmmanuel Vadot frame->channels = ptr[0] & 0x7; 1689*f1d7ae31SEmmanuel Vadot frame->coding_type = (ptr[0] >> 4) & 0xf; 1690*f1d7ae31SEmmanuel Vadot frame->sample_size = ptr[1] & 0x3; 1691*f1d7ae31SEmmanuel Vadot frame->sample_frequency = (ptr[1] >> 2) & 0x7; 1692*f1d7ae31SEmmanuel Vadot frame->coding_type_ext = ptr[2] & 0x1f; 1693*f1d7ae31SEmmanuel Vadot frame->channel_allocation = ptr[3]; 1694*f1d7ae31SEmmanuel Vadot frame->level_shift_value = (ptr[4] >> 3) & 0xf; 1695*f1d7ae31SEmmanuel Vadot frame->downmix_inhibit = ptr[4] & 0x80 ? true : false; 1696*f1d7ae31SEmmanuel Vadot 1697*f1d7ae31SEmmanuel Vadot return 0; 1698*f1d7ae31SEmmanuel Vadot } 1699*f1d7ae31SEmmanuel Vadot 1700*f1d7ae31SEmmanuel Vadot /** 1701*f1d7ae31SEmmanuel Vadot * hdmi_vendor_any_infoframe_unpack() - unpack binary buffer to a HDMI 1702*f1d7ae31SEmmanuel Vadot * vendor infoframe 1703*f1d7ae31SEmmanuel Vadot * @frame: HDMI Vendor infoframe 1704*f1d7ae31SEmmanuel Vadot * @buffer: source buffer 1705*f1d7ae31SEmmanuel Vadot * @size: size of buffer 1706*f1d7ae31SEmmanuel Vadot * 1707*f1d7ae31SEmmanuel Vadot * Unpacks the information contained in binary @buffer into a structured 1708*f1d7ae31SEmmanuel Vadot * @frame of the HDMI Vendor information frame. 1709*f1d7ae31SEmmanuel Vadot * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 1710*f1d7ae31SEmmanuel Vadot * specification. 1711*f1d7ae31SEmmanuel Vadot * 1712*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 1713*f1d7ae31SEmmanuel Vadot */ 1714*f1d7ae31SEmmanuel Vadot static int 1715*f1d7ae31SEmmanuel Vadot hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, 1716*f1d7ae31SEmmanuel Vadot const void *buffer, size_t size) 1717*f1d7ae31SEmmanuel Vadot { 1718*f1d7ae31SEmmanuel Vadot const u8 *ptr = buffer; 1719*f1d7ae31SEmmanuel Vadot size_t length; 1720*f1d7ae31SEmmanuel Vadot int ret; 1721*f1d7ae31SEmmanuel Vadot u8 hdmi_video_format; 1722*f1d7ae31SEmmanuel Vadot struct hdmi_vendor_infoframe *hvf = &frame->hdmi; 1723*f1d7ae31SEmmanuel Vadot 1724*f1d7ae31SEmmanuel Vadot if (size < HDMI_INFOFRAME_HEADER_SIZE) 1725*f1d7ae31SEmmanuel Vadot return -EINVAL; 1726*f1d7ae31SEmmanuel Vadot 1727*f1d7ae31SEmmanuel Vadot if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR || 1728*f1d7ae31SEmmanuel Vadot ptr[1] != 1 || 1729*f1d7ae31SEmmanuel Vadot (ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6)) 1730*f1d7ae31SEmmanuel Vadot return -EINVAL; 1731*f1d7ae31SEmmanuel Vadot 1732*f1d7ae31SEmmanuel Vadot length = ptr[2]; 1733*f1d7ae31SEmmanuel Vadot 1734*f1d7ae31SEmmanuel Vadot if (size < HDMI_INFOFRAME_HEADER_SIZE + length) 1735*f1d7ae31SEmmanuel Vadot return -EINVAL; 1736*f1d7ae31SEmmanuel Vadot 1737*f1d7ae31SEmmanuel Vadot if (hdmi_infoframe_checksum(buffer, 1738*f1d7ae31SEmmanuel Vadot HDMI_INFOFRAME_HEADER_SIZE + length) != 0) 1739*f1d7ae31SEmmanuel Vadot return -EINVAL; 1740*f1d7ae31SEmmanuel Vadot 1741*f1d7ae31SEmmanuel Vadot ptr += HDMI_INFOFRAME_HEADER_SIZE; 1742*f1d7ae31SEmmanuel Vadot 1743*f1d7ae31SEmmanuel Vadot /* HDMI OUI */ 1744*f1d7ae31SEmmanuel Vadot if ((ptr[0] != 0x03) || 1745*f1d7ae31SEmmanuel Vadot (ptr[1] != 0x0c) || 1746*f1d7ae31SEmmanuel Vadot (ptr[2] != 0x00)) 1747*f1d7ae31SEmmanuel Vadot return -EINVAL; 1748*f1d7ae31SEmmanuel Vadot 1749*f1d7ae31SEmmanuel Vadot hdmi_video_format = ptr[3] >> 5; 1750*f1d7ae31SEmmanuel Vadot 1751*f1d7ae31SEmmanuel Vadot if (hdmi_video_format > 0x2) 1752*f1d7ae31SEmmanuel Vadot return -EINVAL; 1753*f1d7ae31SEmmanuel Vadot 1754*f1d7ae31SEmmanuel Vadot ret = hdmi_vendor_infoframe_init(hvf); 1755*f1d7ae31SEmmanuel Vadot if (ret) 1756*f1d7ae31SEmmanuel Vadot return ret; 1757*f1d7ae31SEmmanuel Vadot 1758*f1d7ae31SEmmanuel Vadot hvf->length = length; 1759*f1d7ae31SEmmanuel Vadot 1760*f1d7ae31SEmmanuel Vadot if (hdmi_video_format == 0x2) { 1761*f1d7ae31SEmmanuel Vadot if (length != 5 && length != 6) 1762*f1d7ae31SEmmanuel Vadot return -EINVAL; 1763*f1d7ae31SEmmanuel Vadot hvf->s3d_struct = ptr[4] >> 4; 1764*f1d7ae31SEmmanuel Vadot if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) { 1765*f1d7ae31SEmmanuel Vadot if (length != 6) 1766*f1d7ae31SEmmanuel Vadot return -EINVAL; 1767*f1d7ae31SEmmanuel Vadot hvf->s3d_ext_data = ptr[5] >> 4; 1768*f1d7ae31SEmmanuel Vadot } 1769*f1d7ae31SEmmanuel Vadot } else if (hdmi_video_format == 0x1) { 1770*f1d7ae31SEmmanuel Vadot if (length != 5) 1771*f1d7ae31SEmmanuel Vadot return -EINVAL; 1772*f1d7ae31SEmmanuel Vadot hvf->vic = ptr[4]; 1773*f1d7ae31SEmmanuel Vadot } else { 1774*f1d7ae31SEmmanuel Vadot if (length != 4) 1775*f1d7ae31SEmmanuel Vadot return -EINVAL; 1776*f1d7ae31SEmmanuel Vadot } 1777*f1d7ae31SEmmanuel Vadot 1778*f1d7ae31SEmmanuel Vadot return 0; 1779*f1d7ae31SEmmanuel Vadot } 1780*f1d7ae31SEmmanuel Vadot 1781*f1d7ae31SEmmanuel Vadot /** 1782*f1d7ae31SEmmanuel Vadot * hdmi_drm_infoframe_unpack_only() - unpack binary buffer of CTA-861-G DRM 1783*f1d7ae31SEmmanuel Vadot * infoframe DataBytes to a HDMI DRM 1784*f1d7ae31SEmmanuel Vadot * infoframe 1785*f1d7ae31SEmmanuel Vadot * @frame: HDMI DRM infoframe 1786*f1d7ae31SEmmanuel Vadot * @buffer: source buffer 1787*f1d7ae31SEmmanuel Vadot * @size: size of buffer 1788*f1d7ae31SEmmanuel Vadot * 1789*f1d7ae31SEmmanuel Vadot * Unpacks CTA-861-G DRM infoframe DataBytes contained in the binary @buffer 1790*f1d7ae31SEmmanuel Vadot * into a structured @frame of the HDMI Dynamic Range and Mastering (DRM) 1791*f1d7ae31SEmmanuel Vadot * infoframe. 1792*f1d7ae31SEmmanuel Vadot * 1793*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 1794*f1d7ae31SEmmanuel Vadot */ 1795*f1d7ae31SEmmanuel Vadot int hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe *frame, 1796*f1d7ae31SEmmanuel Vadot const void *buffer, size_t size) 1797*f1d7ae31SEmmanuel Vadot { 1798*f1d7ae31SEmmanuel Vadot const u8 *ptr = buffer; 1799*f1d7ae31SEmmanuel Vadot const u8 *temp; 1800*f1d7ae31SEmmanuel Vadot u8 x_lsb, x_msb; 1801*f1d7ae31SEmmanuel Vadot u8 y_lsb, y_msb; 1802*f1d7ae31SEmmanuel Vadot int ret; 1803*f1d7ae31SEmmanuel Vadot int i; 1804*f1d7ae31SEmmanuel Vadot 1805*f1d7ae31SEmmanuel Vadot if (size < HDMI_DRM_INFOFRAME_SIZE) 1806*f1d7ae31SEmmanuel Vadot return -EINVAL; 1807*f1d7ae31SEmmanuel Vadot 1808*f1d7ae31SEmmanuel Vadot ret = hdmi_drm_infoframe_init(frame); 1809*f1d7ae31SEmmanuel Vadot if (ret) 1810*f1d7ae31SEmmanuel Vadot return ret; 1811*f1d7ae31SEmmanuel Vadot 1812*f1d7ae31SEmmanuel Vadot frame->eotf = ptr[0] & 0x7; 1813*f1d7ae31SEmmanuel Vadot frame->metadata_type = ptr[1] & 0x7; 1814*f1d7ae31SEmmanuel Vadot 1815*f1d7ae31SEmmanuel Vadot temp = ptr + 2; 1816*f1d7ae31SEmmanuel Vadot for (i = 0; i < 3; i++) { 1817*f1d7ae31SEmmanuel Vadot x_lsb = *temp++; 1818*f1d7ae31SEmmanuel Vadot x_msb = *temp++; 1819*f1d7ae31SEmmanuel Vadot frame->display_primaries[i].x = (x_msb << 8) | x_lsb; 1820*f1d7ae31SEmmanuel Vadot y_lsb = *temp++; 1821*f1d7ae31SEmmanuel Vadot y_msb = *temp++; 1822*f1d7ae31SEmmanuel Vadot frame->display_primaries[i].y = (y_msb << 8) | y_lsb; 1823*f1d7ae31SEmmanuel Vadot } 1824*f1d7ae31SEmmanuel Vadot 1825*f1d7ae31SEmmanuel Vadot frame->white_point.x = (ptr[15] << 8) | ptr[14]; 1826*f1d7ae31SEmmanuel Vadot frame->white_point.y = (ptr[17] << 8) | ptr[16]; 1827*f1d7ae31SEmmanuel Vadot 1828*f1d7ae31SEmmanuel Vadot frame->max_display_mastering_luminance = (ptr[19] << 8) | ptr[18]; 1829*f1d7ae31SEmmanuel Vadot frame->min_display_mastering_luminance = (ptr[21] << 8) | ptr[20]; 1830*f1d7ae31SEmmanuel Vadot frame->max_cll = (ptr[23] << 8) | ptr[22]; 1831*f1d7ae31SEmmanuel Vadot frame->max_fall = (ptr[25] << 8) | ptr[24]; 1832*f1d7ae31SEmmanuel Vadot 1833*f1d7ae31SEmmanuel Vadot return 0; 1834*f1d7ae31SEmmanuel Vadot } 1835*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_drm_infoframe_unpack_only); 1836*f1d7ae31SEmmanuel Vadot 1837*f1d7ae31SEmmanuel Vadot /** 1838*f1d7ae31SEmmanuel Vadot * hdmi_drm_infoframe_unpack() - unpack binary buffer to a HDMI DRM infoframe 1839*f1d7ae31SEmmanuel Vadot * @frame: HDMI DRM infoframe 1840*f1d7ae31SEmmanuel Vadot * @buffer: source buffer 1841*f1d7ae31SEmmanuel Vadot * @size: size of buffer 1842*f1d7ae31SEmmanuel Vadot * 1843*f1d7ae31SEmmanuel Vadot * Unpacks the CTA-861-G DRM infoframe contained in the binary @buffer into 1844*f1d7ae31SEmmanuel Vadot * a structured @frame of the HDMI Dynamic Range and Mastering (DRM) 1845*f1d7ae31SEmmanuel Vadot * infoframe. It also verifies the checksum as required by section 5.3.5 of 1846*f1d7ae31SEmmanuel Vadot * the HDMI 1.4 specification. 1847*f1d7ae31SEmmanuel Vadot * 1848*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 1849*f1d7ae31SEmmanuel Vadot */ 1850*f1d7ae31SEmmanuel Vadot static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame, 1851*f1d7ae31SEmmanuel Vadot const void *buffer, size_t size) 1852*f1d7ae31SEmmanuel Vadot { 1853*f1d7ae31SEmmanuel Vadot const u8 *ptr = buffer; 1854*f1d7ae31SEmmanuel Vadot int ret; 1855*f1d7ae31SEmmanuel Vadot 1856*f1d7ae31SEmmanuel Vadot if (size < HDMI_INFOFRAME_SIZE(DRM)) 1857*f1d7ae31SEmmanuel Vadot return -EINVAL; 1858*f1d7ae31SEmmanuel Vadot 1859*f1d7ae31SEmmanuel Vadot if (ptr[0] != HDMI_INFOFRAME_TYPE_DRM || 1860*f1d7ae31SEmmanuel Vadot ptr[1] != 1 || 1861*f1d7ae31SEmmanuel Vadot ptr[2] != HDMI_DRM_INFOFRAME_SIZE) 1862*f1d7ae31SEmmanuel Vadot return -EINVAL; 1863*f1d7ae31SEmmanuel Vadot 1864*f1d7ae31SEmmanuel Vadot if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(DRM)) != 0) 1865*f1d7ae31SEmmanuel Vadot return -EINVAL; 1866*f1d7ae31SEmmanuel Vadot 1867*f1d7ae31SEmmanuel Vadot ret = hdmi_drm_infoframe_unpack_only(frame, ptr + HDMI_INFOFRAME_HEADER_SIZE, 1868*f1d7ae31SEmmanuel Vadot size - HDMI_INFOFRAME_HEADER_SIZE); 1869*f1d7ae31SEmmanuel Vadot return ret; 1870*f1d7ae31SEmmanuel Vadot } 1871*f1d7ae31SEmmanuel Vadot 1872*f1d7ae31SEmmanuel Vadot /** 1873*f1d7ae31SEmmanuel Vadot * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe 1874*f1d7ae31SEmmanuel Vadot * @frame: HDMI infoframe 1875*f1d7ae31SEmmanuel Vadot * @buffer: source buffer 1876*f1d7ae31SEmmanuel Vadot * @size: size of buffer 1877*f1d7ae31SEmmanuel Vadot * 1878*f1d7ae31SEmmanuel Vadot * Unpacks the information contained in binary buffer @buffer into a structured 1879*f1d7ae31SEmmanuel Vadot * @frame of a HDMI infoframe. 1880*f1d7ae31SEmmanuel Vadot * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 1881*f1d7ae31SEmmanuel Vadot * specification. 1882*f1d7ae31SEmmanuel Vadot * 1883*f1d7ae31SEmmanuel Vadot * Returns 0 on success or a negative error code on failure. 1884*f1d7ae31SEmmanuel Vadot */ 1885*f1d7ae31SEmmanuel Vadot int hdmi_infoframe_unpack(union hdmi_infoframe *frame, 1886*f1d7ae31SEmmanuel Vadot const void *buffer, size_t size) 1887*f1d7ae31SEmmanuel Vadot { 1888*f1d7ae31SEmmanuel Vadot int ret; 1889*f1d7ae31SEmmanuel Vadot const u8 *ptr = buffer; 1890*f1d7ae31SEmmanuel Vadot 1891*f1d7ae31SEmmanuel Vadot if (size < HDMI_INFOFRAME_HEADER_SIZE) 1892*f1d7ae31SEmmanuel Vadot return -EINVAL; 1893*f1d7ae31SEmmanuel Vadot 1894*f1d7ae31SEmmanuel Vadot switch (ptr[0]) { 1895*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AVI: 1896*f1d7ae31SEmmanuel Vadot ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer, size); 1897*f1d7ae31SEmmanuel Vadot break; 1898*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_DRM: 1899*f1d7ae31SEmmanuel Vadot ret = hdmi_drm_infoframe_unpack(&frame->drm, buffer, size); 1900*f1d7ae31SEmmanuel Vadot break; 1901*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_SPD: 1902*f1d7ae31SEmmanuel Vadot ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer, size); 1903*f1d7ae31SEmmanuel Vadot break; 1904*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_AUDIO: 1905*f1d7ae31SEmmanuel Vadot ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer, size); 1906*f1d7ae31SEmmanuel Vadot break; 1907*f1d7ae31SEmmanuel Vadot case HDMI_INFOFRAME_TYPE_VENDOR: 1908*f1d7ae31SEmmanuel Vadot ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer, size); 1909*f1d7ae31SEmmanuel Vadot break; 1910*f1d7ae31SEmmanuel Vadot default: 1911*f1d7ae31SEmmanuel Vadot ret = -EINVAL; 1912*f1d7ae31SEmmanuel Vadot break; 1913*f1d7ae31SEmmanuel Vadot } 1914*f1d7ae31SEmmanuel Vadot 1915*f1d7ae31SEmmanuel Vadot return ret; 1916*f1d7ae31SEmmanuel Vadot } 1917*f1d7ae31SEmmanuel Vadot EXPORT_SYMBOL(hdmi_infoframe_unpack); 1918*f1d7ae31SEmmanuel Vadot 1919*f1d7ae31SEmmanuel Vadot 1920*f1d7ae31SEmmanuel Vadot MODULE_VERSION(linuxkpi_hdmi, 1); 1921*f1d7ae31SEmmanuel Vadot MODULE_DEPEND(linuxkpi_hdmi, linuxkpi, 1, 1, 1); 1922*f1d7ae31SEmmanuel Vadot MODULE_DEPEND(linuxkpi_hdmi, wlan, 1, 1, 1); 1923