// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2016 Imagination Technologies
 * Author: Paul Burton <paul.burton@mips.com>
 */

#include <generated/utsrelease.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/sysfs.h>

struct img_ascii_lcd_ctx;

/**
 * struct img_ascii_lcd_config - Configuration information about an LCD model
 * @num_chars: the number of characters the LCD can display
 * @external_regmap: true if registers are in a system controller, else false
 * @update: function called to update the LCD
 */
struct img_ascii_lcd_config {
	unsigned int num_chars;
	bool external_regmap;
	void (*update)(struct img_ascii_lcd_ctx *ctx);
};

/**
 * struct img_ascii_lcd_ctx - Private data structure
 * @pdev: the ASCII LCD platform device
 * @base: the base address of the LCD registers
 * @regmap: the regmap through which LCD registers are accessed
 * @offset: the offset within regmap to the start of the LCD registers
 * @cfg: pointer to the LCD model configuration
 * @message: the full message to display or scroll on the LCD
 * @message_len: the length of the @message string
 * @scroll_pos: index of the first character of @message currently displayed
 * @scroll_rate: scroll interval in jiffies
 * @timer: timer used to implement scrolling
 * @curr: the string currently displayed on the LCD
 */
struct img_ascii_lcd_ctx {
	struct platform_device *pdev;
	union {
		void __iomem *base;
		struct regmap *regmap;
	};
	u32 offset;
	const struct img_ascii_lcd_config *cfg;
	char *message;
	unsigned int message_len;
	unsigned int scroll_pos;
	unsigned int scroll_rate;
	struct timer_list timer;
	char curr[] __aligned(8);
};

/*
 * MIPS Boston development board
 */

static void boston_update(struct img_ascii_lcd_ctx *ctx)
{
	ulong val;

#if BITS_PER_LONG == 64
	val = *((u64 *)&ctx->curr[0]);
	__raw_writeq(val, ctx->base);
#elif BITS_PER_LONG == 32
	val = *((u32 *)&ctx->curr[0]);
	__raw_writel(val, ctx->base);
	val = *((u32 *)&ctx->curr[4]);
	__raw_writel(val, ctx->base + 4);
#else
# error Not 32 or 64 bit
#endif
}

static struct img_ascii_lcd_config boston_config = {
	.num_chars = 8,
	.update = boston_update,
};

/*
 * MIPS Malta development board
 */

static void malta_update(struct img_ascii_lcd_ctx *ctx)
{
	unsigned int i;
	int err = 0;

	for (i = 0; i < ctx->cfg->num_chars; i++) {
		err = regmap_write(ctx->regmap,
				   ctx->offset + (i * 8), ctx->curr[i]);
		if (err)
			break;
	}

	if (unlikely(err))
		pr_err_ratelimited("Failed to update LCD display: %d\n", err);
}

static struct img_ascii_lcd_config malta_config = {
	.num_chars = 8,
	.external_regmap = true,
	.update = malta_update,
};

/*
 * MIPS SEAD3 development board
 */

enum {
	SEAD3_REG_LCD_CTRL		= 0x00,
#define SEAD3_REG_LCD_CTRL_SETDRAM	BIT(7)
	SEAD3_REG_LCD_DATA		= 0x08,
	SEAD3_REG_CPLD_STATUS		= 0x10,
#define SEAD3_REG_CPLD_STATUS_BUSY	BIT(0)
	SEAD3_REG_CPLD_DATA		= 0x18,
#define SEAD3_REG_CPLD_DATA_BUSY	BIT(7)
};

static int sead3_wait_sm_idle(struct img_ascii_lcd_ctx *ctx)
{
	unsigned int status;
	int err;

	do {
		err = regmap_read(ctx->regmap,
				  ctx->offset + SEAD3_REG_CPLD_STATUS,
				  &status);
		if (err)
			return err;
	} while (status & SEAD3_REG_CPLD_STATUS_BUSY);

	return 0;

}

static int sead3_wait_lcd_idle(struct img_ascii_lcd_ctx *ctx)
{
	unsigned int cpld_data;
	int err;

	err = sead3_wait_sm_idle(ctx);
	if (err)
		return err;

	do {
		err = regmap_read(ctx->regmap,
				  ctx->offset + SEAD3_REG_LCD_CTRL,
				  &cpld_data);
		if (err)
			return err;

		err = sead3_wait_sm_idle(ctx);
		if (err)
			return err;

		err = regmap_read(ctx->regmap,
				  ctx->offset + SEAD3_REG_CPLD_DATA,
				  &cpld_data);
		if (err)
			return err;
	} while (cpld_data & SEAD3_REG_CPLD_DATA_BUSY);

	return 0;
}

static void sead3_update(struct img_ascii_lcd_ctx *ctx)
{
	unsigned int i;
	int err = 0;

	for (i = 0; i < ctx->cfg->num_chars; i++) {
		err = sead3_wait_lcd_idle(ctx);
		if (err)
			break;

		err = regmap_write(ctx->regmap,
				   ctx->offset + SEAD3_REG_LCD_CTRL,
				   SEAD3_REG_LCD_CTRL_SETDRAM | i);
		if (err)
			break;

		err = sead3_wait_lcd_idle(ctx);
		if (err)
			break;

		err = regmap_write(ctx->regmap,
				   ctx->offset + SEAD3_REG_LCD_DATA,
				   ctx->curr[i]);
		if (err)
			break;
	}

	if (unlikely(err))
		pr_err_ratelimited("Failed to update LCD display: %d\n", err);
}

static struct img_ascii_lcd_config sead3_config = {
	.num_chars = 16,
	.external_regmap = true,
	.update = sead3_update,
};

static const struct of_device_id img_ascii_lcd_matches[] = {
	{ .compatible = "img,boston-lcd", .data = &boston_config },
	{ .compatible = "mti,malta-lcd", .data = &malta_config },
	{ .compatible = "mti,sead3-lcd", .data = &sead3_config },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, img_ascii_lcd_matches);

/**
 * img_ascii_lcd_scroll() - scroll the display by a character
 * @t: really a pointer to the private data structure
 *
 * Scroll the current message along the LCD by one character, rearming the
 * timer if required.
 */
static void img_ascii_lcd_scroll(struct timer_list *t)
{
	struct img_ascii_lcd_ctx *ctx = from_timer(ctx, t, timer);
	unsigned int i, ch = ctx->scroll_pos;
	unsigned int num_chars = ctx->cfg->num_chars;

	/* update the current message string */
	for (i = 0; i < num_chars;) {
		/* copy as many characters from the string as possible */
		for (; i < num_chars && ch < ctx->message_len; i++, ch++)
			ctx->curr[i] = ctx->message[ch];

		/* wrap around to the start of the string */
		ch = 0;
	}

	/* update the LCD */
	ctx->cfg->update(ctx);

	/* move on to the next character */
	ctx->scroll_pos++;
	ctx->scroll_pos %= ctx->message_len;

	/* rearm the timer */
	if (ctx->message_len > ctx->cfg->num_chars)
		mod_timer(&ctx->timer, jiffies + ctx->scroll_rate);
}

/**
 * img_ascii_lcd_display() - set the message to be displayed
 * @ctx: pointer to the private data structure
 * @msg: the message to display
 * @count: length of msg, or -1
 *
 * Display a new message @msg on the LCD. @msg can be longer than the number of
 * characters the LCD can display, in which case it will begin scrolling across
 * the LCD display.
 *
 * Return: 0 on success, -ENOMEM on memory allocation failure
 */
static int img_ascii_lcd_display(struct img_ascii_lcd_ctx *ctx,
			     const char *msg, ssize_t count)
{
	char *new_msg;

	/* stop the scroll timer */
	del_timer_sync(&ctx->timer);

	if (count == -1)
		count = strlen(msg);

	/* if the string ends with a newline, trim it */
	if (msg[count - 1] == '\n')
		count--;

	if (!count) {
		/* clear the LCD */
		devm_kfree(&ctx->pdev->dev, ctx->message);
		ctx->message = NULL;
		ctx->message_len = 0;
		memset(ctx->curr, ' ', ctx->cfg->num_chars);
		ctx->cfg->update(ctx);
		return 0;
	}

	new_msg = devm_kmalloc(&ctx->pdev->dev, count + 1, GFP_KERNEL);
	if (!new_msg)
		return -ENOMEM;

	memcpy(new_msg, msg, count);
	new_msg[count] = 0;

	if (ctx->message)
		devm_kfree(&ctx->pdev->dev, ctx->message);

	ctx->message = new_msg;
	ctx->message_len = count;
	ctx->scroll_pos = 0;

	/* update the LCD */
	img_ascii_lcd_scroll(&ctx->timer);

	return 0;
}

/**
 * message_show() - read message via sysfs
 * @dev: the LCD device
 * @attr: the LCD message attribute
 * @buf: the buffer to read the message into
 *
 * Read the current message being displayed or scrolled across the LCD display
 * into @buf, for reads from sysfs.
 *
 * Return: the number of characters written to @buf
 */
static ssize_t message_show(struct device *dev, struct device_attribute *attr,
			    char *buf)
{
	struct img_ascii_lcd_ctx *ctx = dev_get_drvdata(dev);

	return sprintf(buf, "%s\n", ctx->message);
}

/**
 * message_store() - write a new message via sysfs
 * @dev: the LCD device
 * @attr: the LCD message attribute
 * @buf: the buffer containing the new message
 * @count: the size of the message in @buf
 *
 * Write a new message to display or scroll across the LCD display from sysfs.
 *
 * Return: the size of the message on success, else -ERRNO
 */
static ssize_t message_store(struct device *dev, struct device_attribute *attr,
			     const char *buf, size_t count)
{
	struct img_ascii_lcd_ctx *ctx = dev_get_drvdata(dev);
	int err;

	err = img_ascii_lcd_display(ctx, buf, count);
	return err ?: count;
}

static DEVICE_ATTR_RW(message);

/**
 * img_ascii_lcd_probe() - probe an LCD display device
 * @pdev: the LCD platform device
 *
 * Probe an LCD display device, ensuring that we have the required resources in
 * order to access the LCD & setting up private data as well as sysfs files.
 *
 * Return: 0 on success, else -ERRNO
 */
static int img_ascii_lcd_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	const struct img_ascii_lcd_config *cfg;
	struct img_ascii_lcd_ctx *ctx;
	struct resource *res;
	int err;

	match = of_match_device(img_ascii_lcd_matches, &pdev->dev);
	if (!match)
		return -ENODEV;

	cfg = match->data;
	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx) + cfg->num_chars,
			   GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	if (cfg->external_regmap) {
		ctx->regmap = syscon_node_to_regmap(pdev->dev.parent->of_node);
		if (IS_ERR(ctx->regmap))
			return PTR_ERR(ctx->regmap);

		if (of_property_read_u32(pdev->dev.of_node, "offset",
					 &ctx->offset))
			return -EINVAL;
	} else {
		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
		ctx->base = devm_ioremap_resource(&pdev->dev, res);
		if (IS_ERR(ctx->base))
			return PTR_ERR(ctx->base);
	}

	ctx->pdev = pdev;
	ctx->cfg = cfg;
	ctx->message = NULL;
	ctx->scroll_pos = 0;
	ctx->scroll_rate = HZ / 2;

	/* initialise a timer for scrolling the message */
	timer_setup(&ctx->timer, img_ascii_lcd_scroll, 0);

	platform_set_drvdata(pdev, ctx);

	/* display a default message */
	err = img_ascii_lcd_display(ctx, "Linux " UTS_RELEASE "       ", -1);
	if (err)
		goto out_del_timer;

	err = device_create_file(&pdev->dev, &dev_attr_message);
	if (err)
		goto out_del_timer;

	return 0;
out_del_timer:
	del_timer_sync(&ctx->timer);
	return err;
}

/**
 * img_ascii_lcd_remove() - remove an LCD display device
 * @pdev: the LCD platform device
 *
 * Remove an LCD display device, freeing private resources & ensuring that the
 * driver stops using the LCD display registers.
 *
 * Return: 0
 */
static int img_ascii_lcd_remove(struct platform_device *pdev)
{
	struct img_ascii_lcd_ctx *ctx = platform_get_drvdata(pdev);

	device_remove_file(&pdev->dev, &dev_attr_message);
	del_timer_sync(&ctx->timer);
	return 0;
}

static struct platform_driver img_ascii_lcd_driver = {
	.driver = {
		.name		= "img-ascii-lcd",
		.of_match_table	= img_ascii_lcd_matches,
	},
	.probe	= img_ascii_lcd_probe,
	.remove	= img_ascii_lcd_remove,
};
module_platform_driver(img_ascii_lcd_driver);

MODULE_DESCRIPTION("Imagination Technologies ASCII LCD Display");
MODULE_AUTHOR("Paul Burton <paul.burton@mips.com>");
MODULE_LICENSE("GPL");
