rk616 hdmi: modify some time edid read err and delete some no necessary log
[firefly-linux-kernel-4.4.55.git] / drivers / video / rockchip / hdmi / chips / rk616 / rk616_hdmi.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/errno.h>
4 #include <linux/string.h>
5 #include <linux/mm.h>
6 #include <linux/slab.h>
7 #include <linux/delay.h>
8 #include <linux/device.h>
9 #include <linux/init.h>
10 #include <linux/dma-mapping.h>
11 #include <linux/interrupt.h>
12 #include <linux/platform_device.h>
13 #include <linux/clk.h>
14 #include <linux/uaccess.h>
15
16 #include <mach/board.h>
17 #include <mach/io.h>
18 #include <mach/gpio.h>
19 #include <mach/iomux.h>
20 #include <linux/rk_fb.h> 
21
22 #if defined(CONFIG_DEBUG_FS)
23 #include <linux/fs.h>
24 #include <linux/debugfs.h>
25 #include <linux/seq_file.h>
26 #endif
27
28 #include "rk616_hdmi.h"
29 #include "rk616_hdmi_hw.h"
30
31 extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent);
32 extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi);
33
34 struct hdmi *hdmi = NULL;
35
36 #if defined(CONFIG_DEBUG_FS)
37 static int rk616_hdmi_reg_show(struct seq_file *s, void *v)
38 {
39         int i = 0;
40         u32 val = 0;
41         struct mfd_rk616 *rk616 = s->private;
42         if(!rk616)
43         {
44                 dev_err(rk616->dev,"no mfd rk616!\n");
45                 return 0;
46         }
47
48         seq_printf(s, "\n>>>rk616_ctl reg");
49         for (i = 0; i < 16; i++) {
50                 seq_printf(s, " %2x", i);
51         }
52         seq_printf(s, "\n-----------------------------------------------------------------");
53         
54         for(i=0;i<= (PHY_PRE_DIV_RATIO << 2);i+=4)
55         {
56                 rk616->read_dev(rk616,RK616_HDMI_BASE + i,&val);
57                 //seq_printf(s,"reg%02x>>0x%08x\n",(i>>2),val);
58                 if((i>>2)%16==0)
59                         seq_printf(s,"\n>>>rk616_ctl %2x:",i>>2);
60                 seq_printf(s," %02x",val);
61
62         }
63         
64         seq_printf(s, "\n-----------------------------------------------------------------\n");
65         
66         return 0;
67 }
68
69 static ssize_t rk616_hdmi_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
70
71         struct mfd_rk616 *rk616 = file->f_path.dentry->d_inode->i_private;
72         u32 reg;
73         u32 val;
74         char kbuf[25];
75         if (copy_from_user(kbuf, buf, count))
76                 return -EFAULT;
77         sscanf(kbuf, "%x%x", &reg, &val);
78         if ((reg < 0) || (reg > 0xed))
79         {
80                 printk("it is no hdmi reg\n");
81                 return count;
82         }
83         printk("/**********rk616 reg config******/");
84         printk("\n reg=%x val=%x\n", reg, val);
85
86         //sscanf(kbuf, "%x%x", &reg, &val);
87         dev_dbg(rk616->dev,"%s:reg:0x%04x val:0x%08x\n",__func__,reg, val);
88         rk616->write_dev(rk616, RK616_HDMI_BASE + (reg << 2), &val);
89
90         return count;
91 }
92
93 static int rk616_hdmi_reg_open(struct inode *inode, struct file *file)
94 {
95         struct mfd_rk616 *rk616 = inode->i_private;
96         return single_open(file,rk616_hdmi_reg_show,rk616);
97 }
98
99 static const struct file_operations rk616_hdmi_reg_fops = {
100         .owner          = THIS_MODULE,
101         .open           = rk616_hdmi_reg_open,
102         .read           = seq_read,
103         .write          = rk616_hdmi_reg_write,
104         .llseek         = seq_lseek,
105         .release        = single_release,
106 };
107 #endif
108
109 int rk616_hdmi_register_hdcp_callbacks(void (*hdcp_cb)(void),
110                 void (*hdcp_irq_cb)(int status),
111                 int (*hdcp_power_on_cb)(void),
112                 void (*hdcp_power_off_cb)(void))
113 {
114         if(hdmi == NULL)
115                 return HDMI_ERROR_FALSE;
116
117         hdmi->hdcp_cb = hdcp_cb;
118         hdmi->hdcp_irq_cb = hdcp_irq_cb;
119         hdmi->hdcp_power_on_cb = hdcp_power_on_cb;
120         hdmi->hdcp_power_off_cb = hdcp_power_off_cb;
121
122         return HDMI_ERROR_SUCESS;
123 }
124
125 #ifdef CONFIG_HAS_EARLYSUSPEND
126 static void hdmi_early_suspend(struct early_suspend *h)
127 {
128         hdmi_dbg(hdmi->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi->pwr_mode, hdmi->state);
129
130         flush_delayed_work(&hdmi->delay_work);  
131         mutex_lock(&hdmi->enable_mutex);
132         hdmi->suspend = 1;
133         if(!hdmi->enable) {
134                 mutex_unlock(&hdmi->enable_mutex);
135                 return;
136         }
137
138         if (hdmi->irq)
139                 disable_irq(hdmi->irq);
140
141         mutex_unlock(&hdmi->enable_mutex);
142         hdmi->command = HDMI_CONFIG_ENABLE;
143         init_completion(&hdmi->complete);
144         hdmi->wait = 1;
145         queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
146         wait_for_completion_interruptible_timeout(&hdmi->complete,
147                         msecs_to_jiffies(5000));
148         flush_delayed_work(&hdmi->delay_work);
149
150         return;
151 }
152
153 static void hdmi_early_resume(struct early_suspend *h)
154 {
155         struct rk616_hdmi *rk616_hdmi;
156
157         rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
158         hdmi_dbg(hdmi->dev, "hdmi exit early resume\n");
159
160         mutex_lock(&hdmi->enable_mutex);
161
162         hdmi->suspend = 0;
163         rk616_hdmi_initial();
164         if(hdmi->enable && hdmi->irq) {
165                 enable_irq(hdmi->irq);
166                 // hdmi_irq();
167                 rk616_hdmi_work();
168         }
169
170         if (rk616_hdmi->rk616_drv->pdata->hdmi_irq == INVALID_GPIO) 
171                 queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, 100);
172
173         queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));   
174         mutex_unlock(&hdmi->enable_mutex);
175         return;
176 }
177 #endif
178 static void rk616_delay_work_func(struct work_struct *work)
179 {
180         struct rk616_hdmi *rk616_hdmi;
181
182         rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
183
184         if(hdmi->suspend == 0) {
185                 if(hdmi->enable == 1) {
186                         //hdmi_irq();
187                         rk616_hdmi_work();
188                 }
189
190                 if (rk616_hdmi->rk616_drv->pdata->hdmi_irq == INVALID_GPIO) {
191                         queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, 100);
192                 }
193         }
194 }
195
196 static void rk616_irq_work_func(struct work_struct *work)
197 {
198         if((hdmi->suspend == 0) && (hdmi->enable == 1)) {
199                 rk616_hdmi_work();
200         }
201         dev_info(hdmi->dev, "func: %s, enable_irq\n", __func__);
202         enable_irq(hdmi->irq);
203 }
204
205 #if 1
206 static irqreturn_t rk616_hdmi_irq(int irq, void *dev_id)
207 {
208         struct work_struct  *rk616_irq_work_struct;
209
210         rk616_irq_work_struct  = dev_id;
211         disable_irq_nosync(hdmi->irq);
212         //printk(KERN_INFO "rk616_hdmi_irq irq triggered.\n");
213         queue_work(hdmi->workqueue, rk616_irq_work_struct);
214         return IRQ_HANDLED;
215 }
216 #endif
217 static int __devinit rk616_hdmi_probe (struct platform_device *pdev)
218 {
219         int ret;
220         struct rk616_hdmi *rk616_hdmi;
221
222         struct mfd_rk616 *rk616 = dev_get_drvdata(pdev->dev.parent);
223         if(!rk616)
224         {
225                 dev_err(&pdev->dev,"null mfd device rk616!\n");
226                 return -ENODEV;
227         }
228
229         rk616_hdmi = devm_kzalloc(&pdev->dev, sizeof(*rk616_hdmi), GFP_KERNEL);
230         if(!rk616_hdmi)
231         {
232                 dev_err(&pdev->dev, ">>rk616_hdmi kmalloc fail!");
233                 return -ENOMEM;
234         }
235         hdmi = &rk616_hdmi->g_hdmi;
236         rk616_hdmi->rk616_drv = rk616;
237
238         hdmi->dev = &pdev->dev;
239         platform_set_drvdata(pdev, hdmi);
240
241         if(HDMI_SOURCE_DEFAULT == HDMI_SOURCE_LCDC0)
242                 hdmi->lcdc = rk_get_lcdc_drv("lcdc0");
243         else
244                 hdmi->lcdc = rk_get_lcdc_drv("lcdc1");
245         if(hdmi->lcdc == NULL)
246         {
247                 dev_err(hdmi->dev, "can not connect to video source lcdc\n");
248                 ret = -ENXIO;
249                 goto err0;
250         }
251         hdmi->xscale = 100;
252         hdmi->yscale = 100;
253
254         ret = rk616_hdmi_initial();
255
256         hdmi_sys_init();
257
258         hdmi->workqueue = create_singlethread_workqueue("hdmi");
259         INIT_DELAYED_WORK(&(hdmi->delay_work), hdmi_work);
260
261 #ifdef CONFIG_HAS_EARLYSUSPEND
262         hdmi->early_suspend.suspend = hdmi_early_suspend;
263         hdmi->early_suspend.resume = hdmi_early_resume;
264         hdmi->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 10;
265         register_early_suspend(&hdmi->early_suspend);
266 #endif
267
268         hdmi_register_display_sysfs(hdmi, NULL);
269 #ifdef CONFIG_SWITCH
270         hdmi->switch_hdmi.name="hdmi";
271         switch_dev_register(&(hdmi->switch_hdmi));
272 #endif
273
274         spin_lock_init(&hdmi->irq_lock);
275         mutex_init(&hdmi->enable_mutex);
276
277         INIT_DELAYED_WORK(&rk616_hdmi->rk616_delay_work, rk616_delay_work_func);
278
279         /* get the IRQ */
280         if(rk616->pdata->hdmi_irq != INVALID_GPIO)
281         {
282                 INIT_WORK(&rk616_hdmi->rk616_irq_work_struct, rk616_irq_work_func);
283                 ret = gpio_request(rk616->pdata->hdmi_irq,"rk616_hdmi_irq");
284                 if(ret < 0)
285                 {
286                         dev_err(hdmi->dev,"request gpio for rk616 hdmi irq fail\n");
287                 }
288                 gpio_direction_input(rk616->pdata->hdmi_irq);
289                 hdmi->irq = gpio_to_irq(rk616->pdata->hdmi_irq);
290                 if(hdmi->irq <= 0) {
291                         dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n", hdmi->irq);
292                         ret = -ENXIO;
293                         goto err1;
294                 }
295
296                 /* request the IRQ */
297                 ret = request_irq(hdmi->irq, rk616_hdmi_irq, IRQF_TRIGGER_LOW, dev_name(&pdev->dev), &rk616_hdmi->rk616_irq_work_struct);
298                 if (ret)
299                 {
300                         dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret);
301                         goto err1;
302                 }
303         } else {
304
305                 /* use roll polling method */
306                 hdmi->irq = 0;
307         }
308 #if defined(CONFIG_DEBUG_FS)
309         if(rk616->debugfs_dir)
310         {
311                 debugfs_create_file("hdmi", S_IRUSR,rk616->debugfs_dir,rk616,&rk616_hdmi_reg_fops);
312         }
313 #endif
314         // rk616_delay_work_func(NULL);
315         queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, msecs_to_jiffies(0));
316         dev_info(hdmi->dev, "rk616 hdmi probe success.\n");
317         return 0;
318 err1:
319 #ifdef CONFIG_SWITCH
320         switch_dev_unregister(&(hdmi->switch_hdmi));
321 #endif
322         hdmi_unregister_display_sysfs(hdmi);
323 #ifdef CONFIG_HAS_EARLYSUSPEND
324         unregister_early_suspend(&hdmi->early_suspend);
325 #endif
326 err0:
327         hdmi_dbg(hdmi->dev, "rk616 hdmi probe error.\n");
328         kfree(hdmi);
329         hdmi = NULL;
330         return ret;
331 }
332
333 static int __devexit rk616_hdmi_remove(struct platform_device *pdev)
334 {
335         if(hdmi) {
336                 mutex_lock(&hdmi->enable_mutex);
337                 if(!hdmi->suspend && hdmi->enable && hdmi->irq)
338                         disable_irq(hdmi->irq);
339                 mutex_unlock(&hdmi->enable_mutex);
340                 if (hdmi->irq) {
341                         free_irq(hdmi->irq, NULL);
342                 }
343                 flush_workqueue(hdmi->workqueue);
344                 destroy_workqueue(hdmi->workqueue);
345 #ifdef CONFIG_SWITCH
346                 switch_dev_unregister(&(hdmi->switch_hdmi));
347 #endif
348                 hdmi_unregister_display_sysfs(hdmi);
349 #ifdef CONFIG_HAS_EARLYSUSPEND
350                 unregister_early_suspend(&hdmi->early_suspend);
351 #endif
352                 fb_destroy_modelist(&hdmi->edid.modelist);
353                 if(hdmi->edid.audio)
354                         kfree(hdmi->edid.audio);
355                 if(hdmi->edid.specs)
356                 {
357                         if(hdmi->edid.specs->modedb)
358                                 kfree(hdmi->edid.specs->modedb);
359                         kfree(hdmi->edid.specs);
360                 }
361                 kfree(hdmi);
362                 hdmi = NULL;
363         }
364         hdmi_dbg(hdmi->dev, "rk616 hdmi removed.\n");
365         return 0;
366 }
367
368 static void rk616_hdmi_shutdown(struct platform_device *pdev)
369 {
370         if(hdmi) {
371 #ifdef CONFIG_HAS_EARLYSUSPEND
372                 unregister_early_suspend(&hdmi->early_suspend);
373 #endif 
374                 flush_delayed_work(&hdmi->delay_work);
375                 mutex_lock(&hdmi->enable_mutex);
376                 hdmi->suspend = 1;
377                 if(!hdmi->enable) {
378                         mutex_unlock(&hdmi->enable_mutex);
379                         return;
380                 }
381                 if (hdmi->irq)
382                         disable_irq(hdmi->irq);
383                 mutex_unlock(&hdmi->enable_mutex);
384         }
385         hdmi_dbg(hdmi->dev,  "rk616 hdmi shut down.\n");
386 }
387
388 static struct platform_driver rk616_hdmi_driver = {
389         .probe          = rk616_hdmi_probe,
390         .remove         = __devexit_p(rk616_hdmi_remove),
391         .driver         = {
392                 .name   = "rk616-hdmi",
393                 .owner  = THIS_MODULE,
394         },
395         .shutdown   = rk616_hdmi_shutdown,
396 };
397
398 static int __init rk616_hdmi_init(void)
399 {
400         return platform_driver_register(&rk616_hdmi_driver);
401 }
402
403 static void __exit rk616_hdmi_exit(void)
404 {
405         platform_driver_unregister(&rk616_hdmi_driver);
406 }
407
408
409 //fs_initcall(rk616_hdmi_init);
410 late_initcall(rk616_hdmi_init);
411 module_exit(rk616_hdmi_exit);