/* Access functions for the per-SIM-slot NCN8025 chip card interface,
 * which is controlled via (half) a SX1503 I2C GPIO expander.
 *
 * (C) 2019 by Harald Welte <laforge@gnumonks.org>
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 */

#include <stdint.h>
#include <string.h>
#include <utils_assert.h>
#include <utils.h>
#include "octsim_i2c.h"
#include "ncn8025.h"

#define SX1503_ADDR	0x20

/*! translate from ncn8025_settings into SX1503 register value */
static uint8_t ncn8025_encode(const struct ncn8025_settings *set)
{
	uint8_t reg = 0;
	if (set->rstin)
		reg |= 0x01;
	if (!set->cmdvcc)
		reg |= 0x02;
	if (set->clkdiv & 1)
		reg |= 0x04;
	if (set->clkdiv & 2)
		reg |= 0x08;
	if (set->vsel & 1)
		reg |= 0x10;
	if (set->vsel & 2)
		reg |= 0x20;
	if (set->led)
		reg |= 0x80;
	return reg;
}

/*! translate from register value to ncn8025_settings */
static int ncn8025_decode(uint8_t reg, struct ncn8025_settings *set)
{
	memset(set, 0, sizeof(*set));

	if (reg & 0x01)
		set->rstin = true;
	if (!(reg & 0x02))
		set->cmdvcc = true;
	if (reg & 0x04)
		set->clkdiv |= 0x01;
	if (reg & 0x08)
		set->clkdiv |= 0x02;
	if (reg & 0x10)
		set->vsel |= 0x01;
	if (reg & 0x20)
		set->vsel |= 0x02;
	if (!(reg & 0x40))
		set->simpres = true;
	if ((reg & 0x80))
		set->led = true;

	return 0;
}

static const struct i2c_adapter *slot2adapter(unsigned int slot)
{
	unsigned int idx = slot / 2;
	ASSERT(idx < ARRAY_SIZE(i2c));
	return &i2c[idx];
}


static const uint8_t slot2data_reg(unsigned int slot)
{
	if (slot & 1)
		return 0x00;
	else
		return 0x01;
}

static const uint8_t slot2dir_reg(unsigned int slot)
{
	if (slot & 1)
		return 0x02;
	else
		return 0x03;
}


/*! Set a given NCN8025 as described in 'set'.
 *  \param[in] slot Slot number (0..7)
 *  \param[in] set Settings that shall be written
 *  \returns 0 on success; negative on error */
int ncn8025_set(uint8_t slot, const struct ncn8025_settings *set)
{
	const struct i2c_adapter *adap = slot2adapter(slot);
	uint8_t reg = slot2data_reg(slot);
	uint8_t raw = ncn8025_encode(set);
	return i2c_write_reg(adap, SX1503_ADDR, reg, raw);
}

/*! Get a given NCN8025 state from the chip.
 *  \param[in] slot Slot number (0..7)
 *  \param[out] set Settings that are retrieved
 *  \returns 0 on success; negative on error */
int ncn8025_get(uint8_t slot, struct ncn8025_settings *set)
{
	const struct i2c_adapter *adap = slot2adapter(slot);
	uint8_t reg = slot2data_reg(slot);
	int rc;
	rc = i2c_read_reg(adap, SX1503_ADDR, reg);
	if (rc < 0)
		return rc;
	return ncn8025_decode(rc, set);
}

/*! default settings we use at start-up: powered off, in reset, slowest clock, 3V */
static const struct ncn8025_settings def_settings = {
	.rstin = true,
	.cmdvcc = false,
	.led = false,
	.clkdiv = SIM_CLKDIV_8,
	.vsel = SIM_VOLT_3V0,
};

/*! Initialize a given NCN8025/slot. */
int ncn8025_init(unsigned int slot)
{
	const struct i2c_adapter *adap = slot2adapter(slot);
	uint8_t reg = slot2dir_reg(slot);
	int rc;
	/* IO6 of each bank is input (!PRESENT), rest are outputs */
	rc = i2c_write_reg(adap, SX1503_ADDR, reg, 0x40);
	if (rc < 0)
		return rc;
	return ncn8025_set(slot, &def_settings);
}
