// SPDX-License-Identifier: GPL-2.0-only
/*
 * NXP LPC18xx/43xx OTP memory NVMEM driver
 *
 * Copyright (c) 2016 Joachim Eastwood <manabian@gmail.com>
 *
 * Based on the imx ocotp driver,
 * Copyright (c) 2015 Pengutronix, Philipp Zabel <p.zabel@pengutronix.de>
 *
 * TODO: add support for writing OTP register via API in boot ROM.
 */

#include <linux/io.h>
#include <linux/module.h>
#include <linux/nvmem-provider.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

/*
 * LPC18xx OTP memory contains 4 banks with 4 32-bit words. Bank 0 starts
 * at offset 0 from the base.
 *
 * Bank 0 contains the part ID for Flashless devices and is reseverd for
 * devices with Flash.
 * Bank 1/2 is generale purpose or AES key storage for secure devices.
 * Bank 3 contains control data, USB ID and generale purpose words.
 */
#define LPC18XX_OTP_NUM_BANKS		4
#define LPC18XX_OTP_WORDS_PER_BANK	4
#define LPC18XX_OTP_WORD_SIZE		sizeof(u32)
#define LPC18XX_OTP_SIZE		(LPC18XX_OTP_NUM_BANKS * \
					 LPC18XX_OTP_WORDS_PER_BANK * \
					 LPC18XX_OTP_WORD_SIZE)

struct lpc18xx_otp {
	void __iomem *base;
};

static int lpc18xx_otp_read(void *context, unsigned int offset,
			    void *val, size_t bytes)
{
	struct lpc18xx_otp *otp = context;
	unsigned int count = bytes >> 2;
	u32 index = offset >> 2;
	u32 *buf = val;
	int i;

	if (count > (LPC18XX_OTP_SIZE - index))
		count = LPC18XX_OTP_SIZE - index;

	for (i = index; i < (index + count); i++)
		*buf++ = readl(otp->base + i * LPC18XX_OTP_WORD_SIZE);

	return 0;
}

static struct nvmem_config lpc18xx_otp_nvmem_config = {
	.name = "lpc18xx-otp",
	.read_only = true,
	.word_size = LPC18XX_OTP_WORD_SIZE,
	.stride = LPC18XX_OTP_WORD_SIZE,
	.reg_read = lpc18xx_otp_read,
};

static int lpc18xx_otp_probe(struct platform_device *pdev)
{
	struct nvmem_device *nvmem;
	struct lpc18xx_otp *otp;

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

	otp->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(otp->base))
		return PTR_ERR(otp->base);

	lpc18xx_otp_nvmem_config.size = LPC18XX_OTP_SIZE;
	lpc18xx_otp_nvmem_config.dev = &pdev->dev;
	lpc18xx_otp_nvmem_config.priv = otp;

	nvmem = devm_nvmem_register(&pdev->dev, &lpc18xx_otp_nvmem_config);

	return PTR_ERR_OR_ZERO(nvmem);
}

static const struct of_device_id lpc18xx_otp_dt_ids[] = {
	{ .compatible = "nxp,lpc1850-otp" },
	{ },
};
MODULE_DEVICE_TABLE(of, lpc18xx_otp_dt_ids);

static struct platform_driver lpc18xx_otp_driver = {
	.probe	= lpc18xx_otp_probe,
	.driver = {
		.name	= "lpc18xx_otp",
		.of_match_table = lpc18xx_otp_dt_ids,
	},
};
module_platform_driver(lpc18xx_otp_driver);

MODULE_AUTHOR("Joachim Eastwoood <manabian@gmail.com>");
MODULE_DESCRIPTION("NXP LPC18xx OTP NVMEM driver");
MODULE_LICENSE("GPL v2");
