/* * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved. */ /* * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License * Version 2 or later at the following locations: * * http://www.opensource.org/licenses/gpl-license.html * http://www.gnu.org/copyleft/gpl.html */ /*! * @defgroup PMIC_BL MXC PMIC Backlight Driver */ /*! * @file mxc_pmic_bl.c * * @brief PMIC Backlight Driver for Freescale MXC/i.MX platforms. * * This file contains API defined in include/linux/clk.h for setting up and * retrieving clocks. * * Based on Sharp's Corgi Backlight Driver * * @ingroup PMIC_BL */ #include #include #include #include #include #include #include #include #include #define MXC_MAX_INTENSITY 255 #define MXC_DEFAULT_INTENSITY 127 #define MXC_INTENSITY_OFF 0 struct mxcbl_dev_data { int bl_id; int intensity; struct backlight_ops bl_ops; }; static int pmic_bl_use_count; static int main_fb_id; static int sec_fb_id; static int mxcbl_send_intensity(struct backlight_device *bd) { int intensity = bd->props.brightness; struct mxcbl_dev_data *devdata = dev_get_drvdata(&bd->dev); if (bd->props.power != FB_BLANK_UNBLANK) intensity = 0; if (bd->props.fb_blank != FB_BLANK_UNBLANK) intensity = 0; intensity = intensity / 16; pmic_bklit_set_dutycycle(devdata->bl_id, intensity); devdata->intensity = intensity; return 0; } static int mxcbl_get_intensity(struct backlight_device *bd) { struct mxcbl_dev_data *devdata = dev_get_drvdata(&bd->dev); return devdata->intensity; } static int mxcbl_check_main_fb(struct fb_info *info) { int id = info->fix.id[4] - '0'; if (id == main_fb_id) { return 1; } else { return 0; } } static int mxcbl_check_sec_fb(struct fb_info *info) { int id = info->fix.id[4] - '0'; if (id == sec_fb_id) { return 1; } else { return 0; } } static int __init mxcbl_probe(struct platform_device *pdev) { int ret = 0; struct backlight_device *bd; struct mxcbl_dev_data *devdata; devdata = kzalloc(sizeof(struct mxcbl_dev_data), GFP_KERNEL); if (!devdata) return -ENOMEM; devdata->bl_id = pdev->id; if (pdev->id == 0) { devdata->bl_ops.check_fb = mxcbl_check_main_fb; main_fb_id = (int)pdev->dev.platform_data; } else { devdata->bl_ops.check_fb = mxcbl_check_sec_fb; sec_fb_id = (int)pdev->dev.platform_data; } devdata->bl_ops.get_brightness = mxcbl_get_intensity; devdata->bl_ops.update_status = mxcbl_send_intensity, bd = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, devdata, &devdata->bl_ops); if (IS_ERR(bd)) { ret = PTR_ERR(bd); goto err0; } platform_set_drvdata(pdev, bd); if (pmic_bl_use_count++ == 0) { pmic_power_regulator_on(SW_SW3); pmic_power_regulator_set_lp_mode(SW_SW3, LOW_POWER_CTRL_BY_PIN); pmic_bklit_tcled_master_enable(); pmic_bklit_enable_edge_slow(); pmic_bklit_set_cycle_time(0); } pmic_bklit_set_current(devdata->bl_id, 7); bd->props.brightness = MXC_DEFAULT_INTENSITY; bd->props.max_brightness = MXC_MAX_INTENSITY; bd->props.power = FB_BLANK_UNBLANK; bd->props.fb_blank = FB_BLANK_UNBLANK; backlight_update_status(bd); printk("MXC Backlight Device %s Initialized.\n", dev_name(&pdev->dev)); return 0; err0: kfree(devdata); return ret; } static int mxcbl_remove(struct platform_device *pdev) { struct backlight_device *bd = platform_get_drvdata(pdev); bd->props.brightness = MXC_INTENSITY_OFF; backlight_update_status(bd); if (--pmic_bl_use_count == 0) { pmic_bklit_tcled_master_disable(); pmic_power_regulator_off(SW_SW3); pmic_power_regulator_set_lp_mode(SW_SW3, LOW_POWER_CTRL_BY_PIN); } backlight_device_unregister(bd); printk("MXC Backlight Driver Unloaded\n"); return 0; } static struct platform_driver mxcbl_driver = { .probe = mxcbl_probe, .remove = mxcbl_remove, .driver = { .name = "mxc_pmic_bl", }, }; static int __init mxcbl_init(void) { return platform_driver_register(&mxcbl_driver); } static void __exit mxcbl_exit(void) { platform_driver_unregister(&mxcbl_driver); } module_init(mxcbl_init); module_exit(mxcbl_exit); MODULE_DESCRIPTION("Freescale MXC/i.MX PMIC Backlight Driver"); MODULE_AUTHOR("Freescale Semiconductor, Inc."); MODULE_LICENSE("GPL");