[zaptel-commits] branch 1.2 r949 - in /branches/1.2: ./ xpp/
zaptel-commits at lists.digium.com
zaptel-commits at lists.digium.com
Tue Feb 14 19:24:21 MST 2006
Author: kpfleming
Date: Tue Feb 14 20:24:18 2006
New Revision: 949
URL: http://svn.digium.com/view/zaptel?rev=949&view=rev
Log:
initial import of Xorcom Astribank driver (issue #6452, with minor mods)
Added:
branches/1.2/README.Astribank (with props)
branches/1.2/xpp/
branches/1.2/xpp/FPGA_XPD.hex (with props)
branches/1.2/xpp/Makefile (with props)
branches/1.2/xpp/card_fxs.c (with props)
branches/1.2/xpp/card_fxs.h (with props)
branches/1.2/xpp/card_global.c (with props)
branches/1.2/xpp/card_global.h (with props)
branches/1.2/xpp/cards.c (with props)
branches/1.2/xpp/cards.h (with props)
branches/1.2/xpp/gen_slic_init (with props)
branches/1.2/xpp/slic.c (with props)
branches/1.2/xpp/slic.h (with props)
branches/1.2/xpp/slic_init.inc (with props)
branches/1.2/xpp/sync.sh (with props)
branches/1.2/xpp/xdefs.h (with props)
branches/1.2/xpp/xpd.h (with props)
branches/1.2/xpp/xpp_fxloader (with props)
branches/1.2/xpp/xpp_fxloader.usermap (with props)
branches/1.2/xpp/xpp_modprobe (with props)
branches/1.2/xpp/xpp_proto.c (with props)
branches/1.2/xpp/xpp_proto.h (with props)
branches/1.2/xpp/xpp_usb.c (with props)
branches/1.2/xpp/xpp_zap.c (with props)
branches/1.2/xpp/xpp_zap.h (with props)
branches/1.2/xpp/xproto.c (with props)
branches/1.2/xpp/xproto.h (with props)
branches/1.2/xpp/zap_debug.c (with props)
branches/1.2/xpp/zap_debug.h (with props)
Modified:
branches/1.2/Makefile
Modified: branches/1.2/Makefile
URL: http://svn.digium.com/view/zaptel/branches/1.2/Makefile?rev=949&r1=948&r2=949&view=diff
==============================================================================
--- branches/1.2/Makefile (original)
+++ branches/1.2/Makefile Tue Feb 14 20:24:18 2006
@@ -1,7 +1,7 @@
#
# Makefile for Zaptel driver modules and utilities
#
-# Copyright (C) 2001-2005 Digium, Inc.
+# Copyright (C) 2001-2006 Digium, Inc.
#
#
BASEADDR=0xd0000
@@ -120,6 +120,7 @@
LIBTONEZONE_SO:=libtonezone.so
LIBTONEZONE_SO_MAJOR_VER:=1
LIBTONEZONE_SO_MINOR_VER:=0
+
MODULES:=zaptel tor2 torisa wcusb wcfxo wctdm wctdm24xxp \
ztdynamic ztd-eth wct1xxp wct4xxp wcte11xp pciradio \
ztd-loc # ztdummy
@@ -128,8 +129,17 @@
ifeq (${BUILDVER},linux26)
MODULES+=ztdummy
endif
+
MODULESO:=$(MODULES:%=%.o)
MODULESKO:=$(MODULES:%=%.ko)
+
+MOD_DESTDIR:=zaptel
+
+obj-m:=$(MODULESO) ${XPPMOD}
+
+ifneq ($(filter xpp,${MAKECMDGOALS}),)
+XPPMOD=xpp/
+endif
ifneq (,$(wildcard /usr/include/newt.h))
ZTTOOL:=zttool
@@ -148,15 +158,13 @@
linux26: prereq $(BINS)
@echo $(KSRC)
@if [ -z "$(KSRC)" -o ! -d "$(KSRC)" ]; then echo "You do not appear to have the sources for the $(KVERS) kernel installed."; exit 1 ; fi
- $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) modules
-
-obj-m := $(MODULESO)
+ $(MAKE) -C $(KSRC) SUBDIRS=$(PWD) XPPMOD=$(XPPMOD) modules
+
+xpp: linux26
#ifneq ($(TOPDIR),)
#include $(TOPDIR)/Rules.make
#endif
-
-MOD_DESTDIR:=zaptel
version.h: FORCE
ZAPTELVERSION="${ZAPTELVERSION}" build_tools/make_version_h > $@.tmp
@@ -471,6 +479,8 @@
rm -f *.o ztcfg tzdriver sethdlc sethdlc-new
rm -f $(TZOBJS) $(LIBTONEZONE_SO) *.lo
rm -f *.ko *.mod.c .*o.cmd
+ rm -f xpp/*.ko xpp/*.mod.c xpp/.*o.cmd
+ rm -f xpp/*.o xpp/*.mod.o
rm -rf .tmp_versions
rm -f gendigits tones.h
rm -f libtonezone*
Added: branches/1.2/README.Astribank
URL: http://svn.digium.com/view/zaptel/branches/1.2/README.Astribank?rev=949&view=auto
==============================================================================
--- branches/1.2/README.Astribank (added)
+++ branches/1.2/README.Astribank Tue Feb 14 20:24:18 2006
@@ -1,0 +1,135 @@
+This file documents the Zaptel drivers for the Xorcom Astribank8 Channel Bank.
+The drivers reside in a separate subdirectory, xpp/ .
+
+
+Building and Installation:
+"""""""""""""""""""""""""
+Building and installation is basically like the normal procedure of
+installing Zaptel. Follow the rest of the documentation here.
+
+In addition, the file xpp/xpp_modprobe contains modprobe settings. It
+should be copied verbatim into /etc/modprobe.conf or (better) copied to
+/etc/modprobe.d/ . If you fail to do so, xpp_usb.ko will fail to load
+xpd_fxs.ko and as a result will not detect your Astribank.
+
+Loading Firmware
+""""""""""""""""
+The Astribank needs a firmware loaded into it. Without the firmware,
+the device will appear in lsusb with vendor ID 04b4 and product ID 8613
+The firmware is provided in the Intel hex format. It can be loaded using
+the program fxload, which is typically part of the package 'fxload' or
+'hotplug-utils' .
+
+To load the firmware automatically using the standard hotplug script,
+place xpp/xpp_fxloader and xpp/xpp_fxloader.usermap in /etc/hotplug/usb
+and place xpp/FPGA_XPD.hex in /etc/xortel (or edit xpp_fxloader
+accordingly).
+
+Alternatively, xpp_fxloader when given the parameter 'xppdetect' will load
+the firmware from /etc/xortel/FPGA_XPD.hex . You can use it to load the
+firmware manually.
+
+You should then get in lsusb the vendor ID e4e4 and device ID 2121
+(those IDs are temporary and likely to change in upcoming versions).
+Once there is such a device, the xpp_usb driver should load
+automatically on hot-plugging. In fact, you may find it simpler to
+disconnect and reconnect the device than running 'modprobe xpp_usb'.
+
+
+The driver has been separated into several modules: xpp.ko, xpd_fxs.ko and
+xpp_usb.ko . Generally you only need to modprobe xpp_usb, and it should also
+be loaded by hotplug when you connect the Astribank. However in order for it
+to load xpd_fks.ko correctly
+
+Refer to the instructions for Zaptel. After our small patches were applies,
+you get xpp.ko which is basically yet another zaptel driver, like wcfxo
+and wctdm.
+
+When loaded, you should get one span, of 8 extensions, 2 output ports and
+4 input ports:
+
+ root at rapid:~# cat /proc/zaptel/2
+ Span 1: XBUS-0/XPD-0 "Xorcom XPD #0/0: FXS" NOTOPEN
+
+ 1 XPP_FXS/0-0 FXOKS (In use)
+ 2 XPP_FXS/0-1 FXOKS (In use)
+ 3 XPP_FXS/0-2 FXOKS (In use)
+ 4 XPP_FXS/0-3 FXOKS (In use)
+ 5 XPP_FXS/0-4 FXOKS (In use)
+ 6 XPP_FXS/0-5 FXOKS (In use)
+ 7 XPP_FXS/0-6 FXOKS (In use)
+ 8 XPP_FXS/0-7 FXOKS (In use)
+ 9 XPP_OUT/0-8 FXOKS (In use)
+ 10 XPP_OUT/0-9 FXOKS (In use)
+ 11 XPP_IN/0-10 FXOKS (In use)
+ 12 XPP_IN/0-11 FXOKS (In use)
+ 13 XPP_IN/0-12 FXOKS (In use)
+ 14 XPP_IN/0-13 FXOKS (In use)
+
+For such a simple case you could use:
+
+/etc/zaptel.conf:
+
+fxoks=1-14
+loadzone=us
+tonezone=us
+
+/etc/asterisk/zapata.conf:
+
+[channels]
+group=1
+signalling=fxo_ks
+immediate=no
+
+context=from-internal
+channels => 1-8
+
+; actually they will never generate calls, so the context
+; here is irrelevant
+;context=outputs
+channels => 9-10
+
+; input ports should get an answer:
+immediate=yes
+context=inputs
+channels => 11-14
+
+;;;;;; end of zapata.conf
+
+
+/proc Interface
+"""""""""""""""
+The Astribank drivers provide their own /proc interface under /proc/xpp .
+(Note that the details of this interface are still potentially subject to
+changes)
+
+/proc/xpp/xbuses lists the connected devices (an xbus is such a device),
+one per line. A device is normally "connected". "missing" means that it
+was disconnected, but Asterisk still holds channels from it open. You can
+also see in the xbuses file to which physical connection the Astribank
+is connected.
+
+/proc/xpp/sync is a read/write file . It prints the current
+synchronization source. printing to it can change the synchronization
+source. Host-synchronization is currently the default but for better
+sound quality you should synchronize from the Astribank.
+
+/proc/xpp/XBUS-n gives information about device number n (starting from
+0). under it, /proc/XBUS-n/XPD-m gives information regarding span number
+m in that device.
+
+/proc/xpp/XBUS-n/XPD-m/zt_registration is a read-write file for
+manually registering/unregistering the span with Zaptel. A span will
+register automatically when generated, though. Span unregistration may
+fail if some channels from the span are used (e.g: by Asterisk).
+Registration is by writing 1 and unregistration is by writing 0 to the
+file.
+
+(There are a bunch of other status files under /proc/xpp/ )
+
+
+
+BTW: XPP here does not stand for X Printing Panel, XML Pull Parser,
+X-Windows Phase Plane or XML Professional Publisher. It is simply the
+Xorcom Peripheral Protocol, which connects a computer to a XPD (Xorcom
+Peripheral Device).
Propchange: branches/1.2/README.Astribank
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/1.2/README.Astribank
------------------------------------------------------------------------------
svn:keywords = Author Id Date Revision
Propchange: branches/1.2/README.Astribank
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/1.2/xpp/FPGA_XPD.hex
URL: http://svn.digium.com/view/zaptel/branches/1.2/xpp/FPGA_XPD.hex?rev=949&view=auto
==============================================================================
--- branches/1.2/xpp/FPGA_XPD.hex (added)
+++ branches/1.2/xpp/FPGA_XPD.hex Tue Feb 14 20:24:18 2006
@@ -1,0 +1,243 @@
+:0A0B3C000001020203030404050592
+:100546005010C0C0F9A4B0999282F880988883C6EA
+:03055600A1868EED
+:1002B700E4F513F512F511F510C203C200C202C22C
+:1002C700011206377E077F008E238F24752B077553
+:1002D7002C1275210775221C752907752A4A752D59
+:1002E70007752E78EE54C070030203B875140075B5
+:1002F70015808E168F17C374C09FFF74079ECF2477
+:1003070002CF3400FEE48F0F8E0EF50DF50CF50BC2
+:10031700F50AF509F508AF0FAE0EAD0DAC0CAB0B3A
+:10032700AA0AA909A808C3120B205033E517250B01
+:10033700F582E516350AF583E0FFE515250BF5820D
+:10034700E514350AF583EFF0E50B2401F50BE435E9
+:100357000AF50AE43509F509E43508F50880B78593
+:10036700142385152474002480FF740734FFFEC30B
+:10037700E52C9FF52CE52B9EF52BC3E5269FF5264F
+:10038700E5259EF525C3E5289FF528E5279EF52752
+:10039700C3E5229FF522E5219EF521C3E52A9FF5B6
+:1003A7002AE5299EF529C3E52E9FF52EE52D9EF515
+:1003B7002DD2E843D82090E668E0440BF090E65C45
+:1003C700E0443DF0000000000000E4F5A20000005A
+:1003D700D2AF90E680E020E105D2041206D090E685
+:1003E70080E054F7F0538EF8C20390E6C2E054FB66
+:1003F700F000000000000090E6187410F000000004
+:1004070090E61A7408F000000090E6017403F0000B
+:100417000000300105120080C2013003F5120B5AAB
+:1004270050F0C203120A7B20001690E682E030E704
+:1004370004E020E1EF90E682E030E604E020E0E42B
+:080447001209FC120B5C80CAD3
+:0B0B310090E50DE030E402C322D32267
+:1000800090E6B9E0700302013F1470030201BC2442
+:10009000FE700302023F24FB700302013914700357
+:1000A00002013314700302012714700302012D248E
+:1000B0000560030202A3120B5E40030202AF90E64A
+:1000C000BBE024FE602714603824FD601114602713
+:1000D00024067050E52390E6B3F0E524803C120B33
+:1000E00031503EE52B90E6B3F0E52C802DE52590D0
+:1000F000E6B3F0E5268023E52790E6B3F0E5288017
+:100100001990E6BAE0FF120A28AA06A9077B01EABD
+:10011000494B600DEE90E6B3F0EF90E6B4F00202CA
+:10012000AF02029E02029E120B0E0202AF120B4E93
+:100130000202AF120B460202AF120AFC0202AF1219
+:100140000B6040030202AF90E6B8E0247F60151414
+:10015000601924027063A200E43325E0FFA202E4E8
+:10016000334F8041E490E740F0803F90E6BCE0549C
+:100170007EFF7E00E0D394807C0040047D018002FD
+:100180007D00EC4EFEED4F243CF582740B3EF58372
+:10019000E493FF3395E0FEEF24A1FFEE34E68F8277
+:1001A000F583E0540190E740F0E4A3F090E68AF094
+:1001B00090E68B7402F00202AF02029E120B6240C4
+:1001C000030202AF90E6B8E024FE6016240260034A
+:1001D0000202AF90E6BAE0B40105C2000202AF022B
+:1001E000029E90E6BAE0705590E6BCE0547EFF7E39
+:1001F00000E0D394807C0040047D0180027D00EC0F
+:100200004EFEED4F243CF582740B3EF583E493FFE4
+:100210003395E0FEEF24A1FFEE34E68F82F583E014
+:1002200054FEF090E6BCE05480131313541FFFE01B
+:10023000540F2F90E683F0E04420F08072805F122C
+:100240000B64506B90E6B8E024FE60192402704EF7
+:1002500090E6BAE0B40104D200805490E6BAE064BB
+:1002600002604C803990E6BCE0547EFF7E00E0D313
+:1002700094807C0040047D0180027D00EC4EFEED08
+:100280004F243CF582740B3EF583E493FF3395E0F5
+:10029000FEEF24A1FFEE34E68F82F583800D90E619
+:1002A000A08008120A53500790E6A0E04401F090A5
+:0602B000E6A0E04480F02E
+:0102B6002225
+:03003300020B5667
+:040B560053D8EF324F
+:100700001201000200000040E4E411220000010296
+:1007100000010A06000200000040010009022E004C
+:1007200001010080320904000004FF0000000705F9
+:10073000020200020007050402000200070586020B
+:100740000002000705880200020009022E000101D4
+:100750000080320904000004FF00000007050202C7
+:100760004000000705040240000007058602400023
+:100770000007058802400000040309041C0341002F
+:100780007300740072006900620061006E006B000B
+:10079000320030003000360028035800500044007A
+:1007A00028004200610073006500640020006F00B3
+:1007B0006E002000410058005500500050002900F4
+:0207C000000037
+:100559005010B0C0F9A4B0999282F880988883C6E7
+:10056900A1868E4110ABFF4110AD004110AEFF4195
+:0705790010AC004110AF00BF
+:1006370090E600E054E74410F000000090E60474F0
+:1006470080F00000007406F0000000E4F0000000F5
+:1006570090E610F090E611F000000090E613F0002D
+:10066700000090E615F090E61074A0F090E611F007
+:1006770000000000000090E61274AAF0000000904D
+:10068700E61474EAF000000090E6047480F00000BD
+:10069700007404F0000000E4F000000090E64974E4
+:1006A70082F0000000F000000090E6187410F000DF
+:1006B700000090E61A7408F090E6917480F000004C
+:0906C70000F000000043AF012225
+:020B5A00D322A4
+:020B5C00D322A2
+:020B5E00D322A0
+:080B460090E6BAE0F51BD32292
+:100AFC0090E740E51BF0E490E68AF090E68B04F07A
+:020B0C00D322F2
+:080B4E0090E6BAE0F51AD3228B
+:100B0E0090E740E51AF0E490E68AF090E68B04F068
+:020B1E00D322E0
+:020B6000D3229E
+:020B6200D3229C
+:020B6400D3229A
+:100A530090E6B9E0242F600D04701990E604E0FFDE
+:100A6300430780800890E604E0FF53077F000000FF
+:070A7300EFF08002D322C363
+:010A7A002259
+:100AA000C0E0C083C082D2015391EF90E65D740133
+:080AB000F0D082D083D0E032C7
+:100AD000C0E0C083C0825391EF90E65D7404F0D013
+:060AE00082D083D0E03259
+:100AE600C0E0C083C0825391EF90E65D7402F0D0FF
+:060AF60082D083D0E03243
+:1009C600C0E0C083C082852925852A2685268285A2
+:1009D6002583A37402F08521278522288528828510
+:1009E6002783A37407F05391EF90E65D7410F0D05F
+:0609F60082D083D0E03244
+:100AB800C0E0C083C082D2035391EF90E65D740812
+:080AC800F0D082D083D0E032AF
+:1007C200C0E0C083C08290E680E030E7208521252A
+:1007D200852226852682852583A37402F085292712
+:1007E200852A28852882852783A37407F05391EFF1
+:0D07F20090E65D7420F0D082D083D0E0321C
+:0106FF0032C8
+:0107FF0032C7
+:010B6600325C
+:010B6700325B
+:010B6800325A
+:010B69003259
+:010B6A003258
+:010B6B003257
+:010B6C003256
+:010B6D003255
+:010B6E003254
+:010B6F003253
+:010B70003252
+:010B71003251
+:010B72003250
+:010B7300324F
+:010B7400324E
+:010B7500324D
+:010B7600324C
+:010B7700324B
+:010B7800324A
+:010B79003249
+:010B7A003248
+:010B7B003247
+:010B7C003246
+:010B7D003245
+:010B7E003244
+:010B7F003243
+:010B80003242
+:010B81003241
+:010B82003240
+:010B8300323F
+:010B8400323E
+:010B8500323D
+:10098A00C0E0C083C08290E6D1E09010ACF090E65F
+:10099A00D0E4F000000090E6D17402F000000053A9
+:1009AA0091BF00000090E66104F000000090E69913
+:0C09BA0004F075BB06D082D083D0E03280
+:010B8600323C
+:03004300020800B0
+:03005300020800A0
+:10080000020AA000020AE600020AD000020AB800AA
+:100810000209C6000207C2000206FF000207FF002D
+:10082000020B6600020B6700020B6800020B6900F6
+:10083000020B6A00020B6B00020B6C00020B6D00D6
+:10084000020B6E000207FF00020B6F00020B70002C
+:10085000020B7100020B7200020B7300020B74009A
+:10086000020B75000207FF000207FF000207FF00EE
+:10087000020B7600020B7700020B7800020B790066
+:10088000020B7A00020B7B00020B7C00020B7D0046
+:10089000020B7E00020B7F00020B8000020B810026
+:1008A000020B8200020B8300020B8400020B850006
+:0808B00002098A00020B860018
+:1009FC0090E682E030E004E020E60B90E682E03006
+:100A0C00E119E030E71590E680E04401F07F147EB8
+:0C0A1C000012094490E680E054FEF02235
+:1006D00030040990E680E0440AF0800790E680E06C
+:1006E0004408F07FDC7E0512094490E65D74FFF05B
+:0F06F00090E65FF05391EF90E680E054F7F02230
+:020A2800A9071C
+:100A2A00AE2DAF2E8F828E83A3E064037017AD01C3
+:100A3A0019ED7001228F828E83E07C002FFDEC3E3F
+:080A4A00FEAF0580DFE4FEFFB2
+:010A52002281
+:100A7B0090E682E044C0F090E681F04387010000ED
+:040A8B000000002245
+:100944008E188F1990E600E054187012E5192401EE
+:10095400FFE43518C313F518EF13F519801590E665
+:1009640000E05418FFBF100BE51925E0F519E51850
+:1009740033F518E5191519AE18700215184E6005EF
+:06098400120A8F80EE2232
+:100A8F007400F58690FDA57C05A3E582458370F97A
+:010A9F002234
+:1005800060801000011113213C01010703030305E2
+:10059000010000000C0D0C0C0E0E0E0E410000367A
+:1005A0000900003F010A013B0101010701010201AD
+:1005B0000000000002020000020202024049004066
+:1005C0000000003F010101010101010700000000DE
+:1005D000000000000E0E0E0E0E0E0E0E00000000AB
+:1005E0000000003F0139010101010107000302027F
+:1005F000020202020E0E0E0E0E0E0E0E002D000056
+:100600000000003F60241087000000000000000090
+:1006100000000000000000000000833611170004F5
+:10062000030201813616170004030201471080E01F
+:0606300000000ECE4E009A
+:10044F0090E60174CEF090E6F574FFF0901080E026
+:10045F0090E6F3F0901081E090E6C3F0901082E008
+:10046F0090E6C1F0901083E090E6C2F0901085E026
+:10047F0090E6C0F0901086E090E6F4F075AF077448
+:10048F0010F59A7400F59B759DE4E4F59EFF90E6D8
+:10049F007BE090E67CF00FBF80F490E67174FFF084
+:1004AF00F5B490E672E04480F043B680000000E4BB
+:1004BF0090E6C4F000000090E6C5F0901087E09041
+:1004CF00E6C6F0901088E090E6C7F0901089E090B3
+:1004DF00E6C8F090108AE090E6C9F090108BE0909B
+:1004EF00E6CAF090108CE090E6CBF090108DE09083
+:1004FF00E6CCF090108EE090E6CDF000000090E694
+:10050F00D27401F000000090E6E204F00000000059
+:10051F00000090E6EB14F000000000000000000067
+:10052F0090E6C0F090E6C1F090E6247408F0000069
+:06053F0000E490E625F047
+:010545002293
+:030000000208B83B
+:0C08B800787FE4F6D8FD75812E0208FF61
+:100B2000EB9FF5F0EA9E42F0E99D42F0E89C45F02B
+:010B300022A2
+:1008C4000202B7E493A3F8E493A34003F68001F291
+:1008D40008DFF48029E493A3F85407240CC8C33335
+:1008E400C4540F4420C8834004F456800146F6DF04
+:1008F400E4800B0102040810204080900546E47E49
+:10090400019360BCA3FF543F30E509541FFEE493F8
+:10091400A360010ECF54C025E060A840B8E493A3BF
+:10092400FAE493A3F8E493A3C8C582C8CAC583CAEA
+:10093400F0A3C8C582C8CAC583CADFE9DEE780BEA2
+:0106360000C3
+:00000001FF
Propchange: branches/1.2/xpp/FPGA_XPD.hex
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/1.2/xpp/FPGA_XPD.hex
------------------------------------------------------------------------------
svn:keywords = Author Id Date Revision
Propchange: branches/1.2/xpp/FPGA_XPD.hex
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/1.2/xpp/Makefile
URL: http://svn.digium.com/view/zaptel/branches/1.2/xpp/Makefile?rev=949&view=auto
==============================================================================
--- branches/1.2/xpp/Makefile (added)
+++ branches/1.2/xpp/Makefile Tue Feb 14 20:24:18 2006
@@ -1,0 +1,5 @@
+EXTRA_CFLAGS = -I$(src)/.. -DSOFT_SIMULATOR=0
+
+obj-m = xpd_fxs.o xpp.o xpp_usb.o
+xpp-y += xproto.o card_global.o xpp_zap.o zap_debug.o
+xpd_fxs-y += card_fxs.o slic.o
Propchange: branches/1.2/xpp/Makefile
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/1.2/xpp/Makefile
------------------------------------------------------------------------------
svn:keywords = Author Id Date Revision
Propchange: branches/1.2/xpp/Makefile
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: branches/1.2/xpp/card_fxs.c
URL: http://svn.digium.com/view/zaptel/branches/1.2/xpp/card_fxs.c?rev=949&view=auto
==============================================================================
--- branches/1.2/xpp/card_fxs.c (added)
+++ branches/1.2/xpp/card_fxs.c Tue Feb 14 20:24:18 2006
@@ -1,0 +1,703 @@
+/*
+ * Written by Oron Peled <oron at actcom.co.il>
+ * Copyright (C) 2004-2005, 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.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include "xpd.h"
+#include "xproto.h"
+#include "xpp_zap.h"
+#include <linux/delay.h>
+
+static const char rcsid[] = "$Id$";
+static const char revision[] = "$Revision$";
+
+DEF_PARM(int, print_dbg, 1, "Print DBG statements"); /* must be before zap_debug.h */
+
+#define LINES_REGULAR 8
+#define LINES_DIGI_OUT 2
+#define LINES_DIGI_INP 4
+
+#define MASK_BITS(b) ((1U << (b)) - 1)
+
+#define MASK_DIGI_OUT (MASK_BITS(LINES_DIGI_OUT) << LINES_REGULAR)
+#define MASK_DIGI_INP (MASK_BITS(LINES_DIGI_INP) << (LINES_REGULAR + LINES_DIGI_OUT))
+
+/*---------------- FXS Protocol Commands ----------------------------------*/
+
+/* 0x0F */ DECLARE_CMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on);
+/* 0x0F */ DECLARE_CMD(FXS, CHAN_POWER, xpp_line_t lines, bool on);
+/* 0x0F */ DECLARE_CMD(FXS, CHAN_CID, xpp_line_t lines);
+/* 0x0F */ DECLARE_CMD(FXS, RING, int pos, bool on);
+/* 0x0F */ DECLARE_CMD(FXS, SETHOOK, xpp_line_t hook_status);
+/* 0x0F */ DECLARE_CMD(FXS, LED, xpp_line_t lines, byte which, bool on);
+/* 0x0F */ DECLARE_CMD(FXS, RELAY_OUT, byte which, bool on);
+/* 0x0F */ DECLARE_CMD(FXS, SLIC_INIT);
+/* 0x0F */ DECLARE_CMD(FXS, SLIC_QUERY, int pos, byte reg_num);
+
+static bool fxs_packet_is_valid(xpacket_t *pack);
+static void fxs_packet_dump(xpacket_t *pack);
+static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data);
+static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data);
+
+#define S_(s,l,...) \
+ { \
+ .lines = s, \
+ { \
+ .len = l, \
+ .data = { __VA_ARGS__ }, \
+ } \
+ }
+struct slic_init_data {
+ xpp_line_t lines;
+ slic_data_t slic_data;
+} slic_init_data[] = {
+#include "slic_init.inc"
+};
+#undef S_
+
+#define PROC_SLIC_FNAME "slics"
+
+struct FXS_priv_data {
+ struct proc_dir_entry *xpd_slic;
+ slic_reply_t last_reply;
+};
+
+/*---------------- FXS: Methods -------------------------------------------*/
+
+static xpd_t *FXS_card_new(xbus_t *xbus, int xpd_num, const xproto_table_t *proto_table, byte revision)
+{
+ xpd_t *xpd = NULL;
+ int channels = min(8, CHANNELS_PERXPD);
+
+ if(xpd_num == 0)
+ channels += 6; /* 2 DIGITAL OUTPUTS, 4 DIGITAL INPUTS */
+ xpd = xpd_alloc(sizeof(struct FXS_priv_data), xbus, xpd_num, proto_table, channels, revision);
+ if(!xpd)
+ return NULL;
+ if(xpd_num == 0) {
+ DBG("First XPD on %s detected. Initialize digital outputs/inputs\n", xbus->busname);
+ xpd->digital_outputs = MASK_DIGI_OUT;
+ xpd->digital_inputs = MASK_DIGI_INP;
+ }
+ xpd->direction = TO_PHONE;
+ return xpd;
+}
+
+static int FXS_card_init(xbus_t *xbus, xpd_t *xpd)
+{
+ struct FXS_priv_data *priv;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ CALL_PROTO(FXS, SLIC_INIT, xbus, xpd);
+#ifdef CONFIG_PROC_FS
+ DBG("Creating SLICs file for %s/%s\n", xbus->busname, xpd->xpdname);
+ priv->xpd_slic = create_proc_entry(PROC_SLIC_FNAME, 0644, xpd->proc_xpd_dir);
+ if(!priv->xpd_slic) {
+ ERR("Failed to create proc file for SLICs of %s/%s\n", xbus->busname, xpd->xpdname);
+ goto out;
+ }
+ priv->xpd_slic->write_proc = proc_xpd_slic_write;
+ priv->xpd_slic->read_proc = proc_xpd_slic_read;
+ priv->xpd_slic->data = xpd;
+out:
+#endif
+ return 0;
+}
+
+static int FXS_card_remove(xbus_t *xbus, xpd_t *xpd)
+{
+ struct FXS_priv_data *priv;
+
+ BUG_ON(!xpd);
+ priv = xpd->priv;
+ DBG("%s/%s\n", xbus->busname, xpd->xpdname);
+#ifdef CONFIG_PROC_FS
+ if(priv->xpd_slic) {
+ DBG("Removing xpd SLIC file %s/%s\n", xbus->busname, xpd->xpdname);
+ remove_proc_entry(PROC_SLIC_FNAME, xpd->proc_xpd_dir);
+ }
+#endif
+ return 0;
+}
+
+/*
+ * INPUT polling is done via SLIC register 0x06 (same as LEDS):
+ * 7 6 5 4 3 2 1 0
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | I1 | I3 | | | I2 | I4 | | |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ *
+ */
+static int input_channels[] = { 6, 7, 2, 3 }; // Slic numbers of input relays
+
+static void poll_inputs(xbus_t *xbus, xpd_t *xpd)
+{
+ int i;
+
+ for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
+ int pos = input_channels[i];
+
+ CALL_PROTO(FXS, SLIC_QUERY, xbus, xpd, pos, 0x06);
+ }
+}
+
+static int FXS_card_tick(xbus_t *xbus, xpd_t *xpd)
+{
+ static int rate_limit = 0;
+
+ if((rate_limit++ % 1000) == 0) {
+ poll_inputs(xbus, xpd);
+ }
+ return 0;
+}
+
+/*---------------- FXS: HOST COMMANDS -------------------------------------*/
+
+/* 0x0F */ HOSTCMD(FXS, CHAN_ENABLE, xpp_line_t lines, bool on)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ slic_cmd_t *sc;
+ int len;
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
+ lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!lines) {
+ return 0;
+ }
+ DBG("Channel Activation: 0x%4X %s\n", lines, (on) ? "on" : "off");
+ XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
+ sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
+ len = slic_cmd_direct_write(sc, lines, 0x40, (on)?0x01:0x00);
+ pack->datalen = len;
+
+ packet_send(xbus, pack);
+ return ret;
+}
+
+/* 0x0F */ HOSTCMD(FXS, CHAN_POWER, xpp_line_t lines, bool on)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ slic_cmd_t *sc;
+ int len;
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
+ lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!lines) {
+ return 0;
+ }
+ DBG("Channel Power: 0x%04X %s\n", lines, (on) ? "up" : "down");
+ XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
+ sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
+ if(on) {
+ // Power up
+ len = slic_cmd_direct_write(sc, lines, 0x42, 0x06);
+ } else {
+ // Power down
+ len = slic_cmd_direct_write(sc, lines, 0x42, 0x00);
+ }
+ pack->datalen = len;
+
+ packet_send(xbus, pack);
+ return ret;
+}
+
+/* 0x0F */ HOSTCMD(FXS, CHAN_CID, xpp_line_t lines)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ slic_cmd_t *sc;
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
+ lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!lines) {
+ return 0;
+ }
+ DBG("Channel CID: 0x%04X\n", lines);
+ XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
+ sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
+ pack->datalen = slic_cmd_direct_write(sc, lines, 0x40, 0x02);
+ packet_send(xbus, pack);
+ return ret;
+}
+
+
+/* 0x0F */ HOSTCMD(FXS, RING, int pos, bool on)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ slic_cmd_t *sc;
+ xpp_line_t mask = (1 << pos);
+ int len;
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
+ mask &= xpd->enabled_chans; // Ignore disabled channels
+ if(!mask) {
+ return 0;
+ }
+ DBG("%s pos=%d %s\n", xpd->xpdname, pos, (on) ? "on" : "off");
+ XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
+ sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
+ len = slic_cmd_direct_write(sc, mask, 0x40, (on)?0x04:0x01);
+ pack->datalen = len;
+
+ packet_send(xbus, pack);
+ return ret;
+}
+
+/* 0x0F */ HOSTCMD(FXS, SETHOOK, xpp_line_t hook_status)
+{
+ DBG("\n");
+ return 0;
+}
+
+/*
+ * LED control is done via SLIC register 0x06:
+ * 7 6 5 4 3 2 1 0
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ * | MR | MG | MB | R | OG | OB | G | B |
+ * +-----+-----+-----+-----+-----+-----+-----+-----+
+ *
+ * B - BLUE LED (0 - OFF, 1 - ON)
+ * G - GREEN LED (0 - OFF, 1 - ON)
+ * OB - Output BLUE (this line is output)
+ * OG - Output GREEN (this line is output)
+ * R - RED LED (0 - OFF, 1 - ON)
+ * MB - Mask BLUE. (1 - B effect the BLUE LED)
+ * MR - Mask RED. (1 - R effect the RED LED)
+ * MG - Mask GREEN. (1 - G effect the GREEN LED)
+ *
+ * The BLUE LED (actually a relay out) is connected to line 0 and 4 only.
+ */
+
+// GREEN RED BLUE
+static const int led_mask[NUM_LEDS] = { BIT(7), BIT(6), BIT(5) };
+static const int led_vals[NUM_LEDS] = { BIT(4), BIT(1), BIT(0) };
+
+/* 0x0F */ HOSTCMD(FXS, LED, xpp_line_t lines, byte which, bool on)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ slic_cmd_t *sc;
+ int len;
+ int value;
+ int i;
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
+ lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!lines) {
+ return 0;
+ }
+ DBG("LED: lines=0x%04X which=%d -- %s\n", lines, which, (on) ? "on" : "off");
+ which = which % NUM_LEDS;
+ value = BIT(2) | BIT(3);
+ value |= ((BIT(5) | BIT(6) | BIT(7)) & ~led_mask[which]);
+ if(on)
+ value |= led_vals[which];
+ for(i = 0; i < CHANNELS_PERXPD; i++) {
+ if(!IS_SET(lines, i))
+ continue;
+ XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
+ sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
+ len = slic_cmd_direct_write(sc, lines, 0x06, value);
+ DBG("LED pack: line=%d value=0x%04X\n", i, value);
+ pack->datalen = len;
+ packet_send(xbus, pack);
+ }
+ return ret;
+}
+
+/* 0x0F */ HOSTCMD(FXS, RELAY_OUT, byte which, bool on)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ slic_cmd_t *sc;
+ int len;
+ int value;
+ xpp_line_t lines;
+ int relay_channels[] = { 0, 4 };
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
+
+ DBG("RELAY_OUT: which=%d -- %s\n", which, (on) ? "on" : "off");
+ which = which % ARRAY_SIZE(relay_channels);
+ lines = BIT(relay_channels[which]);
+ value = BIT(2) | BIT(3);
+ value |= ((BIT(5) | BIT(6) | BIT(7)) & ~led_mask[LED_BLUE]);
+ if(on)
+ value |= led_vals[LED_BLUE];
+ XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
+ sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
+ len = slic_cmd_direct_write(sc, lines, 0x06, value);
+
+ DBG("RELAY_OUT pack: line=%d value=0x%04X\n", lines, value);
+ pack->datalen = len;
+ packet_send(xbus, pack);
+ return ret;
+}
+
+/* 0x0F */ HOSTCMD(FXS, SLIC_INIT)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ slic_data_t *slic;
+ struct slic_init_data *source;
+ int i;
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
+ DBG("INITIALIZING SLIC\n");
+ for(i = 0; i < ARRAY_SIZE(slic_init_data); i++) {
+ source = &slic_init_data[i];
+ XPACKET_NEW(pack, xbus, FXS, SLIC_INIT, xpd->id);
+ RPACKET_FIELD(pack, FXS, SLIC_INIT, lines) = source->lines;
+
+ slic = &RPACKET_FIELD(pack, FXS, SLIC_INIT, slic_data);
+ slic->len = source->slic_data.len;
+ memcpy(slic->data, source->slic_data.data, source->slic_data.len);
+ pack->datalen = sizeof(xpp_line_t) + slic->len + 1;
+// dump_packet("SLIC", pack, print_dbg);
+ packet_send(xbus, pack);
+ mdelay(10); // FIXME: check with Dima
+ }
+ return ret;
+}
+
+/* 0x0F */ HOSTCMD(FXS, SLIC_QUERY, int pos, byte reg_num)
+{
+ int ret = 0;
+ xpacket_t *pack;
+ slic_cmd_t *sc;
+ int len;
+
+ BUG_ON(!xbus);
+ BUG_ON(!xpd);
+ DBG("\n");
+ XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
+ sc = &RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd);
+ len = slic_cmd_direct_read(sc, BIT(pos), reg_num);
+
+ pack->datalen = len;
+
+ packet_send(xbus, pack);
+ return ret;
+}
+
+/*---------------- FXS: Astribank Reply Handlers --------------------------*/
+
+HANDLER_DEF(FXS, SIG_CHANGED)
+{
+ xpp_line_t sig_status = RPACKET_FIELD(pack, FXS, SIG_CHANGED, sig_status);
+
+ if(!xpd) {
+ NOTICE("%s: received %s for non-existing xpd: %d\n",
+ __FUNCTION__, cmd->name, XPD_NUM(pack->content.addr));
+ return -EPROTO;
+ }
+ if(xpd->direction == TO_PHONE) { /* Hook state changes */
+ DBG("%s (PHONE) sig_status=0x%04X\n", xpd->xpdname, sig_status);
+ xpp_check_hookstate(xpd, sig_status);
+ } else { /* TO_PSTN - line ring changes */
+ unsigned long flags;
+ int i;
+
+ DBG("%s (PSTN) sig_status=0x%04X\n", xpd->xpdname, sig_status);
+ spin_lock_irqsave(&xpd->lock, flags);
+ for(i = 0; i < xpd->channels; i++) {
+ if(IS_SET(sig_status, i)) {
+ xpd->ringing[i] = RINGS_NUM*2;
+ zt_hooksig(&xpd->chans[i], ZT_RXSIG_OFFHOOK);
+ } else {
+ zt_hooksig(&xpd->chans[i], ZT_RXSIG_ONHOOK);
+ xpd->ringing[i] = 0;
+ }
+ }
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ }
+ return 0;
+}
+
+HANDLER_DEF(FXS, SLIC_REPLY)
+{
+ slic_reply_t *info = &RPACKET_FIELD(pack, FXS, SLIC_REPLY, info);
+ xpp_line_t lines = RPACKET_FIELD(pack, FXS, SLIC_REPLY, lines);
+ unsigned long flags;
+ struct FXS_priv_data *priv;
+
+ if(!xpd) {
+ NOTICE("%s: received %s for non-existing xpd: %d\n",
+ __FUNCTION__, cmd->name, XPD_NUM(pack->content.addr));
+ return -EPROTO;
+ }
+ spin_lock_irqsave(&xpd->lock, flags);
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ DBG("SLIC_REPLY: xpd #%d %s reg_num=0x%X, dataL=0x%X dataH=0x%X\n",
+ xpd->id, (info->indirect)?"I":"D",
+ info->reg_num, info->data_low, info->data_high);
+ priv->last_reply = *info;
+ if(xpd->id == 0 && info->indirect == 0 && info->reg_num == 0x06) { /* Digital Inputs Poll Result */
+ int i;
+ bool offhook = (info->data_low & 0x1) == 0;
+
+ /* Map SLIC number into line number */
+ for(i = 0; i < ARRAY_SIZE(input_channels); i++) {
+ int channo = input_channels[i];
+ int newchanno;
+
+ if(IS_SET(lines, channo)) {
+ newchanno = LINES_REGULAR + LINES_DIGI_OUT + i;
+ BIT_CLR(lines, channo);
+ BIT_SET(lines, newchanno);
+ phone_hook(xpd, newchanno, offhook);
+ }
+ }
+ }
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ return 0;
+}
+
+
+xproto_table_t PROTO_TABLE(FXS) = {
+ .entries = {
+ /* Card Opcode */
+ XENTRY( FXS, SIG_CHANGED ),
+ XENTRY( FXS, SLIC_REPLY ),
+ },
+ .name = "FXS",
+ .type = XPD_TYPE(FXS),
+ .xops = {
+ .card_new = FXS_card_new,
+ .card_init = FXS_card_init,
+ .card_remove = FXS_card_remove,
+ .card_tick = FXS_card_tick,
+
+ .RING = XPROTO_CALLER(FXS, RING),
+ .SETHOOK = XPROTO_CALLER(FXS, SETHOOK),
+ .LED = XPROTO_CALLER(FXS, LED),
+ .RELAY_OUT = XPROTO_CALLER(FXS, RELAY_OUT),
+ .CHAN_ENABLE = XPROTO_CALLER(FXS, CHAN_ENABLE),
+ .CHAN_POWER = XPROTO_CALLER(FXS, CHAN_POWER),
+ .CHAN_CID = XPROTO_CALLER(FXS, CHAN_CID),
+
+ .SYNC_SOURCE = XPROTO_CALLER(GLOBAL, SYNC_SOURCE),
+ .PCM_WRITE = XPROTO_CALLER(GLOBAL, PCM_WRITE),
+ },
+ .packet_is_valid = fxs_packet_is_valid,
+ .packet_dump = fxs_packet_dump,
+};
+
+static bool fxs_packet_is_valid(xpacket_t *pack)
+{
+ const xproto_entry_t *xe;
+
+ DBG("\n");
+ xe = xproto_card_entry(&PROTO_TABLE(FXS), pack->content.opcode);
+ return xe != NULL;
+}
+
+static void fxs_packet_dump(xpacket_t *pack)
+{
+ DBG("\n");
+}
+
+/*------------------------- SLIC Handling --------------------------*/
+
+static int proc_xpd_slic_read(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len = 0;
+ unsigned long flags;
+ xpd_t *xpd = data;
+ slic_reply_t *info;
+ struct FXS_priv_data *priv;
+
+ BUG_ON(!xpd);
+ spin_lock_irqsave(&xpd->lock, flags);
+ priv = xpd->priv;
+ BUG_ON(!priv);
+ info = &priv->last_reply;
+ len += sprintf(page + len, "# Writing bad data into this file may damage your hardware!\n");
+ len += sprintf(page + len, "# Consult firmware docs first\n");
+ len += sprintf(page + len, "SLIC_REPLY: %s reg_num=0x%X, dataH=0x%X dataL=0x%X\n",
+ (info->indirect)?"I":"D",
+ info->reg_num, info->data_high, info->data_low);
+ spin_unlock_irqrestore(&xpd->lock, flags);
+ if (len <= off+count)
+ *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len > count)
+ len = count;
+ if (len < 0)
+ len = 0;
+ return len;
+}
+
+/*
+ * Direct/Indirect
+ * v
+ * FF FF FF FF WD 06 1
+ * ^---------^ ^ Reg
+ * | Write/Read
+ * |
+ * SLIC #
+ */
+static int parse_slic_cmd(const char *buf, slic_cmd_t *sc)
+{
+ char op; /* [W]rite, [R]ead */
+ char reg_type; /* [D]irect, [I]ndirect */
+ int s1, s2, s3, s4;
+ int reg_num;
+ int data_low, data_high;
+ xpp_line_t lines;
+ int ret;
+
+ ret = sscanf(buf, "%x %x %x %x %c%c %x %x %x",
+ &s1, &s2, &s3, &s4, &op, ®_type, ®_num, &data_high, &data_low);
+ lines = (s4 << 24) | (s3 << 16) | (s2 << 8) | (s1);
+ switch(op) {
+ case 'R':
+ if(reg_type == 'D' && ret == 7) {
+ // DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
+ ret = slic_cmd_direct_read(sc, lines, reg_num);
+ } else if(reg_type == 'I' && ret == 7) {
+ // DBG("0x%X 0x%X 0x%X 0x%X %c %x\n", s1, s2, s3, s4, reg_type, reg_num);
+ ret = slic_cmd_indirect_read(sc, lines, reg_num);
+ } else {
+ NOTICE("%s: Bad read input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
+ goto err;
+ }
+ break;
+ case 'W':
+ if(reg_type == 'D' && ret == 8) {
+ // DBG("0x%X 0x%X 0x%X 0x%X %c %x %X\n", s1, s2, s3, s4, reg_type, reg_num, data_high);
+ ret = slic_cmd_direct_write(sc, lines, reg_num, data_high);
+ } else if(reg_type == 'I' && ret == 9) {
+ // DBG("0x%X 0x%X 0x%X 0x%X %c %x %X %X\n", s1, s2, s3, s4, reg_type, reg_num, data_high, data_low);
+ ret = slic_cmd_indirect_write(sc, lines, reg_num, data_low, data_high);
+ } else {
+ NOTICE("%s: Bad write input: ret=%d buf='%s' reg_type=%c\n", __FUNCTION__, ret, buf, reg_type);
+ goto err;
+ }
+ break;
+ default:
+ NOTICE("%s: Bad input: ret=%d buf='%s' op=%c\n", __FUNCTION__, ret, buf, op);
+ goto err;
+ }
+ return ret;
+err:
+ return -EINVAL;
+}
+
+static int process_slic_cmdline(xpd_t *xpd, char *cmdline)
+{
+ xbus_t *xbus;
+ slic_cmd_t sc;
+ xpacket_t *pack;
+ char *p;
+ int len = strlen(cmdline);
+
+ BUG_ON(!xpd);
+ xbus = xpd->xbus;
+ if((p = strchr(cmdline, '#')) != NULL) /* Truncate comments */
+ *p = '\0';
+ if((p = strchr(cmdline, ';')) != NULL) /* Truncate comments */
+ *p = '\0';
+ for(p = cmdline; *p && (*p == ' ' || *p == '\t'); p++) /* Trim leading whitespace */
+ ;
+ if(*p == '\0')
+ return 0;
+ len = parse_slic_cmd(p, &sc);
+ if(len < 0)
+ return len;
+ sc.lines &= xpd->enabled_chans; // Ignore disabled channels
+ if(!sc.lines) {
+ NOTICE("%s: no enabled channels are marked. Skip.\n", __FUNCTION__);
+ return 0;
+ }
+ dump_slic_cmd("WRITE_SLIC", &sc);
+ XPACKET_NEW(pack, xbus, FXS, SLIC_WRITE, xpd->id);
+ RPACKET_FIELD(pack, FXS, SLIC_WRITE, slic_cmd) = sc;
+ pack->datalen = len;
+ packet_send(xbus, pack);
+ return 0;
+}
+
+static int proc_xpd_slic_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
+{
+ xpd_t *xpd = data;
+ const int LINE_LEN = 500;
+ char buf[LINE_LEN];
+ char *p;
+ int i;
+ int ret;
+
+ BUG_ON(!xpd);
+ for(i = 0; i < count; /* noop */) {
+ for(p = buf; p < buf + LINE_LEN; p++) { /* read a line */
+ if(i >= count)
+ break;
+ if(get_user(*p, buffer + i))
+ return -EFAULT;
+ i++;
+ if(*p == '\n' || *p == '\r') /* whatever */
+ break;
+ }
+ if(p >= buf + LINE_LEN)
+ return -E2BIG;
+ *p = '\0';
+ ret = process_slic_cmdline(xpd, buf);
+ if(ret < 0)
+ return ret;
+ }
+ return count;
+}
+
+
+int __init card_fxs_startup(void)
+{
+ INFO("%s revision %s\n", THIS_MODULE->name, revision);
+ xproto_register(&PROTO_TABLE(FXS));
+ return 0;
+}
+
+void __exit card_fxs_cleanup(void)
+{
+ xproto_unregister(&PROTO_TABLE(FXS));
+}
+
+MODULE_DESCRIPTION("XPP FXS Card Driver");
+MODULE_AUTHOR("Oron Peled <oron at actcom.co.il>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("$Id$");
+
+module_init(card_fxs_startup);
+module_exit(card_fxs_cleanup);
Propchange: branches/1.2/xpp/card_fxs.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: branches/1.2/xpp/card_fxs.c
------------------------------------------------------------------------------
[... 7187 lines stripped ...]
More information about the zaptel-commits
mailing list