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

#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include "line-display.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
 * @ops: character line display operations
 */
struct img_ascii_lcd_config {
	unsigned int num_chars;
	bool external_regmap;
	const struct linedisp_ops ops;
};

/**
 * struct img_ascii_lcd_ctx - Private data structure
 * @linedisp: line display structure
 * @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
 */
struct img_ascii_lcd_ctx {
	struct linedisp linedisp;
	union {
		void __iomem *base;
		struct regmap *regmap;
	};
	u32 offset;
};

/*
 * MIPS Boston development board
 */

static void boston_update(struct linedisp *linedisp)
{
	struct img_ascii_lcd_ctx *ctx =
		container_of(linedisp, struct img_ascii_lcd_ctx, linedisp);
	ulong val;

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

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

/*
 * MIPS Malta development board
 */

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

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

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

static const struct img_ascii_lcd_config malta_config = {
	.num_chars = 8,
	.external_regmap = true,
	.ops = {
		.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 linedisp *linedisp)
{
	struct img_ascii_lcd_ctx *ctx =
		container_of(linedisp, struct img_ascii_lcd_ctx, linedisp);
	unsigned int i;
	int err = 0;

	for (i = 0; i < linedisp->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,
				   linedisp->buf[i]);
		if (err)
			break;
	}

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

static const struct img_ascii_lcd_config sead3_config = {
	.num_chars = 16,
	.external_regmap = true,
	.ops = {
		.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_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)
{
	struct device *dev = &pdev->dev;
	const struct img_ascii_lcd_config *cfg = device_get_match_data(dev);
	struct img_ascii_lcd_ctx *ctx;
	int err;

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

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

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

	err = linedisp_register(&ctx->linedisp, dev, cfg->num_chars, &cfg->ops);
	if (err)
		return err;

	/* for backwards compatibility */
	err = compat_only_sysfs_link_entry_to_kobj(&dev->kobj,
						   &ctx->linedisp.dev.kobj,
						   "message", NULL);
	if (err)
		goto err_unregister;

	platform_set_drvdata(pdev, ctx);
	return 0;

err_unregister:
	linedisp_unregister(&ctx->linedisp);
	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.
 */
static void img_ascii_lcd_remove(struct platform_device *pdev)
{
	struct img_ascii_lcd_ctx *ctx = platform_get_drvdata(pdev);

	sysfs_remove_link(&pdev->dev.kobj, "message");
	linedisp_unregister(&ctx->linedisp);
}

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");
MODULE_IMPORT_NS("LINEDISP");
