2.6.11-rc2 DVB update
Subsystems (2)
cover 2.6.11-rc2 DVB update
Hi Linus,
this is the usual batch of DVB updates from linuxtv.org CVS. The patches were prepared by Michael Hunold, I just rediffed them to apply cleanly against 2.6.11-rc2, and submit them on his behalf this time.
I realize it is actually a bit late in the 2.6.11 release cycle but I hope they can be included in 2.6.11 anyway, as they don't touch anything outside the DVB subsystem. If not I will factor out the important bug fixes and resubmit them.
1 saa7146 fix possible RPS init race
2 bt8xx support pinnacle pctv-sat, clean-ups
3 dibusb refactoring, support Yakumo/HAMA/Typhoon/HanfTek clones
4 misc support nxt2002 frontend, misc skystar2 fixes
5 dvb-core add ATSC support, misc fixes
6 dib3000 refactoring
7 frontends nxt2002: add ATSC support, misc fixes
8 ttpci dvb-ttpci: fix SMP race, budget: fix init race, misc fixes
Johannes
PATCH 1/9 fix RPS init race
- [DVB] saa7146: explicitely disable RPS tasks in saa7146_init_one()
drivers/media/common/saa7146_core.c +2 -2
@@ -380,8 +380,8 @@/* disable all irqs */ saa7146_write (dev,IER ,0 ); -/* shut down all dma transfers */ -saa7146_write (dev,MC1 ,0x00ff0000 ); +/* shut down all dma transfers and rps tasks */ +saa7146_write (dev,MC1 ,0x30ff0000 );/* clear out any rps-signals pending */ saa7146_write (dev,MC2 ,0xf8000000 );
PATCH 2/9 support pinnacle pctv-sat, clean-ups
In reply to Johannes Stezenbach- [DVB] dvb-bt8xx: add support for pinnacle pctv-sat, patch by Peter Hettkamp and Adam Szalkowski
- [DVB] dvb-bt8xx: minor code cleanups, patch by Arne Ahrend
- [DVB] dvb-bt8xx: make sure to compile all necessary frontend modules, remove misleading comment
drivers/media/dvb/bt8xx/dvb-bt8xx.c +80 -2
@@ -181,6 +181,70 @@ .pll_set = thomson_dtt7579_pll_set, }; +static int cx24108_pll_set (struct dvb_frontend * fe,struct dvb_frontend_parameters * params) +{ +u32 freq = params->frequency; + +int i, a, n, pump; +u32 band, pll; + + +u32 osci[]={950000 ,1019000 ,1075000 ,1178000 ,1296000 ,1432000 , +1576000 ,1718000 ,1856000 ,2036000 ,2150000 }; +u32 bandsel[]={0 ,0x00020000 ,0x00040000 ,0x00100800 ,0x00101000 , +0x00102000 ,0x00104000 ,0x00108000 ,0x00110000 , +0x00120000 ,0x00140000 }; + +#define XTAL 1011100/* Hz, really 1.0111 MHz and a /10 prescaler */ +printk ("cx24108 debug: entering SetTunerFreq, freq=%d\n" ,freq); + +/* This is really the bit driving the tuner chip cx24108 */ + +if (freq<950000 ) freq=950000 ;/* kHz */ +if (freq>2150000 ) freq=2150000 ;/* satellite IF is 950..2150MHz */ + +/* decide which VCO to use for the input frequency */ +for (i=1 ;(i<sizeof (osci)/sizeof (osci[0 ]))&&(osci[i]<freq);i++); +printk ("cx24108 debug: select vco #%d (f=%d)\n" ,i,freq); + band=bandsel[i]; +/* the gain values must be set by SetSymbolrate */ +/* compute the pll divider needed, from Conexant data sheet, +resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4, +depending on the divider bit. It is set to /4 on the 2 lowest +bands */ + n=((i<=2 ?2 :1 )*freq*10L )/(XTAL /100 ); + a=n%32 ; n/=32 ;if (a==0 ) n--; + pump=(freq<(osci[i-1 ]+osci[i])/2 ); + pll=0xf8000000 | + ((pump?1 :2 )<<(14 +11 ))| + ((n&0x1ff )<<(5 +11 ))| + ((a&0x1f )<<11 ); +/* everything is shifted left 11 bits to left-align the bits in the +32bit word. Output to the tuner goes MSB-aligned, after all */ +printk ("cx24108 debug: pump=%d, n=%d, a=%d\n" ,pump,n,a); +cx24110_pll_write (fe,band); +/* set vga and vca to their widest-band settings, as a precaution. +SetSymbolrate might not be called to set this up */ +cx24110_pll_write (fe,0x500c0000 ); +cx24110_pll_write (fe,0x83f1f800 ); +cx24110_pll_write (fe,pll); +/* writereg(client,0x56,0x7f);*/ + +return 0 ; +} + +static int pinnsat_pll_init (struct dvb_frontend * fe) +{ +return 0 ; +} + + +static struct cx24110_config pctvsat_config = { + + .demod_address =0x55 , + .pll_init = pinnsat_pll_init, + .pll_set = cx24108_pll_set, +};static int microtune_mt7202dtf_pll_set (struct dvb_frontend * fe,struct dvb_frontend_parameters * params)
@@ -220,7 +284,7 @@return request_firmware (fw, name, &bt->bt->dev->dev); } -struct sp887x_config microtune_mt7202dtf_config = { +static struct sp887x_config microtune_mt7202dtf_config = { .demod_address =0x70 , .pll_set = microtune_mt7202dtf_pll_set,
@@ -387,6 +451,13 @@break ; }break ; + +case BTTV_PINNACLESAT : + card->fe =cx24110_attach (&pctvsat_config, card->i2c_adapter); +if (card->fe !=NULL ) { +break ; + } +break ; }if (card->fe ==NULL ) {
@@ -510,7 +581,14 @@switch (sub->core->type) { -/* case BTTV_PINNACLESAT: UNDEFINED HARDWARE */ +case BTTV_PINNACLESAT : + card->gpio_mode =0x0400c060 ; +/* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, +BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ + card->op_sync_orin =0 ; + card->irq_err_ignore =0 ; +break ; +#ifdef BTTV_DVICO_DVBT_LITE case BTTV_DVICO_DVBT_LITE :#endif
drivers/media/dvb/bt8xx/dvb-bt8xx.h +6 -0
@@ -22,6 +22,9 @@* */ +#ifndef DVB_BT8XX_H +#define DVB_BT8XX_H +#include <linux/i2c.h> #include "dvbdev.h" #include "dvb_net.h"
@@ -30,6 +33,7 @@#include "sp887x.h" #include "dst.h" #include "nxt6000.h" +#include "cx24110.h" struct dvb_bt8xx_card {struct semaphore lock;
@@ -50,3 +54,5 @@ struct dvb_frontend* fe; }; + +#endif /* DVB_BT8XX_H */
drivers/media/dvb/bt8xx/Kconfig +2 -3
@@ -3,6 +3,8 @@ depends on DVB_CORE && PCI && VIDEO_BT848 select DVB_MT352 select DVB_SP887X + select DVB_NXT6000 + select DVB_CX24110 help Support for PCI cards based on the Bt8xx PCI bridge. Examples are the Nebula cards, the Pinnacle PCTV cards and Twinhan DST cards.
@@ -11,8 +13,5 @@ only compressed MPEG data over the PCI bus, so you need an external software decoder to watch TV on your computer. - If you have a Twinhan card, don't forget to select - "Twinhan DST based DVB-S/-T frontend". - Say Y if you own such a device and want to use it.
PATCH 3/9 refactoring, support Yakumo/HAMA/Typhoon/HanfTek clones
In reply to Johannes Stezenbach- [DVB] dvb-dibusb: refactoring of the dibusb driver, support for device clones from Yakumo/HAMA/Typhoon/HanfTek, update the documentation
Documentation/dvb/README.dibusb +44 -16
@@ -26,7 +26,7 @@ - HAMA DVB-T USB device http://www.hama.de/portal/articleId*110620/action*2598 -- CTS Portable (Chinese Television System) +- CTS Portable (Chinese Television System) (2) http://www.2cts.tv/ctsportable/ - Unknown USB DVB-T device with vendor ID Hyper-Paltek
@@ -46,16 +46,16 @@ Others: ------- -- Ultima Electronic/Artec T1 USB TVBOX (AN2135 and AN2235) +- Ultima Electronic/Artec T1 USB TVBOX (AN2135, AN2235, AN2235 with Panasonic Tuner) http://82.161.246.249/products-tvbox.html -- Compro Videomate DVB-U2000 - DVB-T USB +- Compro Videomate DVB-U2000 - DVB-T USB (2) http://www.comprousa.com/products/vmu2000.htm - Grandtec USB DVB-T http://www.grand.com.tw/ -- Avermedia AverTV DVBT USB +- Avermedia AverTV DVBT USB (2) http://www.avermedia.com/ - DiBcom USB DVB-T reference device (non-public)
@@ -63,16 +63,33 @@ Supported devices USB2.0 ======================== -- Twinhan MagicBox II +- Twinhan MagicBox II (2) http://www.twinhan.com/product_terrestrial_7.asp -- Yakumo DVB-T mobile +- Hanftek UMT-010 (1) + http://www.globalsources.com/si/6008819757082/ProductDetail/Digital-TV/product_id-100046529 + +- Typhoon/Yakumo/HAMA DVB-T mobile USB2.0 (1) http://www.yakumo.de/produkte/index.php?pid=1&ag=DVB-T +- Artec T1 USB TVBOX (FX2) (2) + - DiBcom USB2.0 DVB-T reference device (non-public) +1) It is working almost. +2) No test reports received yet. + 0. NEWS: + 2004-01-13 - moved the mirrored pid_filter_table back to dvb-dibusb + - first almost working version for HanfTek UMT-010 + - found out, that Yakumo/HAMA/Typhoon are predessors of the HanfTek + 2004-01-10 - refactoring completed, now everything is very delightful + - tuner quirks for some weird devices (Artec T1 AN2235 device has sometimes a + Panasonic Tuner assembled). Tunerprobing implemented. Thanks a lot to Gunnar Wittich. + 2004-12-29 - after several days of struggling around bug of no returning URBs fixed. + 2004-12-26 - refactored the dibusb-driver, splitted into separate files + - i2c-probing enabled 2004-12-06 - possibility for demod i2c-address probing - new usb IDs (Compro,Artec) 2004-11-23 - merged changes from DiB3000MC_ver2.1
@@ -115,13 +132,15 @@ 1. How to use? NOTE: This driver was developed using Linux 2.6.6., -it is working with 2.6.7, 2.6.8.1, 2.6.9 . +it is working with 2.6.7 and above. Linux 2.4.x support is not planned, but patches are very welcome. NOTE: I'm using Debian testing, so the following explaination (especially the hotplug-path) needn't match your system, but probably it will :). +The driver is included in the kernel since Linux 2.6.10. + 1.1. Firmware The USB driver needs to download a firmware to start working.
@@ -155,9 +174,13 @@ first have a look, which debug level are available: modinfo dib3000mb +modinfo dib3000-common +modinfo dib3000mc modinfo dvb-dibusb +modprobe dib3000-common debug=<level> modprobe dib3000mb debug=<level> +modprobe dib3000mc debug=<level> modprobe dvb-dibusb debug=<level> should do the trick.
@@ -168,13 +191,11 @@ At this point you should be able to start a dvb-capable application. For myself I used mplayer, dvbscan, tzap and kaxtv, they are working. Using the device -as a slave device in vdr, was not working for me. Some work has to be done -(patches and comments are very welcome). +in vdr (at least the USB2.0 one) is working. 2. Known problems and bugs -TODO: -- signal-quality and strength calculations +- none this time 2.1. Adding support for devices
@@ -202,9 +223,10 @@ maximum bandwidth of about 5-6 MBit/s when connected to a USB2.0 hub. This is not enough for receiving the complete transport stream of a DVB-T channel (which can be about 16 MBit/s). Normally this is not a -problem, if you only want to watch TV, but watching a channel while -recording another channel on the same frequency simply does not work. -This applies to all USB1.1 DVB-T devices. +problem, if you only want to watch TV (this does not apply for HDTV), +but watching a channel while recording another channel on the same +frequency simply does not work. This applies to all USB1.1 DVB-T +devices, not only dibusb) A special problem of the dibusb for the USB1.1 is, that the USB control IC has a problem with write accesses while having MPEG2-streaming
@@ -218,14 +240,20 @@ these features is maybe a solution. Additionally this behaviour of VDR exceeds the USB1.1 bandwidth. +Update: +For the USB1.1 and VDR some work has been done (patches and comments are still +very welcome). Maybe the problem is solved in the meantime because I now use +the dmx_sw_filter function instead of dmx_sw_filter_packet. I hope the +linux-dvb software filter is able to get the best of the garbled TS. + 2.3. Comments Patches, comments and suggestions are very very welcome 3. Acknowledgements Amaury Demol ([email protected]) and Francois Kanounnikoff from DiBcom for - providing specs, code and help, on which the dvb-dibusb and dib3000mb are - based. + providing specs, code and help, on which the dvb-dibusb, dib3000mb and + dib3000mc are based. David Matthews for identifying a new device type (Artec T1 with AN2235) and for extending dibusb with remote control event handling. Thank you.
drivers/media/dvb/dibusb/dvb-dibusb-core.c +471 -0
471 lines not on this page · raw message
drivers/media/dvb/dibusb/dvb-dibusb-dvb.c +205 -0
205 lines not on this page · raw message
drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c +598 -0
598 lines not on this page · raw message
drivers/media/dvb/dibusb/dvb-dibusb-firmware.c +85 -0
85 lines not on this page · raw message
drivers/media/dvb/dibusb/dvb-dibusb.h +228 -258
577 lines not on this page · raw message
drivers/media/dvb/dibusb/dvb-dibusb-pid.c +80 -0
80 lines not on this page · raw message
drivers/media/dvb/dibusb/dvb-dibusb-remote.c +197 -0
197 lines not on this page · raw message
drivers/media/dvb/dibusb/dvb-dibusb-usb.c +259 -0
259 lines not on this page · raw message
drivers/media/dvb/dibusb/Kconfig +9 -5
@@ -1,12 +1,13 @@ config DVB_DIBUSB - tristate "DiBcom USB DVB-T devices (see help for device list)" + tristate "DiBcom USB DVB-T devices (see help for a complete device list)" depends on DVB_CORE && USB select FW_LOADER select DVB_DIB3000MB select DVB_DIB3000MC + select DVB_MT352 help Support for USB 1.1 and 2.0 DVB-T devices based on reference designs made by - DiBcom (<http://www.dibcom.fr>). + DiBcom (http://www.dibcom.fr) and C&E. Devices supported by this driver:
@@ -14,12 +15,14 @@ TwinhanDTV Magic Box (VP7041e) KWorld V-Stream XPERT DTV - DVB-T USB Hama DVB-T USB-Box - DiBcom reference device (non-public) + DiBcom reference devices (non-public) Ultima Electronic/Artec T1 USB TVBOX Compro Videomate DVB-U2000 - DVB-T USB Grandtec DVB-T USB Avermedia AverTV DVBT USB - Yakumo DVB-T mobile USB2.0 + Artec T1 USB1.1 and USB2.0 boxes + Yakumo/Typhoon DVB-T USB2.0 + Hanftek UMT-010 USB2.0 The VP7041 seems to be identical to "CTS Portable" (Chinese Television System).
@@ -27,7 +30,7 @@ These devices can be understood as budget ones, they "only" deliver (a part of) the MPEG2 transport stream. - A firmware is needed to get the device working. See <file:Documentation/dvb/README.dibusb> + A firmware is needed to get the device working. See Documentation/dvb/README.dibusb details. Say Y if you own such a device and want to use it. You should build it as
@@ -46,6 +49,7 @@ 0x0574:0x2235 (Artec T1 USB1.1, cold) 0x04b4:0x8613 (Artec T1 USB2.0, cold) 0x0574:0x1002 (Artec T1 USB2.0, warm) + 0x0574:0x2131 (aged DiBcom USB1.1 test device) Say Y if your device has one of the mentioned IDs.
drivers/media/dvb/dibusb/Makefile +8 -0
@@ -1,3 +1,11 @@ +dvb-dibusb-objs = dvb-dibusb-core.o \ + dvb-dibusb-dvb.o \ + dvb-dibusb-fe-i2c.o \ + dvb-dibusb-firmware.o \ + dvb-dibusb-remote.o \ + dvb-dibusb-usb.o \ + dvb-dibusb-pid.o + obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
PATCH 4/9 support nxt2002 frontend, misc skystar2 fixes
In reply to Johannes Stezenbach- [DVB] nxt2002: add support for nxt2002 frontend (firmware extraction, Kconfig, driver)
- [DVB] skystar2: misc cleanup, remove unneeded casts, remove unreachable code, patches by Francois Romieu
- [DVB] skystar2: fix mt352 clock setting for VHF (6 and 7 MHz bw channels), patch by Thomas Martin and Dieter Zander:
- [DVB] b2c2-usb-core: fix file permissions to be octal, ISO C90 compile fix, temporally repaired the request_types
- [DVB] remove remains of dibusb driver after splitup
Documentation/dvb/get_dvb_firmware +19 -1
@@ -21,7 +21,8 @@ use File::Temp qw/ tempdir /; use IO::Handle; -@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t", "dec2540t", "dec3000s", "vp7041", "dibusb" ); +@components = ( "sp8870", "sp887x", "tda10045", "tda10046", "av7110", "dec2000t", + "dec2540t", "dec3000s", "vp7041", "dibusb", "nxt2002" ); # Check args syntax() if (scalar(@ARGV) != 1);
@@ -233,6 +234,23 @@ $outfile; } +sub nxt2002 { + my $sourcefile = "Broadband4PC_4_2_11.zip"; + my $url = "http://www.bbti.us/download/windows/$sourcefile"; + my $hash = "c6d2ea47a8f456d887ada0cfb718ff2a"; + my $outfile = "dvb-fe-nxt2002.fw"; + my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); + + checkstandard(); + + wgetfile($sourcefile, $url); + unzip($sourcefile, $tmpdir); + verify("$tmpdir/SkyNETU.sys", $hash); + extract("$tmpdir/SkyNETU.sys", 375832, 5908, $outfile); + + $outfile; +} + # --------------------------------------------------------------- # Utilities
drivers/media/dvb/frontends/Makefile +2 -0
@@ -24,3 +24,5 @@ obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o obj-$(CONFIG_DVB_TDA10021) += tda10021.o obj-$(CONFIG_DVB_STV0297) += stv0297.o +obj-$(CONFIG_DVB_NXT2002) += nxt2002.o +
drivers/media/dvb/frontends/Kconfig +12 -0
@@ -46,6 +46,7 @@ config DVB_SP8870 tristate "Spase sp8870 based" depends on DVB_CORE + select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -56,6 +57,7 @@ config DVB_SP887X tristate "Spase sp887x based" depends on DVB_CORE + select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -84,6 +86,7 @@ config DVB_TDA1004X tristate "Philips TDA10045H/TDA10046H based" depends on DVB_CORE + select FW_LOADER help A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -145,4 +148,13 @@ help A DVB-C tuner module. Say Y when you want to support this frontend. +comment "ATSC (North American/Korean Terresterial DTV) frontends" + depends on DVB_CORE + +config DVB_NXT2002 + tristate "Nxt2002 based" + depends on DVB_CORE + help + An ATSC 8VSB tuner module. Say Y when you want to support this frontend. + endmenu
drivers/media/dvb/b2c2/Kconfig +4 -2
@@ -4,9 +4,11 @@ select DVB_STV0299 select DVB_MT352 select DVB_MT312 + select DVB_NXT2002 help Support for the Skystar2 PCI DVB card by Technisat, which - is equipped with the FlexCopII chipset by B2C2. + is equipped with the FlexCopII chipset by B2C2, and + for the B2C2/BBTI Air2PC-ATSC card. Say Y if you own such a device and want to use it.
@@ -17,7 +19,7 @@ select DVB_MT352 help Support for the Air/Sky/Cable2PC USB DVB device by B2C2. Currently - this does nothing, but providing basic function for the used usb + the does nothing, but providing basic function for the used usb protocol. Say Y if you own such a device and want to use it.
drivers/media/dvb/b2c2/skystar2.c +193 -159
550 lines not on this page · raw message
drivers/media/dvb/b2c2/b2c2-usb-core.c +12 -2
@@ -33,7 +33,7 @@ }static int debug; -module_param (debug, int,0x644 ); +module_param (debug, int,0644 );MODULE_PARM_DESC (debug,"set debugging level (1=info,ts=2,ctrl=4 (or-able))." ); #define deb_info(args...) dprintk(0x01,args)
@@ -89,12 +89,22 @@/* request types */ typedef enum { + +/* something is wrong with this part RTYPE_READ_DW = (1 << 6), RTYPE_WRITE_DW_1 = (3 << 6), RTYPE_READ_V8_MEMORY = (6 << 6), RTYPE_WRITE_V8_MEMORY = (7 << 6), RTYPE_WRITE_V8_FLASH = (8 << 6), RTYPE_GENERIC = (9 << 6), +*/ +RTYPE_READ_DW = (3 <<6 ), +RTYPE_WRITE_DW_1 = (1 <<6 ), + +RTYPE_READ_V8_MEMORY = (6 <<6 ), +RTYPE_WRITE_V8_MEMORY = (7 <<6 ), +RTYPE_WRITE_V8_FLASH = (8 <<6 ), +RTYPE_GENERIC = (9 <<6 ), }b2c2_usb_request_type_t ;/* request */
@@ -391,9 +401,9 @@ }/* initialising and submitting iso urbs */ for (i =0 ; i <B2C2_USB_NUM_ISO_URB ; i++) { -deb_info ("initializing and submitting urb no. %d (buf_offset: %d).\n" ,i,buffer_offset);int frame_offset =0 ;struct urb *urb = b2c2->iso_urb[i]; +deb_info ("initializing and submitting urb no. %d (buf_offset: %d).\n" ,i,buffer_offset); urb->dev = b2c2->udev; urb->context = b2c2;
drivers/media/dvb/dibusb/dvb-dibusb.c +0 -1032
1,032 lines not on this page · raw message
PATCH 5/9 add ATSC support, misc fixes
In reply to Johannes Stezenbach- [DVB] dvb-core: vfree() checking cleanups, patch by Domen Puncer
- [DVB] dvb-core: fix handling of discontinuity indicator in section filter, bug reported by Frank Rosengart
- [DVB] dvb-core: handle PUSI in section filter correctly, patch by Emard, bug reported by Patrick Valsecchi
- [DVB] dvb-core: add support for ATSC/VSB frontends, patch by Taylor Jacob
- [DVB] dvb-core: removed semi-colon from a very wrong place; FE_ENABLE_HIGH_LNB_VOLTAGE kernel oops; thanks to Christophe Massiot
- [DVB] dvb-core: Fixed slow tuning problems, remove frequeny bending support from frontend code, code simplification
drivers/media/dvb/dvb-core/dvb_demux.c +40 -18
@@ -247,7 +249,22 @@ }/* -** Losless Section Demux 1.4 by Emard +** Losless Section Demux 1.4.1 by Emard +** Valsecchi Patrick: +** - middle of section A (no PUSI) +** - end of section A and start of section B +** (with PUSI pointing to the start of the second section) +** +** In this case, without feed->pusi_seen you'll receive a garbage section +** consisting of the end of section A. Basically because tsfeedp +** is incemented and the use=0 condition is not raised +** when the second packet arrives. +** +** Fix: +** when demux is started, let feed->pusi_seen = 0 to +** prevent initial feeding of garbage from the end of +** previous section. When you for the first time see PUSI=1 +** then set feed->pusi_seen = 1 */ static int dvb_dmx_swfilter_section_copy_dump (struct dvb_demux_feed *feed,const u8 *buf,u8 len) {
@@ -293,7 +310,12 @@ sec->seclen = seclen; sec->crc_val = ~0 ;/* dump [secbuf .. secbuf+seclen) */ +if (feed->pusi_seen)dvb_dmx_swfilter_section_feed (feed); +#ifdef DVB_DEMUX_SECTION_LOSS_LOG + else + printk("dvb_demux.c pusi not seen, discarding section data\n"); +#endif sec->secbufp += seclen;/* secbufp and secbuf moving together is */ sec->secbuf += seclen;/* redundand but saves pointer arithmetic */ }
@@ -305,7 +327,7 @@static int dvb_dmx_swfilter_section_packet (struct dvb_demux_feed *feed,const u8 *buf) {u8 p, count; -int ccok; +int ccok, dc_i =0 ;u8 cc; count =payload (buf);
@@ -316,31 +338,41 @@ p =188 -count;/* payload start */ cc = buf[3 ] &0x0f ; - ccok = ((feed->cc+1 ) &0x0f ) == cc ?1 :0 ; + ccok = ((feed->cc +1 ) &0x0f ) == cc; feed->cc = cc; -if (ccok ==0 ) - { + +if (buf[3 ] &0x20 ) { +/* adaption field present, check for discontinuity_indicator */ +if ((buf[4 ] >0 ) && (buf[5 ] &0x80 )) + dc_i =1 ; + } + +if (!ccok || dc_i) {#ifdef DVB_DEMUX_SECTION_LOSS_LOG printk ("dvb_demux.c discontinuity detected %d bytes lost\n" , count);/* those bytes under sume circumstances will again be reported ** in the following dvb_dmx_swfilter_section_new */ #endif +/* Discontinuity detected. Reset pusi_seen = 0 to +** stop feeding of suspicious data until next PUSI=1 arrives +*/ + feed->pusi_seen =0 ;dvb_dmx_swfilter_section_new (feed);return 0 ; } -if (buf[1 ] &0x40 ) - { +if (buf[1 ] &0x40 ) {// PUSI=1 (is set), section boundary is here -if (count >1 && buf[p] < count) - { +if (count >1 && buf[p] < count) {const u8 *before = buf+p+1 ;u8 before_len = buf[p];const u8 *after = before+before_len;u8 after_len = count-1 -before_len;dvb_dmx_swfilter_section_copy_dump (feed, before, before_len); +/* before start of new section, set pusi_seen = 1 */ + feed->pusi_seen =1 ;dvb_dmx_swfilter_section_new (feed);dvb_dmx_swfilter_section_copy_dump (feed, after, after_len); }
@@ -349,9 +381,7 @@if (count >0 )printk ("dvb_demux.c PUSI=1 but %d bytes lost\n" , count);#endif - } -else - { + }else {// PUSI=0 (is not set), no section boundary const u8 *entire = buf+p;u8 entire_len = count;
@@ -784,10 +814,8 @@ }#ifndef NOBUFS -if (feed->buffer) {vfree (feed->buffer); feed->buffer=0 ; - }#endif feed->state =DMX_STATE_FREE ;
@@ -1055,10 +1094,8 @@return -EINVAL ; }#ifndef NOBUFS -if (dvbdmxfeed->buffer) {vfree (dvbdmxfeed->buffer); dvbdmxfeed->buffer=0 ; - }#endif dvbdmxfeed->state=DMX_STATE_FREE ;
@@ -1269,9 +1317,7 @@struct dmx_demux *dmx = &dvbdemux->dmx;dmx_unregister_demux (dmx); -if (dvbdemux->filter)vfree (dvbdemux->filter); -if (dvbdemux->feed)vfree (dvbdemux->feed);return 0 ; }
drivers/media/dvb/dvb-core/dvb_demux.h +1 -0
@@ -93,6 +93,7 @@enum dmx_ts_pes pes_type;int cc; +int pusi_seen;/* prevents feeding of garbage from previous section */ u16 peslen;
drivers/media/dvb/dvb-core/dvb_frontend.c +198 -147
774 lines not on this page · raw message
drivers/media/dvb/dvb-core/dvb_frontend.h +1 -22
@@ -115,28 +115,7 @@struct dvb_frontend_ops * ops;struct dvb_adapter *dvb;void * demodulator_priv; - -struct dvb_device *dvbdev; -struct dvb_frontend_parameters parameters; -struct dvb_fe_events events; -struct semaphore sem; -struct list_head list_head; -wait_queue_head_t wait_queue; -pid_t thread_pid; -unsigned long release_jiffies; -int state; -int bending; -int lnb_drift; -int inversion; -int auto_step; -int auto_sub_step; -int started_auto_step; -int min_delay; -int max_drift; -int step_size; -int exit; -int wakeup; -fe_status_t status; +void * frontend_priv; }; extern int dvb_register_frontend(struct dvb_adapter* dvb,
drivers/media/dvb/dvb-core/dvb_net.c +10 -4
@@ -123,7 +123,6 @@struct dvb_net_priv {int in_use;struct net_device_stats stats; -char name[6 ];u16 pid;struct dvb_net *host;struct dmx_demux *demux;
@@ -1165,12 +1162,17 @@if ((if_num =get_if (dvbnet)) <0 )return -EINVAL ; - net =alloc_netdev (sizeof (struct dvb_net_priv ),"dvb" , - dvb_net_setup); + net =alloc_netdev (sizeof (struct dvb_net_priv ),"dvb" , dvb_net_setup);if (!net)return -ENOMEM ; -sprintf (net->name,"dvb%d_%d" , dvbnet->dvbdev->adapter->num, if_num); +if (dvbnet->dvbdev->id) +snprintf (net->name,IFNAMSIZ ,"dvb%d%u%d" , + dvbnet->dvbdev->adapter->num, dvbnet->dvbdev->id, if_num); +else +/* compatibility fix to keep dvb0_0 format */ +snprintf (net->name,IFNAMSIZ ,"dvb%d_%d" , + dvbnet->dvbdev->adapter->num, if_num); net->addr_len =6 ;memcpy (net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac,6 );
@@ -1196,6 +1198,7 @@free_netdev (net);return result; } +printk ("dvb_net: created network interface %s\n" , net->name);return if_num; }
@@ -1214,6 +1216,7 @@dvb_net_stop (net);flush_scheduled_work (); +printk ("dvb_net: removed network interface %s\n" , net->name);unregister_netdev (net); dvbnet->state[num]=0 ; dvbnet->device[num] =NULL ;
drivers/media/dvb/ttusb-dec/ttusb_dec.c +3 -3
@@ -756,7 +755,7 @@if (!dec->iso_stream_count) {for (i =0 ; i <ISO_BUF_COUNT ; i++) -usb_unlink_urb (dec->iso_urb[i]); +usb_kill_urb (dec->iso_urb[i]); }up (&dec->iso_sem);
@@ -821,7 +820,7 @@ "error %d\n", __FUNCTION__, i, result);while (i) { -usb_unlink_urb (dec->iso_urb[i -1 ]); +usb_kill_urb (dec->iso_urb[i -1 ]); i--; }
@@ -1379,7 +1378,7 @@ dec->iso_stream_count =0 ;for (i =0 ; i <ISO_BUF_COUNT ; i++) -usb_unlink_urb (dec->iso_urb[i]); +usb_kill_urb (dec->iso_urb[i]);ttusb_dec_free_iso_urbs (dec); }
include/linux/dvb/frontend.h +8 -3
@@ -158,10 +158,11 @@QAM_64 ,QAM_128 ,QAM_256 , - QAM_AUTO +QAM_AUTO , +VSB_8 , + VSB_16 } fe_modulation_t; - typedef enum fe_transmit_mode { TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K,
@@ -206,6 +206,9 @@fe_modulation_t modulation;/* modulation type (see above) */ }; +struct dvb_vsb_parameters { +fe_modulation_t modulation;/* modulation type (see above) */ +};struct dvb_ofdm_parameters {fe_bandwidth_t bandwidth;
@@ -219,13 +222,14 @@struct dvb_frontend_parameters { -__u32 frequency;/* (absolute) frequency in Hz for QAM/OFDM */ +__u32 frequency;/* (absolute) frequency in Hz for QAM/OFDM/ATSC */ /* intermediate frequency in kHz for QPSK */ fe_spectral_inversion_t inversion;union {struct dvb_qpsk_parameters qpsk;struct dvb_qam_parameters qam;struct dvb_ofdm_parameters ofdm; +struct dvb_vsb_parameters vsb; } u; };
include/linux/dvb/version.h +1 -0
@@ -24,6 +24,7 @@#define _DVBVERSION_H_#define DVB_API_VERSION 3 +#define DVB_API_VERSION_MINOR 1#endif /*_DVBVERSION_H_*/
PATCH 6/9 refactoring
In reply to Johannes Stezenbach- [DVB] dib3000: driver refactoring, makes it easier to support device clones
drivers/media/dvb/frontends/dib3000-common.c +1 -63
@@ -2,7 +2,7 @@#ifdef CONFIG_DVB_DIBCOM_DEBUG static int debug; -module_param (debug, int,0x644 ); +module_param (debug, int,0644 );MODULE_PARM_DESC (debug,"set debugging level (1=info,2=i2c,4=srch (|-able))." );#endif #define deb_info(args...) dprintk(0x01,args)
@@ -42,65 +41,6 @@return i2c_transfer (state->i2c,msg,1 ) !=1 ? -EREMOTEIO :0 ; } -int dib3000_init_pid_list (struct dib3000_state *state,int num) -{ -int i; -if (state !=NULL ) { - state->pid_list =kmalloc (sizeof (struct dib3000_pid ) * num,GFP_KERNEL ); -if (state->pid_list ==NULL ) -return -ENOMEM ; - -deb_info ("initializing %d pids for the pid_list.\n" ,num); -spin_lock_init (&state->pid_list_lock); -memset (state->pid_list,0 ,num*(sizeof (struct dib3000_pid ))); -for (i=0 ; i < num; i++) { - state->pid_list[i].pid =0 ; - state->pid_list[i].active =0 ; - } - state->feedcount =0 ; - }else -return -EINVAL ; - -return 0 ; -} - -void dib3000_dealloc_pid_list (struct dib3000_state *state) -{ -if (state !=NULL && state->pid_list !=NULL ) -kfree (state->pid_list); -} - -/* fetch a pid from pid_list */ -int dib3000_get_pid_index (struct dib3000_pid pid_list[],int num_pids,int pid, -spinlock_t *pid_list_lock,int onoff) -{ -int i,ret =-1 ; -unsigned long flags; - -spin_lock_irqsave (pid_list_lock,flags); -for (i=0 ; i < num_pids; i++) -if (onoff) { -if (!pid_list[i].active) { - pid_list[i].pid = pid; - pid_list[i].active =1 ; - ret = i; -break ; - } - }else { -if (pid_list[i].active && pid_list[i].pid == pid) { - pid_list[i].pid =0 ; - pid_list[i].active =0 ; - ret = i; -break ; - } - } - -deb_info ("setting pid: %5d %04x at index %d '%s'\n" ,pid,pid,ret,onoff ?"on" :"off" ); - -spin_unlock_irqrestore (pid_list_lock,flags); -return ret; -} -int dib3000_search_status (u16 irq,u16 lock) {if (irq &0x02 ) {
@@ -139,7 +79,4 @@EXPORT_SYMBOL (dib3000_read_reg);EXPORT_SYMBOL (dib3000_write_reg); -EXPORT_SYMBOL (dib3000_init_pid_list); -EXPORT_SYMBOL (dib3000_dealloc_pid_list); -EXPORT_SYMBOL (dib3000_get_pid_index);EXPORT_SYMBOL (dib3000_search_status);
drivers/media/dvb/frontends/dib3000-common.h +11 -27
@@ -4,7 +4,7 @@* * DiBcom (http://www.dibcom.fr/) * -* Copyright (C) 2004 Patrick Boettcher ([email protected]) +* Copyright (C) 2004-5 Patrick Boettcher ([email protected]) * * based on GPL code from DibCom, which has *
@@ -29,19 +28,10 @@#include "dvb_frontend.h" #include "dib3000.h" -/* info and err, taken from usb.h, if there is anything available like by default, -* please change ! -*/ -#define err(format, arg...) printk(KERN_ERR "%s: " format "\n" , __FILE__ , ## arg) -#define info(format, arg...) printk(KERN_INFO "%s: " format "\n" , __FILE__ , ## arg) -#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n" , __FILE__ , ## arg) - -/* a PID for the pid_filter list, when in use */ -struct dib3000_pid -{ -u16 pid; -int active; -}; +/* info and err, taken from usb.h, if there is anything available like by default. */ +#define err(format, arg...) printk(KERN_ERR "dib3000mX: " format "\n" , ## arg) +#define info(format, arg...) printk(KERN_INFO "dib3000mX: " format "\n" , ## arg) +#define warn(format, arg...) printk(KERN_WARNING "dib3000mX: " format "\n" , ## arg)/* frontend state */ struct dib3000_state {
@@ -52,25 +42,18 @@/* configuration settings */ struct dib3000_config config; -spinlock_t pid_list_lock; -struct dib3000_pid *pid_list; - -int feedcount; -struct dvb_frontend frontend;int timing_offset;int timing_offset_comp_done; + +fe_bandwidth_t last_tuned_bw; +u32 last_tuned_freq; };/* commonly used methods by the dib3000mb/mc/p frontend */ extern int dib3000_read_reg (struct dib3000_state *state,u16 reg);extern int dib3000_write_reg (struct dib3000_state *state,u16 reg,u16 val); -extern int dib3000_init_pid_list (struct dib3000_state *state,int num); -extern void dib3000_dealloc_pid_list (struct dib3000_state *state); -extern int dib3000_get_pid_index (struct dib3000_pid pid_list[],int num_pids, -int pid,spinlock_t *pid_list_lock,int onoff); -extern int dib3000_search_status (u16 irq,u16 lock);/* handy shortcuts */
@@ -81,7 +64,7 @@#define wr_foreach (a,v) { int i; \ if (sizeof(a) != sizeof(v)) \ - err("sizeof: %zd %zd is different",sizeof(a),sizeof(v));\ + err("sizeof: %d %d is different",sizeof(a),sizeof(v));\ for (i=0; i < sizeof(a)/sizeof(u16); i++) \ wr(a[i],v[i]); \ }
@@ -136,8 +119,8 @@#define DIB3000_DDS_INVERSION_OFF ( 0)#define DIB3000_DDS_INVERSION_ON ( 1) -#define DIB3000_TUNER_WRITE_ENABLE (a) (0xffff & (a << 7)) -#define DIB3000_TUNER_WRITE_DISABLE (a) (0xffff & ((a << 7) | (1 << 7))) +#define DIB3000_TUNER_WRITE_ENABLE (a) (0xffff & (a << 8)) +#define DIB3000_TUNER_WRITE_DISABLE (a) (0xffff & ((a << 8) | (1 << 7)))/* for auto search */ extern u16 dib3000_seq[2 ][2 ][2 ];
drivers/media/dvb/frontends/dib3000.h +10 -11
@@ -2,7 +2,7 @@* public header file of the frontend drivers for mobile DVB-T demodulators * DiBcom 3000-MB and DiBcom 3000-MC/P (http://www.dibcom.fr/) * -* Copyright (C) 2004 Patrick Boettcher ([email protected]) +* Copyright (C) 2004-5 Patrick Boettcher ([email protected]) * * based on GPL code from DibCom, which has *
@@ -31,25 +31,24 @@/* the demodulator's i2c address */ u8 demod_address; -/* The i2c address of the PLL */ -u8 pll_addr; - -/* PLL maintenance */ -int (*pll_init)(struct dvb_frontend *fe); - int (*pll_set)(struct dvb_frontend *fe, struct dvb_frontend_parameters* params); +/* PLL maintenance and the i2c address of the PLL */ +u8 (*pll_addr)(struct dvb_frontend *fe); +int (*pll_init)(struct dvb_frontend *fe,u8 pll_buf[5 ]); +int (*pll_set)(struct dvb_frontend *fe,struct dvb_frontend_parameters * params,u8 pll_buf[5 ]); }; -struct dib3000_xfer_ops +struct dib_fe_xfer_ops {/* pid and transfer handling is done in the demodulator */ int (*pid_parse)(struct dvb_frontend *fe,int onoff);int (*fifo_ctrl)(struct dvb_frontend *fe,int onoff); -int (*pid_ctrl)(struct dvb_frontend *fe,int pid,int onoff); +int (*pid_ctrl)(struct dvb_frontend *fe,int index,int pid,int onoff); +int (*tuner_pass_ctrl)(struct dvb_frontend *fe,int onoff,u8 pll_ctrl); };extern struct dvb_frontend *dib3000mb_attach (const struct dib3000_config * config, -struct i2c_adapter * i2c,struct dib3000_xfer_ops *xfer_ops); +struct i2c_adapter * i2c,struct dib_fe_xfer_ops *xfer_ops);extern struct dvb_frontend *dib3000mc_attach (const struct dib3000_config * config, -struct i2c_adapter * i2c,struct dib3000_xfer_ops *xfer_ops); +struct i2c_adapter * i2c,struct dib_fe_xfer_ops *xfer_ops);#endif // DIB3000_H
drivers/media/dvb/frontends/dib3000mb.c +27 -25
137 lines not on this page · raw message
drivers/media/dvb/frontends/dib3000mc.c +300 -229
708 lines not on this page · raw message
drivers/media/dvb/frontends/dib3000mc_priv.h +23 -34
91 lines not on this page · raw message
PATCH 7/9 nxt2002: add ATSC support, misc fixes
In reply to Johannes Stezenbach- [DVB] mt352: exported a mt352_read_reg-function, implemented a single byte write_register function (needed for dibusb)
- [DVB] nxt2002: patch by Taylor Jacob to add support for ATSC/VSB frontends and the B2C2/BBTI Air2PC-ATSC card
- [DVB] stv0297: fix tuning problems and compile time warnings, patch by Markus Breitenberger
- [DVB] fix spelling errors in various frontend drivers
drivers/media/dvb/frontends/mt352.c +18 -6
@@ -58,16 +58,26 @@if (debug)printk (KERN_DEBUG "mt352: " args); \ }while (0 ) -int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen) +static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val) {struct mt352_state * state = (struct mt352_state *) fe->demodulator_priv; +u8 buf[2 ] = { reg, val };struct i2c_msg msg = { .addr = state->config->demod_address, .flags =0 , - .buf = ibuf, .len = ilen }; + .buf = buf, .len =2 };int err =i2c_transfer (state->i2c, &msg,1 );if (err !=1 ) { -dprintk ("mt352_write() failed (err = %d)!\n" , err); +dprintk ("mt352_write() to reg %x failed (err = %d)!\n" , reg, err);return err; } +return 0 ; +} + +int mt352_write (struct dvb_frontend * fe,u8 * ibuf,int ilen) +{ +int err,i; +for (i=0 ; i < ilen-1 ; i++) +if ((err =mt352_single_write (fe,ibuf[0 ]+i,ibuf[i+1 ]))) +return err;return 0 ; }
@@ -92,9 +102,10 @@return b1[0 ]; } - - - +u8 mt352_read (struct dvb_frontend *fe,u8 reg) +{ +return mt352_read_register (fe->demodulator_priv,reg); +}
@@ -556,3 +567,4 @@EXPORT_SYMBOL (mt352_attach);EXPORT_SYMBOL (mt352_write); +EXPORT_SYMBOL (mt352_read);
drivers/media/dvb/frontends/mt352.h +1 -0
@@ -54,5 +54,6 @@ struct i2c_adapter* i2c);extern int mt352_write (struct dvb_frontend * fe,u8 * ibuf,int ilen); +extern u8 mt352_read (struct dvb_frontend *fe,u8 reg);#endif // MT352_H
drivers/media/dvb/frontends/nxt2002.c +670 -0
670 lines not on this page · raw message
drivers/media/dvb/frontends/nxt2002.h +23 -0
@@ -0,0 +1,23 @@ +/* +Driver for the Nxt2002 demodulator +*/ + +#ifndef NXT2002_H +#define NXT2002_H + +#include <linux/dvb/frontend.h> +#include <linux/firmware.h> + +struct nxt2002_config +{ +/* the demodulator's i2c address */ +u8 demod_address; + +/* request firmware for device */ +int (*request_firmware)(struct dvb_frontend * fe,const struct firmware **fw,char * name); +}; + +extern struct dvb_frontend *nxt2002_attach (const struct nxt2002_config * config, +struct i2c_adapter * i2c); + +#endif // NXT2002_H
drivers/media/dvb/frontends/stv0297.c +63 -31
204 lines not on this page · raw message
drivers/media/dvb/frontends/stv0297.h +3 -0
@@ -29,6 +29,9 @@/* the demodulator's i2c address */ u8 demod_address; +/* does the "inversion" need inverted? */ + u8 invert:1; +/* PLL maintenance */ int (*pll_init)(struct dvb_frontend * fe);int (*pll_set)(struct dvb_frontend * fe,struct dvb_frontend_parameters * params);
drivers/media/dvb/frontends/tda10021.c +1 -1
@@ -4,7 +4,7 @@ Copyright (C) 1999 Convergence Integrated Media GmbH <[email protected]> Copyright (C) 2004 Markus Schulz <[email protected]> - Suppport for TDA10021 + Support for TDA10021 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
drivers/media/dvb/frontends/tda10021.h +1 -1
@@ -4,7 +4,7 @@ Copyright (C) 1999 Convergence Integrated Media GmbH <[email protected]> Copyright (C) 2004 Markus Schulz <[email protected]> - Suppport for TDA10021 + Support for TDA10021 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
drivers/media/dvb/frontends/tda80xx.c +1 -1
@@ -27,10 +27,10 @@#include <linux/spinlock.h> #include <linux/threads.h> #include <linux/interrupt.h> +#include <linux/irq.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> -#include <asm/irq.h> #include <asm/div64.h> #include "dvb_frontend.h"
PATCH 8/9 dvb-ttpci: fix SMP race, budget: fixe init race, misc fixes
In reply to Johannes Stezenbach- [DVB] dvb-ttpci: re-added support for Fujitsu-Siemens DVB-S rev 1.6 0x13c2:0x0006
- [DVB] dvb-ttpci: finally clean up debi irq/tasklet handling to make it work on SMP
- [DVB] dvb-ttpci: misc. changes to av7110_send_fw_cmd() error handling done along the way
- [DVB] dvb-ttpci: budgetpatch integrated into dvb-ttpci: enables full ts option running in parallel with all previous functions of dvb-ttpci
- [DVB] dvb-ttpci: fix Oops provoked by insmod/rmmod test loop, patch by Emard
- [DVB] budget: Fixed start_ts_capture(): saa7146 will not issue a VPE interrupt
if VPE bit is set in PSR and VPE interrupts are enabled afterwards.
- [DVB] budget: enable satelco support. code was commented out, but actually it works, patch by Emard
- [DVB] budget: Budget patch improved driver, fixed slight packet loss by using different trigger mode
drivers/media/dvb/ttpci/av7110.c +507 -85
@@ -67,6 +67,12 @@#include "av7110_ca.h" #include "av7110_ipack.h" +#define TS_WIDTH 376 +#define TS_HEIGHT 512 +#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT) +#define TS_MAX_PACKETS (TS_BUFLEN/TS_SIZE) + +int av7110_debug;static int vidmode=CVBS_RGB_OUT ;
@@ -75,6 +81,7 @@static int hw_sections;static int rgb_on;static int volume =255 ; +static int budgetpatch =0 ;module_param_named (debug, av7110_debug, int,0644 );MODULE_PARM_DESC (debug,"debug level (bitmask, default 0)" );
@@ -91,6 +98,8 @@ " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");module_param (volume, int,0444 );MODULE_PARM_DESC (volume,"initial volume: default 255 (range 0-255)" ); +module_param (budgetpatch, int,0444 ); +MODULE_PARM_DESC (budgetpatch,"use budget-patch hardware modification: default 0 (0 no, 1 autodetect, 2 always)" );static void restart_feeds (struct av7110 *av7110);
@@ -349,27 +358,42 @@#endif } +#define DEBI_READ 0 +#define DEBI_WRITE 1 +static inline void start_debi_dma (struct av7110 *av7110,int dir, +unsigned long addr,unsigned int len) +{ +dprintk (8 ,"%c %08lx %u\n" , dir ==DEBI_READ ?'R' :'W' , addr, len); +if (saa7146_wait_for_debi_done (av7110->dev,0 )) { +printk (KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n" , __FUNCTION__); +return ; + } + +SAA7146_ISR_CLEAR (av7110->dev,MASK_19 );/* for good measure */ +SAA7146_IER_ENABLE (av7110->dev,MASK_19 ); +if (len <5 ) + len =5 ;/* we want a real DEBI DMA */ +if (dir ==DEBI_WRITE ) +iwdebi (av7110,DEBISWAB , addr,0 , (len +3 ) & ~3 ); +else +irdebi (av7110,DEBISWAB , addr,0 , len); +} +static void debiirq (unsigned long data) {struct av7110 *av7110 = (struct av7110 *) data;int type=av7110->debitype;int handle=(type>>8 )&0x1f ; - -// dprintk(4, "%p\n",av7110); +unsigned int xfer =0 ;print_time ("debi" ); -SAA7146_IER_DISABLE (av7110->dev,MASK_19 ); -SAA7146_ISR_CLEAR (av7110->dev,MASK_19 ); +dprintk (4 ,"type 0x%04x\n" , type);if (type==-1 ) {printk ("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n" , jiffies,saa7146_read (av7110->dev,PSR ),saa7146_read (av7110->dev,SSR )); -spin_lock (&av7110->debilock); -ARM_ClearMailBox (av7110); -ARM_ClearIrq (av7110); -spin_unlock (&av7110->debilock); -return ; + goto debi_done; } av7110->debitype=-1 ;
@@ -379,22 +403,16 @@dvb_dmx_swfilter_packets (&av7110->demux, (const u8 *)av7110->debi_virt, av7110->debilen/188 ); -spin_lock (&av7110->debilock); -iwdebi (av7110,DEBINOSWAP ,RX_BUFF ,0 ,2 ); -ARM_ClearMailBox (av7110); -spin_unlock (&av7110->debilock); -return ; + xfer =RX_BUFF ; +break ;case DATA_PES_RECORD :if (av7110->demux.recording)av7110_record_cb (&av7110->p2t[handle], (u8 *)av7110->debi_virt, av7110->debilen); -spin_lock (&av7110->debilock); -iwdebi (av7110,DEBINOSWAP ,RX_BUFF ,0 ,2 ); -ARM_ClearMailBox (av7110); -spin_unlock (&av7110->debilock); -return ; + xfer =RX_BUFF ; +break ;case DATA_IPMPE :case DATA_FSECTION :
@@ -404,11 +422,8 @@ av7110->debilen,NULL ,0 , av7110->handle2filter[handle], DMX_OK, av7110); -spin_lock (&av7110->debilock); -iwdebi (av7110,DEBINOSWAP ,RX_BUFF ,0 ,2 ); -ARM_ClearMailBox (av7110); -spin_unlock (&av7110->debilock); -return ; + xfer =RX_BUFF ; +break ;case DATA_CI_GET : {
@@ -425,11 +440,8 @@ci_get_data (&av7110->ci_rbuffer, av7110->debi_virt, av7110->debilen); -spin_lock (&av7110->debilock); -iwdebi (av7110,DEBINOSWAP ,RX_BUFF ,0 ,2 ); -ARM_ClearMailBox (av7110); -spin_unlock (&av7110->debilock); -return ; + xfer =RX_BUFF ; +break ; }case DATA_COMMON_INTERFACE :
@@ -449,37 +461,35 @@printk ("\n" ); }#endif -spin_lock (&av7110->debilock); -iwdebi (av7110,DEBINOSWAP ,RX_BUFF ,0 ,2 ); -ARM_ClearMailBox (av7110); -spin_unlock (&av7110->debilock); -return ; + xfer =RX_BUFF ; +break ;case DATA_DEBUG_MESSAGE : ((s8 *)av7110->debi_virt)[Reserved_SIZE-1 ]=0 ;printk ("%s\n" , (s8 *)av7110->debi_virt); -spin_lock (&av7110->debilock); -iwdebi (av7110,DEBINOSWAP ,RX_BUFF ,0 ,2 ); -ARM_ClearMailBox (av7110); -spin_unlock (&av7110->debilock); -return ; + xfer =RX_BUFF ; +break ;case DATA_CI_PUT : +dprintk (4 ,"debi DATA_CI_PUT\n" );case DATA_MPEG_PLAY : +dprintk (4 ,"debi DATA_MPEG_PLAY\n" );case DATA_BMP_LOAD : -spin_lock (&av7110->debilock); -iwdebi (av7110,DEBINOSWAP ,TX_BUFF ,0 ,2 ); -ARM_ClearMailBox (av7110); -spin_unlock (&av7110->debilock); -return ; +dprintk (4 ,"debi DATA_BMP_LOAD\n" ); + xfer =TX_BUFF ; +break ;default :break ; } +debi_done:spin_lock (&av7110->debilock); +if (xfer) +iwdebi (av7110,DEBINOSWAP , xfer,0 ,2 );ARM_ClearMailBox (av7110);spin_unlock (&av7110->debilock); } +/* irq from av7110 firmware writing the mailbox register in the DPRAM */ static void gpioirq (unsigned long data) {struct av7110 *av7110 = (struct av7110 *) data;
@@ -487,27 +497,29 @@int len;if (av7110->debitype !=-1 ) +/* we shouldn't get any irq while a debi xfer is running */ printk ("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n" , jiffies,saa7146_read (av7110->dev,PSR ),saa7146_read (av7110->dev,SSR )); -spin_lock (&av7110->debilock); +if (saa7146_wait_for_debi_done (av7110->dev,0 )) { +printk (KERN_ERR "%s: saa7146_wait_for_debi_done timed out\n" , __FUNCTION__); +BUG ();/* maybe we should try resetting the debi? */ + } +spin_lock (&av7110->debilock);ARM_ClearIrq (av7110); -SAA7146_IER_DISABLE (av7110->dev,MASK_19 ); -SAA7146_ISR_CLEAR (av7110->dev,MASK_19 ); - +/* see what the av7110 wants */ av7110->debitype =irdebi (av7110,DEBINOSWAP ,IRQ_STATE ,0 ,2 ); av7110->debilen =irdebi (av7110,DEBINOSWAP ,IRQ_STATE_EXT ,0 ,2 ); rxbuf=irdebi (av7110,DEBINOSWAP ,RX_BUFF ,0 ,2 ); txbuf=irdebi (av7110,DEBINOSWAP ,TX_BUFF ,0 ,2 ); len = (av7110->debilen +3 ) & ~3 ; -// dprintk(8, "GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen); print_time ("gpio" ); +dprintk (8 ,"GPIO0 irq 0x%04x %d\n" , av7110->debitype, av7110->debilen); -// dprintk(8, "GPIO0 irq %02x\n", av7110->debitype&0xff); switch (av7110->debitype&0xff ) {case DATA_TS_PLAY :
@@ -579,16 +591,12 @@dvb_ringbuffer_read (cibuf,av7110->debi_virt,len,0 ); -wake_up (&cibuf->queue);iwdebi (av7110,DEBINOSWAP ,TX_LEN , len,2 );iwdebi (av7110,DEBINOSWAP ,IRQ_STATE_EXT , len,2 ); -saa7146_wait_for_debi_done (av7110->dev,0 ); -saa7146_write (av7110->dev,IER , -saa7146_read (av7110->dev,IER ) |MASK_19 ); -if (len <5 ) - len =5 ;/* we want a real DEBI DMA */ -iwdebi (av7110,DEBISWAB ,DPRAM_BASE +txbuf,0 , (len+3 )&~3 ); +dprintk (8 ,"DMA: CI\n" ); +start_debi_dma (av7110,DEBI_WRITE ,DPRAM_BASE + txbuf, len);spin_unlock (&av7110->debilock); +wake_up (&cibuf->queue);return ; }
@@ -620,22 +628,21 @@dprintk (8 ,"GPIO0 PES_PLAY len=%04x\n" , len);iwdebi (av7110,DEBINOSWAP ,TX_LEN , len,2 );iwdebi (av7110,DEBINOSWAP ,IRQ_STATE_EXT , len,2 ); -saa7146_wait_for_debi_done (av7110->dev,0 ); -saa7146_write (av7110->dev,IER , -saa7146_read (av7110->dev,IER ) |MASK_19 ); - -iwdebi (av7110,DEBISWAB ,DPRAM_BASE +txbuf,0 , (len+3 )&~3 ); +dprintk (8 ,"DMA: MPEG_PLAY\n" ); +start_debi_dma (av7110,DEBI_WRITE ,DPRAM_BASE + txbuf, len);spin_unlock (&av7110->debilock);return ;case DATA_BMP_LOAD : len=av7110->debilen; +dprintk (8 ,"gpio DATA_BMP_LOAD len %d\n" , len);if (!len) { av7110->bmp_state=BMP_LOADED ;iwdebi (av7110,DEBINOSWAP ,IRQ_STATE_EXT ,0 ,2 );iwdebi (av7110,DEBINOSWAP ,TX_LEN ,0 ,2 );iwdebi (av7110,DEBINOSWAP ,TX_BUFF ,0 ,2 );wake_up (&av7110->bmpq); +dprintk (8 ,"gpio DATA_BMP_LOAD done\n" );break ; }if (len>av7110->bmplen)
@@ -647,12 +654,8 @@memcpy (av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len); av7110->bmpp+=len; av7110->bmplen-=len; -saa7146_wait_for_debi_done (av7110->dev,0 ); -saa7146_write (av7110->dev,IER , -saa7146_read (av7110->dev,IER ) |MASK_19 ); -if (len <5 ) - len =5 ;/* we want a real DEBI DMA */ -iwdebi (av7110,DEBISWAB ,DPRAM_BASE +txbuf,0 , (len+3 )&~3 ); +dprintk (8 ,"gpio DATA_BMP_LOAD DMA len %d\n" , len); +start_debi_dma (av7110,DEBI_WRITE ,DPRAM_BASE +txbuf, len);spin_unlock (&av7110->debilock);return ;
@@ -669,22 +672,17 @@case DATA_TS_RECORD :case DATA_PES_RECORD : -saa7146_wait_for_debi_done (av7110->dev,0 ); -saa7146_write (av7110->dev,IER , -saa7146_read (av7110->dev,IER ) |MASK_19 ); -irdebi (av7110,DEBISWAB ,DPRAM_BASE +rxbuf,0 , len); +dprintk (8 ,"DMA: TS_REC etc.\n" ); +start_debi_dma (av7110,DEBI_READ ,DPRAM_BASE +rxbuf, len);spin_unlock (&av7110->debilock);return ;case DATA_DEBUG_MESSAGE : -saa7146_wait_for_debi_done (av7110->dev,0 );if (!len || len>0xff ) {iwdebi (av7110,DEBINOSWAP ,RX_BUFF ,0 ,2 );break ; } -saa7146_write (av7110->dev,IER , -saa7146_read (av7110->dev,IER ) |MASK_19 ); -irdebi (av7110,DEBISWAB , Reserved,0 , len); +start_debi_dma (av7110,DEBI_READ , Reserved, len);spin_unlock (&av7110->debilock);return ;
@@ -699,8 +697,8 @@ av7110->debitype, av7110->debilen);break ; } -ARM_ClearMailBox (av7110); av7110->debitype=-1 ; +ARM_ClearMailBox (av7110);spin_unlock (&av7110->debilock); }
@@ -1145,11 +1144,107 @@return 0 ; } +/* simplified code from budget-core.c */ +static int stop_ts_capture (struct av7110 *budget) +{ +dprintk (2 ,"budget: %p\n" , budget); + +if (--budget->feeding1) +return budget->feeding1; +saa7146_write (budget->dev,MC1 ,MASK_20 );/* DMA3 off */ +SAA7146_IER_DISABLE (budget->dev,MASK_10 ); +SAA7146_ISR_CLEAR (budget->dev,MASK_10 ); +return 0 ; +} + +static int start_ts_capture (struct av7110 *budget) +{ +dprintk (2 ,"budget: %p\n" , budget); + +if (budget->feeding1) +return ++budget->feeding1; +memset (budget->grabbing,0x00 ,TS_HEIGHT *TS_WIDTH ); + budget->tsf =0xff ; + budget->ttbp =0 ; +SAA7146_IER_ENABLE (budget->dev,MASK_10 );/* VPE */ +saa7146_write (budget->dev,MC1 , (MASK_04 |MASK_20 ));/* DMA3 on */ +return ++budget->feeding1; +} + +static int budget_start_feed (struct dvb_demux_feed *feed) +{ +struct dvb_demux *demux = feed->demux; +struct av7110 *budget = (struct av7110 *) demux->priv; +int status; + +dprintk (2 ,"av7110: %p\n" , budget); + +spin_lock (&budget->feedlock1); + feed->pusi_seen =0 ;/* have a clean section start */ + status =start_ts_capture (budget); +spin_unlock (&budget->feedlock1); +return status; +} + +static int budget_stop_feed (struct dvb_demux_feed *feed) +{ +struct dvb_demux *demux = feed->demux; +struct av7110 *budget = (struct av7110 *) demux->priv; +int status; + +dprintk (2 ,"budget: %p\n" , budget); + +spin_lock (&budget->feedlock1); + status =stop_ts_capture (budget); +spin_unlock (&budget->feedlock1); +return status; +} + +static void vpeirq (unsigned long data) +{ +struct av7110 *budget = (struct av7110 *) data; +u8 *mem = (u8 *) (budget->grabbing); +u32 olddma = budget->ttbp; +u32 newdma =saa7146_read (budget->dev,PCI_VDP3 ); + +if (!budgetpatch) { +printk ("av7110.c: vpeirq() called while budgetpatch disabled!" +" check saa7146 IER register\n" ); +BUG (); + } +/* nearest lower position divisible by 188 */ + newdma -= newdma %188 ; + +if (newdma >=TS_BUFLEN ) +return ; + + budget->ttbp = newdma; + +if (!budget->feeding1 || (newdma == olddma)) +return ; + +#if 0 +/* track rps1 activity */ +printk ("vpeirq: %02x Event Counter 1 0x%04x\n" , + mem[olddma], +saa7146_read (budget->dev,EC1R ) &0x3fff ); +#endif + +if (newdma > olddma) +/* no wraparound, dump olddma..newdma */ +dvb_dmx_swfilter_packets (&budget->demux1, mem + olddma, (newdma - olddma) /188 ); +else { +/* wraparound, dump olddma..buflen and 0..newdma */ +dvb_dmx_swfilter_packets (&budget->demux1, mem + olddma, (TS_BUFLEN - olddma) /188 ); +dvb_dmx_swfilter_packets (&budget->demux1, mem, newdma /188 ); + } +}static int av7110_register (struct av7110 *av7110) {int ret, i;struct dvb_demux *dvbdemux=&av7110->demux; +struct dvb_demux *dvbdemux1 = &av7110->demux1;dprintk (4 ,"%p\n" , av7110);
@@ -1209,6 +1304,32 @@dvb_net_init (av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx); +if (budgetpatch) { +/* initialize software demux1 without its own frontend +* demux1 hardware is connected to frontend0 of demux0 +*/ + dvbdemux1->priv = (void *) av7110; + + dvbdemux1->filternum =256 ; + dvbdemux1->feednum =256 ; + dvbdemux1->start_feed = budget_start_feed; + dvbdemux1->stop_feed = budget_stop_feed; + dvbdemux1->write_to_decoder =NULL ; + + dvbdemux1->dmx.capabilities = (DMX_TS_FILTERING |DMX_SECTION_FILTERING | +DMX_MEMORY_BASED_FILTERING ); + +dvb_dmx_init (&av7110->demux1); + + av7110->dmxdev1.filternum =256 ; + av7110->dmxdev1.demux = &dvbdemux1->dmx; + av7110->dmxdev1.capabilities =0 ; + +dvb_dmxdev_init (&av7110->dmxdev1, av7110->dvb_adapter); + +dvb_net_init (av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx); +printk ("dvb-ttpci: additional demux1 for budget-patch registered\n" ); + }return 0 ; }
@@ -1216,12 +1337,20 @@static void dvb_unregister (struct av7110 *av7110) {struct dvb_demux *dvbdemux=&av7110->demux; +struct dvb_demux *dvbdemux1 = &av7110->demux1;dprintk (4 ,"%p\n" , av7110);if (!av7110->registered)return ; +if (budgetpatch) { +dvb_net_release (&av7110->dvb_net1); + dvbdemux->dmx.close (&dvbdemux1->dmx); +dvb_dmxdev_release (&av7110->dmxdev1); +dvb_dmx_release (&av7110->demux1); + } +dvb_net_release (&av7110->dvb_net); dvbdemux->dmx.close (&dvbdemux->dmx);
@@ -1700,6 +1829,7 @@static struct stv0297_config nexusca_stv0297_config = { .demod_address =0x1C , + .invert =1 , .pll_set = nexusca_stv0297_pll_set, };
@@ -1899,12 +2029,22 @@ av7110->fe =ves1820_attach (&alps_tdbe2_config, &av7110->i2c_adap,read_pwm (av7110));break ; +case 0x0006 :/* Fujitsu-Siemens DVB-S rev 1.6 */ +/* Grundig 29504-451 */ + av7110->fe =tda8083_attach (&grundig_29504_451_config, &av7110->i2c_adap); +if (av7110->fe) { + av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; + av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; + av7110->fe->ops->set_tone = av7110_set_tone; + } +break ; +case 0x000A :// Hauppauge/TT Nexus-CA rev1.X av7110->fe =stv0297_attach (&nexusca_stv0297_config, &av7110->i2c_adap,0x7b );if (av7110->fe) {/* set TDA9819 into DVB mode */ -saa7146_setgpio (av7110->dev,1 ,SAA7146_GPIO_OUTHI );// TDA9198 pin9(STD) +saa7146_setgpio (av7110->dev,1 ,SAA7146_GPIO_OUTLO );// TDA9198 pin9(STD) saa7146_setgpio (av7110->dev,3 ,SAA7146_GPIO_OUTLO );// TDA9198 pin30(VIF) /* tuner on this needs a slower i2c bus speed */
@@ -1940,13 +2080,169 @@ } } +/* Budgetpatch note: +* Original hardware design by Roberto Deza: +* There is a DVB_Wiki at +* http://212.227.36.83/linuxtv/wiki/index.php/Main_Page +* where is described this 'DVB TT Budget Patch', on Card Modding: +* http://212.227.36.83/linuxtv/wiki/index.php/DVB_TT_Budget_Patch +* On the short description there is also a link to a external file, +* with more details: +* http://perso.wanadoo.es/jesussolano/Ttf_tsc1.zip +* +* New software triggering design by Emard that works on +* original Roberto Deza's hardware: +* +* rps1 code for budgetpatch will copy internal HS event to GPIO3 pin. +* GPIO3 is in budget-patch hardware connectd to port B VSYNC +* HS is an internal event of 7146, accessible with RPS +* and temporarily raised high every n lines +* (n in defined in the RPS_THRESH1 counter threshold) +* I think HS is raised high on the beginning of the n-th line +* and remains high until this n-th line that triggered +* it is completely received. When the receiption of n-th line +* ends, HS is lowered. +* +* To transmit data over DMA, 7146 needs changing state at +* port B VSYNC pin. Any changing of port B VSYNC will +* cause some DMA data transfer, with more or less packets loss. +* It depends on the phase and frequency of VSYNC and +* the way of 7146 is instructed to trigger on port B (defined +* in DD1_INIT register, 3rd nibble from the right valid +* numbers are 0-7, see datasheet) +* +* The correct triggering can minimize packet loss, +* dvbtraffic should give this stable bandwidths: +* 22k transponder = 33814 kbit/s +* 27.5k transponder = 38045 kbit/s +* by experiment it is found that the best results +* (stable bandwidths and almost no packet loss) +* are obtained using DD1_INIT triggering number 2 +* (Va at rising edge of VS Fa = HS x VS-failing forced toggle) +* and a VSYNC phase that occurs in the middle of DMA transfer +* (about byte 188*512=96256 in the DMA window). +* +* Phase of HS is still not clear to me how to control, +* It just happens to be so. It can be seen if one enables +* RPS_IRQ and print Event Counter 1 in vpeirq(). Every +* time RPS_INTERRUPT is called, the Event Counter 1 will +* increment. That's how the 7146 is programmed to do event +* counting in this budget-patch.c +* I *think* HPS setting has something to do with the phase +* of HS but I cant be 100% sure in that. +* +* hardware debug note: a working budget card (including budget patch) +* with vpeirq() interrupt setup in mode "0x90" (every 64K) will +* generate 3 interrupts per 25-Hz DMA frame of 2*188*512 bytes +* and that means 3*25=75 Hz of interrupt freqency, as seen by +* watch cat /proc/interrupts +* +* If this frequency is 3x lower (and data received in the DMA +* buffer don't start with 0x47, but in the middle of packets, +* whose lengths appear to be like 188 292 188 104 etc. +* this means VSYNC line is not connected in the hardware. +* (check soldering pcb and pins) +* The same behaviour of missing VSYNC can be duplicated on budget +* cards, by seting DD1_INIT trigger mode 7 in 3rd nibble. +*/ static int av7110_attach (struct saa7146_dev * dev,struct saa7146_pci_extension_data *pci_ext) {struct av7110 *av7110 =NULL ; +int length =TS_WIDTH *TS_HEIGHT ;int ret =0 ; +int count =0 ;dprintk (4 ,"dev: %p\n" , dev); +/* Set RPS_IRQ to 1 to track rps1 activity. +* Enabling this won't send any interrupt to PC CPU. +*/ +#define RPS_IRQ 0 + +if (budgetpatch ==1 ) { + budgetpatch =0 ; +/* autodetect the presence of budget patch +* this only works if saa7146 has been recently +* reset with with MASK_31 to MC1 +* +* will wait for VBI_B event (vertical blank at port B) +* and will reset GPIO3 after VBI_B is detected. +* (GPIO3 should be raised high by CPU to +* test if GPIO3 will generate vertical blank signal +* in budget patch GPIO3 is connected to VSYNC_B +*/ + +/* RESET SAA7146 */ +saa7146_write (dev,MC1 ,MASK_31 ); +/* autodetection success seems to be time-dependend after reset */ + +/* Fix VSYNC level */ +saa7146_setgpio (dev,3 ,SAA7146_GPIO_OUTLO ); +/* set vsync_b triggering */ +saa7146_write (dev,DD1_STREAM_B ,0 ); +/* port B VSYNC at rising edge */ +saa7146_write (dev,DD1_INIT ,0x00000200 ); +saa7146_write (dev,BRS_CTRL ,0x00000000 );// VBI +saa7146_write (dev,MC2 , +1 * (MASK_08 |MASK_24 ) |// BRS control +0 * (MASK_09 |MASK_25 ) |// a +1 * (MASK_10 |MASK_26 ) |// b +0 * (MASK_06 |MASK_22 ) |// HPS_CTRL1 +0 * (MASK_05 |MASK_21 ) |// HPS_CTRL2 +0 * (MASK_01 |MASK_15 )// DEBI + ); + +/* start writing RPS1 code from beginning */ + count =0 ; +/* Disable RPS1 */ +saa7146_write (dev,MC1 ,MASK_29 ); +/* RPS1 timeout disable */ +saa7146_write (dev,RPS_TOV1 ,0 ); +WRITE_RPS1 (cpu_to_le32 (CMD_PAUSE |EVT_VBI_B )); +WRITE_RPS1 (cpu_to_le32 (CMD_WR_REG_MASK | (GPIO_CTRL >>2 ))); +WRITE_RPS1 (cpu_to_le32 (GPIO3_MSK )); +WRITE_RPS1 (cpu_to_le32 (SAA7146_GPIO_OUTLO <<24 )); +#if RPS_IRQ +/* issue RPS1 interrupt to increment counter */ +WRITE_RPS1 (cpu_to_le32 (CMD_INTERRUPT )); +#endif +WRITE_RPS1 (cpu_to_le32 (CMD_STOP )); +/* Jump to begin of RPS program as safety measure (p37) */ +WRITE_RPS1 (cpu_to_le32 (CMD_JUMP )); +WRITE_RPS1 (cpu_to_le32 (dev->d_rps1.dma_handle)); + +#if RPS_IRQ +/* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) +* use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled +* use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called +*/ +saa7146_write (dev,EC1SSR , (0x03 <<2 ) |3 ); +/* set event counter 1 treshold to maximum allowed value (rEC p55) */ +saa7146_write (dev,ECT1R ,0x3fff ); +#endif +/* Set RPS1 Address register to point to RPS code (r108 p42) */ +saa7146_write (dev,RPS_ADDR1 , dev->d_rps1.dma_handle); +/* Enable RPS1, (rFC p33) */ +saa7146_write (dev,MC1 , (MASK_13 |MASK_29 )); + +mdelay (10 ); +/* now send VSYNC_B to rps1 by rising GPIO3 */ +saa7146_setgpio (dev,3 ,SAA7146_GPIO_OUTHI ); +mdelay (10 ); +/* if rps1 responded by lowering the GPIO3, +* then we have budgetpatch hardware +*/ +if ((saa7146_read (dev,GPIO_CTRL ) &0x10000000 ) ==0 ) { + budgetpatch =1 ; +printk ("dvb-ttpci: BUDGET-PATCH DETECTED.\n" ); + } +/* Disable RPS1 */ +saa7146_write (dev,MC1 , (MASK_29 )); +#if RPS_IRQ +printk ("dvb-ttpci: Event Counter 1 0x%04x\n" ,saa7146_read (dev,EC1R ) &0x3fff ); +#endif + } +/* prepare the av7110 device struct */ if (!(av7110 =kmalloc (sizeof (struct av7110 ),GFP_KERNEL ))) {dprintk (1 ,"out of memory\n" );
@@ -1980,6 +2276,7 @@saa7146_i2c_adapter_prepare (dev, &av7110->i2c_adap,SAA7146_I2C_BUS_BIT_RATE_120 );/* 275 kHz */ if (i2c_add_adapter (&av7110->i2c_adap) <0 ) { +err_no_mem:dvb_unregister_adapter (av7110->dvb_adapter);kfree (av7110);return -ENOMEM ;
@@ -1987,6 +2284,86 @@ttpci_eeprom_parse_mac (&av7110->i2c_adap, av7110->dvb_adapter->proposed_mac); +if (budgetpatch) { +spin_lock_init (&av7110->feedlock1); + av7110->grabbing =saa7146_vmalloc_build_pgtable ( + dev->pci, length, &av7110->pt); +if (!av7110->grabbing) + goto err_no_mem; +saa7146_write (dev,PCI_BT_V1 ,0x1c1f101f ); +saa7146_write (dev,BCS_CTRL ,0x80400040 ); +/* set dd1 stream a & b */ +saa7146_write (dev,DD1_STREAM_B ,0x00000000 ); +saa7146_write (dev,DD1_INIT ,0x03000200 ); +saa7146_write (dev,MC2 , (MASK_09 |MASK_25 |MASK_10 |MASK_26 )); +saa7146_write (dev,BRS_CTRL ,0x60000000 ); +saa7146_write (dev,BASE_ODD3 ,0 ); +saa7146_write (dev,BASE_EVEN3 ,0 ); +saa7146_write (dev,PROT_ADDR3 ,TS_WIDTH *TS_HEIGHT ); +saa7146_write (dev,BASE_PAGE3 , av7110->pt.dma |ME1 |0x90 ); + +saa7146_write (dev,PITCH3 ,TS_WIDTH ); +saa7146_write (dev,NUM_LINE_BYTE3 , (TS_HEIGHT <<16 ) |TS_WIDTH ); + +/* upload all */ +saa7146_write (dev,MC2 ,0x077c077c ); +saa7146_write (dev,GPIO_CTRL ,0x000000 ); +#if RPS_IRQ +/* set event counter 1 source as RPS1 interrupt (0x03) (rE4 p53) +* use 0x03 to track RPS1 interrupts - increase by 1 every gpio3 is toggled +* use 0x15 to track VPE interrupts - increase by 1 every vpeirq() is called +*/ +saa7146_write (dev,EC1SSR , (0x03 <<2 ) |3 ); +/* set event counter 1 treshold to maximum allowed value (rEC p55) */ +saa7146_write (dev,ECT1R ,0x3fff ); +#endif +/* Setup BUDGETPATCH MAIN RPS1 "program" (p35) */ + count =0 ; + +/* Wait Source Line Counter Threshold (p36) */ +WRITE_RPS1 (cpu_to_le32 (CMD_PAUSE |EVT_HS )); +/* Set GPIO3=1 (p42) */ +WRITE_RPS1 (cpu_to_le32 (CMD_WR_REG_MASK | (GPIO_CTRL >>2 ))); +WRITE_RPS1 (cpu_to_le32 (GPIO3_MSK )); +WRITE_RPS1 (cpu_to_le32 (SAA7146_GPIO_OUTHI <<24 )); +#if RPS_IRQ +/* issue RPS1 interrupt */ +WRITE_RPS1 (cpu_to_le32 (CMD_INTERRUPT )); +#endif +/* Wait reset Source Line Counter Threshold (p36) */ +WRITE_RPS1 (cpu_to_le32 (CMD_PAUSE |RPS_INV |EVT_HS )); +/* Set GPIO3=0 (p42) */ +WRITE_RPS1 (cpu_to_le32 (CMD_WR_REG_MASK | (GPIO_CTRL >>2 ))); +WRITE_RPS1 (cpu_to_le32 (GPIO3_MSK )); +WRITE_RPS1 (cpu_to_le32 (SAA7146_GPIO_OUTLO <<24 )); +#if RPS_IRQ +/* issue RPS1 interrupt */ +WRITE_RPS1 (cpu_to_le32 (CMD_INTERRUPT )); +#endif +/* Jump to begin of RPS program (p37) */ +WRITE_RPS1 (cpu_to_le32 (CMD_JUMP )); +WRITE_RPS1 (cpu_to_le32 (dev->d_rps1.dma_handle)); + +/* Fix VSYNC level */ +saa7146_setgpio (dev,3 ,SAA7146_GPIO_OUTLO ); +/* Set RPS1 Address register to point to RPS code (r108 p42) */ +saa7146_write (dev,RPS_ADDR1 , dev->d_rps1.dma_handle); +/* Set Source Line Counter Threshold, using BRS (rCC p43) +* It generates HS event every TS_HEIGHT lines +* this is related to TS_WIDTH set in register +* NUM_LINE_BYTE3. If NUM_LINE_BYTE low 16 bits +* are set to TS_WIDTH bytes (TS_WIDTH=2*188), +* then RPS_THRESH1 should be set to trigger +* every TS_HEIGHT (512) lines. +*/ +saa7146_write (dev,RPS_THRESH1 , (TS_HEIGHT *1 ) |MASK_12 ); + +/* Enable RPS1 (rFC p33) */ +saa7146_write (dev,MC1 , (MASK_13 |MASK_29 )); + +/* end of budgetpatch register initialization */ +tasklet_init (&av7110->vpe_tasklet, vpeirq, (unsigned long ) av7110); + }else {saa7146_write (dev,PCI_BT_V1 ,0x1c00101f );saa7146_write (dev,BCS_CTRL ,0x80400040 );
@@ -1998,6 +2375,7 @@/* upload all */ saa7146_write (dev,MC2 ,0x077c077c );saa7146_write (dev,GPIO_CTRL ,0x000000 ); + }tasklet_init (&av7110->debi_tasklet, debiirq, (unsigned long ) av7110);tasklet_init (&av7110->gpio_tasklet, gpioirq, (unsigned long ) av7110);
@@ -2109,10 +2487,21 @@struct av7110 *av7110 = (struct av7110 *)saa->ext_priv;dprintk (4 ,"%p\n" , av7110); -if (0 == av7110->device_initialized ) { +if (!av7110->device_initialized )return 0 ; - } +if (budgetpatch) { +/* Disable RPS1 */ +saa7146_write (saa,MC1 ,MASK_29 ); +/* VSYNC LOW (inactive) */ +saa7146_setgpio (saa,3 ,SAA7146_GPIO_OUTLO ); +saa7146_write (saa,MC1 ,MASK_20 );/* DMA3 off */ +SAA7146_IER_DISABLE (saa,MASK_10 ); +SAA7146_ISR_CLEAR (saa,MASK_10 ); +msleep (50 ); +tasklet_kill (&av7110->vpe_tasklet); +saa7146_pgtable_free (saa->pci, &av7110->pt); + }av7110_exit_v4l (av7110); av7110->arm_rmmod=1 ;
@@ -2121,6 +2510,9 @@while (av7110->arm_thread)msleep (1 ); +tasklet_kill (&av7110->debi_tasklet); +tasklet_kill (&av7110->gpio_tasklet); +dvb_unregister (av7110);SAA7146_IER_DISABLE (saa,MASK_19 |MASK_03 );
@@ -2153,13 +2545,43 @@ {struct av7110 *av7110 = dev->ext_priv; -if (*isr &MASK_19 ) +//print_time("av7110_irq"); + +/* Note: Don't try to handle the DEBI error irq (MASK_18), in +* intel mode the timeout is asserted all the time... +*/ + +if (*isr &MASK_19 ) { +//printk("av7110_irq: DEBI\n"); +/* Note 1: The DEBI irq is level triggered: We must enable it +* only after we started a DMA xfer, and disable it here +* immediately, or it will be signalled all the time while +* DEBI is idle. +* Note 2: You would think that an irq which is masked is +* not signalled by the hardware. Not so for the SAA7146: +* An irq is signalled as long as the corresponding bit +* in the ISR is set, and disabling irqs just prevents the +* hardware from setting the ISR bit. This means a) that we +* must clear the ISR *after* disabling the irq (which is why +* we must do it here even though saa7146_core did it already), +* and b) that if we were to disable an edge triggered irq +* (like the gpio irqs sadly are) temporarily we would likely +* loose some. This sucks :-( +*/ +SAA7146_IER_DISABLE (av7110->dev,MASK_19 ); +SAA7146_ISR_CLEAR (av7110->dev,MASK_19 );tasklet_schedule (&av7110->debi_tasklet); + } -if (*isr &MASK_03 ) +if (*isr &MASK_03 ) { +//printk("av7110_irq: GPIO\n"); tasklet_schedule (&av7110->gpio_tasklet); } +if ((*isr &MASK_10 ) && budgetpatch) +tasklet_schedule (&av7110->vpe_tasklet); +} +static struct saa7146_extension av7110_extension;
@@ -2173,8 +2595,9 @@MAKE_AV7110_INFO (ttc_1_X,"Technotrend/Hauppauge WinTV Nexus-CA rev1.X" );MAKE_AV7110_INFO (ttc_2_X,"Technotrend/Hauppauge WinTV DVB-C rev2.X" );MAKE_AV7110_INFO (tts_2_X,"Technotrend/Hauppauge WinTV Nexus-S rev2.X" ); -MAKE_AV7110_INFO (tts_1_3se,"Technotrend/Hauppauge WinTV Nexus-S rev1.3" ); +MAKE_AV7110_INFO (tts_1_3se,"Technotrend/Hauppauge WinTV DVB-S rev1.3 SE" );MAKE_AV7110_INFO (fsc,"Fujitsu Siemens DVB-C" ); +MAKE_AV7110_INFO (fss,"Fujitsu Siemens DVB-S rev1.6" );static struct pci_device_id pci_tbl[] = {MAKE_EXTENSION_PCI (tts_1_X,0x13c2 ,0x0000 ),
@@ -2184,10 +2607,10 @@MAKE_EXTENSION_PCI (tts_1_3se,0x13c2 ,0x1002 ),MAKE_EXTENSION_PCI (fsc,0x110a ,0x0000 ),MAKE_EXTENSION_PCI (ttc_1_X,0x13c2 ,0x000a ), +MAKE_EXTENSION_PCI (fss,0x13c2 ,0x0006 ),/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 -/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0006), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-S v???? /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0008), UNDEFINED CARD */ // TT/Hauppauge WinTV DVB-T v???? /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
@@ -2208,7 +2631,7 @@ .attach = av7110_attach, .detach = av7110_detach, - .irq_mask = MASK_19|MASK_03, + .irq_mask = MASK_19 | MASK_03 | MASK_10, .irq_func = av7110_irq, };
drivers/media/dvb/ttpci/av7110.h +13 -1
@@ -115,7 +115,7 @@int bmpp;int bmplen; -int bmp_state; +volatile int bmp_state;#define BMP_NONE 0#define BMP_LOADING 1#define BMP_LOADINGS 2
@@ -158,6 +158,18 @@struct dmx_frontend hw_frontend;struct dmx_frontend mem_frontend; +/* for budget mode demux1 */ +struct dmxdev dmxdev1; +struct dvb_demux demux1; +struct dvb_net dvb_net1; +spinlock_t feedlock1; +int feeding1; +u8 tsf; +u32 ttbp; +unsigned char *grabbing; +struct saa7146_pgtable pt; +struct tasklet_struct vpe_tasklet; +int fe_synced;struct semaphore pid_mutex;
drivers/media/dvb/ttpci/av7110_hw.c +62 -30
259 lines not on this page · raw message
drivers/media/dvb/ttpci/av7110_v4l.c +2 -2
@@ -250,7 +248,7 @@if (ves1820_writereg (dev,0x09 ,0x0f ,0x20 ))dprintk (1 ,"setting band in demodulator failed.\n" ); }else if (av7110->analog_tuner_flags &ANALOG_TUNER_STV0297 ) { -saa7146_setgpio (dev,1 ,SAA7146_GPIO_OUTHI );// TDA9198 pin9(STD) +saa7146_setgpio (dev,1 ,SAA7146_GPIO_OUTLO );// TDA9198 pin9(STD) saa7146_setgpio (dev,3 ,SAA7146_GPIO_OUTLO );// TDA9198 pin30(VIF) } }
@@ -591,7 +589,7 @@if (ves1820_writereg (av7110->dev,0x09 ,0x0f ,0x20 ))dprintk (1 ,"setting band in demodulator failed.\n" ); }else if (av7110->analog_tuner_flags &ANALOG_TUNER_STV0297 ) { -saa7146_setgpio (av7110->dev,1 ,SAA7146_GPIO_OUTHI );// TDA9198 pin9(STD) +saa7146_setgpio (av7110->dev,1 ,SAA7146_GPIO_OUTLO );// TDA9198 pin9(STD) saa7146_setgpio (av7110->dev,3 ,SAA7146_GPIO_OUTLO );// TDA9198 pin30(VIF) }
drivers/media/dvb/ttpci/budget.c +3 -3
@@ -414,7 +412,7 @@ {switch (budget->dev->pci->subsystem_device) {case 0x1003 :// Hauppauge/TT Nova budget (stv0299/ALPS BSRU6(tsa5059) OR ves1893/ALPS BSRV2(sp5659)) - +case 0x1013 :// try the ALPS BSRV2 first of all budget->dvb_frontend =ves1x93_attach (&alps_bsrv2_config, &budget->i2c_adap);if (budget->dvb_frontend) {
@@ -522,14 +517,14 @@MAKE_BUDGET_INFO (ttbs,"TT-Budget/WinTV-NOVA-S PCI" ,BUDGET_TT );MAKE_BUDGET_INFO (ttbc,"TT-Budget/WinTV-NOVA-C PCI" ,BUDGET_TT );MAKE_BUDGET_INFO (ttbt,"TT-Budget/WinTV-NOVA-T PCI" ,BUDGET_TT ); -/* MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); UNDEFINED HARDWARE - mail linuxtv.org list */ +MAKE_BUDGET_INFO (satel,"SATELCO Multimedia PCI" ,BUDGET_TT_HW_DISEQC );MAKE_BUDGET_INFO (fsacs,"Fujitsu Siemens Activy Budget-S PCI" ,BUDGET_FS_ACTIVY );static struct pci_device_id pci_tbl[] = {MAKE_EXTENSION_PCI (ttbs,0x13c2 ,0x1003 ),MAKE_EXTENSION_PCI (ttbc,0x13c2 ,0x1004 ),MAKE_EXTENSION_PCI (ttbt,0x13c2 ,0x1005 ), -/* MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), UNDEFINED HARDWARE */ +MAKE_EXTENSION_PCI (satel,0x13c2 ,0x1013 ),MAKE_EXTENSION_PCI (fsacs,0x1131 ,0x4f61 ), { .vendor =0 ,
drivers/media/dvb/ttpci/budget-core.c +13 -4
@@ -89,11 +87,18 @@* Pitch: 188, NumBytes3: 188, NumLines3: 1024 */ -if (budget->card->type ==BUDGET_FS_ACTIVY ) { +switch (budget->card->type) { +case BUDGET_FS_ACTIVY :saa7146_write (dev,DD1_INIT ,0x04000000 );saa7146_write (dev,MC2 , (MASK_09 |MASK_25 ));saa7146_write (dev,BRS_CTRL ,0x00000000 ); - }else { +break ; +case BUDGET_PATCH : +saa7146_write (dev,DD1_INIT ,0x00000200 ); +saa7146_write (dev,MC2 , (MASK_10 |MASK_26 )); +saa7146_write (dev,BRS_CTRL ,0x60000000 ); +break ; +default :if (budget->video_port ==BUDGET_VIDEO_PORTA ) {saa7146_write (dev,DD1_INIT ,0x06000200 );saa7146_write (dev,MC2 , (MASK_09 |MASK_25 |MASK_10 |MASK_26 ));
@@ -122,9 +127,10 @@ }saa7146_write (dev,MC2 , (MASK_04 |MASK_20 )); -saa7146_write (dev,MC1 , (MASK_04 |MASK_20 ));// DMA3 on -SAA7146_IER_ENABLE (budget->dev,MASK_10 );// VPE +SAA7146_ISR_CLEAR (budget->dev,MASK_10 );/* VPE */ +SAA7146_IER_ENABLE (budget->dev,MASK_10 );/* VPE */ +saa7146_write (dev,MC1 , (MASK_04 |MASK_20 ));/* DMA3 on */ return ++budget->feeding; }
@@ -249,6 +254,7 @@return -EINVAL ;spin_lock (&budget->feedlock); + feed->pusi_seen =0 ;/* have a clean section start */ status =start_ts_capture (budget);spin_unlock (&budget->feedlock);return status;
drivers/media/dvb/ttpci/budget-patch.c +311 -35
440 lines not on this page · raw message