/* * 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 exar7300_init(struct channel *sc) { exar7300_write(sc, SBE_2T3E3_LIU_REG_REG1, 0); /* enable line decodeer and encoder */ exar7300_write(sc, SBE_2T3E3_LIU_REG_REG2, 0); exar7300_write(sc, SBE_2T3E3_LIU_REG_REG3, 0); exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, SBE_2T3E3_LIU_VAL_T3_MODE_SELECT | SBE_2T3E3_LIU_VAL_LOOPBACK_OFF); } void exar7300_set_loopback(struct channel *sc, u32 mode) { u32 val; switch (mode) { case SBE_2T3E3_LIU_VAL_LOOPBACK_OFF: case SBE_2T3E3_LIU_VAL_LOOPBACK_REMOTE: case SBE_2T3E3_LIU_VAL_LOOPBACK_ANALOG: case SBE_2T3E3_LIU_VAL_LOOPBACK_DIGITAL: break; default: return; } val = exar7300_read(sc, SBE_2T3E3_LIU_REG_REG4); val &= ~(SBE_2T3E3_LIU_VAL_LOCAL_LOOPBACK | SBE_2T3E3_LIU_VAL_REMOTE_LOOPBACK); val |= mode; exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, val); } void exar7300_set_frame_type(struct channel *sc, u32 type) { u32 val; switch (type) { case SBE_2T3E3_FRAME_TYPE_T3_CBIT: case SBE_2T3E3_FRAME_TYPE_T3_M13: case SBE_2T3E3_FRAME_TYPE_E3_G751: case SBE_2T3E3_FRAME_TYPE_E3_G832: break; default: return; } val = exar7300_read(sc, SBE_2T3E3_LIU_REG_REG4); val &= ~(SBE_2T3E3_LIU_VAL_T3_MODE_SELECT | SBE_2T3E3_LIU_VAL_E3_MODE_SELECT); switch (type) { case SBE_2T3E3_FRAME_TYPE_T3_CBIT: case SBE_2T3E3_FRAME_TYPE_T3_M13: val |= SBE_2T3E3_LIU_VAL_T3_MODE_SELECT; break; case SBE_2T3E3_FRAME_TYPE_E3_G751: case SBE_2T3E3_FRAME_TYPE_E3_G832: val |= SBE_2T3E3_LIU_VAL_E3_MODE_SELECT; break; default: return; } exar7300_write(sc, SBE_2T3E3_LIU_REG_REG4, val); } void exar7300_transmit_all_ones_onoff(struct channel *sc, u32 mode) { if (sc->p.transmit_all_ones == mode) return; switch (mode) { case SBE_2T3E3_ON: exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1, SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES); break; case SBE_2T3E3_OFF: exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1, SBE_2T3E3_LIU_VAL_TRANSMIT_ALL_ONES); break; default: return; } sc->p.transmit_all_ones = mode; } void exar7300_receive_equalization_onoff(struct channel *sc, u32 mode) { if (sc->p.receive_equalization == mode) return; switch (mode) { case SBE_2T3E3_OFF: exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG2, SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE); break; case SBE_2T3E3_ON: exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG2, SBE_2T3E3_LIU_VAL_RECEIVE_EQUALIZATION_DISABLE); break; default: return; } sc->p.receive_equalization = mode; } void exar7300_line_build_out_onoff(struct channel *sc, u32 mode) { if (sc->p.line_build_out == mode) return; switch (mode) { case SBE_2T3E3_OFF: exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1, SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT); exar7300_receive_equalization_onoff(sc, SBE_2T3E3_OFF); break; case SBE_2T3E3_ON: exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1, SBE_2T3E3_LIU_VAL_TRANSMIT_LEVEL_SELECT); exar7300_receive_equalization_onoff(sc, SBE_2T3E3_ON); break; default: return; } sc->p.line_build_out = mode; } /* TODO - what about encoder in raw mode??? disable it too? */ void exar7300_unipolar_onoff(struct channel *sc, u32 mode) { switch (mode) { case SBE_2T3E3_OFF: exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG3, SBE_2T3E3_LIU_VAL_DECODER_DISABLE); exar7300_clear_bit(sc, SBE_2T3E3_LIU_REG_REG1, SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA); break; case SBE_2T3E3_ON: exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG3, SBE_2T3E3_LIU_VAL_DECODER_DISABLE); exar7300_set_bit(sc, SBE_2T3E3_LIU_REG_REG1, SBE_2T3E3_LIU_VAL_TRANSMIT_BINARY_DATA); break; } }