// 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
 * @cfg: pointer to the LCD model configuration
 */
struct img_ascii_lcd_ctx {
	struct linedisp linedisp;
	union {
		void __iomem *base;
		struct regmap *regmap;
	};
	u32 offset;
	const struct img_ascii_lcd_config *cfg;
};

/*
 * 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 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 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 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_new = 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);
