Exemple #1
0
static void hdmi_early_resume(struct early_suspend *h)
{
	struct rk616_hdmi *rk616_hdmi;

	rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
	hdmi_dbg(hdmi->dev, "hdmi exit early resume\n");

	mutex_lock(&hdmi->enable_mutex);

	hdmi->suspend = 0;
	rk616_hdmi_initial();
	if(hdmi->enable && hdmi->irq) {
		enable_irq(hdmi->irq);
		// hdmi_irq();
		rk616_hdmi_work();
	}

	if (rk616_hdmi->rk616_drv && rk616_hdmi->rk616_drv->pdata->hdmi_irq == INVALID_GPIO) 
		queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, 100);
	queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));	
	mutex_unlock(&hdmi->enable_mutex);
	return;
}
static int __devinit rk616_hdmi_probe (struct platform_device *pdev)
{
	int ret;
        struct rk616_hdmi *rk616_hdmi;
        struct resource __maybe_unused *mem;
        struct resource __maybe_unused *res;

        rk616_hdmi = devm_kzalloc(&pdev->dev, sizeof(*rk616_hdmi), GFP_KERNEL);
        if(!rk616_hdmi)
	{
		dev_err(&pdev->dev, ">>rk616_hdmi kmalloc fail!");
		return -ENOMEM;
	}
        hdmi = &rk616_hdmi->g_hdmi;

#ifdef CONFIG_ARCH_RK3026
	rk616_hdmi->rk616_drv = NULL;
#else
	rk616_hdmi->rk616_drv = dev_get_drvdata(pdev->dev.parent);
	if(!(rk616_hdmi->rk616_drv))
	{
		dev_err(&pdev->dev,"null mfd device rk616!\n");
		return -ENODEV;
	}

#endif

	hdmi->dev = &pdev->dev;
	platform_set_drvdata(pdev, hdmi);

	if(HDMI_SOURCE_DEFAULT == HDMI_SOURCE_LCDC0)
		hdmi->lcdc = rk_get_lcdc_drv("lcdc0");
	else
		hdmi->lcdc = rk_get_lcdc_drv("lcdc1");
	if(hdmi->lcdc == NULL)
	{
		dev_err(hdmi->dev, "can not connect to video source lcdc\n");
		ret = -ENXIO;
		goto err0;
	}
	hdmi->xscale = 100;
	hdmi->yscale = 100;


	hdmi_sys_init();

	hdmi->workqueue = create_singlethread_workqueue("hdmi");
	INIT_DELAYED_WORK(&(hdmi->delay_work), hdmi_work);

#ifdef CONFIG_HAS_EARLYSUSPEND
	hdmi->early_suspend.suspend = hdmi_early_suspend;
	hdmi->early_suspend.resume = hdmi_early_resume;
	hdmi->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 10;
	register_early_suspend(&hdmi->early_suspend);
#endif

#ifdef CONFIG_SWITCH
	hdmi->switch_hdmi.name="hdmi";
	switch_dev_register(&(hdmi->switch_hdmi));
#endif

	spin_lock_init(&hdmi->irq_lock);
	mutex_init(&hdmi->enable_mutex);

	INIT_DELAYED_WORK(&rk616_hdmi->rk616_delay_work, rk616_delay_work_func);

	/* get the IRQ */
	// if(rk616->pdata->hdmi_irq != INVALID_GPIO)
        
#ifdef CONFIG_ARCH_RK3026
        hdmi->hclk = clk_get(NULL,"pclk_hdmi");
        if(IS_ERR(hdmi->hclk)) {
                dev_err(hdmi->dev, "Unable to get hdmi hclk\n");
                ret = -ENXIO;
                goto err0;
        }
        clk_enable(hdmi->hclk);
        
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                dev_err(hdmi->dev, "Unable to get register resource\n");
                ret = -ENXIO;
                goto err0;
        }
        hdmi->regbase_phy = res->start;
        hdmi->regsize_phy = (res->end - res->start) + 1;
        mem = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name);
        if (!mem) {
                dev_err(hdmi->dev, "failed to request mem region for hdmi\n");
                ret = -ENOENT;
                goto err0;
        }
        
        printk("res->start = 0x%x\n, xhc-------res->end = 0x%x\n", res->start, res->end);
        hdmi->regbase = (int)ioremap(res->start, (res->end - res->start) + 1);
        if (!hdmi->regbase) {
                dev_err(hdmi->dev, "cannot ioremap registers\n");
                ret = -ENXIO;
                goto err1;
        }
        
        // rk30_mux_api_set(GPIO0A7_I2C3_SDA_HDMI_DDCSDA_NAME, GPIO0A_HDMI_DDCSDA);
        // rk30_mux_api_set(GPIO0A6_I2C3_SCL_HDMI_DDCSCL_NAME, GPIO0A_HDMI_DDCSCL);
        // rk30_mux_api_set(GPIO0B7_HDMI_HOTPLUGIN_NAME, GPIO0B_HDMI_HOTPLUGIN);
        iomux_set(HDMI_DDCSDA);
        iomux_set(HDMI_DDCSCL);
        iomux_set(HDMI_HOTPLUGIN);
        
        ret = rk616_hdmi_initial();
        /* 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);
                hdmi->irq = 0;
        } else {               
                /* request the IRQ */
                ret = request_irq(hdmi->irq, rk616_hdmi_irq, 0, dev_name(&pdev->dev), hdmi);
                if (ret) {
                        dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret);
                        goto err1;
                }
        }
#else
        ret = rk616_hdmi_initial();
        if(rk616_hdmi->rk616_drv->pdata->hdmi_irq != INVALID_GPIO) {               
                INIT_WORK(&rk616_hdmi->rk616_irq_work_struct, rk616_irq_work_func);
                ret = gpio_request(rk616_hdmi->rk616_drv->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_hdmi->rk616_drv->pdata->hdmi_irq);
                hdmi->irq = gpio_to_irq(rk616_hdmi->rk616_drv->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, rk616_hdmi_irq, IRQF_TRIGGER_LOW, dev_name(&pdev->dev), &rk616_hdmi->rk616_irq_work_struct);
                if (ret) {
                        dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret);
                        goto err1;
                }
        } else {                
                /* use roll polling method */
                hdmi->irq = 0;
        }

#endif
	hdmi_register_display_sysfs(hdmi, NULL);

#if defined(CONFIG_DEBUG_FS)
	if(rk616_hdmi->rk616_drv && rk616_hdmi->rk616_drv->debugfs_dir) {
		debugfs_create_file("hdmi", S_IRUSR, rk616_hdmi->rk616_drv->debugfs_dir, rk616_hdmi->rk616_drv, &rk616_hdmi_reg_fops);
	} else {
                rk616_hdmi->debugfs_dir = debugfs_create_dir("rk616", NULL);
                if (IS_ERR(rk616_hdmi->debugfs_dir)) {
                        dev_err(hdmi->dev,"failed to create debugfs dir for rk616!\n");
                } else {
                        debugfs_create_file("hdmi", S_IRUSR, rk616_hdmi->debugfs_dir, rk616_hdmi, &rk616_hdmi_reg_fops);
                }
        }
#endif
	//rk616_delay_work_func(NULL);
	queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, msecs_to_jiffies(0));
	dev_info(hdmi->dev, "rk616 hdmi probe success.\n");
	return 0;
err1:
#ifdef CONFIG_SWITCH
	switch_dev_unregister(&(hdmi->switch_hdmi));
#endif
	hdmi_unregister_display_sysfs(hdmi);
#ifdef CONFIG_HAS_EARLYSUSPEND
	unregister_early_suspend(&hdmi->early_suspend);
#endif
err0:
	hdmi_dbg(hdmi->dev, "rk616 hdmi probe error.\n");
	kfree(hdmi);
	hdmi = NULL;
	return ret;
}
static int __devinit rk616_hdmi_probe (struct platform_device *pdev)
{
	int ret = -1;
	struct rkdisplay_platform_data *hdmi_data;
		
	RK616DBG("%s\n", __FUNCTION__);
	
	rk616_hdmi = kmalloc(sizeof(struct rk616_hdmi), GFP_KERNEL);
	if(!rk616_hdmi)
	{
    	dev_err(&pdev->dev, ">>rk30 hdmi kmalloc fail!");
    	return -ENOMEM;
	}
	memset(rk616_hdmi, 0, sizeof(struct rk616_hdmi));
	platform_set_drvdata(pdev, rk616_hdmi);
	
	rk616_hdmi->pwr_mode = NORMAL;
	
	rk616_hdmi->rk616_drv = dev_get_drvdata(pdev->dev.parent);
	if(rk616_hdmi->rk616_drv == NULL) {
		goto failed;
	}
	hdmi_data = rk616_hdmi->rk616_drv->pdata->pdata;
	if(hdmi_data == NULL) {
		goto failed;
	}
	// Register HDMI device
	if(hdmi_data) {
		rk616_hdmi_property.videosrc = hdmi_data->video_source;
		rk616_hdmi_property.display = hdmi_data->property;
	}
	
	rk616_hdmi_property.name = (char*)pdev->name;
	rk616_hdmi_property.priv = rk616_hdmi;
	rk616_hdmi->hdmi = hdmi_register(&rk616_hdmi_property, &rk616_hdmi_ops);
	if(rk616_hdmi->hdmi == NULL) {
		dev_err(&pdev->dev, "register hdmi device failed\n");
		ret = -ENOMEM;
		goto failed;
	}
		
	rk616_hdmi->hdmi->dev = &pdev->dev;
	rk616_hdmi->hdmi->xscale = 95;
	rk616_hdmi->hdmi->yscale = 95;
	rk616_hdmi->enable = 1;
	rk616_hdmi_initial(rk616_hdmi);
	
	#ifdef CONFIG_HAS_EARLYSUSPEND
	rk616_hdmi->early_suspend.suspend = rk616_hdmi_early_suspend;
	rk616_hdmi->early_suspend.resume = rk616_hdmi_early_resume;
	rk616_hdmi->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 10;
	register_early_suspend(&rk616_hdmi->early_suspend);
	#endif
	
	#if defined(CONFIG_DEBUG_FS)
	if(rk616_hdmi->rk616_drv && rk616_hdmi->rk616_drv->debugfs_dir) {
		debugfs_create_file("hdmi", S_IRUSR, rk616_hdmi->rk616_drv->debugfs_dir, rk616_hdmi->rk616_drv, &rk616_hdmi_reg_fops);
	} else {
	    rk616_hdmi->debugfs_dir = debugfs_create_dir("rk616", NULL);
	    if (IS_ERR(rk616_hdmi->debugfs_dir)) {
	            dev_err(rk616_hdmi->hdmi->dev,"failed to create debugfs dir for rk616!\n");
	    } else {
	            debugfs_create_file("hdmi", S_IRUSR, rk616_hdmi->debugfs_dir, rk616_hdmi, &rk616_hdmi_reg_fops);
	    }
	}
#endif
	{
		rk616_hdmi->workqueue = create_singlethread_workqueue("rk616 irq");
		INIT_DELAYED_WORK(&(rk616_hdmi->delay_work), rk616_hdmi_irq_work_func);
		rk616_hdmi_irq_work_func(NULL);
	}
	dev_info(&pdev->dev, "rk616 hdmi probe sucess.\n");
	return 0;
	
failed:
	if(rk616_hdmi) {
		kfree(rk616_hdmi);
		rk616_hdmi = NULL;
	}
	dev_err(&pdev->dev, "rk30 hdmi probe error.\n");
	return ret;
}