[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, &reg_type, &reg_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