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 <linux/of_gpio.h>
17 #include <linux/rk_fb.h>
19 #if defined(CONFIG_DEBUG_FS)
21 #include <linux/debugfs.h>
22 #include <linux/seq_file.h>
25 #include "rockchip_hdmiv1.h"
26 #include "rockchip_hdmiv1_hw.h"
28 static struct hdmi_dev *hdmi_dev;
30 #if defined(CONFIG_DEBUG_FS)
31 static int rockchip_hdmiv1_reg_show(struct seq_file *s, void *v)
36 seq_puts(s, "\n\n>>>rk3036_ctl reg");
37 for (i = 0; i < 16; i++)
38 seq_printf(s, " %2x", i);
41 "\n-----------------------------------------------------------------");
43 for (i = 0; i <= PHY_PRE_DIV_RATIO; i++) {
44 hdmi_readl(hdmi_dev, i, &val);
46 seq_printf(s, "\n>>>rk3036_ctl %2x:", i);
47 seq_printf(s, " %02x", val);
50 "\n-----------------------------------------------------------------\n");
55 static ssize_t rockchip_hdmiv1_reg_write(struct file *file,
56 const char __user *buf,
64 struct hdmi *hdmi_drv = hdmi_dev->hdmi;
66 if (copy_from_user(kbuf, buf, count))
68 ret = sscanf(kbuf, "%x%x", ®, &val);
69 if ((reg < 0) || (reg > 0xed)) {
70 dev_info(hdmi_drv->dev, "it is no hdmi reg\n");
73 dev_info(hdmi_drv->dev, "/**********rk3036 reg config******/");
74 dev_info(hdmi_drv->dev, "\n reg=%x val=%x\n", reg, val);
75 hdmi_writel(hdmi_dev, reg, val);
80 static int rockchip_hdmiv1_reg_open(struct inode *inode, struct file *file)
82 return single_open(file, rockchip_hdmiv1_reg_show, NULL);
85 static const struct file_operations rockchip_hdmiv1_reg_fops = {
87 .open = rockchip_hdmiv1_reg_open,
89 .write = rockchip_hdmiv1_reg_write,
91 .release = single_release,
95 static int rockchip_hdmiv1_clk_enable(struct hdmi_dev *hdmi_dev)
97 struct hdmi *hdmi_drv;
99 hdmi_drv = hdmi_dev->hdmi;
100 if (!hdmi_dev->clk_on) {
101 if (hdmi_dev->soctype == HDMI_SOC_RK312X)
102 clk_prepare_enable(hdmi_dev->pd);
104 clk_prepare_enable(hdmi_dev->hclk);
105 spin_lock(&hdmi_dev->reg_lock);
106 hdmi_dev->clk_on = 1;
107 spin_unlock(&hdmi_dev->reg_lock);
113 static int rockchip_hdmiv1_clk_disable(struct hdmi_dev *hdmi_dev)
115 struct hdmi *hdmi_drv;
117 hdmi_drv = hdmi_dev->hdmi;
118 if (hdmi_dev->clk_on) {
119 spin_lock(&hdmi_dev->reg_lock);
120 hdmi_dev->clk_on = 0;
121 spin_unlock(&hdmi_dev->reg_lock);
122 if (hdmi_dev->soctype == HDMI_SOC_RK312X)
123 clk_disable_unprepare(hdmi_dev->pd);
124 clk_disable_unprepare(hdmi_dev->hclk);
130 static void rockchip_hdmiv1_early_suspend(void)
132 struct hdmi *hdmi_drv = hdmi_dev->hdmi;
134 dev_info(hdmi_drv->dev, "hdmi suspend\n");
135 hdmi_submit_work(hdmi_drv,
136 HDMI_SUSPEND_CTL, 0, 1);
137 mutex_lock(&hdmi_drv->lock);
139 disable_irq(hdmi_dev->irq);
140 mutex_unlock(&hdmi_drv->lock);
141 rockchip_hdmiv1_clk_disable(hdmi_dev);
144 static void rockchip_hdmiv1_early_resume(void)
146 struct hdmi *hdmi_drv = hdmi_dev->hdmi;
148 dev_info(hdmi_drv->dev, "hdmi resume\n");
149 mutex_lock(&hdmi_drv->lock);
150 rockchip_hdmiv1_clk_enable(hdmi_dev);
151 rockchip_hdmiv1_initial(hdmi_drv);
152 if (hdmi_drv->enable && hdmi_dev->irq) {
153 rockchip_hdmiv1_irq(hdmi_drv);
154 enable_irq(hdmi_dev->irq);
156 mutex_unlock(&hdmi_drv->lock);
157 hdmi_submit_work(hdmi_drv, HDMI_RESUME_CTL, 0, 0);
160 static int rockchip_hdmiv1_fb_event_notify(struct notifier_block *self,
161 unsigned long action,
164 struct fb_event *event = data;
165 int blank_mode = *((int *)event->data);
167 if (action == FB_EARLY_EVENT_BLANK) {
168 switch (blank_mode) {
169 case FB_BLANK_UNBLANK:
172 if (!hdmi_dev->hdmi->sleep)
173 rockchip_hdmiv1_early_suspend();
176 } else if (action == FB_EVENT_BLANK) {
177 switch (blank_mode) {
178 case FB_BLANK_UNBLANK:
179 if (hdmi_dev->hdmi->sleep)
180 rockchip_hdmiv1_early_resume();
190 static struct notifier_block rockchip_hdmiv1_fb_notifier = {
191 .notifier_call = rockchip_hdmiv1_fb_event_notify,
194 static irqreturn_t rockchip_hdmiv1_irq_func(int irq, void *dev_id)
196 struct hdmi *hdmi_drv = hdmi_dev->hdmi;
198 rockchip_hdmiv1_irq(hdmi_drv);
203 static struct hdmi_property rockchip_hdmiv1_property = {
204 .videosrc = DISPLAY_SOURCE_LCDC0,
205 .display = DISPLAY_MAIN,
207 static struct hdmi_ops rockchip_hdmiv1_ops;
209 #if defined(CONFIG_OF)
210 static const struct of_device_id rockchip_hdmiv1_dt_ids[] = {
211 {.compatible = "rockchip,rk3036-hdmi"},
212 {.compatible = "rockchip,rk312x-hdmi"},
216 static int rockchip_hdmiv1_parse_dt(struct hdmi_dev *hdmi_dev)
219 struct device_node *np = hdmi_dev->dev->of_node;
220 const struct of_device_id *match;
222 match = of_match_node(rockchip_hdmiv1_dt_ids, np);
224 return PTR_ERR(match);
226 if (!strcmp(match->compatible, "rockchip,rk3036-hdmi")) {
227 hdmi_dev->soctype = HDMI_SOC_RK3036;
228 } else if (!strcmp(match->compatible, "rockchip,rk312x-hdmi")) {
229 hdmi_dev->soctype = HDMI_SOC_RK312X;
231 pr_err("It is not a valid rockchip soc!");
235 if (!of_property_read_u32(np, "rockchip,hdmi_video_source", &val))
236 rockchip_hdmiv1_property.videosrc = val;
238 if (!of_property_read_u32(np, "rockchip,hdmi_audio_source", &val))
239 hdmi_dev->audiosrc = val;
241 if (!of_property_read_u32(np, "rockchip,cec_enable", &val) &&
243 pr_debug("hdmi support cec\n");
244 rockchip_hdmiv1_property.feature |= SUPPORT_CEC;
246 if (!of_property_read_u32(np, "rockchip,hdcp_enable", &val) &&
248 pr_debug("hdmi support hdcp\n");
249 rockchip_hdmiv1_property.feature |= SUPPORT_HDCP;
251 if (!of_property_read_u32(np, "rockchip,defaultmode", &val) &&
253 pr_debug("default mode is %d\n", val);
254 rockchip_hdmiv1_property.defaultmode = val;
256 rockchip_hdmiv1_property.defaultmode =
257 HDMI_VIDEO_DEFAULT_MODE;
262 MODULE_DEVICE_TABLE(of, rockchip_hdmiv1_dt_ids);
266 static int rockchip_hdmiv1_probe(struct platform_device *pdev)
269 struct resource *res;
271 hdmi_dev = devm_kzalloc(&pdev->dev,
272 sizeof(struct hdmi_dev),
275 dev_err(hdmi_dev->dev, ">>rk_hdmi kmalloc fail!");
278 hdmi_dev->dev = &pdev->dev;
279 platform_set_drvdata(pdev, hdmi_dev);
280 spin_lock_init(&hdmi_dev->reg_lock);
281 rockchip_hdmiv1_parse_dt(hdmi_dev);
282 /* request and remap iomem */
283 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
285 dev_err(hdmi_dev->dev, "Unable to get register resource\n");
289 hdmi_dev->regbase_phy = res->start;
290 hdmi_dev->regsize_phy = resource_size(res);
291 hdmi_dev->regbase = devm_ioremap_resource(&pdev->dev, res);
292 if (IS_ERR(hdmi_dev->regbase)) {
293 ret = PTR_ERR(hdmi_dev->regbase);
294 dev_err(hdmi_dev->dev, "cannot ioremap registers,err=%d\n",
298 if (hdmi_dev->soctype == HDMI_SOC_RK312X) {
299 hdmi_dev->pd = devm_clk_get(hdmi_dev->dev, "pd_hdmi");
300 if (IS_ERR(hdmi_dev->pd)) {
301 dev_err(hdmi_dev->hdmi->dev, "Unable to get hdmi pd\n");
306 hdmi_dev->hclk = devm_clk_get(hdmi_dev->dev, "pclk_hdmi");
307 if (IS_ERR(hdmi_dev->hclk)) {
308 dev_err(hdmi_dev->hdmi->dev, "Unable to get hdmi hclk\n");
313 rockchip_hdmiv1_clk_enable(hdmi_dev);
314 hdmi_dev->hclk_rate = clk_get_rate(hdmi_dev->hclk);
316 rockchip_hdmiv1_dev_init_ops(&rockchip_hdmiv1_ops);
317 rockchip_hdmiv1_property.name = (char *)pdev->name;
318 rockchip_hdmiv1_property.priv = hdmi_dev;
319 if (rk_fb_get_display_policy() == DISPLAY_POLICY_BOX)
320 rockchip_hdmiv1_property.feature |= SUPPORT_1080I |
322 hdmi_dev->hdmi = rockchip_hdmi_register(&rockchip_hdmiv1_property,
323 &rockchip_hdmiv1_ops);
324 if (hdmi_dev->hdmi == NULL) {
325 dev_err(&pdev->dev, "register hdmi device failed\n");
329 hdmi_dev->hdmi->dev = &pdev->dev;
331 fb_register_client(&rockchip_hdmiv1_fb_notifier);
332 rockchip_hdmiv1_initial(hdmi_dev->hdmi);
334 rk_display_device_enable(hdmi_dev->hdmi->ddev);
335 hdmi_submit_work(hdmi_dev->hdmi, HDMI_HPD_CHANGE, 0, 1);
337 #if defined(CONFIG_DEBUG_FS)
338 hdmi_dev->debugfs_dir = debugfs_create_dir("rockchip_hdmiv1", NULL);
339 if (IS_ERR(hdmi_dev->debugfs_dir)) {
340 dev_err(hdmi_dev->hdmi->dev,
341 "failed to create debugfs dir for hdmi!\n");
343 debugfs_create_file("hdmi", S_IRUSR,
344 hdmi_dev->debugfs_dir, hdmi_dev->hdmi,
345 &rockchip_hdmiv1_reg_fops);
350 hdmi_dev->irq = platform_get_irq(pdev, 0);
351 if (hdmi_dev->irq <= 0) {
352 dev_err(hdmi_dev->hdmi->dev, "failed to get hdmi irq resource (%d).\n",
356 /* request the IRQ */
357 ret = devm_request_irq(hdmi_dev->hdmi->dev,
359 rockchip_hdmiv1_irq_func,
360 IRQF_TRIGGER_HIGH | IRQF_DISABLED,
361 dev_name(hdmi_dev->hdmi->dev),
364 dev_err(hdmi_dev->hdmi->dev, "hdmi request_irq failed (%d)\n",
369 dev_info(hdmi_dev->hdmi->dev, "hdmi probe success.\n");
373 rockchip_hdmi_unregister(hdmi_dev->hdmi);
377 dev_err(&pdev->dev, "rk3288 hdmi probe error.\n");
381 static int rockchip_hdmiv1_remove(struct platform_device *pdev)
383 struct hdmi *hdmi_drv = NULL;
385 hdmi_drv = hdmi_dev->hdmi;
386 rockchip_hdmi_unregister(hdmi_drv);
390 static void rockchip_hdmiv1_shutdown(struct platform_device *pdev)
392 struct hdmi_dev *hdmi_dev = platform_get_drvdata(pdev);
393 struct hdmi *hdmi_drv = NULL;
396 hdmi_drv = hdmi_dev->hdmi;
397 #ifdef CONFIG_HAS_EARLYSUSPEND
398 unregister_early_suspend(&hdmi_drv->early_suspend);
400 mutex_lock(&hdmi_drv->lock);
402 if (!hdmi_drv->enable) {
403 mutex_unlock(&hdmi_drv->lock);
407 disable_irq(hdmi_dev->irq);
408 mutex_unlock(&hdmi_drv->lock);
409 if (hdmi_drv->hotplug == HDMI_HPD_ACTIVED)
410 hdmi_drv->ops->setmute(hdmi_drv,
413 rockchip_hdmiv1_clk_disable(hdmi_dev);
415 dev_info(hdmi_drv->dev, "rk hdmi shut down.\n");
419 static struct platform_driver rockchip_hdmiv1_driver = {
420 .probe = rockchip_hdmiv1_probe,
421 .remove = rockchip_hdmiv1_remove,
424 .owner = THIS_MODULE,
425 #if defined(CONFIG_OF)
426 .of_match_table = of_match_ptr(rockchip_hdmiv1_dt_ids),
429 .shutdown = rockchip_hdmiv1_shutdown,
432 static int __init rockchip_hdmiv1_init(void)
434 return platform_driver_register(&rockchip_hdmiv1_driver);
437 static void __exit rockchip_hdmiv1_exit(void)
439 platform_driver_unregister(&rockchip_hdmiv1_driver);
442 module_init(rockchip_hdmiv1_init);
443 module_exit(rockchip_hdmiv1_exit);