180 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Backlight Driver for Dialog DA9052 PMICs4 *5 * Copyright(c) 2012 Dialog Semiconductor Ltd.6 *7 * Author: David Dajun Chen <dchen@diasemi.com>8 */9 10#include <linux/backlight.h>11#include <linux/delay.h>12#include <linux/fb.h>13#include <linux/module.h>14#include <linux/platform_device.h>15 16#include <linux/mfd/da9052/da9052.h>17#include <linux/mfd/da9052/reg.h>18 19#define DA9052_MAX_BRIGHTNESS 0xFF20 21enum {22 DA9052_WLEDS_OFF,23 DA9052_WLEDS_ON,24};25 26enum {27 DA9052_TYPE_WLED1,28 DA9052_TYPE_WLED2,29 DA9052_TYPE_WLED3,30};31 32static const unsigned char wled_bank[] = {33 DA9052_LED1_CONF_REG,34 DA9052_LED2_CONF_REG,35 DA9052_LED3_CONF_REG,36};37 38struct da9052_bl {39 struct da9052 *da9052;40 uint brightness;41 uint state;42 uint led_reg;43};44 45static int da9052_adjust_wled_brightness(struct da9052_bl *wleds)46{47 unsigned char boost_en;48 unsigned char i_sink;49 int ret;50 51 boost_en = 0x3F;52 i_sink = 0xFF;53 if (wleds->state == DA9052_WLEDS_OFF) {54 boost_en = 0x00;55 i_sink = 0x00;56 }57 58 ret = da9052_reg_write(wleds->da9052, DA9052_BOOST_REG, boost_en);59 if (ret < 0)60 return ret;61 62 ret = da9052_reg_write(wleds->da9052, DA9052_LED_CONT_REG, i_sink);63 if (ret < 0)64 return ret;65 66 ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], 0x0);67 if (ret < 0)68 return ret;69 70 usleep_range(10000, 11000);71 72 if (wleds->brightness) {73 ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg],74 wleds->brightness);75 if (ret < 0)76 return ret;77 }78 79 return 0;80}81 82static int da9052_backlight_update_status(struct backlight_device *bl)83{84 int brightness = bl->props.brightness;85 struct da9052_bl *wleds = bl_get_data(bl);86 87 wleds->brightness = brightness;88 wleds->state = DA9052_WLEDS_ON;89 90 return da9052_adjust_wled_brightness(wleds);91}92 93static int da9052_backlight_get_brightness(struct backlight_device *bl)94{95 struct da9052_bl *wleds = bl_get_data(bl);96 97 return wleds->brightness;98}99 100static const struct backlight_ops da9052_backlight_ops = {101 .update_status = da9052_backlight_update_status,102 .get_brightness = da9052_backlight_get_brightness,103};104 105static int da9052_backlight_probe(struct platform_device *pdev)106{107 struct backlight_device *bl;108 struct backlight_properties props;109 struct da9052_bl *wleds;110 111 wleds = devm_kzalloc(&pdev->dev, sizeof(struct da9052_bl), GFP_KERNEL);112 if (!wleds)113 return -ENOMEM;114 115 wleds->da9052 = dev_get_drvdata(pdev->dev.parent);116 wleds->brightness = 0;117 wleds->led_reg = platform_get_device_id(pdev)->driver_data;118 wleds->state = DA9052_WLEDS_OFF;119 120 memset(&props, 0, sizeof(struct backlight_properties));121 props.type = BACKLIGHT_RAW;122 props.max_brightness = DA9052_MAX_BRIGHTNESS;123 124 bl = devm_backlight_device_register(&pdev->dev, pdev->name,125 wleds->da9052->dev, wleds,126 &da9052_backlight_ops, &props);127 if (IS_ERR(bl)) {128 dev_err(&pdev->dev, "Failed to register backlight\n");129 return PTR_ERR(bl);130 }131 132 bl->props.max_brightness = DA9052_MAX_BRIGHTNESS;133 bl->props.brightness = 0;134 platform_set_drvdata(pdev, bl);135 136 return da9052_adjust_wled_brightness(wleds);137}138 139static void da9052_backlight_remove(struct platform_device *pdev)140{141 struct backlight_device *bl = platform_get_drvdata(pdev);142 struct da9052_bl *wleds = bl_get_data(bl);143 144 wleds->brightness = 0;145 wleds->state = DA9052_WLEDS_OFF;146 da9052_adjust_wled_brightness(wleds);147}148 149static const struct platform_device_id da9052_wled_ids[] = {150 {151 .name = "da9052-wled1",152 .driver_data = DA9052_TYPE_WLED1,153 },154 {155 .name = "da9052-wled2",156 .driver_data = DA9052_TYPE_WLED2,157 },158 {159 .name = "da9052-wled3",160 .driver_data = DA9052_TYPE_WLED3,161 },162 { },163};164MODULE_DEVICE_TABLE(platform, da9052_wled_ids);165 166static struct platform_driver da9052_wled_driver = {167 .probe = da9052_backlight_probe,168 .remove_new = da9052_backlight_remove,169 .id_table = da9052_wled_ids,170 .driver = {171 .name = "da9052-wled",172 },173};174 175module_platform_driver(da9052_wled_driver);176 177MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");178MODULE_DESCRIPTION("Backlight driver for DA9052 PMIC");179MODULE_LICENSE("GPL");180