Linux Audio

Check our new training course

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