brintos

brintos / linux-shallow public Read only

0
0
Text · 4.8 KiB · 68d327e Raw
207 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * linux/drivers/video/backlight/aat2870_bl.c4 *5 * Copyright (c) 2011, NVIDIA Corporation.6 * Author: Jin Park <jinyoungp@nvidia.com>7 */8 9#include <linux/module.h>10#include <linux/kernel.h>11#include <linux/init.h>12#include <linux/platform_device.h>13#include <linux/mutex.h>14#include <linux/delay.h>15#include <linux/backlight.h>16#include <linux/mfd/aat2870.h>17 18struct aat2870_bl_driver_data {19	struct platform_device *pdev;20	struct backlight_device *bd;21 22	int channels;23	int max_current;24	int brightness; /* current brightness */25};26 27static inline int aat2870_brightness(struct aat2870_bl_driver_data *aat2870_bl,28				     int brightness)29{30	struct backlight_device *bd = aat2870_bl->bd;31	int val;32 33	val = brightness * (aat2870_bl->max_current - 1);34	val /= bd->props.max_brightness;35 36	return val;37}38 39static inline int aat2870_bl_enable(struct aat2870_bl_driver_data *aat2870_bl)40{41	struct aat2870_data *aat287042			= dev_get_drvdata(aat2870_bl->pdev->dev.parent);43 44	return aat2870->write(aat2870, AAT2870_BL_CH_EN,45			      (u8)aat2870_bl->channels);46}47 48static inline int aat2870_bl_disable(struct aat2870_bl_driver_data *aat2870_bl)49{50	struct aat2870_data *aat287051			= dev_get_drvdata(aat2870_bl->pdev->dev.parent);52 53	return aat2870->write(aat2870, AAT2870_BL_CH_EN, 0x0);54}55 56static int aat2870_bl_update_status(struct backlight_device *bd)57{58	struct aat2870_bl_driver_data *aat2870_bl = bl_get_data(bd);59	struct aat2870_data *aat2870 =60			dev_get_drvdata(aat2870_bl->pdev->dev.parent);61	int brightness = backlight_get_brightness(bd);62	int ret;63 64	if ((brightness < 0) || (bd->props.max_brightness < brightness)) {65		dev_err(&bd->dev, "invalid brightness, %d\n", brightness);66		return -EINVAL;67	}68 69	dev_dbg(&bd->dev, "brightness=%d, power=%d, state=%d\n",70		 bd->props.brightness, bd->props.power, bd->props.state);71 72	ret = aat2870->write(aat2870, AAT2870_BLM,73			     (u8)aat2870_brightness(aat2870_bl, brightness));74	if (ret < 0)75		return ret;76 77	if (brightness == 0) {78		ret = aat2870_bl_disable(aat2870_bl);79		if (ret < 0)80			return ret;81	} else if (aat2870_bl->brightness == 0) {82		ret = aat2870_bl_enable(aat2870_bl);83		if (ret < 0)84			return ret;85	}86 87	aat2870_bl->brightness = brightness;88 89	return 0;90}91 92static const struct backlight_ops aat2870_bl_ops = {93	.options = BL_CORE_SUSPENDRESUME,94	.update_status = aat2870_bl_update_status,95};96 97static int aat2870_bl_probe(struct platform_device *pdev)98{99	struct aat2870_bl_platform_data *pdata = dev_get_platdata(&pdev->dev);100	struct aat2870_bl_driver_data *aat2870_bl;101	struct backlight_device *bd;102	struct backlight_properties props;103	int ret = 0;104 105	if (!pdata) {106		dev_err(&pdev->dev, "No platform data\n");107		ret = -ENXIO;108		goto out;109	}110 111	if (pdev->id != AAT2870_ID_BL) {112		dev_err(&pdev->dev, "Invalid device ID, %d\n", pdev->id);113		ret = -EINVAL;114		goto out;115	}116 117	aat2870_bl = devm_kzalloc(&pdev->dev,118				  sizeof(struct aat2870_bl_driver_data),119				  GFP_KERNEL);120	if (!aat2870_bl) {121		ret = -ENOMEM;122		goto out;123	}124 125	memset(&props, 0, sizeof(struct backlight_properties));126 127	props.type = BACKLIGHT_RAW;128	bd = devm_backlight_device_register(&pdev->dev, "aat2870-backlight",129					&pdev->dev, aat2870_bl, &aat2870_bl_ops,130					&props);131	if (IS_ERR(bd)) {132		dev_err(&pdev->dev,133			"Failed allocate memory for backlight device\n");134		ret = PTR_ERR(bd);135		goto out;136	}137 138	aat2870_bl->pdev = pdev;139	platform_set_drvdata(pdev, aat2870_bl);140 141	aat2870_bl->bd = bd;142 143	if (pdata->channels > 0)144		aat2870_bl->channels = pdata->channels;145	else146		aat2870_bl->channels = AAT2870_BL_CH_ALL;147 148	if (pdata->max_current > 0)149		aat2870_bl->max_current = pdata->max_current;150	else151		aat2870_bl->max_current = AAT2870_CURRENT_27_9;152 153	if (pdata->max_brightness > 0)154		bd->props.max_brightness = pdata->max_brightness;155	else156		bd->props.max_brightness = 255;157 158	aat2870_bl->brightness = 0;159	bd->props.power = BACKLIGHT_POWER_ON;160	bd->props.brightness = bd->props.max_brightness;161 162	ret = aat2870_bl_update_status(bd);163	if (ret < 0) {164		dev_err(&pdev->dev, "Failed to initialize\n");165		return ret;166	}167 168	return 0;169 170out:171	return ret;172}173 174static void aat2870_bl_remove(struct platform_device *pdev)175{176	struct aat2870_bl_driver_data *aat2870_bl = platform_get_drvdata(pdev);177	struct backlight_device *bd = aat2870_bl->bd;178 179	bd->props.power = BACKLIGHT_POWER_OFF;180	bd->props.brightness = 0;181	backlight_update_status(bd);182}183 184static struct platform_driver aat2870_bl_driver = {185	.driver = {186		.name	= "aat2870-backlight",187	},188	.probe		= aat2870_bl_probe,189	.remove_new	= aat2870_bl_remove,190};191 192static int __init aat2870_bl_init(void)193{194	return platform_driver_register(&aat2870_bl_driver);195}196subsys_initcall(aat2870_bl_init);197 198static void __exit aat2870_bl_exit(void)199{200	platform_driver_unregister(&aat2870_bl_driver);201}202module_exit(aat2870_bl_exit);203 204MODULE_DESCRIPTION("AnalogicTech AAT2870 Backlight");205MODULE_LICENSE("GPL");206MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>");207