// SPDX-License-Identifier: GPL-2.0
/*
 * MAX6958/6959 7-segment LED display controller
 * Datasheet:
 * https://www.analog.com/media/en/technical-documentation/data-sheets/MAX6958-MAX6959.pdf
 *
 * Copyright (c) 2024, Intel Corporation.
 * Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 */
#include <linux/array_size.h>
#include <linux/bitrev.h>
#include <linux/bits.h>
#include <linux/container_of.h>
#include <linux/device/devres.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/regmap.h>
#include <linux/types.h>
#include <linux/workqueue.h>

#include <linux/map_to_7segment.h>

#include "line-display.h"

/* Registers */
#define REG_DECODE_MODE			0x01
#define REG_INTENSITY			0x02
#define REG_SCAN_LIMIT			0x03
#define REG_CONFIGURATION		0x04
#define REG_CONFIGURATION_S_BIT		BIT(0)

#define REG_DIGIT(x)			(0x20 + (x))
#define REG_DIGIT0			0x20
#define REG_DIGIT1			0x21
#define REG_DIGIT2			0x22
#define REG_DIGIT3			0x23

#define REG_SEGMENTS			0x24
#define REG_MAX				REG_SEGMENTS

struct max6959_priv {
	struct linedisp linedisp;
	struct delayed_work work;
	struct regmap *regmap;
};

static void max6959_disp_update(struct work_struct *work)
{
	struct max6959_priv *priv = container_of(work, struct max6959_priv, work.work);
	struct linedisp *linedisp = &priv->linedisp;
	struct linedisp_map *map = linedisp->map;
	char *s = linedisp->buf;
	u8 buf[4];

	/* Map segments according to datasheet */
	buf[0] = bitrev8(map_to_seg7(&map->map.seg7, *s++)) >> 1;
	buf[1] = bitrev8(map_to_seg7(&map->map.seg7, *s++)) >> 1;
	buf[2] = bitrev8(map_to_seg7(&map->map.seg7, *s++)) >> 1;
	buf[3] = bitrev8(map_to_seg7(&map->map.seg7, *s++)) >> 1;

	regmap_bulk_write(priv->regmap, REG_DIGIT(0), buf, ARRAY_SIZE(buf));
}

static int max6959_linedisp_get_map_type(struct linedisp *linedisp)
{
	struct max6959_priv *priv = container_of(linedisp, struct max6959_priv, linedisp);

	INIT_DELAYED_WORK(&priv->work, max6959_disp_update);
	return LINEDISP_MAP_SEG7;
}

static void max6959_linedisp_update(struct linedisp *linedisp)
{
	struct max6959_priv *priv = container_of(linedisp, struct max6959_priv, linedisp);

	schedule_delayed_work(&priv->work, 0);
}

static const struct linedisp_ops max6959_linedisp_ops = {
	.get_map_type = max6959_linedisp_get_map_type,
	.update = max6959_linedisp_update,
};

static int max6959_enable(struct max6959_priv *priv, bool enable)
{
	return regmap_assign_bits(priv->regmap, REG_CONFIGURATION, REG_CONFIGURATION_S_BIT, enable);
}

static void max6959_power_off(void *priv)
{
	max6959_enable(priv, false);
}

static int max6959_power_on(struct max6959_priv *priv)
{
	struct device *dev = regmap_get_device(priv->regmap);
	int ret;

	ret = max6959_enable(priv, true);
	if (ret)
		return ret;

	return devm_add_action_or_reset(dev, max6959_power_off, priv);
}

static const struct regmap_config max6959_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,

	.max_register = REG_MAX,
	.cache_type = REGCACHE_MAPLE,
};

static int max6959_i2c_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct max6959_priv *priv;
	int ret;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	priv->regmap = devm_regmap_init_i2c(client, &max6959_regmap_config);
	if (IS_ERR(priv->regmap))
		return PTR_ERR(priv->regmap);

	ret = max6959_power_on(priv);
	if (ret)
		return ret;

	ret = linedisp_register(&priv->linedisp, dev, 4, &max6959_linedisp_ops);
	if (ret)
		return ret;

	i2c_set_clientdata(client, priv);

	return 0;
}

static void max6959_i2c_remove(struct i2c_client *client)
{
	struct max6959_priv *priv = i2c_get_clientdata(client);

	cancel_delayed_work_sync(&priv->work);
	linedisp_unregister(&priv->linedisp);
}

static int max6959_suspend(struct device *dev)
{
	return max6959_enable(dev_get_drvdata(dev), false);
}

static int max6959_resume(struct device *dev)
{
	return max6959_enable(dev_get_drvdata(dev), true);
}

static DEFINE_SIMPLE_DEV_PM_OPS(max6959_pm_ops, max6959_suspend, max6959_resume);

static const struct i2c_device_id max6959_i2c_id[] = {
	{ "max6959" },
	{ }
};
MODULE_DEVICE_TABLE(i2c, max6959_i2c_id);

static const struct of_device_id max6959_of_table[] = {
	{ .compatible = "maxim,max6959" },
	{ }
};
MODULE_DEVICE_TABLE(of, max6959_of_table);

static struct i2c_driver max6959_i2c_driver = {
	.driver = {
		.name = "max6959",
		.pm = pm_sleep_ptr(&max6959_pm_ops),
		.of_match_table = max6959_of_table,
	},
	.probe = max6959_i2c_probe,
	.remove = max6959_i2c_remove,
	.id_table = max6959_i2c_id,
};
module_i2c_driver(max6959_i2c_driver);

MODULE_DESCRIPTION("MAX6958/6959 7-segment LED controller");
MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("LINEDISP");
