summaryrefslogtreecommitdiff
path: root/exynos-hdcp2-dplink-if.c
blob: e5e7a9b5d49c6b490ad43467d2977d65ca99817c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * drivers/soc/samsung/exynos_hdcp/dp_link/exynos-hdcp2-dplink-if.c
 *
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <net/sock.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/module.h>
#include "exynos-hdcp2-log.h"
#include "exynos-hdcp2-dplink-reg.h"
#include "exynos-hdcp2-dplink-if.h"

static void (*pdp_hdcp22_enable)(u32 en);
static int (*pdp_dpcd_read_for_hdcp22)(u32 address, u32 length, u8 *data);
static int (*pdp_dpcd_write_for_hdcp22)(u32 address, u32 length, u8 *data);

/* Address define for HDCP within DPCD address space */
static uint32_t dpcd_addr[NUM_HDCP22_MSG_NAME] = {
	DPCD_ADDR_HDCP22_Rtx,
	DPCD_ADDR_HDCP22_TxCaps,
	DPCD_ADDR_HDCP22_cert_rx,
	DPCD_ADDR_HDCP22_Rrx,
	DPCD_ADDR_HDCP22_RxCaps,
	DPCD_ADDR_HDCP22_Ekpub_km,
	DPCD_ADDR_HDCP22_Ekh_km_w,
	DPCD_ADDR_HDCP22_m,
	DPCD_ADDR_HDCP22_Hprime,
	DPCD_ADDR_HDCP22_Ekh_km_r,
	DPCD_ADDR_HDCP22_rn,
	DPCD_ADDR_HDCP22_Lprime,
	DPCD_ADDR_HDCP22_Edkey0_ks,
	DPCD_ADDR_HDCP22_Edkey1_ks,
	DPCD_ADDR_HDCP22_riv,
	DPCD_ADDR_HDCP22_RxInfo,
	DPCD_ADDR_HDCP22_seq_num_V,
	DPCD_ADDR_HDCP22_Vprime,
	DPCD_ADDR_HDCP22_Rec_ID_list,
	DPCD_ADDR_HDCP22_V,
	DPCD_ADDR_HDCP22_seq_num_M,
	DPCD_ADDR_HDCP22_k,
	DPCD_ADDR_HDCP22_stream_IDtype,
	DPCD_ADDR_HDCP22_Mprime,
	DPCD_ADDR_HDCP22_RxStatus,
	DPCD_ADDR_HDCP22_Type,
};

void hdcp_dplink_config(int en)
{
	pdp_hdcp22_enable(en);
}

int hdcp_dplink_is_enabled_hdcp22(void)
{
	/* todo: check hdcp22 enable */
	return 1;
}

/* todo: get stream info from DP */
#define HDCP_DP_STREAM_NUM	0x01
static uint8_t stream_id[1] = {0x00};
int hdcp_dplink_get_stream_info(uint16_t *num, uint8_t *strm_id)
{
	*num = HDCP_DP_STREAM_NUM;
	memcpy(strm_id, stream_id, sizeof(uint8_t) * (*num));

	return 0;
}

int hdcp_dplink_recv(uint32_t msg_name, uint8_t *data, uint32_t size)
{
	int i;
	int ret;
	int remain;

	if (size > DPCD_PACKET_SIZE) {
		for (i = 0; i < (size / DPCD_PACKET_SIZE); i++) {
			ret = pdp_dpcd_read_for_hdcp22(
				dpcd_addr[msg_name] + i * DPCD_PACKET_SIZE,
				DPCD_PACKET_SIZE,
				&data[i * DPCD_PACKET_SIZE]);
			if (ret) {
				hdcp_err("dpcd read fail. ret(%d)\n", ret);
				return ret;
			}
		}

		remain = size % DPCD_PACKET_SIZE;
		if (remain) {
			ret = pdp_dpcd_read_for_hdcp22(
				dpcd_addr[msg_name] + i * DPCD_PACKET_SIZE,
				remain,
				&data[i * DPCD_PACKET_SIZE]);
			if (ret) {
				hdcp_err("dpcd read fail. ret(%d)\n", ret);
				return ret;
			}
		}
		return 0;
	} else
		return pdp_dpcd_read_for_hdcp22(dpcd_addr[msg_name], size, data);
}

int hdcp_dplink_send(uint32_t msg_name, uint8_t *data, uint32_t size)
{
	int i;
	int ret;

	if (size > DPCD_PACKET_SIZE) {
		for (i = 0; i < (size / DPCD_PACKET_SIZE); i++) {
			ret = pdp_dpcd_write_for_hdcp22(
				dpcd_addr[msg_name] + i * DPCD_PACKET_SIZE,
				DPCD_PACKET_SIZE,
				&data[i * DPCD_PACKET_SIZE]);
			if (ret) {
				hdcp_err("dpcd write fail. ret(%d)\n", ret);
				return ret;
			}
		}
		return 0;
	}
	else
		return pdp_dpcd_write_for_hdcp22(dpcd_addr[msg_name], size, data);
}

void dp_register_func_for_hdcp22(void (*func0)(u32 en), int (*func1)(u32 address, u32 length, u8 *data), int (*func2)(u32 address, u32 length, u8 *data))
{
	pdp_hdcp22_enable = func0;
	pdp_dpcd_read_for_hdcp22 = func1;
	pdp_dpcd_write_for_hdcp22 = func2;
}
EXPORT_SYMBOL_GPL(dp_register_func_for_hdcp22);