- 论坛徽章:
- 0
|
各位好,目前遇到这样一个问题,我们使用飞思卡尔的imx6q,使用的LVDS手册中对LVDS各个信号的时序有要求,如图,
背光和VDD都是两个gpio,通过对他输出1/0来控制使能与关闭,现在主要是signal,不知道该如何在关机的时候按照要求关闭。以下是我的使能部分的代码,是在drivers/video/mxc/mxc_ipuv3_fb.c的probe函数中,开机的时序现在是对的,还请各位帮我看看关机的时候,该如何关闭signal信号。谢谢!
static int mxcfb_probe(struct platform_device *pdev)
{
struct ipuv3_fb_platform_data *plat_data = pdev->dev.platform_data;
struct fb_info *fbi;
struct mxcfb_info *mxcfbi;
struct resource *res;
struct device *disp_dev;
char buf[32];
int ret = 0;
gpio_request(SABRESD_LCD_VDD_EN, "panel-en");
gpio_direction_output(SABRESD_LCD_VDD_EN, 1);
mdelay(20);
/* Initialize FB structures */
fbi = mxcfb_init_fbinfo(&pdev->dev, &mxcfb_ops);
if (!fbi) {
ret = -ENOMEM;
goto init_fbinfo_failed;
}
ret = mxcfb_option_setup(pdev, fbi);
if (ret)
goto get_fb_option_failed;
mxcfbi = (struct mxcfb_info *)fbi->par;
spin_lock_init(&mxcfbi->lock);
mxcfbi->fbi = fbi;
mxcfbi->ipu_int_clk = plat_data->int_clk;
mxcfbi->late_init = plat_data->late_init;
mxcfbi->first_set_par = true;
mxcfbi->panel_width_mm = plat_data->panel_width_mm;
mxcfbi->panel_height_mm = plat_data->panel_height_mm;
ret = mxcfb_dispdrv_init(pdev, fbi);
if (ret < 0)
goto init_dispdrv_failed;
ret = ipu_test_set_usage(mxcfbi->ipu_id, mxcfbi->ipu_di);
if (ret < 0) {
dev_err(&pdev->dev, "ipu%d-di%d already in use\n",
mxcfbi->ipu_id, mxcfbi->ipu_di);
goto ipu_in_busy;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res && res->start && res->end) {
fbi->fix.smem_len = res->end - res->start + 1;
fbi->fix.smem_start = res->start;
fbi->screen_base = ioremap(fbi->fix.smem_start, fbi->fix.smem_len);
/* Do not clear the fb content drawn in bootloader. */
if (!mxcfbi->late_init)
memset(fbi->screen_base, 0, fbi->fix.smem_len);
}
mxcfbi->ipu = ipu_get_soc(mxcfbi->ipu_id);
if (IS_ERR(mxcfbi->ipu)) {
ret = -ENODEV;
goto get_ipu_failed;
}
/* first user uses DP with alpha feature */
if (!g_dp_in_use[mxcfbi->ipu_id]) {
mxcfbi->ipu_ch_irq = IPU_IRQ_BG_SYNC_EOF;
mxcfbi->ipu_ch_nf_irq = IPU_IRQ_BG_SYNC_NFACK;
mxcfbi->ipu_alp_ch_irq = IPU_IRQ_BG_ALPHA_SYNC_EOF;
mxcfbi->ipu_vsync_pre_irq = mxcfbi->ipu_di ?
IPU_IRQ_VSYNC_PRE_1 :
IPU_IRQ_VSYNC_PRE_0;
mxcfbi->ipu_ch = MEM_BG_SYNC;
/* Unblank the primary fb only by default */
if (pdev->id == 0)
mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_UNBLANK;
else
mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
ret = mxcfb_register(fbi);
if (ret < 0)
goto mxcfb_register_failed;
ipu_disp_set_global_alpha(mxcfbi->ipu, mxcfbi->ipu_ch,
true, 0x80);
ipu_disp_set_color_key(mxcfbi->ipu, mxcfbi->ipu_ch, false, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
ret = mxcfb_setup_overlay(pdev, fbi, res);
if (ret < 0) {
mxcfb_unregister(fbi);
goto mxcfb_setupoverlay_failed;
}
g_dp_in_use[mxcfbi->ipu_id] = true;
ret = device_create_file(mxcfbi->ovfbi->dev,
&dev_attr_fsl_disp_property);
if (ret)
dev_err(mxcfbi->ovfbi->dev, "Error %d on creating "
"file for disp property\n",
ret);
ret = device_create_file(mxcfbi->ovfbi->dev,
&dev_attr_fsl_disp_dev_property);
if (ret)
dev_err(mxcfbi->ovfbi->dev, "Error %d on creating "
"file for disp device "
"propety\n", ret);
} else {
mxcfbi->ipu_ch_irq = IPU_IRQ_DC_SYNC_EOF;
mxcfbi->ipu_ch_nf_irq = IPU_IRQ_DC_SYNC_NFACK;
mxcfbi->ipu_alp_ch_irq = -1;
mxcfbi->ipu_vsync_pre_irq = mxcfbi->ipu_di ?
IPU_IRQ_VSYNC_PRE_1 :
IPU_IRQ_VSYNC_PRE_0;
mxcfbi->ipu_ch = MEM_DC_SYNC;
mxcfbi->cur_blank = mxcfbi->next_blank = FB_BLANK_POWERDOWN;
ret = mxcfb_register(fbi);
if (ret < 0)
goto mxcfb_register_failed;
}
platform_set_drvdata(pdev, fbi);
ret = device_create_file(fbi->dev, &dev_attr_fsl_disp_property);
if (ret)
dev_err(&pdev->dev, "Error %d on creating file for disp "
"property\n", ret);
ret = device_create_file(fbi->dev, &dev_attr_fsl_disp_dev_property);
if (ret)
dev_err(&pdev->dev, "Error %d on creating file for disp "
" device propety\n", ret);
disp_dev = mxc_dispdrv_getdev(mxcfbi->dispdrv);
if (disp_dev) {
ret = sysfs_create_link(&fbi->dev->kobj,
&disp_dev->kobj, "disp_dev");
if (ret)
dev_err(&pdev->dev,
"Error %d on creating file\n", ret);
}
INIT_WORK(&mxcfbi->vsync_pre_work, mxcfb_vsync_pre_work);
snprintf(buf, sizeof(buf), "mxcfb%d-vsync-pre", fbi->node);
mxcfbi->vsync_pre_queue = create_singlethread_workqueue(buf);
if (mxcfbi->vsync_pre_queue == NULL) {
dev_err(fbi->device,
"Failed to alloc vsync-pre workqueue\n");
ret = -ENOMEM;
goto workqueue_alloc_failed;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
mxcfbi->fbdrv_earlysuspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
mxcfbi->fbdrv_earlysuspend.suspend = mxcfb_early_suspend;
mxcfbi->fbdrv_earlysuspend.resume = mxcfb_later_resume;
mxcfbi->fbdrv_earlysuspend.data = pdev;
register_early_suspend(&mxcfbi->fbdrv_earlysuspend);
#endif
#ifdef CONFIG_LOGO
fb_prepare_logo(fbi, 0);
fb_show_logo(fbi, 0);
#endif
/* LVDS backlight enable */
mdelay(150);
gpio_request(SABRESD_DISP0_WR_REVB, "bklt-en");
gpio_direction_output(SABRESD_DISP0_WR_REVB, 1);
//end
return 0;
workqueue_alloc_failed:
mxcfb_setupoverlay_failed:
mxcfb_register_failed:
get_ipu_failed:
ipu_clear_usage(mxcfbi->ipu_id, mxcfbi->ipu_di);
ipu_in_busy:
init_dispdrv_failed:
fb_dealloc_cmap(&fbi->cmap);
framebuffer_release(fbi);
get_fb_option_failed:
init_fbinfo_failed:
return ret;
} |
|