From d717b83056e5076a64c9471dd85573de409582d7 Mon Sep 17 00:00:00 2001 From: tzafrir Date: Thu, 25 Jan 2007 10:48:33 +0000 Subject: * Xbus protocol version: 2.4 (Zaptel 1.2.12/1.4.0 had 2.3). XPS Init scripts renamed accordingly. * Performance improvements for multi-XPD (span) devices. * Astribank BRI driver (in next commit). * Changes under /proc: - XBUS and XPD numbers have two digits. - Every script wildcard should be replaced from XBUS-? to XBUS-[0-9]* - Added /proc/xpp/XBUS-*/XPD-*/blink: echo 1 to start and 0 to stop. * Several countries (South Africa, UAE, anybody else) require a shorter ring delay. Adjust FXO reg 0x17 (23)'s bits 0:2 to 011. * Use tasklets to move most of the interrupt PCM copying out of the interrupt. * Debugfs-based code to dump data to userspace (used to debug BRI D channel). * Pretend every 2.6.9 actually has later RHEL's typedefs. * fpga_load supports /dev/bus/usb . * Fixed physical order sorting in genzaptelconf. git-svn-id: http://svn.digium.com/svn/zaptel/branches/1.2@1966 5390a7c7-147a-4af0-8ec9-7488f05a26cb --- xpp/init_card_7_24 | 414 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 414 insertions(+) create mode 100755 xpp/init_card_7_24 (limited to 'xpp/init_card_7_24') diff --git a/xpp/init_card_7_24 b/xpp/init_card_7_24 new file mode 100755 index 0000000..e06e8b0 --- /dev/null +++ b/xpp/init_card_7_24 @@ -0,0 +1,414 @@ +#! /usr/bin/perl -w +use strict; + +# +# $Id$ +# + +# +# Written by Oron Peled +# Copyright (C) 2006, Xorcom +# +# All rights reserved. +# +# 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. +# +# See the file LICENSE in the top level of this tarball. +# + +# This script is run from the xpp kernel module upon detection +# of a new XPD. +# +# Expects the following environment variables to be set: +# XPD_BUS - bus name +# XPD_NAME - xpd name +# XPD_UNIT - xpd unit number +# XPD_SUBUNIT - xpd subunit number +# XPD_TYPE - xpd type number (from protocol reply): +# 3 - FXS +# 4 - FXO +# 6 - BRI_TE +# 7 - BRI_NT +# XPD_REVISION - xpd revision number +# +# Output data format: +# - An optional comment start with ';' or '#' until the end of line +# - Optional Blank lines are ignored +# - Fields are whitespace separated (spaces or tabs) +# +# The fields are (in command line order): +# 1. CHIP select in decimal (ignored, taken from 3 LSB's of subunit number) +# 2. Command word: +# - RD Read Direct register. +# - RS Read Sub-register. +# - WD Write Direct register. +# - WS Write Sub-register. +# 3. Register number in hexadecimal. +# 4. Subregister number in hexadecimal. (for RS and WS commands). +# 5. Data byte in hexadecimal. (for WD and WS commands only). +# + +package main; +sub logit { + print STDERR "@_\n"; +} + +package BRI; + +sub gen { + my $fmt = shift; + printf "$fmt\n", @_; +} + +package BRI::Port; + +sub new { + my $pack = shift; + my $port = { @_ }; + bless $port, $pack; +} + +# zap_xhfc_su.c:995 +sub init_su { + my $port = shift; + my $portnum = $port->{PORT_NUM}; + my $port_mode_up = $port->{PORT_MODE_UP}; + my $port_mode_exch = $port->{PORT_MODE_EXCH}; + my $bri_nt = $port->{BRI_NT}; + #logit "init_su(portnum=$portnum, port_mode_up=$port_mode_up, bri_nt=$bri_nt)"; + + # Setting PLL + # R_PLL_CTRL = 0 (V_PLL_M = 0, Reset PLL, Disable PLL_ + # R_CLK_CFG = 05 (PLL clock as system clock, output it to CLK_OUT pin) + # R_PLL_P = 1 + # R_PLL_N = 6 + # R_PLL_S = 1 + # R_PLL_CTRL = 1 (V_PLL_M) + + BRI::gen "#--------------------------- init_su($portnum, $bri_nt, $port_mode_up, $port_mode_exch)"; + BRI::gen "0 WD 02 04"; + BRI::gen "0 WD 50 00"; # disable PLL + BRI::gen "0 WD 51 02"; + BRI::gen "0 WD 52 06"; + BRI::gen "0 WD 53 04"; + BRI::gen "0 WD 50 01"; # Enable PLL + BRI::gen "0 WD 02 05"; # Enable PLL + + su_sel($portnum); # select port + if ("$port_mode_up" == 1) { + $port->{CTRL3} = 0x01; # A_ST_CTRL3: V_ST_SEL = 1 + $port->{CTRL0} = 0x10; # A_SU_CTRL0: V_ST_SQ_EN = 1 + BRI::gen "0 WD 34 0F"; # A_MS_TX: + # (multiframe/superframe transmit register) + } else { + $port->{CTRL3} = 0x00; # A_ST_CTRL3: V_ST_SEL = 0 + $port->{CTRL0} = 0x00; # A_SU_CTRL0: V_ST_SQ_EN = 0 + } + if ("$bri_nt" == 1) { + $port->{CTRL0} |= 0x04; # V_SU_MD + } + # ((V_SU_EXCH)?0x80:00) (change polarity) + if($port_mode_exch) { + $port->{CTRL2} = 0x80; + } else { + $port->{CTRL2} = 0x00; + } + BRI::gen "0 WD 35 %02X", $port->{CTRL3}; # A_ST_CTRL3 + BRI::gen "0 WD 31 %02X", $port->{CTRL0}; # A_SU_CTRL0 + BRI::gen "0 WD 35 F8"; # A_ST_CTRL3 = set end of pulse control to 0xF8 + BRI::gen "0 WD 32 08"; # A_SU_CTRL1 = Ignore E-channel data + BRI::gen "0 WD 33 %02X", $port->{CTRL2}; # A_SU_CTRL2 + + # zap_xhfc_su.c:1030 in init_su() + # A_SU_CLK_DLY + my $clk_dly; + if ("$bri_nt" == 1) { + $clk_dly = 0x6C; + } else { + $clk_dly = 0x0E; + } + #logit "clk_dly=$clk_dly"; + BRI::gen "0 WD 37 %02X", "$clk_dly"; +} + +sub su_sel { + if (@_ != 1 ) { + main::logit "ERROR: su_sel() called with " . scalar(@_) . " parameters"; + exit 1; + } + my $portnum = shift; + BRI::gen "0 WD 16 %02X", $portnum; # R_SU_SEL +} + +# zap_xhfc_su.c:281 +sub xhfc_selfifo { + if (@_ != 1 ) { + main::logit "ERROR: xhfc_selfifo() called with " . scalar(@_) . " parameters"; + exit 1; + } + my $fifonum = shift; + #logit "xhfc_selfifo($fifonum)"; + BRI::gen "0 WD 0F %02X", $fifonum; + # --> WAIT UNTIL (R_STATUS & M_BUSY) == 0 +} + +# zap_xhfc_su.c:295 +sub xhfc_resetfifo() { + #logit "xhfc_resetfifo()"; + # A_INC_RES_FIFO = M_RES_FIFO | M_RES_FIFO_ERR + BRI::gen "0 WD 0E 0A"; + # --> WAIT UNTIL (R_STATUS & M_BUSY) == 0 +} + +# zap_xhfc_su.c:1040 +# Initialize fifo (called for each portnum, channel, direction) +sub setup_fifo { + my $port = shift; + my $chan = shift; + my $direction = shift; + my $conhdlc = shift; + my $subcfg = shift; + my $fifoctrl = shift; + + my $portnum = $port->{PORT_NUM}; + my $port_mode_up = $port->{PORT_MODE_UP}; + my $port_mode_exch = $port->{PORT_MODE_EXCH}; + my $bri_nt = $port->{BRI_NT}; + + BRI::gen "#--------------------------- setup_fifo($portnum, $chan, $direction)"; + # my $fifonum = 0x80 | ($portnum << 3) | ($chan << 1) | ($direction); # # MSB first + my $fifonum = ($portnum << 3) | ($chan << 1) | ($direction); # # MSB first + my $r_slot = ($portnum << 3) | ($chan << 1) | ($direction); + # receive data from STIO2, transmit to STIO1 + my $a_sl_cfg = (0x80 | ($portnum << 3) | ($chan << 1) | ($direction)); + + #logit "setup_fifo($fifonum)"; + xhfc_selfifo $fifonum; + # A_CON_HDLC: transparent mode selection + BRI::gen "0 WD FA %02X", $conhdlc; + # A_SUBCH_CFG: subchnl params + BRI::gen "0 WD FB %02X", $subcfg; + # A_FIFO_CTRL: FIFO Control Register + BRI::gen "0 WD FF %02X", $fifoctrl; + xhfc_resetfifo; + xhfc_selfifo $fifonum; # wait for busy is builtin in this command + BRI::gen "0 WD 10 %02X", $r_slot; # R_SLOT + BRI::gen "0 WD D0 %02X", $a_sl_cfg; # A_SL_CFG +} + +# zap_xhfc_su.c:1071 +sub setup_su { + my $port = shift; + my $bchan = shift; + my $portnum = $port->{PORT_NUM}; + my $port_mode_exch = $port->{PORT_MODE_EXCH}; + my $bri_nt = $port->{BRI_NT}; + + BRI::gen "#--------------------------- setup_su($portnum, $bchan)"; + #logit "setup_su(portnum=$portnum, bchan=$bchan, port_mode_exch=$port_mode_exch, bri_nt=$bri_nt)"; + $port->{CTRL0} |= (1 << $bchan) | $bri_nt; + $port->{CTRL2} |= ($port_mode_exch << 7) | (1 << $bchan); + su_sel($portnum); # Select port + BRI::gen "0 WD 31 %02X", $port->{CTRL0}; # A_SU_CTRL0: V_B1_TX_EN | V_SU_MD | (NT/TE) + BRI::gen "0 WD 33 %02X", $port->{CTRL2}; # A_SU_CTRL2: V_B1_RX_EN +} + +sub xhfc_ph_command { + my $port = shift; + my $cmd = shift; + my $portnum = $port->{PORT_NUM}; + #logit "xhfc_ph_command(portnum=$portnum)"; + if ("$cmd" eq "HFC_L1_ACTIVATE_TE") { + su_sel($portnum); # Select port + BRI::gen "0 WD 30 60"; # A_SU_WR_STA = (M_SU_ACT & 0x03) + # (set activation) + } elsif ("$cmd" eq "HFC_L1_FORCE_DEACTIVATE_TE") { + su_sel($portnum); # Select port + BRI::gen "0 WD 30 40"; # A_SU_WR_STA = (M_SU_ACT & 0x02) + # (set deactivation) + } elsif ("$cmd" eq "HFC_L1_ACTIVATE_NT") { + su_sel($portnum); # Select port + BRI::gen "0 WD 30 E0"; # A_SU_WR_STA = (M_SU_ACT & 0x03) | 0x80 + # (set activation + NT) + } elsif ("$cmd" eq "HFC_L1_DEACTIVATE_NT") { + su_sel($portnum); # Select port + BRI::gen "0 WD 30 40"; # A_SU_WR_STA = (M_SU_ACT & 0x02) + # (set deactivation) + } +} + + +sub zthfc_startup { + my $port = shift; + my $portnum = $port->{PORT_NUM}; + my $port_mode_exch = $port->{PORT_MODE_EXCH}; + my $bri_nt = $port->{BRI_NT}; + #logit "zthfc_startup(portnum=$portnum, port_mode_exch=$port_mode_exch, bri_nt=$bri_nt)"; + + # PCM <-> ST/Up Configuration + foreach my $chan ( 0, 1 ) { + $port->setup_fifo($chan, 0, 0xFE, 0, 0);# Transparent mode, FIFO EN, ST->PCM + $port->setup_fifo($chan, 1, 0xFE, 0, 0);# Transparent mode, FIFO EN, ST->PCM + $port->setup_su($chan); # zap_xhfc_su.c:194 + } + + # Zaptel chan 2 used as HDLC D-Channel + $port->setup_fifo(2, 0, 0x05, 2, 0); # D-TX: zap_xhfc_su.c:205 + $port->setup_fifo(2, 1, 0x05, 2, 0); # D-RX: zap_xhfc_su.c:206 + # E-chan, Echo channel is ignored + + + # enable this port's state machine + su_sel($portnum); # Select port + # A_SU_WR_STA: reset port state machine + BRI::gen "0 WD 30 00"; + if ("$bri_nt" == 0) { + $port->xhfc_ph_command("HFC_L1_ACTIVATE_TE"); + } else { + $port->xhfc_ph_command("HFC_L1_ACTIVATE_NT"); + } +} + + +package main; + +use File::Basename; +use Getopt::Std; + +my $program = basename("$0"); +my $init_dir = dirname("$0"); + +# Arrange for error logging +if (-t STDERR) { + logit "Interactive\n"; +} else { + open (STDERR, "| logger -s -t $program -p kern.info") || die; + logit "Non Interactive\n"; +} + +my %opts; +getopts('o:', \%opts); + +$ENV{XPP_BASE} = '/proc/xpp'; +my $output; +my $unit_id; +if ($opts{o}) { + $output = $opts{o}; + $unit_id = 'Interactive'; +} else { + $ENV{XPD_BUS} || die "Missing XPD_BUS environment variable\n"; + $ENV{XPD_NAME} || die "Missing XPD_NAME environment variable\n"; + $ENV{XPD_TYPE} || die "Missing XPD_TYPE environment variable\n"; + $ENV{XPD_REVISION} || die "Missing XPD_REVISION environment variable\n"; + $output = "$ENV{XPP_BASE}/$ENV{XPD_BUS}/$ENV{XPD_NAME}/slics"; + $unit_id = "$ENV{XPD_BUS}/$ENV{XPD_NAME}"; +} + +open(REG, ">$output") || die "Failed to open '$output': $!\n"; +select REG; + + +#logit "$unit_id: Starting '$0'"; + +#------------------------------------------- Instance detection + +# zap_xhfc_su.c:895 +sub init_xhfc() { + #logit "init_xhfc()"; + BRI::gen "#--------------------------- init_xhfc"; + BRI::gen "0 WD 0D 00"; # r_FIFO_MD: 16 fifos, + # 64 bytes for TX and RX each (FIFO mode config) + + # software reset to enable R_FIFO_MD setting + BRI::gen "0 WD 00 08"; # R_CIRM = M_SRES (soft reset) + # --> WAIT 5u + BRI::gen "0 WD 00 00"; # R_CIRM = 0 (zero it to deactivate reset) + + # amplitude + BRI::gen "0 WD 46 80"; # R_PWM_MD: (PWM output mode register) + # PWM push to zero only + BRI::gen "0 WD 39 18"; # R_PWM1: (modulator register for PWM1) + # set duty cycle + + BRI::gen "0 WD 0C 11"; # R_FIFO_THRES: (FIFO fill lvl control register) + # RX/TX threshold = 16 bytes + + # --> Wait until (R_STATUS & (M_BUSY | M_PCM_INIT)) + # M_BUSY status will be checked after fifo selection + BRI::gen "0 WD 0F 80"; + # set PCM !master mode + BRI::gen "0 WD 14 08"; # R_PCM_MD0 = PCM slave mode, F0IO duration is 2 HFC_PCLK's + + # (C4IO, F0IO are inputs) + + # set pll adjust + # WD 14 90 # R_PCM_MD0: Index value to select + # the register at address 15 + # WD 15 2C # R_PCM_MD1: V_PLL_ADJ (DPLL adjust speed), C4IO is 16.384MHz(128 time slots) + # in the last slot of PCM frame + BRI::gen "0 WS 14 98 20"; # R_PCM_MD1: V_PLL_ADJ + # (DPLL adjust speed) in the + # last slot of PCM frame +} + +my %port_type = ( + 6 => { 'BRI_NT' => 0 }, + 7 => { 'BRI_NT' => 1 } + ); + +# zap_xhfc_su.c:175 +sub main() { + #logit "main()"; + + $ENV{XPD_TYPE} || die "Missing XPD_TYPE environment variable\n"; + my $type = $port_type{$ENV{XPD_TYPE}}; + die "Bad XPD_TYPE=$ENV{XPD_TYPE}\n" unless $type; + die "Missing XPD_SUBUNIT information\n" unless defined($ENV{XPD_SUBUNIT}); + + # We must first turn off packet reception. + # + # Otherwise we mess with registers while the FPGA firmware tries to + # send us packets. + BRI::gen "0 Wm"; + + # Common initialization + if($ENV{XPD_SUBUNIT} eq '0') { + # Turn off multi-byte packet reception before initialization started + system("/bin/echo \"0A 00 0F 00 C0 00 00 00 00 00\" >/proc/xpp/$ENV{XPD_BUS}/command"); + system("/bin/echo \"0A 00 0F 08 C0 00 00 00 00 00\" >/proc/xpp/$ENV{XPD_BUS}/command"); + system("/bin/echo \"0A 00 0F 10 C0 00 00 00 00 00\" >/proc/xpp/$ENV{XPD_BUS}/command"); + system("/bin/echo \"0A 00 0F 18 C0 00 00 00 00 00\" >/proc/xpp/$ENV{XPD_BUS}/command"); + + init_xhfc; # zap_xhfc_su.c:1173 in setup_instance() + } + + # Port initialization + my $p = BRI::Port->new( + 'PORT_NUM' => $ENV{XPD_SUBUNIT}, + 'BRI_NT' => $type->{BRI_NT}, + 'PORT_MODE_UP' => 0, + 'PORT_MODE_EXCH' => 0 + ); + # zap_XHfc_su.c:1186 in setup_instance() + $p->init_su; + + $p->zthfc_startup; + + if($ENV{XPD_SUBUNIT} eq 3) { + # Turn on multi-byte packet reception when ports initialization finished + system("/bin/echo \"0A 00 0F 00 80 00 00 00 00 00\" >/proc/xpp/$ENV{XPD_BUS}/command"); + system("/bin/echo \"0A 00 0F 08 80 00 00 00 00 00\" >/proc/xpp/$ENV{XPD_BUS}/command"); + system("/bin/echo \"0A 00 0F 10 80 00 00 00 00 00\" >/proc/xpp/$ENV{XPD_BUS}/command"); + system("/bin/echo \"0A 00 0F 18 80 00 00 00 00 00\" >/proc/xpp/$ENV{XPD_BUS}/command"); + } +} + +main; + +#logit "$unit_id: Ending '$0'"; + +close REG; +exit 0; -- cgit v1.2.3