add rk616 hdmi roll polling method when hdmi_irq = INVALID_GPIO
authorxuhuicong <xhc@rock-chips.com>
Tue, 14 May 2013 10:43:11 +0000 (18:43 +0800)
committerxuhuicong <xhc@rock-chips.com>
Tue, 14 May 2013 10:43:11 +0000 (18:43 +0800)
drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c
drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c

index 4a715487ddaa9e7428439e145e7ceeda744cbd4e..f9815f6a4de289480a64bc402efc4ba5a140796b 100755 (executable)
 
 struct hdmi *hdmi = NULL;
 struct mfd_rk616 *g_rk616_hdmi = NULL;
-struct work_struct     g_irq_work;
+// struct work_struct  g_rk616_delay_work;
+struct delayed_work     g_rk616_delay_work;
 
-extern void hdmi_irq(void);
+// extern void hdmi_irq(void);
+extern void rk616_hdmi_work(void);
 extern void hdmi_work(struct work_struct *work);
 extern struct rk_lcdc_device_driver * rk_get_lcdc_drv(char *name);
 extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent);
@@ -51,18 +53,24 @@ static int rk616_hdmi_reg_show(struct seq_file *s, void *v)
        }
 
 
-       seq_printf(s,"------>gpio = %d \n",gpio_get_value(rk616->pdata->hdmi_irq));
+       //seq_printf(s,"------>gpio = %d \n",gpio_get_value(rk616->pdata->hdmi_irq));
+       seq_printf(s, "\n>>>rk616_ctl reg");
+       for (i = 0; i < 16; i++) {
+               seq_printf(s, " %2x", i);
+       }
+       seq_printf(s, "\n-----------------------------------------------------------------");
+       
        for(i=0;i<= (PHY_PRE_DIV_RATIO << 2);i+=4)
        {
                rk616->read_dev(rk616,RK616_HDMI_BASE + i,&val);
                //seq_printf(s,"reg%02x>>0x%08x\n",(i>>2),val);
                if((i>>2)%16==0)
-                       seq_printf(s,"\n>>>rk610_ctl %02x:",i>>2);
+                       seq_printf(s,"\n>>>rk616_ctl %2x:",i>>2);
                seq_printf(s," %02x",val);
 
        }
        
-       seq_printf(s,"\n");
+       seq_printf(s, "\n-----------------------------------------------------------------\n");
        
        return 0;
 }
@@ -75,9 +83,19 @@ static ssize_t rk616_hdmi_reg_write (struct file *file, const char __user *buf,
        char kbuf[25];
        if (copy_from_user(kbuf, buf, count))
                return -EFAULT;
-       sscanf(kbuf, "%x%x", &reg,&val);
-       dev_dbg(rk616->dev,"%s:reg:0x%04x val:0x%08x\n",__func__,reg,val);
-       rk616->write_dev(rk616,reg,&val);
+       sscanf(kbuf, "%x%x", &reg, &val);
+        if ((reg < 0) || (reg > 0xed))
+        {
+                printk("it is no hdmi reg\n");
+                return count;
+        }
+       printk("/**********rk616 reg config******/");
+       printk("\n reg=%x val=%x\n", reg, val);
+
+       //sscanf(kbuf, "%x%x", &reg, &val);
+       dev_dbg(rk616->dev,"%s:reg:0x%04x val:0x%08x\n",__func__,reg, val);
+       rk616->write_dev(rk616, RK616_HDMI_BASE + (reg << 2), &val);
+
        return count;
 }
 
@@ -125,7 +143,10 @@ static void hdmi_early_suspend(struct early_suspend *h)
                mutex_unlock(&hdmi->enable_mutex);
                return;
        }
-       disable_irq(hdmi->irq);
+
+        if (hdmi->irq)
+               disable_irq(hdmi->irq);
+
        mutex_unlock(&hdmi->enable_mutex);
        hdmi->command = HDMI_CONFIG_ENABLE;
        init_completion(&hdmi->complete);
@@ -145,30 +166,39 @@ static void hdmi_early_resume(struct early_suspend *h)
 
        hdmi->suspend = 0;
        rk616_hdmi_initial();
-       if(hdmi->enable) {
+       if(hdmi->enable && hdmi->irq) {
                enable_irq(hdmi->irq);
-               hdmi_irq();
+               // hdmi_irq();
+                rk616_hdmi_work();
        }
+        if (g_rk616_hdmi->pdata->hdmi_irq == INVALID_GPIO) 
+               queue_delayed_work(hdmi->workqueue, &g_rk616_delay_work, 100);
+
        queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));   
        mutex_unlock(&hdmi->enable_mutex);
        return;
 }
 #endif
-static void rk616_irq_work_func(struct work_struct *work)
+static void rk616_delay_work_func(struct work_struct *work)
 {
        if(hdmi->suspend == 0) {
                if(hdmi->enable == 1) {
-                       hdmi_irq();
+                       //hdmi_irq();
+                        rk616_hdmi_work();
                }
-//             queue_delayed_work(hdmi->workqueue, &g_irq_work, 100);
+
+                if (g_rk616_hdmi->pdata->hdmi_irq == INVALID_GPIO) {
+                       queue_delayed_work(hdmi->workqueue, &g_rk616_delay_work, 100);
+                }
        }
 }
+
 #if 1
 static irqreturn_t rk616_hdmi_irq(int irq, void *dev_id)
 {
        printk(KERN_INFO "rk616_hdmi_irq irq triggered.\n");
-       schedule_work(&g_irq_work);
-    return IRQ_HANDLED;
+       queue_delayed_work(hdmi->workqueue, &g_rk616_delay_work, 0);
+        return IRQ_HANDLED;
 }
 #endif
 static int __devinit rk616_hdmi_probe (struct platform_device *pdev)
@@ -230,10 +260,11 @@ static int __devinit rk616_hdmi_probe (struct platform_device *pdev)
        spin_lock_init(&hdmi->irq_lock);
        mutex_init(&hdmi->enable_mutex);
 
+       INIT_DELAYED_WORK(&g_rk616_delay_work, rk616_delay_work_func);
        /* get the IRQ */
        if(rk616->pdata->hdmi_irq != INVALID_GPIO)
        {
-               INIT_WORK(&g_irq_work, rk616_irq_work_func);
+               // INIT_DELAYED_WORK(&g_rk616_delay_work, rk616_delay_work_func);
                ret = gpio_request(rk616->pdata->hdmi_irq,"rk616_hdmi_irq");
                if(ret < 0)
                {
@@ -254,15 +285,19 @@ static int __devinit rk616_hdmi_probe (struct platform_device *pdev)
                        dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret);
                        goto err1;
                }
-       }
+       } else {
+
+                /* use roll polling method */
+               hdmi->irq = 0;
+        }
 #if defined(CONFIG_DEBUG_FS)
        if(rk616->debugfs_dir)
        {
                debugfs_create_file("hdmi", S_IRUSR,rk616->debugfs_dir,rk616,&rk616_hdmi_reg_fops);
        }
 #endif
-       rk616_irq_work_func(NULL);
-       //queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10)); 
+       // rk616_delay_work_func(NULL);
+       queue_delayed_work(hdmi->workqueue, &g_rk616_delay_work, msecs_to_jiffies(0));  
        dev_info(hdmi->dev, "rk616 hdmi probe success.\n");
        return 0;
 err1:
@@ -284,10 +319,12 @@ static int __devexit rk616_hdmi_remove(struct platform_device *pdev)
 {
        if(hdmi) {
                mutex_lock(&hdmi->enable_mutex);
-               if(!hdmi->suspend && hdmi->enable)
+               if(!hdmi->suspend && hdmi->enable && hdmi->irq)
                        disable_irq(hdmi->irq);
                mutex_unlock(&hdmi->enable_mutex);
-               free_irq(hdmi->irq, NULL);
+                if (hdmi->irq) {
+                       free_irq(hdmi->irq, NULL);
+                }
                flush_workqueue(hdmi->workqueue);
                destroy_workqueue(hdmi->workqueue);
 #ifdef CONFIG_SWITCH
index e45db4b4025d5a9e00a8f6fb33ae0927cddbf342..cf59a81d2c8650a5fb937ab27da02d5884be633c 100755 (executable)
@@ -3,8 +3,9 @@
 #include <mach/io.h>
 #include "rk616_hdmi.h"
 #include "rk616_hdmi_hw.h"
+#include <mach/gpio.h>
 
-static char edid_result = 0;
+// static char edid_result = 0;
 
 
 static int rk616_hdmi_set_vif(rk_screen * screen,bool connect)
@@ -54,7 +55,7 @@ static void rk616_hdmi_set_pwr_mode(int mode)
        hdmi_dbg(hdmi->dev,"%s change pwr_mode %d --> %d\n",__FUNCTION__,hdmi->pwr_mode,mode);
     switch(mode){
      case NORMAL:
-            hdmi_dbg(hdmi->dev,"%s change pwr_mode NORMAL\n",__FUNCTION__,hdmi->pwr_mode,mode);
+            hdmi_dbg(hdmi->dev,"%s change pwr_mode NORMALpwr_mode = %d, mode = %d\n",__FUNCTION__,hdmi->pwr_mode,mode);
                rk616_hdmi_sys_power_down();
                HDMIWrReg(PHY_DRIVER,0xaa);
                HDMIWrReg(PHY_PRE_EMPHASIS,0x0f);
@@ -69,7 +70,7 @@ static void rk616_hdmi_set_pwr_mode(int mode)
                rk616_hdmi_sys_power_up();
                break;
        case LOWER_PWR:
-               hdmi_dbg(hdmi->dev,"%s change pwr_mode LOWER_PWR\n",__FUNCTION__,hdmi->pwr_mode,mode);
+               hdmi_dbg(hdmi->dev,"%s change pwr_mode LOWER_PWR pwr_mode = %d, mode = %d\n",__FUNCTION__,hdmi->pwr_mode,mode);
                rk616_hdmi_av_mute(0);
                rk616_hdmi_sys_power_down();
                HDMIWrReg(PHY_DRIVER,0x00);
@@ -415,20 +416,45 @@ int rk616_hdmi_removed(void)
 }
 
 
-void hdmi_irq(void)
+void rk616_hdmi_work(void)
 {              
        u32 interrupt = 0;
+        static int hpd = 0;
+
+        /* if hdmi_irq == INVALID_GPIO use irq mode, else use roll polling method */
+        if (g_rk616_hdmi->pdata->hdmi_irq == INVALID_GPIO) {
        
-       HDMIRdReg(INTERRUPT_STATUS1,&interrupt);
-       HDMIWrReg(INTERRUPT_STATUS1, interrupt);
+               HDMIRdReg(INTERRUPT_STATUS1,&interrupt);
+               HDMIWrReg(INTERRUPT_STATUS1, interrupt);
+
+               if(interrupt & m_HOTPLUG){
+                       if(hdmi->state == HDMI_SLEEP)
+                               hdmi->state = WAIT_HOTPLUG;
+                       if(hdmi->pwr_mode == LOWER_PWR)
+                               rk616_hdmi_set_pwr_mode(NORMAL);
+
+                       queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));   
+               }
+
+        } else {
+                int value = 0;
+                HDMIRdReg(HDMI_STATUS,&value);
+                if((value & m_HOTPLUG)&& hpd == 0){
+                       if(hdmi->state == HDMI_SLEEP)
+                               hdmi->state = WAIT_HOTPLUG;
+                       if(hdmi->pwr_mode == LOWER_PWR)
+                               rk616_hdmi_set_pwr_mode(NORMAL);
+
+                       queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));   
+                        hpd = 1;
+                } else if (((value & m_HOTPLUG)== 0) && (hpd == 1)) {
+                        queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));  
+                        hpd = 0;
+
+                }
+        }
+
 
-       if(interrupt & m_HOTPLUG){
-               if(hdmi->state == HDMI_SLEEP)
-                       hdmi->state = WAIT_HOTPLUG;
-               if(hdmi->pwr_mode == LOWER_PWR)
-                       rk616_hdmi_set_pwr_mode(NORMAL);
-               queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));   
-       }
 #if 0  
        if(hdmi->state == HDMI_SLEEP) {
 //             hdmi_dbg(hdmi->dev, "hdmi return to sleep mode\n");