1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/errno.h>
4 #include <linux/string.h>
5 #include <linux/miscdevice.h>
6 #include <linux/workqueue.h>
7 #include <linux/firmware.h>
8 #include "rk616_hdmi.h"
9 #include "rk616_hdcp.h"
11 struct hdcp *hdcp = NULL;
13 static void hdcp_work_queue(struct work_struct *work);
15 /*-----------------------------------------------------------------------------
16 * Function: hdcp_submit_work
17 *-----------------------------------------------------------------------------
19 static struct delayed_work *hdcp_submit_work(int event, int delay)
21 struct hdcp_delayed_work *work;
23 DBG("%s event %04x delay %d", __FUNCTION__, event, delay);
25 work = kmalloc(sizeof(struct hdcp_delayed_work), GFP_ATOMIC);
28 INIT_DELAYED_WORK(&work->work, hdcp_work_queue);
30 queue_delayed_work(hdcp->workqueue,
32 msecs_to_jiffies(delay));
34 printk(KERN_WARNING "HDCP: Cannot allocate memory to "
42 /*-----------------------------------------------------------------------------
43 * Function: hdcp_cancel_work
44 *-----------------------------------------------------------------------------
46 static void hdcp_cancel_work(struct delayed_work **work)
51 ret = cancel_delayed_work(*work);
53 ret = cancel_work_sync(&((*work)->work));
54 printk(KERN_INFO "Canceling work failed - "
55 "cancel_work_sync done %d\n", ret);
62 /*-----------------------------------------------------------------------------
63 * Function: hdcp_wq_authentication_failure
64 *-----------------------------------------------------------------------------
66 static void hdcp_wq_authentication_failure(void)
68 if (hdcp->hdmi_state == HDMI_STOPPED) {
73 rk616_hdmi_control_output(false);
75 hdcp_cancel_work(&hdcp->pending_wq_event);
77 if (hdcp->retry_cnt && (hdcp->hdmi_state != HDMI_STOPPED)) {
78 if (hdcp->retry_cnt < HDCP_INFINITE_REAUTH) {
80 printk(KERN_INFO "HDCP: authentication failed - "
81 "retrying, attempts=%d\n",
84 printk(KERN_INFO "HDCP: authentication failed - "
87 hdcp->hdcp_state = HDCP_AUTHENTICATION_START;
89 hdcp->pending_wq_event = hdcp_submit_work(HDCP_AUTH_REATT_EVENT,
92 printk(KERN_INFO "HDCP: authentication failed - "
94 hdcp->hdcp_state = HDCP_ENABLE_PENDING;
99 /*-----------------------------------------------------------------------------
100 * Function: hdcp_wq_start_authentication
101 *-----------------------------------------------------------------------------
103 static void hdcp_wq_start_authentication(void)
105 int status = HDCP_OK;
107 hdcp->hdcp_state = HDCP_AUTHENTICATION_START;
109 DBG("HDCP: authentication start");
111 status = rk616_hdcp_start_authentication();
113 if (status != HDCP_OK) {
114 DBG("HDCP: authentication failed");
115 hdcp_wq_authentication_failure();
117 hdcp->hdcp_state = HDCP_WAIT_KSV_LIST;
118 // hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK;
122 /*-----------------------------------------------------------------------------
123 * Function: hdcp_wq_check_bksv
124 *-----------------------------------------------------------------------------
126 static void hdcp_wq_check_bksv(void)
128 int status = HDCP_OK;
130 DBG("Check BKSV start");
132 status = rk616_hdcp_check_bksv();
134 if (status != HDCP_OK) {
135 printk(KERN_INFO "HDCP: Check BKSV failed");
137 hdcp_wq_authentication_failure();
140 DBG("HDCP: Check BKSV successful");
142 hdcp->hdcp_state = HDCP_LINK_INTEGRITY_CHECK;
144 /* Restore retry counter */
145 if(hdcp->retry_times == 0)
146 hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
148 hdcp->retry_cnt = hdcp->retry_times;
152 /*-----------------------------------------------------------------------------
153 * Function: hdcp_wq_authentication_sucess
154 *-----------------------------------------------------------------------------
156 static void hdcp_wq_authentication_sucess(void)
158 rk616_hdmi_control_output(true);
159 printk(KERN_INFO "HDCP: authentication pass");
162 /*-----------------------------------------------------------------------------
163 * Function: hdcp_wq_disable
164 *-----------------------------------------------------------------------------
166 static void hdcp_wq_disable(int event)
168 printk(KERN_INFO "HDCP: disabled");
170 hdcp_cancel_work(&hdcp->pending_wq_event);
171 rk616_hdcp_disable();
172 if(event == HDCP_DISABLE_CTL) {
173 hdcp->hdcp_state = HDCP_DISABLED;
174 if(hdcp->hdmi_state == HDMI_STARTED)
175 rk616_hdmi_control_output(true);
177 else if(event == HDCP_STOP_FRAME_EVENT)
178 hdcp->hdcp_state = HDCP_ENABLE_PENDING;
181 /*-----------------------------------------------------------------------------
182 * Function: hdcp_work_queue
183 *-----------------------------------------------------------------------------
185 static void hdcp_work_queue(struct work_struct *work)
187 struct hdcp_delayed_work *hdcp_w =
188 container_of(work, struct hdcp_delayed_work, work.work);
189 int event = hdcp_w->event;
191 mutex_lock(&hdcp->lock);
193 DBG("hdcp_work_queue() - START - %u hdmi=%d hdcp=%d evt= %x %d",
194 jiffies_to_msecs(jiffies),
197 (event & 0xFF00) >> 8,
200 if(event == HDCP_STOP_FRAME_EVENT) {
201 hdcp->hdmi_state = HDMI_STOPPED;
204 if (event == HDCP_DISABLE_CTL || event == HDCP_STOP_FRAME_EVENT) {
205 hdcp_wq_disable(event);
208 if (event & HDCP_WORKQUEUE_SRC)
209 hdcp->pending_wq_event = 0;
211 /* First handle HDMI state */
212 if (event == HDCP_START_FRAME_EVENT) {
213 hdcp->pending_start = 0;
214 hdcp->hdmi_state = HDMI_STARTED;
217 /**********************/
218 /* HDCP state machine */
219 /**********************/
220 switch (hdcp->hdcp_state) {
222 /* HDCP enable control or re-authentication event */
223 if (event == HDCP_ENABLE_CTL) {
224 if(hdcp->retry_times == 0)
225 hdcp->retry_cnt = HDCP_INFINITE_REAUTH;
227 hdcp->retry_cnt = hdcp->retry_times;
228 if (hdcp->hdmi_state == HDMI_STARTED)
229 hdcp_wq_start_authentication();
231 hdcp->hdcp_state = HDCP_ENABLE_PENDING;
235 case HDCP_ENABLE_PENDING:
236 /* HDMI start frame event */
237 if (event == HDCP_START_FRAME_EVENT)
238 hdcp_wq_start_authentication();
242 case HDCP_AUTHENTICATION_START:
243 /* Re-authentication */
244 if (event == HDCP_AUTH_REATT_EVENT)
245 hdcp_wq_start_authentication();
249 case HDCP_WAIT_KSV_LIST:
251 if (event == HDCP_FAIL_EVENT) {
252 printk(KERN_INFO "HDCP: KSV switch failure\n");
254 hdcp_wq_authentication_failure();
256 /* KSV list ready event */
257 else if (event == HDCP_KSV_LIST_RDY_EVENT)
258 hdcp_wq_check_bksv();
261 case HDCP_LINK_INTEGRITY_CHECK:
263 if (event == HDCP_FAIL_EVENT) {
264 printk(KERN_INFO "HDCP: Ri check failure\n");
265 hdcp_wq_authentication_failure();
267 else if(event == HDCP_AUTH_PASS_EVENT)
268 hdcp_wq_authentication_sucess();
272 printk(KERN_WARNING "HDCP: error - unknow HDCP state\n");
277 if(event == HDCP_STOP_FRAME_EVENT)
278 complete(&hdcp->complete);
280 mutex_unlock(&hdcp->lock);
283 /*-----------------------------------------------------------------------------
284 * Function: hdcp_start_frame_cb
285 *-----------------------------------------------------------------------------
287 static void hdcp_start_frame_cb(void)
289 DBG("hdcp_start_frame_cb()");
291 /* Cancel any pending work */
292 if (hdcp->pending_start)
293 hdcp_cancel_work(&hdcp->pending_start);
294 if (hdcp->pending_wq_event)
295 hdcp_cancel_work(&hdcp->pending_wq_event);
297 hdcp->pending_start = hdcp_submit_work(HDCP_START_FRAME_EVENT,
301 /*-----------------------------------------------------------------------------
302 * Function: hdcp_irq_cb
303 *-----------------------------------------------------------------------------
305 static void hdcp_irq_cb(int status)
310 rk616_hdcp_interrupt(&interrupt1, &interrupt2);
311 DBG("%s 0x%02x 0x%02x", __FUNCTION__, interrupt1, interrupt2);
312 if(interrupt1 & m_INT_HDCP_ERR)
314 if( (hdcp->hdcp_state != HDCP_DISABLED) &&
315 (hdcp->hdcp_state != HDCP_ENABLE_PENDING) )
317 hdcp_submit_work(HDCP_FAIL_EVENT, 0);
320 else if(interrupt1 & (m_INT_BKSV_READY | m_INT_BKSV_UPDATE))
321 hdcp_submit_work(HDCP_KSV_LIST_RDY_EVENT, 0);
322 else if(interrupt1 & m_INT_AUTH_SUCCESS)
323 hdcp_submit_work(HDCP_AUTH_PASS_EVENT, 0);
326 /*-----------------------------------------------------------------------------
327 * Function: hdcp_power_on_cb
328 *-----------------------------------------------------------------------------
330 static int hdcp_power_on_cb(void)
332 DBG("%s", __FUNCTION__);
333 // return rk616_hdcp_load_key2mem(hdcp->keys);
337 /*-----------------------------------------------------------------------------
338 * Function: hdcp_power_off_cb
339 *-----------------------------------------------------------------------------
341 static void hdcp_power_off_cb(void)
343 DBG("%s", __FUNCTION__);
347 hdcp_cancel_work(&hdcp->pending_start);
348 hdcp_cancel_work(&hdcp->pending_wq_event);
349 init_completion(&hdcp->complete);
350 /* Post event to workqueue */
351 if (hdcp_submit_work(HDCP_STOP_FRAME_EVENT, 0))
352 wait_for_completion_interruptible_timeout(&hdcp->complete,
353 msecs_to_jiffies(5000));
356 // Load HDCP key to external HDCP memory
357 static void hdcp_load_keys_cb(const struct firmware *fw, void *context)
360 pr_err("HDCP: failed to load keys\n");
364 if(fw->size < HDCP_KEY_SIZE) {
365 pr_err("HDCP: firmware wrong size %d\n", fw->size);
369 hdcp->keys = kmalloc(HDCP_KEY_SIZE, GFP_KERNEL);
370 if(hdcp->keys == NULL) {
371 pr_err("HDCP: can't allocated space for keys\n");
375 memcpy(hdcp->keys, fw->data, HDCP_KEY_SIZE);
377 printk(KERN_INFO "HDCP: load hdcp key success\n");
379 if(fw->size > HDCP_KEY_SIZE) {
380 DBG("%s invalid key size %d", __FUNCTION__, fw->size - HDCP_KEY_SIZE);
381 if((fw->size - HDCP_KEY_SIZE) % 5) {
382 pr_err("HDCP: failed to load invalid keys\n");
385 hdcp->invalidkeys = kmalloc(fw->size - HDCP_KEY_SIZE, GFP_KERNEL);
386 if(hdcp->invalidkeys == NULL) {
387 pr_err("HDCP: can't allocated space for invalid keys\n");
390 memcpy(hdcp->invalidkeys, fw->data + HDCP_KEY_SIZE, fw->size - HDCP_KEY_SIZE);
391 hdcp->invalidkey = (fw->size - HDCP_KEY_SIZE)/5;
392 printk(KERN_INFO "HDCP: loaded hdcp invalid key success\n");
396 static ssize_t hdcp_enable_read(struct device *device,
397 struct device_attribute *attr, char *buf)
402 enable = hdcp->enable;
404 return snprintf(buf, PAGE_SIZE, "%d\n", enable);
407 static ssize_t hdcp_enable_write(struct device *device,
408 struct device_attribute *attr, const char *buf, size_t count)
415 sscanf(buf, "%d", &enable);
416 if(hdcp->enable != enable)
418 /* Post event to workqueue */
420 if (hdcp_submit_work(HDCP_ENABLE_CTL, 0) == 0)
424 hdcp_cancel_work(&hdcp->pending_start);
425 hdcp_cancel_work(&hdcp->pending_wq_event);
427 /* Post event to workqueue */
428 if (hdcp_submit_work(HDCP_DISABLE_CTL, 0) == 0)
431 hdcp->enable = enable;
436 static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, hdcp_enable_read, hdcp_enable_write);
438 static ssize_t hdcp_trytimes_read(struct device *device,
439 struct device_attribute *attr, char *buf)
444 trytimes = hdcp->retry_times;
446 return snprintf(buf, PAGE_SIZE, "%d\n", trytimes);
449 static ssize_t hdcp_trytimes_wrtie(struct device *device,
450 struct device_attribute *attr, const char *buf, size_t count)
457 sscanf(buf, "%d", &trytimes);
458 if(hdcp->retry_times != trytimes)
459 hdcp->retry_times = trytimes;
465 static DEVICE_ATTR(trytimes, S_IRUGO|S_IWUSR, hdcp_trytimes_read, hdcp_trytimes_wrtie);
468 static struct miscdevice mdev;
470 static int __init rk616_hdcp_init(void)
474 DBG("[%s] %u", __FUNCTION__, jiffies_to_msecs(jiffies));
476 hdcp = kmalloc(sizeof(struct hdcp), GFP_KERNEL);
479 printk(KERN_ERR ">>HDCP: kmalloc fail!");
483 memset(hdcp, 0, sizeof(struct hdcp));
484 mutex_init(&hdcp->lock);
486 mdev.minor = MISC_DYNAMIC_MINOR;
489 if (misc_register(&mdev)) {
490 printk(KERN_ERR "HDCP: Could not add character driver\n");
491 ret = HDMI_ERROR_FALSE;
494 ret = device_create_file(mdev.this_device, &dev_attr_enable);
497 printk(KERN_ERR "HDCP: Could not add sys file enable\n");
502 ret = device_create_file(mdev.this_device, &dev_attr_trytimes);
505 printk(KERN_ERR "HDCP: Could not add sys file trytimes\n");
510 hdcp->workqueue = create_singlethread_workqueue("hdcp");
511 if (hdcp->workqueue == NULL) {
512 printk(KERN_ERR "HDCP,: create workqueue failed.\n");
517 ret = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG,
518 "hdcp.keys", mdev.this_device, GFP_KERNEL,
519 hdcp, hdcp_load_keys_cb);
521 printk(KERN_ERR "HDCP: request_firmware_nowait failed: %d\n", ret);
525 rk616_hdmi_register_hdcp_callbacks(hdcp_start_frame_cb,
530 DBG("%s success %u", __FUNCTION__, jiffies_to_msecs(jiffies));
534 destroy_workqueue(hdcp->workqueue);
536 device_remove_file(mdev.this_device, &dev_attr_trytimes);
538 device_remove_file(mdev.this_device, &dev_attr_enable);
540 misc_deregister(&mdev);
544 if(hdcp->invalidkeys)
545 kfree(hdcp->invalidkeys);
551 static void __exit rk616_hdcp_exit(void)
553 device_remove_file(mdev.this_device, &dev_attr_enable);
554 misc_deregister(&mdev);
557 if(hdcp->invalidkeys)
558 kfree(hdcp->invalidkeys);
562 module_init(rk616_hdcp_init);
563 module_exit(rk616_hdcp_exit);