cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

aat2870_bl.c (5246B)


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