blob: 0900f23ba0e8df0fac813114b3043f0399c2ad0b [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/i2c.h>
14#include <linux/types.h>
15#include <linux/bitops.h>
16#include <linux/adv7520.h>
17#include <linux/time.h>
18#include <linux/completion.h>
19#include <linux/wakelock.h>
20#include <asm/atomic.h>
21#include "msm_fb.h"
22
23#define DEBUG
24#define DEV_DBG_PREFIX "HDMI: "
25
26#include "external_common.h"
27
28/* #define PORT_DEBUG */
29/* #define TESTING_FORCE_480p */
30
31#define HPD_DUTY_CYCLE 4 /*secs*/
32
33static struct external_common_state_type hdmi_common;
34
35static struct i2c_client *hclient;
36
37static bool chip_power_on = FALSE; /* For chip power on/off */
38static bool enable_5v_on = FALSE;
39static bool hpd_power_on = FALSE;
40static atomic_t comm_power_on; /* For dtv power on/off (I2C) */
41static int suspend_count;
42
43static u8 reg[256]; /* HDMI panel registers */
44
45struct hdmi_data {
46 struct msm_hdmi_platform_data *pd;
47 struct work_struct isr_work;
48};
49static struct hdmi_data *dd;
50static struct work_struct hpd_timer_work;
51
52#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
53static struct work_struct hdcp_handle_work;
54static int hdcp_activating;
55static DEFINE_MUTEX(hdcp_state_mutex);
56static int has_hdcp_hw_support = true;
57#endif
58
59static struct timer_list hpd_timer;
60static struct timer_list hpd_duty_timer;
61static struct work_struct hpd_duty_work;
62static unsigned int monitor_sense;
63static boolean hpd_cable_chg_detected;
64
65struct wake_lock wlock;
66
67/* Change HDMI state */
68static void change_hdmi_state(int online)
69{
70 if (!external_common_state)
71 return;
72
73 mutex_lock(&external_common_state_hpd_mutex);
74 external_common_state->hpd_state = online;
75 mutex_unlock(&external_common_state_hpd_mutex);
76
77 if (!external_common_state->uevent_kobj)
78 return;
79
80 if (online)
81 kobject_uevent(external_common_state->uevent_kobj,
82 KOBJ_ONLINE);
83 else
84 kobject_uevent(external_common_state->uevent_kobj,
85 KOBJ_OFFLINE);
86 DEV_INFO("adv7520_uevent: %d [suspend# %d]\n", online, suspend_count);
87}
88
89
90/*
91 * Read a value from a register on ADV7520 device
92 * If sucessfull returns value read , otherwise error.
93 */
94static u8 adv7520_read_reg(struct i2c_client *client, u8 reg)
95{
96 int err;
97 struct i2c_msg msg[2];
98 u8 reg_buf[] = { reg };
99 u8 data_buf[] = { 0 };
100
101 if (!client->adapter)
102 return -ENODEV;
103 if (!atomic_read(&comm_power_on)) {
104 DEV_WARN("%s: WARN: missing GPIO power\n", __func__);
105 return -ENODEV;
106 }
107
108 msg[0].addr = client->addr;
109 msg[0].flags = 0;
110 msg[0].len = 1;
111 msg[0].buf = reg_buf;
112
113 msg[1].addr = client->addr;
114 msg[1].flags = I2C_M_RD;
115 msg[1].len = 1;
116 msg[1].buf = data_buf;
117
118 err = i2c_transfer(client->adapter, msg, 2);
119
120 if (err < 0) {
121 DEV_INFO("%s: I2C err: %d\n", __func__, err);
122 return err;
123 }
124
125#ifdef PORT_DEBUG
126 DEV_INFO("HDMI[%02x] [R] %02x\n", reg, data);
127#endif
128 return *data_buf;
129}
130
131/*
132 * Write a value to a register on adv7520 device.
133 * Returns zero if successful, or non-zero otherwise.
134 */
135static int adv7520_write_reg(struct i2c_client *client, u8 reg, u8 val)
136{
137 int err;
138 struct i2c_msg msg[1];
139 unsigned char data[2];
140
141 if (!client->adapter)
142 return -ENODEV;
143 if (!atomic_read(&comm_power_on)) {
144 DEV_WARN("%s: WARN: missing GPIO power\n", __func__);
145 return -ENODEV;
146 }
147
148 msg->addr = client->addr;
149 msg->flags = 0;
150 msg->len = 2;
151 msg->buf = data;
152 data[0] = reg;
153 data[1] = val;
154
155 err = i2c_transfer(client->adapter, msg, 1);
156 if (err >= 0)
157 return 0;
158#ifdef PORT_DEBUG
159 DEV_INFO("HDMI[%02x] [W] %02x [%d]\n", reg, val, err);
160#endif
161 return err;
162}
163
164#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
165static void adv7520_close_hdcp_link(void)
166{
167 if (!external_common_state->hdcp_active && !hdcp_activating)
168 return;
169
170 DEV_INFO("HDCP: Close link\n");
171
172 reg[0xD5] = adv7520_read_reg(hclient, 0xD5);
173 reg[0xD5] &= 0xFE;
174 adv7520_write_reg(hclient, 0xD5, (u8)reg[0xD5]);
175
176 reg[0x16] = adv7520_read_reg(hclient, 0x16);
177 reg[0x16] &= 0xFE;
178 adv7520_write_reg(hclient, 0x16, (u8)reg[0x16]);
179
180 /* UnMute Audio */
181 adv7520_write_reg(hclient, 0x0C, (u8)0x84);
182
183 external_common_state->hdcp_active = FALSE;
184 mutex_lock(&hdcp_state_mutex);
185 hdcp_activating = FALSE;
186 mutex_unlock(&hdcp_state_mutex);
187}
188
189static void adv7520_comm_power(int on, int show);
190static void adv7520_hdcp_enable(struct work_struct *work)
191{
192 DEV_INFO("HDCP: Start reg[0xaf]=%02x (mute audio)\n", reg[0xaf]);
193
194 adv7520_comm_power(1, 1);
195
196 /* Mute Audio */
197 adv7520_write_reg(hclient, 0x0C, (u8)0xC3);
198
199 msleep(200);
200 /* Wait for BKSV ready interrupt */
201 /* Read BKSV's keys from HDTV */
202 reg[0xBF] = adv7520_read_reg(hclient, 0xBF);
203 reg[0xC0] = adv7520_read_reg(hclient, 0xC0);
204 reg[0xC1] = adv7520_read_reg(hclient, 0xC1);
205 reg[0xC2] = adv7520_read_reg(hclient, 0xC2);
206 reg[0xc3] = adv7520_read_reg(hclient, 0xC3);
207
208 DEV_DBG("HDCP: BKSV={%02x,%02x,%02x,%02x,%02x}\n", reg[0xbf], reg[0xc0],
209 reg[0xc1], reg[0xc2], reg[0xc3]);
210
211 /* Is SINK repeater */
212 reg[0xBE] = adv7520_read_reg(hclient, 0xBE);
213 if (~(reg[0xBE] & 0x40)) {
214 ; /* compare with revocation list */
215 /* Check 20 1's and 20 zero's */
216 } else {
217 /* Don't implement HDCP if sink as a repeater */
218 adv7520_write_reg(hclient, 0x0C, (u8)0x84);
219 mutex_lock(&hdcp_state_mutex);
220 hdcp_activating = FALSE;
221 mutex_unlock(&hdcp_state_mutex);
222 DEV_WARN("HDCP: Sink Repeater (%02x), (unmute audio)\n",
223 reg[0xbe]);
224
225 adv7520_comm_power(0, 1);
226 return;
227 }
228
229 msleep(200);
230 reg[0xB8] = adv7520_read_reg(hclient, 0xB8);
231 DEV_INFO("HDCP: Status reg[0xB8] is %02x\n", reg[0xb8]);
232 if (reg[0xb8] & 0x40) {
233 /* UnMute Audio */
234 adv7520_write_reg(hclient, 0x0C, (u8)0x84);
235 DEV_INFO("HDCP: A/V content Encrypted (unmute audio)\n");
236 external_common_state->hdcp_active = TRUE;
237 }
238 adv7520_comm_power(0, 1);
239
240 mutex_lock(&hdcp_state_mutex);
241 hdcp_activating = FALSE;
242 mutex_unlock(&hdcp_state_mutex);
243}
244#endif
245
246static int adv7520_read_edid_block(int block, uint8 *edid_buf)
247{
248 u8 r = 0;
249 int ret;
250 struct i2c_msg msg[] = {
251 { .addr = reg[0x43] >> 1,
252 .flags = 0,
253 .len = 1,
254 .buf = &r },
255 { .addr = reg[0x43] >> 1,
256 .flags = I2C_M_RD,
257 .len = 0x100,
258 .buf = edid_buf } };
259
260 if (block > 0)
261 return 0;
262 ret = i2c_transfer(hclient->adapter, msg, 2);
263 DEV_DBG("EDID block: addr=%02x, ret=%d\n", reg[0x43] >> 1, ret);
264 return (ret < 2) ? -ENODEV : 0;
265}
266
267static void adv7520_read_edid(void)
268{
269 external_common_state->read_edid_block = adv7520_read_edid_block;
270 if (hdmi_common_read_edid()) {
271 u8 timeout;
272 DEV_INFO("%s: retry\n", __func__);
273 adv7520_write_reg(hclient, 0xc9, 0x13);
274 msleep(500);
275 timeout = (adv7520_read_reg(hclient, 0x96) & (1 << 2));
276 if (timeout) {
277 hdmi_common_read_edid();
278 }
279 }
280}
281
282static void adv7520_chip_on(void)
283{
284 if (!chip_power_on) {
285 /* Get the current register holding the power bit. */
286 unsigned long reg0xaf = adv7520_read_reg(hclient, 0xaf);
287
288 dd->pd->core_power(1, 1);
289
290 /* Set the HDMI select bit. */
291 set_bit(1, &reg0xaf);
292 DEV_INFO("%s: turn on chip power\n", __func__);
293 adv7520_write_reg(hclient, 0x41, 0x10);
294 adv7520_write_reg(hclient, 0xaf, (u8)reg0xaf);
295 chip_power_on = TRUE;
296 } else
297 DEV_INFO("%s: chip already has power\n", __func__);
298}
299
300static void adv7520_chip_off(void)
301{
302 if (chip_power_on) {
303#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
304 if (has_hdcp_hw_support)
305 adv7520_close_hdcp_link();
306#endif
307
308 DEV_INFO("%s: turn off chip power\n", __func__);
309 adv7520_write_reg(hclient, 0x41, 0x50);
310 dd->pd->core_power(0, 1);
311 chip_power_on = FALSE;
312 } else
313 DEV_INFO("%s: chip is already off\n", __func__);
314
315 monitor_sense = 0;
316 hpd_cable_chg_detected = FALSE;
317
318 if (enable_5v_on) {
319 dd->pd->enable_5v(0);
320 enable_5v_on = FALSE;
321 }
322}
323
324/* Power ON/OFF ADV7520 chip */
325static void adv7520_isr_w(struct work_struct *work);
326static void adv7520_comm_power(int on, int show)
327{
328 if (!on)
329 atomic_dec(&comm_power_on);
330 dd->pd->comm_power(on, 0/*show*/);
331 if (on)
332 atomic_inc(&comm_power_on);
333}
334
335#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
336static void adv7520_start_hdcp(void);
337#endif
338static int adv7520_power_on(struct platform_device *pdev)
339{
340 struct msm_fb_data_type *mfd = platform_get_drvdata(pdev);
341
342 external_common_state->dev = &pdev->dev;
343 if (mfd != NULL) {
344 DEV_INFO("adv7520_power: ON (%dx%d %d)\n",
345 mfd->var_xres, mfd->var_yres, mfd->var_pixclock);
346 hdmi_common_get_video_format_from_drv_data(mfd);
347 }
348
349 adv7520_comm_power(1, 1);
350 /* Check if HPD is signaled */
351 if (adv7520_read_reg(hclient, 0x42) & (1 << 6)) {
352 DEV_INFO("power_on: cable detected\n");
353 monitor_sense = adv7520_read_reg(hclient, 0xC6);
354#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
355 if (has_hdcp_hw_support) {
356 if (!hdcp_activating)
357 adv7520_start_hdcp();
358 }
359#endif
360 } else
361 DEV_INFO("power_on: cable NOT detected\n");
362 adv7520_comm_power(0, 1);
363 wake_lock(&wlock);
364
365 return 0;
366}
367
368static int adv7520_power_off(struct platform_device *pdev)
369{
370 DEV_INFO("power_off\n");
371 adv7520_comm_power(1, 1);
372 adv7520_chip_off();
373 wake_unlock(&wlock);
374 adv7520_comm_power(0, 1);
375
376 return 0;
377}
378
379
380/* AV7520 chip specific initialization */
381static void adv7520_chip_init(void)
382{
383 /* Initialize the variables used to read/write the ADV7520 chip. */
384 memset(&reg, 0xff, sizeof(reg));
385
386 /* Get the values from the "Fixed Registers That Must Be Set". */
387 reg[0x98] = adv7520_read_reg(hclient, 0x98);
388 reg[0x9c] = adv7520_read_reg(hclient, 0x9c);
389 reg[0x9d] = adv7520_read_reg(hclient, 0x9d);
390 reg[0xa2] = adv7520_read_reg(hclient, 0xa2);
391 reg[0xa3] = adv7520_read_reg(hclient, 0xa3);
392 reg[0xde] = adv7520_read_reg(hclient, 0xde);
393
394 /* Get the "HDMI/DVI Selection" register. */
395 reg[0xaf] = adv7520_read_reg(hclient, 0xaf);
396
397 /* Read Packet Memory I2C Address */
398 reg[0x45] = adv7520_read_reg(hclient, 0x45);
399
400 /* Hard coded values provided by ADV7520 data sheet. */
401 reg[0x98] = 0x03;
402 reg[0x9c] = 0x38;
403 reg[0x9d] = 0x61;
404 reg[0xa2] = 0x94;
405 reg[0xa3] = 0x94;
406 reg[0xde] = 0x88;
407
408 /* Set the HDMI select bit. */
409 reg[0xaf] |= 0x16;
410
411 /* Set the audio related registers. */
412 reg[0x01] = 0x00;
413 reg[0x02] = 0x2d;
414 reg[0x03] = 0x80;
415 reg[0x0a] = 0x4d;
416 reg[0x0b] = 0x0e;
417 reg[0x0c] = 0x84;
418 reg[0x0d] = 0x10;
419 reg[0x12] = 0x00;
420 reg[0x14] = 0x00;
421 reg[0x15] = 0x20;
422 reg[0x44] = 0x79;
423 reg[0x73] = 0x01;
424 reg[0x76] = 0x00;
425
426 /* Set 720p display related registers */
427 reg[0x16] = 0x00;
428
429 reg[0x18] = 0x46;
430 reg[0x55] = 0x00;
431 reg[0x3c] = 0x04;
432
433 /* Set Interrupt Mask register for HPD/HDCP */
434 reg[0x94] = 0xC0;
435#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
436 if (has_hdcp_hw_support)
437 reg[0x95] = 0xC0;
438 else
439 reg[0x95] = 0x00;
440#else
441 reg[0x95] = 0x00;
442#endif
443 adv7520_write_reg(hclient, 0x94, reg[0x94]);
444 adv7520_write_reg(hclient, 0x95, reg[0x95]);
445
446 /* Set Packet Memory I2C Address */
447 reg[0x45] = 0x74;
448
449 /* Set the values from the "Fixed Registers That Must Be Set". */
450 adv7520_write_reg(hclient, 0x98, reg[0x98]);
451 adv7520_write_reg(hclient, 0x9c, reg[0x9c]);
452 adv7520_write_reg(hclient, 0x9d, reg[0x9d]);
453 adv7520_write_reg(hclient, 0xa2, reg[0xa2]);
454 adv7520_write_reg(hclient, 0xa3, reg[0xa3]);
455 adv7520_write_reg(hclient, 0xde, reg[0xde]);
456
457 /* Set the "HDMI/DVI Selection" register. */
458 adv7520_write_reg(hclient, 0xaf, reg[0xaf]);
459
460 /* Set EDID Monitor address */
461 reg[0x43] = 0x7E;
462 adv7520_write_reg(hclient, 0x43, reg[0x43]);
463
464 /* Enable the i2s audio input. */
465 adv7520_write_reg(hclient, 0x01, reg[0x01]);
466 adv7520_write_reg(hclient, 0x02, reg[0x02]);
467 adv7520_write_reg(hclient, 0x03, reg[0x03]);
468 adv7520_write_reg(hclient, 0x0a, reg[0x0a]);
469 adv7520_write_reg(hclient, 0x0b, reg[0x0b]);
470 adv7520_write_reg(hclient, 0x0c, reg[0x0c]);
471 adv7520_write_reg(hclient, 0x0d, reg[0x0d]);
472 adv7520_write_reg(hclient, 0x12, reg[0x12]);
473 adv7520_write_reg(hclient, 0x14, reg[0x14]);
474 adv7520_write_reg(hclient, 0x15, reg[0x15]);
475 adv7520_write_reg(hclient, 0x44, reg[0x44]);
476 adv7520_write_reg(hclient, 0x73, reg[0x73]);
477 adv7520_write_reg(hclient, 0x76, reg[0x76]);
478
479 /* Enable 720p display */
480 adv7520_write_reg(hclient, 0x16, reg[0x16]);
481 adv7520_write_reg(hclient, 0x18, reg[0x18]);
482 adv7520_write_reg(hclient, 0x55, reg[0x55]);
483 adv7520_write_reg(hclient, 0x3c, reg[0x3c]);
484
485 /* Set Packet Memory address to avoid conflict
486 with Bosch Accelerometer */
487 adv7520_write_reg(hclient, 0x45, reg[0x45]);
488
489 /* Ensure chip is in low-power state */
490 adv7520_write_reg(hclient, 0x41, 0x50);
491}
492
493#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
494static void adv7520_start_hdcp(void)
495{
496 mutex_lock(&hdcp_state_mutex);
497 if (hdcp_activating) {
498 DEV_WARN("adv7520_timer: HDCP already"
499 " activating, skipping\n");
500 mutex_unlock(&hdcp_state_mutex);
501 return;
502 }
503 hdcp_activating = TRUE;
504 mutex_unlock(&hdcp_state_mutex);
505
506 del_timer(&hpd_duty_timer);
507
508 adv7520_comm_power(1, 1);
509
510 if (!enable_5v_on) {
511 dd->pd->enable_5v(1);
512 enable_5v_on = TRUE;
513 adv7520_chip_on();
514 }
515
516 /* request for HDCP */
517 reg[0xaf] = adv7520_read_reg(hclient, 0xaf);
518 reg[0xaf] |= 0x90;
519 adv7520_write_reg(hclient, 0xaf, reg[0xaf]);
520 reg[0xaf] = adv7520_read_reg(hclient, 0xaf);
521
522 reg[0xba] = adv7520_read_reg(hclient, 0xba);
523 reg[0xba] |= 0x10;
524 adv7520_write_reg(hclient, 0xba, reg[0xba]);
525 reg[0xba] = adv7520_read_reg(hclient, 0xba);
526 adv7520_comm_power(0, 1);
527
528 DEV_INFO("HDCP: reg[0xaf]=0x%02x, reg[0xba]=0x%02x, waiting for BKSV\n",
529 reg[0xaf], reg[0xba]);
530
531 /* will check for HDCP Error or BKSV ready */
532 mod_timer(&hpd_duty_timer, jiffies + HZ/2);
533}
534#endif
535
536static void adv7520_hpd_timer_w(struct work_struct *work)
537{
538 if (!external_common_state->hpd_feature_on) {
539 DEV_INFO("adv7520_timer: skipping, feature off\n");
540 return;
541 }
542
543 if ((monitor_sense & 0x4) && !external_common_state->hpd_state) {
544 int timeout;
545 DEV_DBG("adv7520_timer: Cable Detected\n");
546 adv7520_comm_power(1, 1);
547 adv7520_chip_on();
548
549 if (hpd_cable_chg_detected) {
550 hpd_cable_chg_detected = FALSE;
551 /* Ensure 5V to read EDID */
552 if (!enable_5v_on) {
553 dd->pd->enable_5v(1);
554 enable_5v_on = TRUE;
555 }
556 msleep(500);
557 timeout = (adv7520_read_reg(hclient, 0x96) & (1 << 2));
558 if (timeout) {
559 DEV_DBG("adv7520_timer: EDID-Ready..\n");
560 adv7520_read_edid();
561 } else
562 DEV_DBG("adv7520_timer: EDID TIMEOUT (C9=%02x)"
563 "\n", adv7520_read_reg(hclient, 0xC9));
564 }
565#ifdef TESTING_FORCE_480p
566 external_common_state->disp_mode_list.num_of_elements = 1;
567 external_common_state->disp_mode_list.disp_mode_list[0] =
568 HDMI_VFRMT_720x480p60_16_9;
569#endif
570 adv7520_comm_power(0, 1);
571#ifndef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
572 /* HDMI_5V_EN not needed anymore */
573 if (enable_5v_on) {
574 DEV_DBG("adv7520_timer: EDID done, no HDCP, 5V not "
575 "needed anymore\n");
576 dd->pd->enable_5v(0);
577 enable_5v_on = FALSE;
578 }
579#endif
580 change_hdmi_state(1);
581 } else if (external_common_state->hpd_state) {
582 adv7520_comm_power(1, 1);
583 adv7520_chip_off();
584 adv7520_comm_power(0, 1);
585 DEV_DBG("adv7520_timer: Cable Removed\n");
586 change_hdmi_state(0);
587 }
588}
589
590static void adv7520_hpd_timer_f(unsigned long data)
591{
592 schedule_work(&hpd_timer_work);
593}
594
595static void adv7520_isr_w(struct work_struct *work)
596{
597 static int state_count;
598 static u8 last_reg0x96;
599 u8 reg0xc8;
600 u8 reg0x96;
601#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
602 static u8 last_reg0x97;
603 u8 reg0x97 = 0;
604#endif
605 if (!external_common_state->hpd_feature_on) {
606 DEV_DBG("adv7520_irq: skipping, hpd off\n");
607 return;
608 }
609
610 adv7520_comm_power(1, 1);
611 reg0x96 = adv7520_read_reg(hclient, 0x96);
612#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
613 if (has_hdcp_hw_support) {
614 reg0x97 = adv7520_read_reg(hclient, 0x97);
615 /* Clearing the Interrupts */
616 adv7520_write_reg(hclient, 0x97, reg0x97);
617 }
618#endif
619 /* Clearing the Interrupts */
620 adv7520_write_reg(hclient, 0x96, reg0x96);
621
622 if ((reg0x96 == 0xC0) || (reg0x96 & 0x40)) {
623#ifdef DEBUG
624 unsigned int hpd_state = adv7520_read_reg(hclient, 0x42);
625#endif
626 monitor_sense = adv7520_read_reg(hclient, 0xC6);
627 DEV_DBG("adv7520_irq: reg[0x42]=%02x && reg[0xC6]=%02x\n",
628 hpd_state, monitor_sense);
629
630 if (!enable_5v_on) {
631 dd->pd->enable_5v(1);
632 enable_5v_on = TRUE;
633 }
634 if (!hpd_power_on) {
635 dd->pd->core_power(1, 1);
636 hpd_power_on = TRUE;
637 }
638
639 /* Timer for catching interrupt debouning */
640 DEV_DBG("adv7520_irq: Timer in .5sec\n");
641 hpd_cable_chg_detected = TRUE;
642 mod_timer(&hpd_timer, jiffies + HZ/2);
643 }
644#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
645 if (has_hdcp_hw_support) {
646 if (hdcp_activating) {
647 /* HDCP controller error Interrupt */
648 if (reg0x97 & 0x80) {
649 DEV_ERR("adv7520_irq: HDCP_ERROR\n");
650 state_count = 0;
651 adv7520_close_hdcp_link();
652 /* BKSV Ready interrupts */
653 } else if (reg0x97 & 0x40) {
654 DEV_INFO("adv7520_irq: BKSV keys ready, Begin"
655 " HDCP encryption\n");
656 state_count = 0;
657 schedule_work(&hdcp_handle_work);
658 } else if (++state_count > 2 && (monitor_sense & 0x4)) {
659 DEV_INFO("adv7520_irq: Still waiting for BKSV,"
660 "restart HDCP\n");
661 hdcp_activating = FALSE;
662 state_count = 0;
663 adv7520_chip_off();
664 adv7520_start_hdcp();
665 }
666 reg0xc8 = adv7520_read_reg(hclient, 0xc8);
667 DEV_INFO("adv7520_irq: DDC controller reg[0xC8]=0x%02x,"
668 "state_count=%d, monitor_sense=%x\n",
669 reg0xc8, state_count, monitor_sense);
670 } else if (!external_common_state->hdcp_active
671 && (monitor_sense & 0x4)) {
672 DEV_INFO("adv7520_irq: start HDCP with"
673 " monitor sense\n");
674 state_count = 0;
675 adv7520_start_hdcp();
676 } else
677 state_count = 0;
678 if (last_reg0x97 != reg0x97 || last_reg0x96 != reg0x96)
679 DEV_DBG("adv7520_irq: reg[0x96]=%02x "
680 "reg[0x97]=%02x: HDCP: %d\n", reg0x96, reg0x97,
681 external_common_state->hdcp_active);
682 last_reg0x97 = reg0x97;
683 } else {
684 if (last_reg0x96 != reg0x96)
685 DEV_DBG("adv7520_irq: reg[0x96]=%02x\n", reg0x96);
686 }
687#else
688 if (last_reg0x96 != reg0x96)
689 DEV_DBG("adv7520_irq: reg[0x96]=%02x\n", reg0x96);
690#endif
691 last_reg0x96 = reg0x96;
692 adv7520_comm_power(0, 1);
693}
694
695static void adv7520_hpd_duty_work(struct work_struct *work)
696{
697 if (!external_common_state->hpd_feature_on) {
698 DEV_WARN("%s: hpd feature is off, skipping\n", __func__);
699 return;
700 }
701
702 dd->pd->core_power(1, 0);
703 msleep(10);
704 adv7520_isr_w(NULL);
705 dd->pd->core_power(0, 0);
706}
707
708static void adv7520_hpd_duty_timer_f(unsigned long data)
709{
710 if (!external_common_state->hpd_feature_on) {
711 DEV_WARN("%s: hpd feature is off, skipping\n", __func__);
712 return;
713 }
714
715 mod_timer(&hpd_duty_timer, jiffies + HPD_DUTY_CYCLE*HZ);
716 schedule_work(&hpd_duty_work);
717}
718
719static const struct i2c_device_id adv7520_id[] = {
720 { ADV7520_DRV_NAME , 0},
721 {}
722};
723
724static struct msm_fb_panel_data hdmi_panel_data = {
725 .on = adv7520_power_on,
726 .off = adv7520_power_off,
727};
728
729static struct platform_device hdmi_device = {
730 .name = ADV7520_DRV_NAME ,
731 .id = 2,
732 .dev = {
733 .platform_data = &hdmi_panel_data,
734 }
735};
736
737static void adv7520_ensure_init(void)
738{
739 static boolean init_done;
740 if (!init_done) {
741 int rc = dd->pd->init_irq();
742 if (rc) {
743 DEV_ERR("adv7520_init: init_irq: %d\n", rc);
744 return;
745 }
746
747 init_done = TRUE;
748 }
749 DEV_INFO("adv7520_init: chip init\n");
750 adv7520_comm_power(1, 1);
751 adv7520_chip_init();
752 adv7520_comm_power(0, 1);
753}
754
755static int adv7520_hpd_feature(int on)
756{
757 int rc = 0;
758
759 if (!on) {
760 if (enable_5v_on) {
761 dd->pd->enable_5v(0);
762 enable_5v_on = FALSE;
763 }
764 if (hpd_power_on) {
765 dd->pd->core_power(0, 1);
766 hpd_power_on = FALSE;
767 }
768
769 DEV_DBG("adv7520_hpd: %d: stop duty timer\n", on);
770 del_timer(&hpd_timer);
771 del_timer(&hpd_duty_timer);
772 external_common_state->hpd_state = 0;
773 }
774
775 if (on) {
776 dd->pd->core_power(1, 0);
777 adv7520_ensure_init();
778
779 adv7520_comm_power(1, 1);
780 monitor_sense = adv7520_read_reg(hclient, 0xC6);
781 DEV_DBG("adv7520_irq: reg[0xC6]=%02x\n", monitor_sense);
782 adv7520_comm_power(0, 1);
783 dd->pd->core_power(0, 0);
784
785 if (monitor_sense & 0x4) {
786 if (!enable_5v_on) {
787 dd->pd->enable_5v(1);
788 enable_5v_on = TRUE;
789 }
790 if (!hpd_power_on) {
791 dd->pd->core_power(1, 1);
792 hpd_power_on = TRUE;
793 }
794
795 hpd_cable_chg_detected = TRUE;
796 mod_timer(&hpd_timer, jiffies + HZ/2);
797 }
798
799 DEV_DBG("adv7520_hpd: %d start duty timer\n", on);
800 mod_timer(&hpd_duty_timer, jiffies + HZ/100);
801 }
802
803 DEV_INFO("adv7520_hpd: %d\n", on);
804 return rc;
805}
806
807static int __devinit
808 adv7520_probe(struct i2c_client *client, const struct i2c_device_id *id)
809{
810 int rc;
811 struct platform_device *fb_dev;
812
813 dd = kzalloc(sizeof *dd, GFP_KERNEL);
814 if (!dd) {
815 rc = -ENOMEM;
816 goto probe_exit;
817 }
818
819 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
820 return -ENODEV;
821
822 external_common_state->dev = &client->dev;
823
824 /* Init real i2c_client */
825 hclient = client;
826
827 i2c_set_clientdata(client, dd);
828 dd->pd = client->dev.platform_data;
829 if (!dd->pd) {
830 rc = -ENODEV;
831 goto probe_free;
832 }
833
834 INIT_WORK(&dd->isr_work, adv7520_isr_w);
835 INIT_WORK(&hpd_timer_work, adv7520_hpd_timer_w);
836#ifdef CONFIG_FB_MSM_HDMI_ADV7520_PANEL_HDCP_SUPPORT
837 if (dd->pd->check_hdcp_hw_support)
838 has_hdcp_hw_support = dd->pd->check_hdcp_hw_support();
839
840 if (has_hdcp_hw_support)
841 INIT_WORK(&hdcp_handle_work, adv7520_hdcp_enable);
842 else
843 DEV_INFO("%s: no hdcp hw support.\n", __func__);
844#endif
845
846 init_timer(&hpd_timer);
847 hpd_timer.function = adv7520_hpd_timer_f;
848 hpd_timer.data = (unsigned long)NULL;
849 hpd_timer.expires = 0xffffffff;
850 add_timer(&hpd_timer);
851
852 external_common_state->hpd_feature = adv7520_hpd_feature;
853 DEV_INFO("adv7520_probe: HPD detection on request\n");
854 init_timer(&hpd_duty_timer);
855 hpd_duty_timer.function = adv7520_hpd_duty_timer_f;
856 hpd_duty_timer.data = (unsigned long)NULL;
857 hpd_duty_timer.expires = 0xffffffff;
858 add_timer(&hpd_duty_timer);
859 INIT_WORK(&hpd_duty_work, adv7520_hpd_duty_work);
860 DEV_INFO("adv7520_probe: HPD detection ON (duty)\n");
861
862 fb_dev = msm_fb_add_device(&hdmi_device);
863
864 if (fb_dev) {
865 rc = external_common_state_create(fb_dev);
866 if (rc)
867 goto probe_free;
868 } else
869 DEV_ERR("adv7520_probe: failed to add fb device\n");
870
871 return 0;
872
873probe_free:
874 kfree(dd);
875 dd = NULL;
876probe_exit:
877 return rc;
878
879}
880
881static int __devexit adv7520_remove(struct i2c_client *client)
882{
883 if (!client->adapter) {
884 DEV_ERR("%s: No HDMI Device\n", __func__);
885 return -ENODEV;
886 }
887 wake_lock_destroy(&wlock);
888 kfree(dd);
889 dd = NULL;
890 return 0;
891}
892
893#ifdef CONFIG_SUSPEND
894static int adv7520_i2c_suspend(struct device *dev)
895{
896 DEV_INFO("%s\n", __func__);
897
898 ++suspend_count;
899
900 if (external_common_state->hpd_feature_on) {
901 DEV_DBG("%s: stop duty timer\n", __func__);
902 del_timer(&hpd_duty_timer);
903 del_timer(&hpd_timer);
904 }
905
906 /* Turn off LDO8 and go into low-power state */
907 if (chip_power_on) {
908 DEV_DBG("%s: turn off power\n", __func__);
909 adv7520_comm_power(1, 1);
910 adv7520_write_reg(hclient, 0x41, 0x50);
911 adv7520_comm_power(0, 1);
912 dd->pd->core_power(0, 1);
913 }
914
915 return 0;
916}
917
918static int adv7520_i2c_resume(struct device *dev)
919{
920 DEV_INFO("%s\n", __func__);
921
922 /* Turn on LDO8 and go into normal-power state */
923 if (chip_power_on) {
924 DEV_DBG("%s: turn on power\n", __func__);
925 dd->pd->core_power(1, 1);
926 adv7520_comm_power(1, 1);
927 adv7520_write_reg(hclient, 0x41, 0x10);
928 adv7520_comm_power(0, 1);
929 }
930
931 if (external_common_state->hpd_feature_on) {
932 DEV_DBG("%s: start duty timer\n", __func__);
933 mod_timer(&hpd_duty_timer, jiffies + HPD_DUTY_CYCLE*HZ);
934 }
935
936 return 0;
937}
938#else
939#define adv7520_i2c_suspend NULL
940#define adv7520_i2c_resume NULL
941#endif
942
943static const struct dev_pm_ops adv7520_device_pm_ops = {
944 .suspend = adv7520_i2c_suspend,
945 .resume = adv7520_i2c_resume,
946};
947
948static struct i2c_driver hdmi_i2c_driver = {
949 .driver = {
950 .name = ADV7520_DRV_NAME,
951 .owner = THIS_MODULE,
952 .pm = &adv7520_device_pm_ops,
953 },
954 .probe = adv7520_probe,
955 .id_table = adv7520_id,
956 .remove = __devexit_p(adv7520_remove),
957};
958
959static int __init adv7520_init(void)
960{
961 int rc;
962
963 pr_info("%s\n", __func__);
964 external_common_state = &hdmi_common;
965 external_common_state->video_resolution = HDMI_VFRMT_1280x720p60_16_9;
966 HDMI_SETUP_LUT(640x480p60_4_3); /* 25.20MHz */
967 HDMI_SETUP_LUT(720x480p60_16_9); /* 27.03MHz */
968 HDMI_SETUP_LUT(1280x720p60_16_9); /* 74.25MHz */
969
970 HDMI_SETUP_LUT(720x576p50_16_9); /* 27.00MHz */
971 HDMI_SETUP_LUT(1280x720p50_16_9); /* 74.25MHz */
972
973 hdmi_common_init_panel_info(&hdmi_panel_data.panel_info);
974
975 rc = i2c_add_driver(&hdmi_i2c_driver);
976 if (rc) {
977 pr_err("hdmi_init FAILED: i2c_add_driver rc=%d\n", rc);
978 goto init_exit;
979 }
980
981 if (machine_is_msm7x30_surf() || machine_is_msm8x55_surf()) {
982 short *hdtv_mux = (short *)ioremap(0x8e000170 , 0x100);
983 *hdtv_mux++ = 0x020b;
984 *hdtv_mux = 0x8000;
985 iounmap(hdtv_mux);
986 }
987 wake_lock_init(&wlock, WAKE_LOCK_IDLE, "hdmi_active");
988
989 return 0;
990
991init_exit:
992 return rc;
993}
994
995static void __exit adv7520_exit(void)
996{
997 i2c_del_driver(&hdmi_i2c_driver);
998}
999
1000module_init(adv7520_init);
1001module_exit(adv7520_exit);
1002MODULE_LICENSE("GPL v2");
1003MODULE_VERSION("0.1");
1004MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
1005MODULE_DESCRIPTION("ADV7520 HDMI driver");