/*
 * SBE 2T3E3 synchronous serial card driver for Linux
 *
 * Copyright (C) 2009-2010 Krzysztof Halasa <khc@pm.waw.pl>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 *
 * This code is based on a driver written by SBE Inc.
 */

#include "2t3e3.h"
#include "ctrl.h"

void exar7250_init(struct channel *sc)
{
	exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
		       SBE_2T3E3_FRAMER_VAL_T3_CBIT |
		       SBE_2T3E3_FRAMER_VAL_INTERRUPT_ENABLE_RESET |
		       SBE_2T3E3_FRAMER_VAL_TIMING_ASYNCH_TXINCLK);

	exar7250_write(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
		       SBE_2T3E3_FRAMER_VAL_DISABLE_TX_LOSS_OF_CLOCK |
		       SBE_2T3E3_FRAMER_VAL_DISABLE_RX_LOSS_OF_CLOCK |
		       SBE_2T3E3_FRAMER_VAL_AMI_LINE_CODE |
		       SBE_2T3E3_FRAMER_VAL_RX_LINE_CLOCK_INVERT);

	exar7250_set_frame_type(sc, SBE_2T3E3_FRAME_TYPE_T3_CBIT);
}

void exar7250_set_frame_type(struct channel *sc, u32 type)
{
	u32 val;

	switch (type) {
	case SBE_2T3E3_FRAME_TYPE_E3_G751:
	case SBE_2T3E3_FRAME_TYPE_E3_G832:
	case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
	case SBE_2T3E3_FRAME_TYPE_T3_M13:
		break;
	default:
		return;
	}

	exar7250_stop_intr(sc, type);

	val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE);
	val &= ~(SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE |
		 SBE_2T3E3_FRAMER_VAL_T3_E3_SELECT |
		 SBE_2T3E3_FRAMER_VAL_FRAME_FORMAT_SELECT);
	switch (type) {
	case SBE_2T3E3_FRAME_TYPE_E3_G751:
		val |= SBE_2T3E3_FRAMER_VAL_E3_G751;
		break;
	case SBE_2T3E3_FRAME_TYPE_E3_G832:
		val |= SBE_2T3E3_FRAMER_VAL_E3_G832;
		break;
	case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
		val |= SBE_2T3E3_FRAMER_VAL_T3_CBIT;
		break;
	case SBE_2T3E3_FRAME_TYPE_T3_M13:
		val |= SBE_2T3E3_FRAMER_VAL_T3_M13;
		break;
	default:
		return;
	}
	exar7250_write(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE, val);
	exar7250_start_intr(sc, type);
}


void exar7250_start_intr(struct channel *sc, u32 type)
{
	u32 val;

	switch (type) {
	case SBE_2T3E3_FRAME_TYPE_E3_G751:
	case SBE_2T3E3_FRAME_TYPE_E3_G832:
		val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_CONFIGURATION_STATUS_2);

		cpld_LOS_update(sc);

		sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_E3_RX_OOF ? 1 : 0;
		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1,
			       SBE_2T3E3_FRAMER_VAL_E3_RX_OOF_INTERRUPT_ENABLE |
			       SBE_2T3E3_FRAMER_VAL_E3_RX_LOS_INTERRUPT_ENABLE);

		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
		break;

	case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
	case SBE_2T3E3_FRAME_TYPE_T3_M13:
		val = exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_CONFIGURATION_STATUS);

		cpld_LOS_update(sc);

		sc->s.OOF = val & SBE_2T3E3_FRAMER_VAL_T3_RX_OOF ? 1 : 0;

		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE,
			       SBE_2T3E3_FRAMER_VAL_T3_RX_LOS_INTERRUPT_ENABLE |
			       SBE_2T3E3_FRAMER_VAL_T3_RX_OOF_INTERRUPT_ENABLE);

		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);

		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0);
		break;

	default:
		return;
	}

	exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);
	exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE,
		       SBE_2T3E3_FRAMER_VAL_RX_INTERRUPT_ENABLE |
		       SBE_2T3E3_FRAMER_VAL_TX_INTERRUPT_ENABLE);
}


void exar7250_stop_intr(struct channel *sc, u32 type)
{
	exar7250_write(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_ENABLE, 0);
	exar7250_read(sc, SBE_2T3E3_FRAMER_REG_BLOCK_INTERRUPT_STATUS);

	switch (type) {
	case SBE_2T3E3_FRAME_TYPE_E3_G751:
	case SBE_2T3E3_FRAME_TYPE_E3_G832:
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_1, 0);
		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_1);
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_ENABLE_2, 0);
		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_INTERRUPT_STATUS_2);
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL, 0);
		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_RX_LAPD_CONTROL);
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS, 0);
		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_E3_TX_LAPD_STATUS);
		break;

	case SBE_2T3E3_FRAME_TYPE_T3_CBIT:
	case SBE_2T3E3_FRAME_TYPE_T3_M13:
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_ENABLE, 0);
		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_INTERRUPT_STATUS);
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS, 0);
		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_FEAC_INTERRUPT_ENABLE_STATUS);
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL, 0);
		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_RX_LAPD_CONTROL);
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS, 0);
		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_FEAC_CONFIGURATION_STATUS);
		exar7250_write(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS, 0);
		exar7250_read(sc, SBE_2T3E3_FRAMER_REG_T3_TX_LAPD_STATUS);
		break;
	}
}




void exar7250_unipolar_onoff(struct channel *sc, u32 mode)
{
	switch (mode) {
	case SBE_2T3E3_OFF:
		exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
				   SBE_2T3E3_FRAMER_VAL_UNIPOLAR);
		break;
	case SBE_2T3E3_ON:
		exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_IO_CONTROL,
				 SBE_2T3E3_FRAMER_VAL_UNIPOLAR);
		break;
	}
}

void exar7250_set_loopback(struct channel *sc, u32 mode)
{
	switch (mode) {
	case SBE_2T3E3_FRAMER_VAL_LOOPBACK_OFF:
		exar7300_clear_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
				   SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE);
		break;
	case SBE_2T3E3_FRAMER_VAL_LOOPBACK_ON:
		exar7300_set_bit(sc, SBE_2T3E3_FRAMER_REG_OPERATING_MODE,
				 SBE_2T3E3_FRAMER_VAL_LOCAL_LOOPBACK_MODE);
		break;
	}
}
