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

lv5207lp.c (4026B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Sanyo LV5207LP LED Driver
      4 *
      5 * Copyright (C) 2013 Ideas on board SPRL
      6 *
      7 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
      8 */
      9
     10#include <linux/backlight.h>
     11#include <linux/err.h>
     12#include <linux/fb.h>
     13#include <linux/i2c.h>
     14#include <linux/module.h>
     15#include <linux/platform_data/lv5207lp.h>
     16#include <linux/slab.h>
     17
     18#define LV5207LP_CTRL1			0x00
     19#define LV5207LP_CPSW			(1 << 7)
     20#define LV5207LP_SCTEN			(1 << 6)
     21#define LV5207LP_C10			(1 << 5)
     22#define LV5207LP_CKSW			(1 << 4)
     23#define LV5207LP_RSW			(1 << 3)
     24#define LV5207LP_GSW			(1 << 2)
     25#define LV5207LP_BSW			(1 << 1)
     26#define LV5207LP_CTRL2			0x01
     27#define LV5207LP_MSW			(1 << 7)
     28#define LV5207LP_MLED4			(1 << 6)
     29#define LV5207LP_RED			0x02
     30#define LV5207LP_GREEN			0x03
     31#define LV5207LP_BLUE			0x04
     32
     33#define LV5207LP_MAX_BRIGHTNESS		32
     34
     35struct lv5207lp {
     36	struct i2c_client *client;
     37	struct backlight_device *backlight;
     38	struct lv5207lp_platform_data *pdata;
     39};
     40
     41static int lv5207lp_write(struct lv5207lp *lv, u8 reg, u8 data)
     42{
     43	return i2c_smbus_write_byte_data(lv->client, reg, data);
     44}
     45
     46static int lv5207lp_backlight_update_status(struct backlight_device *backlight)
     47{
     48	struct lv5207lp *lv = bl_get_data(backlight);
     49	int brightness = backlight_get_brightness(backlight);
     50
     51	if (brightness) {
     52		lv5207lp_write(lv, LV5207LP_CTRL1,
     53			       LV5207LP_CPSW | LV5207LP_C10 | LV5207LP_CKSW);
     54		lv5207lp_write(lv, LV5207LP_CTRL2,
     55			       LV5207LP_MSW | LV5207LP_MLED4 |
     56			       (brightness - 1));
     57	} else {
     58		lv5207lp_write(lv, LV5207LP_CTRL1, 0);
     59		lv5207lp_write(lv, LV5207LP_CTRL2, 0);
     60	}
     61
     62	return 0;
     63}
     64
     65static int lv5207lp_backlight_check_fb(struct backlight_device *backlight,
     66				       struct fb_info *info)
     67{
     68	struct lv5207lp *lv = bl_get_data(backlight);
     69
     70	return lv->pdata->fbdev == NULL || lv->pdata->fbdev == info->dev;
     71}
     72
     73static const struct backlight_ops lv5207lp_backlight_ops = {
     74	.options	= BL_CORE_SUSPENDRESUME,
     75	.update_status	= lv5207lp_backlight_update_status,
     76	.check_fb	= lv5207lp_backlight_check_fb,
     77};
     78
     79static int lv5207lp_probe(struct i2c_client *client,
     80			  const struct i2c_device_id *id)
     81{
     82	struct lv5207lp_platform_data *pdata = dev_get_platdata(&client->dev);
     83	struct backlight_device *backlight;
     84	struct backlight_properties props;
     85	struct lv5207lp *lv;
     86
     87	if (pdata == NULL) {
     88		dev_err(&client->dev, "No platform data supplied\n");
     89		return -EINVAL;
     90	}
     91
     92	if (!i2c_check_functionality(client->adapter,
     93				     I2C_FUNC_SMBUS_BYTE_DATA)) {
     94		dev_warn(&client->dev,
     95			 "I2C adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
     96		return -EIO;
     97	}
     98
     99	lv = devm_kzalloc(&client->dev, sizeof(*lv), GFP_KERNEL);
    100	if (!lv)
    101		return -ENOMEM;
    102
    103	lv->client = client;
    104	lv->pdata = pdata;
    105
    106	memset(&props, 0, sizeof(props));
    107	props.type = BACKLIGHT_RAW;
    108	props.max_brightness = min_t(unsigned int, pdata->max_value,
    109				     LV5207LP_MAX_BRIGHTNESS);
    110	props.brightness = clamp_t(unsigned int, pdata->def_value, 0,
    111				   props.max_brightness);
    112
    113	backlight = devm_backlight_device_register(&client->dev,
    114				dev_name(&client->dev), &lv->client->dev,
    115				lv, &lv5207lp_backlight_ops, &props);
    116	if (IS_ERR(backlight)) {
    117		dev_err(&client->dev, "failed to register backlight\n");
    118		return PTR_ERR(backlight);
    119	}
    120
    121	backlight_update_status(backlight);
    122	i2c_set_clientdata(client, backlight);
    123
    124	return 0;
    125}
    126
    127static int lv5207lp_remove(struct i2c_client *client)
    128{
    129	struct backlight_device *backlight = i2c_get_clientdata(client);
    130
    131	backlight->props.brightness = 0;
    132	backlight_update_status(backlight);
    133
    134	return 0;
    135}
    136
    137static const struct i2c_device_id lv5207lp_ids[] = {
    138	{ "lv5207lp", 0 },
    139	{ }
    140};
    141MODULE_DEVICE_TABLE(i2c, lv5207lp_ids);
    142
    143static struct i2c_driver lv5207lp_driver = {
    144	.driver = {
    145		.name = "lv5207lp",
    146	},
    147	.probe = lv5207lp_probe,
    148	.remove = lv5207lp_remove,
    149	.id_table = lv5207lp_ids,
    150};
    151
    152module_i2c_driver(lv5207lp_driver);
    153
    154MODULE_DESCRIPTION("Sanyo LV5207LP Backlight Driver");
    155MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
    156MODULE_LICENSE("GPL");