// SPDX-License-Identifier: GPL-2.0-only
/*
 * ROHM Semiconductor BD6107 LED Driver
 *
 * Copyright (C) 2013 Ideas on board SPRL
 *
 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
 */

#include <linux/backlight.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/fb.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/platform_data/bd6107.h>
#include <linux/slab.h>

#define BD6107_PSCNT1				0x00
#define BD6107_PSCNT1_PSCNTREG2			(1 << 2)
#define BD6107_PSCNT1_PSCNTREG1			(1 << 0)
#define BD6107_REGVSET				0x02
#define BD6107_REGVSET_REG1VSET_2_85V		(1 << 2)
#define BD6107_REGVSET_REG1VSET_2_80V		(0 << 2)
#define BD6107_LEDCNT1				0x03
#define BD6107_LEDCNT1_LEDONOFF2		(1 << 1)
#define BD6107_LEDCNT1_LEDONOFF1		(1 << 0)
#define BD6107_PORTSEL				0x04
#define BD6107_PORTSEL_LEDM(n)			(1 << (n))
#define BD6107_RGB1CNT1				0x05
#define BD6107_RGB1CNT2				0x06
#define BD6107_RGB1CNT3				0x07
#define BD6107_RGB1CNT4				0x08
#define BD6107_RGB1CNT5				0x09
#define BD6107_RGB1FLM				0x0a
#define BD6107_RGB2CNT1				0x0b
#define BD6107_RGB2CNT2				0x0c
#define BD6107_RGB2CNT3				0x0d
#define BD6107_RGB2CNT4				0x0e
#define BD6107_RGB2CNT5				0x0f
#define BD6107_RGB2FLM				0x10
#define BD6107_PSCONT3				0x11
#define BD6107_SMMONCNT				0x12
#define BD6107_DCDCCNT				0x13
#define BD6107_IOSEL				0x14
#define BD6107_OUT1				0x15
#define BD6107_OUT2				0x16
#define BD6107_MASK1				0x17
#define BD6107_MASK2				0x18
#define BD6107_FACTOR1				0x19
#define BD6107_FACTOR2				0x1a
#define BD6107_CLRFACT1				0x1b
#define BD6107_CLRFACT2				0x1c
#define BD6107_STATE1				0x1d
#define BD6107_LSIVER				0x1e
#define BD6107_GRPSEL				0x1f
#define BD6107_LEDCNT2				0x20
#define BD6107_LEDCNT3				0x21
#define BD6107_MCURRENT				0x22
#define BD6107_MAINCNT1				0x23
#define BD6107_MAINCNT2				0x24
#define BD6107_SLOPECNT				0x25
#define BD6107_MSLOPE				0x26
#define BD6107_RGBSLOPE				0x27
#define BD6107_TEST				0x29
#define BD6107_SFTRST				0x2a
#define BD6107_SFTRSTGD				0x2b

struct bd6107 {
	struct i2c_client *client;
	struct backlight_device *backlight;
	struct bd6107_platform_data *pdata;
	struct gpio_desc *reset;
};

static int bd6107_write(struct bd6107 *bd, u8 reg, u8 data)
{
	return i2c_smbus_write_byte_data(bd->client, reg, data);
}

static int bd6107_backlight_update_status(struct backlight_device *backlight)
{
	struct bd6107 *bd = bl_get_data(backlight);
	int brightness = backlight->props.brightness;

	if (backlight->props.power != FB_BLANK_UNBLANK ||
	    backlight->props.fb_blank != FB_BLANK_UNBLANK ||
	    backlight->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))
		brightness = 0;

	if (brightness) {
		bd6107_write(bd, BD6107_PORTSEL, BD6107_PORTSEL_LEDM(2) |
			     BD6107_PORTSEL_LEDM(1) | BD6107_PORTSEL_LEDM(0));
		bd6107_write(bd, BD6107_MAINCNT1, brightness);
		bd6107_write(bd, BD6107_LEDCNT1, BD6107_LEDCNT1_LEDONOFF1);
	} else {
		/* Assert the reset line (gpiolib will handle active low) */
		gpiod_set_value(bd->reset, 1);
		msleep(24);
		gpiod_set_value(bd->reset, 0);
	}

	return 0;
}

static int bd6107_backlight_check_fb(struct backlight_device *backlight,
				       struct fb_info *info)
{
	struct bd6107 *bd = bl_get_data(backlight);

	return bd->pdata->fbdev == NULL || bd->pdata->fbdev == info->dev;
}

static const struct backlight_ops bd6107_backlight_ops = {
	.options	= BL_CORE_SUSPENDRESUME,
	.update_status	= bd6107_backlight_update_status,
	.check_fb	= bd6107_backlight_check_fb,
};

static int bd6107_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	struct bd6107_platform_data *pdata = dev_get_platdata(&client->dev);
	struct backlight_device *backlight;
	struct backlight_properties props;
	struct bd6107 *bd;
	int ret;

	if (pdata == NULL) {
		dev_err(&client->dev, "No platform data\n");
		return -EINVAL;
	}

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_SMBUS_BYTE_DATA)) {
		dev_warn(&client->dev,
			 "I2C adapter doesn't support I2C_FUNC_SMBUS_BYTE\n");
		return -EIO;
	}

	bd = devm_kzalloc(&client->dev, sizeof(*bd), GFP_KERNEL);
	if (!bd)
		return -ENOMEM;

	bd->client = client;
	bd->pdata = pdata;

	/*
	 * Request the reset GPIO line with GPIOD_OUT_HIGH meaning asserted,
	 * so in the machine descriptor table (or other hardware description),
	 * the line should be flagged as active low so this will assert
	 * the reset.
	 */
	bd->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
	if (IS_ERR(bd->reset)) {
		dev_err(&client->dev, "unable to request reset GPIO\n");
		ret = PTR_ERR(bd->reset);
		return ret;
	}

	memset(&props, 0, sizeof(props));
	props.type = BACKLIGHT_RAW;
	props.max_brightness = 128;
	props.brightness = clamp_t(unsigned int, pdata->def_value, 0,
				   props.max_brightness);

	backlight = devm_backlight_device_register(&client->dev,
					      dev_name(&client->dev),
					      &bd->client->dev, bd,
					      &bd6107_backlight_ops, &props);
	if (IS_ERR(backlight)) {
		dev_err(&client->dev, "failed to register backlight\n");
		return PTR_ERR(backlight);
	}

	backlight_update_status(backlight);
	i2c_set_clientdata(client, backlight);

	return 0;
}

static int bd6107_remove(struct i2c_client *client)
{
	struct backlight_device *backlight = i2c_get_clientdata(client);

	backlight->props.brightness = 0;
	backlight_update_status(backlight);

	return 0;
}

static const struct i2c_device_id bd6107_ids[] = {
	{ "bd6107", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, bd6107_ids);

static struct i2c_driver bd6107_driver = {
	.driver = {
		.name = "bd6107",
	},
	.probe = bd6107_probe,
	.remove = bd6107_remove,
	.id_table = bd6107_ids,
};

module_i2c_driver(bd6107_driver);

MODULE_DESCRIPTION("Rohm BD6107 Backlight Driver");
MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
MODULE_LICENSE("GPL");
