Home | History | Annotate | Line # | Download | only in hdcp
      1 /*	$NetBSD: amdgpu_hdcp_ddc.c,v 1.3 2021/12/19 12:02:39 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2019 Advanced Micro Devices, Inc.
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a
      7  * copy of this software and associated documentation files (the "Software"),
      8  * to deal in the Software without restriction, including without limitation
      9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  * and/or sell copies of the Software, and to permit persons to whom the
     11  * Software is furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in
     14  * all copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
     20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     22  * OTHER DEALINGS IN THE SOFTWARE.
     23  *
     24  * Authors: AMD
     25  *
     26  */
     27 
     28 #include <sys/cdefs.h>
     29 __KERNEL_RCSID(0, "$NetBSD: amdgpu_hdcp_ddc.c,v 1.3 2021/12/19 12:02:39 riastradh Exp $");
     30 
     31 #include "hdcp.h"
     32 
     33 #define HDCP_I2C_ADDR 0x3a	/* 0x74 >> 1*/
     34 #define KSV_READ_SIZE 0xf	/* 0x6803b - 0x6802c */
     35 #define HDCP_MAX_AUX_TRANSACTION_SIZE 16
     36 
     37 enum mod_hdcp_ddc_message_id {
     38 	MOD_HDCP_MESSAGE_ID_INVALID = -1,
     39 
     40 	/* HDCP 1.4 */
     41 
     42 	MOD_HDCP_MESSAGE_ID_READ_BKSV = 0,
     43 	MOD_HDCP_MESSAGE_ID_READ_RI_R0,
     44 	MOD_HDCP_MESSAGE_ID_WRITE_AKSV,
     45 	MOD_HDCP_MESSAGE_ID_WRITE_AINFO,
     46 	MOD_HDCP_MESSAGE_ID_WRITE_AN,
     47 	MOD_HDCP_MESSAGE_ID_READ_VH_X,
     48 	MOD_HDCP_MESSAGE_ID_READ_VH_0,
     49 	MOD_HDCP_MESSAGE_ID_READ_VH_1,
     50 	MOD_HDCP_MESSAGE_ID_READ_VH_2,
     51 	MOD_HDCP_MESSAGE_ID_READ_VH_3,
     52 	MOD_HDCP_MESSAGE_ID_READ_VH_4,
     53 	MOD_HDCP_MESSAGE_ID_READ_BCAPS,
     54 	MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
     55 	MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
     56 	MOD_HDCP_MESSAGE_ID_READ_BINFO,
     57 
     58 	/* HDCP 2.2 */
     59 
     60 	MOD_HDCP_MESSAGE_ID_HDCP2VERSION,
     61 	MOD_HDCP_MESSAGE_ID_RX_CAPS,
     62 	MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
     63 	MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
     64 	MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
     65 	MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
     66 	MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
     67 	MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
     68 	MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
     69 	MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
     70 	MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
     71 	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
     72 	MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
     73 	MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
     74 	MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
     75 	MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
     76 	MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
     77 
     78 	MOD_HDCP_MESSAGE_ID_MAX
     79 };
     80 
     81 static const uint8_t hdcp_i2c_offsets[] = {
     82 	[MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x0,
     83 	[MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x8,
     84 	[MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x10,
     85 	[MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x15,
     86 	[MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x18,
     87 	[MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x20,
     88 	[MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x20,
     89 	[MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x24,
     90 	[MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x28,
     91 	[MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x2C,
     92 	[MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x30,
     93 	[MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x40,
     94 	[MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x41,
     95 	[MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x43,
     96 	[MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0xFF,
     97 	[MOD_HDCP_MESSAGE_ID_HDCP2VERSION] = 0x50,
     98 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x60,
     99 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x80,
    100 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x60,
    101 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x60,
    102 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x80,
    103 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x80,
    104 	[MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x60,
    105 	[MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x80,
    106 	[MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x60,
    107 	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x80,
    108 	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x60,
    109 	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x60,
    110 	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x80,
    111 	[MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x70,
    112 	[MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x0
    113 };
    114 
    115 static const uint32_t hdcp_dpcd_addrs[] = {
    116 	[MOD_HDCP_MESSAGE_ID_READ_BKSV] = 0x68000,
    117 	[MOD_HDCP_MESSAGE_ID_READ_RI_R0] = 0x68005,
    118 	[MOD_HDCP_MESSAGE_ID_WRITE_AKSV] = 0x68007,
    119 	[MOD_HDCP_MESSAGE_ID_WRITE_AINFO] = 0x6803B,
    120 	[MOD_HDCP_MESSAGE_ID_WRITE_AN] = 0x6800c,
    121 	[MOD_HDCP_MESSAGE_ID_READ_VH_X] = 0x68014,
    122 	[MOD_HDCP_MESSAGE_ID_READ_VH_0] = 0x68014,
    123 	[MOD_HDCP_MESSAGE_ID_READ_VH_1] = 0x68018,
    124 	[MOD_HDCP_MESSAGE_ID_READ_VH_2] = 0x6801c,
    125 	[MOD_HDCP_MESSAGE_ID_READ_VH_3] = 0x68020,
    126 	[MOD_HDCP_MESSAGE_ID_READ_VH_4] = 0x68024,
    127 	[MOD_HDCP_MESSAGE_ID_READ_BCAPS] = 0x68028,
    128 	[MOD_HDCP_MESSAGE_ID_READ_BSTATUS] = 0x68029,
    129 	[MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO] = 0x6802c,
    130 	[MOD_HDCP_MESSAGE_ID_READ_BINFO] = 0x6802a,
    131 	[MOD_HDCP_MESSAGE_ID_RX_CAPS] = 0x6921d,
    132 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT] = 0x69000,
    133 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT] = 0x6900b,
    134 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM] = 0x69220,
    135 	[MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM] = 0x692a0,
    136 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME] = 0x692c0,
    137 	[MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO] = 0x692e0,
    138 	[MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT] = 0x692f0,
    139 	[MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME] = 0x692f8,
    140 	[MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS] = 0x69318,
    141 	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST] = 0x69330,
    142 	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK] = 0x693e0,
    143 	[MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE] = 0x693f0,
    144 	[MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY] = 0x69473,
    145 	[MOD_HDCP_MESSAGE_ID_READ_RXSTATUS] = 0x69493,
    146 	[MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE] = 0x69494
    147 };
    148 
    149 static enum mod_hdcp_status read(struct mod_hdcp *hdcp,
    150 		enum mod_hdcp_ddc_message_id msg_id,
    151 		uint8_t *buf,
    152 		uint32_t buf_len)
    153 {
    154 	bool success = true;
    155 	uint32_t cur_size = 0;
    156 	uint32_t data_offset = 0;
    157 
    158 	if (is_dp_hdcp(hdcp)) {
    159 		while (buf_len > 0) {
    160 			cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
    161 			success = hdcp->config.ddc.funcs.read_dpcd(hdcp->config.ddc.handle,
    162 					hdcp_dpcd_addrs[msg_id] + data_offset,
    163 					buf + data_offset,
    164 					cur_size);
    165 
    166 			if (!success)
    167 				break;
    168 
    169 			buf_len -= cur_size;
    170 			data_offset += cur_size;
    171 		}
    172 	} else {
    173 		success = hdcp->config.ddc.funcs.read_i2c(
    174 				hdcp->config.ddc.handle,
    175 				HDCP_I2C_ADDR,
    176 				hdcp_i2c_offsets[msg_id],
    177 				buf,
    178 				(uint32_t)buf_len);
    179 	}
    180 
    181 	return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
    182 }
    183 
    184 static enum mod_hdcp_status read_repeatedly(struct mod_hdcp *hdcp,
    185 		enum mod_hdcp_ddc_message_id msg_id,
    186 		uint8_t *buf,
    187 		uint32_t buf_len,
    188 		uint8_t read_size)
    189 {
    190 	enum mod_hdcp_status status = MOD_HDCP_STATUS_DDC_FAILURE;
    191 	uint32_t cur_size = 0;
    192 	uint32_t data_offset = 0;
    193 
    194 	while (buf_len > 0) {
    195 		cur_size = MIN(buf_len, read_size);
    196 		status = read(hdcp, msg_id, buf + data_offset, cur_size);
    197 
    198 		if (status != MOD_HDCP_STATUS_SUCCESS)
    199 			break;
    200 
    201 		buf_len -= cur_size;
    202 		data_offset += cur_size;
    203 	}
    204 
    205 	return status;
    206 }
    207 
    208 static enum mod_hdcp_status write(struct mod_hdcp *hdcp,
    209 		enum mod_hdcp_ddc_message_id msg_id,
    210 		uint8_t *buf,
    211 		uint32_t buf_len)
    212 {
    213 	bool success = true;
    214 	uint32_t cur_size = 0;
    215 	uint32_t data_offset = 0;
    216 
    217 	if (is_dp_hdcp(hdcp)) {
    218 		while (buf_len > 0) {
    219 			cur_size = MIN(buf_len, HDCP_MAX_AUX_TRANSACTION_SIZE);
    220 			success = hdcp->config.ddc.funcs.write_dpcd(
    221 					hdcp->config.ddc.handle,
    222 					hdcp_dpcd_addrs[msg_id] + data_offset,
    223 					buf + data_offset,
    224 					cur_size);
    225 
    226 			if (!success)
    227 				break;
    228 
    229 			buf_len -= cur_size;
    230 			data_offset += cur_size;
    231 		}
    232 	} else {
    233 		hdcp->buf[0] = hdcp_i2c_offsets[msg_id];
    234 		memmove(&hdcp->buf[1], buf, buf_len);
    235 		success = hdcp->config.ddc.funcs.write_i2c(
    236 				hdcp->config.ddc.handle,
    237 				HDCP_I2C_ADDR,
    238 				hdcp->buf,
    239 				(uint32_t)(buf_len+1));
    240 	}
    241 
    242 	return success ? MOD_HDCP_STATUS_SUCCESS : MOD_HDCP_STATUS_DDC_FAILURE;
    243 }
    244 
    245 enum mod_hdcp_status mod_hdcp_read_bksv(struct mod_hdcp *hdcp)
    246 {
    247 	return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BKSV,
    248 			hdcp->auth.msg.hdcp1.bksv,
    249 			sizeof(hdcp->auth.msg.hdcp1.bksv));
    250 }
    251 
    252 enum mod_hdcp_status mod_hdcp_read_bcaps(struct mod_hdcp *hdcp)
    253 {
    254 	return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BCAPS,
    255 			&hdcp->auth.msg.hdcp1.bcaps,
    256 			sizeof(hdcp->auth.msg.hdcp1.bcaps));
    257 }
    258 
    259 enum mod_hdcp_status mod_hdcp_read_bstatus(struct mod_hdcp *hdcp)
    260 {
    261 	enum mod_hdcp_status status;
    262 
    263 	if (is_dp_hdcp(hdcp))
    264 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
    265 					(uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,
    266 					1);
    267 	else
    268 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BSTATUS,
    269 				(uint8_t *)&hdcp->auth.msg.hdcp1.bstatus,
    270 				sizeof(hdcp->auth.msg.hdcp1.bstatus));
    271 	return status;
    272 }
    273 
    274 enum mod_hdcp_status mod_hdcp_read_r0p(struct mod_hdcp *hdcp)
    275 {
    276 	return read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RI_R0,
    277 			(uint8_t *)&hdcp->auth.msg.hdcp1.r0p,
    278 			sizeof(hdcp->auth.msg.hdcp1.r0p));
    279 }
    280 
    281 /* special case, reading repeatedly at the same address, don't use read() */
    282 enum mod_hdcp_status mod_hdcp_read_ksvlist(struct mod_hdcp *hdcp)
    283 {
    284 	enum mod_hdcp_status status;
    285 
    286 	if (is_dp_hdcp(hdcp))
    287 		status = read_repeatedly(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
    288 				hdcp->auth.msg.hdcp1.ksvlist,
    289 				hdcp->auth.msg.hdcp1.ksvlist_size,
    290 				KSV_READ_SIZE);
    291 	else
    292 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_KSV_FIFO,
    293 				(uint8_t *)&hdcp->auth.msg.hdcp1.ksvlist,
    294 				hdcp->auth.msg.hdcp1.ksvlist_size);
    295 	return status;
    296 }
    297 
    298 enum mod_hdcp_status mod_hdcp_read_vp(struct mod_hdcp *hdcp)
    299 {
    300 	enum mod_hdcp_status status;
    301 
    302 	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_0,
    303 			&hdcp->auth.msg.hdcp1.vp[0], 4);
    304 	if (status != MOD_HDCP_STATUS_SUCCESS)
    305 		goto out;
    306 
    307 	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_1,
    308 			&hdcp->auth.msg.hdcp1.vp[4], 4);
    309 	if (status != MOD_HDCP_STATUS_SUCCESS)
    310 		goto out;
    311 
    312 	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_2,
    313 			&hdcp->auth.msg.hdcp1.vp[8], 4);
    314 	if (status != MOD_HDCP_STATUS_SUCCESS)
    315 		goto out;
    316 
    317 	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_3,
    318 			&hdcp->auth.msg.hdcp1.vp[12], 4);
    319 	if (status != MOD_HDCP_STATUS_SUCCESS)
    320 		goto out;
    321 
    322 	status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_VH_4,
    323 			&hdcp->auth.msg.hdcp1.vp[16], 4);
    324 out:
    325 	return status;
    326 }
    327 
    328 enum mod_hdcp_status mod_hdcp_read_binfo(struct mod_hdcp *hdcp)
    329 {
    330 	enum mod_hdcp_status status;
    331 
    332 	if (is_dp_hdcp(hdcp))
    333 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_BINFO,
    334 				(uint8_t *)&hdcp->auth.msg.hdcp1.binfo_dp,
    335 				sizeof(hdcp->auth.msg.hdcp1.binfo_dp));
    336 	else
    337 		status = MOD_HDCP_STATUS_INVALID_OPERATION;
    338 
    339 	return status;
    340 }
    341 
    342 enum mod_hdcp_status mod_hdcp_write_aksv(struct mod_hdcp *hdcp)
    343 {
    344 	return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKSV,
    345 			hdcp->auth.msg.hdcp1.aksv,
    346 			sizeof(hdcp->auth.msg.hdcp1.aksv));
    347 }
    348 
    349 enum mod_hdcp_status mod_hdcp_write_ainfo(struct mod_hdcp *hdcp)
    350 {
    351 	return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AINFO,
    352 			&hdcp->auth.msg.hdcp1.ainfo,
    353 			sizeof(hdcp->auth.msg.hdcp1.ainfo));
    354 }
    355 
    356 enum mod_hdcp_status mod_hdcp_write_an(struct mod_hdcp *hdcp)
    357 {
    358 	return write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AN,
    359 			hdcp->auth.msg.hdcp1.an,
    360 			sizeof(hdcp->auth.msg.hdcp1.an));
    361 }
    362 
    363 enum mod_hdcp_status mod_hdcp_read_hdcp2version(struct mod_hdcp *hdcp)
    364 {
    365 	enum mod_hdcp_status status;
    366 
    367 	if (is_dp_hdcp(hdcp))
    368 		status = MOD_HDCP_STATUS_INVALID_OPERATION;
    369 	else
    370 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_HDCP2VERSION,
    371 				&hdcp->auth.msg.hdcp2.hdcp2version_hdmi,
    372 				sizeof(hdcp->auth.msg.hdcp2.hdcp2version_hdmi));
    373 
    374 	return status;
    375 }
    376 
    377 enum mod_hdcp_status mod_hdcp_read_rxcaps(struct mod_hdcp *hdcp)
    378 {
    379 	enum mod_hdcp_status status;
    380 
    381 	if (!is_dp_hdcp(hdcp))
    382 		status = MOD_HDCP_STATUS_INVALID_OPERATION;
    383 	else
    384 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_RX_CAPS,
    385 				hdcp->auth.msg.hdcp2.rxcaps_dp,
    386 				sizeof(hdcp->auth.msg.hdcp2.rxcaps_dp));
    387 
    388 	return status;
    389 }
    390 
    391 enum mod_hdcp_status mod_hdcp_read_rxstatus(struct mod_hdcp *hdcp)
    392 {
    393 	enum mod_hdcp_status status;
    394 
    395 	if (is_dp_hdcp(hdcp)) {
    396 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
    397 				&hdcp->auth.msg.hdcp2.rxstatus_dp,
    398 				1);
    399 	} else {
    400 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_RXSTATUS,
    401 					(uint8_t *)&hdcp->auth.msg.hdcp2.rxstatus,
    402 					sizeof(hdcp->auth.msg.hdcp2.rxstatus));
    403 	}
    404 	return status;
    405 }
    406 
    407 enum mod_hdcp_status mod_hdcp_read_ake_cert(struct mod_hdcp *hdcp)
    408 {
    409 	enum mod_hdcp_status status;
    410 
    411 	if (is_dp_hdcp(hdcp)) {
    412 		hdcp->auth.msg.hdcp2.ake_cert[0] = 3;
    413 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
    414 				hdcp->auth.msg.hdcp2.ake_cert+1,
    415 				sizeof(hdcp->auth.msg.hdcp2.ake_cert)-1);
    416 
    417 	} else {
    418 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_CERT,
    419 					hdcp->auth.msg.hdcp2.ake_cert,
    420 					sizeof(hdcp->auth.msg.hdcp2.ake_cert));
    421 	}
    422 	return status;
    423 }
    424 
    425 enum mod_hdcp_status mod_hdcp_read_h_prime(struct mod_hdcp *hdcp)
    426 {
    427 	enum mod_hdcp_status status;
    428 
    429 	if (is_dp_hdcp(hdcp)) {
    430 		hdcp->auth.msg.hdcp2.ake_h_prime[0] = 7;
    431 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
    432 				hdcp->auth.msg.hdcp2.ake_h_prime+1,
    433 				sizeof(hdcp->auth.msg.hdcp2.ake_h_prime)-1);
    434 
    435 	} else {
    436 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_H_PRIME,
    437 				hdcp->auth.msg.hdcp2.ake_h_prime,
    438 				sizeof(hdcp->auth.msg.hdcp2.ake_h_prime));
    439 	}
    440 	return status;
    441 }
    442 
    443 enum mod_hdcp_status mod_hdcp_read_pairing_info(struct mod_hdcp *hdcp)
    444 {
    445 	enum mod_hdcp_status status;
    446 
    447 	if (is_dp_hdcp(hdcp)) {
    448 		hdcp->auth.msg.hdcp2.ake_pairing_info[0] = 8;
    449 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
    450 				hdcp->auth.msg.hdcp2.ake_pairing_info+1,
    451 				sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info)-1);
    452 
    453 	} else {
    454 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_AKE_SEND_PAIRING_INFO,
    455 				hdcp->auth.msg.hdcp2.ake_pairing_info,
    456 				sizeof(hdcp->auth.msg.hdcp2.ake_pairing_info));
    457 	}
    458 	return status;
    459 }
    460 
    461 enum mod_hdcp_status mod_hdcp_read_l_prime(struct mod_hdcp *hdcp)
    462 {
    463 	enum mod_hdcp_status status;
    464 
    465 	if (is_dp_hdcp(hdcp)) {
    466 		hdcp->auth.msg.hdcp2.lc_l_prime[0] = 10;
    467 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
    468 				hdcp->auth.msg.hdcp2.lc_l_prime+1,
    469 				sizeof(hdcp->auth.msg.hdcp2.lc_l_prime)-1);
    470 
    471 	} else {
    472 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_LC_SEND_L_PRIME,
    473 				hdcp->auth.msg.hdcp2.lc_l_prime,
    474 				sizeof(hdcp->auth.msg.hdcp2.lc_l_prime));
    475 	}
    476 	return status;
    477 }
    478 
    479 enum mod_hdcp_status mod_hdcp_read_rx_id_list(struct mod_hdcp *hdcp)
    480 {
    481 	enum mod_hdcp_status status;
    482 
    483 	if (is_dp_hdcp(hdcp)) {
    484 		hdcp->auth.msg.hdcp2.rx_id_list[0] = 12;
    485 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
    486 				hdcp->auth.msg.hdcp2.rx_id_list+1,
    487 				sizeof(hdcp->auth.msg.hdcp2.rx_id_list)-1);
    488 
    489 	} else {
    490 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_SEND_RECEIVERID_LIST,
    491 				hdcp->auth.msg.hdcp2.rx_id_list,
    492 				hdcp->auth.msg.hdcp2.rx_id_list_size);
    493 	}
    494 	return status;
    495 }
    496 
    497 enum mod_hdcp_status mod_hdcp_read_stream_ready(struct mod_hdcp *hdcp)
    498 {
    499 	enum mod_hdcp_status status;
    500 
    501 	if (is_dp_hdcp(hdcp)) {
    502 		hdcp->auth.msg.hdcp2.repeater_auth_stream_ready[0] = 17;
    503 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
    504 				hdcp->auth.msg.hdcp2.repeater_auth_stream_ready+1,
    505 				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready)-1);
    506 
    507 	} else {
    508 		status = read(hdcp, MOD_HDCP_MESSAGE_ID_READ_REPEATER_AUTH_STREAM_READY,
    509 				hdcp->auth.msg.hdcp2.repeater_auth_stream_ready,
    510 				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_stream_ready));
    511 	}
    512 	return status;
    513 }
    514 
    515 enum mod_hdcp_status mod_hdcp_write_ake_init(struct mod_hdcp *hdcp)
    516 {
    517 	enum mod_hdcp_status status;
    518 
    519 	if (is_dp_hdcp(hdcp))
    520 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
    521 				hdcp->auth.msg.hdcp2.ake_init+1,
    522 				sizeof(hdcp->auth.msg.hdcp2.ake_init)-1);
    523 	else
    524 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_INIT,
    525 					hdcp->auth.msg.hdcp2.ake_init,
    526 					sizeof(hdcp->auth.msg.hdcp2.ake_init));
    527 	return status;
    528 }
    529 
    530 enum mod_hdcp_status mod_hdcp_write_no_stored_km(struct mod_hdcp *hdcp)
    531 {
    532 	enum mod_hdcp_status status;
    533 
    534 	if (is_dp_hdcp(hdcp))
    535 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
    536 				hdcp->auth.msg.hdcp2.ake_no_stored_km+1,
    537 				sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km)-1);
    538 	else
    539 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_NO_STORED_KM,
    540 			hdcp->auth.msg.hdcp2.ake_no_stored_km,
    541 			sizeof(hdcp->auth.msg.hdcp2.ake_no_stored_km));
    542 	return status;
    543 }
    544 
    545 enum mod_hdcp_status mod_hdcp_write_stored_km(struct mod_hdcp *hdcp)
    546 {
    547 	enum mod_hdcp_status status;
    548 
    549 	if (is_dp_hdcp(hdcp))
    550 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
    551 				hdcp->auth.msg.hdcp2.ake_stored_km+1,
    552 				sizeof(hdcp->auth.msg.hdcp2.ake_stored_km)-1);
    553 	else
    554 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_AKE_STORED_KM,
    555 				hdcp->auth.msg.hdcp2.ake_stored_km,
    556 				sizeof(hdcp->auth.msg.hdcp2.ake_stored_km));
    557 	return status;
    558 }
    559 
    560 enum mod_hdcp_status mod_hdcp_write_lc_init(struct mod_hdcp *hdcp)
    561 {
    562 	enum mod_hdcp_status status;
    563 
    564 	if (is_dp_hdcp(hdcp))
    565 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
    566 				hdcp->auth.msg.hdcp2.lc_init+1,
    567 				sizeof(hdcp->auth.msg.hdcp2.lc_init)-1);
    568 	else
    569 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_LC_INIT,
    570 				hdcp->auth.msg.hdcp2.lc_init,
    571 				sizeof(hdcp->auth.msg.hdcp2.lc_init));
    572 	return status;
    573 }
    574 
    575 enum mod_hdcp_status mod_hdcp_write_eks(struct mod_hdcp *hdcp)
    576 {
    577 	enum mod_hdcp_status status;
    578 
    579 	if (is_dp_hdcp(hdcp))
    580 		status = write(hdcp,
    581 				MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
    582 				hdcp->auth.msg.hdcp2.ske_eks+1,
    583 				sizeof(hdcp->auth.msg.hdcp2.ske_eks)-1);
    584 	else
    585 		status = write(hdcp,
    586 			MOD_HDCP_MESSAGE_ID_WRITE_SKE_SEND_EKS,
    587 			hdcp->auth.msg.hdcp2.ske_eks,
    588 			sizeof(hdcp->auth.msg.hdcp2.ske_eks));
    589 	return status;
    590 }
    591 
    592 enum mod_hdcp_status mod_hdcp_write_repeater_auth_ack(struct mod_hdcp *hdcp)
    593 {
    594 	enum mod_hdcp_status status;
    595 
    596 	if (is_dp_hdcp(hdcp))
    597 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
    598 				hdcp->auth.msg.hdcp2.repeater_auth_ack+1,
    599 				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack)-1);
    600 	else
    601 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_SEND_ACK,
    602 				hdcp->auth.msg.hdcp2.repeater_auth_ack,
    603 				sizeof(hdcp->auth.msg.hdcp2.repeater_auth_ack));
    604 	return status;
    605 }
    606 
    607 enum mod_hdcp_status mod_hdcp_write_stream_manage(struct mod_hdcp *hdcp)
    608 {
    609 	enum mod_hdcp_status status;
    610 
    611 	if (is_dp_hdcp(hdcp))
    612 		status = write(hdcp,
    613 				MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
    614 				hdcp->auth.msg.hdcp2.repeater_auth_stream_manage+1,
    615 				hdcp->auth.msg.hdcp2.stream_manage_size-1);
    616 	else
    617 		status = write(hdcp,
    618 				MOD_HDCP_MESSAGE_ID_WRITE_REPEATER_AUTH_STREAM_MANAGE,
    619 				hdcp->auth.msg.hdcp2.repeater_auth_stream_manage,
    620 				hdcp->auth.msg.hdcp2.stream_manage_size);
    621 	return status;
    622 }
    623 
    624 enum mod_hdcp_status mod_hdcp_write_content_type(struct mod_hdcp *hdcp)
    625 {
    626 	enum mod_hdcp_status status;
    627 
    628 	if (is_dp_hdcp(hdcp))
    629 		status = write(hdcp, MOD_HDCP_MESSAGE_ID_WRITE_CONTENT_STREAM_TYPE,
    630 				hdcp->auth.msg.hdcp2.content_stream_type_dp+1,
    631 				sizeof(hdcp->auth.msg.hdcp2.content_stream_type_dp)-1);
    632 	else
    633 		status = MOD_HDCP_STATUS_INVALID_OPERATION;
    634 	return status;
    635 }
    636