1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/errno.h>
4 #include <linux/string.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>
16 #include <mach/board.h>
18 #include <mach/gpio.h>
19 #include <mach/iomux.h>
21 #if defined(CONFIG_DEBUG_FS)
23 #include <linux/debugfs.h>
24 #include <linux/seq_file.h>
27 #include "rk616_hdmi.h"
28 #include "rk616_hdmi_hw.h"
30 struct hdmi *hdmi = NULL;
31 struct mfd_rk616 *g_rk616_hdmi = NULL;
33 struct work_struct g_rk616_irq_work_struct;
34 struct delayed_work g_rk616_delay_work;
36 // extern void hdmi_irq(void);
37 extern void rk616_hdmi_work(void);
38 extern void hdmi_work(struct work_struct *work);
39 extern struct rk_lcdc_device_driver * rk_get_lcdc_drv(char *name);
40 extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent);
41 extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi);
44 #if defined(CONFIG_DEBUG_FS)
45 static int rk616_hdmi_reg_show(struct seq_file *s, void *v)
49 struct mfd_rk616 *rk616 = s->private;
52 dev_err(rk616->dev,"no mfd rk616!\n");
57 //seq_printf(s,"------>gpio = %d \n",gpio_get_value(rk616->pdata->hdmi_irq));
58 seq_printf(s, "\n>>>rk616_ctl reg");
59 for (i = 0; i < 16; i++) {
60 seq_printf(s, " %2x", i);
62 seq_printf(s, "\n-----------------------------------------------------------------");
64 for(i=0;i<= (PHY_PRE_DIV_RATIO << 2);i+=4)
66 rk616->read_dev(rk616,RK616_HDMI_BASE + i,&val);
67 //seq_printf(s,"reg%02x>>0x%08x\n",(i>>2),val);
69 seq_printf(s,"\n>>>rk616_ctl %2x:",i>>2);
70 seq_printf(s," %02x",val);
74 seq_printf(s, "\n-----------------------------------------------------------------\n");
79 static ssize_t rk616_hdmi_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
81 struct mfd_rk616 *rk616 = file->f_path.dentry->d_inode->i_private;
85 if (copy_from_user(kbuf, buf, count))
87 sscanf(kbuf, "%x%x", ®, &val);
88 if ((reg < 0) || (reg > 0xed))
90 printk("it is no hdmi reg\n");
93 printk("/**********rk616 reg config******/");
94 printk("\n reg=%x val=%x\n", reg, val);
96 //sscanf(kbuf, "%x%x", ®, &val);
97 dev_dbg(rk616->dev,"%s:reg:0x%04x val:0x%08x\n",__func__,reg, val);
98 rk616->write_dev(rk616, RK616_HDMI_BASE + (reg << 2), &val);
103 static int rk616_hdmi_reg_open(struct inode *inode, struct file *file)
105 struct mfd_rk616 *rk616 = inode->i_private;
106 return single_open(file,rk616_hdmi_reg_show,rk616);
109 static const struct file_operations rk616_hdmi_reg_fops = {
110 .owner = THIS_MODULE,
111 .open = rk616_hdmi_reg_open,
113 .write = rk616_hdmi_reg_write,
115 .release = single_release,
119 int rk616_hdmi_register_hdcp_callbacks(void (*hdcp_cb)(void),
120 void (*hdcp_irq_cb)(int status),
121 int (*hdcp_power_on_cb)(void),
122 void (*hdcp_power_off_cb)(void))
125 return HDMI_ERROR_FALSE;
127 hdmi->hdcp_cb = hdcp_cb;
128 hdmi->hdcp_irq_cb = hdcp_irq_cb;
129 hdmi->hdcp_power_on_cb = hdcp_power_on_cb;
130 hdmi->hdcp_power_off_cb = hdcp_power_off_cb;
132 return HDMI_ERROR_SUCESS;
135 #ifdef CONFIG_HAS_EARLYSUSPEND
136 static void hdmi_early_suspend(struct early_suspend *h)
138 hdmi_dbg(hdmi->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi->pwr_mode, hdmi->state);
140 flush_delayed_work(&hdmi->delay_work);
141 mutex_lock(&hdmi->enable_mutex);
144 mutex_unlock(&hdmi->enable_mutex);
149 disable_irq(hdmi->irq);
151 mutex_unlock(&hdmi->enable_mutex);
152 hdmi->command = HDMI_CONFIG_ENABLE;
153 init_completion(&hdmi->complete);
155 queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
156 wait_for_completion_interruptible_timeout(&hdmi->complete,
157 msecs_to_jiffies(5000));
158 flush_delayed_work(&hdmi->delay_work);
163 static void hdmi_early_resume(struct early_suspend *h)
165 hdmi_dbg(hdmi->dev, "hdmi exit early resume\n");
166 mutex_lock(&hdmi->enable_mutex);
169 rk616_hdmi_initial();
170 if(hdmi->enable && hdmi->irq) {
171 enable_irq(hdmi->irq);
175 if (g_rk616_hdmi->pdata->hdmi_irq == INVALID_GPIO)
176 queue_delayed_work(hdmi->workqueue, &g_rk616_delay_work, 100);
178 queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));
179 mutex_unlock(&hdmi->enable_mutex);
183 static void rk616_delay_work_func(struct work_struct *work)
185 if(hdmi->suspend == 0) {
186 if(hdmi->enable == 1) {
191 if (g_rk616_hdmi->pdata->hdmi_irq == INVALID_GPIO) {
192 queue_delayed_work(hdmi->workqueue, &g_rk616_delay_work, 100);
197 static void rk616_irq_work_func(struct work_struct *work)
199 if((hdmi->suspend == 0) && (hdmi->enable == 1)) {
202 hdmi_dbg(hdmi->dev, "func: %s, enable_irq\n", __func__);
203 enable_irq(hdmi->irq);
208 static irqreturn_t rk616_hdmi_irq(int irq, void *dev_id)
210 struct work_struct *rk616_irq_work_struct;
212 rk616_irq_work_struct = dev_id;
213 disable_irq_nosync(hdmi->irq);
214 printk(KERN_INFO "rk616_hdmi_irq irq triggered.\n");
215 queue_work(hdmi->workqueue, rk616_irq_work_struct);
219 static int __devinit rk616_hdmi_probe (struct platform_device *pdev)
223 struct mfd_rk616 *rk616 = dev_get_drvdata(pdev->dev.parent);
226 dev_err(&pdev->dev,"null mfd device rk616!\n");
230 g_rk616_hdmi = rk616;
232 hdmi = kmalloc(sizeof(struct hdmi), GFP_KERNEL);
235 dev_err(&pdev->dev, ">>rk616 hdmi kmalloc fail!");
238 memset(hdmi, 0, sizeof(struct hdmi));
239 hdmi->dev = &pdev->dev;
240 platform_set_drvdata(pdev, hdmi);
242 if(HDMI_SOURCE_DEFAULT == HDMI_SOURCE_LCDC0)
243 hdmi->lcdc = rk_get_lcdc_drv("lcdc0");
245 hdmi->lcdc = rk_get_lcdc_drv("lcdc1");
246 if(hdmi->lcdc == NULL)
248 dev_err(hdmi->dev, "can not connect to video source lcdc\n");
255 ret = rk616_hdmi_initial();
259 hdmi->workqueue = create_singlethread_workqueue("hdmi");
260 INIT_DELAYED_WORK(&(hdmi->delay_work), hdmi_work);
262 #ifdef CONFIG_HAS_EARLYSUSPEND
263 hdmi->early_suspend.suspend = hdmi_early_suspend;
264 hdmi->early_suspend.resume = hdmi_early_resume;
265 hdmi->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 10;
266 register_early_suspend(&hdmi->early_suspend);
269 hdmi_register_display_sysfs(hdmi, NULL);
271 hdmi->switch_hdmi.name="hdmi";
272 switch_dev_register(&(hdmi->switch_hdmi));
275 spin_lock_init(&hdmi->irq_lock);
276 mutex_init(&hdmi->enable_mutex);
278 INIT_DELAYED_WORK(&g_rk616_delay_work, rk616_delay_work_func);
280 if(rk616->pdata->hdmi_irq != INVALID_GPIO)
282 INIT_WORK(&g_rk616_irq_work_struct, rk616_irq_work_func);
283 ret = gpio_request(rk616->pdata->hdmi_irq,"rk616_hdmi_irq");
286 dev_err(hdmi->dev,"request gpio for rk616 hdmi irq fail\n");
288 gpio_direction_input(rk616->pdata->hdmi_irq);
289 hdmi->irq = gpio_to_irq(rk616->pdata->hdmi_irq);
291 dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n", hdmi->irq);
296 /* request the IRQ */
297 ret = request_irq(hdmi->irq, rk616_hdmi_irq, IRQF_TRIGGER_LOW, dev_name(&pdev->dev), &g_rk616_irq_work_struct);
300 dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret);
305 /* use roll polling method */
308 #if defined(CONFIG_DEBUG_FS)
309 if(rk616->debugfs_dir)
311 debugfs_create_file("hdmi", S_IRUSR,rk616->debugfs_dir,rk616,&rk616_hdmi_reg_fops);
314 // rk616_delay_work_func(NULL);
315 queue_delayed_work(hdmi->workqueue, &g_rk616_delay_work, msecs_to_jiffies(0));
316 dev_info(hdmi->dev, "rk616 hdmi probe success.\n");
320 switch_dev_unregister(&(hdmi->switch_hdmi));
322 hdmi_unregister_display_sysfs(hdmi);
323 #ifdef CONFIG_HAS_EARLYSUSPEND
324 unregister_early_suspend(&hdmi->early_suspend);
327 hdmi_dbg(hdmi->dev, "rk616 hdmi probe error.\n");
333 static int __devexit rk616_hdmi_remove(struct platform_device *pdev)
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);
341 free_irq(hdmi->irq, NULL);
343 flush_workqueue(hdmi->workqueue);
344 destroy_workqueue(hdmi->workqueue);
346 switch_dev_unregister(&(hdmi->switch_hdmi));
348 hdmi_unregister_display_sysfs(hdmi);
349 #ifdef CONFIG_HAS_EARLYSUSPEND
350 unregister_early_suspend(&hdmi->early_suspend);
352 fb_destroy_modelist(&hdmi->edid.modelist);
354 kfree(hdmi->edid.audio);
357 if(hdmi->edid.specs->modedb)
358 kfree(hdmi->edid.specs->modedb);
359 kfree(hdmi->edid.specs);
364 printk(KERN_INFO "rk616 hdmi removed.\n");
368 static void rk616_hdmi_shutdown(struct platform_device *pdev)
371 #ifdef CONFIG_HAS_EARLYSUSPEND
372 unregister_early_suspend(&hdmi->early_suspend);
374 flush_delayed_work(&hdmi->delay_work);
375 mutex_lock(&hdmi->enable_mutex);
378 mutex_unlock(&hdmi->enable_mutex);
382 disable_irq(hdmi->irq);
383 mutex_unlock(&hdmi->enable_mutex);
385 printk(KERN_INFO "rk616 hdmi shut down.\n");
388 static struct platform_driver rk616_hdmi_driver = {
389 .probe = rk616_hdmi_probe,
390 .remove = __devexit_p(rk616_hdmi_remove),
392 .name = "rk616-hdmi",
393 .owner = THIS_MODULE,
395 .shutdown = rk616_hdmi_shutdown,
398 static int __init rk616_hdmi_init(void)
400 return platform_driver_register(&rk616_hdmi_driver);
403 static void __exit rk616_hdmi_exit(void)
405 platform_driver_unregister(&rk616_hdmi_driver);
409 //fs_initcall(rk616_hdmi_init);
410 late_initcall(rk616_hdmi_init);
411 module_exit(rk616_hdmi_exit);