static OMAP_ERROR EnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) { int res; OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; OMAP_ERROR eError; memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); psDevInfo->sLINNotifBlock.notifier_call = FrameBufferEvents; psSwapChain->bBlanked = OMAP_FALSE; res = fb_register_client(&psDevInfo->sLINNotifBlock); if (res != 0) { printk(KERN_WARNING DRIVER_PREFIX ": fb_register_client failed (%d)", res); return (OMAP_ERROR_GENERIC); } eError = UnblankDisplay(psDevInfo); if (eError != OMAP_OK) { DEBUG_PRINTK((KERN_WARNING DRIVER_PREFIX ": UnblankDisplay failed (%d)", eError)); return eError; } return (OMAP_OK); }
static int __init am200_init(void) { int ret; /* before anything else, we request notification for any fb * creation events */ fb_register_client(&am200_fb_notif); /* request our platform independent driver */ request_module("metronomefb"); am200_device = platform_device_alloc("metronomefb", -1); if (!am200_device) return -ENOMEM; /* the am200_board that will be seen by metronomefb is a copy */ platform_device_add_data(am200_device, &am200_board, sizeof(am200_board)); /* this _add binds metronomefb to am200. metronomefb refcounts am200 */ ret = platform_device_add(am200_device); if (ret) { platform_device_put(am200_device); fb_unregister_client(&am200_fb_notif); return ret; } am200_presetup_fb(); return 0; }
int __init init_display_devices(void) { int ret; ret = fb_register_client(&framebuffer_nb); if (ret) pr_warning("Failed to register framebuffer notifier\n"); ret = mcde_dss_register_notifier(&display_nb); if (ret) pr_warning("Failed to register dss notifier\n"); #ifdef CONFIG_DISPLAY_GENERIC_PRIMARY if (display_initialized_during_boot) generic_display0.power_mode = MCDE_DISPLAY_PM_STANDBY; ret = mcde_display_device_register(&generic_display0); if (ret) pr_warning("Failed to register generic display device 0\n"); #endif #ifdef CONFIG_DISPLAY_AV8100_TERTIARY INIT_DELAYED_WORK_DEFERRABLE(&work_dispreg_hdmi, delayed_work_dispreg_hdmi); schedule_delayed_work(&work_dispreg_hdmi, msecs_to_jiffies(DISPREG_HDMI_DELAY)); #endif return ret; }
static int __init ppm_lcmoff_policy_init(void) { int ret = 0; FUNC_ENTER(FUNC_LV_POLICY); #ifdef CONFIG_HAS_EARLYSUSPEND register_early_suspend(&ppm_lcmoff_es_handler); #else if (fb_register_client(&ppm_lcmoff_fb_notifier)) { ppm_err("@%s: lcmoff policy register FB client failed!\n", __func__); ret = -EINVAL; goto out; } #endif if (ppm_main_register_policy(&lcmoff_policy)) { ppm_err("@%s: lcmoff policy register failed\n", __func__); ret = -EINVAL; goto out; } ppm_info("@%s: register %s done!\n", __func__, lcmoff_policy.name); out: FUNC_EXIT(FUNC_LV_POLICY); return ret; }
int __init mdss_dsi_status_init(void) { int rc = 0; pstatus_data = kzalloc(sizeof(struct dsi_status_data), GFP_KERNEL); if (!pstatus_data) { pr_err("%s: can't allocate memory\n", __func__); return -ENOMEM; } pstatus_data->fb_notifier.notifier_call = fb_event_callback; rc = fb_register_client(&pstatus_data->fb_notifier); if (rc < 0) { pr_err("%s: fb_register_client failed, returned with rc=%d\n", __func__, rc); kfree(pstatus_data); return -EPERM; } pstatus_data->check_interval = interval; pr_info("%s: DSI status check interval:%d\n", __func__, interval); INIT_DELAYED_WORK(&pstatus_data->check_status, check_dsi_ctrl_status); pr_debug("%s: DSI ctrl status work queue initialized\n", __func__); return rc; }
/*! * This function is called whenever the platform device is detected. * * @param pdev the platform device * * @return Returns 0 on SUCCESS and error on FAILURE. */ static int __devinit lcd_probe(struct platform_device *pdev) { int i; struct mxc_lcd_platform_data *plat = pdev->dev.platform_data; if (plat) { if (plat->reset) plat->reset(); io_reg = regulator_get(&pdev->dev, plat->io_reg); if (IS_ERR(io_reg)) io_reg = NULL; core_reg = regulator_get(&pdev->dev, plat->core_reg); if (!IS_ERR(core_reg)) regulator_set_voltage(io_reg, 1800000, 1800000); else core_reg = NULL; } for (i = 0; i < num_registered_fb; i++) { if (strcmp(registered_fb[i]->fix.id, "mxc_elcdif_fb") == 0) { lcd_init_fb(registered_fb[i]); fb_show_logo(registered_fb[i], 0); lcd_poweron(); } } fb_register_client(&nb); plcd_dev = pdev; return 0; }
static int __devinit ite661x_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret; struct mxc_lcd_platform_data *plat = client->dev.platform_data; struct fb_info edid_fbi; if (plat->boot_enable && !g_enable_hdmi) g_enable_hdmi = MXC_ENABLE; if (!g_enable_hdmi) g_enable_hdmi = MXC_DISABLE; if (g_enable_hdmi == MXC_DISABLE) { printk(KERN_WARNING "By setting, ITE driver will not be enabled\n"); return -ENODEV; } ite661x.client = client; if (plat->reset) { ite661x_reset = plat->reset; ite661x_reset(); } HDMITX_ChangeDisplayOption(HDMI_480p60, HDMI_RGB444) ; InitCAT6611(client); if (ite661x.client->irq) { ret = request_irq(ite661x.client->irq, ite661x_detect_handler, IRQF_TRIGGER_FALLING, "ite661x_det", &ite661x); if (ret < 0) dev_warn(&ite661x.client->dev, "ite661x: cound not request det irq %d\n", ite661x.client->irq); else { /*enable cable hot plug irq*/ INIT_DELAYED_WORK(&(ite661x.det_work), det_worker); } ret = device_create_file(&ite661x.pdev->dev, &dev_attr_fb_name); if (ret < 0) dev_warn(&ite661x.client->dev, "ite661x: cound not create sys node for fb name\n"); ret = device_create_file(&ite661x.pdev->dev, &dev_attr_cable_state); if (ret < 0) dev_warn(&ite661x.client->dev, "ite661x: cound not create sys node for cable state\n"); ret = device_create_file(&ite661x.pdev->dev, &dev_attr_edid); if (ret < 0) dev_warn(&ite661x.client->dev, "ite661x: cound not create sys node for edid\n"); } fb_register_client(&nb); return 0; }
static void __init rk3288_init_suspend(void) { printk("%s\n",__FUNCTION__); fb_register_client(&rk3288_pll_early_suspend_notifier); rockchip_suspend_init(); rkpm_pie_init(); rk3288_suspend_init(); rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend,rk_pm_soc_pd_resume); }
static void gf_setup_fb_notifier(struct gf_dev *gf_dev) { int rc = 0; gf_dev->fb_notifier.notifier_call = gf_fb_notifier_callback; rc = fb_register_client(&gf_dev->fb_notifier); if (rc) GF_LOG_ERROR("failed to register fb_notifier: %d\n", rc); }
static int __init msm_sleeper_init(void) { pr_info("msm-sleeper version %d.%d\n", MSM_SLEEPER_MAJOR_VERSION, MSM_SLEEPER_MINOR_VERSION); fb_register_client(&msm_sleeper_fb_notif); return 0; }
static int __init cpu_iboost_init(void) { struct boost_policy *b; int cpu, ret; boost_wq = alloc_workqueue("cpu_iboost_wq", WQ_HIGHPRI, 0); if (!boost_wq) { pr_err("Failed to allocate workqueue\n"); ret = -EFAULT; goto err; } cpufreq_register_notifier(&cpu_do_boost_nb, CPUFREQ_POLICY_NOTIFIER); INIT_DELAYED_WORK(&fb_boost_work, fb_boost_fn); fb_register_client(&fb_boost_nb); for_each_possible_cpu(cpu) { b = &per_cpu(boost_info, cpu); b->cpu = cpu; INIT_DELAYED_WORK(&b->ib_restore_work, ib_restore_main); init_waitqueue_head(&b->sync_wq); atomic_set(&b->being_woken, 0); spin_lock_init(&b->lock); INIT_DELAYED_WORK(&b->mig_boost_rem, do_mig_boost_rem); b->thread = kthread_run(boost_mig_sync_thread, (void *)cpu, "boost_sync/%d", cpu); set_cpus_allowed(b->thread, *cpumask_of(cpu)); } atomic_notifier_chain_register(&migration_notifier_head, &boost_migration_nb); INIT_WORK(&boost_work, ib_boost_main); ret = input_register_handler(&cpu_iboost_input_handler); if (ret) { pr_err("Failed to register input handler, err: %d\n", ret); goto err; } cpu_iboost_kobject = kobject_create_and_add("cpu_input_boost", kernel_kobj); if (!cpu_iboost_kobject) { pr_err("Failed to create kobject\n"); goto err; } ret = sysfs_create_group(cpu_iboost_kobject, &cpu_iboost_attr_group); if (ret) { pr_err("Failed to create sysfs interface\n"); kobject_put(cpu_iboost_kobject); } err: return ret; }
/* common functions */ void __init lge_add_lcd_devices(void) { if(ebi2_tovis_panel_data.initialized) ebi2_tovis_power_save(1); fb_register_client(&jump_fb_event_notifier); platform_device_register(&ebi2_tovis_panel_device); msm_fb_add_devices(); lge_add_gpio_i2c_device(jump_init_i2c_backlight); }
void __init lge_add_lcd_devices(void) { if(ebi2_tovis_panel_data.initialized) ebi2_tovis_power_save(1); fb_register_client(&e0eu_fb_event_notifier); platform_add_devices(e0eu_panel_devices, ARRAY_SIZE(e0eu_panel_devices)); msm_fb_add_devices(); lge_add_gpio_i2c_device(msm7x27a_e0eu_init_i2c_backlight); }
static void cyttsp4_setup_early_suspend(struct cyttsp4_mt_data *md) { int retval = 0; struct device *dev = &md->ttsp->dev; dev_dbg(dev, "%s\n", __func__); md->fb_notif.notifier_call = cyttsp4_mt_fb_notifier_callback; retval = fb_register_client(&md->fb_notif); if (retval) dev_err(&md->ttsp->dev, "Unable to register fb_notifier: %d\n", retval); return; }
static int __init exynos_init_cpuidle(void) { int ret; ret = exynos_idle_state_init(&exynos64_idle_cluster0_driver, &hmp_fast_cpu_mask); if (ret) { pr_err("fail exynos_idle_state_init(cluster 0) ret = %d\n", ret); return ret; } cpuidle_profile_state_init(&exynos64_idle_cluster0_driver); exynos64_idle_cluster0_driver.safe_state_index = IDLE_C1; exynos64_idle_cluster0_driver.cpumask = &hmp_fast_cpu_mask; ret = cpuidle_register(&exynos64_idle_cluster0_driver, NULL); if (ret) { pr_err("fast cpu cpuidle_register fail ret = %d\n", ret); return ret; } ret = exynos_idle_state_init(&exynos64_idle_cluster1_driver, &hmp_slow_cpu_mask); if (ret) { pr_err("fail exynos_idle_state_init(cluster 1) ret = %d\n", ret); return ret; } exynos64_idle_cluster1_driver.safe_state_index = IDLE_C1; exynos64_idle_cluster1_driver.cpumask = &hmp_slow_cpu_mask; ret = cpuidle_register(&exynos64_idle_cluster1_driver, NULL); if (ret) { pr_err("slow cpu cpuidle_register fail ret = %d\n", ret); return ret; } /* TODO : SKIP idle correlation */ register_pm_notifier(&exynos_cpuidle_notifier); register_reboot_notifier(&exynos_cpuidle_reboot_nb); #if defined(CONFIG_EXYNOS_MARCH_DYNAMIC_CPU_HOTPLUG) fb_register_client(&fb_block); #endif pr_info("%s, finish initialization of cpuidle\n", __func__); return 0; }
void __init msm_fb_add_devices(void) { if (ebi2_tovis_panel_data.initialized) ebi2_tovis_power_save(1); fb_register_client(&v1_fb_event_notifier); platform_add_devices(msm_fb_devices, ARRAY_SIZE(msm_fb_devices)); platform_add_devices(v1_panel_devices, ARRAY_SIZE(v1_panel_devices)); msm_fb_register_device("mdp", &mdp_pdata); #ifdef CONFIG_FB_MSM_EBI2 msm_fb_register_device("ebi2", 0); #endif #if defined(CONFIG_BACKLIGHT_LGE_RT8966) msm7x27a_v1_init_backlight(); #endif }
void __init msm_fb_add_devices(void) { if(ebi2_tovis_panel_data.initialized) ebi2_tovis_power_save(1); fb_register_client(&v3eu_fb_event_notifier); platform_add_devices(msm_fb_devices, ARRAY_SIZE(msm_fb_devices)); platform_add_devices(v3eu_panel_devices, ARRAY_SIZE(v3eu_panel_devices)); msm_fb_register_device("mdp", &mdp_pdata); msm_fb_register_device("lcdc", 0); #ifdef CONFIG_FB_MSM_EBI2 msm_fb_register_device("ebi2", 0); #endif #ifdef CONFIG_FB_MSM_MIPI_DSI msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata); #endif lge_add_gpio_i2c_device(msm7x27a_v3eu_init_i2c_backlight); }
static int __devinit at91sam9x5_video_probe(struct platform_device *pdev) { int ret = -ENOMEM; size_t i; struct at91sam9x5_video_priv *priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(&pdev->dev, "failed to allocate driver private data\n"); goto err_alloc_priv; } priv->pdev = pdev; priv->fb_notifier.notifier_call = at91sam9x5_video_fb_event_notify; platform_set_drvdata(pdev, priv); spin_lock_init(&priv->lock); ret = fb_register_client(&priv->fb_notifier); if (ret) { dev_err(&pdev->dev, "failed to register fb client (%d)\n", ret); kfree(priv); err_alloc_priv: return ret; } /* XXX: This is racy. If a new fb is registered then * at91sam9x5_video_register is called twice. This should be solved * somewhere in drivers/fb. priv->fbinfo is used to prevent multiple * registration. */ for (i = 0; i < ARRAY_SIZE(registered_fb); ++i) if (registered_fb[i]) at91sam9x5_video_register(priv, registered_fb[i]); return 0; }
/*! * This function is called whenever the SPI slave device is detected. * * @param spi the SPI slave device * * @return Returns 0 on SUCCESS and error on FAILURE. */ static int __devinit lcd_spi_probe(struct spi_device *spi) { int i; struct mxc_lcd_platform_data *plat = spi->dev.platform_data; lcd_spi = spi; lcd_24bpp_ioinit(); if (plat) { io_reg = regulator_get(&spi->dev, plat->io_reg); if (!IS_ERR(io_reg)) { regulator_set_voltage(io_reg, 1800000); regulator_enable(io_reg); } core_reg = regulator_get(&spi->dev, plat->core_reg); if (!IS_ERR(core_reg)) { regulator_set_voltage(core_reg, 2800000); regulator_enable(core_reg); } lcd_reset = plat->reset; if (lcd_reset) lcd_reset(); } lcd_spi_setup(lcd_spi); for (i = 0; i < num_registered_fb; i++) { if (strcmp(registered_fb[i]->fix.id, "DISP3 BG") == 0) { lcd_init_fb(registered_fb[i]); fb_show_logo(registered_fb[i], 0); lcd_poweron(); } } fb_register_client(&nb); return 0; }
/* Set up Linux Framebuffer event notification */ OMAPLFB_ERROR OMAPLFBEnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo) { int res; OMAPLFB_ERROR eError; /* Set up Linux Framebuffer event notification */ memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); psDevInfo->sLINNotifBlock.notifier_call = OMAPLFBFrameBufferEvents; OMAPLFBAtomicBoolSet(&psDevInfo->sBlanked, OMAPLFB_FALSE); OMAPLFBAtomicIntSet(&psDevInfo->sBlankEvents, 0); res = fb_register_client(&psDevInfo->sLINNotifBlock); if (res != 0) { printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: fb_register_client failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, res); return (OMAPLFB_ERROR_GENERIC); } eError = OMAPLFBUnblankDisplay(psDevInfo); if (eError != OMAPLFB_OK) { printk(KERN_ERR DRIVER_PREFIX ": %s: Device %u: UnblankDisplay failed (%d)\n", __FUNCTION__, psDevInfo->uiFBDevID, eError); return eError; } #ifdef CONFIG_HAS_EARLYSUSPEND psDevInfo->sEarlySuspend.suspend = OMAPLFBEarlySuspendHandler; psDevInfo->sEarlySuspend.resume = OMAPLFBEarlyResumeHandler; psDevInfo->sEarlySuspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1; register_early_suspend(&psDevInfo->sEarlySuspend); #endif return (OMAPLFB_OK); }
static enum PVRSRV_ERROR EnableLFBEventNotification(struct OMAPLFB_DEVINFO *psDevInfo) { int res; struct OMAPLFB_SWAPCHAIN *psSwapChain = psDevInfo->psSwapChain; memset(&psDevInfo->sLINNotifBlock, 0, sizeof(psDevInfo->sLINNotifBlock)); psDevInfo->sLINNotifBlock.notifier_call = FrameBufferEvents; psSwapChain->bBlanked = IMG_FALSE; res = fb_register_client(&psDevInfo->sLINNotifBlock); if (res != 0) { printk(KERN_WARNING DRIVER_PREFIX ": fb_register_client failed (%d)", res); return PVRSRV_ERROR_GENERIC; } return PVRSRV_OK; }
static int __init cpufreq_limit_manager_init(void) { int rc; rc = sysfs_create_group(kernel_kobj, &cpufreq_limit_manager_attr_group); if (rc) { pr_info("%s sysfs create failed!\n", __FUNCTION__); return -EFAULT; } #if defined(CONFIG_POWERSUSPEND) register_power_suspend(&cpufreq_limit_suspend_driver); #elif defined(CONFIG_HAS_EARLYSUSPEND) register_early_suspend(&cpufreq_limit_suspend_driver); #else notif.notifier_call = fb_notifier_callback; if (fb_register_client(¬if)) pr_err("Failed to register FB notifier callback for cpufreq limit manager\n"); #endif /* CONFIG_POWERSUSPEND || CONFIG_HAS_EARLYSUSPEND || FB NOTIFIER */ return (rc); }
/*! * This function is called whenever the SPI slave device is detected. * * @param spi the SPI slave device * * @return Returns 0 on SUCCESS and error on FAILURE. */ static int __devinit lcd_probe(struct device *dev) { int ret = 0; int i; struct mxc_lcd_platform_data *plat = dev->platform_data; ch7036_VGA_enable(1); for (i = 0; i < num_registered_fb; i++) { if (strcmp(registered_fb[i]->fix.id, "DISP3 BG - DI1") == 0) { ret = lcd_init(); if (ret < 0) goto err; //lcd_init_fb(registered_fb[i]); fb_show_logo(registered_fb[i], 0); //lcd_poweron(registered_fb[i]); } } fb_register_client(&nb); // -> [Walker Chen], 2014/01/29 - VGA reboot kthread_run(vga_reboot_thread, NULL, "VGA reboot"); vga_gpio = irq_to_gpio(ch7036_client->irq); gpio_set_debounce( vga_gpio , 1000 ); //1000ms irq_set_irq_wake( ch7036_client->irq , 1 ); ret = request_irq(ch7036_client->irq, vga_reboot_interrupt, IRQF_TRIGGER_FALLING, "ch7036 VGA_in", ch7036_client); enable_irq_wake(ch7036_client->irq); // <- End. return 0; err: return ret; }
static void init_info_data(struct sdchg_info_nochip_t *info) { //struct sdchg_info_personal_t *pData = info->pData; info->need_state = SDCHG_STATE_NONE; info->set_state = SDCHG_STATE_NONE; wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND, "sdchg"); info->wake_lock_set =false; wake_lock_init(&info->end_wake_lock, WAKE_LOCK_SUSPEND, "sdchg_end"); info->state_machine_run = false; #ifdef CONFIG_FB info->display_on = false; info->fb_nb.notifier_call = sdchg_fb_notifier_callback; fb_register_client(&info->fb_nb); #endif return; }
int __init init_gavini_display_devices(void) { int ret; ret = fb_register_client(&framebuffer_nb); if (ret) pr_warning("Failed to register framebuffer notifier\n"); ret = mcde_dss_register_notifier(&display_nb); if (ret) pr_warning("Failed to register dss notifier\n"); if (display_initialized_during_boot) { generic_display0.power_mode = MCDE_DISPLAY_PM_ON; gavini_dpi_pri_display_info.platform_enabled = 1; } /* * The pixclock setting is not used within MCDE. The clock is * setup elsewhere. But the pixclock value is visible in user * space. */ gavini_dpi_pri_display_info.video_mode.pixclock /= port0.phy.dpi.clock_div; ret = mcde_display_device_register(&generic_display0); if (ret) pr_warning("Failed to register generic display device 0\n"); #ifndef CONFIG_HAS_EARLYSUSPEND dpi_pins = ux500_pins_get("mcde-dpi"); if (!dpi_pins) return -EINVAL; #endif return ret; }
static int mdnie_register_fb(struct mdnie_info *mdnie) { memset(&mdnie->fb_notif, 0, sizeof(mdnie->fb_notif)); mdnie->fb_notif.notifier_call = fb_notifier_callback; return fb_register_client(&mdnie->fb_notif); }
static int ldb_disp_init(struct mxc_dispdrv_handle *disp, struct mxc_dispdrv_setting *setting) { int ret = 0, i; struct ldb_data *ldb = mxc_dispdrv_getdata(disp); struct fsl_mxc_ldb_platform_data *plat_data = ldb->pdev->dev.platform_data; struct resource *res; uint32_t base_addr; uint32_t reg, setting_idx; uint32_t ch_mask = 0, ch_val = 0; uint32_t ipu_id, disp_id; /* if input format not valid, make RGB666 as default*/ if (!valid_mode(setting->if_fmt)) { dev_warn(&ldb->pdev->dev, "Input pixel format not valid" " use default RGB666\n"); setting->if_fmt = IPU_PIX_FMT_RGB666; } if (!ldb->inited) { char di_clk[] = "ipu1_di0_clk"; char ldb_clk[] = "ldb_di0_clk"; int lvds_channel = 0; setting_idx = 0; res = platform_get_resource(ldb->pdev, IORESOURCE_MEM, 0); if (IS_ERR(res)) return -ENOMEM; base_addr = res->start; ldb->reg = ioremap(base_addr, res->end - res->start + 1); ldb->control_reg = ldb->reg + 2; ldb->gpr3_reg = ldb->reg + 3; ldb->lvds_bg_reg = regulator_get(&ldb->pdev->dev, plat_data->lvds_bg_reg); if (!IS_ERR(ldb->lvds_bg_reg)) { regulator_set_voltage(ldb->lvds_bg_reg, 2500000, 2500000); regulator_enable(ldb->lvds_bg_reg); } /* ipu selected by platform data setting */ setting->dev_id = plat_data->ipu_id; reg = readl(ldb->control_reg); /* refrence resistor select */ reg &= ~LDB_BGREF_RMODE_MASK; if (plat_data->ext_ref) reg |= LDB_BGREF_RMODE_EXT; else reg |= LDB_BGREF_RMODE_INT; /* TODO: now only use SPWG data mapping for both channel */ reg &= ~(LDB_BIT_MAP_CH0_MASK | LDB_BIT_MAP_CH1_MASK); reg |= LDB_BIT_MAP_CH0_SPWG | LDB_BIT_MAP_CH1_SPWG; /* channel mode setting */ reg &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK); reg &= ~(LDB_DATA_WIDTH_CH0_MASK | LDB_DATA_WIDTH_CH1_MASK); if (bits_per_pixel(setting->if_fmt) == 24) reg |= LDB_DATA_WIDTH_CH0_24 | LDB_DATA_WIDTH_CH1_24; else reg |= LDB_DATA_WIDTH_CH0_18 | LDB_DATA_WIDTH_CH1_18; if (g_ldb_mode) ldb->mode = g_ldb_mode; else ldb->mode = plat_data->mode; if ((ldb->mode == LDB_SIN0) || (ldb->mode == LDB_SIN1)) { ret = ldb->mode - LDB_SIN0; if (plat_data->disp_id != ret) { dev_warn(&ldb->pdev->dev, "change IPU DI%d to IPU DI%d for LDB " "channel%d.\n", plat_data->disp_id, ret, ret); plat_data->disp_id = ret; } } else if (((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1)) && (cpu_is_mx6q() || cpu_is_mx6dl())) { if (plat_data->disp_id == plat_data->sec_disp_id) { dev_err(&ldb->pdev->dev, "For LVDS separate mode," "two DIs should be different!\n"); return -EINVAL; } if (((!plat_data->disp_id) && (ldb->mode == LDB_SEP1)) || ((plat_data->disp_id) && (ldb->mode == LDB_SEP0))) { dev_dbg(&ldb->pdev->dev, "LVDS separate mode:" "swap DI configuration!\n"); ipu_id = plat_data->ipu_id; disp_id = plat_data->disp_id; plat_data->ipu_id = plat_data->sec_ipu_id; plat_data->disp_id = plat_data->sec_disp_id; plat_data->sec_ipu_id = ipu_id; plat_data->sec_disp_id = disp_id; } } if (ldb->mode == LDB_SPL_DI0) { reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0; setting->disp_id = 0; } else if (ldb->mode == LDB_SPL_DI1) { reg |= LDB_SPLIT_MODE_EN | LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1; setting->disp_id = 1; } else if (ldb->mode == LDB_DUL_DI0) { reg &= ~LDB_SPLIT_MODE_EN; reg |= LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0; setting->disp_id = 0; } else if (ldb->mode == LDB_DUL_DI1) { reg &= ~LDB_SPLIT_MODE_EN; reg |= LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1; setting->disp_id = 1; } else if (ldb->mode == LDB_SIN0) { reg &= ~LDB_SPLIT_MODE_EN; setting->disp_id = plat_data->disp_id; if (setting->disp_id == 0) reg |= LDB_CH0_MODE_EN_TO_DI0; else reg |= LDB_CH0_MODE_EN_TO_DI1; ch_mask = LDB_CH0_MODE_MASK; ch_val = reg & LDB_CH0_MODE_MASK; } else if (ldb->mode == LDB_SIN1) { reg &= ~LDB_SPLIT_MODE_EN; setting->disp_id = plat_data->disp_id; if (setting->disp_id == 0) reg |= LDB_CH1_MODE_EN_TO_DI0; else reg |= LDB_CH1_MODE_EN_TO_DI1; ch_mask = LDB_CH1_MODE_MASK; ch_val = reg & LDB_CH1_MODE_MASK; } else { /* separate mode*/ setting->disp_id = plat_data->disp_id; /* first output is LVDS0 or LVDS1 */ if (ldb->mode == LDB_SEP0) lvds_channel = 0; else lvds_channel = 1; reg &= ~LDB_SPLIT_MODE_EN; if ((lvds_channel == 0) && (setting->disp_id == 0)) reg |= LDB_CH0_MODE_EN_TO_DI0; else if ((lvds_channel == 0) && (setting->disp_id == 1)) reg |= LDB_CH0_MODE_EN_TO_DI1; else if ((lvds_channel == 1) && (setting->disp_id == 0)) reg |= LDB_CH1_MODE_EN_TO_DI0; else reg |= LDB_CH1_MODE_EN_TO_DI1; ch_mask = lvds_channel ? LDB_CH1_MODE_MASK : LDB_CH0_MODE_MASK; ch_val = reg & ch_mask; if (bits_per_pixel(setting->if_fmt) == 24) { if (lvds_channel == 0) reg &= ~LDB_DATA_WIDTH_CH1_24; else reg &= ~LDB_DATA_WIDTH_CH0_24; } else { if (lvds_channel == 0) reg &= ~LDB_DATA_WIDTH_CH1_18; else reg &= ~LDB_DATA_WIDTH_CH0_18; } } writel(reg, ldb->control_reg); if (ldb->mode < LDB_SIN0) { ch_mask = LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK; ch_val = reg & (LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK); } /* clock setting */ if ((cpu_is_mx6q() || cpu_is_mx6dl()) && ((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1))) ldb_clk[6] += lvds_channel; else ldb_clk[6] += setting->disp_id; ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev, ldb_clk); if (IS_ERR(ldb->setting[setting_idx].ldb_di_clk)) { dev_err(&ldb->pdev->dev, "get ldb clk0 failed\n"); iounmap(ldb->reg); return PTR_ERR(ldb->setting[setting_idx].ldb_di_clk); } di_clk[3] += setting->dev_id; di_clk[7] += setting->disp_id; ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev, di_clk); if (IS_ERR(ldb->setting[setting_idx].di_clk)) { dev_err(&ldb->pdev->dev, "get di clk0 failed\n"); iounmap(ldb->reg); return PTR_ERR(ldb->setting[setting_idx].di_clk); } dev_dbg(&ldb->pdev->dev, "ldb_clk to di clk: %s -> %s\n", ldb_clk, di_clk); /* fb notifier for clk setting */ ldb->nb.notifier_call = ldb_fb_event, ret = fb_register_client(&ldb->nb); if (ret < 0) { iounmap(ldb->reg); return ret; } ldb->inited = true; } else { /* second time for separate mode */ char di_clk[] = "ipu1_di0_clk"; char ldb_clk[] = "ldb_di0_clk"; int lvds_channel; if ((ldb->mode == LDB_SPL_DI0) || (ldb->mode == LDB_SPL_DI1) || (ldb->mode == LDB_DUL_DI0) || (ldb->mode == LDB_DUL_DI1) || (ldb->mode == LDB_SIN0) || (ldb->mode == LDB_SIN1)) { dev_err(&ldb->pdev->dev, "for second ldb disp" "ldb mode should in separate mode\n"); return -EINVAL; } setting_idx = 1; if (cpu_is_mx6q() || cpu_is_mx6dl()) { setting->dev_id = plat_data->sec_ipu_id; setting->disp_id = plat_data->sec_disp_id; } else { setting->dev_id = plat_data->ipu_id; setting->disp_id = !plat_data->disp_id; } if (setting->disp_id == ldb->setting[0].di) { dev_err(&ldb->pdev->dev, "Err: for second ldb disp in" "separate mode, DI should be different!\n"); return -EINVAL; } /* second output is LVDS0 or LVDS1 */ if (ldb->mode == LDB_SEP0) lvds_channel = 1; else lvds_channel = 0; reg = readl(ldb->control_reg); if ((lvds_channel == 0) && (setting->disp_id == 0)) reg |= LDB_CH0_MODE_EN_TO_DI0; else if ((lvds_channel == 0) && (setting->disp_id == 1)) reg |= LDB_CH0_MODE_EN_TO_DI1; else if ((lvds_channel == 1) && (setting->disp_id == 0)) reg |= LDB_CH1_MODE_EN_TO_DI0; else reg |= LDB_CH1_MODE_EN_TO_DI1; ch_mask = lvds_channel ? LDB_CH1_MODE_MASK : LDB_CH0_MODE_MASK; ch_val = reg & ch_mask; if (bits_per_pixel(setting->if_fmt) == 24) { if (lvds_channel == 0) reg |= LDB_DATA_WIDTH_CH0_24; else reg |= LDB_DATA_WIDTH_CH1_24; } else { if (lvds_channel == 0) reg |= LDB_DATA_WIDTH_CH0_18; else reg |= LDB_DATA_WIDTH_CH1_18; } writel(reg, ldb->control_reg); /* clock setting */ if (cpu_is_mx6q() || cpu_is_mx6dl()) ldb_clk[6] += lvds_channel; else ldb_clk[6] += setting->disp_id; ldb->setting[setting_idx].ldb_di_clk = clk_get(&ldb->pdev->dev, ldb_clk); if (IS_ERR(ldb->setting[setting_idx].ldb_di_clk)) { dev_err(&ldb->pdev->dev, "get ldb clk1 failed\n"); return PTR_ERR(ldb->setting[setting_idx].ldb_di_clk); } di_clk[3] += setting->dev_id; di_clk[7] += setting->disp_id; ldb->setting[setting_idx].di_clk = clk_get(&ldb->pdev->dev, di_clk); if (IS_ERR(ldb->setting[setting_idx].di_clk)) { dev_err(&ldb->pdev->dev, "get di clk1 failed\n"); return PTR_ERR(ldb->setting[setting_idx].di_clk); } dev_dbg(&ldb->pdev->dev, "ldb_clk to di clk: %s -> %s\n", ldb_clk, di_clk); } ldb->setting[setting_idx].ch_mask = ch_mask; ldb->setting[setting_idx].ch_val = ch_val; if (cpu_is_mx6q() || cpu_is_mx6dl()) ldb_ipu_ldb_route(setting->dev_id, setting->disp_id, ldb); /* * ldb_di0_clk -> ipux_di0_clk * ldb_di1_clk -> ipux_di1_clk */ clk_set_parent(ldb->setting[setting_idx].di_clk, ldb->setting[setting_idx].ldb_di_clk); /* must use spec video mode defined by driver */ ret = fb_find_mode(&setting->fbi->var, setting->fbi, setting->dft_mode_str, ldb_modedb, ldb_modedb_sz, NULL, setting->default_bpp); if (ret != 1) fb_videomode_to_var(&setting->fbi->var, &ldb_modedb[0]); INIT_LIST_HEAD(&setting->fbi->modelist); for (i = 0; i < ldb_modedb_sz; i++) { struct fb_videomode m; fb_var_to_videomode(&m, &setting->fbi->var); if (fb_mode_is_equal(&m, &ldb_modedb[i])) { fb_add_videomode(&ldb_modedb[i], &setting->fbi->modelist); break; } } /* save current ldb setting for fb notifier */ ldb->setting[setting_idx].active = true; ldb->setting[setting_idx].ipu = setting->dev_id; ldb->setting[setting_idx].di = setting->disp_id; return ret; }
static int pwm_backlight_probe(struct platform_device *pdev) { struct platform_pwm_backlight_data *data = pdev->dev.platform_data; struct backlight_device *bl; struct pwm_bl_data *pb; int ret; if (!data) { dev_err(&pdev->dev, "failed to find platform data\n"); return -EINVAL; } if (data->init) { ret = data->init(&pdev->dev); if (ret < 0) return ret; } pb = kzalloc(sizeof(*pb), GFP_KERNEL); if (!pb) { dev_err(&pdev->dev, "no memory for state\n"); ret = -ENOMEM; goto err_alloc; } pb->period = data->pwm_period_ns; pb->notify = data->notify; pb->power = data->power; pb->pwm = pwm_request(data->pwm_id, "backlight"); if (IS_ERR(pb->pwm)) { dev_err(&pdev->dev, "unable to request PWM for backlight\n"); ret = PTR_ERR(pb->pwm); goto err_pwm; } else dev_dbg(&pdev->dev, "got pwm for backlight\n"); bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb, &pwm_backlight_ops); if (IS_ERR(bl)) { dev_err(&pdev->dev, "failed to register backlight\n"); ret = PTR_ERR(bl); goto err_bl; } pb->notifier.notifier_call = pwm_bl_notifier_call; ret = fb_register_client(&pb->notifier); bl->props.max_brightness = data->max_brightness; bl->props.brightness = data->dft_brightness; backlight_update_status(bl); platform_set_drvdata(pdev, bl); return 0; err_bl: pwm_free(pb->pwm); err_pwm: kfree(pb); err_alloc: if (data->exit) data->exit(&pdev->dev); return ret; }
/*! * This function is called by the driver framework to initialize the LDB * device. * * @param dev The device structure for the LDB passed in by the * driver framework. * * @return Returns 0 on success or negative error code on error */ static int ldb_probe(struct platform_device *pdev) { int ret = 0, i, ipu_di, ipu_di_pix_fmt[2]; bool primary = false, find_1080p = false; struct resource *res; struct ldb_platform_data *plat_data = pdev->dev.platform_data; mm_segment_t old_fs; struct clk *ldb_clk_parent; unsigned long ldb_clk_prate = 455000000; struct fb_var_screeninfo *var[2]; uint32_t reg; struct device *temp; int mxc_ldb_major; const struct fb_videomode *mode; struct class *mxc_ldb_class; if (g_enable_ldb == false) return -ENODEV; spin_lock_init(&ldb_lock); g_ldb_dev = &pdev->dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (IS_ERR(res)) return -ENODEV; memset(&ldb, 0, sizeof(struct ldb_data)); enabled[0] = enabled[1] = false; var[0] = var[1] = NULL; if (g_boot_cmd) { ldb.chan_mode_opt = g_chan_mode_opt; ldb.chan_bit_map[0] = g_chan_bit_map[0]; ldb.chan_bit_map[1] = g_chan_bit_map[1]; } ldb.base_addr = res->start; ldb_reg = ioremap(ldb.base_addr, res->end - res->start + 1); ldb.control_reg = ldb_reg + 2; INIT_LIST_HEAD(&ldb.modelist); for (i = 0; i < mxcfb_ldb_modedb_sz; i++) fb_add_videomode(&mxcfb_ldb_modedb[i], &ldb.modelist); for (i = 0; i < num_registered_fb; i++) { if ((registered_fb[i]->var.sync & FB_SYNC_EXT) && (registered_fb[i]->var.vmode == FB_VMODE_NONINTERLACED)) { ldb.fbi[i] = registered_fb[i]; mode = fb_match_mode(&ldb.fbi[i]->var, &ldb.modelist); if (mode) { dev_dbg(g_ldb_dev, "fb mode found\n"); fb_videomode_to_var(&ldb.fbi[i]->var, mode); } else { dev_warn(g_ldb_dev, "can't find video mode\n"); goto err0; } /* * Default ldb mode: * 1080p: DI0 split, SPWG or DI1 split, SPWG * others: single, SPWG */ if (g_boot_cmd == false) { if (fb_mode_is_equal(mode, &mxcfb_ldb_modedb[0])) { if (strcmp(ldb.fbi[i]->fix.id, "DISP3 BG") == 0) { ldb.chan_mode_opt = LDB_SPL_DI0; dev_warn(g_ldb_dev, "default di0 split mode\n"); } else if (strcmp(ldb.fbi[i]->fix.id, "DISP3 BG - DI1") == 0) { ldb.chan_mode_opt = LDB_SPL_DI1; dev_warn(g_ldb_dev, "default di1 split mode\n"); } ldb.chan_bit_map[0] = LDB_BIT_MAP_SPWG; ldb.chan_bit_map[1] = LDB_BIT_MAP_SPWG; find_1080p = true; } else if (!find_1080p) { if (strcmp(ldb.fbi[i]->fix.id, "DISP3 BG") == 0) { ldb.chan_mode_opt = LDB_SIN_DI0; ldb.chan_bit_map[0] = LDB_BIT_MAP_SPWG; dev_warn(g_ldb_dev, "default di0 single mode\n"); } else if (strcmp(ldb.fbi[i]->fix.id, "DISP3 BG - DI1") == 0) { ldb.chan_mode_opt = LDB_SIN_DI1; ldb.chan_bit_map[1] = LDB_BIT_MAP_SPWG; dev_warn(g_ldb_dev, "default di1 single mode\n"); } } } acquire_console_sem(); fb_blank(ldb.fbi[i], FB_BLANK_POWERDOWN); release_console_sem(); if (i == 0) primary = true; if (ldb.fbi[1] != NULL) break; } } /* * We cannot support two LVDS panel with different pixel clock rates * except that one's pixel clock rate is two times of the others'. */ if (ldb.fbi[1] && ldb.fbi[0] != NULL) { if (ldb.fbi[0]->var.pixclock != ldb.fbi[1]->var.pixclock && ldb.fbi[0]->var.pixclock != 2 * ldb.fbi[1]->var.pixclock && ldb.fbi[1]->var.pixclock != 2 * ldb.fbi[0]->var.pixclock) return -EINVAL; } ldb.bgref_rmode = plat_data->ext_ref; ldb.lvds_bg_reg = regulator_get(&pdev->dev, plat_data->lvds_bg_reg); if (!IS_ERR(ldb.lvds_bg_reg)) { regulator_set_voltage(ldb.lvds_bg_reg, 2500000, 2500000); regulator_enable(ldb.lvds_bg_reg); } for (i = 0; i < 2; i++) { if (ldb.fbi[i] != NULL) { if (strcmp(ldb.fbi[i]->fix.id, "DISP3 BG") == 0) ipu_di = 0; else if (strcmp(ldb.fbi[i]->fix.id, "DISP3 BG - DI1") == 0) ipu_di = 1; else { dev_err(g_ldb_dev, "Wrong framebuffer\n"); goto err0; } var[ipu_di] = &ldb.fbi[i]->var; if (ldb.fbi[i]->fbops->fb_ioctl) { old_fs = get_fs(); set_fs(KERNEL_DS); ldb.fbi[i]->fbops->fb_ioctl(ldb.fbi[i], MXCFB_GET_DIFMT, (unsigned long)&(ipu_di_pix_fmt[ipu_di])); set_fs(old_fs); } else { dev_err(g_ldb_dev, "Can't get framebuffer " "information\n"); goto err0; } if (!valid_mode(ipu_di_pix_fmt[ipu_di])) { dev_err(g_ldb_dev, "Unsupport pixel format " "for ldb input\n"); goto err0; } reg = __raw_readl(ldb.control_reg); if (var[ipu_di]->sync & FB_SYNC_VERT_HIGH_ACT) { if (ipu_di == 0) __raw_writel((reg & ~LDB_DI0_VS_POL_MASK) | LDB_DI0_VS_POL_ACT_HIGH, ldb.control_reg); else __raw_writel((reg & ~LDB_DI1_VS_POL_MASK) | LDB_DI1_VS_POL_ACT_HIGH, ldb.control_reg); } else { if (ipu_di == 0) __raw_writel((reg & ~LDB_DI0_VS_POL_MASK) | LDB_DI0_VS_POL_ACT_LOW, ldb.control_reg); else __raw_writel((reg & ~LDB_DI1_VS_POL_MASK) | LDB_DI1_VS_POL_ACT_LOW, ldb.control_reg); } /* TODO:Set the correct pll4 rate for all situations */ if (ipu_di == 1) { ldb.ldb_di_clk[1] = clk_get(&pdev->dev, "ldb_di1_clk"); ldb_clk_parent = clk_get_parent(ldb.ldb_di_clk[1]); clk_set_rate(ldb_clk_parent, ldb_clk_prate); clk_put(ldb.ldb_di_clk[1]); } else { ldb.ldb_di_clk[0] = clk_get(&pdev->dev, "ldb_di0_clk"); ldb_clk_parent = clk_get_parent(ldb.ldb_di_clk[0]); clk_set_rate(ldb_clk_parent, ldb_clk_prate); clk_put(ldb.ldb_di_clk[0]); } } } reg = __raw_readl(ldb.control_reg); if (ldb.bgref_rmode == LDB_EXT_REF) __raw_writel((reg & ~LDB_BGREF_RMODE_MASK) | LDB_BGREF_RMODE_EXT, ldb.control_reg); else __raw_writel((reg & ~LDB_BGREF_RMODE_MASK) | LDB_BGREF_RMODE_INT, ldb.control_reg); switch (ldb.chan_mode_opt) { case LDB_SIN_DI0: if (var[0] == NULL) { dev_err(g_ldb_dev, "Can't find framebuffer on DI0\n"); break; } reg = __raw_readl(ldb.control_reg); if (bits_per_pixel(ipu_di_pix_fmt[0]) == 24) __raw_writel((reg & ~LDB_DATA_WIDTH_CH0_MASK) | LDB_DATA_WIDTH_CH0_24, ldb.control_reg); else if (bits_per_pixel(ipu_di_pix_fmt[0]) == 18) __raw_writel((reg & ~LDB_DATA_WIDTH_CH0_MASK) | LDB_DATA_WIDTH_CH0_18, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (ldb.chan_bit_map[0] == LDB_BIT_MAP_SPWG) __raw_writel((reg & ~LDB_BIT_MAP_CH0_MASK) | LDB_BIT_MAP_CH0_SPWG, ldb.control_reg); else __raw_writel((reg & ~LDB_BIT_MAP_CH0_MASK) | LDB_BIT_MAP_CH0_JEIDA, ldb.control_reg); ldb.ldb_di_clk[0] = clk_get(NULL, "ldb_di0_clk"); clk_set_rate(ldb.ldb_di_clk[0], ldb_clk_prate/7); clk_enable(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[0]); reg = __raw_readl(ldb.control_reg); __raw_writel((reg & ~LDB_CH0_MODE_MASK) | LDB_CH0_MODE_EN_TO_DI0, ldb.control_reg); ldb.ch_working[0] = true; break; case LDB_SIN_DI1: if (var[1] == NULL) { dev_err(g_ldb_dev, "Can't find framebuffer on DI1\n"); break; } reg = __raw_readl(ldb.control_reg); if (bits_per_pixel(ipu_di_pix_fmt[1]) == 24) __raw_writel((reg & ~LDB_DATA_WIDTH_CH1_MASK) | LDB_DATA_WIDTH_CH1_24, ldb.control_reg); else if (bits_per_pixel(ipu_di_pix_fmt[1]) == 18) __raw_writel((reg & ~LDB_DATA_WIDTH_CH1_MASK) | LDB_DATA_WIDTH_CH1_18, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (ldb.chan_bit_map[1] == LDB_BIT_MAP_SPWG) __raw_writel((reg & ~LDB_BIT_MAP_CH1_MASK) | LDB_BIT_MAP_CH1_SPWG, ldb.control_reg); else __raw_writel((reg & ~LDB_BIT_MAP_CH1_MASK) | LDB_BIT_MAP_CH1_JEIDA, ldb.control_reg); ldb.ldb_di_clk[1] = clk_get(NULL, "ldb_di1_clk"); clk_set_rate(ldb.ldb_di_clk[1], ldb_clk_prate/7); clk_enable(ldb.ldb_di_clk[1]); clk_put(ldb.ldb_di_clk[1]); reg = __raw_readl(ldb.control_reg); __raw_writel((reg & ~LDB_CH1_MODE_MASK) | LDB_CH1_MODE_EN_TO_DI1, ldb.control_reg); ldb.ch_working[1] = true; break; case LDB_SEP: if (var[0] == NULL || var[1] == NULL) { dev_err(g_ldb_dev, "Can't find framebuffers on DI0/1\n"); break; } reg = __raw_readl(ldb.control_reg); if (bits_per_pixel(ipu_di_pix_fmt[0]) == 24) __raw_writel((reg & ~LDB_DATA_WIDTH_CH0_MASK) | LDB_DATA_WIDTH_CH0_24, ldb.control_reg); else if (bits_per_pixel(ipu_di_pix_fmt[0]) == 18) __raw_writel((reg & ~LDB_DATA_WIDTH_CH0_MASK) | LDB_DATA_WIDTH_CH0_18, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (bits_per_pixel(ipu_di_pix_fmt[1]) == 24) __raw_writel((reg & ~LDB_DATA_WIDTH_CH1_MASK) | LDB_DATA_WIDTH_CH1_24, ldb.control_reg); else if (bits_per_pixel(ipu_di_pix_fmt[1]) == 18) __raw_writel((reg & ~LDB_DATA_WIDTH_CH1_MASK) | LDB_DATA_WIDTH_CH1_18, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (ldb.chan_bit_map[0] == LDB_BIT_MAP_SPWG) __raw_writel((reg & ~LDB_BIT_MAP_CH0_MASK) | LDB_BIT_MAP_CH0_SPWG, ldb.control_reg); else __raw_writel((reg & ~LDB_BIT_MAP_CH0_MASK) | LDB_BIT_MAP_CH0_JEIDA, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (ldb.chan_bit_map[1] == LDB_BIT_MAP_SPWG) __raw_writel((reg & ~LDB_BIT_MAP_CH1_MASK) | LDB_BIT_MAP_CH1_SPWG, ldb.control_reg); else __raw_writel((reg & ~LDB_BIT_MAP_CH1_MASK) | LDB_BIT_MAP_CH1_JEIDA, ldb.control_reg); ldb.ldb_di_clk[0] = clk_get(NULL, "ldb_di0_clk"); clk_set_rate(ldb.ldb_di_clk[0], ldb_clk_prate/7); clk_enable(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[0]); ldb.ldb_di_clk[1] = clk_get(NULL, "ldb_di1_clk"); clk_set_rate(ldb.ldb_di_clk[1], ldb_clk_prate/7); clk_enable(ldb.ldb_di_clk[1]); clk_put(ldb.ldb_di_clk[1]); reg = __raw_readl(ldb.control_reg); __raw_writel((reg & ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK)) | LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI1, ldb.control_reg); ldb.ch_working[0] = true; ldb.ch_working[1] = true; break; case LDB_DUL_DI0: case LDB_SPL_DI0: if (var[0] == NULL) { dev_err(g_ldb_dev, "Can't find framebuffer on DI0\n"); break; } reg = __raw_readl(ldb.control_reg); if (bits_per_pixel(ipu_di_pix_fmt[0]) == 24) __raw_writel((reg & ~(LDB_DATA_WIDTH_CH0_MASK | LDB_DATA_WIDTH_CH1_MASK)) | LDB_DATA_WIDTH_CH0_24 | LDB_DATA_WIDTH_CH1_24, ldb.control_reg); else if (bits_per_pixel(ipu_di_pix_fmt[0]) == 18) __raw_writel((reg & ~(LDB_DATA_WIDTH_CH0_MASK | LDB_DATA_WIDTH_CH1_MASK)) | LDB_DATA_WIDTH_CH0_18 | LDB_DATA_WIDTH_CH1_18, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (ldb.chan_bit_map[0] == LDB_BIT_MAP_SPWG) __raw_writel((reg & ~LDB_BIT_MAP_CH0_MASK) | LDB_BIT_MAP_CH0_SPWG, ldb.control_reg); else __raw_writel((reg & ~LDB_BIT_MAP_CH0_MASK) | LDB_BIT_MAP_CH0_JEIDA, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (ldb.chan_bit_map[1] == LDB_BIT_MAP_SPWG) __raw_writel((reg & ~LDB_BIT_MAP_CH1_MASK) | LDB_BIT_MAP_CH1_SPWG, ldb.control_reg); else __raw_writel((reg & ~LDB_BIT_MAP_CH1_MASK) | LDB_BIT_MAP_CH1_JEIDA, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (ldb.chan_mode_opt == LDB_SPL_DI0) __raw_writel(reg | LDB_SPLIT_MODE_EN, ldb.control_reg); ldb.ldb_di_clk[0] = clk_get(NULL, "ldb_di0_clk"); ldb.ldb_di_clk[1] = clk_get(NULL, "ldb_di1_clk"); if (ldb.chan_mode_opt == LDB_DUL_DI0) { clk_set_rate(ldb.ldb_di_clk[0], ldb_clk_prate/7); } else { clk_set_rate(ldb.ldb_di_clk[0], 2*ldb_clk_prate/7); clk_set_rate(ldb.ldb_di_clk[1], 2*ldb_clk_prate/7); } clk_enable(ldb.ldb_di_clk[0]); clk_enable(ldb.ldb_di_clk[1]); clk_put(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[1]); reg = __raw_readl(ldb.control_reg); __raw_writel((reg & ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK)) | LDB_CH0_MODE_EN_TO_DI0 | LDB_CH1_MODE_EN_TO_DI0, ldb.control_reg); ldb.ch_working[0] = true; ldb.ch_working[1] = true; break; case LDB_DUL_DI1: case LDB_SPL_DI1: if (var[1] == NULL) { dev_err(g_ldb_dev, "Can't find framebuffer on DI1\n"); break; } reg = __raw_readl(ldb.control_reg); if (bits_per_pixel(ipu_di_pix_fmt[1]) == 24) __raw_writel((reg & ~(LDB_DATA_WIDTH_CH0_MASK | LDB_DATA_WIDTH_CH1_MASK)) | LDB_DATA_WIDTH_CH0_24 | LDB_DATA_WIDTH_CH1_24, ldb.control_reg); else if (bits_per_pixel(ipu_di_pix_fmt[1]) == 18) __raw_writel((reg & ~(LDB_DATA_WIDTH_CH0_MASK | LDB_DATA_WIDTH_CH1_MASK)) | LDB_DATA_WIDTH_CH0_18 | LDB_DATA_WIDTH_CH1_18, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (ldb.chan_bit_map[0] == LDB_BIT_MAP_SPWG) __raw_writel((reg & ~LDB_BIT_MAP_CH0_MASK) | LDB_BIT_MAP_CH0_SPWG, ldb.control_reg); else __raw_writel((reg & ~LDB_BIT_MAP_CH0_MASK) | LDB_BIT_MAP_CH0_JEIDA, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (ldb.chan_bit_map[1] == LDB_BIT_MAP_SPWG) __raw_writel((reg & ~LDB_BIT_MAP_CH1_MASK) | LDB_BIT_MAP_CH1_SPWG, ldb.control_reg); else __raw_writel((reg & ~LDB_BIT_MAP_CH1_MASK) | LDB_BIT_MAP_CH1_JEIDA, ldb.control_reg); reg = __raw_readl(ldb.control_reg); if (ldb.chan_mode_opt == LDB_SPL_DI1) __raw_writel(reg | LDB_SPLIT_MODE_EN, ldb.control_reg); ldb.ldb_di_clk[0] = clk_get(NULL, "ldb_di0_clk"); ldb.ldb_di_clk[1] = clk_get(NULL, "ldb_di1_clk"); if (ldb.chan_mode_opt == LDB_DUL_DI1) { clk_set_rate(ldb.ldb_di_clk[1], ldb_clk_prate/7); } else { clk_set_rate(ldb.ldb_di_clk[0], 2*ldb_clk_prate/7); clk_set_rate(ldb.ldb_di_clk[1], 2*ldb_clk_prate/7); } clk_enable(ldb.ldb_di_clk[0]); clk_enable(ldb.ldb_di_clk[1]); clk_put(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[1]); reg = __raw_readl(ldb.control_reg); __raw_writel((reg & ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK)) | LDB_CH0_MODE_EN_TO_DI1 | LDB_CH1_MODE_EN_TO_DI1, ldb.control_reg); ldb.ch_working[0] = true; ldb.ch_working[1] = true; break; default: break; } mxc_ldb_major = register_chrdev(0, "mxc_ldb", &mxc_ldb_fops); if (mxc_ldb_major < 0) { dev_err(g_ldb_dev, "Unable to register MXC LDB as a char " "device\n"); ret = mxc_ldb_major; goto err0; } mxc_ldb_class = class_create(THIS_MODULE, "mxc_ldb"); if (IS_ERR(mxc_ldb_class)) { dev_err(g_ldb_dev, "Unable to create class for MXC LDB\n"); ret = PTR_ERR(mxc_ldb_class); goto err1; } temp = device_create(mxc_ldb_class, NULL, MKDEV(mxc_ldb_major, 0), NULL, "mxc_ldb"); if (IS_ERR(temp)) { dev_err(g_ldb_dev, "Unable to create class device for " "MXC LDB\n"); ret = PTR_ERR(temp); goto err2; } ret = fb_register_client(&nb); if (ret < 0) goto err2; if (primary && ldb.fbi[0] != NULL) { acquire_console_sem(); fb_blank(ldb.fbi[0], FB_BLANK_UNBLANK); release_console_sem(); fb_show_logo(ldb.fbi[0], 0); } return ret; err2: class_destroy(mxc_ldb_class); err1: unregister_chrdev(mxc_ldb_major, "mxc_ldb"); err0: iounmap(ldb_reg); return ret; }
static int vga_edid_probe(struct i2c_client *client, const struct i2c_device_id *id) { char buf[EDID_LENGTH]; struct fb_monspecs specs; struct fb_videomode *moded; int ret = -1; int gpio, rc,flag; unsigned long data; struct regulator * ldo; struct device_node *vga_node = client->dev.of_node; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; ldo = regulator_get(NULL, "act_ldo3"); if (ldo == NULL) { pr_err("\n%s get ldo3 failed\n", __func__); } else{ regulator_set_voltage(ldo, 1800000, 1800000); ret = regulator_enable(ldo); if(ret != 0){ pr_err("%s: faild to enable ldo3\n", __func__); } else { pr_info("%s: turn on ldo3 done.\n", __func__); } } ldo = regulator_get(NULL, "act_ldo4"); if (ldo == NULL) { pr_err("\n%s get ldo failed\n", __func__); } else{ regulator_set_voltage(ldo, 3300000, 3300000); ret = regulator_enable(ldo); if(ret != 0){ pr_err("%s: faild to enable ldo4.\n", __func__); } else { pr_info("%s: turn on ldo done.\n", __func__); } } ldo = regulator_get(NULL, "act_ldo2"); if (ldo == NULL) { pr_err("\n%s get ldo2 failed\n", __func__); } else{ regulator_set_voltage(ldo, 1000000, 1000000); ret = regulator_enable(ldo); if(ret != 0){ pr_err("%s: faild to enable ldo2\n", __func__); } else { pr_info("%s: turn on ldo2 done.\n", __func__); } } ldo = regulator_get(NULL, "act_ldo8"); if (ldo == NULL) { pr_err("\n%s get ldo8 failed\n", __func__); } else{ regulator_set_voltage(ldo, 1800000, 1800000); ret = regulator_enable(ldo); if(ret != 0){ pr_err("%s: faild to enable ldo8.\n", __func__); } else { pr_info("%s: turn on ldo done.\n", __func__); } } ddev = kzalloc(sizeof(struct vga_ddc_dev), GFP_KERNEL); if (ddev == NULL) return -ENOMEM; INIT_LIST_HEAD(&ddev->modelist); ddev->client = client; gpio = of_get_named_gpio_flags(vga_node,"gpio-pwn", 0,&flag); if (!gpio_is_valid(gpio)){ printk("invalid gpio-pwn: %d\n",gpio); return -1; } ret = gpio_request(gpio, "vga_pwn"); if (ret != 0) { gpio_free(gpio); ret = -EIO; goto failed_1; } ddev->gpio_pwn = gpio; ddev->gpio_pwn_enable = (flag == OF_GPIO_ACTIVE_LOW)? 0:1; #ifdef CONFIG_FIREFLY_VGA_OUT_ONLY gpio_direction_output(ddev->gpio_pwn, !(ddev->gpio_pwn_enable)); #else gpio_direction_output(ddev->gpio_pwn, ddev->gpio_pwn_enable); gpio = of_get_named_gpio_flags(vga_node,"gpio-sel", 0,&flag); if (!gpio_is_valid(gpio)){ printk("invalid gpio-sel: %d\n",gpio); return -1; } ret = gpio_request(gpio, "vga_sel"); if (ret != 0) { gpio_free(gpio); ret = -EIO; goto failed_1; } ddev->gpio_sel = gpio; ddev->gpio_sel_enable = (flag == OF_GPIO_ACTIVE_LOW)? 0:1; gpio_direction_output(ddev->gpio_sel, ddev->gpio_sel_enable); #endif of_property_read_u32(vga_node, "rockchip,source", &(rc)); ddev->video_source = rc; of_property_read_u32(vga_node, "rockchip,prop", &(rc)); ddev->property = rc - 1; ddev->modeNum = vga_switch_default_screen(); #ifndef CONFIG_FIREFLY_VGA_OUT_ONLY vga_switch_source(VGA_SOURCE_EXTERN); #endif printk("%s: success. %d \n", __func__,ddev->modeNum); //setup_timer(&timer_vga_ddc, vga_ddc_timer, data); //INIT_DELAYED_WORK(&ddev->work, vga_ddc_timer); //schedule_work(&chip->work); memset(&vga_monspecs, 0, sizeof(struct sda7123_monspecs)); ddev->vga = &vga_monspecs; #ifdef CONFIG_SWITCH ddev->switchdev.name="vga"; ddev->switchdev.print_name = vga_print_name; switch_dev_register(&(ddev->switchdev)); #endif mutex_init(&ddev->vga->lock); ddev->vga->workqueue = create_singlethread_workqueue("vga"); if (ddev->vga->workqueue == NULL) { printk(KERN_ERR "vga,: create workqueue failed.\n"); goto failed_1; } ddev->first_start = 1; ddev->set_mode = 0; firefly_register_display_vga(&client->dev); fb_register_client(&firefly_fb_notifier); vga_submit_work(ddev->vga, VGA_TIMER_DELAY, 8000, NULL); return 0; failed_1: return ret; }