/**
 * Register map access API - ENCX24J600 support
 *
 * Copyright 2015 Gridpoint
 *
 * Author: Jon Ringle <jringle@gridpoint.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#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 inline bool is_bits_set(int value, int mask)
{
	return (value & mask) == mask;
}

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);
	else
		/* 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");
