From: xuhuicong Date: Tue, 14 May 2013 10:43:11 +0000 (+0800) Subject: add rk616 hdmi roll polling method when hdmi_irq = INVALID_GPIO X-Git-Tag: firefly_0821_release~7099 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=firefly-linux-kernel-4.4.55.git;a=commitdiff_plain;h=1c1636013000268142b5b79a135a3d2294093dd7 add rk616 hdmi roll polling method when hdmi_irq = INVALID_GPIO --- diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c index 4a715487ddaa..f9815f6a4de2 100755 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c +++ b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c @@ -29,9 +29,11 @@ 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", ®,&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", ®, &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", ®, &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 diff --git a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c index e45db4b4025d..cf59a81d2c86 100755 --- a/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c +++ b/drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c @@ -3,8 +3,9 @@ #include #include "rk616_hdmi.h" #include "rk616_hdmi_hw.h" +#include -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");