mfd rk616 hdmi:fix register config bug
authoryxj <yxj@rock-chips.com>
Fri, 19 Apr 2013 07:23:17 +0000 (15:23 +0800)
committeryxj <yxj@rock-chips.com>
Fri, 19 Apr 2013 07:23:17 +0000 (15:23 +0800)
drivers/mfd/rk616-core.c
drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi.c
drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.c
drivers/video/rockchip/hdmi/chips/rk616/rk616_hdmi_hw.h
include/linux/mfd/rk616.h

index 44e85ae5b4276886b58bd981473bdb3573cb1322..cb929603d712e28c6449a96d60fa71f156732e73 100644 (file)
@@ -312,7 +312,7 @@ static int rk616_i2c_probe(struct i2c_client *client,const struct i2c_device_id
                dev_err(rk616->dev,"failed to create debugfs dir for rk616!\n");
        }
        else
-               debugfs_create_file("rk616-reg", S_IRUSR,rk616->debugfs_dir,rk616,&rk616_reg_fops);
+               debugfs_create_file("rk616-core", S_IRUSR,rk616->debugfs_dir,rk616,&rk616_reg_fops);
 #endif
        rk616_clk_common_init(rk616);
        ret = mfd_add_devices(rk616->dev, -1,
index 10ff85dde5465923222d9fc70da29b2752985667..12edee746db09af8e60fa8591db866f9e7bcc849 100755 (executable)
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
+#include <linux/uaccess.h>
 
 #include <mach/board.h>
 #include <mach/io.h>
 #include <mach/gpio.h>
 #include <mach/iomux.h>
+
+#if defined(CONFIG_DEBUG_FS)
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#endif
+
 #include "rk616_hdmi.h"
 #include "rk616_hdmi_hw.h"
 
@@ -28,6 +36,59 @@ extern struct rk_lcdc_device_driver * rk_get_lcdc_drv(char *name);
 extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent);
 extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi);
 
+
+
+#if defined(CONFIG_DEBUG_FS)
+static int rk616_hdmi_reg_show(struct seq_file *s, void *v)
+{
+       int i = 0;
+       u32 val = 0;
+       struct mfd_rk616 *rk616 = s->private;
+       if(!rk616)
+       {
+               dev_err(rk616->dev,"no mfd rk616!\n");
+               return 0;
+       }
+
+       for(i=0;i<= (PHY_PRE_DIV_RATIO << 2);i+=4)
+       {
+               rk616->read_dev(rk616,i,&val);
+               seq_printf(s,"reg%02x>>0x%08x\n",i>>2,val);
+       }
+
+       return 0;
+}
+
+static ssize_t rk616_hdmi_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+{ 
+       struct mfd_rk616 *rk616 = file->f_path.dentry->d_inode->i_private;
+       u32 reg;
+       u32 val;
+       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);
+       return count;
+}
+
+static int rk616_hdmi_reg_open(struct inode *inode, struct file *file)
+{
+       struct mfd_rk616 *rk616 = inode->i_private;
+       return single_open(file,rk616_hdmi_reg_show,rk616);
+}
+
+static const struct file_operations rk616_hdmi_reg_fops = {
+       .owner          = THIS_MODULE,
+       .open           = rk616_hdmi_reg_open,
+       .read           = seq_read,
+       .write          = rk616_hdmi_reg_write,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+#endif
+
 int rk616_hdmi_register_hdcp_callbacks(void (*hdcp_cb)(void),
                void (*hdcp_irq_cb)(int status),
                int (*hdcp_power_on_cb)(void),
@@ -144,21 +205,35 @@ static int __devinit rk616_hdmi_probe (struct platform_device *pdev)
        mutex_init(&hdmi->enable_mutex);
 
        /* get the IRQ */
-       hdmi->irq = platform_get_irq(pdev, 0);
-       if(hdmi->irq <= 0) {
-               dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n", hdmi->irq);
-               ret = -ENXIO;
-               goto err1;
-       }
+       if(rk616->pdata->hdmi_irq != INVALID_GPIO)
+       {
+               ret = gpio_request(rk616->pdata->hdmi_irq,"rk616_hdmi_irq");
+               if(ret < 0)
+               {
+                       dev_err(hdmi->dev,"request gpio for rk616 hdmi irq fail\n");
+               }
+               gpio_direction_input(rk616->pdata->hdmi_irq);
+               hdmi->irq = gpio_to_irq(rk616->pdata->hdmi_irq);
+               if(hdmi->irq <= 0) {
+                       dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n", hdmi->irq);
+                       ret = -ENXIO;
+                       goto err1;
+               }
 
-       /* request the IRQ */
-       ret = request_irq(hdmi->irq, hdmi_irq, 0, dev_name(&pdev->dev), hdmi);
-       if (ret)
+               /* request the IRQ */
+               ret = request_irq(hdmi->irq, hdmi_irq,IRQF_TRIGGER_FALLING,dev_name(&pdev->dev), hdmi);
+               if (ret)
+               {
+                       dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret);
+                       goto err1;
+               }
+       }
+#if defined(CONFIG_DEBUG_FS)
+       if(rk616->debugfs_dir)
        {
-               dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret);
-               goto err1;
+               debugfs_create_file("rk616-hdmi", S_IRUSR,rk616->debugfs_dir,rk616,&rk616_hdmi_reg_fops);
        }
-
+#endif
        dev_info(hdmi->dev, "rk616 hdmi probe success.\n");
        return 0;
 err1:
index 8af156e4823db675c1bb18e6eba1c820f974ee59..dca27eb0abfc6e766de242c0b94e5db3902f6538 100755 (executable)
@@ -7,6 +7,20 @@
 static char edid_result = 0;
 static bool analog_sync = 0;
 
+
+static int rk616_hdmi_init_pol_set(struct mfd_rk616 * rk616,int pol)
+{
+       u32 val;
+       int ret;
+       ret = rk616->read_dev(rk616,CRU_CFGMISC_CON,&val);
+       if(pol)
+               val &= 0xffffffdf;
+       else
+               val |= 0x20;
+       ret = rk616->write_dev(rk616,CRU_CFGMISC_CON,&val);
+
+       return 0;
+}
 static inline void delay100us(void)
 {
        msleep(1);
@@ -462,7 +476,7 @@ int rk616_hdmi_initial(void)
        hdmi->read_edid = rk616_hdmi_read_edid;
        
        rk616_hdmi_reset();
-       
+       //rk616_hdmi_init_pol_set(g_rk616_hdmi,0);
        if(hdmi->hdcp_power_on_cb)
                rc = hdmi->hdcp_power_on_cb();
 
index 40b1863f8241773551ec6bc24a2c6776e1014065..11ca16dedf2d546ed7a75de3564c2108ec3d6263 100755 (executable)
@@ -1,6 +1,7 @@
 #ifndef _RK616_HDMI_HW_H
 #define _RK616_HDMI_HW_H
 
+#define RK616_HDMI_BASE 0x400
 enum PWR_MODE{
     NORMAL,
     LOWER_PWR,
@@ -268,11 +269,11 @@ enum {
 #define PHY_PRE_DIV_RATIO              0xed
        #define v_PRE_DIV_RATIO(n)      (n&1f)
 
-#define HDMIRdReg(addr,val)            g_rk616_hdmi->read_dev(g_rk616_hdmi,addr,(u32 *)val) 
+#define HDMIRdReg(addr,val)            g_rk616_hdmi->read_dev(g_rk616_hdmi,(RK616_HDMI_BASE + ((addr)<<2)),(u32 *)val) 
 
 #define HDMIWrReg(addr, val)           do{ \
                                                u32 temp = val; \
-                                               g_rk616_hdmi->write_dev(g_rk616_hdmi,addr,&temp); \
+                                               g_rk616_hdmi->write_dev(g_rk616_hdmi,(RK616_HDMI_BASE + ((addr)<<2)),&temp); \
                                        }while(0)
 
 #define HDMIMskReg(addr,Msk,val)       do{ \
index df5bad7b2791e10341590825517ac9d0bd8fa43b..7ed0e4818e4863786151bc912844341bef1a2556 100644 (file)
@@ -184,6 +184,7 @@ struct rk616_platform_data {
        enum lcd_port_func lcd0_func;
        enum lcd_port_func lcd1_func;
        int lvds_ch_nr;                 //the number of used  lvds channel 
+       int hdmi_irq;
 };
 
 struct rk616_route {