xref: /openbmc/linux/drivers/video/backlight/da9052_bl.c (revision 5ee9cd065836e5934710ca35653bce7905add20b)
12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
26ede3d83SAshish Jangam /*
36ede3d83SAshish Jangam  * Backlight Driver for Dialog DA9052 PMICs
46ede3d83SAshish Jangam  *
56ede3d83SAshish Jangam  * Copyright(c) 2012 Dialog Semiconductor Ltd.
66ede3d83SAshish Jangam  *
76ede3d83SAshish Jangam  * Author: David Dajun Chen <dchen@diasemi.com>
86ede3d83SAshish Jangam  */
96ede3d83SAshish Jangam 
106ede3d83SAshish Jangam #include <linux/backlight.h>
116ede3d83SAshish Jangam #include <linux/delay.h>
126ede3d83SAshish Jangam #include <linux/fb.h>
136ede3d83SAshish Jangam #include <linux/module.h>
146ede3d83SAshish Jangam #include <linux/platform_device.h>
156ede3d83SAshish Jangam 
166ede3d83SAshish Jangam #include <linux/mfd/da9052/da9052.h>
176ede3d83SAshish Jangam #include <linux/mfd/da9052/reg.h>
186ede3d83SAshish Jangam 
196ede3d83SAshish Jangam #define DA9052_MAX_BRIGHTNESS		0xFF
206ede3d83SAshish Jangam 
216ede3d83SAshish Jangam enum {
226ede3d83SAshish Jangam 	DA9052_WLEDS_OFF,
236ede3d83SAshish Jangam 	DA9052_WLEDS_ON,
246ede3d83SAshish Jangam };
256ede3d83SAshish Jangam 
266ede3d83SAshish Jangam enum {
276ede3d83SAshish Jangam 	DA9052_TYPE_WLED1,
286ede3d83SAshish Jangam 	DA9052_TYPE_WLED2,
296ede3d83SAshish Jangam 	DA9052_TYPE_WLED3,
306ede3d83SAshish Jangam };
316ede3d83SAshish Jangam 
32b5d6904bSJingoo Han static const unsigned char wled_bank[] = {
336ede3d83SAshish Jangam 	DA9052_LED1_CONF_REG,
346ede3d83SAshish Jangam 	DA9052_LED2_CONF_REG,
356ede3d83SAshish Jangam 	DA9052_LED3_CONF_REG,
366ede3d83SAshish Jangam };
376ede3d83SAshish Jangam 
386ede3d83SAshish Jangam struct da9052_bl {
396ede3d83SAshish Jangam 	struct da9052 *da9052;
406ede3d83SAshish Jangam 	uint brightness;
416ede3d83SAshish Jangam 	uint state;
426ede3d83SAshish Jangam 	uint led_reg;
436ede3d83SAshish Jangam };
446ede3d83SAshish Jangam 
da9052_adjust_wled_brightness(struct da9052_bl * wleds)456ede3d83SAshish Jangam static int da9052_adjust_wled_brightness(struct da9052_bl *wleds)
466ede3d83SAshish Jangam {
476ede3d83SAshish Jangam 	unsigned char boost_en;
486ede3d83SAshish Jangam 	unsigned char i_sink;
496ede3d83SAshish Jangam 	int ret;
506ede3d83SAshish Jangam 
516ede3d83SAshish Jangam 	boost_en = 0x3F;
526ede3d83SAshish Jangam 	i_sink = 0xFF;
536ede3d83SAshish Jangam 	if (wleds->state == DA9052_WLEDS_OFF) {
546ede3d83SAshish Jangam 		boost_en = 0x00;
556ede3d83SAshish Jangam 		i_sink = 0x00;
566ede3d83SAshish Jangam 	}
576ede3d83SAshish Jangam 
586ede3d83SAshish Jangam 	ret = da9052_reg_write(wleds->da9052, DA9052_BOOST_REG, boost_en);
596ede3d83SAshish Jangam 	if (ret < 0)
606ede3d83SAshish Jangam 		return ret;
616ede3d83SAshish Jangam 
626ede3d83SAshish Jangam 	ret = da9052_reg_write(wleds->da9052, DA9052_LED_CONT_REG, i_sink);
636ede3d83SAshish Jangam 	if (ret < 0)
646ede3d83SAshish Jangam 		return ret;
656ede3d83SAshish Jangam 
666ede3d83SAshish Jangam 	ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg], 0x0);
676ede3d83SAshish Jangam 	if (ret < 0)
686ede3d83SAshish Jangam 		return ret;
696ede3d83SAshish Jangam 
705333e254SJingoo Han 	usleep_range(10000, 11000);
716ede3d83SAshish Jangam 
726ede3d83SAshish Jangam 	if (wleds->brightness) {
736ede3d83SAshish Jangam 		ret = da9052_reg_write(wleds->da9052, wled_bank[wleds->led_reg],
746ede3d83SAshish Jangam 				       wleds->brightness);
756ede3d83SAshish Jangam 		if (ret < 0)
766ede3d83SAshish Jangam 			return ret;
776ede3d83SAshish Jangam 	}
786ede3d83SAshish Jangam 
796ede3d83SAshish Jangam 	return 0;
806ede3d83SAshish Jangam }
816ede3d83SAshish Jangam 
da9052_backlight_update_status(struct backlight_device * bl)826ede3d83SAshish Jangam static int da9052_backlight_update_status(struct backlight_device *bl)
836ede3d83SAshish Jangam {
846ede3d83SAshish Jangam 	int brightness = bl->props.brightness;
856ede3d83SAshish Jangam 	struct da9052_bl *wleds = bl_get_data(bl);
866ede3d83SAshish Jangam 
876ede3d83SAshish Jangam 	wleds->brightness = brightness;
886ede3d83SAshish Jangam 	wleds->state = DA9052_WLEDS_ON;
896ede3d83SAshish Jangam 
906ede3d83SAshish Jangam 	return da9052_adjust_wled_brightness(wleds);
916ede3d83SAshish Jangam }
926ede3d83SAshish Jangam 
da9052_backlight_get_brightness(struct backlight_device * bl)936ede3d83SAshish Jangam static int da9052_backlight_get_brightness(struct backlight_device *bl)
946ede3d83SAshish Jangam {
956ede3d83SAshish Jangam 	struct da9052_bl *wleds = bl_get_data(bl);
966ede3d83SAshish Jangam 
976ede3d83SAshish Jangam 	return wleds->brightness;
986ede3d83SAshish Jangam }
996ede3d83SAshish Jangam 
1006ede3d83SAshish Jangam static const struct backlight_ops da9052_backlight_ops = {
1016ede3d83SAshish Jangam 	.update_status = da9052_backlight_update_status,
1026ede3d83SAshish Jangam 	.get_brightness = da9052_backlight_get_brightness,
1036ede3d83SAshish Jangam };
1046ede3d83SAshish Jangam 
da9052_backlight_probe(struct platform_device * pdev)1056ede3d83SAshish Jangam static int da9052_backlight_probe(struct platform_device *pdev)
1066ede3d83SAshish Jangam {
1076ede3d83SAshish Jangam 	struct backlight_device *bl;
1086ede3d83SAshish Jangam 	struct backlight_properties props;
1096ede3d83SAshish Jangam 	struct da9052_bl *wleds;
1106ede3d83SAshish Jangam 
1116ede3d83SAshish Jangam 	wleds = devm_kzalloc(&pdev->dev, sizeof(struct da9052_bl), GFP_KERNEL);
1126ede3d83SAshish Jangam 	if (!wleds)
1136ede3d83SAshish Jangam 		return -ENOMEM;
1146ede3d83SAshish Jangam 
1156ede3d83SAshish Jangam 	wleds->da9052 = dev_get_drvdata(pdev->dev.parent);
1166ede3d83SAshish Jangam 	wleds->brightness = 0;
1176ede3d83SAshish Jangam 	wleds->led_reg = platform_get_device_id(pdev)->driver_data;
1186ede3d83SAshish Jangam 	wleds->state = DA9052_WLEDS_OFF;
1196ede3d83SAshish Jangam 
120*6b97127dSDaniel Thompson 	memset(&props, 0, sizeof(struct backlight_properties));
1216ede3d83SAshish Jangam 	props.type = BACKLIGHT_RAW;
1226ede3d83SAshish Jangam 	props.max_brightness = DA9052_MAX_BRIGHTNESS;
1236ede3d83SAshish Jangam 
12402f0092cSJingoo Han 	bl = devm_backlight_device_register(&pdev->dev, pdev->name,
12502f0092cSJingoo Han 					wleds->da9052->dev, wleds,
1266ede3d83SAshish Jangam 					&da9052_backlight_ops, &props);
1276ede3d83SAshish Jangam 	if (IS_ERR(bl)) {
1286ede3d83SAshish Jangam 		dev_err(&pdev->dev, "Failed to register backlight\n");
1296ede3d83SAshish Jangam 		return PTR_ERR(bl);
1306ede3d83SAshish Jangam 	}
1316ede3d83SAshish Jangam 
1326ede3d83SAshish Jangam 	bl->props.max_brightness = DA9052_MAX_BRIGHTNESS;
1336ede3d83SAshish Jangam 	bl->props.brightness = 0;
1346ede3d83SAshish Jangam 	platform_set_drvdata(pdev, bl);
1356ede3d83SAshish Jangam 
1366ede3d83SAshish Jangam 	return da9052_adjust_wled_brightness(wleds);
1376ede3d83SAshish Jangam }
1386ede3d83SAshish Jangam 
da9052_backlight_remove(struct platform_device * pdev)13978a2bb48SUwe Kleine-König static void da9052_backlight_remove(struct platform_device *pdev)
1406ede3d83SAshish Jangam {
1416ede3d83SAshish Jangam 	struct backlight_device *bl = platform_get_drvdata(pdev);
1426ede3d83SAshish Jangam 	struct da9052_bl *wleds = bl_get_data(bl);
1436ede3d83SAshish Jangam 
1446ede3d83SAshish Jangam 	wleds->brightness = 0;
1456ede3d83SAshish Jangam 	wleds->state = DA9052_WLEDS_OFF;
1466ede3d83SAshish Jangam 	da9052_adjust_wled_brightness(wleds);
1476ede3d83SAshish Jangam }
1486ede3d83SAshish Jangam 
149dba5ff95SKrzysztof Kozlowski static const struct platform_device_id da9052_wled_ids[] = {
1506ede3d83SAshish Jangam 	{
1516ede3d83SAshish Jangam 		.name		= "da9052-wled1",
1526ede3d83SAshish Jangam 		.driver_data	= DA9052_TYPE_WLED1,
1536ede3d83SAshish Jangam 	},
1546ede3d83SAshish Jangam 	{
1556ede3d83SAshish Jangam 		.name		= "da9052-wled2",
1566ede3d83SAshish Jangam 		.driver_data	= DA9052_TYPE_WLED2,
1576ede3d83SAshish Jangam 	},
1586ede3d83SAshish Jangam 	{
1596ede3d83SAshish Jangam 		.name		= "da9052-wled3",
1606ede3d83SAshish Jangam 		.driver_data	= DA9052_TYPE_WLED3,
1616ede3d83SAshish Jangam 	},
162b1f85c0fSAndrey Ryabinin 	{ },
1636ede3d83SAshish Jangam };
164bb82250fSJavier Martinez Canillas MODULE_DEVICE_TABLE(platform, da9052_wled_ids);
1656ede3d83SAshish Jangam 
1666ede3d83SAshish Jangam static struct platform_driver da9052_wled_driver = {
1676ede3d83SAshish Jangam 	.probe		= da9052_backlight_probe,
16878a2bb48SUwe Kleine-König 	.remove_new	= da9052_backlight_remove,
1696ede3d83SAshish Jangam 	.id_table	= da9052_wled_ids,
1706ede3d83SAshish Jangam 	.driver	= {
1716ede3d83SAshish Jangam 		.name	= "da9052-wled",
1726ede3d83SAshish Jangam 	},
1736ede3d83SAshish Jangam };
1746ede3d83SAshish Jangam 
1756ede3d83SAshish Jangam module_platform_driver(da9052_wled_driver);
1766ede3d83SAshish Jangam 
1776ede3d83SAshish Jangam MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
1786ede3d83SAshish Jangam MODULE_DESCRIPTION("Backlight driver for DA9052 PMIC");
1796ede3d83SAshish Jangam MODULE_LICENSE("GPL");
180