// SPDX-License-Identifier: GPL-2.0-only
/**
 * Register map access API - ENCX24J600 support
 *
 * Copyright 2015 Gridpoint
 *
 * Author: Jon Ringle <jringle@gridpoint.com>
 */

#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/regmap.h>
#include <linux/spi/spi.h>

#include "encx24j600_hw.h"

static int encx24j600_switch_bank(struct encx24j600_context *ctx,
				  int bank)
{
	int ret = 0;
	int bank_opcode = BANK_SELECT(bank);

	ret = spi_write(ctx->spi, &bank_opcode, 1);
	if (ret == 0)
		ctx->bank = bank;

	return ret;
}

static int encx24j600_cmdn(struct encx24j600_context *ctx, u8 opcode,
			   const void *buf, size_t len)
{
	struct spi_message m;
	struct spi_transfer t[2] = { { .tx_buf = &opcode, .len = 1, },
				     { .tx_buf = buf, .len = len }, };
	spi_message_init(&m);
	spi_message_add_tail(&t[0], &m);
	spi_message_add_tail(&t[1], &m);

	return spi_sync(ctx->spi, &m);
}

static void regmap_lock_mutex(void *context)
{
	struct encx24j600_context *ctx = context;

	mutex_lock(&ctx->mutex);
}

static void regmap_unlock_mutex(void *context)
{
	struct encx24j600_context *ctx = context;

	mutex_unlock(&ctx->mutex);
}

static int regmap_encx24j600_sfr_read(void *context, u8 reg, u8 *val,
				      size_t len)
{
	struct encx24j600_context *ctx = context;
	u8 banked_reg = reg & ADDR_MASK;
	u8 bank = ((reg & BANK_MASK) >> BANK_SHIFT);
	u8 cmd = RCRU;
	int ret = 0;
	int i = 0;
	u8 tx_buf[2];

	if (reg < 0x80) {
		cmd = RCRCODE | banked_reg;
		if ((banked_reg < 0x16) && (ctx->bank != bank))
			ret = encx24j600_switch_bank(ctx, bank);
		if (unlikely(ret))
			return ret;
	} else {
		/* Translate registers that are more effecient using
		 * 3-byte SPI commands
		 */
		switch (reg) {
		case EGPRDPT:
			cmd = RGPRDPT; break;
		case EGPWRPT:
			cmd = RGPWRPT; break;
		case ERXRDPT:
			cmd = RRXRDPT; break;
		case ERXWRPT:
			cmd = RRXWRPT; break;
		case EUDARDPT:
			cmd = RUDARDPT; break;
		case EUDAWRPT:
			cmd = RUDAWRPT; break;
		case EGPDATA:
		case ERXDATA:
		case EUDADATA:
		default:
			return -EINVAL;
		}
	}

	tx_buf[i++] = cmd;
	if (cmd == RCRU)
		tx_buf[i++] = reg;

	ret = spi_write_then_read(ctx->spi, tx_buf, i, val, len);

	return ret;
}

static int regmap_encx24j600_sfr_update(struct encx24j600_context *ctx,
					u8 reg, u8 *val, size_t len,
					u8 unbanked_cmd, u8 banked_code)
{
	u8 banked_reg = reg & ADDR_MASK;
	u8 bank = ((reg & BANK_MASK) >> BANK_SHIFT);
	u8 cmd = unbanked_cmd;
	struct spi_message m;
	struct spi_transfer t[3] = { { .tx_buf = &cmd, .len = sizeof(cmd), },
				     { .tx_buf = &reg, .len = sizeof(reg), },
				     { .tx_buf = val, .len = len }, };

	if (reg < 0x80) {
		int ret = 0;

		cmd = banked_code | banked_reg;
		if ((banked_reg < 0x16) && (ctx->bank != bank))
			ret = encx24j600_switch_bank(ctx, bank);
		if (unlikely(ret))
			return ret;
	} else {
		/* Translate registers that are more effecient using
		 * 3-byte SPI commands
		 */
		switch (reg) {
		case EGPRDPT:
			cmd = WGPRDPT; break;
		case EGPWRPT:
			cmd = WGPWRPT; break;
		case ERXRDPT:
			cmd = WRXRDPT; break;
		case ERXWRPT:
			cmd = WRXWRPT; break;
		case EUDARDPT:
			cmd = WUDARDPT; break;
		case EUDAWRPT:
			cmd = WUDAWRPT; break;
		case EGPDATA:
		case ERXDATA:
		case EUDADATA:
		default:
			return -EINVAL;
		}
	}

	spi_message_init(&m);
	spi_message_add_tail(&t[0], &m);

	if (cmd == unbanked_cmd) {
		t[1].tx_buf = &reg;
		spi_message_add_tail(&t[1], &m);
	}

	spi_message_add_tail(&t[2], &m);
	return spi_sync(ctx->spi, &m);
}

static int regmap_encx24j600_sfr_write(void *context, u8 reg, u8 *val,
				       size_t len)
{
	struct encx24j600_context *ctx = context;

	return regmap_encx24j600_sfr_update(ctx, reg, val, len, WCRU, WCRCODE);
}

static int regmap_encx24j600_sfr_set_bits(struct encx24j600_context *ctx,
					  u8 reg, u8 val)
{
	return regmap_encx24j600_sfr_update(ctx, reg, &val, 1, BFSU, BFSCODE);
}

static int regmap_encx24j600_sfr_clr_bits(struct encx24j600_context *ctx,
					  u8 reg, u8 val)
{
	return regmap_encx24j600_sfr_update(ctx, reg, &val, 1, BFCU, BFCCODE);
}

static int regmap_encx24j600_reg_update_bits(void *context, unsigned int reg,
					     unsigned int mask,
					     unsigned int val)
{
	struct encx24j600_context *ctx = context;

	int ret = 0;
	unsigned int set_mask = mask & val;
	unsigned int clr_mask = mask & ~val;

	if ((reg >= 0x40 && reg < 0x6c) || reg >= 0x80)
		return -EINVAL;

	if (set_mask & 0xff)
		ret = regmap_encx24j600_sfr_set_bits(ctx, reg, set_mask);

	set_mask = (set_mask & 0xff00) >> 8;

	if ((set_mask & 0xff) && (ret == 0))
		ret = regmap_encx24j600_sfr_set_bits(ctx, reg + 1, set_mask);

	if ((clr_mask & 0xff) && (ret == 0))
		ret = regmap_encx24j600_sfr_clr_bits(ctx, reg, clr_mask);

	clr_mask = (clr_mask & 0xff00) >> 8;

	if ((clr_mask & 0xff) && (ret == 0))
		ret = regmap_encx24j600_sfr_clr_bits(ctx, reg + 1, clr_mask);

	return ret;
}

int regmap_encx24j600_spi_write(void *context, u8 reg, const u8 *data,
				size_t count)
{
	struct encx24j600_context *ctx = context;

	if (reg < 0xc0)
		return encx24j600_cmdn(ctx, reg, data, count);

	/* SPI 1-byte command. Ignore data */
	return spi_write(ctx->spi, &reg, 1);
}
EXPORT_SYMBOL_GPL(regmap_encx24j600_spi_write);

int regmap_encx24j600_spi_read(void *context, u8 reg, u8 *data, size_t count)
{
	struct encx24j600_context *ctx = context;

	if (reg == RBSEL && count > 1)
		count = 1;

	return spi_write_then_read(ctx->spi, &reg, sizeof(reg), data, count);
}
EXPORT_SYMBOL_GPL(regmap_encx24j600_spi_read);

static int regmap_encx24j600_write(void *context, const void *data,
				   size_t len)
{
	u8 *dout = (u8 *)data;
	u8 reg = dout[0];
	++dout;
	--len;

	if (reg > 0xa0)
		return regmap_encx24j600_spi_write(context, reg, dout, len);

	if (len > 2)
		return -EINVAL;

	return regmap_encx24j600_sfr_write(context, reg, dout, len);
}

static int regmap_encx24j600_read(void *context,
				  const void *reg_buf, size_t reg_size,
				  void *val, size_t val_size)
{
	u8 reg = *(const u8 *)reg_buf;

	if (reg_size != 1) {
		pr_err("%s: reg=%02x reg_size=%zu\n", __func__, reg, reg_size);
		return -EINVAL;
	}

	if (reg > 0xa0)
		return regmap_encx24j600_spi_read(context, reg, val, val_size);

	if (val_size > 2) {
		pr_err("%s: reg=%02x val_size=%zu\n", __func__, reg, val_size);
		return -EINVAL;
	}

	return regmap_encx24j600_sfr_read(context, reg, val, val_size);
}

static bool encx24j600_regmap_readable(struct device *dev, unsigned int reg)
{
	if ((reg < 0x36) ||
	    ((reg >= 0x40) && (reg < 0x4c)) ||
	    ((reg >= 0x52) && (reg < 0x56)) ||
	    ((reg >= 0x60) && (reg < 0x66)) ||
	    ((reg >= 0x68) && (reg < 0x80)) ||
	    ((reg >= 0x86) && (reg < 0x92)) ||
	    (reg == 0xc8))
		return true;
	else
		return false;
}

static bool encx24j600_regmap_writeable(struct device *dev, unsigned int reg)
{
	if ((reg < 0x12) ||
	    ((reg >= 0x14) && (reg < 0x1a)) ||
	    ((reg >= 0x1c) && (reg < 0x36)) ||
	    ((reg >= 0x40) && (reg < 0x4c)) ||
	    ((reg >= 0x52) && (reg < 0x56)) ||
	    ((reg >= 0x60) && (reg < 0x68)) ||
	    ((reg >= 0x6c) && (reg < 0x80)) ||
	    ((reg >= 0x86) && (reg < 0x92)) ||
	    ((reg >= 0xc0) && (reg < 0xc8)) ||
	    ((reg >= 0xca) && (reg < 0xf0)))
		return true;
	else
		return false;
}

static bool encx24j600_regmap_volatile(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case ERXHEAD:
	case EDMACS:
	case ETXSTAT:
	case ETXWIRE:
	case ECON1:	/* Can be modified via single byte cmds */
	case ECON2:	/* Can be modified via single byte cmds */
	case ESTAT:
	case EIR:	/* Can be modified via single byte cmds */
	case MIRD:
	case MISTAT:
		return true;
	default:
		break;
	}

	return false;
}

static bool encx24j600_regmap_precious(struct device *dev, unsigned int reg)
{
	/* single byte cmds are precious */
	if (((reg >= 0xc0) && (reg < 0xc8)) ||
	    ((reg >= 0xca) && (reg < 0xf0)))
		return true;
	else
		return false;
}

static int regmap_encx24j600_phy_reg_read(void *context, unsigned int reg,
					  unsigned int *val)
{
	struct encx24j600_context *ctx = context;
	int ret;
	unsigned int mistat;

	reg = MIREGADR_VAL | (reg & PHREG_MASK);
	ret = regmap_write(ctx->regmap, MIREGADR, reg);
	if (unlikely(ret))
		goto err_out;

	ret = regmap_write(ctx->regmap, MICMD, MIIRD);
	if (unlikely(ret))
		goto err_out;

	usleep_range(26, 100);
	while ((ret = regmap_read(ctx->regmap, MISTAT, &mistat) != 0) &&
	       (mistat & BUSY))
		cpu_relax();

	if (unlikely(ret))
		goto err_out;

	ret = regmap_write(ctx->regmap, MICMD, 0);
	if (unlikely(ret))
		goto err_out;

	ret = regmap_read(ctx->regmap, MIRD, val);

err_out:
	if (ret)
		pr_err("%s: error %d reading reg %02x\n", __func__, ret,
		       reg & PHREG_MASK);

	return ret;
}

static int regmap_encx24j600_phy_reg_write(void *context, unsigned int reg,
					   unsigned int val)
{
	struct encx24j600_context *ctx = context;
	int ret;
	unsigned int mistat;

	reg = MIREGADR_VAL | (reg & PHREG_MASK);
	ret = regmap_write(ctx->regmap, MIREGADR, reg);
	if (unlikely(ret))
		goto err_out;

	ret = regmap_write(ctx->regmap, MIWR, val);
	if (unlikely(ret))
		goto err_out;

	usleep_range(26, 100);
	while ((ret = regmap_read(ctx->regmap, MISTAT, &mistat) != 0) &&
	       (mistat & BUSY))
		cpu_relax();

err_out:
	if (ret)
		pr_err("%s: error %d writing reg %02x=%04x\n", __func__, ret,
		       reg & PHREG_MASK, val);

	return ret;
}

static bool encx24j600_phymap_readable(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case PHCON1:
	case PHSTAT1:
	case PHANA:
	case PHANLPA:
	case PHANE:
	case PHCON2:
	case PHSTAT2:
	case PHSTAT3:
		return true;
	default:
		return false;
	}
}

static bool encx24j600_phymap_writeable(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case PHCON1:
	case PHCON2:
	case PHANA:
		return true;
	case PHSTAT1:
	case PHSTAT2:
	case PHSTAT3:
	case PHANLPA:
	case PHANE:
	default:
		return false;
	}
}

static bool encx24j600_phymap_volatile(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case PHSTAT1:
	case PHSTAT2:
	case PHSTAT3:
	case PHANLPA:
	case PHANE:
	case PHCON2:
		return true;
	default:
		return false;
	}
}

static struct regmap_config regcfg = {
	.name = "reg",
	.reg_bits = 8,
	.val_bits = 16,
	.max_register = 0xee,
	.reg_stride = 2,
	.cache_type = REGCACHE_RBTREE,
	.val_format_endian = REGMAP_ENDIAN_LITTLE,
	.readable_reg = encx24j600_regmap_readable,
	.writeable_reg = encx24j600_regmap_writeable,
	.volatile_reg = encx24j600_regmap_volatile,
	.precious_reg = encx24j600_regmap_precious,
	.lock = regmap_lock_mutex,
	.unlock = regmap_unlock_mutex,
};

static struct regmap_bus regmap_encx24j600 = {
	.write = regmap_encx24j600_write,
	.read = regmap_encx24j600_read,
	.reg_update_bits = regmap_encx24j600_reg_update_bits,
};

static struct regmap_config phycfg = {
	.name = "phy",
	.reg_bits = 8,
	.val_bits = 16,
	.max_register = 0x1f,
	.cache_type = REGCACHE_RBTREE,
	.val_format_endian = REGMAP_ENDIAN_LITTLE,
	.readable_reg = encx24j600_phymap_readable,
	.writeable_reg = encx24j600_phymap_writeable,
	.volatile_reg = encx24j600_phymap_volatile,
};

static struct regmap_bus phymap_encx24j600 = {
	.reg_write = regmap_encx24j600_phy_reg_write,
	.reg_read = regmap_encx24j600_phy_reg_read,
};

void devm_regmap_init_encx24j600(struct device *dev,
				 struct encx24j600_context *ctx)
{
	mutex_init(&ctx->mutex);
	regcfg.lock_arg = ctx;
	ctx->regmap = devm_regmap_init(dev, &regmap_encx24j600, ctx, &regcfg);
	ctx->phymap = devm_regmap_init(dev, &phymap_encx24j600, ctx, &phycfg);
}
EXPORT_SYMBOL_GPL(devm_regmap_init_encx24j600);

MODULE_LICENSE("GPL");
