/* (C) 2019 by Harald Welte <laforge@osmocom.org>
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <stdint.h>

#include "idt82v2081.h"
#include "idt82v2081_regs.h"

/*! \brief Set or clear some (masked) bits inside a register
 *  \param[in] e4k reference to the tuner
 *  \param[in] reg number of the register
 *  \param[in] mask bit-mask of the value
 *  \param[in] val data value to be written to register
 *  \returns 0 on success, negative in case of error
 */
static int idt82_reg_set_bit_mask(struct idt82 *idt, uint8_t reg,
				  uint8_t mask, uint8_t val)
{
	uint8_t tmp = idt82_reg_read(idt, reg);

	if ((tmp & mask) == val)
		return 0;

	return idt82_reg_write(idt, reg, (tmp & ~mask) | (val & mask));
}

int idt82_termination(struct idt82 *idt, enum idt82_term term)
{
	uint8_t puls, scal;

	idt82_reg_set_bit_mask(idt, IDT_REG_TERM, term | (term << IDT_TERM_T_SHIFT),
			       IDT_TERM_T_MASK | IDT_TERM_R_MASK);

	switch (idt->mode) {
	case IDT_MODE_E1:
		if (term == IDT_TERM_INT_75)
			puls = 0;
		else
			puls = 1;
		scal = 0x21;
		break;
	case IDT_MODE_T1:
		/* FIXME: different length! */
		puls = 2;
		scal = 0x36;
		break;
	case IDT_MODE_J1:
		puls = 7;
		scal = 0x36;
		break;
	default:
		return -1;
	}

	idt82_reg_set_bit_mask(idt, IDT_REG_TCF1, puls, IDT_TCF1_PULS_MASK);
	idt82_reg_set_bit_mask(idt, IDT_REG_TCF2, scal, IDT_TCF2_SCAL_MASK);

	idt->term = term;

	return 0;
}

int idt82_mode(struct idt82 *idt, enum idt82_mode mode)
{
	switch (mode) {
	case IDT_MODE_E1:
		idt82_reg_set_bit_mask(idt, IDT_REG_GCF, IDT_GCF_T1E1_E1,
				       IDT_GCF_T1E1_MASK);
		break;
	case IDT_MODE_T1:
	case IDT_MODE_J1:
		idt82_reg_set_bit_mask(idt, IDT_REG_GCF, IDT_GCF_T1E1_T1,
				       IDT_GCF_T1E1_MASK);
		break;
	}
	idt->mode = mode;

	return 0;
}

int idt82_get_errcount(struct idt82 *idt)
{
	uint16_t ret;
	int rc;

	rc = idt82_reg_read(idt, IDT_REG_CNT0);
	if (rc < 0)
		return rc;

	ret = rc;

	rc = idt82_reg_read(idt, IDT_REG_CNT1);
	if (rc < 0)
		return rc;

	ret |= (rc << 8);

	return ret;
}

/* return in dB, range is return value ... (value + 2) */
int idt82_get_line_att(struct idt82 *idt)
{
	int rc;

	rc = idt82_reg_read(idt, IDT_REG_STAT1);
	if (rc < 0)
		return rc;

	return (rc & IDT_STAT1_ATT_MASK)*2;
}

int idt82_init(struct idt82 *idt, bool monitor)
{
	idt82_reg_write(idt, IDT_REG_RST,  0x00);	/* Reset to defaults */

	idt82_mode(idt, IDT_MODE_E1);
	idt82_termination(idt, IDT_TERM_INT_120);

	idt82_reg_write(idt, IDT_REG_TCF0, 0x10);	/* Disable TX */

	if (monitor)
		idt82_reg_write(idt, IDT_REG_RCF2, 0x19);	/* 22 dB monitor mode */

	return 0;
}

