// SPDX-License-Identifier: GPL-2.0+
/*
 * Driver for one wire controller in some i.MX Socs
 *
 * There are currently two silicon variants:
 * V1: i.MX21, i.MX27, i.MX31, i.MX51
 * V2: i.MX25, i.MX35, i.MX50, i.MX53
 * Newer i.MX SoCs such as the i.MX6 do not have one wire controllers.
 *
 * The V1 controller only supports single bit operations.
 * The V2 controller is backwards compatible on the register level but adds
 * byte size operations and a "search ROM accelerator mode"
 *
 * This driver does not currently support the search ROM accelerator
 *
 * Copyright (c) 2018 Flowbird
 * Martin Fuzzey <martin.fuzzey@flowbird.group>
 */

#include <asm/arch/clock.h>
#include <common.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <linux/io.h>
#include <w1.h>

struct mxc_w1_regs {
	u16 control;
#define MXC_W1_CONTROL_RPP	BIT(7)
#define MXC_W1_CONTROL_PST	BIT(6)
#define MXC_W1_CONTROL_WR(x)	BIT(5 - (x))
#define MXC_W1_CONTROL_RDST	BIT(3)

	u16 time_divider;
	u16 reset;

	/* Registers below on V2 silicon only */
	u16 command;
	u16 tx_rx;
	u16 interrupt;
#define MXC_W1_INTERRUPT_TBE	BIT(2)
#define MXC_W1_INTERRUPT_TSRE	BIT(3)
#define MXC_W1_INTERRUPT_RBF	BIT(4)
#define MXC_W1_INTERRUPT_RSRF	BIT(5)

	u16 interrupt_en;
};

struct mxc_w1_pdata {
	struct mxc_w1_regs *regs;
};

/*
 * this is the low level routine to read/write a bit on the One Wire
 * interface on the hardware. It does write 0 if parameter bit is set
 * to 0, otherwise a write 1/read.
 */
static u8 mxc_w1_touch_bit(struct mxc_w1_pdata *pdata, u8 bit)
{
	u16 *ctrl_addr = &pdata->regs->control;
	u16 mask = MXC_W1_CONTROL_WR(bit);
	unsigned int timeout_cnt = 400; /* Takes max. 120us according to
					 * datasheet.
					 */

	writew(mask, ctrl_addr);

	while (timeout_cnt--) {
		if (!(readw(ctrl_addr) & mask))
			break;

		udelay(1);
	}

	return (readw(ctrl_addr) & MXC_W1_CONTROL_RDST) ? 1 : 0;
}

static u8 mxc_w1_read_byte(struct udevice *dev)
{
	struct mxc_w1_pdata *pdata = dev_get_platdata(dev);
	struct mxc_w1_regs *regs = pdata->regs;
	u16 status;

	if (dev_get_driver_data(dev) < 2) {
		int i;
		u8 ret = 0;

		for (i = 0; i < 8; i++)
			ret |= (mxc_w1_touch_bit(pdata, 1) << i);

		return ret;
	}

	readw(&regs->tx_rx);
	writew(0xFF, &regs->tx_rx);

	do {
		udelay(1); /* Without this bytes are sometimes duplicated... */
		status = readw(&regs->interrupt);
	} while (!(status & MXC_W1_INTERRUPT_RBF));

	return (u8)readw(&regs->tx_rx);
}

static void mxc_w1_write_byte(struct udevice *dev, u8 byte)
{
	struct mxc_w1_pdata *pdata = dev_get_platdata(dev);
	struct mxc_w1_regs *regs = pdata->regs;
	u16 status;

	if (dev_get_driver_data(dev) < 2) {
		int i;

		for (i = 0; i < 8; i++)
			mxc_w1_touch_bit(pdata, (byte >> i) & 0x1);

		return;
	}

	readw(&regs->tx_rx);
	writew(byte, &regs->tx_rx);

	do {
		udelay(1);
		status = readw(&regs->interrupt);
	} while (!(status & MXC_W1_INTERRUPT_TSRE));
}

static bool mxc_w1_reset(struct udevice *dev)
{
	struct mxc_w1_pdata *pdata = dev_get_platdata(dev);
	u16 reg_val;

	writew(MXC_W1_CONTROL_RPP, &pdata->regs->control);

	do {
		reg_val = readw(&pdata->regs->control);
	}  while (reg_val & MXC_W1_CONTROL_RPP);

	return !(reg_val & MXC_W1_CONTROL_PST);
}

static u8 mxc_w1_triplet(struct udevice *dev, bool bdir)
{
	struct mxc_w1_pdata *pdata = dev_get_platdata(dev);
	u8 id_bit   = mxc_w1_touch_bit(pdata, 1);
	u8 comp_bit = mxc_w1_touch_bit(pdata, 1);
	u8 retval;

	if (id_bit && comp_bit)
		return 0x03;  /* error */

	if (!id_bit && !comp_bit) {
		/* Both bits are valid, take the direction given */
		retval = bdir ? 0x04 : 0;
	} else {
		/* Only one bit is valid, take that direction */
		bdir = id_bit;
		retval = id_bit ? 0x05 : 0x02;
	}

	mxc_w1_touch_bit(pdata, bdir);

	return retval;
}

static int mxc_w1_ofdata_to_platdata(struct udevice *dev)
{
	struct mxc_w1_pdata *pdata = dev_get_platdata(dev);
	fdt_addr_t addr;

	addr = devfdt_get_addr(dev);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	pdata->regs = (struct mxc_w1_regs *)addr;

	return 0;
};

static int mxc_w1_probe(struct udevice *dev)
{
	struct mxc_w1_pdata *pdata = dev_get_platdata(dev);
	unsigned int clkrate = mxc_get_clock(MXC_IPG_PERCLK);
	unsigned int clkdiv;

	if (clkrate < 10000000) {
		dev_err(dev, "input clock frequency (%u Hz) too low\n",
			clkrate);
		return -EINVAL;
	}

	clkdiv = clkrate / 1000000;
	clkrate /= clkdiv;
	if (clkrate < 980000 || clkrate > 1020000) {
		dev_err(dev, "Incorrect time base frequency %u Hz\n", clkrate);
		return -EINVAL;
	}

	writew(clkdiv - 1, &pdata->regs->time_divider);

	return 0;
}

static const struct w1_ops mxc_w1_ops = {
	.read_byte	= mxc_w1_read_byte,
	.reset		= mxc_w1_reset,
	.triplet	= mxc_w1_triplet,
	.write_byte	= mxc_w1_write_byte,
};

static const struct udevice_id mxc_w1_id[] = {
	{ .compatible = "fsl,imx21-owire", .data = 1 },
	{ .compatible = "fsl,imx27-owire", .data = 1 },
	{ .compatible = "fsl,imx31-owire", .data = 1 },
	{ .compatible = "fsl,imx51-owire", .data = 1 },

	{ .compatible = "fsl,imx25-owire", .data = 2 },
	{ .compatible = "fsl,imx35-owire", .data = 2 },
	{ .compatible = "fsl,imx50-owire", .data = 2 },
	{ .compatible = "fsl,imx53-owire", .data = 2 },
	{ },
};

U_BOOT_DRIVER(mxc_w1_drv) = {
	.id				= UCLASS_W1,
	.name				= "mxc_w1_drv",
	.of_match			= mxc_w1_id,
	.ofdata_to_platdata		= mxc_w1_ofdata_to_platdata,
	.ops				= &mxc_w1_ops,
	.platdata_auto_alloc_size	= sizeof(struct mxc_w1_pdata),
	.probe				= mxc_w1_probe,
};
