backlight: da903x: Add backlight driver for DA9030/DA9034

Signed-off-by: Mike Rapoport <mike@compulab.co.il>
Signed-off-by: Eric Miao <eric.miao@marvell.com>
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>

authored by

Mike Rapoport and committed by
Richard Purdie
923ae48b 14b7b401

+209
+7
drivers/video/backlight/Kconfig
··· 180 180 If you have a LCD backlight adjustable by PWM, say Y to enable 181 181 this driver. 182 182 183 + config BACKLIGHT_DA903X 184 + tristate "Backlight Driver for DA9030/DA9034 using WLED" 185 + depends on BACKLIGHT_CLASS_DEVICE && PMIC_DA903X 186 + help 187 + If you have a LCD backlight connected to the WLED output of DA9030 188 + or DA9034 WLED output, say Y here to enable this driver. 189 + 183 190 config BACKLIGHT_MBP_NVIDIA 184 191 tristate "MacBook Pro Nvidia Backlight Driver" 185 192 depends on BACKLIGHT_CLASS_DEVICE && X86
+1
drivers/video/backlight/Makefile
··· 18 18 obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o 19 19 obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o 20 20 obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o 21 + obj-$(CONFIG_BACKLIGHT_DA903X) += da903x.o 21 22 obj-$(CONFIG_BACKLIGHT_MBP_NVIDIA) += mbp_nvidia_bl.o 22 23 obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o 23 24
+201
drivers/video/backlight/da903x.c
··· 1 + /* 2 + * Backlight driver for Dialog Semiconductor DA9030/DA9034 3 + * 4 + * Copyright (C) 2008 Compulab, Ltd. 5 + * Mike Rapoport <mike@compulab.co.il> 6 + * 7 + * Copyright (C) 2006-2008 Marvell International Ltd. 8 + * Eric Miao <eric.miao@marvell.com> 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 as 12 + * published by the Free Software Foundation. 13 + */ 14 + 15 + #include <linux/kernel.h> 16 + #include <linux/init.h> 17 + #include <linux/platform_device.h> 18 + #include <linux/fb.h> 19 + #include <linux/backlight.h> 20 + #include <linux/mfd/da903x.h> 21 + 22 + #define DA9030_WLED_CONTROL 0x25 23 + #define DA9030_WLED_CP_EN (1 << 6) 24 + #define DA9030_WLED_TRIM(x) ((x) & 0x7) 25 + 26 + #define DA9034_WLED_CONTROL1 0x3C 27 + #define DA9034_WLED_CONTROL2 0x3D 28 + 29 + #define DA9034_WLED_BOOST_EN (1 << 5) 30 + 31 + #define DA9030_MAX_BRIGHTNESS 7 32 + #define DA9034_MAX_BRIGHTNESS 0x7f 33 + 34 + struct da903x_backlight_data { 35 + struct device *da903x_dev; 36 + int id; 37 + int current_brightness; 38 + }; 39 + 40 + static int da903x_backlight_set(struct backlight_device *bl, int brightness) 41 + { 42 + struct da903x_backlight_data *data = bl_get_data(bl); 43 + struct device *dev = data->da903x_dev; 44 + uint8_t val; 45 + int ret = 0; 46 + 47 + switch (data->id) { 48 + case DA9034_ID_WLED: 49 + ret = da903x_update(dev, DA9034_WLED_CONTROL1, 50 + brightness, 0x7f); 51 + if (ret) 52 + return ret; 53 + 54 + if (data->current_brightness && brightness == 0) 55 + ret = da903x_clr_bits(dev, 56 + DA9034_WLED_CONTROL2, 57 + DA9034_WLED_BOOST_EN); 58 + 59 + if (data->current_brightness == 0 && brightness) 60 + ret = da903x_set_bits(dev, 61 + DA9034_WLED_CONTROL2, 62 + DA9034_WLED_BOOST_EN); 63 + break; 64 + case DA9030_ID_WLED: 65 + val = DA9030_WLED_TRIM(brightness); 66 + val |= brightness ? DA9030_WLED_CP_EN : 0; 67 + ret = da903x_write(dev, DA9030_WLED_CONTROL, val); 68 + break; 69 + } 70 + 71 + if (ret) 72 + return ret; 73 + 74 + data->current_brightness = brightness; 75 + return 0; 76 + } 77 + 78 + static int da903x_backlight_update_status(struct backlight_device *bl) 79 + { 80 + int brightness = bl->props.brightness; 81 + 82 + if (bl->props.power != FB_BLANK_UNBLANK) 83 + brightness = 0; 84 + 85 + if (bl->props.fb_blank != FB_BLANK_UNBLANK) 86 + brightness = 0; 87 + 88 + return da903x_backlight_set(bl, brightness); 89 + } 90 + 91 + static int da903x_backlight_get_brightness(struct backlight_device *bl) 92 + { 93 + struct da903x_backlight_data *data = bl_get_data(bl); 94 + return data->current_brightness; 95 + } 96 + 97 + static struct backlight_ops da903x_backlight_ops = { 98 + .update_status = da903x_backlight_update_status, 99 + .get_brightness = da903x_backlight_get_brightness, 100 + }; 101 + 102 + static int da903x_backlight_probe(struct platform_device *pdev) 103 + { 104 + struct da903x_backlight_data *data; 105 + struct backlight_device *bl; 106 + int max_brightness; 107 + 108 + data = kzalloc(sizeof(*data), GFP_KERNEL); 109 + if (data == NULL) 110 + return -ENOMEM; 111 + 112 + switch (pdev->id) { 113 + case DA9030_ID_WLED: 114 + max_brightness = DA9030_MAX_BRIGHTNESS; 115 + break; 116 + case DA9034_ID_WLED: 117 + max_brightness = DA9034_MAX_BRIGHTNESS; 118 + break; 119 + default: 120 + dev_err(&pdev->dev, "invalid backlight device ID(%d)\n", 121 + pdev->id); 122 + return -EINVAL; 123 + } 124 + 125 + data->id = pdev->id; 126 + data->da903x_dev = pdev->dev.parent; 127 + data->current_brightness = 0; 128 + 129 + bl = backlight_device_register(pdev->name, data->da903x_dev, 130 + data, &da903x_backlight_ops); 131 + if (IS_ERR(bl)) { 132 + dev_err(&pdev->dev, "failed to register backlight\n"); 133 + return PTR_ERR(bl); 134 + } 135 + 136 + bl->props.max_brightness = max_brightness; 137 + bl->props.brightness = max_brightness; 138 + 139 + platform_set_drvdata(pdev, bl); 140 + backlight_update_status(bl); 141 + return 0; 142 + } 143 + 144 + static int da903x_backlight_remove(struct platform_device *pdev) 145 + { 146 + struct backlight_device *bl = platform_get_drvdata(pdev); 147 + struct da903x_backlight_data *data = bl_get_data(bl); 148 + 149 + backlight_device_unregister(bl); 150 + kfree(data); 151 + return 0; 152 + } 153 + 154 + #ifdef CONFIG_PM 155 + static int da903x_backlight_suspend(struct platform_device *pdev, 156 + pm_message_t state) 157 + { 158 + struct backlight_device *bl = platform_get_drvdata(pdev); 159 + return da903x_backlight_set(bl, 0); 160 + } 161 + 162 + static int da903x_backlight_resume(struct platform_device *pdev) 163 + { 164 + struct backlight_device *bl = platform_get_drvdata(pdev); 165 + 166 + backlight_update_status(bl); 167 + return 0; 168 + } 169 + #else 170 + #define da903x_backlight_suspend NULL 171 + #define da903x_backlight_resume NULL 172 + #endif 173 + 174 + static struct platform_driver da903x_backlight_driver = { 175 + .driver = { 176 + .name = "da903x-backlight", 177 + .owner = THIS_MODULE, 178 + }, 179 + .probe = da903x_backlight_probe, 180 + .remove = da903x_backlight_remove, 181 + .suspend = da903x_backlight_suspend, 182 + .resume = da903x_backlight_resume, 183 + }; 184 + 185 + static int __init da903x_backlight_init(void) 186 + { 187 + return platform_driver_register(&da903x_backlight_driver); 188 + } 189 + module_init(da903x_backlight_init); 190 + 191 + static void __exit da903x_backlight_exit(void) 192 + { 193 + platform_driver_unregister(&da903x_backlight_driver); 194 + } 195 + module_exit(da903x_backlight_exit); 196 + 197 + MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034"); 198 + MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>" 199 + "Mike Rapoport <mike@compulab.co.il>"); 200 + MODULE_LICENSE("GPL"); 201 + MODULE_ALIAS("platform:da903x-backlight");