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

da903x_bl.c (4079B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Backlight driver for Dialog Semiconductor DA9030/DA9034
      4 *
      5 * Copyright (C) 2008 Compulab, Ltd.
      6 *	Mike Rapoport <mike@compulab.co.il>
      7 *
      8 * Copyright (C) 2006-2008 Marvell International Ltd.
      9 *	Eric Miao <eric.miao@marvell.com>
     10 */
     11
     12#include <linux/kernel.h>
     13#include <linux/init.h>
     14#include <linux/platform_device.h>
     15#include <linux/fb.h>
     16#include <linux/backlight.h>
     17#include <linux/mfd/da903x.h>
     18#include <linux/slab.h>
     19#include <linux/module.h>
     20
     21#define DA9030_WLED_CONTROL	0x25
     22#define DA9030_WLED_CP_EN	(1 << 6)
     23#define DA9030_WLED_TRIM(x)	((x) & 0x7)
     24
     25#define DA9034_WLED_CONTROL1	0x3C
     26#define DA9034_WLED_CONTROL2	0x3D
     27#define DA9034_WLED_ISET(x)	((x) & 0x1f)
     28
     29#define DA9034_WLED_BOOST_EN	(1 << 5)
     30
     31#define DA9030_MAX_BRIGHTNESS	7
     32#define DA9034_MAX_BRIGHTNESS	0x7f
     33
     34struct da903x_backlight_data {
     35	struct device *da903x_dev;
     36	int id;
     37	int current_brightness;
     38};
     39
     40static 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
     78static int da903x_backlight_update_status(struct backlight_device *bl)
     79{
     80	return da903x_backlight_set(bl, backlight_get_brightness(bl));
     81}
     82
     83static int da903x_backlight_get_brightness(struct backlight_device *bl)
     84{
     85	struct da903x_backlight_data *data = bl_get_data(bl);
     86
     87	return data->current_brightness;
     88}
     89
     90static const struct backlight_ops da903x_backlight_ops = {
     91	.options	= BL_CORE_SUSPENDRESUME,
     92	.update_status	= da903x_backlight_update_status,
     93	.get_brightness	= da903x_backlight_get_brightness,
     94};
     95
     96static int da903x_backlight_probe(struct platform_device *pdev)
     97{
     98	struct da9034_backlight_pdata *pdata = dev_get_platdata(&pdev->dev);
     99	struct da903x_backlight_data *data;
    100	struct backlight_device *bl;
    101	struct backlight_properties props;
    102	int max_brightness;
    103
    104	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
    105	if (data == NULL)
    106		return -ENOMEM;
    107
    108	switch (pdev->id) {
    109	case DA9030_ID_WLED:
    110		max_brightness = DA9030_MAX_BRIGHTNESS;
    111		break;
    112	case DA9034_ID_WLED:
    113		max_brightness = DA9034_MAX_BRIGHTNESS;
    114		break;
    115	default:
    116		dev_err(&pdev->dev, "invalid backlight device ID(%d)\n",
    117				pdev->id);
    118		return -EINVAL;
    119	}
    120
    121	data->id = pdev->id;
    122	data->da903x_dev = pdev->dev.parent;
    123	data->current_brightness = 0;
    124
    125	/* adjust the WLED output current */
    126	if (pdata)
    127		da903x_write(data->da903x_dev, DA9034_WLED_CONTROL2,
    128				DA9034_WLED_ISET(pdata->output_current));
    129
    130	memset(&props, 0, sizeof(props));
    131	props.type = BACKLIGHT_RAW;
    132	props.max_brightness = max_brightness;
    133	bl = devm_backlight_device_register(&pdev->dev, pdev->name,
    134					data->da903x_dev, data,
    135					&da903x_backlight_ops, &props);
    136	if (IS_ERR(bl)) {
    137		dev_err(&pdev->dev, "failed to register backlight\n");
    138		return PTR_ERR(bl);
    139	}
    140
    141	bl->props.brightness = max_brightness;
    142
    143	platform_set_drvdata(pdev, bl);
    144	backlight_update_status(bl);
    145	return 0;
    146}
    147
    148static struct platform_driver da903x_backlight_driver = {
    149	.driver		= {
    150		.name	= "da903x-backlight",
    151	},
    152	.probe		= da903x_backlight_probe,
    153};
    154
    155module_platform_driver(da903x_backlight_driver);
    156
    157MODULE_DESCRIPTION("Backlight Driver for Dialog Semiconductor DA9030/DA9034");
    158MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
    159MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
    160MODULE_LICENSE("GPL");
    161MODULE_ALIAS("platform:da903x-backlight");