mirror of
				https://github.com/DigitalDevices/dddvb.git
				synced 2025-03-01 10:35:23 +00:00 
			
		
		
		
	initial commit from dddvb-0.9.19c
This commit is contained in:
		
							
								
								
									
										189
									
								
								CHANGELOG
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								CHANGELOG
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,189 @@ | ||||
| 0.9.19c 2015.07.20 | ||||
| - MAX S8: | ||||
|   do not turn on diseqc and tuners on init | ||||
|   of to save power | ||||
|   turn off tuners when not used | ||||
| - support new Octopus CI in flashprog | ||||
|  | ||||
| 0.9.19b 2015.06.15 | ||||
| - fix version number | ||||
| - option "old_quattro=1" for old MAX S8 input numbering | ||||
|   new is "VL VH HL HH", old is "VL HL VH HH" | ||||
| - set drive strength in mxl5xx to 1 to fix problems with | ||||
|   8th demod | ||||
|  | ||||
| 0.9.19 2015.06.14 | ||||
| - lock flash access | ||||
| - support serial numbers for newer cards | ||||
|  | ||||
| 0.9.18 2015.05.05 | ||||
| - support GT links | ||||
| - fixes for mxl5xx tuning | ||||
|   (prevent simultaneous tuning inside 100ms) | ||||
| - allow dynamic fmode change | ||||
|  | ||||
| 0.9.18 (beta) 2015.01.24 | ||||
| - initial support of GT links | ||||
| - fixes for mxl5xx tuning | ||||
|  | ||||
| 0.9.17 2015.01.10 | ||||
| - support input modes for MAX S8 4/8 | ||||
| 	ddbridge parameter fmode: | ||||
| 	fmode = 0  : demod 0 & 4 on input 0, demod 1 & 5 on input 1, etc. | ||||
| 	             input for each frontend can be changed with ioctl DTV_INPUT | ||||
| 	fmode = 1  : connect all lines to QUAD LNB | ||||
| 	fmode = 2  : connect to QUATTRO LNB: input 0=V,L, 1=H,L, 2=V,H, 3=H,H | ||||
| 	fmode = 3  : all demods on input 0 | ||||
| 	             send JESS or SCR commands from application | ||||
|  | ||||
| - preparations for support of GT links | ||||
|  | ||||
| 0.9.16 2014.12.19 | ||||
| - support MAX S8 4/8 production card | ||||
|  | ||||
| 0.9.15a 2014.07.29 | ||||
| - last minute fixes | ||||
|  | ||||
| 0.9.15 2014.06.24 | ||||
| - support MAX S8 4/8 prototype | ||||
|  | ||||
| 0.9.14b 2014.04.24 | ||||
| - fix fe read lockup in cxd2843 | ||||
|  | ||||
| 0.9.14a 2014.04.23 | ||||
| - fix Cine S2 V7 PCIe ID | ||||
|  | ||||
| 0.9.14 2014.04.20 | ||||
| - support for CineCT V7 with C2 | ||||
| - initial support for STV0910/STV6111/LNBH25 | ||||
| - more coding style cleanups | ||||
| - API changes for modulator | ||||
|  | ||||
| 0.9.13 2014.03.25 | ||||
| - support for CineCT V7 | ||||
|  | ||||
| 0.9.12 2014.02.17 | ||||
| - support for SNR in XO2 and LED connected to XO2 | ||||
|  | ||||
| 0.9.11 2014.02.04 | ||||
|  | ||||
| - kernel style cleanups | ||||
| - attr alloc fixes for modulator card | ||||
|  | ||||
| 0.9.10 2013.10.09  | ||||
|  | ||||
| - Bugfixes CXD2843 | ||||
|   support slice id | ||||
|  | ||||
| 0.9.9 2013.08.14 | ||||
|  | ||||
| - support for CXD2843 DVB-C/T/C2/T2 demod | ||||
|  | ||||
| 0.9.7 2013.04.15 | ||||
|  | ||||
| - Octopus Net complete | ||||
|  | ||||
| - changes for 3.8 kernels | ||||
|  | ||||
|  | ||||
| 0.9.6 2012.09.26 | ||||
|  | ||||
| - basic Octopus Net support | ||||
|  | ||||
|  | ||||
| 0.9.5 2012.08.05 | ||||
|  | ||||
| - cleanup | ||||
|  | ||||
| 0.9.4 2012.07.11 | ||||
|  | ||||
| - support for new modulator bitstream 1.1 | ||||
|  | ||||
| 0.9.3 2012.06.13 | ||||
|  | ||||
| - add hwid, remap attributes | ||||
|  | ||||
| 0.9.2 2012.06.08 | ||||
|  | ||||
| - fix cxd2099 address writing optmization | ||||
|  | ||||
| - add setting of TS output gap size through sysfs  | ||||
|   gap_size = (gap_value*2)+4 | ||||
|   bit rate = 72 Mbps * 188 / gap_size | ||||
|  | ||||
| 0.9.1 2012.05.01 | ||||
|  | ||||
| - support for reworked DVB-C modulator | ||||
|  | ||||
| - support for multiple channels | ||||
|  | ||||
| - move some funktions from tasklets back into  | ||||
|   interrupt in those cases where it is more efficient | ||||
|  | ||||
|  | ||||
| 0.9.0 2012.03.05 | ||||
|  | ||||
| - initial support of DVB-C modulator card | ||||
|  | ||||
| - rework of redirect mechanism to support modulator | ||||
|  | ||||
|  | ||||
| 0.8.5 2012.01.30 | ||||
|  | ||||
| - init DMA_BUFFER_CONTROL before starting input/output | ||||
|   in case it was not stopped properly before reboot | ||||
|   (can only happen on cards on PCIe extensions without reset line) | ||||
|  | ||||
|  | ||||
| 0.8.4 2012.01.04 | ||||
|  | ||||
| - support for reading bridge serial number | ||||
|  | ||||
| - test code for proper start/stop of redirected streams | ||||
|  | ||||
|  | ||||
| 0.8.3 2011.12.18  | ||||
|  | ||||
| - add support for EEProms on 0x50 | ||||
|  | ||||
| - make flashprog safer to use for end users | ||||
|  | ||||
| - lost of kernel coding style adjustments | ||||
|  | ||||
|  | ||||
| 0.8.2 2011.10.14  | ||||
|  | ||||
| - added some documentation in docs/ | ||||
|  | ||||
| 0.8.1 2011.10.13  | ||||
|  | ||||
| - signal strength and SNR for STV0367/TDA18212 combo | ||||
|  | ||||
| - serial number support via sysfs | ||||
|  | ||||
|  | ||||
| 0.8 2011.07.30 | ||||
|  | ||||
| - Support for DVB-C/T cards with stv0367 demod and TDA18212 tuner  | ||||
|   | ||||
| - loopback TS for testing | ||||
|  | ||||
| - support of octopus cards with fan, led and temperature sensors | ||||
|   via attributes. | ||||
|  | ||||
| - redirect of TS to CI and back | ||||
|  | ||||
|  | ||||
| 0.7 2011.06.14 | ||||
|  | ||||
| - Add IDs for new cards in ddbridge driver | ||||
|  | ||||
| - Change dvb adapter allocation for ddbridge driver | ||||
|   Configurable with module parameter adapter_alloc: | ||||
|    | ||||
|   0 = one adapter per io (old behavior) | ||||
|   1 = one per tab with io present (tab connected to something) | ||||
|   2 = one per tab regardless of something connected or not | ||||
|   3 = one adapter for all devices of one card | ||||
|  | ||||
|  | ||||
							
								
								
									
										7
									
								
								Kbuild
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								Kbuild
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| # | ||||
| # Makefile for the kernel multimedia device drivers. | ||||
| # | ||||
|  | ||||
| obj-y        := dvb-core/	\ | ||||
| 		ddbridge/       \ | ||||
| 		frontends/ | ||||
							
								
								
									
										19
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| KDIR	?= /lib/modules/$(shell uname -r)/build | ||||
| PWD	:= $(shell pwd) | ||||
|  | ||||
| MODDEFS := CONFIG_DVB_CORE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_CXD2099=m CONFIG_DVB_LNBP21=m  CONFIG_DVB_STV090x=m CONFIG_DVB_STV6110x=m CONFIG_DVB_STV0367=m CONFIG_DVB_TDA18212=m CONFIG_DVB_STV0367DD=m CONFIG_DVB_TDA18212DD=m CONFIG_DVB_OCTONET=m CONFIG_DVB_CXD2843=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6111=m CONFIG_DVB_LNBH25=m CONFIG_DVB_MXL5XX=m | ||||
|  | ||||
| all:  | ||||
| 	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MODDEFS) modules | ||||
| 	$(MAKE) -C apps | ||||
|  | ||||
| dep: | ||||
| 	DIR=`pwd`; (cd $(TOPDIR); make SUBDIRS=$$DIR dep) | ||||
|  | ||||
| install: all | ||||
| 	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install | ||||
|  | ||||
| clean: | ||||
| 	rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules* | ||||
|  | ||||
|  | ||||
							
								
								
									
										19
									
								
								apps/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								apps/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| all: cit citin flashprog modt ddtest setmod ddflash | ||||
|  | ||||
| cit: cit.c | ||||
| 	gcc -o cit cit.c -lpthread | ||||
|  | ||||
| modt: modt.c | ||||
| 	gcc -o modt modt.c -lpthread | ||||
|  | ||||
| setmod: setmod.c | ||||
| 	gcc -o setmod setmod.c -I../include/ | ||||
|  | ||||
| flashprog: flashprog.c | ||||
| 	gcc -o flashprog flashprog.c | ||||
|  | ||||
| ddtest: ddtest.c | ||||
| 	gcc -o ddtest ddtest.c | ||||
|  | ||||
| ddflash: ddflash.c | ||||
| 	gcc -o ddflash ddflash.c | ||||
							
								
								
									
										138
									
								
								apps/cit.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								apps/cit.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,138 @@ | ||||
| #include <stdio.h> | ||||
| #include <ctype.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <stdint.h> | ||||
| #include <stdlib.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <pthread.h> | ||||
|  | ||||
| uint8_t fill[188]={0x47, 0x1f, 0xff, 0x10, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
| 		   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; | ||||
|  | ||||
| uint8_t ts[188]={0x47, 0x0a, 0xaa, 0x00, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
| 		   0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; | ||||
|  | ||||
| void proc_buf(uint8_t *buf, uint32_t *d) | ||||
| { | ||||
| 	uint32_t c; | ||||
| 	static uint32_t tc=0; | ||||
| 	 | ||||
|  | ||||
| 	if (buf[1]==0x1f && buf[2]==0xff) { | ||||
| 		//printf("fill\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 	if (buf[1]==0x9f && buf[2]==0xff) { | ||||
| 		//printf("fill\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 	if (buf[1]==0x1a && buf[2]==0xbb) { | ||||
| 		tc++; | ||||
| 		if (!(tc&0xfff)) | ||||
| 			printf("T %d\n", tc); | ||||
| 		return; | ||||
| 	} | ||||
| 	//printf("%02x %02x %02x %02x\n", buf[0], buf[1], buf [2], buf[3]); | ||||
| 	if (buf[1]!=0x0a || buf[2]!=0xaa) | ||||
| 		return; | ||||
| 	c=(buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|buf[7]; | ||||
| 	if (c!=*d) { | ||||
| 		printf("CONT ERROR: got %08x  expected %08x\n", c, *d); | ||||
| 		*d=c; | ||||
| 	} else { | ||||
| 		if (memcmp(ts+8, buf+8, 180)) | ||||
| 			printf("error\n"); | ||||
| 		if (!(c&0xffff)) | ||||
| 			printf("R %08x\n", c); | ||||
| 	} | ||||
| 	(*d)++; | ||||
| } | ||||
|  | ||||
| void *get_ts(void *a) | ||||
| { | ||||
| 	uint8_t buf[188*1024]; | ||||
| 	int len, off; | ||||
|  | ||||
| 	int fdi=open("/dev/dvb/adapter2/ci0", O_RDONLY); | ||||
| 	uint32_t d=0; | ||||
|  | ||||
| 	while (1) { | ||||
| 		len=read(fdi, buf, 188*1024); | ||||
| 		if (len<0) | ||||
| 			continue; | ||||
| 		if (buf[0]!=0x47) { | ||||
| 			read(fdi, buf, 1); | ||||
| 			continue; | ||||
| 		} | ||||
| 		for (off=0; off<len; off+=188) { | ||||
| 			proc_buf(buf+off, &d); | ||||
| 		} | ||||
| 	}	 | ||||
| } | ||||
|  | ||||
| #define SNUM 233 | ||||
| //671 | ||||
| void send(void) | ||||
| { | ||||
| 	uint8_t buf[188*SNUM], *cts; | ||||
| 	int i; | ||||
| 	uint32_t c=0; | ||||
| 	int fdo; | ||||
|  | ||||
| 	fdo=open("/dev/dvb/adapter2/ci0", O_WRONLY); | ||||
|  | ||||
|  | ||||
| 	while (1) { | ||||
| 		for (i=0; i<SNUM; i++) { | ||||
| 			cts=buf+i*188; | ||||
| 			memcpy(cts, ts, 188); | ||||
| 			cts[4]=(c>>24); | ||||
| 			cts[5]=(c>>16); | ||||
| 			cts[6]=(c>>8); | ||||
| 			cts[7]=c; | ||||
| 			//write(fdo, fill, 188); | ||||
| 			//printf("S %d\n", c);  | ||||
| 			c++; | ||||
| 			//usleep(100000+0xffff&rand()); | ||||
| 			//usleep(1000); | ||||
| 		} | ||||
| 		write(fdo, buf, 188*SNUM); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| int main() | ||||
| { | ||||
| 	pthread_t th; | ||||
|  | ||||
| 	memset(ts+8, 180, 0x5a); | ||||
| 	pthread_create(&th, NULL, get_ts, NULL); | ||||
| 	usleep(10000); | ||||
| 	send(); | ||||
| } | ||||
							
								
								
									
										61
									
								
								apps/citin.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								apps/citin.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| #include <stdio.h> | ||||
| #include <ctype.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <stdint.h> | ||||
| #include <stdlib.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <linux/dvb/dmx.h> | ||||
| #include <linux/dvb/frontend.h> | ||||
| #include <linux/dvb/video.h> | ||||
|  | ||||
| void proc_ts(int i, uint8_t *buf) | ||||
| { | ||||
|         uint16_t pid=0x1fff&((buf[1]<<8)|buf[2]); | ||||
|  | ||||
| 	if (buf[3]&0xc0) /* only descrambled packets */ | ||||
| 		return; | ||||
| 	/* only ORF */ | ||||
| 	if (pid==160 || pid==161 || pid==1001||pid==13001 || pid==0) | ||||
| 		write(1, buf, 188); | ||||
| } | ||||
|  | ||||
| #define TSBUFSIZE (100*188) | ||||
|  | ||||
| void citest() | ||||
| { | ||||
|         uint8_t *buf; | ||||
| 	uint8_t id; | ||||
| 	int i, nts; | ||||
| 	int len; | ||||
| 	int ts=open("/dev/dvb/adapter4/ci0", O_RDONLY); | ||||
| 	buf=(uint8_t *)malloc(TSBUFSIZE); | ||||
|  | ||||
| 	 | ||||
| 	while(1) { | ||||
| 		len=read(ts, buf, TSBUFSIZE); | ||||
| 		if (len<0) { | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (buf[0]!=0x47) { | ||||
| 			read(ts, buf, 1); | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (len%188) { /* should not happen */ | ||||
| 			printf("blah\n"); | ||||
| 			continue; | ||||
| 		} | ||||
| 		nts=len/188; | ||||
| 		for (i=0; i<nts; i++) | ||||
| 			proc_ts(i, buf+i*188); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
| 	citest(); | ||||
| } | ||||
|  | ||||
							
								
								
									
										55
									
								
								apps/citout.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								apps/citout.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| #include <stdio.h> | ||||
| #include <ctype.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <stdint.h> | ||||
| #include <stdlib.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <linux/dvb/dmx.h> | ||||
| #include <linux/dvb/frontend.h> | ||||
| #include <linux/dvb/video.h> | ||||
|  | ||||
| #define TSBUFSIZE (100*188) | ||||
|  | ||||
| void citest() | ||||
| { | ||||
|         uint8_t *buf; | ||||
| 	uint8_t id; | ||||
| 	int i, nts; | ||||
| 	int len; | ||||
| 	int ts0=open("/dev/dvb/adapter0/dvr0", O_RDONLY); | ||||
| 	int ts1=open("/dev/dvb/adapter4/sec0", O_WRONLY); | ||||
| 	int demux0=open("/dev/dvb/adapter0/demux0", O_RDWR); | ||||
|  | ||||
| 	struct dmx_pes_filter_params pesFilterParams;  | ||||
| 	 | ||||
| 	pesFilterParams.input = DMX_IN_FRONTEND;  | ||||
| 	pesFilterParams.output = DMX_OUT_TS_TAP;  | ||||
| 	pesFilterParams.pes_type = DMX_PES_OTHER;  | ||||
| 	pesFilterParams.flags = DMX_IMMEDIATE_START; | ||||
|    | ||||
| 	pesFilterParams.pid = 8192; | ||||
| 	if (ioctl(demux0, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { | ||||
| 	        printf("Could not set PES filter\n");  | ||||
| 		return; | ||||
| 	} | ||||
| 	buf=(uint8_t *)malloc(TSBUFSIZE); | ||||
|  | ||||
| 	while(1) { | ||||
| 		len=read(ts0, buf, TSBUFSIZE); | ||||
| 		if (len<=0) | ||||
| 			break; | ||||
| 		if (buf[0]!=0x47) | ||||
| 			printf("oops\n"); | ||||
| 		write(ts1, buf, len); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int main() | ||||
| { | ||||
| 	citest(); | ||||
| } | ||||
|  | ||||
							
								
								
									
										1
									
								
								apps/ddflash.c
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								apps/ddflash.c
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| octonet/ddflash.c | ||||
							
								
								
									
										1
									
								
								apps/ddtest.c
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								apps/ddtest.c
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| octonet/ddtest.c | ||||
							
								
								
									
										1
									
								
								apps/flash.h
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						
									
										1
									
								
								apps/flash.h
									
									
									
									
									
										Symbolic link
									
								
							| @@ -0,0 +1 @@ | ||||
| ./octonet/flash.h | ||||
							
								
								
									
										722
									
								
								apps/flashprog.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										722
									
								
								apps/flashprog.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,722 @@ | ||||
| /* | ||||
| /* flashprog - Programmer for flash on Digital Devices Octopus  | ||||
|  * | ||||
|  * Copyright (C) 2010-2011 Digital Devices GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdint.h> | ||||
| #include <unistd.h> | ||||
| #include <getopt.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
| #include <string.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <linux/types.h> | ||||
|  | ||||
| #define DDB_MAGIC 'd' | ||||
|  | ||||
| static uint32_t linknr = 0; | ||||
|  | ||||
| struct ddb_id { | ||||
| 	__u16 vendor; | ||||
| 	__u16 device; | ||||
| 	__u16 subvendor; | ||||
| 	__u16 subdevice; | ||||
| 	__u32 hw; | ||||
| 	__u32 regmap; | ||||
| }; | ||||
|  | ||||
| struct ddb_flashio { | ||||
| 	__u8 *write_buf; | ||||
| 	__u32 write_len; | ||||
| 	__u8 *read_buf; | ||||
| 	__u32 read_len; | ||||
| 	__u32 link; | ||||
| }; | ||||
|  | ||||
| #define IOCTL_DDB_FLASHIO  _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio) | ||||
| #define IOCTL_DDB_ID       _IOR(DDB_MAGIC, 0x03, struct ddb_id) | ||||
|  | ||||
|  | ||||
| int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen) | ||||
| { | ||||
| 	struct ddb_flashio fio = { | ||||
| 		.write_buf=wbuf, | ||||
| 		.write_len=wlen, | ||||
| 		.read_buf=rbuf, | ||||
| 		.read_len=rlen, | ||||
| 		.link=linknr, | ||||
| 	}; | ||||
| 	 | ||||
| 	return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio); | ||||
| } | ||||
|  | ||||
| enum { | ||||
| 	UNKNOWN_FLASH = 0, | ||||
| 	ATMEL_AT45DB642D = 1, | ||||
| 	SSTI_SST25VF016B = 2, | ||||
| 	SSTI_SST25VF032B = 3, | ||||
| 	SSTI_SST25VF064C = 4, | ||||
| 	SPANSION_S25FL116K = 5, | ||||
| }; | ||||
|  | ||||
|  | ||||
| int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len) | ||||
| { | ||||
| 	uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,  | ||||
| 			 (addr >> 8) & 0xff, addr & 0xff}; | ||||
| 	 | ||||
| 	return flashio(ddb, cmd, 4, buf, len); | ||||
| } | ||||
|  | ||||
| int flashdump(int ddb, uint32_t addr, uint32_t len) | ||||
| { | ||||
| 	int i, j; | ||||
| 	uint8_t buf[32]; | ||||
| 	int bl = sizeof(buf); | ||||
| 	 | ||||
| 	for (j=0; j<len; j+=bl, addr+=bl) { | ||||
| 		flashread(ddb, buf, addr, bl); | ||||
| 		for (i=0; i<bl; i++) { | ||||
| 			printf("%02x ", buf[i]); | ||||
| 		} | ||||
| 		printf("\n"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| int FlashDetect(int dev) | ||||
| { | ||||
| 	uint8_t Cmd = 0x9F; | ||||
| 	uint8_t Id[3]; | ||||
| 	 | ||||
| 	int r = flashio(dev, &Cmd,1,Id,3); | ||||
| 	if (r < 0) | ||||
| 		return r; | ||||
| 	 | ||||
| 	if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x41 ) | ||||
| 		r = SSTI_SST25VF016B;  | ||||
| 	else if( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4A )  | ||||
| 		r = SSTI_SST25VF032B;  | ||||
| 	else if( Id[0] == 0x1F && Id[1] == 0x28 ) | ||||
| 		r = ATMEL_AT45DB642D;  | ||||
| 	else if( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4B ) | ||||
| 		r = SSTI_SST25VF064C;  | ||||
| 	else if( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x15 ) | ||||
| 		r = SPANSION_S25FL116K;  | ||||
| 	else  | ||||
| 		r = UNKNOWN_FLASH; | ||||
| 	 | ||||
| 	switch(r) { | ||||
|         case UNKNOWN_FLASH:  | ||||
| 		printf("Unknown Flash Flash ID = %02x %02x %02x\n",Id[0],Id[1],Id[2]); | ||||
| 		break; | ||||
|         case ATMEL_AT45DB642D: | ||||
| 		printf("Flash: Atmel AT45DB642D  64 MBit\n"); | ||||
| 		break; | ||||
|         case SSTI_SST25VF016B: | ||||
| 		printf("Flash: SSTI  SST25VF016B 16 MBit\n"); | ||||
| 		break; | ||||
|         case SSTI_SST25VF032B: | ||||
| 		printf("Flash: SSTI  SST25VF032B 32 MBit\n"); break; | ||||
|         case SSTI_SST25VF064C: | ||||
| 		printf("Flash: SSTI  SST25VF064C 64 MBit\n"); break; | ||||
|         case SPANSION_S25FL116K: | ||||
| 		printf("Flash: SPANSION S25FL116K 16 MBit\n"); break; | ||||
| 	} | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
|  | ||||
| int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize) | ||||
| { | ||||
|     int err = 0; | ||||
|     int BlockErase = BufferSize >= 8192; | ||||
|     int i; | ||||
|      | ||||
|     if (BlockErase) { | ||||
| 	    for(i = 0; i < BufferSize; i += 8192 ) { | ||||
| 		    uint8_t Cmd[4]; | ||||
| 		    if( (i & 0xFFFF) == 0 ) | ||||
| 			    printf(" Erase    %08x\n",FlashOffset + i); | ||||
| 		    Cmd[0] = 0x50; // Block Erase | ||||
| 		    Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); | ||||
| 		    Cmd[2] = ( (( FlashOffset + i ) >>  8) & 0xFF ); | ||||
| 		    Cmd[3] = 0x00; | ||||
| 		    err = flashio(dev,Cmd,4,NULL,0); | ||||
| 		    if( err < 0 ) break; | ||||
| 		     | ||||
| 		    while( 1 ) | ||||
| 		    { | ||||
| 			    Cmd[0] = 0xD7;  // Read Status register | ||||
| 			    err = flashio(dev,Cmd,1,&Cmd[0],1); | ||||
| 			    if( err < 0 ) break; | ||||
| 			    if( (Cmd[0] & 0x80) == 0x80 ) break; | ||||
| 		    } | ||||
| 	    } | ||||
|     } | ||||
|      | ||||
|     for(i = 0; i < BufferSize; i += 1024 ) | ||||
|     { | ||||
|         uint8_t Cmd[4 + 1024]; | ||||
|         if( (i & 0xFFFF) == 0 ) | ||||
|         { | ||||
|             printf(" Program  %08x\n",FlashOffset + i); | ||||
|         } | ||||
|         Cmd[0] = 0x84; // Buffer 1 | ||||
|         Cmd[1] = 0x00; | ||||
|         Cmd[2] = 0x00; | ||||
|         Cmd[3] = 0x00; | ||||
|         memcpy(&Cmd[4],&Buffer[i],1024); | ||||
|  | ||||
|         err = flashio(dev,Cmd,4 + 1024,NULL,0); | ||||
|         if( err < 0 ) break; | ||||
|  | ||||
|         Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase) | ||||
|         Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); | ||||
|         Cmd[2] = ( (( FlashOffset + i ) >>  8) & 0xFF ); | ||||
|         Cmd[3] = 0x00; | ||||
|  | ||||
|         err = flashio(dev,Cmd,4,NULL,0); | ||||
|         if( err < 0 ) break; | ||||
|  | ||||
|         while( 1 ) | ||||
|         { | ||||
| 		Cmd[0] = 0xD7;  // Read Status register | ||||
| 		err = flashio(dev,Cmd,1,&Cmd[0],1); | ||||
|             if( err < 0 ) break; | ||||
|             if( (Cmd[0] & 0x80) == 0x80 ) break; | ||||
|         } | ||||
|         if( err < 0 ) break; | ||||
|     } | ||||
|     return err; | ||||
| } | ||||
|  | ||||
|  | ||||
| int FlashWritePageMode(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize, uint8_t LockBits) | ||||
| { | ||||
| 	int err = 0, i, j; | ||||
| 	uint8_t Cmd[260]; | ||||
| 	 | ||||
| 	if( (BufferSize % 4096) != 0 ) | ||||
| 		return -1;   // Must be multiple of sector size | ||||
| 	 | ||||
| 	do { | ||||
| 		Cmd[0] = 0x50;  // EWSR | ||||
| 		err = flashio(dev, Cmd,1,NULL,0); | ||||
| 		if( err < 0 ) break; | ||||
| 		 | ||||
| 		Cmd[0] = 0x01;  // WRSR | ||||
| 		Cmd[1] = 0x00;  // BPx = 0, Unlock all blocks | ||||
| 		err = flashio(dev, Cmd,2,NULL,0); | ||||
| 		if( err < 0 ) break; | ||||
| 		 | ||||
| 		for(i = 0; i < BufferSize; i += 4096 ) { | ||||
| 			if( (i & 0xFFFF) == 0 )	{ | ||||
| 				printf(" Erase    %08x\n",FlashOffset + i); | ||||
| 			} | ||||
| 			 | ||||
| 			Cmd[0] = 0x06;  // WREN | ||||
| 			err = flashio(dev, Cmd,1,NULL,0); | ||||
| 			if( err < 0 ) break; | ||||
| 			 | ||||
| 			Cmd[0] = 0x20;  // Sector erase ( 4Kb) | ||||
| 			Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); | ||||
| 			Cmd[2] = ( (( FlashOffset + i ) >>  8) & 0xFF ); | ||||
| 			Cmd[3] = 0x00; | ||||
| 			err = flashio(dev, Cmd,4,NULL,0); | ||||
| 			if( err < 0 ) break; | ||||
| 			 | ||||
| 			while(1) | ||||
| 			{ | ||||
| 				Cmd[0] = 0x05;  // RDRS | ||||
| 				err = flashio(dev, Cmd,1,&Cmd[0],1); | ||||
| 				if( err < 0 ) break; | ||||
| 				if( (Cmd[0] & 0x01) == 0 ) break; | ||||
| 			} | ||||
| 			if( err < 0 ) break; | ||||
| 			 | ||||
| 		} | ||||
| 		if( err < 0 ) break; | ||||
| 		 | ||||
| 		 | ||||
| 		for (j = BufferSize - 256; j >= 0; j -= 256 ) | ||||
| 		{ | ||||
| 			if( (j & 0xFFFF) == 0 ) | ||||
| 			{ | ||||
| 				printf(" Programm %08x\n",FlashOffset + j); | ||||
| 			} | ||||
| 			 | ||||
| 			Cmd[0] = 0x06;  // WREN | ||||
| 			err = flashio(dev, Cmd,1,NULL,0); | ||||
| 			if( err < 0 ) break; | ||||
| 			 | ||||
| 			Cmd[0] = 0x02;  // PP | ||||
| 			Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); | ||||
| 			Cmd[2] = ( (( FlashOffset + j ) >>  8) & 0xFF ); | ||||
| 			Cmd[3] = 0x00; | ||||
| 			memcpy(&Cmd[4],&Buffer[j],256); | ||||
| 			err = flashio(dev, Cmd,260,NULL,0); | ||||
| 			if( err < 0 ) break; | ||||
| 			 | ||||
| 			while(1) | ||||
| 			{ | ||||
| 				Cmd[0] = 0x05;  // RDRS | ||||
| 				err = flashio(dev, Cmd,1,&Cmd[0],1); | ||||
| 				if( err < 0 ) break; | ||||
| 				if( (Cmd[0] & 0x01) == 0 ) break; | ||||
| 			} | ||||
| 			if( err < 0 ) break; | ||||
| 			 | ||||
| 		} | ||||
| 		if( err < 0 ) break; | ||||
| 		 | ||||
| 		Cmd[0] = 0x50;  // EWSR | ||||
| 		err = flashio(dev, Cmd,1,NULL,0); | ||||
| 		if( err < 0 ) break; | ||||
| 		 | ||||
| 		Cmd[0] = 0x01;  // WRSR | ||||
| 		Cmd[1] = LockBits;  // BPx = 0, Lock all blocks | ||||
| 		err = flashio(dev, Cmd,2,NULL,0); | ||||
| 		 | ||||
| 	} while(0); | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
|  | ||||
| int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize) | ||||
| { | ||||
|     int err = 0; | ||||
|     uint8_t Cmd[6]; | ||||
|     int i, j; | ||||
|  | ||||
|     // Must be multiple of sector size | ||||
|     if( (BufferSize % 4096) != 0 )  | ||||
| 	    return -1;    | ||||
|      | ||||
|     do { | ||||
| 	    Cmd[0] = 0x50;  // EWSR | ||||
| 	    err = flashio(dev,Cmd,1,NULL,0); | ||||
| 	    if( err < 0 )  | ||||
| 		    break; | ||||
|  | ||||
| 	    Cmd[0] = 0x01;  // WRSR | ||||
| 	    Cmd[1] = 0x00;  // BPx = 0, Unlock all blocks | ||||
| 	    err = flashio(dev,Cmd,2,NULL,0); | ||||
| 	    if( err < 0 ) | ||||
| 		    break; | ||||
| 	     | ||||
| 	    for(i = 0; i < BufferSize; i += 4096 ) { | ||||
| 		    if( (i & 0xFFFF) == 0 ) | ||||
| 			    printf(" Erase    %08x\n",FlashOffset + i); | ||||
| 		    Cmd[0] = 0x06;  // WREN | ||||
| 		    err = flashio(dev,Cmd,1,NULL,0); | ||||
| 		    if( err < 0 ) | ||||
| 			    break; | ||||
| 		     | ||||
| 		    Cmd[0] = 0x20;  // Sector erase ( 4Kb) | ||||
| 		    Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); | ||||
| 		    Cmd[2] = ( (( FlashOffset + i ) >>  8) & 0xFF ); | ||||
| 		    Cmd[3] = 0x00; | ||||
| 		    err = flashio(dev,Cmd,4,NULL,0); | ||||
| 		    if( err < 0 ) | ||||
| 			    break; | ||||
| 		     | ||||
| 		    while(1) { | ||||
| 			    Cmd[0] = 0x05;  // RDRS | ||||
| 			    err = flashio(dev,Cmd,1,&Cmd[0],1); | ||||
| 			    if( err < 0 ) break; | ||||
| 			    if( (Cmd[0] & 0x01) == 0 ) break; | ||||
| 		    } | ||||
| 		    if( err < 0 ) break; | ||||
| 	    } | ||||
| 	    if( err < 0 )  | ||||
| 		    break; | ||||
| 	    for(j = BufferSize - 4096; j >= 0; j -= 4096 ) { | ||||
| 		    if( (j & 0xFFFF) == 0 ) | ||||
| 			    printf(" Program  %08x\n",FlashOffset + j); | ||||
| 		     | ||||
| 		    for(i = 0; i < 4096; i += 2 ) { | ||||
| 			    if( i == 0 ) { | ||||
| 				    Cmd[0] = 0x06;  // WREN | ||||
| 				    err = flashio(dev,Cmd,1,NULL,0); | ||||
| 				    if( err < 0 )  | ||||
| 					    break; | ||||
| 				     | ||||
| 				    Cmd[0] = 0xAD;  // AAI | ||||
| 				    Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); | ||||
| 				    Cmd[2] = ( (( FlashOffset + j ) >>  8) & 0xFF ); | ||||
| 				    Cmd[3] = 0x00; | ||||
| 				    Cmd[4] = Buffer[j+i]; | ||||
| 				    Cmd[5] = Buffer[j+i+1]; | ||||
| 				    err = flashio(dev,Cmd,6,NULL,0); | ||||
| 			    } else { | ||||
| 				    Cmd[0] = 0xAD;  // AAI | ||||
| 				    Cmd[1] = Buffer[j+i]; | ||||
| 				    Cmd[2] = Buffer[j+i+1]; | ||||
| 				    err = flashio(dev,Cmd,3,NULL,0); | ||||
| 			    } | ||||
| 			    if( err < 0 )  | ||||
| 				    break; | ||||
| 			     | ||||
| 			    while(1) { | ||||
| 				    Cmd[0] = 0x05;  // RDRS | ||||
| 				    err = flashio(dev,Cmd,1,&Cmd[0],1); | ||||
| 				    if( err < 0 ) break; | ||||
| 				    if( (Cmd[0] & 0x01) == 0 ) break; | ||||
| 			    } | ||||
| 			    if( err < 0 ) break; | ||||
| 		    } | ||||
| 		    if( err < 0 ) break; | ||||
| 		     | ||||
| 		    Cmd[0] = 0x04;  // WDIS | ||||
| 		    err = flashio(dev,Cmd,1,NULL,0); | ||||
| 		    if( err < 0 ) break; | ||||
| 		     | ||||
| 	    } | ||||
| 	    if( err < 0 ) break; | ||||
| 	     | ||||
| 	    Cmd[0] = 0x50;  // EWSR | ||||
| 	    err = flashio(dev,Cmd,1,NULL,0); | ||||
| 	    if( err < 0 ) break; | ||||
| 	     | ||||
| 	    Cmd[0] = 0x01;  // WRSR | ||||
| 	    Cmd[1] = 0x1C;  // BPx = 0, Lock all blocks | ||||
| 	    err = flashio(dev,Cmd,2,NULL,0); | ||||
|     } while(0); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| void get_id(int ddb, struct ddb_id *ddbid) { | ||||
| 	uint8_t id[4]; | ||||
|  | ||||
| 	if (ioctl(ddb, IOCTL_DDB_ID, ddbid)>=0) | ||||
| 		return; | ||||
| 	memset(ddbid, 0, sizeof(*ddbid)); | ||||
| 	flashread(ddb, id, 0, 4); | ||||
| 	printf("%02x %02x %02x %02x\n",  | ||||
| 	       id[0], id[1], id[2], id[3]); | ||||
| 	ddbid->subvendor=(id[0] << 8) | id[1]; | ||||
| 	ddbid->subdevice=(id[2] << 8) | id[3]; | ||||
| } | ||||
|  | ||||
| int sure() | ||||
| { | ||||
| 	char c; | ||||
|  | ||||
| 	printf("\n\nWARNING! Flashing a new FPGA image might make your card unusable!\n"); | ||||
| 	printf("\n\nWARNUNG! Das Flashen eines neuen FPGA-Images kann Ihre Karte unbrauchbar machen.\n"); | ||||
| 	printf("\n\nAre you sure? y/n?"); | ||||
| 	printf("\n\nSind Sie sicher? y/n?"); | ||||
| 	fflush(0); | ||||
| 	c = getchar(); | ||||
| 	if (c!='y') { | ||||
| 		printf("\nFlashing aborted.\n\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	printf("\nStarting to flash\n\n"); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
| 	char ddbname[80]; | ||||
| 	int type = 0; | ||||
| 	struct ddb_id ddbid; | ||||
| 	uint8_t *buffer; | ||||
| 	int BufferSize = 0; | ||||
| 	int BlockErase = 0; | ||||
| 	uint32_t FlashOffset = 0x10000; | ||||
| 	int ddb; | ||||
| 	int i, err; | ||||
| 	int SectorSize=0; | ||||
| 	int FlashSize=0; | ||||
| 	int Flash; | ||||
|  | ||||
| 	uint32_t svid=0, jump=0, dump=0; | ||||
| 	int bin; | ||||
|  | ||||
| 	int ddbnum = 0; | ||||
| 	int force = 0; | ||||
|  | ||||
|         while (1) { | ||||
|                 int option_index = 0; | ||||
| 		int c; | ||||
|                 static struct option long_options[] = { | ||||
| 			{"svid", required_argument, NULL, 's'}, | ||||
| 			{"help", no_argument , NULL, 'h'}, | ||||
| 			{"force", no_argument , NULL, 'f'}, | ||||
| 			{0, 0, 0, 0} | ||||
| 		}; | ||||
|                 c = getopt_long(argc, argv,  | ||||
| 				"d:n:s:o:l:dfhj", | ||||
| 				long_options, &option_index); | ||||
| 		if (c==-1) | ||||
| 			break; | ||||
|  | ||||
| 		switch (c) { | ||||
| 		case 'd': | ||||
| 			dump = strtoul(optarg, NULL, 16); | ||||
| 			break; | ||||
| 		case 's': | ||||
| 			svid = strtoul(optarg, NULL, 16); | ||||
| 			break; | ||||
| 		case 'o': | ||||
| 			FlashOffset = strtoul(optarg, NULL, 16); | ||||
| 			break; | ||||
| 		case 'n': | ||||
| 			ddbnum = strtol(optarg, NULL, 0); | ||||
| 			break; | ||||
| 		case 'l': | ||||
| 			linknr = strtol(optarg, NULL, 0); | ||||
| 			break; | ||||
| 		case 'f': | ||||
| 			force = 1; | ||||
| 			break; | ||||
| 		case 'j': | ||||
| 			jump = 1; | ||||
| 			break; | ||||
| 		case 'h': | ||||
| 		default: | ||||
| 			break; | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
| 	if (optind<argc) { | ||||
| 		printf("Warning: unused arguments\n"); | ||||
| 	} | ||||
|  | ||||
| 	sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum); | ||||
| 	ddb=open(ddbname, O_RDWR); | ||||
| 	if (ddb < 0) { | ||||
| 		printf("Could not open device\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	Flash=FlashDetect(ddb); | ||||
|  | ||||
| 	switch(Flash) { | ||||
|         case ATMEL_AT45DB642D:  | ||||
| 		SectorSize = 1024;  | ||||
| 		FlashSize = 0x800000;  | ||||
| 		break; | ||||
|         case SSTI_SST25VF016B:  | ||||
| 		SectorSize = 4096;  | ||||
| 		FlashSize = 0x200000;  | ||||
| 		break; | ||||
|         case SSTI_SST25VF032B:  | ||||
| 		SectorSize = 4096;  | ||||
| 		FlashSize = 0x400000;  | ||||
| 		break; | ||||
|         case SSTI_SST25VF064C: | ||||
| 		SectorSize = 4096; | ||||
| 		FlashSize = 0x800000; | ||||
| 		break; | ||||
|         case SPANSION_S25FL116K: | ||||
| 		SectorSize = 4096; | ||||
| 		FlashSize = 0x200000; | ||||
| 		break; | ||||
| 	default: | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	get_id(ddb, &ddbid); | ||||
| #if 1 | ||||
| 	printf("%04x %04x %04x %04x %08x %08x\n", | ||||
| 	       ddbid.vendor, ddbid.device, | ||||
| 	       ddbid.subvendor, ddbid.subdevice, | ||||
| 	       ddbid.hw, ddbid.regmap); | ||||
| #endif | ||||
|  | ||||
| 	if (dump) { | ||||
| 		flashdump(ddb, dump, 128); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (ddbid.device == 0x0011) | ||||
| 		type = 1; | ||||
| 	if (ddbid.device == 0x0201) | ||||
| 		type = 2; | ||||
| 	if (ddbid.device == 0x02) | ||||
| 		type = 3; | ||||
| 	if (ddbid.device == 0x03) | ||||
| 		type = 0; | ||||
| 	if (ddbid.device == 0x07) | ||||
| 		type = 4; | ||||
| 	if (ddbid.device == 0x320) | ||||
| 		type = 5; | ||||
| 	if (ddbid.device == 0x13) | ||||
| 		type = 6; | ||||
| 	if (ddbid.device == 0x12) | ||||
| 		type = 7; | ||||
| 	 | ||||
| 	if (!SectorSize) | ||||
| 		return 0; | ||||
| 	 | ||||
| 	if (jump) { | ||||
| 		uint32_t Jump = 0x200000; | ||||
| 		 | ||||
| 		BufferSize = SectorSize; | ||||
| 		FlashOffset = FlashSize - SectorSize; | ||||
| 		buffer = malloc(BufferSize); | ||||
| 		if (!buffer) { | ||||
| 			printf("out of memory\n"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		memset(buffer, 0xFF, BufferSize); | ||||
| 		memset(&buffer[BufferSize - 256 + 0x10], 0x00, 16); | ||||
|  | ||||
| 		buffer[BufferSize - 256 + 0x10] = 0xbd; | ||||
| 		buffer[BufferSize - 256 + 0x11] = 0xb3; | ||||
| 		buffer[BufferSize - 256 + 0x12] = 0xc4; | ||||
| 		buffer[BufferSize - 256 + 0x1a] = 0xfe; | ||||
| 		buffer[BufferSize - 256 + 0x1e] = 0x03; | ||||
| 		buffer[BufferSize - 256 + 0x1f] = ( ( Jump >> 16 ) & 0xFF ); | ||||
| 		buffer[BufferSize - 256 + 0x20] = ( ( Jump >>  8 ) & 0xFF ); | ||||
| 		buffer[BufferSize - 256 + 0x21] = ( ( Jump       ) & 0xFF ); | ||||
| 	} else if (svid) { | ||||
| 		BufferSize = SectorSize; | ||||
| 		FlashOffset = 0; | ||||
| 		 | ||||
| 		buffer = malloc(BufferSize); | ||||
| 		if (!buffer) { | ||||
| 			printf("out of memory\n"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		memset(buffer,0xFF,BufferSize); | ||||
| 		 | ||||
| 		buffer[0] = ((svid >> 24 ) & 0xFF); | ||||
| 		buffer[1] = ((svid >> 16 ) & 0xFF); | ||||
| 		buffer[2] = ((svid >>  8 ) & 0xFF); | ||||
| 		buffer[3] = ((svid       ) & 0xFF); | ||||
| 	} else { | ||||
| 		int fh, i; | ||||
| 		int fsize; | ||||
| 		char *fname; | ||||
|  | ||||
| 		switch (type) { | ||||
| 		case 0: | ||||
| 			fname="DVBBridgeV1B_DVBBridgeV1B.bit"; | ||||
| 			printf("Octopus\n"); | ||||
| 			break; | ||||
| 		case 1: | ||||
| 			fname="CIBridgeV1B_CIBridgeV1B.bit"; | ||||
| 			printf("Octopus CI\n"); | ||||
| 			break; | ||||
| 		case 2: | ||||
| 			fname="DVBModulatorV1B_DVBModulatorV1B.bit"; | ||||
| 			printf("Modulator\n"); | ||||
| 			break; | ||||
| 		case 3: | ||||
| 			fname="DVBBridgeV1A_DVBBridgeV1A.bit"; | ||||
| 			printf("Octopus 35\n"); | ||||
| 			break; | ||||
| 		case 4: | ||||
| 			fname="DVBBridgeV2A_DD01_0007_MXL.bit"; | ||||
| 			printf("Octopus 4/8\n"); | ||||
| 			break; | ||||
| 		case 6: | ||||
| 			fname="DVBBridgeV2B_DD01_0013_PRO.fpga"; | ||||
| 			printf("Octopus PRO\n"); | ||||
| 			break; | ||||
| 		case 7: | ||||
| 			fname="DVBBridgeV2B_DD01_0012_STD.fpga"; | ||||
| 			printf("Octopus CI\n"); | ||||
| 			break; | ||||
| 		default: | ||||
| 			printf("UNKNOWN\n"); | ||||
| 			break; | ||||
| 		} | ||||
| 		fh = open(fname, O_RDONLY); | ||||
| 		if (fh < 0 ) { | ||||
| 			printf("File not found \n"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		printf("Using bitstream %s\n", fname); | ||||
|  | ||||
| 		fsize = lseek(fh,0,SEEK_END); | ||||
| 		if( fsize > 4000000 || fsize < SectorSize ) | ||||
| 		{ | ||||
| 			close(fh); | ||||
| 			printf("Invalid File Size \n"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		 | ||||
| 		if( Flash == ATMEL_AT45DB642D ) { | ||||
| 			BlockErase = fsize >= 8192; | ||||
| 			if( BlockErase ) | ||||
| 				BufferSize = (fsize + 8191) & ~8191; | ||||
| 			else | ||||
| 				BufferSize = (fsize + 1023) & ~1023; | ||||
| 		} else { | ||||
| 			BufferSize = (fsize + SectorSize - 1 ) & ~(SectorSize - 1); | ||||
| 		} | ||||
| 		printf(" Size     %08x, target %08x\n", BufferSize, FlashOffset); | ||||
| 		 | ||||
| 		buffer = malloc(BufferSize); | ||||
|  | ||||
| 		if( buffer == NULL ) { | ||||
| 			close(fh); | ||||
| 			printf("out of memory\n"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	 | ||||
| 		memset(buffer, 0xFF, BufferSize); | ||||
| 		lseek(fh, 0, SEEK_SET); | ||||
| 		read(fh, buffer, fsize); | ||||
| 		close(fh); | ||||
| 		 | ||||
| 		if (BufferSize >= 0x10000) { | ||||
| 			for(i = 0; i < 0x200; i += 1 ) { | ||||
| 				if ( *(uint16_t *) (&buffer[i]) == 0xFFFF ) | ||||
| 					break; | ||||
| 				buffer[i] = 0xFF; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if (!force && sure()<0) | ||||
| 		return 0; | ||||
| 	switch(Flash) { | ||||
|         case ATMEL_AT45DB642D: | ||||
| 		err = FlashWriteAtmel(ddb,FlashOffset,buffer,BufferSize); | ||||
| 		break; | ||||
|         case SSTI_SST25VF016B:  | ||||
|         case SSTI_SST25VF032B: | ||||
| 		err = FlashWriteSSTI_B(ddb,FlashOffset,buffer,BufferSize); | ||||
| 		break; | ||||
|         case SSTI_SST25VF064C: | ||||
| 		err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x3C); | ||||
| 		break; | ||||
|         case SPANSION_S25FL116K: | ||||
| 		err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C); | ||||
| 		break;             | ||||
| 	} | ||||
| 	 | ||||
| 	if (err < 0)  | ||||
| 		printf("Programming Error\n"); | ||||
| 	else | ||||
| 		printf("Programming Done\n"); | ||||
| 	 | ||||
| 	free(buffer); | ||||
| 	return 0; | ||||
| } | ||||
							
								
								
									
										36
									
								
								apps/modt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								apps/modt.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| #include <stdio.h> | ||||
| #include <ctype.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <stdint.h> | ||||
| #include <stdlib.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <pthread.h> | ||||
|  | ||||
|  | ||||
| #define SNUM 1000 | ||||
| //671 | ||||
| void send(void) | ||||
| { | ||||
| 	uint8_t buf[188*SNUM], *cts; | ||||
| 	int i; | ||||
| 	uint32_t c=0; | ||||
| 	int fdo; | ||||
|  | ||||
| 	fdo=open("/dev/dvb/adapter0/mod0", O_WRONLY); | ||||
|  | ||||
|  | ||||
| 	while (1) { | ||||
| 		read(0, buf, sizeof(buf)); | ||||
| 		write(fdo, buf, 188*SNUM); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| int main() | ||||
| { | ||||
| 	send(); | ||||
| } | ||||
							
								
								
									
										19
									
								
								apps/octonet/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								apps/octonet/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| all: ddtest octonet octokey ddflash | ||||
|  | ||||
| install: all | ||||
| 	install -m 0755 ddtest $(DESTDIR)/usr/bin | ||||
| 	install -m 0755 octonet $(DESTDIR)/usr/bin | ||||
| 	install -m 0755 octokey $(DESTDIR)/usr/bin | ||||
| 	install -m 0755 ddflash $(DESTDIR)/usr/bin | ||||
|  | ||||
| ddflash: ddflash.c | ||||
| 	$(CC) -o ddflash ddflash.c | ||||
|  | ||||
| ddtest: ddtest.c | ||||
| 	$(CC) -o ddtest ddtest.c | ||||
|  | ||||
| octonet: octonet.c | ||||
| 	$(CC) -o octonet octonet.c | ||||
|  | ||||
| octokey: octokey.c | ||||
| 	$(CC) -o octokey octokey.c | ||||
							
								
								
									
										791
									
								
								apps/octonet/ddflash.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										791
									
								
								apps/octonet/ddflash.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,791 @@ | ||||
| /* | ||||
| /* ddflash - Programmer for flash on Digital Devices devices | ||||
|  * | ||||
|  * Copyright (C) 2013 Digital Devices GmbH | ||||
|  *                    Ralph Metzler <rmetzler@digitaldevices.de> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 3 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdint.h> | ||||
| #include <unistd.h> | ||||
| #include <getopt.h> | ||||
| #include <errno.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
| #include <string.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <linux/types.h> | ||||
|  | ||||
| #include "flash.h" | ||||
|  | ||||
| static int reboot(uint32_t off) | ||||
| { | ||||
| 	FILE *f; | ||||
| 	uint32_t time; | ||||
|  | ||||
| 	if ((f = fopen ("/sys/class/rtc/rtc0/since_epoch", "r")) == NULL) | ||||
| 		return -1; | ||||
| 	fscanf(f, "%u", &time); | ||||
| 	fclose(f); | ||||
|  | ||||
| 	if ((f = fopen ("/sys/class/rtc/rtc0/wakealarm", "r+")) == NULL) | ||||
| 		return -1; | ||||
| 	fprintf(f, "%u", time + off); | ||||
| 	fclose(f); | ||||
| 	system("/sbin/poweroff"); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| struct ddflash { | ||||
| 	int fd; | ||||
| 	struct ddb_id id; | ||||
| 	uint32_t type; | ||||
| 	uint32_t version; | ||||
|  | ||||
| 	uint32_t sector_size; | ||||
| 	uint32_t size; | ||||
|  | ||||
| 	uint32_t bufsize; | ||||
| 	uint32_t block_erase; | ||||
|  | ||||
| 	uint8_t * buffer; | ||||
| }; | ||||
|  | ||||
| int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen) | ||||
| { | ||||
| 	struct ddb_flashio fio = { | ||||
| 		.write_buf=wbuf, | ||||
| 		.write_len=wlen, | ||||
| 		.read_buf=rbuf, | ||||
| 		.read_len=rlen, | ||||
| 		.link=0, | ||||
| 	}; | ||||
| 	 | ||||
| 	return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio); | ||||
| } | ||||
|  | ||||
| enum { | ||||
| 	UNKNOWN_FLASH = 0, | ||||
| 	ATMEL_AT45DB642D = 1, | ||||
| 	SSTI_SST25VF016B = 2, | ||||
| 	SSTI_SST25VF032B = 3, | ||||
| }; | ||||
|  | ||||
| static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len) | ||||
| { | ||||
| 	uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,  | ||||
| 			 (addr >> 8) & 0xff, addr & 0xff}; | ||||
| 	 | ||||
| 	return flashio(ddb, cmd, 4, buf, len); | ||||
| } | ||||
|  | ||||
| static int flashdump(struct ddflash *ddf, uint32_t addr, uint32_t len) | ||||
| { | ||||
| 	int i, j; | ||||
| 	uint8_t buf[32]; | ||||
| 	int bl = sizeof(buf); | ||||
| 	 | ||||
| 	for (j = 0; j < len; j += bl, addr += bl) { | ||||
| 		flashread(ddf->fd, buf, addr, bl); | ||||
| 		for (i = 0; i < bl; i++) { | ||||
| 			printf("%02x ", buf[i]); | ||||
| 		} | ||||
| 		printf("\n"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void dump(const uint8_t *b, int l) | ||||
| { | ||||
| 	int i, j; | ||||
| 	 | ||||
| 	for (j = 0; j < l; j += 16, b += 16) {  | ||||
| 		for (i = 0; i < 16; i++) | ||||
| 			if (i + j < l) | ||||
| 				printf("%02x ", b[i]); | ||||
| 			else | ||||
| 				printf("   "); | ||||
| 		printf(" | "); | ||||
| 		for (i = 0; i < 16; i++) | ||||
| 			if (i + j < l) | ||||
| 				putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.'); | ||||
| 		printf("\n"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int flashwrite_SSTI(struct ddflash *ddf, int fs, uint32_t FlashOffset, uint32_t maxlen, uint32_t fw_off) | ||||
| { | ||||
|     int err = 0; | ||||
|     uint8_t cmd[6]; | ||||
|     int i, j; | ||||
|     uint32_t flen, blen; | ||||
|  | ||||
|     blen = flen = lseek(fs, 0, SEEK_END) - fw_off; | ||||
|     if (blen % 0xfff) | ||||
| 	    blen = (blen + 0xfff) & 0xfffff000;  | ||||
|     printf("blen = %u, flen = %u\n", blen, flen); | ||||
|     do { | ||||
| #if 1 | ||||
| 	    cmd[0] = 0x50;  // EWSR | ||||
| 	    err = flashio(ddf->fd, cmd, 1, NULL, 0); | ||||
| 	    if (err < 0)  | ||||
| 		    break; | ||||
|  | ||||
| 	    cmd[0] = 0x01;  // WRSR | ||||
| 	    cmd[1] = 0x00;  // BPx = 0, Unlock all blocks | ||||
| 	    err = flashio(ddf->fd, cmd, 2, NULL, 0); | ||||
| 	    if (err < 0 ) | ||||
| 		    break; | ||||
| 	     | ||||
| 	    for (i = 0; i < flen; i += 4096) { | ||||
| 		    if ((i & 0xFFFF) == 0 ) | ||||
| 			    printf("Erase %08x\n", FlashOffset + i); | ||||
| 		    cmd[0] = 0x06;  // WREN | ||||
| 		    err = flashio(ddf->fd, cmd, 1, NULL, 0); | ||||
| 		    if (err < 0 ) | ||||
| 			    break; | ||||
| 		     | ||||
| 		    cmd[0] = 0x20;  // Sector erase ( 4Kb) | ||||
| 		    cmd[1] = (((FlashOffset + i ) >> 16) & 0xFF); | ||||
| 		    cmd[2] = (((FlashOffset + i ) >>  8) & 0xFF); | ||||
| 		    cmd[3] = 0x00; | ||||
| 		    err = flashio(ddf->fd,cmd,4,NULL,0); | ||||
| 		    if (err < 0 ) | ||||
| 			    break; | ||||
| 		     | ||||
| 		    while(1) { | ||||
| 			    cmd[0] = 0x05;  // RDRS | ||||
| 			    err = flashio(ddf->fd,cmd,1,&cmd[0],1); | ||||
| 			    if (err < 0 ) break; | ||||
| 			    if ((cmd[0] & 0x01) == 0 ) break; | ||||
| 		    } | ||||
| 		    if (err < 0 ) break; | ||||
| 	    } | ||||
| 	    if (err < 0 )  | ||||
| 		    break; | ||||
| #endif | ||||
| 	    for (j = blen - 4096; j >= 0; j -= 4096 ) { | ||||
| 		    uint32_t len = 4096;  | ||||
| 		    ssize_t rlen; | ||||
| 		     | ||||
| 		    if (lseek(fs, j + fw_off, SEEK_SET) < 0) { | ||||
| 			    printf("seek error\n"); | ||||
| 			    return -1; | ||||
| 		    } | ||||
| 		    if (flen - j < 4096) { | ||||
| 			    len = flen - j; | ||||
| 			    memset(ddf->buffer, 0xff, 4096); | ||||
| 		    } | ||||
|    		    rlen = read(fs, ddf->buffer, len); | ||||
| 		    if (rlen < 0 || rlen != len) { | ||||
| 			    printf("file read error %d,%d at %u\n", rlen, errno, j); | ||||
| 			    return -1; | ||||
| 		    } | ||||
| 		    printf ("write %u bytes at %08x\n", len, j); | ||||
|  | ||||
| 		    if ((j & 0xFFFF) == 0 ) | ||||
| 			    printf(" Program  %08x\n",FlashOffset + j); | ||||
| #if 1		     | ||||
| 		    for (i = 0; i < 4096; i += 2) { | ||||
| 			    if (i == 0) { | ||||
| 				    cmd[0] = 0x06;  // WREN | ||||
| 				    err = flashio(ddf->fd, cmd, 1, NULL, 0); | ||||
| 				    if (err < 0 )  | ||||
| 					    break; | ||||
| 				     | ||||
| 				    cmd[0] = 0xAD;  // AAI | ||||
| 				    cmd[1] = ((( FlashOffset + j ) >> 16) & 0xFF ); | ||||
| 				    cmd[2] = ((( FlashOffset + j ) >>  8) & 0xFF ); | ||||
| 				    cmd[3] = 0x00; | ||||
| 				    cmd[4] = ddf->buffer[i]; | ||||
| 				    cmd[5] = ddf->buffer[i + 1]; | ||||
| 				    err = flashio(ddf->fd,cmd,6,NULL,0); | ||||
| 			    } else { | ||||
| 				    cmd[0] = 0xAD;  // AAI | ||||
| 				    cmd[1] = ddf->buffer[i]; | ||||
| 				    cmd[2] = ddf->buffer[i + 1]; | ||||
| 				    err = flashio(ddf->fd,cmd,3,NULL,0); | ||||
| 			    } | ||||
| 			    if (err < 0 )  | ||||
| 				    break; | ||||
| 			     | ||||
| 			    while(1) { | ||||
| 				    cmd[0] = 0x05;  // RDRS | ||||
| 				    err = flashio(ddf->fd,cmd,1,&cmd[0],1); | ||||
| 				    if (err < 0 ) break; | ||||
| 				    if ((cmd[0] & 0x01) == 0 ) break; | ||||
| 			    } | ||||
| 			    if (err < 0 )  | ||||
| 				    break; | ||||
| 		    } | ||||
| 		    if (err < 0) | ||||
| 			    break; | ||||
| 		     | ||||
| 		    cmd[0] = 0x04;  // WDIS | ||||
| 		    err = flashio(ddf->fd, cmd, 1, NULL, 0); | ||||
| 		    if (err < 0 )  | ||||
| 			    break; | ||||
| #endif | ||||
| 	    } | ||||
| 	    if (err < 0 ) break; | ||||
| 	     | ||||
| 	    cmd[0] = 0x50;  // EWSR | ||||
| 	    err = flashio(ddf->fd,cmd,1,NULL,0); | ||||
| 	    if (err < 0 ) break; | ||||
| 	     | ||||
| 	    cmd[0] = 0x01;  // WRSR | ||||
| 	    cmd[1] = 0x1C;  // BPx = 0, Lock all blocks | ||||
| 	    err = flashio(ddf->fd,cmd,2,NULL,0); | ||||
|     } while(0); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off) | ||||
| { | ||||
| 	flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off); | ||||
| } | ||||
|  | ||||
| static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off) | ||||
| { | ||||
| 	off_t off; | ||||
| 	uint32_t len; | ||||
| 	int i, j, rlen; | ||||
| 	uint8_t buf[256], buf2[256]; | ||||
| 	int bl = sizeof(buf); | ||||
| 	 | ||||
| 	off = lseek(fs, 0, SEEK_END); | ||||
| 	if (off < 0) | ||||
| 		return -1; | ||||
| 	len = off - fw_off; | ||||
| 	lseek(fs, fw_off, SEEK_SET); | ||||
| 	if (len > maxlen) { | ||||
| 		printf("file too big\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	printf("flash file len %u, compare to %08x in flash\n", len, addr); | ||||
| 	for (j = 0; j < len; j += bl, addr += bl) { | ||||
| 		if (len - j < bl) | ||||
| 			bl = len - j; | ||||
| 		flashread(ddf->fd, buf, addr, bl); | ||||
| 		rlen = read(fs, buf2, bl); | ||||
| 		if (rlen < 0 || rlen != bl) { | ||||
| 			printf("read error\n"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 			 | ||||
| 		if (memcmp(buf, buf2, bl)) { | ||||
| 			printf("flash differs at %08x (offset %u)\n", addr, j); | ||||
| 			dump(buf, 32); | ||||
| 			dump(buf2, 32); | ||||
| 			return addr; | ||||
| 		} | ||||
| 	} | ||||
| 	printf("flash same as file\n"); | ||||
| 	return -2; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int flash_detect(struct ddflash *ddf) | ||||
| { | ||||
| 	uint8_t cmd = 0x9F; | ||||
| 	uint8_t id[3]; | ||||
| 	 | ||||
| 	int r = flashio(ddf->fd, &cmd, 1, id, 3); | ||||
| 	if (r < 0) | ||||
| 		return r; | ||||
| 	 | ||||
| 	if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x41) { | ||||
| 		r = SSTI_SST25VF016B;  | ||||
| 		//printf("Flash: SSTI  SST25VF016B 16 MBit\n"); | ||||
| 		ddf->sector_size = 4096;  | ||||
| 		ddf->size = 0x200000;  | ||||
| 	} else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4A) { | ||||
| 		r = SSTI_SST25VF032B;  | ||||
| 		//printf("Flash: SSTI  SST25VF032B 32 MBit\n"); | ||||
| 		ddf->sector_size = 4096;  | ||||
| 		ddf->size = 0x400000;  | ||||
| 	} else if (id[0] == 0x1F && id[1] == 0x28) { | ||||
| 		r = ATMEL_AT45DB642D;  | ||||
| 		//printf("Flash: Atmel AT45DB642D  64 MBit\n"); | ||||
| 		ddf->sector_size = 1024;  | ||||
| 		ddf->size = 0x800000;  | ||||
| 	} else { | ||||
| 		r = UNKNOWN_FLASH; | ||||
| 		//printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]); | ||||
| 	} | ||||
| 	if (ddf->sector_size) { | ||||
| 		ddf->buffer = malloc(ddf->sector_size); | ||||
| 		//printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);   | ||||
| 	} | ||||
| 	return r; | ||||
| } | ||||
|  | ||||
|  | ||||
| int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize) | ||||
| { | ||||
|     int err = 0; | ||||
|     int BlockErase = BufferSize >= 8192; | ||||
|     int i; | ||||
|      | ||||
|     if (BlockErase) { | ||||
| 	    for (i = 0; i < BufferSize; i += 8192 ) { | ||||
| 		    uint8_t cmd[4]; | ||||
| 		    if ((i & 0xFFFF) == 0 ) | ||||
| 			    printf(" Erase    %08x\n",FlashOffset + i); | ||||
| 		    cmd[0] = 0x50; // Block Erase | ||||
| 		    cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); | ||||
| 		    cmd[2] = ( (( FlashOffset + i ) >>  8) & 0xFF ); | ||||
| 		    cmd[3] = 0x00; | ||||
| 		    err = flashio(dev,cmd,4,NULL,0); | ||||
| 		    if (err < 0 ) break; | ||||
| 		     | ||||
| 		    while( 1 ) | ||||
| 		    { | ||||
| 			    cmd[0] = 0xD7;  // Read Status register | ||||
| 			    err = flashio(dev,cmd,1,&cmd[0],1); | ||||
| 			    if (err < 0 ) break; | ||||
| 			    if ((cmd[0] & 0x80) == 0x80 ) break; | ||||
| 		    } | ||||
| 	    } | ||||
|     } | ||||
|      | ||||
|     for (i = 0; i < BufferSize; i += 1024) { | ||||
|         uint8_t cmd[4 + 1024]; | ||||
|         if ((i & 0xFFFF) == 0 ) | ||||
|         { | ||||
|             printf(" Program  %08x\n",FlashOffset + i); | ||||
|         } | ||||
|         cmd[0] = 0x84; // Buffer 1 | ||||
|         cmd[1] = 0x00; | ||||
|         cmd[2] = 0x00; | ||||
|         cmd[3] = 0x00; | ||||
|         memcpy(&cmd[4],&Buffer[i],1024); | ||||
|  | ||||
|         err = flashio(dev,cmd,4 + 1024,NULL,0); | ||||
|         if (err < 0 ) break; | ||||
|  | ||||
|         cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase) | ||||
|         cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); | ||||
|         cmd[2] = ( (( FlashOffset + i ) >>  8) & 0xFF ); | ||||
|         cmd[3] = 0x00; | ||||
|  | ||||
|         err = flashio(dev,cmd,4,NULL,0); | ||||
|         if (err < 0 ) break; | ||||
|  | ||||
|         while( 1 ) | ||||
|         { | ||||
| 		cmd[0] = 0xD7;  // Read Status register | ||||
| 		err = flashio(dev,cmd,1,&cmd[0],1); | ||||
|             if (err < 0 ) break; | ||||
|             if ((cmd[0] & 0x80) == 0x80 ) break; | ||||
|         } | ||||
|         if (err < 0 ) break; | ||||
|     } | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize) | ||||
| { | ||||
|     int err = 0; | ||||
|     uint8_t cmd[6]; | ||||
|     int i, j; | ||||
|  | ||||
|     // Must be multiple of sector size | ||||
|     if ((BufferSize % 4096) != 0 )  | ||||
| 	    return -1;    | ||||
|      | ||||
|     do { | ||||
| 	    cmd[0] = 0x50;  // EWSR | ||||
| 	    err = flashio(dev,cmd,1,NULL,0); | ||||
| 	    if (err < 0 )  | ||||
| 		    break; | ||||
|  | ||||
| 	    cmd[0] = 0x01;  // WRSR | ||||
| 	    cmd[1] = 0x00;  // BPx = 0, Unlock all blocks | ||||
| 	    err = flashio(dev,cmd,2,NULL,0); | ||||
| 	    if (err < 0 ) | ||||
| 		    break; | ||||
| 	     | ||||
| 	    for (i = 0; i < BufferSize; i += 4096 ) { | ||||
| 		    if ((i & 0xFFFF) == 0 ) | ||||
| 			    printf(" Erase    %08x\n",FlashOffset + i); | ||||
| 		    cmd[0] = 0x06;  // WREN | ||||
| 		    err = flashio(dev,cmd,1,NULL,0); | ||||
| 		    if (err < 0 ) | ||||
| 			    break; | ||||
| 		     | ||||
| 		    cmd[0] = 0x20;  // Sector erase ( 4Kb) | ||||
| 		    cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); | ||||
| 		    cmd[2] = ( (( FlashOffset + i ) >>  8) & 0xFF ); | ||||
| 		    cmd[3] = 0x00; | ||||
| 		    err = flashio(dev,cmd,4,NULL,0); | ||||
| 		    if (err < 0 ) | ||||
| 			    break; | ||||
| 		     | ||||
| 		    while(1) { | ||||
| 			    cmd[0] = 0x05;  // RDRS | ||||
| 			    err = flashio(dev,cmd,1,&cmd[0],1); | ||||
| 			    if (err < 0 ) break; | ||||
| 			    if ((cmd[0] & 0x01) == 0 ) break; | ||||
| 		    } | ||||
| 		    if (err < 0 ) break; | ||||
| 	    } | ||||
| 	    if (err < 0 )  | ||||
| 		    break; | ||||
| 	    for (j = BufferSize - 4096; j >= 0; j -= 4096 ) { | ||||
| 		    if ((j & 0xFFFF) == 0 ) | ||||
| 			    printf(" Program  %08x\n",FlashOffset + j); | ||||
| 		     | ||||
| 		    for (i = 0; i < 4096; i += 2 ) { | ||||
| 			    if (i == 0 ) { | ||||
| 				    cmd[0] = 0x06;  // WREN | ||||
| 				    err = flashio(dev,cmd,1,NULL,0); | ||||
| 				    if (err < 0 )  | ||||
| 					    break; | ||||
| 				     | ||||
| 				    cmd[0] = 0xAD;  // AAI | ||||
| 				    cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); | ||||
| 				    cmd[2] = ( (( FlashOffset + j ) >>  8) & 0xFF ); | ||||
| 				    cmd[3] = 0x00; | ||||
| 				    cmd[4] = Buffer[j+i]; | ||||
| 				    cmd[5] = Buffer[j+i+1]; | ||||
| 				    err = flashio(dev,cmd,6,NULL,0); | ||||
| 			    } else { | ||||
| 				    cmd[0] = 0xAD;  // AAI | ||||
| 				    cmd[1] = Buffer[j+i]; | ||||
| 				    cmd[2] = Buffer[j+i+1]; | ||||
| 				    err = flashio(dev,cmd,3,NULL,0); | ||||
| 			    } | ||||
| 			    if (err < 0 )  | ||||
| 				    break; | ||||
| 			     | ||||
| 			    while(1) { | ||||
| 				    cmd[0] = 0x05;  // RDRS | ||||
| 				    err = flashio(dev,cmd,1,&cmd[0],1); | ||||
| 				    if (err < 0 ) break; | ||||
| 				    if ((cmd[0] & 0x01) == 0 ) break; | ||||
| 			    } | ||||
| 			    if (err < 0 ) break; | ||||
| 		    } | ||||
| 		    if (err < 0 ) break; | ||||
| 		     | ||||
| 		    cmd[0] = 0x04;  // WDIS | ||||
| 		    err = flashio(dev,cmd,1,NULL,0); | ||||
| 		    if (err < 0 ) break; | ||||
| 		     | ||||
| 	    } | ||||
| 	    if (err < 0 ) break; | ||||
| 	     | ||||
| 	    cmd[0] = 0x50;  // EWSR | ||||
| 	    err = flashio(dev,cmd,1,NULL,0); | ||||
| 	    if (err < 0 ) break; | ||||
| 	     | ||||
| 	    cmd[0] = 0x01;  // WRSR | ||||
| 	    cmd[1] = 0x1C;  // BPx = 0, Lock all blocks | ||||
| 	    err = flashio(dev,cmd,2,NULL,0); | ||||
|     } while(0); | ||||
|     return err; | ||||
| } | ||||
|  | ||||
| static int get_id(struct ddflash *ddf) { | ||||
| 	uint8_t id[4]; | ||||
|  | ||||
| 	if (ioctl(ddf->fd, IOCTL_DDB_ID, &ddf->id) < 0) | ||||
| 		return -1; | ||||
| #if 1 | ||||
| 	printf("%04x %04x %04x %04x %08x %08x\n", | ||||
| 	       ddf->id.vendor, ddf->id.device, | ||||
| 	       ddf->id.subvendor, ddf->id.subdevice, | ||||
| 	       ddf->id.hw, ddf->id.regmap); | ||||
| #endif	 | ||||
| 	if (ddf->id.device == 0x0011) | ||||
| 		ddf->type = 1; | ||||
| 	if (ddf->id.device == 0x0201) | ||||
| 		ddf->type = 2; | ||||
| 	if (ddf->id.device == 0x02) | ||||
| 		ddf->type = 3; | ||||
| 	if (ddf->id.device == 0x03) | ||||
| 		ddf->type = 0; | ||||
| 	if (ddf->id.device == 0x0300) | ||||
| 		ddf->type = 4; | ||||
| 	if (ddf->id.device == 0x0320) | ||||
| 		ddf->type = 5; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off) | ||||
| { | ||||
| 	int fd, fsize, ret = 0; | ||||
| 	off_t off; | ||||
| 	uint32_t p, i; | ||||
| 	uint8_t *buf; | ||||
| 	uint8_t hdr[256]; | ||||
| 	unsigned int devid, version, length; | ||||
| 	unsigned int cid[8]; | ||||
| 	int cids = 0; | ||||
| 	uint32_t maxlen = 1024 * 1024; | ||||
| 	 | ||||
| 	fd = open(fn, O_RDONLY); | ||||
| 	if (fd < 0) { | ||||
| 		printf("%s: not found\n", fn); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	off = lseek(fd, 0, SEEK_END); | ||||
| 	if (off < 0) | ||||
| 		return -1; | ||||
| 	fsize = off; | ||||
| 	if (fsize > maxlen) { | ||||
| 		close(fd); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	lseek(fd, 0, SEEK_SET);	 | ||||
| 	buf = malloc(fsize); | ||||
| 	if (!buf) | ||||
| 		return -1; | ||||
| 	read(fd, buf, fsize); | ||||
| 	close(fd); | ||||
| 	 | ||||
| 	for (p = 0; p < fsize && buf[p]; p++) { | ||||
| 		char *key = &buf[p], *val = NULL; | ||||
|  | ||||
| 		for (; p < fsize && buf[p] != 0x0a; p++) { | ||||
| 			if (buf[p] == ':') { | ||||
| 				buf[p] = 0; | ||||
| 				val = &buf[p + 1]; | ||||
| 			} | ||||
| 		} | ||||
| 		if (val == NULL || p == fsize) | ||||
| 			break; | ||||
| 		buf[p] = 0; | ||||
| 		//printf("%-20s:%s\n", key, val); | ||||
| 		if (!strcasecmp(key, "Devid")) { | ||||
| 			sscanf(val, "%x", &devid); | ||||
| 		} else if (!strcasecmp(key, "Compat")) { | ||||
| 			cids = sscanf(val, "%x,%x,%x,%x,%x,%x,%x,%x", | ||||
| 				      &cid[0], &cid[1], &cid[2], &cid[3], | ||||
| 				      &cid[4], &cid[5], &cid[6], &cid[7]); | ||||
| 			if (cids < 1) | ||||
| 				break; | ||||
| 			for (i = 0; i < cids; i++)  | ||||
| 				if (cid[i] == ddf->id.device) | ||||
| 					break; | ||||
| 			if (i == cids) { | ||||
| 				printf("%s: no compatible id\n", fn); | ||||
| 				ret = -2; /* no compatible ID */ | ||||
| 				goto out; | ||||
| 			} | ||||
| 		} else if (!strcasecmp(key, "Version")) { | ||||
| 			sscanf(val, "%x", &version); | ||||
| 		} else if (!strcasecmp(key, "Length")) { | ||||
| 			sscanf(val, "%u", &length); | ||||
| 		}  | ||||
| 	} | ||||
| 	p++; | ||||
| 	*fw_off = p; | ||||
| 	printf("devid = %04x\n", devid); | ||||
| 	printf("version = %08x  %08x\n", version, ddf->id.hw); | ||||
| 	printf("length = %u\n", length); | ||||
| 	printf("fsize = %u, p = %u, f-p = %u\n", fsize, p, fsize - p); | ||||
| 	if (devid == ddf->id.device) { | ||||
| 		if (version <= (ddf->id.hw & 0xffffff)) { | ||||
| 			printf("%s: old version\n", fn); | ||||
| 			ret = -3; /* same id but no newer version */ | ||||
| 		} | ||||
| 	} else | ||||
| 		ret = 1; | ||||
|  | ||||
| out: | ||||
| 	free(buf); | ||||
| 	printf("check_fw = %d\n", ret); | ||||
| 	return ret; | ||||
| 	 | ||||
| } | ||||
|  | ||||
| static int update_image(struct ddflash *ddf, char *fn,  | ||||
| 			uint32_t adr, uint32_t len, | ||||
| 			int has_header, int no_change) | ||||
| { | ||||
| 	int fs, res = 0; | ||||
| 	uint32_t fw_off = 0; | ||||
|  | ||||
| 	printf("Check %s\n", fn); | ||||
| 	if (has_header) { | ||||
| 		int ck; | ||||
| 		 | ||||
| 		ck = check_fw(ddf, fn, &fw_off); | ||||
| 		if (ck < 0) | ||||
| 			return ck; | ||||
| 		if (ck == 1 && no_change) | ||||
| 			return 0; | ||||
| 	} | ||||
| 	fs = open(fn, O_RDONLY); | ||||
| 	if (fs < 0 ) { | ||||
| 		printf("File %s not found \n", fn); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	res = flashcmp(ddf, fs, adr, len, fw_off); | ||||
| 	if (res == -2) { | ||||
| 		printf("%s: same as flash\n", fn); | ||||
| 	} | ||||
| 	if (res < 0)  | ||||
| 		goto out; | ||||
| 	res = flashwrite(ddf, fs, adr, len, fw_off); | ||||
| 	if (res == 0) | ||||
| 		res = 1; | ||||
| out: | ||||
| 	close(fs); | ||||
| 	return res; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int fexists(char *fn) | ||||
| { | ||||
| 	struct stat b; | ||||
|  | ||||
| 	return (!stat(fn, &b)); | ||||
| } | ||||
|  | ||||
| static int update_flash(struct ddflash *ddf) | ||||
| { | ||||
| 	char *fname; | ||||
| 	int res, stat = 0; | ||||
|  | ||||
| 	switch (ddf->id.device) { | ||||
| 	case 0x300: | ||||
| 	case 0x301: | ||||
| 	case 0x302: | ||||
| 	case 0x307: | ||||
| 		if ((res = update_image(ddf, "/boot/bs.img", 0x4000, 0x1000, 0, 0)) == 1) | ||||
| 			stat |= 4; | ||||
| 		if ((res = update_image(ddf, "/boot/uboot.img", 0xb0000, 0xb0000, 0, 0)) == 1) | ||||
| 			stat |= 2; | ||||
| 		if (fexists("/config/gtl.enabled")) { | ||||
| 			if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 0)) == 1) | ||||
| 				stat |= 1; | ||||
| 			if (res == -1) | ||||
| 				if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 0)) == 1) | ||||
| 					stat |= 1; | ||||
| 		} else if (fexists("/config/gtl.disabled")) { | ||||
| 			if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1) | ||||
| 				stat |= 1; | ||||
| 			if (res == -1) | ||||
| 				if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1) | ||||
| 					stat |= 1; | ||||
| 		} else { | ||||
| 			if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1) | ||||
| 				stat |= 1; | ||||
| 			if (res == -1) | ||||
| 				if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1) | ||||
| 					stat |= 1; | ||||
| 			if (res == -1) | ||||
| 				if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1) | ||||
| 					stat |= 1; | ||||
| 			if (res == -1) | ||||
| 				if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1) | ||||
| 					stat |= 1; | ||||
| 		} | ||||
| 		break; | ||||
| 	case 0x320: | ||||
| 		//fname="/boot/DVBNetV1A_DD01_0300.bit"; | ||||
| 		fname="/boot/fpga.img"; | ||||
| 		if ((res = update_image(ddf, fname, 0x10000, 0x100000, 1, 0)) == 1) | ||||
| 			stat |= 1; | ||||
| 		return stat; | ||||
| 		break; | ||||
| 	default: | ||||
| 		return 0; | ||||
| 	} | ||||
| 	return stat; | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
| 	struct ddflash ddf; | ||||
| 	char ddbname[80]; | ||||
| 	uint8_t *buffer = 0; | ||||
| 	uint32_t FlashOffset = 0x10000; | ||||
| 	int i, err, res; | ||||
| 	int ddbnum = 0; | ||||
|  | ||||
| 	uint32_t svid, jump, flash; | ||||
|  | ||||
| 	memset(&ddf, 0, sizeof(ddf)); | ||||
|  | ||||
|         while (1) { | ||||
|                 int option_index = 0; | ||||
| 		int c; | ||||
|                 static struct option long_options[] = { | ||||
| 			{"svid", required_argument, NULL, 's'}, | ||||
| 			{"help", no_argument , NULL, 'h'}, | ||||
| 			{0, 0, 0, 0} | ||||
| 		}; | ||||
|                 c = getopt_long(argc, argv,  | ||||
| 				"d:n:s:o:l:dfhj", | ||||
| 				long_options, &option_index); | ||||
| 		if (c==-1) | ||||
| 			break; | ||||
|  | ||||
| 		switch (c) { | ||||
| 		case 's': | ||||
| 			svid = strtoul(optarg, NULL, 16); | ||||
| 			break; | ||||
| 		case 'o': | ||||
| 			FlashOffset = strtoul(optarg, NULL, 16); | ||||
| 			break; | ||||
| 		case 'n': | ||||
| 			ddbnum = strtol(optarg, NULL, 0); | ||||
| 			break; | ||||
| 		case 'j': | ||||
| 			jump = 1; | ||||
| 			break; | ||||
| 		case 'h': | ||||
| 		default: | ||||
| 			break; | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
| 	if (optind < argc) { | ||||
| 		printf("Warning: unused arguments\n"); | ||||
| 	} | ||||
| 	sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum); | ||||
| 	while ((ddf.fd = open(ddbname, O_RDWR)) < 0) { | ||||
| 		if (errno == EBUSY) | ||||
| 			usleep(100000); | ||||
| 		else { | ||||
| 			printf("Could not open device\n"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
| 	flash = flash_detect(&ddf); | ||||
| 	get_id(&ddf); | ||||
|  | ||||
| 	res = update_flash(&ddf); | ||||
|  | ||||
| 	if (ddf.buffer) | ||||
| 		free(ddf.buffer); | ||||
| 	if (res < 0) | ||||
| 		return res; | ||||
| 	if (res & 1) | ||||
| 		reboot(40); | ||||
| 	return res; | ||||
| } | ||||
							
								
								
									
										1528
									
								
								apps/octonet/ddtest.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1528
									
								
								apps/octonet/ddtest.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										63
									
								
								apps/octonet/flash.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								apps/octonet/flash.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| #define DDB_MAGIC 'd' | ||||
|  | ||||
|  | ||||
| struct ddb_flashio { | ||||
| 	__u8 *write_buf; | ||||
| 	__u32 write_len; | ||||
| 	__u8 *read_buf; | ||||
| 	__u32 read_len; | ||||
| 	__u32 link; | ||||
| }; | ||||
|  | ||||
| struct ddb_gpio { | ||||
| 	__u32 mask; | ||||
| 	__u32 data; | ||||
| }; | ||||
|  | ||||
| struct ddb_id { | ||||
| 	__u16 vendor; | ||||
| 	__u16 device; | ||||
| 	__u16 subvendor; | ||||
| 	__u16 subdevice; | ||||
| 	__u32 hw; | ||||
| 	__u32 regmap; | ||||
| }; | ||||
|  | ||||
| struct ddb_reg { | ||||
| 	__u32 reg; | ||||
| 	__u32 val; | ||||
| }; | ||||
|  | ||||
| struct ddb_mem { | ||||
| 	__u32  off; | ||||
| 	__u8  *buf; | ||||
| 	__u32  len; | ||||
| }; | ||||
|  | ||||
| struct ddb_mdio { | ||||
| 	__u8   adr; | ||||
| 	__u8   reg; | ||||
| 	__u16  val; | ||||
| }; | ||||
|  | ||||
| struct ddb_i2c_msg { | ||||
| 	__u8   bus; | ||||
| 	__u8   adr; | ||||
| 	__u8  *hdr; | ||||
| 	__u32  hlen; | ||||
| 	__u8  *msg; | ||||
| 	__u32  mlen; | ||||
| }; | ||||
|  | ||||
| #define IOCTL_DDB_FLASHIO    _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio) | ||||
| #define IOCTL_DDB_GPIO_IN    _IOWR(DDB_MAGIC, 0x01, struct ddb_gpio) | ||||
| #define IOCTL_DDB_GPIO_OUT   _IOWR(DDB_MAGIC, 0x02, struct ddb_gpio) | ||||
| #define IOCTL_DDB_ID         _IOR(DDB_MAGIC, 0x03, struct ddb_id) | ||||
| #define IOCTL_DDB_READ_REG   _IOWR(DDB_MAGIC, 0x04, struct ddb_reg) | ||||
| #define IOCTL_DDB_WRITE_REG  _IOW(DDB_MAGIC, 0x05, struct ddb_reg) | ||||
| #define IOCTL_DDB_READ_MEM   _IOWR(DDB_MAGIC, 0x06, struct ddb_mem) | ||||
| #define IOCTL_DDB_WRITE_MEM  _IOR(DDB_MAGIC, 0x07, struct ddb_mem) | ||||
| #define IOCTL_DDB_READ_MDIO  _IOWR(DDB_MAGIC, 0x08, struct ddb_mdio) | ||||
| #define IOCTL_DDB_WRITE_MDIO _IOR(DDB_MAGIC, 0x09, struct ddb_mdio) | ||||
| #define IOCTL_DDB_READ_I2C   _IOWR(DDB_MAGIC, 0x0a, struct ddb_i2c_msg) | ||||
| #define IOCTL_DDB_WRITE_I2C  _IOR(DDB_MAGIC, 0x0b, struct ddb_i2c_msg) | ||||
							
								
								
									
										68
									
								
								apps/octonet/ns.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								apps/octonet/ns.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| #ifndef _UAPI_DVBNS_H_ | ||||
| #define _UAPI_DVBNS_H_ | ||||
|  | ||||
| #include <linux/types.h> | ||||
|  | ||||
| struct dvb_ns_params { | ||||
| 	__u8     smac[6]; | ||||
| 	__u8     dmac[6]; | ||||
| 	__u8     sip[16]; | ||||
| 	__u8     dip[16]; | ||||
| 	__u16    sport; | ||||
| 	__u16    dport; | ||||
| 	__u16    sport2; | ||||
| 	__u16    dport2; | ||||
| 	__u8     ssrc[8]; | ||||
| 	__u8     flags; | ||||
| 	__u8     qos; | ||||
| 	__u16    vlan; | ||||
| 	__u8     ttl; | ||||
| }; | ||||
|  | ||||
| #define DVB_NS_IPV6    1 | ||||
| #define DVB_NS_RTP     2 | ||||
| #define DVB_NS_RTCP    4 | ||||
| #define DVB_NS_RTP_TO  8 | ||||
|  | ||||
| struct dvb_ns_rtcp { | ||||
| 	__u8    *msg; | ||||
| 	__u16    len; | ||||
| }; | ||||
|  | ||||
| struct dvb_ns_packet { | ||||
| 	__u8    *buf; | ||||
| 	__u8     count; | ||||
| }; | ||||
|  | ||||
| struct dvb_nsd_ts { | ||||
| 	__u16    pid; | ||||
| 	__u16    num; | ||||
| 	__u16    input; | ||||
| 	__u16    timeout; | ||||
| 	__u16    len; | ||||
| 	__u8    *ts; | ||||
| 	__u8     mode; | ||||
| 	__u8     table; | ||||
|  | ||||
| 	__u8	 filter_mask; | ||||
|  	__u8     section; | ||||
| 	__u16	 section_id; | ||||
| }; | ||||
|  | ||||
| #define NS_SET_NET               _IOW('o', 192, struct dvb_ns_params) | ||||
| #define NS_START                 _IO('o', 193) | ||||
| #define NS_STOP                  _IO('o', 194) | ||||
| #define NS_SET_PID               _IOW('o', 195, __u16) | ||||
| #define NS_SET_PIDS              _IOW('o', 196, __u8 *) | ||||
| #define NS_SET_RTCP_MSG          _IOW('o', 197, struct dvb_ns_rtcp) | ||||
|  | ||||
| #define NSD_START_GET_TS         _IOWR('o', 198, struct dvb_nsd_ts) | ||||
| #define NSD_STOP_GET_TS          _IOWR('o', 199, struct dvb_nsd_ts) | ||||
| #define NSD_CANCEL_GET_TS        _IO('o', 200) | ||||
| #define NSD_POLL_GET_TS          _IOWR('o', 201, struct dvb_nsd_ts) | ||||
|  | ||||
| #define NS_SET_PACKETS           _IOW('o', 202, struct dvb_ns_packet) | ||||
| #define NS_INSERT_PACKETS	 _IOW('o', 203, __u8) | ||||
| #define NS_SET_CI	         _IOW('o', 204, __u8) | ||||
|  | ||||
| #endif /*_UAPI_DVBNS_H_*/ | ||||
							
								
								
									
										37
									
								
								apps/octonet/octokey.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								apps/octonet/octokey.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <dirent.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/select.h> | ||||
| #include <sys/time.h> | ||||
| #include <termios.h> | ||||
| #include <signal.h> | ||||
|  | ||||
| #include <linux/input.h> | ||||
|  | ||||
|  | ||||
| int main(int argc, char *argv[]) | ||||
| { | ||||
| 	int fd, len; | ||||
| 	struct input_event ev; | ||||
| 	uint32_t time; | ||||
|  | ||||
| 	fd = open("/dev/input/event0", O_RDONLY); | ||||
|  | ||||
| 	if (fd < 0) | ||||
| 		return -1; | ||||
| 	 | ||||
| 	while (1) { | ||||
| 		if ((len = read(fd, &ev, sizeof(ev)) < sizeof(struct input_event))) | ||||
| 			return -1; | ||||
| 		printf("%u.%06u %u %u %u\n", ev.time.tv_sec, ev.time.tv_usec, ev.type, ev.code, ev.value);  | ||||
| 	} | ||||
| 	 | ||||
|  | ||||
| } | ||||
							
								
								
									
										83
									
								
								apps/octonet/octonet.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								apps/octonet/octonet.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdint.h> | ||||
| #include <unistd.h> | ||||
| #include <getopt.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
| #include <string.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <linux/types.h> | ||||
| #include "ns.h" | ||||
|  | ||||
|  | ||||
| struct dvb_ns_params nsp = { | ||||
| 	.dmac = { 0x00, 0x01, 0x2e, 0x3a, 0x66,0xfc }, | ||||
| 	.smac = { 0x00, 0x12, 0x34, 0x56, 0x78,0x90 }, | ||||
| 	.sip = { 192, 168, 2, 80 }, | ||||
| 	.dip = { 192, 168, 2, 58 }, | ||||
| 	.sport = 1234, | ||||
| 	.dport = 6670, | ||||
| 	.ssrc = { 0x91, 0x82, 0x73, 0x64 }, | ||||
| }; | ||||
|  | ||||
| static int set(int fd) | ||||
| { | ||||
| 	uint16_t pid = 0xa000; | ||||
|  | ||||
| 	ioctl(fd, NS_SET_NET, &nsp); | ||||
| 	ioctl(fd, NS_START); | ||||
| 	ioctl(fd, NS_SET_PID, &pid); | ||||
| 	while(1); | ||||
| 	ioctl(fd, NS_STOP); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
| 	int ddbnum; | ||||
| 	int force; | ||||
| 	int ddb; | ||||
| 	char ddbname[80]; | ||||
|  | ||||
|         while (1) { | ||||
|                 int oi = 0; | ||||
| 		int c; | ||||
|                 static struct option lopts[] = { | ||||
| 			{"help", no_argument , NULL, 'h'}, | ||||
| 			{"force", no_argument , NULL, 'f'}, | ||||
| 			{0, 0, 0, 0} | ||||
| 		}; | ||||
|                 c = getopt_long(argc, argv,  | ||||
| 				"n:l:fh", | ||||
| 				lopts, &oi); | ||||
| 		if (c == -1) | ||||
| 			break; | ||||
|  | ||||
| 		switch (c) { | ||||
| 		case 'm': | ||||
| 			 | ||||
| 			break; | ||||
| 		case 'n': | ||||
| 			ddbnum = strtol(optarg, NULL, 0); | ||||
| 			break; | ||||
| 		case 'f': | ||||
| 			force = 1; | ||||
| 			break; | ||||
| 		case 'h': | ||||
| 		default: | ||||
| 			break; | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
| 	if (optind < argc) { | ||||
| 		printf("Warning: unused arguments\n"); | ||||
| 	} | ||||
| 	sprintf(ddbname, "/dev/dvb/adapter0/ns%d", ddbnum); | ||||
| 	ddb=open(ddbname, O_RDWR); | ||||
| 	if (ddb < 0) { | ||||
| 		printf("Could not open device\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										33
									
								
								apps/setmod.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								apps/setmod.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| #include <stdio.h> | ||||
| #include <ctype.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <stdint.h> | ||||
| #include <stdlib.h> | ||||
| #include <fcntl.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <pthread.h> | ||||
|  | ||||
| #include <linux/dvb/mod.h> | ||||
|  | ||||
| int main() | ||||
| { | ||||
| 	int fd; | ||||
| 	struct dvb_mod_params mp; | ||||
| 	struct dvb_mod_channel_params mc; | ||||
|  | ||||
| 	fd = open("/dev/dvb/adapter1/mod0", O_RDONLY); | ||||
|  | ||||
| 	mp.base_frequency = 722000000; | ||||
| 	mp.attenuator = 0; | ||||
| 	ioctl(fd, DVB_MOD_SET, &mp); | ||||
|  | ||||
| 	mc.modulation = QAM_256; | ||||
| 	mc.input_bitrate = 40000000ULL << 32; | ||||
| 	mc.pcr_correction = 0; | ||||
| 	ioctl(fd, DVB_MOD_CHANNEL_SET, &mc); | ||||
| 	close(fd); | ||||
| } | ||||
|  | ||||
							
								
								
									
										8
									
								
								ddbridge/Kbuild
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								ddbridge/Kbuild
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843 -DCONFIG_DVB_LNBP21 -DCONFIG_DVB_STV090x -DCONFIG_DVB_STV6110x -DCONFIG_DVB_DRXK -DCONFIG_DVB_STV0910 -DCONFIG_DVB_STV6111 -DCONFIG_DVB_LNBH25 -DCONFIG_DVB_MXL5XX | ||||
|  | ||||
| obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o  | ||||
| obj-$(CONFIG_DVB_OCTONET) += octonet.o  | ||||
|  | ||||
| EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -Idrivers/media/dvb-frontends | ||||
| EXTRA_CFLAGS += -Idrivers/media/common/tuners  | ||||
| NOSTDINC_FLAGS += -I$(SUBDIRS)/frontends -I$(SUBDIRS)/include -I$(SUBDIRS)/dvb-core  | ||||
							
								
								
									
										19
									
								
								ddbridge/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								ddbridge/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| KDIR	?= /lib/modules/$(shell uname -r)/build | ||||
| PWD	:= $(shell pwd) | ||||
|  | ||||
| MODDEFS := CONFIG_DVB_DDBRIDGE=m  | ||||
|  | ||||
| all:  | ||||
| 	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MODDEFS) modules | ||||
| 	$(MAKE) -C apps | ||||
|  | ||||
| dep: | ||||
| 	DIR=`pwd`; (cd $(TOPDIR); make SUBDIRS=$$DIR dep) | ||||
|  | ||||
| install: all | ||||
| 	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install | ||||
|  | ||||
| clean: | ||||
| 	rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules* | ||||
|  | ||||
|  | ||||
							
								
								
									
										4641
									
								
								ddbridge/ddbridge-core.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4641
									
								
								ddbridge/ddbridge-core.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										275
									
								
								ddbridge/ddbridge-i2c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								ddbridge/ddbridge-i2c.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,275 @@ | ||||
| /* | ||||
|  * ddbridge-i2c.c: Digital Devices bridge i2c driver | ||||
|  * | ||||
|  * Copyright (C) 2010-2015 Digital Devices GmbH | ||||
|  *                         Ralph Metzler <rjkm@metzlerbros.de> | ||||
|  *                         Marcus Metzler <mocm@metzlerbros.de> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| static int i2c_io(struct i2c_adapter *adapter, u8 adr, | ||||
| 		  u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) | ||||
| { | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0, | ||||
| 				   .buf  = wbuf, .len   = wlen }, | ||||
| 				  {.addr = adr,  .flags = I2C_M_RD, | ||||
| 				   .buf  = rbuf,  .len   = rlen } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) | ||||
| { | ||||
| 	struct i2c_msg msg = {.addr = adr, .flags = 0, | ||||
| 			      .buf = data, .len = len}; | ||||
|  | ||||
| 	return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) | ||||
| { | ||||
| 	struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD, | ||||
| 				   .buf  = val,  .len   = 1 } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static int i2c_read_regs(struct i2c_adapter *adapter, | ||||
| 			 u8 adr, u8 reg, u8 *val, u8 len) | ||||
| { | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0, | ||||
| 				   .buf  = ®, .len   = 1 }, | ||||
| 				  {.addr = adr,  .flags = I2C_M_RD, | ||||
| 				   .buf  = val,  .len   = len } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static int i2c_read_regs16(struct i2c_adapter *adapter, | ||||
| 			   u8 adr, u16 reg, u8 *val, u8 len) | ||||
| { | ||||
| 	u8 reg16[2] = { reg >> 8, reg }; | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0, | ||||
| 				   .buf  = reg16, .len   = 2 }, | ||||
| 				  {.addr = adr,  .flags = I2C_M_RD, | ||||
| 				   .buf  = val,  .len   = len } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) | ||||
| { | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0, | ||||
| 				   .buf  = ®, .len   = 1}, | ||||
| 				  {.addr = adr,  .flags = I2C_M_RD, | ||||
| 				   .buf  = val,  .len   = 1 } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, | ||||
| 			  u16 reg, u8 *val) | ||||
| { | ||||
| 	u8 msg[2] = {reg >> 8, reg & 0xff}; | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||||
| 				   .buf  = msg, .len   = 2}, | ||||
| 				  {.addr = adr, .flags = I2C_M_RD, | ||||
| 				   .buf  = val, .len   = 1 } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, | ||||
| 			   u16 reg, u8 val) | ||||
| { | ||||
| 	u8 msg[3] = {reg >> 8, reg & 0xff, val}; | ||||
|  | ||||
| 	return i2c_write(adap, adr, msg, 3); | ||||
| } | ||||
|  | ||||
| static int i2c_write_reg(struct i2c_adapter *adap, u8 adr, | ||||
| 			 u8 reg, u8 val) | ||||
| { | ||||
| 	u8 msg[2] = {reg, val}; | ||||
|  | ||||
| 	return i2c_write(adap, adr, msg, 2); | ||||
| } | ||||
|  | ||||
| static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) | ||||
| { | ||||
| 	struct ddb *dev = i2c->dev; | ||||
| 	unsigned long stat; | ||||
| 	u32 val; | ||||
|  | ||||
| 	ddbwritel(dev, (adr << 9) | cmd, i2c->regs + I2C_COMMAND); | ||||
| 	stat = wait_for_completion_timeout(&i2c->completion, HZ); | ||||
| 	if (stat == 0) { | ||||
| 		pr_err("DDBridge I2C timeout, card %d, port %d, link %u\n", | ||||
| 		       dev->nr, i2c->nr, i2c->link); | ||||
| #ifdef CONFIG_PCI_MSI | ||||
| 		{ /* MSI debugging*/ | ||||
| 			u32 istat = ddbreadl(dev, INTERRUPT_STATUS); | ||||
|  | ||||
| 			dev_err(dev->dev, "DDBridge IRS %08x\n", istat); | ||||
| 			ddbwritel(dev, istat, INTERRUPT_ACK); | ||||
| 		} | ||||
| #endif | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 	val = ddbreadl(dev, i2c->regs + I2C_COMMAND); | ||||
| 	if (val & 0x70000) | ||||
| 		return -EIO; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, | ||||
| 			       struct i2c_msg msg[], int num) | ||||
| { | ||||
| 	struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter); | ||||
| 	struct ddb *dev = i2c->dev; | ||||
| 	u8 addr = 0; | ||||
| 	 | ||||
| 	if (num != 1 && num != 2) | ||||
| 		return -EIO; | ||||
| 	addr = msg[0].addr; | ||||
| 	if (msg[0].len > i2c->bsize) | ||||
| 		return -EIO; | ||||
| 	if (num == 2 && msg[1].flags & I2C_M_RD && | ||||
| 	    !(msg[0].flags & I2C_M_RD)) { | ||||
| 		if (msg[1].len > i2c->bsize) | ||||
| 			return -EIO; | ||||
| 		ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); | ||||
| 		ddbwritel(dev, msg[0].len | (msg[1].len << 16), | ||||
| 			  i2c->regs + I2C_TASKLENGTH); | ||||
| 		if (!ddb_i2c_cmd(i2c, addr, 1)) { | ||||
| 			ddbcpyfrom(dev, msg[1].buf, | ||||
| 				   i2c->rbuf, | ||||
| 				   msg[1].len); | ||||
| 			return num; | ||||
| 		} | ||||
| 	} | ||||
| 	if (num == 1 && !(msg[0].flags & I2C_M_RD)) { | ||||
| 		ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); | ||||
| 		ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH); | ||||
| 		if (!ddb_i2c_cmd(i2c, addr, 2)) | ||||
| 			return num; | ||||
| 	} | ||||
| 	if (num == 1 && (msg[0].flags & I2C_M_RD)) { | ||||
| 		ddbwritel(dev, msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); | ||||
| 		if (!ddb_i2c_cmd(i2c, addr, 3)) { | ||||
| 			ddbcpyfrom(dev, msg[0].buf, | ||||
| 				   i2c->rbuf, msg[0].len); | ||||
| 			return num; | ||||
| 		} | ||||
| 	} | ||||
| 	return -EIO; | ||||
| } | ||||
|  | ||||
| static u32 ddb_i2c_functionality(struct i2c_adapter *adap) | ||||
| { | ||||
| 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||||
| } | ||||
|  | ||||
| struct i2c_algorithm ddb_i2c_algo = { | ||||
| 	.master_xfer   = ddb_i2c_master_xfer, | ||||
| 	.functionality = ddb_i2c_functionality, | ||||
| }; | ||||
|  | ||||
| static void ddb_i2c_release(struct ddb *dev) | ||||
| { | ||||
| 	int i; | ||||
| 	struct ddb_i2c *i2c; | ||||
|  | ||||
| 	for (i = 0; i < dev->i2c_num; i++) { | ||||
| 		i2c = &dev->i2c[i]; | ||||
| 		i2c_del_adapter(&i2c->adap); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void i2c_handler(unsigned long priv) | ||||
| { | ||||
| 	struct ddb_i2c *i2c = (struct ddb_i2c *) priv; | ||||
|  | ||||
| 	complete(&i2c->completion); | ||||
| } | ||||
|  | ||||
| static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c, | ||||
| 		       struct ddb_regmap *regmap, int link, int i, int num) | ||||
| { | ||||
| 	struct i2c_adapter *adap; | ||||
| 	 | ||||
| 	i2c->nr = i; | ||||
| 	i2c->dev = dev; | ||||
| 	i2c->link = link; | ||||
| 	i2c->bsize = regmap->i2c_buf->size; | ||||
| 	i2c->wbuf = DDB_LINK_TAG(link) | (regmap->i2c_buf->base + i2c->bsize * i); | ||||
| 	i2c->rbuf = i2c->wbuf;// + i2c->bsize / 2; | ||||
| 	i2c->regs = DDB_LINK_TAG(link) | (regmap->i2c->base + regmap->i2c->size * i); | ||||
| 	ddbwritel(dev, I2C_SPEED_100, i2c->regs + I2C_TIMING); | ||||
| 	ddbwritel(dev, ((i2c->rbuf & 0xffff) << 16) | (i2c->wbuf & 0xffff), | ||||
| 		  i2c->regs + I2C_TASKADDRESS); | ||||
| 	init_completion(&i2c->completion); | ||||
| 	 | ||||
| 	adap = &i2c->adap; | ||||
| 	i2c_set_adapdata(adap, i2c); | ||||
| #ifdef I2C_ADAP_CLASS_TV_DIGITAL | ||||
| 	adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; | ||||
| #else | ||||
| #ifdef I2C_CLASS_TV_ANALOG | ||||
| 	adap->class = I2C_CLASS_TV_ANALOG; | ||||
| #endif | ||||
| #endif | ||||
| 	strcpy(adap->name, "ddbridge"); | ||||
| 	adap->algo = &ddb_i2c_algo; | ||||
| 	adap->algo_data = (void *)i2c; | ||||
| 	adap->dev.parent = dev->dev; | ||||
| 	return i2c_add_adapter(adap); | ||||
| } | ||||
|  | ||||
| static int ddb_i2c_init(struct ddb *dev) | ||||
| { | ||||
| 	int stat = 0; | ||||
| 	u32 i, j, num = 0, l; | ||||
| 	struct ddb_i2c *i2c; | ||||
| 	struct i2c_adapter *adap; | ||||
| 	struct ddb_regmap *regmap; | ||||
| 	 | ||||
| 	for (l = 0; l < DDB_MAX_LINK; l++) { | ||||
| 		if (!dev->link[l].info) | ||||
| 			continue; | ||||
| 		regmap = dev->link[l].info->regmap; | ||||
| 		if (!regmap || !regmap->i2c) | ||||
| 			continue; | ||||
| 		for (i = 0; i < regmap->i2c->num; i++) { | ||||
| 			if (!(dev->link[l].info->i2c_mask & (1 << i))) | ||||
| 				continue; | ||||
| 			i2c = &dev->i2c[num]; | ||||
| 			dev->handler_data[i + l * 32] = (unsigned long) i2c; | ||||
| 			dev->handler[i + l * 32] = i2c_handler; | ||||
| 			stat = ddb_i2c_add(dev, i2c, regmap, l, i, num); | ||||
| 			if (stat) | ||||
| 				break; | ||||
| 			num++; | ||||
| 		} | ||||
| 	} | ||||
| 	if (stat) { | ||||
| 		for (j = 0; j < num; j++) { | ||||
| 			i2c = &dev->i2c[j]; | ||||
| 			adap = &i2c->adap; | ||||
| 			i2c_del_adapter(adap); | ||||
| 		} | ||||
| 	} else  | ||||
| 		dev->i2c_num = num; | ||||
| 	return stat; | ||||
| } | ||||
|  | ||||
							
								
								
									
										116
									
								
								ddbridge/ddbridge-i2c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								ddbridge/ddbridge-i2c.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,116 @@ | ||||
| /* | ||||
|  * ddbridge-i2c.h: Digital Devices bridge i2c driver | ||||
|  * | ||||
|  * Copyright (C) 2010-2015 Digital Devices GmbH | ||||
|  *                         Marcus Metzler <mocm@metzlerbros.de> | ||||
|  *                         Ralph Metzler <rjkm@metzlerbros.de> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| #ifndef _DDBRIDGE_I2C_H_ | ||||
| #define _DDBRIDGE_I2C_H_ | ||||
|  | ||||
| #include <linux/i2c.h> | ||||
| #include <linux/types.h> | ||||
|  | ||||
| static inline int i2c_io(struct i2c_adapter *adapter, u8 adr, | ||||
| 			 u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) | ||||
| { | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0, | ||||
| 				   .buf  = wbuf, .len   = wlen }, | ||||
| 				  {.addr = adr,  .flags = I2C_M_RD, | ||||
| 				   .buf  = rbuf,  .len   = rlen } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static inline int i2c_write(struct i2c_adapter *adap, u8 adr, | ||||
| 			    u8 *data, int len) | ||||
| { | ||||
| 	struct i2c_msg msg = {.addr = adr, .flags = 0, | ||||
| 			      .buf = data, .len = len}; | ||||
|  | ||||
| 	return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static inline int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) | ||||
| { | ||||
| 	struct i2c_msg msgs[1] = {{.addr = adr,  .flags = I2C_M_RD, | ||||
| 				   .buf  = val,  .len   = 1 } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static inline int i2c_read_regs(struct i2c_adapter *adapter, | ||||
| 				u8 adr, u8 reg, u8 *val, u8 len) | ||||
| { | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0, | ||||
| 				   .buf  = ®, .len   = 1 }, | ||||
| 				  {.addr = adr,  .flags = I2C_M_RD, | ||||
| 				   .buf  = val,  .len   = len } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static inline int i2c_read_regs16(struct i2c_adapter *adapter, | ||||
| 				  u8 adr, u16 reg, u8 *val, u8 len) | ||||
| { | ||||
| 	u8 reg16[2] = { reg >> 8, reg }; | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0, | ||||
| 				   .buf  = reg16, .len   = 2 }, | ||||
| 				  {.addr = adr,  .flags = I2C_M_RD, | ||||
| 				   .buf  = val,  .len   = len } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static inline int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, | ||||
| 			       u8 reg, u8 *val) | ||||
| { | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr,  .flags = 0, | ||||
| 				   .buf  = ®, .len   = 1}, | ||||
| 				  {.addr = adr,  .flags = I2C_M_RD, | ||||
| 				   .buf  = val,  .len   = 1 } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static inline int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, | ||||
| 				 u16 reg, u8 *val) | ||||
| { | ||||
| 	u8 msg[2] = {reg >> 8, reg & 0xff}; | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||||
| 				   .buf  = msg, .len   = 2}, | ||||
| 				  {.addr = adr, .flags = I2C_M_RD, | ||||
| 				   .buf  = val, .len   = 1 } }; | ||||
| 	return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; | ||||
| } | ||||
|  | ||||
| static inline int i2c_write_reg16(struct i2c_adapter *adap, u8 adr, | ||||
| 				  u16 reg, u8 val) | ||||
| { | ||||
| 	u8 msg[3] = {reg >> 8, reg & 0xff, val}; | ||||
|  | ||||
| 	return i2c_write(adap, adr, msg, 3); | ||||
| } | ||||
|  | ||||
| static inline int i2c_write_reg(struct i2c_adapter *adap, u8 adr, | ||||
| 				u8 reg, u8 val) | ||||
| { | ||||
| 	u8 msg[2] = {reg, val}; | ||||
|  | ||||
| 	return i2c_write(adap, adr, msg, 2); | ||||
| } | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										1150
									
								
								ddbridge/ddbridge-mod.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1150
									
								
								ddbridge/ddbridge-mod.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										491
									
								
								ddbridge/ddbridge-ns.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										491
									
								
								ddbridge/ddbridge-ns.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,491 @@ | ||||
| /* | ||||
|  * ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming | ||||
|  * | ||||
|  * Copyright (C) 2010-2015 Marcus Metzler <mocm@metzlerbros.de> | ||||
|  *                         Ralph Metzler <rjkm@metzlerbros.de> | ||||
|  *                         Digital Devices GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| static int ddb_dvb_ns_input_start(struct ddb_input *input); | ||||
| static int ddb_dvb_ns_input_stop(struct ddb_input *input); | ||||
|  | ||||
| static u16 calc_pcs(struct dvb_ns_params *p) | ||||
| { | ||||
| 	u32 sum = 0; | ||||
| 	u16 pcs; | ||||
|  | ||||
| 	sum += (p->sip[0] << 8) | p->sip[1]; | ||||
| 	sum += (p->sip[2] << 8) | p->sip[3]; | ||||
| 	sum += (p->dip[0] << 8) | p->dip[1]; | ||||
| 	sum += (p->dip[2] << 8) | p->dip[3]; | ||||
| 	sum += 0x11; /* UDP proto */ | ||||
| 	sum = (sum >> 16) + (sum & 0xffff); | ||||
| 	pcs = sum; | ||||
| 	return pcs; | ||||
| } | ||||
|  | ||||
| static u16 calc_pcs16(struct dvb_ns_params *p, int ipv) | ||||
| { | ||||
| 	u32 sum = 0, i; | ||||
| 	u16 pcs; | ||||
|  | ||||
| 	for (i = 0; i < ipv ? 16 : 4; i += 2) { | ||||
| 		sum += (p->sip[i] << 8) | p->sip[i + 1]; | ||||
| 		sum += (p->dip[i] << 8) | p->dip[i + 1]; | ||||
| 	} | ||||
| 	sum += 0x11; /* UDP proto */ | ||||
| 	sum = (sum >> 16) + (sum & 0xffff); | ||||
| 	pcs = sum; | ||||
| 	return pcs; | ||||
| } | ||||
|  | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| static void ns_free(struct dvbnss *nss) | ||||
| { | ||||
| 	struct ddb_ns *dns = (struct ddb_ns *) nss->priv; | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
|  | ||||
| 	mutex_lock(&dev->mutex); | ||||
| 	dns->input = 0; | ||||
| 	mutex_unlock(&dev->mutex); | ||||
| } | ||||
|  | ||||
| static int ns_alloc(struct dvbnss *nss) | ||||
| { | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
| 	int i, ret = -EBUSY; | ||||
|  | ||||
| 	mutex_lock(&dev->mutex); | ||||
| 	for (i = 0; i < dev->ns_num; i++) { | ||||
| 		if (dev->ns[i].input) | ||||
| 			continue; | ||||
| 		dev->ns[i].input = input; | ||||
| 		dev->ns[i].fe = input; | ||||
| 		nss->priv = &dev->ns[i]; | ||||
| 		ret = 0; | ||||
| 		/*pr_info("%s i=%d fe=%d\n", __func__, i, input->nr); */ | ||||
| 		break; | ||||
| 	} | ||||
| 	ddbwritel(dev, 0x03, RTP_MASTER_CONTROL); | ||||
| 	mutex_unlock(&dev->mutex); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static int ns_set_pids(struct dvbnss *nss) | ||||
| { | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
| 	struct ddb_ns *dns = (struct ddb_ns *) nss->priv; | ||||
|  | ||||
| 	if (dev->ids.devid == 0x0301dd01) { | ||||
| 		u32 sys = 0; | ||||
| 		int pid, j = 1; | ||||
|  | ||||
| 		sys |= nss->pids[0] & 3; | ||||
| 		sys |= (nss->pids[2] & 0x1f) << 4; | ||||
| 		ddbwritel(dev, sys, PID_FILTER_SYSTEM_PIDS(dns->nr)); | ||||
| 		for (pid = 20; j < 5 && pid < 8192; pid++) | ||||
| 			if (nss->pids[pid >> 3] & (1 << (pid & 7))) { | ||||
| 				ddbwritel(dev, 0x8000 | pid, | ||||
| 					  PID_FILTER_PID(dns->nr, j)); | ||||
| 				j++; | ||||
| 			} | ||||
| 		/* disable unused pids */ | ||||
| 		for (; j < 5; j++) | ||||
| 			ddbwritel(dev, 0, PID_FILTER_PID(dns->nr, j)); | ||||
| 	} else | ||||
| 		ddbcpyto(dev, STREAM_PIDS(dns->nr), nss->pids, 0x400); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int ns_set_pid(struct dvbnss *nss, u16 pid) | ||||
| { | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
| 	struct ddb_ns *dns = (struct ddb_ns *) nss->priv; | ||||
| 	u16 byte = (pid & 0x1fff) >> 3; | ||||
| 	u8 bit = 1 << (pid & 7); | ||||
| 	u32 off = STREAM_PIDS(dns->nr); | ||||
|  | ||||
| #if 1 | ||||
| 	if (dev->ids.devid == 0x0301dd01) { | ||||
| 		if (pid & 0x2000) { | ||||
| 			if (pid & 0x8000) | ||||
| 				memset(nss->pids, 0xff, 0x400); | ||||
| 			else | ||||
| 				memset(nss->pids, 0x00, 0x400); | ||||
| 		} else { | ||||
| 			if (pid & 0x8000) | ||||
| 				nss->pids[byte] |= bit; | ||||
| 			else | ||||
| 				nss->pids[byte] &= ~bit; | ||||
| 		} | ||||
| 		ns_set_pids(nss); | ||||
| 	} else { | ||||
| 		if (pid & 0x2000) { | ||||
| 			if (pid & 0x8000) | ||||
| 				ddbmemset(dev, off, 0xff, 0x400); | ||||
| 			else | ||||
| 				ddbmemset(dev, off, 0x00, 0x400); | ||||
| 		} else { | ||||
| 			u8 val = ddbreadb(dev, off + byte); | ||||
|  | ||||
| 			if (pid & 0x8000) | ||||
| 				ddbwriteb(dev, val | bit, off + byte); | ||||
| 			else | ||||
| 				ddbwriteb(dev, val & ~bit, off + byte); | ||||
| 		} | ||||
| 	} | ||||
| #else | ||||
| 	ddbcpyto(dev, STREAM_PIDS(dns->nr), nss->pids, 0x400); | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int citoport(struct ddb *dev, u8 ci) | ||||
| { | ||||
| 	int i, j; | ||||
|  | ||||
| 	for (i = j = 0; i < dev->link[0].info->port_num; i++) { | ||||
| 		if (dev->port[i].class == DDB_PORT_CI) { | ||||
| 			if (j == ci) | ||||
| 				return i; | ||||
| 			j++; | ||||
| 		} | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static int ns_set_ci(struct dvbnss *nss, u8 ci) | ||||
| { | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
| 	struct ddb_ns *dns = (struct ddb_ns *) nss->priv; | ||||
| 	int ciport; | ||||
|  | ||||
| 	if (ci == 255) { | ||||
| 		dns->fe = input; | ||||
| 		return 0; | ||||
| 	} | ||||
| 	ciport = citoport(dev, ci); | ||||
| 	if (ciport < 0) | ||||
| 		return -EINVAL; | ||||
| 	 | ||||
| 	pr_info("input %d.%d to ci %d at port %d\n", input->port->lnr, input->nr, ci, ciport); | ||||
| 	ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1c, TS_OUTPUT_CONTROL(ciport)); | ||||
| 	usleep_range(1, 5); | ||||
| 	ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1d, TS_OUTPUT_CONTROL(ciport)); | ||||
| 	dns->fe = dev->port[ciport].input[0]; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static u8 rtp_head[]  = { | ||||
| 	0x80, 0x21, | ||||
| 	0x00, 0x00, /* seq number */ | ||||
| 	0x00, 0x00, 0x00, 0x00, /* time stamp*/ | ||||
| 	0x91, 0x82, 0x73, 0x64, /* SSRC */ | ||||
| }; | ||||
|  | ||||
| static u8 rtcp_head[] = { | ||||
| 	/* SR off 42:8 len 28*/ | ||||
| 	0x80, 0xc8, /* SR type */ | ||||
| 	0x00, 0x06, /* len  */ | ||||
| 	0x91, 0x82, 0x73, 0x64, /* SSRC */ | ||||
| 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* NTP */ | ||||
| 	0x73, 0x64, 0x00, 0x00, /* RTP TS */ | ||||
| 	0x00, 0x00, 0x00, 0x00, /* packet count */ | ||||
| 	0x00, 0x00, 0x00, 0x00, /* octet count */ | ||||
| 	/* SDES off 70:36 len 20 */ | ||||
| 	0x81, 0xca, /* SDES */ | ||||
| 	0x00, 0x03, /* len */ | ||||
| 	0x91, 0x82, 0x73, 0x64, /* SSRC */ | ||||
| 	0x01, 0x05, /* CNAME item */ | ||||
| 	0x53, 0x41, 0x54, 0x49, 0x50, /* "SATIP" */ | ||||
| 	0x00, /* item type 0 */ | ||||
| 	/*  APP off 86:52 len 16+string  length */ | ||||
| 	0x80, 0xcc, /* APP */ | ||||
| 	0x00, 0x04, /* len */ | ||||
| 	0x91, 0x82, 0x73, 0x64, /* SSRC */ | ||||
| 	0x53, 0x45, 0x53, 0x31, /* "SES1" */ | ||||
| 	0x00, 0x00, /* identifier */ | ||||
| 	0x00, 0x00, /* string length */ | ||||
| 	/* string off 102:68 */ | ||||
| }; | ||||
|  | ||||
| static int ns_set_rtcp_msg(struct dvbnss *nss, u8 *msg, u32 len) | ||||
| { | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
| 	struct ddb_ns *dns = (struct ddb_ns *) nss->priv; | ||||
| 	u32 off = STREAM_PACKET_ADR(dns->nr); | ||||
| 	u32 coff = 96; | ||||
| 	u16 wlen; | ||||
|  | ||||
| 	if (!len) { | ||||
| 		ddbwritel(dev, ddbreadl(dev, STREAM_CONTROL(dns->nr)) & | ||||
| 			  ~0x10, | ||||
| 			  STREAM_CONTROL(dns->nr)); | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if (copy_from_user(dns->p + coff + dns->rtcp_len, msg, len)) | ||||
| 		return -EFAULT; | ||||
| 	dns->p[coff + dns->rtcp_len - 2] = (len >> 8); | ||||
| 	dns->p[coff + dns->rtcp_len - 1] = (len & 0xff); | ||||
| 	if (len & 3) { | ||||
| 		u32 pad = 4 - (len & 3); | ||||
|  | ||||
| 		memset(dns->p + coff + dns->rtcp_len + len, 0, pad); | ||||
| 		len += pad; | ||||
| 	} | ||||
| 	wlen = len / 4; | ||||
| 	wlen += 3; | ||||
| 	dns->p[coff + dns->rtcp_len - 14] = (wlen >> 8); | ||||
| 	dns->p[coff + dns->rtcp_len - 13] = (wlen & 0xff); | ||||
| 	ddbcpyto(dev, off, dns->p, sizeof(dns->p)); | ||||
| 	ddbwritel(dev, (dns->rtcp_udplen + len) | | ||||
| 		  ((STREAM_PACKET_OFF(dns->nr) + coff) << 16), | ||||
| 		  STREAM_RTCP_PACKET(dns->nr)); | ||||
| 	ddbwritel(dev, ddbreadl(dev, STREAM_CONTROL(dns->nr)) | 0x10, | ||||
| 		  STREAM_CONTROL(dns->nr)); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static u32 set_nsbuf(struct dvb_ns_params *p, u8 *buf, | ||||
| 		     u32 *udplen, int rtcp, int vlan) | ||||
| { | ||||
| 	u32 c = 0; | ||||
| 	u16 pcs; | ||||
| 	u16 sport, dport; | ||||
|  | ||||
| 	sport = rtcp ? p->sport2 : p->sport; | ||||
| 	dport = rtcp ? p->dport2 : p->dport; | ||||
|  | ||||
| 	/* MAC header */ | ||||
| 	memcpy(buf + c, p->dmac, 6); | ||||
| 	memcpy(buf + c + 6, p->smac, 6); | ||||
| 	c += 12; | ||||
| 	if (vlan) { | ||||
| 		buf[c + 0] = 0x81; | ||||
| 		buf[c + 1] = 0x00; | ||||
| 		buf[c + 2] = ((p->qos & 7) << 5) | ((p->vlan & 0xf00) >> 8); | ||||
| 		buf[c + 3] = p->vlan & 0xff; | ||||
| 		c += 4; | ||||
| 	} | ||||
| 	buf[c + 0] = 0x08; | ||||
| 	buf[c + 1] = 0x00; | ||||
| 	c += 2; | ||||
|  | ||||
| 	/* IP header */ | ||||
| 	if (p->flags & DVB_NS_IPV6) { | ||||
| 		u8 ip6head[8]  = { 0x65, 0x00, 0x00, 0x00, | ||||
| 				    0x00, 0x00, 0x11, 0x00, }; | ||||
| 		memcpy(buf + c, ip6head, sizeof(ip6head)); | ||||
| 		buf[c + 7] = p->ttl; | ||||
| 		memcpy(buf + c +  8, p->sip, 16); | ||||
| 		memcpy(buf + c + 24, p->dip, 16); | ||||
| 		c += 40; | ||||
|  | ||||
| 		/* UDP */ | ||||
| 		buf[c + 0] = sport >> 8; | ||||
| 		buf[c + 1] = sport & 0xff; | ||||
| 		buf[c + 2] = dport >> 8; | ||||
| 		buf[c + 3] = dport & 0xff; | ||||
| 		buf[c + 4] = 0; /* length */ | ||||
| 		buf[c + 5] = 0; | ||||
| 		pcs = calc_pcs16(p, p->flags & DVB_NS_IPV6); | ||||
| 		buf[c + 6] = pcs >> 8; | ||||
| 		buf[c + 7] = pcs & 0xff; | ||||
| 		c += 8; | ||||
| 		*udplen = 8; | ||||
|  | ||||
| 	} else { | ||||
| 		u8 ip4head[12]  = { 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
| 				    0x40, 0x00, 0x40, 0x11, 0x00, 0x00 }; | ||||
|  | ||||
| 		memcpy(buf + c, ip4head, sizeof(ip4head)); | ||||
| 		buf[c + 8] = p->ttl; | ||||
| 		memcpy(buf + c + 12, p->sip, 4); | ||||
| 		memcpy(buf + c + 16, p->dip, 4); | ||||
| 		c += 20; | ||||
|  | ||||
| 		/* UDP */ | ||||
| 		buf[c + 0] = sport >> 8; | ||||
| 		buf[c + 1] = sport & 0xff; | ||||
| 		buf[c + 2] = dport >> 8; | ||||
| 		buf[c + 3] = dport & 0xff; | ||||
| 		buf[c + 4] = 0; /* length */ | ||||
| 		buf[c + 5] = 0; | ||||
| 		pcs = calc_pcs(p); | ||||
| 		buf[c + 6] = pcs >> 8; | ||||
| 		buf[c + 7] = pcs & 0xff; | ||||
| 		c += 8; | ||||
| 		*udplen = 8; | ||||
| 	} | ||||
|  | ||||
| 	if (rtcp) { | ||||
| 		memcpy(buf + c, rtcp_head, sizeof(rtcp_head)); | ||||
| 		memcpy(buf + c +  4, p->ssrc, 4); | ||||
| 		memcpy(buf + c + 32, p->ssrc, 4); | ||||
| 		memcpy(buf + c + 48, p->ssrc, 4); | ||||
| 		c += sizeof(rtcp_head); | ||||
| 		*udplen += sizeof(rtcp_head); | ||||
| 	} else if (p->flags & DVB_NS_RTP) { | ||||
| 		memcpy(buf + c, rtp_head, sizeof(rtp_head)); | ||||
| 		memcpy(buf + c + 8, p->ssrc, 4); | ||||
| 		c += sizeof(rtp_head); | ||||
| 		*udplen += sizeof(rtp_head); | ||||
| 	} | ||||
| 	return c; | ||||
| } | ||||
|  | ||||
| static int ns_set_ts_packets(struct dvbnss *nss, u8 *buf, u32 len) | ||||
| { | ||||
| 	struct ddb_ns *dns = (struct ddb_ns *) nss->priv; | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
| 	u32 off = STREAM_PACKET_ADR(dns->nr); | ||||
|  | ||||
| 	if (nss->params.flags & DVB_NS_RTCP) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	if (copy_from_user(dns->p + dns->ts_offset, buf, len)) | ||||
| 		return -EFAULT; | ||||
| 	ddbcpyto(dev, off, dns->p, sizeof(dns->p)); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int ns_insert_ts_packets(struct dvbnss *nss, u8 count) | ||||
| { | ||||
| 	struct ddb_ns *dns = (struct ddb_ns *) nss->priv; | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
| 	u32 value = count; | ||||
|  | ||||
| 	if (nss->params.flags & DVB_NS_RTCP) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	if (count < 1 || count > 2) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	ddbwritel(dev, value, STREAM_INSERT_PACKET(dns->nr)); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int ns_set_net(struct dvbnss *nss) | ||||
| { | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
| 	struct dvb_ns_params *p = &nss->params; | ||||
| 	struct ddb_ns *dns = (struct ddb_ns *) nss->priv; | ||||
| 	u32 off = STREAM_PACKET_ADR(dns->nr); | ||||
| 	u32 coff = 96; | ||||
|  | ||||
| 	dns->ts_offset = set_nsbuf(p, dns->p, &dns->udplen, 0, dev->vlan); | ||||
| 	if (nss->params.flags & DVB_NS_RTCP) | ||||
| 		dns->rtcp_len = set_nsbuf(p, dns->p + coff, | ||||
| 					  &dns->rtcp_udplen, 1, dev->vlan); | ||||
| 	ddbcpyto(dev, off, dns->p, sizeof(dns->p)); | ||||
| 	ddbwritel(dev, dns->udplen | (STREAM_PACKET_OFF(dns->nr) << 16), | ||||
| 		  STREAM_RTP_PACKET(dns->nr)); | ||||
| 	ddbwritel(dev, dns->rtcp_udplen | | ||||
| 		  ((STREAM_PACKET_OFF(dns->nr) + coff) << 16), | ||||
| 		  STREAM_RTCP_PACKET(dns->nr)); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int ns_start(struct dvbnss *nss) | ||||
| { | ||||
| 	struct ddb_ns *dns = (struct ddb_ns *) nss->priv; | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
| 	u32 reg = 0x8003; | ||||
|  | ||||
| 	if (nss->params.flags & DVB_NS_RTCP) | ||||
| 		reg |= 0x10; | ||||
| 	if (nss->params.flags & DVB_NS_RTP_TO) | ||||
| 		reg |= 0x20; | ||||
| 	if (nss->params.flags & DVB_NS_RTP) | ||||
| 		reg |= 0x40; | ||||
| 	if (nss->params.flags & DVB_NS_IPV6) | ||||
| 		reg |= 0x80; | ||||
| 	if (dns->fe != input) | ||||
| 		ddb_dvb_ns_input_start(dns->fe); | ||||
| 	ddb_dvb_ns_input_start(input); | ||||
| 	printk("ns start ns %u, fe %u link %u\n", dns->nr, dns->fe->nr, dns->fe->port->lnr); | ||||
| 	ddbwritel(dev, reg | (dns->fe->nr << 8) | (dns->fe->port->lnr << 16), | ||||
| 		  STREAM_CONTROL(dns->nr)); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int ns_stop(struct dvbnss *nss) | ||||
| { | ||||
| 	struct ddb_ns *dns = (struct ddb_ns *) nss->priv; | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	struct ddb_input *input = ns->priv; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
|  | ||||
| 	ddbwritel(dev, 0x00, STREAM_CONTROL(dns->nr)); | ||||
| 	ddb_dvb_ns_input_stop(input); | ||||
| 	if (dns->fe != input) | ||||
| 		ddb_dvb_ns_input_stop(dns->fe); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int netstream_init(struct ddb_input *input) | ||||
| { | ||||
| 	struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; | ||||
| 	struct dvb_adapter *adap = dvb->adap; | ||||
| 	struct dvb_netstream *ns = &dvb->dvbns; | ||||
| 	struct ddb *dev = input->port->dev; | ||||
| 	int i, res; | ||||
|  | ||||
| 	ddbmemset(dev, STREAM_PIDS(input->nr), 0x00, 0x400); | ||||
| 	for (i = 0; i < dev->ns_num; i++) | ||||
| 		dev->ns[i].nr = i; | ||||
| 	ns->priv = input; | ||||
| 	ns->set_net = ns_set_net; | ||||
| 	ns->set_rtcp_msg = ns_set_rtcp_msg; | ||||
| 	ns->set_ts_packets = ns_set_ts_packets; | ||||
| 	ns->insert_ts_packets = ns_insert_ts_packets; | ||||
| 	ns->set_pid = ns_set_pid; | ||||
| 	ns->set_pids = ns_set_pids; | ||||
| 	ns->set_ci = ns_set_ci; | ||||
| 	ns->start = ns_start; | ||||
| 	ns->stop = ns_stop; | ||||
| 	ns->alloc = ns_alloc; | ||||
| 	ns->free = ns_free; | ||||
| 	res = dvb_netstream_init(adap, ns); | ||||
| 	return res; | ||||
| } | ||||
							
								
								
									
										435
									
								
								ddbridge/ddbridge-regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										435
									
								
								ddbridge/ddbridge-regs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,435 @@ | ||||
| /* | ||||
|  * ddbridge-regs.h: Digital Devices PCIe bridge driver | ||||
|  * | ||||
|  * Copyright (C) 2010-2015 Digital Devices GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| /* Register Definitions */ | ||||
|  | ||||
| #define CUR_REGISTERMAP_VERSION     0x10003 | ||||
| #define CUR_REGISTERMAP_VERSION_CI  0x10000 | ||||
| #define CUR_REGISTERMAP_VERSION_MOD 0x10000 | ||||
|  | ||||
| #define HARDWARE_VERSION       0x00 | ||||
| #define REGISTERMAP_VERSION    0x04 | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| /* SPI Controller */ | ||||
|  | ||||
| #define SPI_CONTROL     0x10 | ||||
| #define SPI_DATA        0x14 | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| /* GPIO */ | ||||
|  | ||||
| #define GPIO_OUTPUT      0x20 | ||||
| #define GPIO_INPUT       0x24 | ||||
| #define GPIO_DIRECTION   0x28 | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| /* MDIO */ | ||||
|  | ||||
| #define MDIO_CTRL        0x20 | ||||
| #define MDIO_ADR         0x24 | ||||
| #define MDIO_REG         0x28 | ||||
| #define MDIO_VAL         0x2C | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
|  | ||||
| #define BOARD_CONTROL    0x30 | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
|  | ||||
| /* Interrupt controller | ||||
|    How many MSI's are available depends on HW (Min 2 max 8) | ||||
|    How many are usable also depends on Host platform | ||||
| */ | ||||
|  | ||||
| #define INTERRUPT_BASE   (0x40) | ||||
|  | ||||
| #define INTERRUPT_ENABLE (INTERRUPT_BASE + 0x00) | ||||
| #define MSI0_ENABLE      (INTERRUPT_BASE + 0x00) | ||||
| #define MSI1_ENABLE      (INTERRUPT_BASE + 0x04) | ||||
| #define MSI2_ENABLE      (INTERRUPT_BASE + 0x08) | ||||
| #define MSI3_ENABLE      (INTERRUPT_BASE + 0x0C) | ||||
| #define MSI4_ENABLE      (INTERRUPT_BASE + 0x10) | ||||
| #define MSI5_ENABLE      (INTERRUPT_BASE + 0x14) | ||||
| #define MSI6_ENABLE      (INTERRUPT_BASE + 0x18) | ||||
| #define MSI7_ENABLE      (INTERRUPT_BASE + 0x1C) | ||||
|  | ||||
| #define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20) | ||||
| #define INTERRUPT_ACK    (INTERRUPT_BASE + 0x20) | ||||
|  | ||||
| #define INTMASK_CLOCKGEN    (0x00000001) | ||||
| #define INTMASK_TEMPMON     (0x00000002) | ||||
|  | ||||
| #define INTMASK_I2C1        (0x00000001) | ||||
| #define INTMASK_I2C2        (0x00000002) | ||||
| #define INTMASK_I2C3        (0x00000004) | ||||
| #define INTMASK_I2C4        (0x00000008) | ||||
|  | ||||
| #define INTMASK_CIRQ1       (0x00000010) | ||||
| #define INTMASK_CIRQ2       (0x00000020) | ||||
| #define INTMASK_CIRQ3       (0x00000040) | ||||
| #define INTMASK_CIRQ4       (0x00000080) | ||||
|  | ||||
| #define INTMASK_TSINPUT1    (0x00000100) | ||||
| #define INTMASK_TSINPUT2    (0x00000200) | ||||
| #define INTMASK_TSINPUT3    (0x00000400) | ||||
| #define INTMASK_TSINPUT4    (0x00000800) | ||||
| #define INTMASK_TSINPUT5    (0x00001000) | ||||
| #define INTMASK_TSINPUT6    (0x00002000) | ||||
| #define INTMASK_TSINPUT7    (0x00004000) | ||||
| #define INTMASK_TSINPUT8    (0x00008000) | ||||
|  | ||||
| #define INTMASK_TSOUTPUT1   (0x00010000) | ||||
| #define INTMASK_TSOUTPUT2   (0x00020000) | ||||
| #define INTMASK_TSOUTPUT3   (0x00040000) | ||||
| #define INTMASK_TSOUTPUT4   (0x00080000) | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Modulator registers */ | ||||
|  | ||||
| /*  Clock Generator ( Sil598 @ 0xAA I2c ) */ | ||||
| #define CLOCKGEN_BASE       (0x80) | ||||
| #define CLOCKGEN_CONTROL    (CLOCKGEN_BASE + 0x00) | ||||
| #define CLOCKGEN_INDEX      (CLOCKGEN_BASE + 0x04) | ||||
| #define CLOCKGEN_WRITEDATA  (CLOCKGEN_BASE + 0x08) | ||||
| #define CLOCKGEN_READDATA   (CLOCKGEN_BASE + 0x0C) | ||||
|  | ||||
| /* DAC ( AD9781/AD9783 SPI ) */ | ||||
| #define DAC_BASE            (0x090) | ||||
| #define DAC_CONTROL         (DAC_BASE) | ||||
| #define DAC_WRITE_DATA      (DAC_BASE+4) | ||||
| #define DAC_READ_DATA       (DAC_BASE+8) | ||||
|  | ||||
| #define DAC_CONTROL_INSTRUCTION_REG (0xFF) | ||||
| #define DAC_CONTROL_STARTIO         (0x100) | ||||
| #define DAC_CONTROL_RESET           (0x200) | ||||
|  | ||||
| /* Temperature Monitor ( 2x LM75A @ 0x90,0x92 I2c ) */ | ||||
| #define TEMPMON_BASE        (0xA0) | ||||
| #define TEMPMON_CONTROL    (TEMPMON_BASE + 0x00) | ||||
| /* SHORT Temperature in <20>C x 256 */ | ||||
| #define TEMPMON_CORE       (TEMPMON_BASE + 0x04) | ||||
| #define TEMPMON_SENSOR1    (TEMPMON_BASE + 0x08) | ||||
| #define TEMPMON_SENSOR2    (TEMPMON_BASE + 0x0C) | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| /* I2C Master Controller */ | ||||
|  | ||||
| #define I2C_BASE        (0x80)  /* Byte offset */ | ||||
|  | ||||
| #define I2C_COMMAND     (0x00) | ||||
| #define I2C_TIMING      (0x04) | ||||
| #define I2C_TASKLENGTH  (0x08)     /* High read, low write */ | ||||
| #define I2C_TASKADDRESS (0x0C)     /* High read, low write */ | ||||
| #define I2C_MONITOR     (0x1C) | ||||
|  | ||||
|  | ||||
| #define I2C_SPEED_666   (0x02010202) | ||||
| #define I2C_SPEED_400   (0x04030404) | ||||
| #define I2C_SPEED_200   (0x09080909) | ||||
| #define I2C_SPEED_154   (0x0C0B0C0C) | ||||
| #define I2C_SPEED_100   (0x13121313) | ||||
| #define I2C_SPEED_77    (0x19181919) | ||||
| #define I2C_SPEED_50    (0x27262727) | ||||
|  | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| /* DMA  Controller */ | ||||
|  | ||||
| #define DMA_BASE_WRITE        (0x100) | ||||
| #define DMA_BASE_READ         (0x140) | ||||
|  | ||||
| #define DMA_CONTROL     (0x00) | ||||
| #define DMA_ERROR       (0x04) | ||||
|  | ||||
| #define DMA_DIAG_CONTROL                (0x1C) | ||||
| #define DMA_DIAG_PACKETCOUNTER_LOW      (0x20) | ||||
| #define DMA_DIAG_PACKETCOUNTER_HIGH     (0x24) | ||||
| #define DMA_DIAG_TIMECOUNTER_LOW        (0x28) | ||||
| #define DMA_DIAG_TIMECOUNTER_HIGH       (0x2C) | ||||
| #define DMA_DIAG_RECHECKCOUNTER         (0x30) | ||||
| #define DMA_DIAG_WAITTIMEOUTINIT        (0x34) | ||||
| #define DMA_DIAG_WAITOVERFLOWCOUNTER    (0x38) | ||||
| #define DMA_DIAG_WAITCOUNTER            (0x3C) | ||||
|  | ||||
| #define TS_INPUT_BASE       (0x200) | ||||
| #define TS_INPUT_CONTROL(i)         (TS_INPUT_BASE + (i) * 0x10 + 0x00) | ||||
| #define TS_INPUT_CONTROL2(i)        (TS_INPUT_BASE + (i) * 0x10 + 0x04) | ||||
|  | ||||
| #define TS_OUTPUT_BASE       (0x280) | ||||
| #define TS_OUTPUT_CONTROL(i)        (TS_OUTPUT_BASE + (i) * 0x10 + 0x00) | ||||
| #define TS_OUTPUT_CONTROL2(i)       (TS_OUTPUT_BASE + (i) * 0x10 + 0x04) | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| /* DMA  Buffer */ | ||||
|  | ||||
| #define DMA_BUFFER_BASE     (0x300) | ||||
|  | ||||
| #define DMA_BUFFER_CONTROL(i)       (DMA_BUFFER_BASE + (i) * 0x10 + 0x00) | ||||
| #define DMA_BUFFER_ACK(i)           (DMA_BUFFER_BASE + (i) * 0x10 + 0x04) | ||||
| #define DMA_BUFFER_CURRENT(i)       (DMA_BUFFER_BASE + (i) * 0x10 + 0x08) | ||||
| #define DMA_BUFFER_SIZE(i)          (DMA_BUFFER_BASE + (i) * 0x10 + 0x0c) | ||||
|  | ||||
| #define DMA_BASE_ADDRESS_TABLE  (0x2000) | ||||
| #define DMA_BASE_ADDRESS_TABLE_ENTRIES (512) | ||||
|  | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
|  | ||||
| #define LNB_BASE                     (0x400) | ||||
| #define LNB_CONTROL(i)               (LNB_BASE + (i) * 0x20 + 0x00) | ||||
| #define LNB_CMD   (7ULL <<  0) | ||||
| #define LNB_CMD_NOP    0 | ||||
| #define LNB_CMD_INIT   1 | ||||
| #define LNB_CMD_STATUS 2 | ||||
| #define LNB_CMD_LOW    3 | ||||
| #define LNB_CMD_HIGH   4 | ||||
| #define LNB_CMD_OFF    5 | ||||
| #define LNB_CMD_DISEQC 6 | ||||
| #define LNB_CMD_UNI    7 | ||||
|  | ||||
| #define LNB_BUSY  (1ULL <<  4) | ||||
| #define LNB_TONE  (1ULL << 15) | ||||
|  | ||||
| #define LNB_STATUS(i)                (LNB_BASE + (i) * 0x20 + 0x04) | ||||
| #define LNB_VOLTAGE(i)               (LNB_BASE + (i) * 0x20 + 0x08) | ||||
| #define LNB_CONFIG(i)                (LNB_BASE + (i) * 0x20 + 0x0c) | ||||
| #define LNB_BUF_LEVEL(i)             (LNB_BASE + (i) * 0x20 + 0x10) | ||||
| #define LNB_BUF_WRITE(i)             (LNB_BASE + (i) * 0x20 + 0x14) | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| /* CI Interface (only CI-Bridge) */ | ||||
|  | ||||
| #define CI_BASE                     (0x400) | ||||
| #define CI_CONTROL(i)               (CI_BASE + (i) * 32 + 0x00) | ||||
|  | ||||
| #define CI_DO_ATTRIBUTE_RW(i)       (CI_BASE + (i) * 32 + 0x04) | ||||
| #define CI_DO_IO_RW(i)              (CI_BASE + (i) * 32 + 0x08) | ||||
| #define CI_READDATA(i)              (CI_BASE + (i) * 32 + 0x0c) | ||||
| #define CI_DO_READ_ATTRIBUTES(i)    (CI_BASE + (i) * 32 + 0x10) | ||||
|  | ||||
| #define CI_RESET_CAM                    (0x00000001) | ||||
| #define CI_POWER_ON                     (0x00000002) | ||||
| #define CI_ENABLE                       (0x00000004) | ||||
| #define CI_BLOCKIO_ENABLE               (0x00000008) | ||||
| #define CI_BYPASS_DISABLE               (0x00000010) | ||||
| #define CI_DISABLE_AUTO_OFF             (0x00000020) | ||||
|  | ||||
| #define CI_CAM_READY                    (0x00010000) | ||||
| #define CI_CAM_DETECT                   (0x00020000) | ||||
| #define CI_READY                        (0x80000000) | ||||
| #define CI_BLOCKIO_ACTIVE               (0x40000000) | ||||
| #define CI_BLOCKIO_RCVDATA              (0x20000000) | ||||
| #define CI_BLOCKIO_SEND_PENDING         (0x10000000) | ||||
| #define CI_BLOCKIO_SEND_COMPLETE        (0x08000000) | ||||
|  | ||||
| #define CI_READ_CMD                     (0x40000000) | ||||
| #define CI_WRITE_CMD                    (0x80000000) | ||||
|  | ||||
| #define CI_BLOCKIO_SEND(i)              (CI_BASE + (i) * 32 + 0x14) | ||||
| #define CI_BLOCKIO_RECEIVE(i)           (CI_BASE + (i) * 32 + 0x18) | ||||
|  | ||||
| #define CI_BLOCKIO_SEND_COMMAND         (0x80000000) | ||||
| #define CI_BLOCKIO_SEND_COMPLETE_ACK    (0x40000000) | ||||
| #define CI_BLOCKIO_RCVDATA_ACK          (0x40000000) | ||||
|  | ||||
| #define CI_BUFFER_BASE                  (0x3000) | ||||
| #define CI_BUFFER_SIZE                  (0x0800) | ||||
| #define CI_BLOCKIO_BUFFER_SIZE          (CI_BUFFER_SIZE/2) | ||||
|  | ||||
| #define CI_BUFFER(i)                  (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE) | ||||
| #define CI_BLOCKIO_RECEIVE_BUFFER(i)  (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE) | ||||
| #define CI_BLOCKIO_SEND_BUFFER(i)  \ | ||||
| 	(CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE + CI_BLOCKIO_BUFFER_SIZE) | ||||
|  | ||||
| #define VCO1_BASE           (0xC0) | ||||
| #define VCO1_CONTROL        (VCO1_BASE + 0x00) | ||||
| #define VCO1_DATA           (VCO1_BASE + 0x04)  /* 24 Bit */ | ||||
| /* 1 = Trigger write, resets when done */ | ||||
| #define VCO1_CONTROL_WRITE  (0x00000001) | ||||
| /* 0 = Put VCO into power down */ | ||||
| #define VCO1_CONTROL_CE     (0x00000002) | ||||
| /* Muxout from VCO (usually = Lock) */ | ||||
| #define VCO1_CONTROL_MUXOUT (0x00000004) | ||||
|  | ||||
| #define VCO2_BASE           (0xC8) | ||||
| #define VCO2_CONTROL        (VCO2_BASE + 0x00) | ||||
| #define VCO2_DATA           (VCO2_BASE + 0x04)  /* 24 Bit */ | ||||
| /* 1 = Trigger write, resets when done */ | ||||
| #define VCO2_CONTROL_WRITE  (0x00000001) | ||||
| /* 0 = Put VCO into power down */ | ||||
| #define VCO2_CONTROL_CE     (0x00000002) | ||||
| /* Muxout from VCO (usually = Lock) */ | ||||
| #define VCO2_CONTROL_MUXOUT (0x00000004) | ||||
|  | ||||
| #define VCO3_BASE           (0xD0) | ||||
| #define VCO3_CONTROL        (VCO3_BASE + 0x00) | ||||
| #define VCO3_DATA           (VCO3_BASE + 0x04)  /* 32 Bit */ | ||||
| /* 1 = Trigger write, resets when done */ | ||||
| #define VCO3_CONTROL_WRITE  (0x00000001) | ||||
| /* 0 = Put VCO into power down */ | ||||
| #define VCO3_CONTROL_CE     (0x00000002) | ||||
| /* Muxout from VCO (usually = Lock) */ | ||||
| #define VCO3_CONTROL_MUXOUT (0x00000004) | ||||
|  | ||||
| #define RF_ATTENUATOR   (0xD8) | ||||
| /*  0x00 =  0 dB | ||||
|     0x01 =  1 dB | ||||
|       ... | ||||
|     0x1F = 31 dB | ||||
| */ | ||||
|  | ||||
| #define RF_POWER        (0xE0) | ||||
| #define RF_POWER_BASE       (0xE0) | ||||
| #define RF_POWER_CONTROL    (RF_POWER_BASE + 0x00) | ||||
| #define RF_POWER_DATA       (RF_POWER_BASE + 0x04) | ||||
|  | ||||
| #define RF_POWER_CONTROL_START     (0x00000001) | ||||
| #define RF_POWER_CONTROL_DONE      (0x00000002) | ||||
| #define RF_POWER_CONTROL_VALIDMASK (0x00000700) | ||||
| #define RF_POWER_CONTROL_VALID     (0x00000500) | ||||
|  | ||||
|  | ||||
| /* -------------------------------------------------------------------------- | ||||
|    Output control | ||||
| */ | ||||
|  | ||||
| #define IQOUTPUT_BASE           (0x240) | ||||
| #define IQOUTPUT_CONTROL        (IQOUTPUT_BASE + 0x00) | ||||
| #define IQOUTPUT_CONTROL2       (IQOUTPUT_BASE + 0x04) | ||||
| #define IQOUTPUT_PEAK_DETECTOR  (IQOUTPUT_BASE + 0x08) | ||||
| #define IQOUTPUT_POSTSCALER     (IQOUTPUT_BASE + 0x0C) | ||||
| #define IQOUTPUT_PRESCALER      (IQOUTPUT_BASE + 0x10) | ||||
|  | ||||
| #define IQOUTPUT_EQUALIZER_0    (IQOUTPUT_BASE + 0x14) | ||||
| #define IQOUTPUT_EQUALIZER_1    (IQOUTPUT_BASE + 0x18) | ||||
| #define IQOUTPUT_EQUALIZER_2    (IQOUTPUT_BASE + 0x1C) | ||||
| #define IQOUTPUT_EQUALIZER_3    (IQOUTPUT_BASE + 0x20) | ||||
| #define IQOUTPUT_EQUALIZER_4    (IQOUTPUT_BASE + 0x24) | ||||
| #define IQOUTPUT_EQUALIZER_5    (IQOUTPUT_BASE + 0x28) | ||||
| #define IQOUTPUT_EQUALIZER_6    (IQOUTPUT_BASE + 0x2C) | ||||
| #define IQOUTPUT_EQUALIZER_7    (IQOUTPUT_BASE + 0x30) | ||||
| #define IQOUTPUT_EQUALIZER_8    (IQOUTPUT_BASE + 0x34) | ||||
| #define IQOUTPUT_EQUALIZER_9    (IQOUTPUT_BASE + 0x38) | ||||
| #define IQOUTPUT_EQUALIZER_10   (IQOUTPUT_BASE + 0x3C) | ||||
|  | ||||
| #define IQOUTPUT_EQUALIZER(i)   (IQOUTPUT_EQUALIZER_0 + (i) * 4) | ||||
|  | ||||
| #define IQOUTPUT_CONTROL_RESET              (0x00000001) | ||||
| #define IQOUTPUT_CONTROL_ENABLE             (0x00000002) | ||||
| #define IQOUTPUT_CONTROL_RESET_PEAK         (0x00000004) | ||||
| #define IQOUTPUT_CONTROL_ENABLE_PEAK        (0x00000008) | ||||
| #define IQOUTPUT_CONTROL_BYPASS_EQUALIZER   (0x00000010) | ||||
|  | ||||
|  | ||||
| /* Modulator Base */ | ||||
|  | ||||
| #define MODULATOR_BASE          (0x200) | ||||
| #define MODULATOR_CONTROL         (MODULATOR_BASE) | ||||
| #define MODULATOR_IQTABLE_END     (MODULATOR_BASE+4) | ||||
| #define MODULATOR_IQTABLE_INDEX   (MODULATOR_BASE+8) | ||||
| #define MODULATOR_IQTABLE_DATA    (MODULATOR_BASE+12) | ||||
|  | ||||
| #define MODULATOR_IQTABLE_INDEX_CHANNEL_MASK  (0x000F0000) | ||||
| #define MODULATOR_IQTABLE_INDEX_IQ_MASK       (0x00008000) | ||||
| #define MODULATOR_IQTABLE_INDEX_ADDRESS_MASK  (0x000007FF) | ||||
| #define MODULATOR_IQTABLE_INDEX_SEL_I         (0x00000000) | ||||
| #define MODULATOR_IQTABLE_INDEX_SEL_Q     (MODULATOR_IQTABLE_INDEX_IQ_MASK) | ||||
| #define MODULATOR_IQTABLE_SIZE    (2048) | ||||
|  | ||||
|  | ||||
| /* Modulator Channels */ | ||||
|  | ||||
| #define CHANNEL_BASE                (0x400) | ||||
| #define CHANNEL_CONTROL(i)          (CHANNEL_BASE + (i) * 64 + 0x00) | ||||
| #define CHANNEL_SETTINGS(i)         (CHANNEL_BASE + (i) * 64 + 0x04) | ||||
| #define CHANNEL_RATE_INCR(i)        (CHANNEL_BASE + (i) * 64 + 0x0C) | ||||
| #define CHANNEL_PCR_ADJUST_OUTL(i)  (CHANNEL_BASE + (i) * 64 + 0x10) | ||||
| #define CHANNEL_PCR_ADJUST_OUTH(i)  (CHANNEL_BASE + (i) * 64 + 0x14) | ||||
| #define CHANNEL_PCR_ADJUST_INL(i)   (CHANNEL_BASE + (i) * 64 + 0x18) | ||||
| #define CHANNEL_PCR_ADJUST_INH(i)   (CHANNEL_BASE + (i) * 64 + 0x1C) | ||||
| #define CHANNEL_PCR_ADJUST_ACCUL(i) (CHANNEL_BASE + (i) * 64 + 0x20) | ||||
| #define CHANNEL_PCR_ADJUST_ACCUH(i) (CHANNEL_BASE + (i) * 64 + 0x24) | ||||
| #define CHANNEL_PKT_COUNT_OUT(i)    (CHANNEL_BASE + (i) * 64 + 0x28) | ||||
| #define CHANNEL_PKT_COUNT_IN(i)     (CHANNEL_BASE + (i) * 64 + 0x2C) | ||||
|  | ||||
| #define CHANNEL_CONTROL_RESET               (0x00000001) | ||||
| #define CHANNEL_CONTROL_ENABLE_DVB          (0x00000002) | ||||
| #define CHANNEL_CONTROL_ENABLE_IQ           (0x00000004) | ||||
| #define CHANNEL_CONTROL_ENABLE_SOURCE       (0x00000008) | ||||
| #define CHANNEL_CONTROL_ENABLE_PCRADJUST    (0x00000010) | ||||
| #define CHANNEL_CONTROL_FREEZE_STATUS       (0x00000100) | ||||
|  | ||||
| #define CHANNEL_CONTROL_RESET_ERROR         (0x00010000) | ||||
| #define CHANNEL_CONTROL_BUSY                (0x01000000) | ||||
| #define CHANNEL_CONTROL_ERROR_SYNC          (0x20000000) | ||||
| #define CHANNEL_CONTROL_ERROR_UNDERRUN      (0x40000000) | ||||
| #define CHANNEL_CONTROL_ERROR_FATAL         (0x80000000) | ||||
|  | ||||
| #define CHANNEL_SETTINGS_QAM_MASK           (0x00000007) | ||||
| #define CHANNEL_SETTINGS_QAM16              (0x00000000) | ||||
| #define CHANNEL_SETTINGS_QAM32              (0x00000001) | ||||
| #define CHANNEL_SETTINGS_QAM64              (0x00000002) | ||||
| #define CHANNEL_SETTINGS_QAM128             (0x00000003) | ||||
| #define CHANNEL_SETTINGS_QAM256             (0x00000004) | ||||
|  | ||||
|  | ||||
| /* OCTONET */ | ||||
|  | ||||
| #define ETHER_BASE       (0x100) | ||||
| #define ETHER_CONTROL    (ETHER_BASE + 0x00) | ||||
| #define ETHER_LENGTH     (ETHER_BASE + 0x04) | ||||
|  | ||||
| #define RTP_MASTER_BASE      (0x120) | ||||
| #define RTP_MASTER_CONTROL          (RTP_MASTER_BASE + 0x00) | ||||
| #define RTP_RTCP_INTERRUPT          (RTP_MASTER_BASE + 0x04) | ||||
| #define RTP_MASTER_RTCP_SETTINGS    (RTP_MASTER_BASE + 0x0c) | ||||
|  | ||||
| #define STREAM_BASE       (0x400) | ||||
| #define STREAM_CONTROL(i)        (STREAM_BASE + (i) * 0x20 + 0x00) | ||||
| #define STREAM_RTP_PACKET(i)        (STREAM_BASE + (i) * 0x20 + 0x04) | ||||
| #define STREAM_RTCP_PACKET(i)       (STREAM_BASE + (i) * 0x20 + 0x08) | ||||
| #define STREAM_RTP_SETTINGS(i)      (STREAM_BASE + (i) * 0x20 + 0x0c) | ||||
| #define STREAM_INSERT_PACKET(i)     (STREAM_BASE + (i) * 0x20 + 0x10) | ||||
|  | ||||
| #define STREAM_PACKET_OFF(i) ((i) * 0x200) | ||||
| #define STREAM_PACKET_ADR(i) (0x2000 + (STREAM_PACKET_OFF(i))) | ||||
|  | ||||
| #define STREAM_PIDS(i) (0x4000 + (i) * 0x400) | ||||
|  | ||||
| #define TS_CAPTURE_BASE (0x0140) | ||||
| #define TS_CAPTURE_CONTROL       (TS_CAPTURE_BASE + 0x00) | ||||
| #define TS_CAPTURE_PID           (TS_CAPTURE_BASE + 0x04) | ||||
| #define TS_CAPTURE_RECEIVED      (TS_CAPTURE_BASE + 0x08) | ||||
| #define TS_CAPTURE_TIMEOUT       (TS_CAPTURE_BASE + 0x0c) | ||||
| #define TS_CAPTURE_TABLESECTION  (TS_CAPTURE_BASE + 0x10) | ||||
|  | ||||
| #define TS_CAPTURE_MEMORY (0x7000) | ||||
|  | ||||
| #define PID_FILTER_BASE       (0x800) | ||||
| #define PID_FILTER_SYSTEM_PIDS(i)     (PID_FILTER_BASE + (i) * 0x20) | ||||
| #define PID_FILTER_PID(i, j)     (PID_FILTER_BASE + (i) * 0x20 + (j) * 4) | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										533
									
								
								ddbridge/ddbridge.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										533
									
								
								ddbridge/ddbridge.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,533 @@ | ||||
| /* | ||||
|  * ddbridge.c: Digital Devices PCIe bridge driver | ||||
|  * | ||||
|  * Copyright (C) 2010-2015 Digital Devices GmbH   | ||||
|  *                         Ralph Metzler <rjkm@metzlerbros.de> | ||||
|  *                         Marcus Metzler <mocm@metzlerbros.de> | ||||
|  *                          | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| /*#define DDB_ALT_DMA*/ | ||||
| #define DDB_USE_WORK | ||||
| /*#define DDB_TEST_THREADED*/ | ||||
|  | ||||
| #include "ddbridge.h" | ||||
| #include "ddbridge-regs.h" | ||||
|  | ||||
| static struct workqueue_struct *ddb_wq; | ||||
|  | ||||
| static int adapter_alloc; | ||||
| module_param(adapter_alloc, int, 0444); | ||||
| MODULE_PARM_DESC(adapter_alloc, | ||||
| 		 "0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); | ||||
|  | ||||
| #ifdef CONFIG_PCI_MSI | ||||
| static int msi = 1; | ||||
| module_param(msi, int, 0444); | ||||
| MODULE_PARM_DESC(msi, | ||||
| 		 " Control MSI interrupts: 0-disable, 1-enable (default)"); | ||||
| #endif | ||||
|  | ||||
| #include "ddbridge-core.c" | ||||
|  | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| static void ddb_unmap(struct ddb *dev) | ||||
| { | ||||
| 	if (dev->regs) | ||||
| 		iounmap(dev->regs); | ||||
| 	vfree(dev); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void __devexit ddb_remove(struct pci_dev *pdev) | ||||
| { | ||||
| 	struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev); | ||||
|  | ||||
| 	ddb_nsd_detach(dev); | ||||
| 	ddb_ports_detach(dev); | ||||
| 	ddb_i2c_release(dev); | ||||
|  | ||||
| 	if (dev->link[0].info->ns_num) | ||||
| 		ddbwritel(dev, 0, ETHER_CONTROL); | ||||
| 	ddbwritel(dev, 0, INTERRUPT_ENABLE); | ||||
| 	ddbwritel(dev, 0, MSI1_ENABLE); | ||||
| 	if (dev->msi == 2) | ||||
| 		free_irq(dev->pdev->irq + 1, dev); | ||||
| 	free_irq(dev->pdev->irq, dev); | ||||
| #ifdef CONFIG_PCI_MSI | ||||
| 	if (dev->msi) | ||||
| 		pci_disable_msi(dev->pdev); | ||||
| #endif | ||||
| 	ddb_ports_release(dev); | ||||
| 	ddb_buffers_free(dev); | ||||
| 	ddb_device_destroy(dev); | ||||
|  | ||||
| 	ddb_unmap(dev); | ||||
| 	pci_set_drvdata(pdev, 0); | ||||
| 	pci_disable_device(pdev); | ||||
| } | ||||
|  | ||||
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) | ||||
| #define __devinit | ||||
| #define __devinitdata | ||||
| #endif | ||||
|  | ||||
| static int __devinit ddb_probe(struct pci_dev *pdev, | ||||
| 			       const struct pci_device_id *id) | ||||
| { | ||||
| 	struct ddb *dev; | ||||
| 	int stat = 0; | ||||
| 	int irq_flag = IRQF_SHARED; | ||||
|  | ||||
| 	if (pci_enable_device(pdev) < 0) | ||||
| 		return -ENODEV; | ||||
|  | ||||
| 	dev = vzalloc(sizeof(struct ddb)); | ||||
| 	if (dev == NULL) | ||||
| 		return -ENOMEM; | ||||
|  | ||||
| 	mutex_init(&dev->mutex); | ||||
| 	dev->has_dma = 1; | ||||
| 	dev->pdev = pdev; | ||||
| 	dev->dev = &pdev->dev; | ||||
| 	pci_set_drvdata(pdev, dev); | ||||
|  | ||||
| 	dev->ids.vendor = id->vendor; | ||||
| 	dev->ids.device = id->device; | ||||
| 	dev->ids.subvendor = id->subvendor; | ||||
| 	dev->ids.subdevice = id->subdevice; | ||||
|  | ||||
| 	dev->link[0].dev = dev; | ||||
| 	dev->link[0].info = (struct ddb_info *) id->driver_data; | ||||
| 	pr_info("DDBridge driver detected: %s\n", dev->link[0].info->name); | ||||
|  | ||||
| 	dev->regs_len = pci_resource_len(dev->pdev, 0); | ||||
| 	dev->regs = ioremap(pci_resource_start(dev->pdev, 0), | ||||
| 			    pci_resource_len(dev->pdev, 0)); | ||||
|  | ||||
| 	if (!dev->regs) { | ||||
| 		pr_err("DDBridge: not enough memory for register map\n"); | ||||
| 		stat = -ENOMEM; | ||||
| 		goto fail; | ||||
| 	} | ||||
| 	if (ddbreadl(dev, 0) == 0xffffffff) { | ||||
| 		pr_err("DDBridge: cannot read registers\n"); | ||||
| 		stat = -ENODEV; | ||||
| 		goto fail; | ||||
| 	} | ||||
|  | ||||
| 	dev->ids.hwid = ddbreadl(dev, 0); | ||||
| 	dev->ids.regmapid = ddbreadl(dev, 4); | ||||
|  | ||||
| 	pr_info("DDBridge: HW %08x REGMAP %08x\n", | ||||
| 		dev->ids.hwid, dev->ids.regmapid); | ||||
|  | ||||
| 	if (dev->link[0].info->ns_num) { | ||||
| 		int i; | ||||
|  | ||||
| 		ddbwritel(dev, 0, ETHER_CONTROL); | ||||
| 		for (i = 0; i < 16; i++) | ||||
| 			ddbwritel(dev, 0x00, TS_OUTPUT_CONTROL(i)); | ||||
| 		usleep_range(5000, 6000); | ||||
| 	} | ||||
| 	ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE); | ||||
| 	ddbwritel(dev, 0x00000000, MSI1_ENABLE); | ||||
| 	ddbwritel(dev, 0x00000000, MSI2_ENABLE); | ||||
| 	ddbwritel(dev, 0x00000000, MSI3_ENABLE); | ||||
| 	ddbwritel(dev, 0x00000000, MSI4_ENABLE); | ||||
| 	ddbwritel(dev, 0x00000000, MSI5_ENABLE); | ||||
| 	ddbwritel(dev, 0x00000000, MSI6_ENABLE); | ||||
| 	ddbwritel(dev, 0x00000000, MSI7_ENABLE); | ||||
|  | ||||
| #ifdef CONFIG_PCI_MSI | ||||
| 	if (msi && pci_msi_enabled()) { | ||||
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) | ||||
| 		stat = pci_enable_msi_range(dev->pdev, 1, 2); | ||||
| 		if (stat >= 1) { | ||||
| 			dev->msi = stat; | ||||
| 			pr_info("DDBridge: using %d MSI interrupt(s)\n", dev->msi); | ||||
| 			irq_flag = 0; | ||||
| 		} else | ||||
| 			pr_info("DDBridge: MSI not available.\n"); | ||||
|  | ||||
| #else | ||||
| 		stat = pci_enable_msi_block(dev->pdev, 2); | ||||
| 		if (stat == 0) { | ||||
| 			dev->msi = 1; | ||||
| 			pr_info("DDBridge: using 2 MSI interrupts\n"); | ||||
| 		} | ||||
| 		if (stat == 1) | ||||
| 			stat = pci_enable_msi(dev->pdev); | ||||
| 		if (stat < 0) { | ||||
| 			pr_info("DDBridge: MSI not available.\n"); | ||||
| 		} else { | ||||
| 			irq_flag = 0; | ||||
| 			dev->msi++; | ||||
| 		} | ||||
| #endif | ||||
| 	} | ||||
| 	if (dev->msi == 2) { | ||||
| 		stat = request_irq(dev->pdev->irq, irq_handler0, | ||||
| 				   irq_flag, "ddbridge", (void *) dev); | ||||
| 		if (stat < 0) | ||||
| 			goto fail0; | ||||
| 		stat = request_irq(dev->pdev->irq + 1, irq_handler1, | ||||
| 				   irq_flag, "ddbridge", (void *) dev); | ||||
| 		if (stat < 0) { | ||||
| 			free_irq(dev->pdev->irq, dev); | ||||
| 			goto fail0; | ||||
| 		} | ||||
| 	} else | ||||
| #endif | ||||
| 	{ | ||||
| #ifdef DDB_TEST_THREADED | ||||
| 		stat = request_threaded_irq(dev->pdev->irq, irq_handler, | ||||
| 					    irq_thread, | ||||
| 					    irq_flag, | ||||
| 					    "ddbridge", (void *) dev); | ||||
| #else | ||||
| 		stat = request_irq(dev->pdev->irq, irq_handler, | ||||
| 				   irq_flag, "ddbridge", (void *) dev); | ||||
| #endif | ||||
| 		if (stat < 0) | ||||
| 			goto fail0; | ||||
| 	} | ||||
| 	ddbwritel(dev, 0, DMA_BASE_READ); | ||||
| 	if (dev->link[0].info->type != DDB_MOD) | ||||
| 		ddbwritel(dev, 0, DMA_BASE_WRITE); | ||||
| 	 | ||||
| 	if (dev->link[0].info->type == DDB_MOD) { | ||||
| 		if  (ddbreadl(dev, 0x1c) == 4) | ||||
| 			dev->link[0].info->port_num = 4; | ||||
| 	} | ||||
|  | ||||
| 	/*ddbwritel(dev, 0xffffffff, INTERRUPT_ACK);*/ | ||||
| 	if (dev->msi == 2) { | ||||
| 		ddbwritel(dev, 0x0fffff00, INTERRUPT_ENABLE); | ||||
| 		ddbwritel(dev, 0x0000000f, MSI1_ENABLE); | ||||
| 	} else { | ||||
| 		ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE); | ||||
| 		ddbwritel(dev, 0x00000000, MSI1_ENABLE); | ||||
| 	} | ||||
| 	if (ddb_init(dev) == 0) | ||||
| 		return 0; | ||||
| 	 | ||||
| 	ddbwritel(dev, 0, INTERRUPT_ENABLE); | ||||
| 	ddbwritel(dev, 0, MSI1_ENABLE); | ||||
| 	free_irq(dev->pdev->irq, dev); | ||||
| 	if (dev->msi == 2) | ||||
| 		free_irq(dev->pdev->irq + 1, dev); | ||||
| fail0: | ||||
| 	pr_err("fail0\n"); | ||||
| 	if (dev->msi) | ||||
| 		pci_disable_msi(dev->pdev); | ||||
| fail: | ||||
| 	pr_err("fail\n"); | ||||
|  | ||||
| 	ddb_unmap(dev); | ||||
| 	pci_set_drvdata(pdev, 0); | ||||
| 	pci_disable_device(pdev); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| static struct ddb_regset octopus_i2c = { | ||||
| 	.base = 0x80, | ||||
| 	.num  = 0x04, | ||||
| 	.size = 0x20, | ||||
| }; | ||||
|  | ||||
| static struct ddb_regset octopus_i2c_buf = { | ||||
| 	.base = 0x1000, | ||||
| 	.num  = 0x04, | ||||
| 	.size = 0x200, | ||||
| }; | ||||
|  | ||||
| /****************************************************************************/ | ||||
|  | ||||
|  | ||||
| static struct ddb_regmap octopus_map = { | ||||
| 	.i2c = &octopus_i2c, | ||||
| 	.i2c_buf = &octopus_i2c_buf, | ||||
| }; | ||||
|  | ||||
| static struct ddb_regmap octopus_net_map = { | ||||
| 	.i2c = &octopus_i2c, | ||||
| 	.i2c_buf = &octopus_i2c_buf, | ||||
| }; | ||||
|  | ||||
| static struct ddb_regmap octopus_mod_map = { | ||||
| }; | ||||
|  | ||||
|  | ||||
| /****************************************************************************/ | ||||
|  | ||||
| static struct ddb_info ddb_none = { | ||||
| 	.type     = DDB_NONE, | ||||
| 	.name     = "unknown Digital Devices PCIe card, install newer driver", | ||||
| 	.regmap   = &octopus_map, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octopus = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Digital Devices Octopus DVB adapter", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x0f, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octopusv3 = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Digital Devices Octopus V3 DVB adapter", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x0f, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octopus_le = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Digital Devices Octopus LE DVB adapter", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 2, | ||||
| 	.i2c_mask = 0x03, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octopus_oem = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Digital Devices Octopus OEM", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x0f, | ||||
| 	.led_num  = 1, | ||||
| 	.fan_num  = 1, | ||||
| 	.temp_num = 1, | ||||
| 	.temp_bus = 0, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octopus_mini = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Digital Devices Octopus Mini", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x0f, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_v6 = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Digital Devices Cine S2 V6 DVB adapter", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 3, | ||||
| 	.i2c_mask = 0x07, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_v6_5 = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Digital Devices Cine S2 V6.5 DVB adapter", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x0f, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_v7 = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Digital Devices Cine S2 V7 DVB adapter", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x0f, | ||||
| 	.board_control = 2, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_ctv7 = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Digital Devices Cine CT V7 DVB adapter", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x0f, | ||||
| 	.board_control = 3, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_satixS2v3 = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Mystique SaTiX-S2 V3 DVB adapter", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 3, | ||||
| 	.i2c_mask = 0x07, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_ci = { | ||||
| 	.type     = DDB_OCTOPUS_CI, | ||||
| 	.name     = "Digital Devices Octopus CI", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x03, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_cis = { | ||||
| 	.type     = DDB_OCTOPUS_CI, | ||||
| 	.name     = "Digital Devices Octopus CI single", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 3, | ||||
| 	.i2c_mask = 0x01, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_ci_s2_pro = { | ||||
| 	.type     = DDB_OCTOPUS_CI, | ||||
| 	.name     = "Digital Devices Octopus CI S2 Pro", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x01, | ||||
| 	.board_control = 3, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_dvbct = { | ||||
| 	.type     = DDB_OCTOPUS, | ||||
| 	.name     = "Digital Devices DVBCT V6.1 DVB adapter", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 3, | ||||
| 	.i2c_mask = 0x07, | ||||
| }; | ||||
|  | ||||
| /****************************************************************************/ | ||||
|  | ||||
| static struct ddb_info ddb_s2_48 = { | ||||
| 	.type     = DDB_OCTOPUS_MAX, | ||||
| 	.name     = "Digital Devices MAX S8 4/8", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x01, | ||||
| 	.board_control = 1, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_mod = { | ||||
| 	.type     = DDB_MOD, | ||||
| 	.name     = "Digital Devices DVB-C modulator", | ||||
| 	.regmap   = &octopus_mod_map, | ||||
| 	.port_num = 10, | ||||
| 	.temp_num = 1, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octopus_net = { | ||||
| 	.type     = DDB_OCTONET, | ||||
| 	.name     = "Digital Devices OctopusNet network DVB adapter", | ||||
| 	.regmap   = &octopus_net_map, | ||||
| 	.port_num = 10, | ||||
| 	.i2c_mask = 0x3ff, | ||||
| 	.ns_num   = 12, | ||||
| 	.mdio_num = 1, | ||||
| }; | ||||
|  | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| #define DDVID 0xdd01 /* Digital Devices Vendor ID */ | ||||
|  | ||||
| #define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ | ||||
| 	.vendor      = _vend,    .device    = _dev, \ | ||||
| 	.subvendor   = _subvend, .subdevice = _subdev, \ | ||||
| 	.driver_data = (unsigned long)&_driverdata } | ||||
|  | ||||
| static const struct pci_device_id ddb_id_tbl[] __devinitconst = { | ||||
| 	DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), | ||||
| 	DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), | ||||
| 	DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3), | ||||
| 	DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), | ||||
| 	DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem), | ||||
| 	DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini), | ||||
| 	DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini), | ||||
| 	DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), | ||||
| 	DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), | ||||
| 	DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7), | ||||
| 	DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), | ||||
| 	DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), | ||||
| 	DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7), | ||||
| 	DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7), | ||||
| 	DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7), | ||||
| 	DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48), | ||||
| 	DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci), | ||||
| 	DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis), | ||||
| 	DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci), | ||||
| 	DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro), | ||||
| 	DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod), | ||||
| 	DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod), | ||||
| 	DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_octopus_net), | ||||
| 	/* in case sub-ids got deleted in flash */ | ||||
| 	DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	DDB_ID(DDVID, 0x0005, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	{0} | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(pci, ddb_id_tbl); | ||||
|  | ||||
| static struct pci_driver ddb_pci_driver = { | ||||
| 	.name        = "ddbridge", | ||||
| 	.id_table    = ddb_id_tbl, | ||||
| 	.probe       = ddb_probe, | ||||
| 	.remove      = ddb_remove, | ||||
| }; | ||||
|  | ||||
| static __init int module_init_ddbridge(void) | ||||
| { | ||||
| 	int stat = -1; | ||||
|  | ||||
| 	pr_info("Digital Devices PCIE bridge driver " | ||||
| 		DDBRIDGE_VERSION | ||||
| 		", Copyright (C) 2010-15 Digital Devices GmbH\n"); | ||||
| 	if (ddb_class_create() < 0) | ||||
| 		return -1; | ||||
| 	ddb_wq = create_workqueue("ddbridge"); | ||||
| 	if (ddb_wq == NULL) | ||||
| 		goto exit1; | ||||
| 	stat = pci_register_driver(&ddb_pci_driver); | ||||
| 	if (stat < 0) | ||||
| 		goto exit2; | ||||
| 	return stat; | ||||
| exit2: | ||||
| 	destroy_workqueue(ddb_wq); | ||||
| exit1: | ||||
| 	ddb_class_destroy(); | ||||
| 	return stat; | ||||
| } | ||||
|  | ||||
| static __exit void module_exit_ddbridge(void) | ||||
| { | ||||
| 	pci_unregister_driver(&ddb_pci_driver); | ||||
| 	destroy_workqueue(ddb_wq); | ||||
| 	ddb_class_destroy(); | ||||
| } | ||||
|  | ||||
| module_init(module_init_ddbridge); | ||||
| module_exit(module_exit_ddbridge); | ||||
|  | ||||
| MODULE_DESCRIPTION("Digital Devices PCIe Bridge"); | ||||
| MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR"); | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_VERSION(DDBRIDGE_VERSION); | ||||
							
								
								
									
										711
									
								
								ddbridge/ddbridge.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										711
									
								
								ddbridge/ddbridge.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,711 @@ | ||||
| /* | ||||
|  * ddbridge.h: Digital Devices PCIe bridge driver | ||||
|  * | ||||
|  * Copyright (C) 2010-2015 Digital Devices GmbH | ||||
|  *                         Ralph Metzler <rmetzler@digitaldevices.de> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| #ifndef _DDBRIDGE_H_ | ||||
| #define _DDBRIDGE_H_ | ||||
|  | ||||
| #include <linux/version.h> | ||||
|  | ||||
| #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0)) | ||||
| #define __devexit | ||||
| #define __devinit | ||||
| #define __devinitconst | ||||
| #endif | ||||
|  | ||||
| #include <linux/module.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/poll.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/pci.h> | ||||
| //#include <linux/pci_ids.h> | ||||
| #include <linux/timer.h> | ||||
| #include <linux/i2c.h> | ||||
| #include <linux/swab.h> | ||||
| #include <linux/vmalloc.h> | ||||
| #include <linux/workqueue.h> | ||||
| #include <linux/kthread.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/clk.h> | ||||
| #include <linux/spi/spi.h> | ||||
| #include <linux/gpio.h> | ||||
| #include <linux/completion.h> | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/sched.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/mutex.h> | ||||
| #include <asm/dma.h> | ||||
| #include <asm/irq.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/uaccess.h> | ||||
|  | ||||
| #include <linux/dvb/ca.h> | ||||
| #include <linux/socket.h> | ||||
| #include <linux/device.h> | ||||
| #include <linux/io.h> | ||||
|  | ||||
| #include "dvb_netstream.h" | ||||
| #include "dmxdev.h" | ||||
| #include "dvbdev.h" | ||||
| #include "dvb_demux.h" | ||||
| #include "dvb_frontend.h" | ||||
| #include "dvb_ringbuffer.h" | ||||
| #include "dvb_ca_en50221.h" | ||||
| #include "dvb_net.h" | ||||
|  | ||||
| #include "tda18271c2dd.h" | ||||
| #include "stv6110x.h" | ||||
| #include "stv090x.h" | ||||
| #include "lnbh24.h" | ||||
| #include "drxk.h" | ||||
| #include "stv0367dd.h" | ||||
| #include "tda18212dd.h" | ||||
| #include "cxd2843.h" | ||||
| #include "cxd2099.h" | ||||
| #include "stv0910.h" | ||||
| #include "stv6111.h" | ||||
| #include "lnbh25.h" | ||||
| #include "mxl5xx.h" | ||||
|  | ||||
| #define DDB_MAX_I2C    16 | ||||
| #define DDB_MAX_PORT   16 | ||||
| #define DDB_MAX_INPUT  44 | ||||
| #define DDB_MAX_OUTPUT 10 | ||||
| #define DDB_MAX_LINK    4 | ||||
| #define DDB_LINK_SHIFT 28 | ||||
|  | ||||
| #define DDB_LINK_TAG(_x) (_x << DDB_LINK_SHIFT) | ||||
|  | ||||
| struct ddb_regset { | ||||
| 	u32 base; | ||||
| 	u32 num; | ||||
| 	u32 size; | ||||
| }; | ||||
|  | ||||
| struct ddb_ports { | ||||
| 	u32 base; | ||||
| 	u32 num; | ||||
| 	u32 size; | ||||
| }; | ||||
|  | ||||
| struct ddb_regmap { | ||||
| 	struct ddb_ports  *bc; | ||||
| 	struct ddb_regset *i2c; | ||||
| 	struct ddb_regset *i2c_buf; | ||||
| 	struct ddb_regset *dma; | ||||
| 	struct ddb_regset *dma_buf; | ||||
| 	struct ddb_regset *input; | ||||
| 	struct ddb_regset *output; | ||||
| 	struct ddb_regset *channel; | ||||
| 	struct ddb_regset *ci; | ||||
| 	struct ddb_regset *pid_filter; | ||||
| 	struct ddb_regset *ns; | ||||
| 	struct ddb_regset *gtl; | ||||
| }; | ||||
|  | ||||
| struct ddb_ids { | ||||
| 	u16 vendor; | ||||
| 	u16 device; | ||||
| 	u16 subvendor; | ||||
| 	u16 subdevice; | ||||
| 	 | ||||
| 	u32 hwid; | ||||
| 	u32 regmapid; | ||||
| 	u32 devid; | ||||
| 	u32 mac; | ||||
| }; | ||||
|  | ||||
| struct ddb_info { | ||||
| 	int   type; | ||||
| #define DDB_NONE         0 | ||||
| #define DDB_OCTOPUS      1 | ||||
| #define DDB_OCTOPUS_CI   2 | ||||
| #define DDB_MOD          3 | ||||
| #define DDB_OCTONET      4 | ||||
| #define DDB_OCTOPUS_MAX  5 | ||||
| 	char *name; | ||||
| 	u32   i2c_mask; | ||||
| 	u8    port_num; | ||||
| 	u8    led_num; | ||||
| 	u8    fan_num; | ||||
| 	u8    temp_num; | ||||
| 	u8    temp_bus; | ||||
| 	u8    board_control; | ||||
| 	u8    ns_num; | ||||
| 	u8    mdio_num; | ||||
| 	u8    con_clock; | ||||
| 	struct ddb_regmap *regmap; | ||||
| }; | ||||
|  | ||||
| /* DMA_SIZE MUST be smaller than 256k and | ||||
|    MUST be divisible by 188 and 128 !!! */ | ||||
|  | ||||
| #define DMA_MAX_BUFS 32      /* hardware table limit */ | ||||
|  | ||||
| #define INPUT_DMA_BUFS 8 | ||||
| #define INPUT_DMA_SIZE (128*47*21) | ||||
| #define INPUT_DMA_IRQ_DIV 1 | ||||
|  | ||||
| #define OUTPUT_DMA_BUFS 8 | ||||
| #define OUTPUT_DMA_SIZE (128*47*21) | ||||
| #define OUTPUT_DMA_IRQ_DIV 1 | ||||
|  | ||||
| struct ddb; | ||||
| struct ddb_port; | ||||
|  | ||||
| struct ddb_dma { | ||||
| 	void                  *io; | ||||
| 	u32                    nr; | ||||
| 	dma_addr_t             pbuf[DMA_MAX_BUFS]; | ||||
| 	u8                    *vbuf[DMA_MAX_BUFS]; | ||||
| 	u32                    num; | ||||
| 	u32                    size; | ||||
| 	u32                    div; | ||||
| 	u32                    bufreg; | ||||
| 	 | ||||
| #ifdef DDB_USE_WORK | ||||
| 	struct work_struct     work; | ||||
| #else | ||||
| 	struct tasklet_struct  tasklet; | ||||
| #endif | ||||
| 	spinlock_t             lock; | ||||
| 	wait_queue_head_t      wq; | ||||
| 	int                    running; | ||||
| 	u32                    stat; | ||||
| 	u32                    ctrl; | ||||
| 	u32                    cbuf; | ||||
| 	u32                    coff; | ||||
| }; | ||||
| 	 | ||||
| struct ddb_dvb { | ||||
| 	struct dvb_adapter    *adap; | ||||
| 	int                    adap_registered; | ||||
| 	struct dvb_device     *dev; | ||||
| 	struct dvb_frontend   *fe; | ||||
| 	struct dvb_frontend   *fe2; | ||||
| 	struct dmxdev          dmxdev; | ||||
| 	struct dvb_demux       demux; | ||||
| 	struct dvb_net         dvbnet; | ||||
| 	struct dvb_netstream   dvbns; | ||||
| 	struct dmx_frontend    hw_frontend; | ||||
| 	struct dmx_frontend    mem_frontend; | ||||
| 	int                    users; | ||||
| 	u32                    attached; | ||||
| 	u8                     input; | ||||
| 	 | ||||
| 	fe_sec_tone_mode_t     tone; | ||||
| 	fe_sec_voltage_t       voltage; | ||||
| 	 | ||||
| 	int (*i2c_gate_ctrl)(struct dvb_frontend *, int); | ||||
| 	int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage); | ||||
| 	int (*set_input)(struct dvb_frontend *fe, int input); | ||||
| 	int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd); | ||||
| }; | ||||
|  | ||||
| struct ddb_ci { | ||||
| 	struct dvb_ca_en50221  en; | ||||
| 	struct ddb_port       *port; | ||||
| 	u32                    nr; | ||||
| 	struct mutex           lock; | ||||
| }; | ||||
|  | ||||
| struct ddb_io { | ||||
| 	struct ddb_port       *port; | ||||
| 	u32                    nr; | ||||
| 	struct ddb_dma        *dma; | ||||
| 	struct ddb_io         *redo; | ||||
| 	struct ddb_io         *redi; | ||||
| }; | ||||
|  | ||||
| #define ddb_output ddb_io | ||||
| #define ddb_input ddb_io | ||||
|  | ||||
| struct ddb_i2c { | ||||
| 	struct ddb            *dev; | ||||
| 	u32                    nr; | ||||
| 	u32                    regs; | ||||
| 	u32                    link; | ||||
| 	struct i2c_adapter     adap; | ||||
| 	u32                    rbuf; | ||||
| 	u32                    wbuf; | ||||
| 	u32                    bsize; | ||||
| 	struct completion      completion; | ||||
| }; | ||||
|  | ||||
| struct ddb_port { | ||||
| 	struct ddb            *dev; | ||||
| 	u32                    nr; | ||||
| 	u32                    pnr; | ||||
| 	u32                    regs; | ||||
| 	u32                    lnr; | ||||
| 	struct ddb_i2c        *i2c; | ||||
| 	struct mutex           i2c_gate_lock; | ||||
| 	u32                    class; | ||||
| #define DDB_PORT_NONE           0 | ||||
| #define DDB_PORT_CI             1 | ||||
| #define DDB_PORT_TUNER          2 | ||||
| #define DDB_PORT_LOOP           3 | ||||
| #define DDB_PORT_MOD            4 | ||||
| 	char                   *name; | ||||
| 	u32                     type; | ||||
| #define DDB_TUNER_NONE           0 | ||||
| #define DDB_TUNER_DVBS_ST        1 | ||||
| #define DDB_TUNER_DVBS_ST_AA     2 | ||||
| #define DDB_TUNER_DVBCT_TR       3 | ||||
| #define DDB_TUNER_DVBCT_ST       4 | ||||
| #define DDB_CI_INTERNAL          5 | ||||
| #define DDB_CI_EXTERNAL_SONY     6 | ||||
| #define DDB_TUNER_DVBCT2_SONY_P  7 | ||||
| #define DDB_TUNER_DVBC2T2_SONY_P 8 | ||||
| #define DDB_TUNER_ISDBT_SONY_P   9 | ||||
| #define DDB_TUNER_DVBS_STV0910_P 10 | ||||
| #define DDB_TUNER_MXL5XX         11 | ||||
| #define DDB_CI_EXTERNAL_XO2      12 | ||||
| #define DDB_CI_EXTERNAL_XO2_B    13 | ||||
|  | ||||
| #define DDB_TUNER_XO2            16 | ||||
| #define DDB_TUNER_DVBS_STV0910   16 | ||||
| #define DDB_TUNER_DVBCT2_SONY    17 | ||||
| #define DDB_TUNER_ISDBT_SONY     18 | ||||
| #define DDB_TUNER_DVBC2T2_SONY   19 | ||||
| #define DDB_TUNER_ATSC_ST        20 | ||||
| #define DDB_TUNER_DVBC2T2_ST     21 | ||||
|  | ||||
| 	struct ddb_input      *input[2]; | ||||
| 	struct ddb_output     *output; | ||||
| 	struct dvb_ca_en50221 *en; | ||||
| 	struct ddb_dvb         dvb[2]; | ||||
| 	u32                    gap; | ||||
| 	u32                    obr; | ||||
| 	u8                     creg; | ||||
| }; | ||||
|  | ||||
| struct mod_base { | ||||
| 	u32                    frequency; | ||||
| 	u32                    flat_start; | ||||
| 	u32                    flat_end; | ||||
| }; | ||||
|  | ||||
| struct mod_state { | ||||
| 	u32                    modulation; | ||||
| 	u64                    obitrate; | ||||
| 	u64                    ibitrate; | ||||
| 	u32                    pcr_correction; | ||||
|  | ||||
| 	u32                    rate_inc; | ||||
| 	u32                    Control; | ||||
| 	u32                    State; | ||||
| 	u32                    StateCounter; | ||||
| 	s32                    LastPCRAdjust; | ||||
| 	s32                    PCRAdjustSum; | ||||
| 	s32                    InPacketsSum; | ||||
| 	s32                    OutPacketsSum; | ||||
| 	s64                    PCRIncrement; | ||||
| 	s64                    PCRDecrement; | ||||
| 	s32                    PCRRunningCorr; | ||||
| 	u32                    OutOverflowPacketCount; | ||||
| 	u32                    InOverflowPacketCount; | ||||
| 	u32                    LastOutPacketCount; | ||||
| 	u32                    LastInPacketCount; | ||||
| 	u64                    LastOutPackets; | ||||
| 	u64                    LastInPackets; | ||||
| 	u32                    MinInputPackets; | ||||
| }; | ||||
|  | ||||
| #define CM_STARTUP_DELAY 2 | ||||
| #define CM_AVERAGE  20 | ||||
| #define CM_GAIN     10 | ||||
|  | ||||
| #define HW_LSB_SHIFT    12 | ||||
| #define HW_LSB_MASK     0x1000 | ||||
|  | ||||
| #define CM_IDLE    0 | ||||
| #define CM_STARTUP 1 | ||||
| #define CM_ADJUST  2 | ||||
|  | ||||
| #define TS_CAPTURE_LEN  (4096) | ||||
|  | ||||
| /* net streaming hardware block */ | ||||
|  | ||||
| #define DDB_NS_MAX 15 | ||||
|  | ||||
| struct ddb_ns { | ||||
| 	struct ddb_input      *input; | ||||
| 	int                    nr; | ||||
| 	struct ddb_input      *fe; | ||||
| 	u32                    rtcp_udplen; | ||||
| 	u32                    rtcp_len; | ||||
| 	u32                    ts_offset; | ||||
| 	u32                    udplen; | ||||
| 	u8                     p[512]; | ||||
| }; | ||||
|  | ||||
| struct ddb_lnb { | ||||
| 	struct mutex           lock; | ||||
| 	u32                    tone; | ||||
|         fe_sec_voltage_t       oldvoltage[4]; | ||||
| 	u32                    voltage[4]; | ||||
| 	u32                    voltages; | ||||
| 	u32                    fmode; | ||||
| 	u32                    setmode; | ||||
| }; | ||||
|  | ||||
| struct ddb_link { | ||||
| 	struct ddb            *dev; | ||||
| 	struct ddb_info       *info; | ||||
| 	u32                    nr; | ||||
| 	u32                    regs; | ||||
| 	spinlock_t             lock; | ||||
| 	struct mutex           flash_mutex; | ||||
| 	struct ddb_lnb         lnb; | ||||
| 	struct tasklet_struct  tasklet; | ||||
| }; | ||||
|  | ||||
| struct ddb { | ||||
| 	struct pci_dev        *pdev; | ||||
| 	struct platform_device *pfdev; | ||||
| 	struct device         *dev; | ||||
| 	struct ddb_ids         ids; | ||||
| 	 | ||||
| 	int                    msi; | ||||
| 	struct workqueue_struct *wq; | ||||
| 	u32                    has_dma; | ||||
| 	u32                    has_ns; | ||||
| 	 | ||||
| 	struct ddb_link        link[DDB_MAX_LINK]; | ||||
| 	unsigned char         *regs; | ||||
| 	u32                    regs_len; | ||||
| 	u32                    port_num; | ||||
| 	struct ddb_port        port[DDB_MAX_PORT]; | ||||
| 	u32                    i2c_num; | ||||
| 	struct ddb_i2c         i2c[DDB_MAX_I2C]; | ||||
| 	struct ddb_input       input[DDB_MAX_INPUT]; | ||||
| 	struct ddb_output      output[DDB_MAX_OUTPUT]; | ||||
| 	struct dvb_adapter     adap[DDB_MAX_INPUT]; | ||||
| 	struct ddb_dma         dma[DDB_MAX_INPUT + DDB_MAX_OUTPUT]; | ||||
| 	 | ||||
| 	void                   (*handler[128])(unsigned long); | ||||
| 	unsigned long          handler_data[128]; | ||||
|  | ||||
| 	struct device         *ddb_dev; | ||||
| 	u32                    ddb_dev_users; | ||||
| 	u32                    nr; | ||||
| 	u8                     iobuf[1028]; | ||||
|  | ||||
| 	u8                     leds; | ||||
| 	u32                    ts_irq; | ||||
| 	u32                    i2c_irq; | ||||
|  | ||||
| 	int                    ns_num; | ||||
| 	struct ddb_ns          ns[DDB_NS_MAX]; | ||||
| 	int                    vlan; | ||||
| 	struct mutex           mutex; | ||||
|  | ||||
| 	struct dvb_device     *nsd_dev; | ||||
| 	u8                     tsbuf[TS_CAPTURE_LEN]; | ||||
|  | ||||
| 	struct mod_base        mod_base; | ||||
| 	struct mod_state       mod[10]; | ||||
| }; | ||||
|  | ||||
| static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr) | ||||
| { | ||||
| 	writeb(val, (char *) (dev->regs + (adr))); | ||||
| } | ||||
|  | ||||
| static inline u32 ddbreadb(struct ddb *dev, u32 adr) | ||||
| { | ||||
| 	return readb((char *) (dev->regs + (adr))); | ||||
| } | ||||
|  | ||||
| static inline void ddbwritel0(struct ddb_link *link, u32 val, u32 adr) | ||||
| { | ||||
| 	writel(val, (char *) (link->dev->regs + (adr))); | ||||
| } | ||||
|  | ||||
| static inline u32 ddbreadl0(struct ddb_link *link, u32 adr) | ||||
| { | ||||
| 	return readl((char *) (link->dev->regs + (adr))); | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| static inline void gtlw(struct ddb_link *link) | ||||
| { | ||||
|         u32 count = 0; | ||||
|         static u32 max = 0; | ||||
|  | ||||
|         while (1 & ddbreadl0(link, link->regs + 0x10)) { | ||||
|         if (++count == 1024) { | ||||
|                         printk("LTO\n"); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	if (count > max) { | ||||
| 		max = count; | ||||
| 		printk("TO=%u\n", max);  | ||||
| 	} | ||||
| 	if (ddbreadl0(link, link->regs + 0x10) & 0x8000) | ||||
| 		printk("link error\n"); | ||||
| } | ||||
| #else | ||||
| static inline void gtlw(struct ddb_link *link) | ||||
| { | ||||
|         while (1 & ddbreadl0(link, link->regs + 0x10)); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static u32 ddblreadl(struct ddb_link *link, u32 adr) | ||||
| { | ||||
|         if (unlikely(link->nr)) { | ||||
|                 unsigned long flags; | ||||
|                 u32 val; | ||||
| 		 | ||||
|                 spin_lock_irqsave(&link->lock, flags); | ||||
| 		gtlw(link); | ||||
| 		ddbwritel0(link, adr & 0xfffc, link->regs + 0x14); | ||||
| 		ddbwritel0(link, 3, link->regs + 0x10); | ||||
| 		gtlw(link); | ||||
| 		val = ddbreadl0(link, link->regs + 0x1c); | ||||
| 		spin_unlock_irqrestore(&link->lock, flags); | ||||
| 		return val; | ||||
| 	} | ||||
| 	return readl((char *) (link->dev->regs + (adr))); | ||||
| } | ||||
|  | ||||
| static void ddblwritel(struct ddb_link *link, u32 val, u32 adr) | ||||
| { | ||||
| 	if (unlikely(link->nr)) { | ||||
| 		unsigned long flags; | ||||
| 		 | ||||
|                 spin_lock_irqsave(&link->lock, flags); | ||||
| 		gtlw(link); | ||||
| 		ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14); | ||||
| 		ddbwritel0(link, val, link->regs + 0x18); | ||||
| 		ddbwritel0(link, 1, link->regs + 0x10); | ||||
| 		spin_unlock_irqrestore(&link->lock, flags); | ||||
| 		return; | ||||
| 	} | ||||
| 	writel(val, (char *) (link->dev->regs + (adr))); | ||||
| } | ||||
|  | ||||
| static u32 ddbreadl(struct ddb *dev, u32 adr) | ||||
| { | ||||
|         if (unlikely(adr & 0xf0000000)) { | ||||
|                 unsigned long flags; | ||||
|                 u32 val, l = (adr >> DDB_LINK_SHIFT); | ||||
| 		struct ddb_link *link = &dev->link[l]; | ||||
| 		 | ||||
|                 spin_lock_irqsave(&link->lock, flags); | ||||
| 		gtlw(link); | ||||
| 		ddbwritel0(link, adr & 0xfffc, link->regs + 0x14); | ||||
| 		ddbwritel0(link, 3, link->regs + 0x10); | ||||
| 		gtlw(link); | ||||
| 		val = ddbreadl0(link, link->regs + 0x1c); | ||||
| 		spin_unlock_irqrestore(&link->lock, flags); | ||||
| 		return val; | ||||
| 	} | ||||
| 	return readl((char *) (dev->regs + (adr))); | ||||
| } | ||||
|  | ||||
| static void ddbwritel(struct ddb *dev, u32 val, u32 adr) | ||||
| { | ||||
| 	if (unlikely(adr & 0xf0000000)) { | ||||
| 		unsigned long flags; | ||||
| 		u32 l = (adr >> DDB_LINK_SHIFT); | ||||
| 		struct ddb_link *link = &dev->link[l]; | ||||
| 		 | ||||
|                 spin_lock_irqsave(&link->lock, flags); | ||||
| 		gtlw(link); | ||||
| 		ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14); | ||||
| 		ddbwritel0(link, val, link->regs + 0x18); | ||||
| 		ddbwritel0(link, 1, link->regs + 0x10); | ||||
| 		spin_unlock_irqrestore(&link->lock, flags); | ||||
| 		return; | ||||
| 	} | ||||
| 	writel(val, (char *) (dev->regs + (adr))); | ||||
| } | ||||
|  | ||||
| static void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf, | ||||
| 		     unsigned int count) | ||||
| { | ||||
| 	u32 val = 0, p = adr; | ||||
| 	u32 aa = p & 3; | ||||
|  | ||||
| 	if (aa) { | ||||
| 		while (p & 3 && count) { | ||||
| 			val >>= 8; | ||||
| 			val |= *buf << 24; | ||||
| 			p++; | ||||
| 			buf++; | ||||
| 			count--; | ||||
| 		} | ||||
| 		ddbwritel(dev, val, adr); | ||||
| 	} | ||||
| 	while (count >= 4) { | ||||
| 		val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); | ||||
| 		ddbwritel(dev, val, p); | ||||
| 		p += 4; | ||||
| 		buf += 4; | ||||
| 		count -= 4; | ||||
| 	} | ||||
| 	if (count) { | ||||
| 		val = buf[0]; | ||||
| 		if (count > 1) | ||||
| 			val |= buf[1] << 8; | ||||
| 		if (count > 2) | ||||
| 			val |= buf[2] << 16; | ||||
| 		ddbwritel(dev, val, p); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count) | ||||
| { | ||||
| 	u32 val = 0, p = adr; | ||||
| 	u32 a = p & 3; | ||||
|  | ||||
| 	if (a) { | ||||
| 		val = ddbreadl(dev, p) >> (8 * a); | ||||
| 		while (p & 3 && count) { | ||||
| 			*buf = val & 0xff; | ||||
| 			val >>= 8; | ||||
| 			p++; | ||||
| 			buf++; | ||||
| 			count--; | ||||
| 		} | ||||
| 	} | ||||
| 	while (count >= 4) { | ||||
| 		val = ddbreadl(dev, p); | ||||
| 		buf[0] = val & 0xff; | ||||
| 		buf[1] = (val >> 8) & 0xff; | ||||
| 		buf[2] = (val >> 16) & 0xff; | ||||
| 		buf[3] = (val >> 24) & 0xff; | ||||
| 		p += 4; | ||||
| 		buf += 4; | ||||
| 		count -= 4; | ||||
| 	} | ||||
| 	if (count) { | ||||
| 		val = ddbreadl(dev, p); | ||||
| 		buf[0] = val & 0xff; | ||||
| 		if (count > 1) | ||||
| 			buf[1] = (val >> 8) & 0xff; | ||||
| 		if (count > 2) | ||||
| 			buf[2] = (val >> 16) & 0xff; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count) | ||||
| { | ||||
| 	if (unlikely(adr & 0xf0000000)) | ||||
| 		return gtlcpyto(dev, adr, src, count); | ||||
| 	return memcpy_toio((char *) (dev->regs + adr), src, count); | ||||
| } | ||||
|  | ||||
| static void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) | ||||
| { | ||||
| 	if (unlikely(adr & 0xf0000000)) | ||||
| 		return gtlcpyfrom(dev, dst, adr, count); | ||||
| 	return memcpy_fromio(dst, (char *) (dev->regs + adr), count); | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
|  | ||||
| #define ddbcpyto(_dev, _adr, _src, _count) \ | ||||
| 	memcpy_toio((char *) (_dev->regs + (_adr)), (_src), (_count)) | ||||
|  | ||||
| #define ddbcpyfrom(_dev, _dst, _adr, _count) \ | ||||
| 	memcpy_fromio((_dst), (char *) (_dev->regs + (_adr)), (_count)) | ||||
| #endif | ||||
|  | ||||
| #define ddbmemset(_dev, _adr, _val, _count) \ | ||||
| 	memset_io((char *) (_dev->regs + (_adr)), (_val), (_count)) | ||||
|  | ||||
|  | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| #define dd_uint8    u8 | ||||
| #define dd_uint16   u16 | ||||
| #define dd_int16    s16 | ||||
| #define dd_uint32   u32 | ||||
| #define dd_int32    s32 | ||||
| #define dd_uint64   u64 | ||||
| #define dd_int64    s64 | ||||
|  | ||||
| #define DDMOD_FLASH_START  0x1000 | ||||
|  | ||||
| struct DDMOD_FLASH_DS { | ||||
| 	dd_uint32   Symbolrate;             /* kSymbols/s */ | ||||
| 	dd_uint32   DACFrequency;           /* kHz        */ | ||||
| 	dd_uint16   FrequencyResolution;    /* kHz        */ | ||||
| 	dd_uint16   IQTableLength; | ||||
| 	dd_uint16   FrequencyFactor; | ||||
| 	dd_int16    PhaseCorr;              /* TBD        */ | ||||
| 	dd_uint32   Control2; | ||||
| 	dd_uint16   PostScaleI; | ||||
| 	dd_uint16   PostScaleQ; | ||||
| 	dd_uint16   PreScale; | ||||
| 	dd_int16    EQTap[11]; | ||||
| 	dd_uint16   FlatStart; | ||||
| 	dd_uint16   FlatEnd; | ||||
| 	dd_uint32   FlashOffsetPrecalculatedIQTables;       /* 0 = none */ | ||||
| 	dd_uint8    Reserved[28]; | ||||
|  | ||||
| }; | ||||
|  | ||||
| struct DDMOD_FLASH { | ||||
| 	dd_uint32   Magic; | ||||
| 	dd_uint16   Version; | ||||
| 	dd_uint16   DataSets; | ||||
|  | ||||
| 	dd_uint16   VCORefFrequency;    /* MHz */ | ||||
| 	dd_uint16   VCO1Frequency;      /* MHz */ | ||||
| 	dd_uint16   VCO2Frequency;      /* MHz */ | ||||
|  | ||||
| 	dd_uint16   DACAux1;    /* TBD */ | ||||
| 	dd_uint16   DACAux2;    /* TBD */ | ||||
|  | ||||
| 	dd_uint8    Reserved1[238]; | ||||
|  | ||||
| 	struct DDMOD_FLASH_DS DataSet[1]; | ||||
| }; | ||||
|  | ||||
| #define DDMOD_FLASH_MAGIC   0x5F564d5F | ||||
|  | ||||
|  | ||||
| int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg); | ||||
| int ddbridge_mod_init(struct ddb *dev); | ||||
| void ddbridge_mod_output_stop(struct ddb_output *output); | ||||
| void ddbridge_mod_output_start(struct ddb_output *output); | ||||
| void ddbridge_mod_rate_handler(unsigned long data); | ||||
|  | ||||
|  | ||||
| int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len); | ||||
|  | ||||
| #define DDBRIDGE_VERSION "0.9.19" | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										260
									
								
								ddbridge/octonet.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								ddbridge/octonet.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,260 @@ | ||||
| /* | ||||
|  * octonet.c: Digital Devices network tuner driver | ||||
|  * | ||||
|  * Copyright (C) 2012-15 Digital Devices GmbH | ||||
|  *                       Marcus Metzler <mocm@metzlerbros.de> | ||||
|  *                       Ralph Metzler <rjkm@metzlerbros.de> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| #include "ddbridge.h" | ||||
| #include "ddbridge-regs.h" | ||||
| #include <asm-generic/pci-dma-compat.h> | ||||
|  | ||||
| static int adapter_alloc = 3; | ||||
| module_param(adapter_alloc, int, 0444); | ||||
| MODULE_PARM_DESC(adapter_alloc, | ||||
| "0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all"); | ||||
|  | ||||
| #include "ddbridge-core.c" | ||||
|  | ||||
| static struct ddb_regset octopus_i2c = { | ||||
| 	.base = 0x80, | ||||
| 	.num  = 0x04, | ||||
| 	.size = 0x20, | ||||
| }; | ||||
|  | ||||
| static struct ddb_regset octopus_i2c_buf = { | ||||
| 	.base = 0x1000, | ||||
| 	.num  = 0x04, | ||||
| 	.size = 0x200, | ||||
| }; | ||||
|  | ||||
| static struct ddb_regmap octopus_net_map = { | ||||
| 	.i2c = &octopus_i2c, | ||||
| 	.i2c_buf = &octopus_i2c_buf, | ||||
| }; | ||||
|  | ||||
| static struct ddb_regset octopus_gtl = { | ||||
| 	.base = 0x180, | ||||
| 	.num  = 0x01, | ||||
| 	.size = 0x20, | ||||
| }; | ||||
|  | ||||
| static struct ddb_regmap octopus_net_gtl = { | ||||
| 	.i2c = &octopus_i2c, | ||||
| 	.i2c_buf = &octopus_i2c_buf, | ||||
| 	.gtl = &octopus_gtl, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octonet = { | ||||
| 	.type     = DDB_OCTONET, | ||||
| 	.name     = "Digital Devices OctopusNet network DVB adapter", | ||||
| 	.regmap   = &octopus_net_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x0f, | ||||
| 	.ns_num   = 12, | ||||
| 	.mdio_num = 1, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octonet_jse = { | ||||
| 	.type     = DDB_OCTONET, | ||||
| 	.name     = "Digital Devices OctopusNet network DVB adapter JSE", | ||||
| 	.regmap   = &octopus_net_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x0f, | ||||
| 	.ns_num   = 15, | ||||
| 	.mdio_num = 1, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octonet_gtl = { | ||||
| 	.type     = DDB_OCTONET, | ||||
| 	.name     = "Digital Devices OctopusNet GTL", | ||||
| 	.regmap   = &octopus_net_gtl, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x05, | ||||
| 	.ns_num   = 12, | ||||
| 	.mdio_num = 1, | ||||
| 	.con_clock = 1, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octonet_tbd = { | ||||
| 	.type     = DDB_OCTONET, | ||||
| 	.name     = "Digital Devices OctopusNet", | ||||
| 	.regmap   = &octopus_net_map, | ||||
| }; | ||||
|  | ||||
| static void octonet_unmap(struct ddb *dev) | ||||
| { | ||||
| 	if (dev->regs) | ||||
| 		iounmap(dev->regs); | ||||
| 	vfree(dev); | ||||
| } | ||||
|  | ||||
| static int __exit octonet_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	struct ddb *dev; | ||||
|  | ||||
| 	dev = platform_get_drvdata(pdev); | ||||
|  | ||||
| 	ddb_nsd_detach(dev); | ||||
| 	ddb_ports_detach(dev); | ||||
| 	ddb_i2c_release(dev); | ||||
|  | ||||
| 	ddbwritel(dev, 0, ETHER_CONTROL); | ||||
| 	ddbwritel(dev, 0, INTERRUPT_ENABLE); | ||||
| 	free_irq(platform_get_irq(dev->pfdev, 0), dev); | ||||
|  | ||||
| 	ddb_ports_release(dev); | ||||
| 	ddb_device_destroy(dev); | ||||
| 	octonet_unmap(dev); | ||||
| 	platform_set_drvdata(pdev, 0); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int __init octonet_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct ddb *dev; | ||||
| 	struct resource *regs; | ||||
| 	int irq; | ||||
| 	int i; | ||||
|  | ||||
| 	dev = vzalloc(sizeof(struct ddb)); | ||||
| 	if (!dev) | ||||
| 		return -ENOMEM; | ||||
| 	platform_set_drvdata(pdev, dev); | ||||
| 	dev->dev = &pdev->dev; | ||||
| 	dev->pfdev = pdev; | ||||
|  | ||||
| 	mutex_init(&dev->mutex); | ||||
| 	regs = platform_get_resource(dev->pfdev, IORESOURCE_MEM, 0); | ||||
| 	if (!regs) | ||||
| 		return -ENXIO; | ||||
| 	dev->regs_len = (regs->end - regs->start) + 1; | ||||
| 	dev_info(dev->dev, "regs_start=%08x regs_len=%08x\n", | ||||
| 		 (u32) regs->start, (u32) dev->regs_len); | ||||
| 	dev->regs = ioremap(regs->start, dev->regs_len); | ||||
|  | ||||
| 	if (!dev->regs) { | ||||
| 		dev_err(dev->dev, "ioremap failed\n"); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
|  | ||||
| 	dev->ids.hwid = ddbreadl(dev, 0); | ||||
| 	dev->ids.regmapid = ddbreadl(dev, 4); | ||||
| 	dev->ids.devid = ddbreadl(dev, 8); | ||||
| 	dev->ids.mac = ddbreadl(dev, 12); | ||||
|  | ||||
| 	dev->ids.vendor = dev->ids.devid & 0xffff; | ||||
| 	dev->ids.device = dev->ids.devid >> 16; | ||||
| 	dev->ids.subvendor = dev->ids.devid & 0xffff; | ||||
| 	dev->ids.subdevice = dev->ids.devid >> 16; | ||||
|  | ||||
| 	dev->link[0].dev = dev; | ||||
| 	if (dev->ids.devid == 0x0300dd01) | ||||
| 		dev->link[0].info = &ddb_octonet; | ||||
| 	else if (dev->ids.devid == 0x0301dd01) | ||||
| 		dev->link[0].info = &ddb_octonet_jse; | ||||
| 	else if (dev->ids.devid == 0x0307dd01) | ||||
| 		dev->link[0].info = &ddb_octonet_gtl; | ||||
| 	else | ||||
| 		dev->link[0].info = &ddb_octonet_tbd; | ||||
| 		 | ||||
| 	pr_info("HW  %08x REGMAP %08x\n", dev->ids.hwid, dev->ids.regmapid); | ||||
| 	pr_info("MAC %08x DEVID  %08x\n", dev->ids.mac, dev->ids.devid); | ||||
|  | ||||
| 	ddbwritel(dev, 0, ETHER_CONTROL); | ||||
| 	ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE); | ||||
| 	ddbwritel(dev, 0xffffffff, INTERRUPT_STATUS); | ||||
| 	for (i = 0; i < 16; i++) | ||||
| 		ddbwritel(dev, 0x00, TS_OUTPUT_CONTROL(i)); | ||||
| 	usleep_range(5000, 6000); | ||||
|  | ||||
| 	irq = platform_get_irq(dev->pfdev, 0); | ||||
| 	if (irq < 0) | ||||
| 		goto fail; | ||||
| 	if (request_irq(irq, irq_handler, | ||||
| 			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | ||||
| 			"octonet-dvb", (void *) dev) < 0) | ||||
| 		goto fail; | ||||
| 	ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE); | ||||
|  | ||||
| 	if (ddb_init(dev) == 0) | ||||
| 		return 0; | ||||
|  | ||||
| fail: | ||||
| 	dev_err(dev->dev, "fail\n"); | ||||
| 	ddbwritel(dev, 0, ETHER_CONTROL); | ||||
| 	ddbwritel(dev, 0, INTERRUPT_ENABLE); | ||||
| 	octonet_unmap(dev); | ||||
| 	platform_set_drvdata(pdev, 0); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| #ifdef CONFIG_OF | ||||
| static const struct of_device_id octonet_dt_ids[] = { | ||||
| 	{ .compatible = "digitaldevices,octonet-dvb" }, | ||||
| 	{ /* sentinel */ } | ||||
| }; | ||||
|  | ||||
| MODULE_DEVICE_TABLE(of, octonet_dt_ids); | ||||
| #endif | ||||
|  | ||||
| static struct platform_driver octonet_driver = { | ||||
| 	.remove	= __exit_p(octonet_remove), | ||||
| 	.probe	= octonet_probe, | ||||
| 	.driver		= { | ||||
| 		.name	= "octonet-dvb", | ||||
| 		.owner	= THIS_MODULE, | ||||
| #ifdef CONFIG_OF | ||||
| 		.of_match_table = of_match_ptr(octonet_dt_ids), | ||||
| #endif | ||||
| 	}, | ||||
| }; | ||||
|  | ||||
| static __init int init_octonet(void) | ||||
| { | ||||
| 	int res; | ||||
|  | ||||
| 	pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION | ||||
| 		", Copyright (C) 2010-14 Digital Devices GmbH\n"); | ||||
| 	res = ddb_class_create(); | ||||
| 	if (res) | ||||
| 		return res; | ||||
| 	res = platform_driver_probe(&octonet_driver, octonet_probe); | ||||
| 	if (res) { | ||||
| 		ddb_class_destroy(); | ||||
| 		return res; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static __exit void exit_octonet(void) | ||||
| { | ||||
| 	platform_driver_unregister(&octonet_driver); | ||||
| 	ddb_class_destroy(); | ||||
| } | ||||
|  | ||||
| module_init(init_octonet); | ||||
| module_exit(exit_octonet); | ||||
|  | ||||
| MODULE_DESCRIPTION("GPL"); | ||||
| MODULE_AUTHOR("Marcus and Ralph Metzler, Metzler Brothers Systementwicklung GbR"); | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_VERSION("0.6"); | ||||
							
								
								
									
										5
									
								
								ddip/Kbuild
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								ddip/Kbuild
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| obj-$(CONFIG_DVB_DDBRIDGE) += ddip.o  | ||||
|  | ||||
| EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -Idrivers/media/dvb-frontends | ||||
| EXTRA_CFLAGS += -Idrivers/media/common/tuners  | ||||
| NOSTDINC_FLAGS += -I$(SUBDIRS)/frontends -I$(SUBDIRS)/include -I$(SUBDIRS)/dvb-core  | ||||
							
								
								
									
										18
									
								
								ddip/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								ddip/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| KDIR	?= /lib/modules/$(shell uname -r)/build | ||||
| PWD	:= $(shell pwd) | ||||
|  | ||||
| MODDEFS := CONFIG_DVB_DDIP=m  | ||||
|  | ||||
| all:  | ||||
| 	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MODDEFS) modules | ||||
|  | ||||
| dep: | ||||
| 	DIR=`pwd`; (cd $(TOPDIR); make SUBDIRS=$$DIR dep) | ||||
|  | ||||
| install: all | ||||
| 	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install | ||||
|  | ||||
| clean: | ||||
| 	rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules* | ||||
|  | ||||
|  | ||||
							
								
								
									
										24
									
								
								ddip/ddip.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								ddip/ddip.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| #include <linux/module.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/interrupt.h> | ||||
|  | ||||
|  | ||||
| static __init int init_ddip(void) | ||||
| { | ||||
| 	 | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static __exit void exit_ddip(void) | ||||
| { | ||||
| } | ||||
|  | ||||
| module_init(init_ddip); | ||||
| module_exit(exit_ddip); | ||||
|  | ||||
| MODULE_DESCRIPTION("GPL"); | ||||
| MODULE_AUTHOR("Metzler Brothers Systementwicklung"); | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_VERSION("0.1"); | ||||
|  | ||||
							
								
								
									
										7
									
								
								docs/adapter_alloc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								docs/adapter_alloc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| The module parameter adapter_alloc lets you choose how adapter names are allocated. | ||||
|  | ||||
| 0 = one adapter per io if modules are present | ||||
| 1 = one adapter for each tab on which a module was detected | ||||
| 2 = one per tab even if no modules were detected | ||||
| 3 = one adapter for all devices of one card | ||||
|  | ||||
							
								
								
									
										31
									
								
								docs/ci
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								docs/ci
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| The caX device associated with a CI device behaves just like any other  | ||||
| caX interface. You usually use it through a library like libdvben50221  | ||||
| which is part of the dvb-apps package available at linuxtv.org. | ||||
|  | ||||
| But contrary to other hardware where the CI module is physically placed | ||||
| in the data path between the the demod and PCIe bridge, in the Digital | ||||
| Devices cards the CI module is separate hardware. | ||||
| So, you have to feed data to the CI module by writing to the secX | ||||
| (in later kernel ci0) device and read it back from the same secX device. | ||||
| The advantage is that the CI module can be used with any data coming from | ||||
| any frontend or file. The disadvantage is that the user application has to | ||||
| write/read the data to/from the module by itself.  | ||||
|  | ||||
| The sample application apps/cit.c shows how to pipe a stream through | ||||
| the CI interface. In its ouput it will show discontinuities. Those should  | ||||
| only occur at the start of the program (due to old packets inside the CI  | ||||
| interface hardware and the CI module itself) and when a CI module is | ||||
| inserted or removed. | ||||
|  | ||||
| Since some users have problems using standard software which cannot use  | ||||
| the CI interface in this way, there is now the redirect feature which allows  | ||||
| you to tell the driver to automatically pass the data coming from one  | ||||
| demod through a CI before offering it through the normal demux/dvr interface. | ||||
| But note that this is a kludge to support old software until they can | ||||
| use the new interface. | ||||
| See docs/redirect for more info. | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										29
									
								
								docs/modulator
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								docs/modulator
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
|  | ||||
| Modulator channels will automatically be enabled if you redirect data  | ||||
| from a demodulator to it.  | ||||
| E.g._: | ||||
|  | ||||
| first demod on bridge 0 TAB1, modulator on bridge 1. | ||||
|  | ||||
| echo "00 10" > /sys/class/ddbridge/ddbridge0/redirect | ||||
|  | ||||
| Currently it is fixed to QAM256. Controls will be added later. | ||||
| Rate control is experimental and PCR correction also not | ||||
| implemented yet. So, depending on the reception device | ||||
| there can be disturbances in playback. | ||||
|  | ||||
| It is now also possible to chain redirects. | ||||
| E.g., demod and modulator as above, CI on bridge 0 TAB 2: | ||||
|  | ||||
| echo "00 01" > /sys/class/ddbridge/ddbridge0/redirect | ||||
| echo "02 10" > /sys/class/ddbridge/ddbridge0/redirect | ||||
|  | ||||
| The stream is also still available at the demux device  | ||||
| belonging to the demod devices. | ||||
|  | ||||
| Now write and start an application (not provided) that  | ||||
| talks to the CI to decrypt the desired services. | ||||
| For testing one can use a standard application that | ||||
| supports decryption. Additionally to seeing the | ||||
| decoded service on the PC it will then also be streamed | ||||
| into cable by the modulator. | ||||
							
								
								
									
										89
									
								
								docs/octopusnet
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								docs/octopusnet
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| OctopusNet | ||||
| ---------- | ||||
|  | ||||
| Hardware: | ||||
|  | ||||
| - SoC Atmel SAM9G45 400MHz ARM 926 | ||||
|   64 MB DRAM | ||||
|   256 MB NAND flash | ||||
|  | ||||
| - FPGA Lattice ECP3 17 | ||||
|   data flash | ||||
|  | ||||
| - 5 port switch Marvell 88E6175R | ||||
|  | ||||
|  | ||||
| The FPGA is connected to the memory bus of the G45 and maps control registers into the memory space | ||||
| of the G45. This is mainly to control the data flow on the FPGA. Only minimal data can be transferred | ||||
| (e.g. single sections). Transport streams cannot be transferred to the G45 this way! | ||||
| The FPGA can receive up to 8 TS from up to 4 Duo-Flex cards. You can also can alternatively connect | ||||
| CI modules to port 2 and 3 (TAP 3 and 4). | ||||
|  | ||||
| The FPGA is also connected to one of the ports of the gigabit switch. | ||||
| There are up to 12 channels. Each channel can select one input TS, which is then passed through | ||||
| a PID filter (8192 bit array) and sent to the switch as a UDP/RTP stream. | ||||
|  | ||||
| The G45 is connected to another port of the switch (but only with 100 MBit) | ||||
|  | ||||
|  | ||||
| Booting: | ||||
|  | ||||
| The G45 does not boot from the NAND flash but from the dataflash connected to the FPGA. The G45 | ||||
| does not support error correction for the boot sector and NAND with zero error boot pages | ||||
| is no longer easily available. | ||||
| Newer Atmel SoCs support 4-bit error correction in boot ROM but not the G45. | ||||
|  | ||||
| So, the G45 boot looks like this: | ||||
|  | ||||
| - Run a minimal boot rom mapped by the FPGA. | ||||
| - Boot rom loads a modified bootstrap via SPI (provided via FPGA ports) from the dataflash. | ||||
| - Bootstrap loads u-boot via SPI from dataflash. | ||||
| - u-boot boots Linux ... | ||||
|  | ||||
| If you remove jumper XX, boot rom is disabled and the G45 will boot from NAND flash like this: | ||||
|  | ||||
| - Internal G45 boot rom bootstrap from NAND flash. | ||||
| - Bootstrap boots u-boot from NAND flash | ||||
| - u-boot boots Linux ... | ||||
|  | ||||
| This is just a fall-back since page 0 can contain errors which cannot be corrected by the G45 boot ROM | ||||
| and the bootstrap code which loads u-boot also does not contain error correction. | ||||
|  | ||||
|  | ||||
|  | ||||
| - SPI dataflash | ||||
|  | ||||
| 0x000000 - 0x003fff FPGA config data | ||||
| 0x004000 - 0x005fff G45 bootstrap | ||||
| 0x010000 - 0x0affff FPGA bitstream | ||||
| 0x0b0000 - 0x15ffff G45 u-boot | ||||
| 0x160000 - 0x1fefff FPGA golden image | ||||
| 0x1ff000 - 0x1fffff FPGA jump to golden image | ||||
|  | ||||
|  | ||||
| - NAND flash 256MB, block size 128K (0x20000) | ||||
|  | ||||
| 0x00000000 - 0x0001ffff G45 bootstrap (fallback bootstrap if SPI corrupted, pull jumper to use) | ||||
| 0x00020000 - 0x0007ffff G45 u-boot (fallback u-boot if SPI corrupted) | ||||
| 0x00080000 - 0x0009ffff spare (e.g. for bigger u-boot) | ||||
| 0x000a0000 - 0x000bffff G45 u-boot environment | ||||
| 0x000c0000 - 0x000dffff G45 u-boot redundant environment | ||||
| 0x000e0000 - 0x000fffff spare | ||||
| 0x00100000 - 0x01ffffff G45 Linux recovery | ||||
| 0x02000000 - 0x0fffffff Linux UBI | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										104
									
								
								docs/octopusnet.multicast
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								docs/octopusnet.multicast
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| Multicast | ||||
| --------- | ||||
|  | ||||
| Multicast setup supports 2 file formats. | ||||
| 1) Simple variant for the avarage home user | ||||
| 2) More parameters for the expert. | ||||
|  | ||||
| The file is in csv (comma seperated values) format, which can be created with any plain text editor or imported/exported | ||||
| to/from Microsoft Office Excel or OpenOffice Scalc. With Excel or Scalc care for character set (should be UTF-8) and | ||||
| column formats is required. First line is contain then column headers. | ||||
|  | ||||
| Standard parameters | ||||
| ------------------- | ||||
|  | ||||
| TITLE: Stream Title | ||||
|  | ||||
| REQUEST: SAT>IP tune request string without the pid parameter. Exact format depends on frontend (DVB-S,DVB-T ..) | ||||
| use "-" to stream another program from the previous full entry (tuner sharing) | ||||
|  | ||||
| PIDS: Pid list. Must start with a P, the values separated with a colon. "Pall" streams the whole transponder. | ||||
| (The P is there to ensure Excel or Scalc don't do some fancy format detection, like time conversion) | ||||
|  | ||||
| LANPORTS: Empty or a list with colon separated lan ports starting with L, "Lall" = all ports. | ||||
| If empty, the stream will only be activated when subscribed with an IGMPv3 request. It will also | ||||
| only be active on the lan ports through which an IGMPv3 request for the stream has benn received. | ||||
| (For details how IGMPv3 works look up the relevant RFCs.) | ||||
| If not empty the stream will be preactived on the listed lan ports (and permanently using bandwidth!). | ||||
| It still can be subscribed with IGMPv3 on the other ports. | ||||
|  | ||||
|  | ||||
| TITLE,REQUEST,PIDS,LANPORTS | ||||
| "Das Erste","?freq=346&msys=dvbc&sr=6900&mtype=256qam","P0:100:101:104:102:103:106","" | ||||
| "Bayerisches FS Nord","-","P0:500:201:204:202:203:206","" | ||||
| "hr-fernsehen","-","P0:300:301:304:302:303","" | ||||
| "SWR Fernsehen BW","-","P0:800:801:804:802:803:806","" | ||||
| "WDR Köln","-","P0:600:601:604:602:603","" | ||||
| "ZDF","?freq=370&msys=dvbc&sr=6900&mtype=256qam","P0:100:110:130:120:121:122:125","" | ||||
| "ZDF HD","-","P0:6100:6110:6130:6120:6121:6122:6123","" | ||||
| "zdf neo","-","P0:650:660:680:670:671:672:675","" | ||||
| "zdf kultur","-","P0:1100:1110:1130:1120:1121:1122:1125","" | ||||
| "ZDFInfo","-","P0:600:610:630:620:621:622:625","" | ||||
| "KiKA","-","P0:300:310:330:320:321:325","L3:4:5" | ||||
| "3sat","-","P0:200:210:230:220:221:222:225","" | ||||
|  | ||||
|  | ||||
| Expert parameters: | ||||
| ------------------ | ||||
|  | ||||
| PROTO: Protocol, must be "RTP" or "UDP". If you don't know what this means use "RTP". | ||||
|  | ||||
| IP: Multicast IP address, recommended range 239.5.0.0 - 239.126.255.255, see notes below  | ||||
| about selecting a multicast IP address. | ||||
|  | ||||
| PORT: Destination port. If you don't know what this means set it to 6670 | ||||
|  | ||||
| TTL: Time to live used in the IP headers. If you don't know what this means set it to 5. | ||||
|  | ||||
|  | ||||
| TITLE,REQUEST,PIDS,PROTO,IP,PORT,TTL,LANPORTS | ||||
| "Das Erste","?freq=346&msys=dvbc&sr=6900&mtype=256qam","P0:100:101:104:102:103:106","UDP","239.7.7.100",1234,7,"" | ||||
| "Bayerisches FS Nord","-","P0:500:201:204:202:203:206","UDP","239.7.7.101",1234,7,"" | ||||
| "hr-fernsehen","-","P0:300:301:304:302:303","UDP","239.7.7.102",1234,7,"" | ||||
| "SWR Fernsehen BW","-","P0:800:801:804:802:803:806","UDP","239.7.7.103",1234,7,"" | ||||
| "WDR Köln","-","P0:600:601:604:602:603","UDP","239.7.7.104",1234,7,"" | ||||
| "ZDF","?freq=370&msys=dvbc&sr=6900&mtype=256qam","P0:100:110:130:120:121:122:125","UDP","239.7.8.100",1234,7,"" | ||||
| "ZDF HD","-","P0:6100:6110:6130:6120:6121:6122:6123","UDP","239.7.8.101",1234,7,"" | ||||
| "zdf neo","-","P0:650:660:680:670:671:672:675","UDP","239.7.8.102",1234,7,"" | ||||
| "zdf kultur","-","P0:1100:1110:1130:1120:1121:1122:1125","UDP","239.7.8.103",1234,7,"" | ||||
| "ZDFInfo","-","P0:600:610:630:620:621:622:625","UDP","239.7.8.104",1234,7,"" | ||||
| "KiKA","-","P0:300:310:330:320:321:325","UDP","239.7.8.105",1234,7,"L3:4:5" | ||||
| "3sat","-","P0:200:210:230:220:221:222:225","UDP","239.7.8.106",1234,7,"" | ||||
|  | ||||
|  | ||||
| Selecting a multicast IP address. | ||||
| --------------------------------- | ||||
|  | ||||
| It is obvious that there should be no conflicts with other services (like UPnP, Windows network ...) | ||||
| which also use Multicast for communication and advertisments. | ||||
|  | ||||
| For media streaming usually an IP in the range 239.0.0.0 - 239.255.255.255 is used and | ||||
| will usually only conflict with other media sources. But this is not the whole truth! | ||||
|  | ||||
| The complete IP multicast range is 224.0.0.0 - 255.255.255.254,  that is 536870911 different values. | ||||
| But there are only 8388608 different Ethernet MAC addresses allocated for IPv4 multicast. That | ||||
| means a lot of collisions. For example, 239.0.0.22 uses the same MAC address as 224.0.0.22 (IGMP). | ||||
| This means that 239.0.0.22 can't be blocked in an Ethernet switch without breaking IGMP. | ||||
| An IP from the range 239.5.0.0 - 239.126.255.255 does not collide with most documented | ||||
| services, and should be safe to use in most situations and the benefit from IGMPv3  | ||||
| snooping Ethernet switches. | ||||
|  | ||||
| Multicast and WLAN | ||||
| ------------------ | ||||
|  | ||||
| As there is no real support for it (due to encryption) Multicast over WLAN will not work very well. | ||||
| Therefor it should be avoided to send a out a multicast stream on a lan port there a WLAN router | ||||
| is connected (at least when the WLAN router is configured as LAN-WLAN bridge). | ||||
|  | ||||
| As long there are free streams on the OctopusNet a RTSP player (including WLAN connected players) | ||||
| can request any service from a configured multicast source. | ||||
| For exmaple RTSP://<onetip>/stream=2?pids=0,300,310,330,320,321,325 will request KIKA | ||||
| as single cast stream from the above example. This is possible even if the entry for KIKA | ||||
| is removed from the multicast setup. | ||||
| (the above sample has no free streams left, but it should be clear what is meant) | ||||
|  | ||||
							
								
								
									
										9
									
								
								docs/octopusnetpro
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								docs/octopusnetpro
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| - NAND flash | ||||
|  | ||||
| 0x00000000 - 0x0025ffff U-boot | ||||
| 0x00260000 - 0x0027ffff ENV | ||||
| 0x00300000 - 0x00ffffff Linux image | ||||
|  | ||||
| 0x01000000 - 0x01ffffff Linux recovery | ||||
| 0x02000000 - 0x1fffffff Linux UBI | ||||
|  | ||||
							
								
								
									
										30
									
								
								docs/redirect
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								docs/redirect
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| NOTE: This is an unsupported hack so that legacy software works | ||||
|       with the hardware! | ||||
|       To properly pass data through a CI CAM you should read | ||||
|       the TS from a dvr device and write it to a ci device | ||||
|       in user space! | ||||
|  | ||||
| Redirection of TS streams through CI modules is now supported  | ||||
| through /sys/class/ddbridge/ddbridge0/redirect. | ||||
| It only works with cards based on the ddbridge PCIe bridge, not | ||||
| with nGene based cards. | ||||
|  | ||||
| It is set up in such a way that you can write "AB CD" to | ||||
| a "redirect" attribute and data from input B of card A is then piped through | ||||
| port D (meaning TAB (D+1) which uses output D and input 2*D for CI io) | ||||
| of card C and then shows up in the demux device belonging to | ||||
| input B (input (B&1) of TAB (B/2+1)) of card A. | ||||
|  | ||||
| E.g.: | ||||
|  | ||||
| echo "00 01" > /sys/class/ddbridge/ddbridge0/redirect | ||||
|  | ||||
| will pipe input 0 of card 0 through CI at port 1 (TAB 2) of card 0. | ||||
|  | ||||
| Redirection should only be done right after loading the driver  | ||||
| (or booting if the driver is built-in) and before using the | ||||
| devices in any way. | ||||
|  | ||||
| adapter_alloc=3 is rcommended when using redirect | ||||
| The ci device will then show up in the same adapter directory and most | ||||
| software will then assume it belongs to the frontend in the same directory. | ||||
							
								
								
									
										12
									
								
								dvb-core/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								dvb-core/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| # | ||||
| # Makefile for the kernel DVB device drivers. | ||||
| # | ||||
|  | ||||
| dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o 	\ | ||||
| 		 dvb_ca_en50221.o dvb_frontend.o 		\ | ||||
| 		 dvb_net.o dvb_ringbuffer.o dvb_math.o dvb_netstream.o | ||||
|  | ||||
| obj-$(CONFIG_DVB_CORE) += dvb-core.o | ||||
|  | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_DYNAMIC_MINORS -DCONFIG_DVB_NET | ||||
| NOSTDINC_FLAGS += -I$(SUBDIRS)/include -I$(SUBDIRS)/dvb-core | ||||
							
								
								
									
										241
									
								
								dvb-core/demux.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										241
									
								
								dvb-core/demux.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,241 @@ | ||||
| /* | ||||
|  * demux.h | ||||
|  * | ||||
|  * Copyright (c) 2002 Convergence GmbH | ||||
|  * | ||||
|  * based on code: | ||||
|  * Copyright (c) 2000 Nokia Research Center | ||||
|  *                    Tampere, FINLAND | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef __DEMUX_H | ||||
| #define __DEMUX_H | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/list.h> | ||||
| #include <linux/time.h> | ||||
| #include <linux/dvb/dmx.h> | ||||
|  | ||||
| /*--------------------------------------------------------------------------*/ | ||||
| /* Common definitions */ | ||||
| /*--------------------------------------------------------------------------*/ | ||||
|  | ||||
| /* | ||||
|  * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter. | ||||
|  */ | ||||
|  | ||||
| #ifndef DMX_MAX_FILTER_SIZE | ||||
| #define DMX_MAX_FILTER_SIZE 18 | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter. | ||||
|  */ | ||||
|  | ||||
| #ifndef DMX_MAX_SECTION_SIZE | ||||
| #define DMX_MAX_SECTION_SIZE 4096 | ||||
| #endif | ||||
| #ifndef DMX_MAX_SECFEED_SIZE | ||||
| #define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188) | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * enum dmx_success: Success codes for the Demux Callback API. | ||||
|  */ | ||||
|  | ||||
| enum dmx_success { | ||||
|   DMX_OK = 0, /* Received Ok */ | ||||
|   DMX_LENGTH_ERROR, /* Incorrect length */ | ||||
|   DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */ | ||||
|   DMX_CRC_ERROR, /* Incorrect CRC */ | ||||
|   DMX_FRAME_ERROR, /* Frame alignment error */ | ||||
|   DMX_FIFO_ERROR, /* Receiver FIFO overrun */ | ||||
|   DMX_MISSED_ERROR /* Receiver missed packet */ | ||||
| } ; | ||||
|  | ||||
| /*--------------------------------------------------------------------------*/ | ||||
| /* TS packet reception */ | ||||
| /*--------------------------------------------------------------------------*/ | ||||
|  | ||||
| /* TS filter type for set() */ | ||||
|  | ||||
| #define TS_PACKET       1   /* send TS packets (188 bytes) to callback (default) */ | ||||
| #define	TS_PAYLOAD_ONLY 2   /* in case TS_PACKET is set, only send the TS | ||||
| 			       payload (<=184 bytes per packet) to callback */ | ||||
| #define TS_DECODER      4   /* send stream to built-in decoder (if present) */ | ||||
| #define TS_DEMUX        8   /* in case TS_PACKET is set, send the TS to | ||||
| 			       the demux device, not to the dvr device */ | ||||
|  | ||||
| struct dmx_ts_feed { | ||||
| 	int is_filtering; /* Set to non-zero when filtering in progress */ | ||||
| 	struct dmx_demux *parent; /* Back-pointer */ | ||||
| 	void *priv; /* Pointer to private data of the API client */ | ||||
| 	int (*set) (struct dmx_ts_feed *feed, | ||||
| 		    u16 pid, | ||||
| 		    int type, | ||||
| 		    enum dmx_ts_pes pes_type, | ||||
| 		    size_t circular_buffer_size, | ||||
| 		    struct timespec timeout); | ||||
| 	int (*start_filtering) (struct dmx_ts_feed* feed); | ||||
| 	int (*stop_filtering) (struct dmx_ts_feed* feed); | ||||
| }; | ||||
|  | ||||
| /*--------------------------------------------------------------------------*/ | ||||
| /* Section reception */ | ||||
| /*--------------------------------------------------------------------------*/ | ||||
|  | ||||
| struct dmx_section_filter { | ||||
| 	u8 filter_value [DMX_MAX_FILTER_SIZE]; | ||||
| 	u8 filter_mask [DMX_MAX_FILTER_SIZE]; | ||||
| 	u8 filter_mode [DMX_MAX_FILTER_SIZE]; | ||||
| 	struct dmx_section_feed* parent; /* Back-pointer */ | ||||
| 	void* priv; /* Pointer to private data of the API client */ | ||||
| }; | ||||
|  | ||||
| struct dmx_section_feed { | ||||
| 	int is_filtering; /* Set to non-zero when filtering in progress */ | ||||
| 	struct dmx_demux* parent; /* Back-pointer */ | ||||
| 	void* priv; /* Pointer to private data of the API client */ | ||||
|  | ||||
| 	int check_crc; | ||||
| 	u32 crc_val; | ||||
|  | ||||
| 	u8 *secbuf; | ||||
| 	u8 secbuf_base[DMX_MAX_SECFEED_SIZE]; | ||||
| 	u16 secbufp, seclen, tsfeedp; | ||||
|  | ||||
| 	int (*set) (struct dmx_section_feed* feed, | ||||
| 		    u16 pid, | ||||
| 		    size_t circular_buffer_size, | ||||
| 		    int check_crc); | ||||
| 	int (*allocate_filter) (struct dmx_section_feed* feed, | ||||
| 				struct dmx_section_filter** filter); | ||||
| 	int (*release_filter) (struct dmx_section_feed* feed, | ||||
| 			       struct dmx_section_filter* filter); | ||||
| 	int (*start_filtering) (struct dmx_section_feed* feed); | ||||
| 	int (*stop_filtering) (struct dmx_section_feed* feed); | ||||
| }; | ||||
|  | ||||
| /*--------------------------------------------------------------------------*/ | ||||
| /* Callback functions */ | ||||
| /*--------------------------------------------------------------------------*/ | ||||
|  | ||||
| typedef int (*dmx_ts_cb) ( const u8 * buffer1, | ||||
| 			   size_t buffer1_length, | ||||
| 			   const u8 * buffer2, | ||||
| 			   size_t buffer2_length, | ||||
| 			   struct dmx_ts_feed* source, | ||||
| 			   enum dmx_success success); | ||||
|  | ||||
| typedef int (*dmx_section_cb) (	const u8 * buffer1, | ||||
| 				size_t buffer1_len, | ||||
| 				const u8 * buffer2, | ||||
| 				size_t buffer2_len, | ||||
| 				struct dmx_section_filter * source, | ||||
| 				enum dmx_success success); | ||||
|  | ||||
| /*--------------------------------------------------------------------------*/ | ||||
| /* DVB Front-End */ | ||||
| /*--------------------------------------------------------------------------*/ | ||||
|  | ||||
| enum dmx_frontend_source { | ||||
| 	DMX_MEMORY_FE, | ||||
| 	DMX_FRONTEND_0, | ||||
| 	DMX_FRONTEND_1, | ||||
| 	DMX_FRONTEND_2, | ||||
| 	DMX_FRONTEND_3, | ||||
| 	DMX_STREAM_0,    /* external stream input, e.g. LVDS */ | ||||
| 	DMX_STREAM_1, | ||||
| 	DMX_STREAM_2, | ||||
| 	DMX_STREAM_3 | ||||
| }; | ||||
|  | ||||
| struct dmx_frontend { | ||||
| 	struct list_head connectivity_list; /* List of front-ends that can | ||||
| 					       be connected to a particular | ||||
| 					       demux */ | ||||
| 	enum dmx_frontend_source source; | ||||
| }; | ||||
|  | ||||
| /*--------------------------------------------------------------------------*/ | ||||
| /* MPEG-2 TS Demux */ | ||||
| /*--------------------------------------------------------------------------*/ | ||||
|  | ||||
| /* | ||||
|  * Flags OR'ed in the capabilities field of struct dmx_demux. | ||||
|  */ | ||||
|  | ||||
| #define DMX_TS_FILTERING                        1 | ||||
| #define DMX_PES_FILTERING                       2 | ||||
| #define DMX_SECTION_FILTERING                   4 | ||||
| #define DMX_MEMORY_BASED_FILTERING              8    /* write() available */ | ||||
| #define DMX_CRC_CHECKING                        16 | ||||
| #define DMX_TS_DESCRAMBLING                     32 | ||||
|  | ||||
| /* | ||||
|  * Demux resource type identifier. | ||||
| */ | ||||
|  | ||||
| /* | ||||
|  * DMX_FE_ENTRY(): Casts elements in the list of registered | ||||
|  * front-ends from the generic type struct list_head | ||||
|  * to the type * struct dmx_frontend | ||||
|  *. | ||||
| */ | ||||
|  | ||||
| #define DMX_FE_ENTRY(list) list_entry(list, struct dmx_frontend, connectivity_list) | ||||
|  | ||||
| struct dmx_demux { | ||||
| 	u32 capabilities;            /* Bitfield of capability flags */ | ||||
| 	struct dmx_frontend* frontend;    /* Front-end connected to the demux */ | ||||
| 	void* priv;                  /* Pointer to private data of the API client */ | ||||
| 	int (*open) (struct dmx_demux* demux); | ||||
| 	int (*close) (struct dmx_demux* demux); | ||||
| 	int (*write) (struct dmx_demux* demux, const char __user *buf, size_t count); | ||||
| 	int (*allocate_ts_feed) (struct dmx_demux* demux, | ||||
| 				 struct dmx_ts_feed** feed, | ||||
| 				 dmx_ts_cb callback); | ||||
| 	int (*release_ts_feed) (struct dmx_demux* demux, | ||||
| 				struct dmx_ts_feed* feed); | ||||
| 	int (*allocate_section_feed) (struct dmx_demux* demux, | ||||
| 				      struct dmx_section_feed** feed, | ||||
| 				      dmx_section_cb callback); | ||||
| 	int (*release_section_feed) (struct dmx_demux* demux, | ||||
| 				     struct dmx_section_feed* feed); | ||||
| 	int (*add_frontend) (struct dmx_demux* demux, | ||||
| 			     struct dmx_frontend* frontend); | ||||
| 	int (*remove_frontend) (struct dmx_demux* demux, | ||||
| 				struct dmx_frontend* frontend); | ||||
| 	struct list_head* (*get_frontends) (struct dmx_demux* demux); | ||||
| 	int (*connect_frontend) (struct dmx_demux* demux, | ||||
| 				 struct dmx_frontend* frontend); | ||||
| 	int (*disconnect_frontend) (struct dmx_demux* demux); | ||||
|  | ||||
| 	int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids); | ||||
|  | ||||
| 	int (*get_caps) (struct dmx_demux* demux, struct dmx_caps *caps); | ||||
|  | ||||
| 	int (*set_source) (struct dmx_demux* demux, const dmx_source_t *src); | ||||
|  | ||||
| 	int (*get_stc) (struct dmx_demux* demux, unsigned int num, | ||||
| 			u64 *stc, unsigned int *base); | ||||
| }; | ||||
|  | ||||
| #endif /* #ifndef __DEMUX_H */ | ||||
							
								
								
									
										1272
									
								
								dvb-core/dmxdev.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1272
									
								
								dvb-core/dmxdev.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										119
									
								
								dvb-core/dmxdev.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								dvb-core/dmxdev.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| /* | ||||
|  * dmxdev.h | ||||
|  * | ||||
|  * Copyright (C) 2000 Ralph Metzler & Marcus Metzler | ||||
|  *                    for convergence integrated media GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef _DMXDEV_H_ | ||||
| #define _DMXDEV_H_ | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/spinlock.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/time.h> | ||||
| #include <linux/timer.h> | ||||
| #include <linux/wait.h> | ||||
| #include <linux/fs.h> | ||||
| #include <linux/string.h> | ||||
| #include <linux/mutex.h> | ||||
| #include <linux/slab.h> | ||||
|  | ||||
| #include <linux/dvb/dmx.h> | ||||
|  | ||||
| #include "dvbdev.h" | ||||
| #include "demux.h" | ||||
| #include "dvb_ringbuffer.h" | ||||
|  | ||||
| enum dmxdev_type { | ||||
| 	DMXDEV_TYPE_NONE, | ||||
| 	DMXDEV_TYPE_SEC, | ||||
| 	DMXDEV_TYPE_PES, | ||||
| }; | ||||
|  | ||||
| enum dmxdev_state { | ||||
| 	DMXDEV_STATE_FREE, | ||||
| 	DMXDEV_STATE_ALLOCATED, | ||||
| 	DMXDEV_STATE_SET, | ||||
| 	DMXDEV_STATE_GO, | ||||
| 	DMXDEV_STATE_DONE, | ||||
| 	DMXDEV_STATE_TIMEDOUT | ||||
| }; | ||||
|  | ||||
| struct dmxdev_feed { | ||||
| 	u16 pid; | ||||
| 	struct dmx_ts_feed *ts; | ||||
| 	struct list_head next; | ||||
| }; | ||||
|  | ||||
| struct dmxdev_filter { | ||||
| 	union { | ||||
| 		struct dmx_section_filter *sec; | ||||
| 	} filter; | ||||
|  | ||||
| 	union { | ||||
| 		/* list of TS and PES feeds (struct dmxdev_feed) */ | ||||
| 		struct list_head ts; | ||||
| 		struct dmx_section_feed *sec; | ||||
| 	} feed; | ||||
|  | ||||
| 	union { | ||||
| 		struct dmx_sct_filter_params sec; | ||||
| 		struct dmx_pes_filter_params pes; | ||||
| 	} params; | ||||
|  | ||||
| 	enum dmxdev_type type; | ||||
| 	enum dmxdev_state state; | ||||
| 	struct dmxdev *dev; | ||||
| 	struct dvb_ringbuffer buffer; | ||||
|  | ||||
| 	struct mutex mutex; | ||||
|  | ||||
| 	/* only for sections */ | ||||
| 	struct timer_list timer; | ||||
| 	int todo; | ||||
| 	u8 secheader[3]; | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct dmxdev { | ||||
| 	struct dvb_device *dvbdev; | ||||
| 	struct dvb_device *dvr_dvbdev; | ||||
|  | ||||
| 	struct dmxdev_filter *filter; | ||||
| 	struct dmx_demux *demux; | ||||
|  | ||||
| 	int filternum; | ||||
| 	int capabilities; | ||||
|  | ||||
| 	unsigned int exit:1; | ||||
| #define DMXDEV_CAP_DUPLEX 1 | ||||
| 	struct dmx_frontend *dvr_orig_fe; | ||||
|  | ||||
| 	struct dvb_ringbuffer dvr_buffer; | ||||
| #define DVR_BUFFER_SIZE (10*188*1024) | ||||
|  | ||||
| 	struct mutex mutex; | ||||
| 	spinlock_t lock; | ||||
| }; | ||||
|  | ||||
|  | ||||
| int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *); | ||||
| void dvb_dmxdev_release(struct dmxdev *dmxdev); | ||||
|  | ||||
| #endif /* _DMXDEV_H_ */ | ||||
							
								
								
									
										1814
									
								
								dvb-core/dvb_ca_en50221.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1814
									
								
								dvb-core/dvb_ca_en50221.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										140
									
								
								dvb-core/dvb_ca_en50221.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								dvb-core/dvb_ca_en50221.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| /* | ||||
|  * dvb_ca.h: generic DVB functions for EN50221 CA interfaces | ||||
|  * | ||||
|  * Copyright (C) 2004 Andrew de Quincey | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef _DVB_CA_EN50221_H_ | ||||
| #define _DVB_CA_EN50221_H_ | ||||
|  | ||||
| #include <linux/list.h> | ||||
| #include <linux/dvb/ca.h> | ||||
|  | ||||
| #include "dvbdev.h" | ||||
|  | ||||
| #define DVB_CA_EN50221_POLL_CAM_PRESENT	1 | ||||
| #define DVB_CA_EN50221_POLL_CAM_CHANGED	2 | ||||
| #define DVB_CA_EN50221_POLL_CAM_READY		4 | ||||
|  | ||||
| #define DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE	1 | ||||
| #define DVB_CA_EN50221_FLAG_IRQ_FR		2 | ||||
| #define DVB_CA_EN50221_FLAG_IRQ_DA		4 | ||||
|  | ||||
| #define DVB_CA_EN50221_CAMCHANGE_REMOVED		0 | ||||
| #define DVB_CA_EN50221_CAMCHANGE_INSERTED		1 | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Structure describing a CA interface */ | ||||
| struct dvb_ca_en50221 { | ||||
|  | ||||
| 	/* the module owning this structure */ | ||||
| 	struct module* owner; | ||||
|  | ||||
| 	/* NOTE: the read_*, write_* and poll_slot_status functions will be | ||||
| 	 * called for different slots concurrently and need to use locks where | ||||
| 	 * and if appropriate. There will be no concurrent access to one slot. | ||||
| 	 */ | ||||
|  | ||||
| 	/* functions for accessing attribute memory on the CAM */ | ||||
| 	int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address); | ||||
| 	int (*write_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address, u8 value); | ||||
|  | ||||
| 	/* functions for accessing the control interface on the CAM */ | ||||
| 	int (*read_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address); | ||||
| 	int (*write_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address, u8 value); | ||||
|  | ||||
| 	/* functions for readin/writing data */ | ||||
| 	int (*read_data)(struct dvb_ca_en50221* ca, int slot, u8 *ebuf, int ecount); | ||||
| 	int (*write_data)(struct dvb_ca_en50221* ca, int slot, u8 *ebuf, int ecount); | ||||
|  | ||||
| 	/* Functions for controlling slots */ | ||||
| 	int (*slot_reset)(struct dvb_ca_en50221* ca, int slot); | ||||
| 	int (*slot_shutdown)(struct dvb_ca_en50221* ca, int slot); | ||||
| 	int (*slot_ts_enable)(struct dvb_ca_en50221* ca, int slot); | ||||
|  | ||||
| 	/* | ||||
| 	* Poll slot status. | ||||
| 	* Only necessary if DVB_CA_FLAG_EN50221_IRQ_CAMCHANGE is not set | ||||
| 	*/ | ||||
| 	int (*poll_slot_status)(struct dvb_ca_en50221* ca, int slot, int open); | ||||
|  | ||||
| 	/* private data, used by caller */ | ||||
| 	void* data; | ||||
|  | ||||
| 	/* Opaque data used by the dvb_ca core. Do not modify! */ | ||||
| 	void* private; | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* ******************************************************************************** */ | ||||
| /* Functions for reporting IRQ events */ | ||||
|  | ||||
| /** | ||||
|  * A CAMCHANGE IRQ has occurred. | ||||
|  * | ||||
|  * @param ca CA instance. | ||||
|  * @param slot Slot concerned. | ||||
|  * @param change_type One of the DVB_CA_CAMCHANGE_* values | ||||
|  */ | ||||
| void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int change_type); | ||||
|  | ||||
| /** | ||||
|  * A CAMREADY IRQ has occurred. | ||||
|  * | ||||
|  * @param ca CA instance. | ||||
|  * @param slot Slot concerned. | ||||
|  */ | ||||
| void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot); | ||||
|  | ||||
| /** | ||||
|  * An FR or a DA IRQ has occurred. | ||||
|  * | ||||
|  * @param ca CA instance. | ||||
|  * @param slot Slot concerned. | ||||
|  */ | ||||
| void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot); | ||||
|  | ||||
|  | ||||
|  | ||||
| /* ******************************************************************************** */ | ||||
| /* Initialisation/shutdown functions */ | ||||
|  | ||||
| /** | ||||
|  * Initialise a new DVB CA device. | ||||
|  * | ||||
|  * @param dvb_adapter DVB adapter to attach the new CA device to. | ||||
|  * @param ca The dvb_ca instance. | ||||
|  * @param flags Flags describing the CA device (DVB_CA_EN50221_FLAG_*). | ||||
|  * @param slot_count Number of slots supported. | ||||
|  * | ||||
|  * @return 0 on success, nonzero on failure | ||||
|  */ | ||||
| extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_en50221* ca, int flags, int slot_count); | ||||
|  | ||||
| /** | ||||
|  * Release a DVB CA device. | ||||
|  * | ||||
|  * @param ca The associated dvb_ca instance. | ||||
|  */ | ||||
| extern void dvb_ca_en50221_release(struct dvb_ca_en50221* ca); | ||||
|  | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										1320
									
								
								dvb-core/dvb_demux.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1320
									
								
								dvb-core/dvb_demux.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										151
									
								
								dvb-core/dvb_demux.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								dvb-core/dvb_demux.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,151 @@ | ||||
| /* | ||||
|  * dvb_demux.h: DVB kernel demux API | ||||
|  * | ||||
|  * Copyright (C) 2000-2001 Marcus Metzler & Ralph Metzler | ||||
|  *                         for convergence integrated media GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef _DVB_DEMUX_H_ | ||||
| #define _DVB_DEMUX_H_ | ||||
|  | ||||
| #include <linux/time.h> | ||||
| #include <linux/timer.h> | ||||
| #include <linux/spinlock.h> | ||||
| #include <linux/mutex.h> | ||||
|  | ||||
| #include "demux.h" | ||||
|  | ||||
| #define DMX_TYPE_TS  0 | ||||
| #define DMX_TYPE_SEC 1 | ||||
| #define DMX_TYPE_PES 2 | ||||
|  | ||||
| #define DMX_STATE_FREE      0 | ||||
| #define DMX_STATE_ALLOCATED 1 | ||||
| #define DMX_STATE_SET       2 | ||||
| #define DMX_STATE_READY     3 | ||||
| #define DMX_STATE_GO        4 | ||||
|  | ||||
| #define DVB_DEMUX_MASK_MAX 18 | ||||
|  | ||||
| #define MAX_PID 0x1fff | ||||
|  | ||||
| #define SPEED_PKTS_INTERVAL 50000 | ||||
|  | ||||
| struct dvb_demux_filter { | ||||
| 	struct dmx_section_filter filter; | ||||
| 	u8 maskandmode[DMX_MAX_FILTER_SIZE]; | ||||
| 	u8 maskandnotmode[DMX_MAX_FILTER_SIZE]; | ||||
| 	int doneq; | ||||
|  | ||||
| 	struct dvb_demux_filter *next; | ||||
| 	struct dvb_demux_feed *feed; | ||||
| 	int index; | ||||
| 	int state; | ||||
| 	int type; | ||||
|  | ||||
| 	u16 hw_handle; | ||||
| 	struct timer_list timer; | ||||
| }; | ||||
|  | ||||
| #define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head) | ||||
|  | ||||
| struct dvb_demux_feed { | ||||
| 	union { | ||||
| 		struct dmx_ts_feed ts; | ||||
| 		struct dmx_section_feed sec; | ||||
| 	} feed; | ||||
|  | ||||
| 	union { | ||||
| 		dmx_ts_cb ts; | ||||
| 		dmx_section_cb sec; | ||||
| 	} cb; | ||||
|  | ||||
| 	struct dvb_demux *demux; | ||||
| 	void *priv; | ||||
| 	int type; | ||||
| 	int state; | ||||
| 	u16 pid; | ||||
| 	u8 *buffer; | ||||
| 	int buffer_size; | ||||
|  | ||||
| 	struct timespec timeout; | ||||
| 	struct dvb_demux_filter *filter; | ||||
|  | ||||
| 	int ts_type; | ||||
| 	enum dmx_ts_pes pes_type; | ||||
|  | ||||
| 	int cc; | ||||
| 	int pusi_seen;		/* prevents feeding of garbage from previous section */ | ||||
|  | ||||
| 	u16 peslen; | ||||
|  | ||||
| 	struct list_head list_head; | ||||
| 	unsigned int index;	/* a unique index for each feed (can be used as hardware pid filter index) */ | ||||
| }; | ||||
|  | ||||
| struct dvb_demux { | ||||
| 	struct dmx_demux dmx; | ||||
| 	void *priv; | ||||
| 	int filternum; | ||||
| 	int feednum; | ||||
| 	int (*start_feed)(struct dvb_demux_feed *feed); | ||||
| 	int (*stop_feed)(struct dvb_demux_feed *feed); | ||||
| 	int (*write_to_decoder)(struct dvb_demux_feed *feed, | ||||
| 				 const u8 *buf, size_t len); | ||||
| 	u32 (*check_crc32)(struct dvb_demux_feed *feed, | ||||
| 			    const u8 *buf, size_t len); | ||||
| 	void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst, | ||||
| 			 const u8 *src, size_t len); | ||||
|  | ||||
| 	int users; | ||||
| #define MAX_DVB_DEMUX_USERS 10 | ||||
| 	struct dvb_demux_filter *filter; | ||||
| 	struct dvb_demux_feed *feed; | ||||
|  | ||||
| 	struct list_head frontend_list; | ||||
|  | ||||
| 	struct dvb_demux_feed *pesfilter[DMX_PES_OTHER]; | ||||
| 	u16 pids[DMX_PES_OTHER]; | ||||
| 	int playing; | ||||
| 	int recording; | ||||
|  | ||||
| #define DMX_MAX_PID 0x2000 | ||||
| 	struct list_head feed_list; | ||||
| 	u8 tsbuf[204]; | ||||
| 	int tsbufp; | ||||
|  | ||||
| 	struct mutex mutex; | ||||
| 	spinlock_t lock; | ||||
|  | ||||
| 	uint8_t *cnt_storage; /* for TS continuity check */ | ||||
|  | ||||
| 	struct timespec speed_last_time; /* for TS speed check */ | ||||
| 	uint32_t speed_pkts_cnt; /* for TS speed check */ | ||||
| }; | ||||
|  | ||||
| int dvb_dmx_init(struct dvb_demux *dvbdemux); | ||||
| void dvb_dmx_release(struct dvb_demux *dvbdemux); | ||||
| void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf, | ||||
| 			      size_t count); | ||||
| void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count); | ||||
| void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, | ||||
| 			  size_t count); | ||||
| void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf, | ||||
| 			  size_t count); | ||||
|  | ||||
| #endif /* _DVB_DEMUX_H_ */ | ||||
							
								
								
									
										603
									
								
								dvb-core/dvb_filter.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										603
									
								
								dvb-core/dvb_filter.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,603 @@ | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/string.h> | ||||
| #include "dvb_filter.h" | ||||
|  | ||||
| #if 0 | ||||
| static unsigned int bitrates[3][16] = | ||||
| {{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, | ||||
|  {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, | ||||
|  {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}}; | ||||
| #endif | ||||
|  | ||||
| static u32 freq[4] = {480, 441, 320, 0}; | ||||
|  | ||||
| static unsigned int ac3_bitrates[32] = | ||||
|     {32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640, | ||||
|      0,0,0,0,0,0,0,0,0,0,0,0,0}; | ||||
|  | ||||
| static u32 ac3_frames[3][32] = | ||||
|     {{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024, | ||||
|       1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0}, | ||||
|      {69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114, | ||||
|       1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0}, | ||||
|      {96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344, | ||||
|       1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}}; | ||||
|  | ||||
|  | ||||
|  | ||||
| #if 0 | ||||
| static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv, | ||||
| 		  void (*pes_write)(u8 *buf, int count, void *data), | ||||
| 		  void *priv) | ||||
| { | ||||
| 	dvb_filter_ipack_init(pa, IPACKS, pes_write); | ||||
| 	dvb_filter_ipack_init(pv, IPACKS, pes_write); | ||||
| 	pa->pid = pida; | ||||
| 	pv->pid = pidv; | ||||
| 	pa->data = priv; | ||||
| 	pv->data = priv; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188) | ||||
| { | ||||
| 	u8 off = 0; | ||||
|  | ||||
| 	if (!buf || !p ){ | ||||
| 		printk("NULL POINTER IDIOT\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 	if (buf[1]&PAY_START) { | ||||
| 		if (p->plength == MMAX_PLENGTH-6 && p->found>6){ | ||||
| 			p->plength = p->found-6; | ||||
| 			p->found = 0; | ||||
| 			send_ipack(p); | ||||
| 			dvb_filter_ipack_reset(p); | ||||
| 		} | ||||
| 	} | ||||
| 	if (buf[3] & ADAPT_FIELD) {  // adaptation field? | ||||
| 		off = buf[4] + 1; | ||||
| 		if (off+4 > 187) return; | ||||
| 	} | ||||
| 	dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| /* needs 5 byte input, returns picture coding type*/ | ||||
| static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr) | ||||
| { | ||||
| 	u8 pct; | ||||
|  | ||||
| 	if (pr) printk( "Pic header: "); | ||||
| 	pic->temporal_reference[field] = (( headr[0] << 2 ) | | ||||
| 					  (headr[1] & 0x03) )& 0x03ff; | ||||
| 	if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]); | ||||
|  | ||||
| 	pct = ( headr[1] >> 2 ) & 0x07; | ||||
| 	pic->picture_coding_type[field] = pct; | ||||
| 	if (pr) { | ||||
| 		switch(pct){ | ||||
| 			case I_FRAME: | ||||
| 				printk( "  I-FRAME"); | ||||
| 				break; | ||||
| 			case B_FRAME: | ||||
| 				printk( "  B-FRAME"); | ||||
| 				break; | ||||
| 			case P_FRAME: | ||||
| 				printk( "  P-FRAME"); | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	pic->vinfo.vbv_delay  = (( headr[1] >> 5 ) | ( headr[2] << 3) | | ||||
| 				 ( (headr[3] & 0x1F) << 11) ) & 0xffff; | ||||
|  | ||||
| 	if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay); | ||||
|  | ||||
| 	pic->picture_header_parameter = ( headr[3] & 0xe0 ) | | ||||
| 		((headr[4] & 0x80) >> 3); | ||||
|  | ||||
| 	if ( pct == B_FRAME ){ | ||||
| 		pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f; | ||||
| 	} | ||||
| 	if (pr) printk( " pic head param: 0x%x", | ||||
| 			pic->picture_header_parameter); | ||||
|  | ||||
| 	return pct; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| /* needs 4 byte input */ | ||||
| static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr) | ||||
| { | ||||
| 	if (pr) printk("GOP header: "); | ||||
|  | ||||
| 	pic->time_code  = (( headr[0] << 17 ) | ( headr[1] << 9) | | ||||
| 			   ( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff; | ||||
|  | ||||
| 	if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F, | ||||
| 		       ((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F), | ||||
| 		       ((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F)); | ||||
|  | ||||
| 	if ( ( headr[3] & 0x40 ) != 0 ){ | ||||
| 		pic->closed_gop = 1; | ||||
| 	} else { | ||||
| 		pic->closed_gop = 0; | ||||
| 	} | ||||
| 	if (pr) printk("closed: %d", pic->closed_gop); | ||||
|  | ||||
| 	if ( ( headr[3] & 0x20 ) != 0 ){ | ||||
| 		pic->broken_link = 1; | ||||
| 	} else { | ||||
| 		pic->broken_link = 0; | ||||
| 	} | ||||
| 	if (pr) printk(" broken: %d\n", pic->broken_link); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| /* needs 8 byte input */ | ||||
| static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr) | ||||
| { | ||||
| 	int sw; | ||||
| 	int form = -1; | ||||
|  | ||||
| 	if (pr) printk("Reading sequence header\n"); | ||||
|  | ||||
| 	vi->horizontal_size	= ((headr[1] &0xF0) >> 4) | (headr[0] << 4); | ||||
| 	vi->vertical_size	= ((headr[1] &0x0F) << 8) | (headr[2]); | ||||
|  | ||||
| 	sw = (int)((headr[3]&0xF0) >> 4) ; | ||||
|  | ||||
| 	switch( sw ){ | ||||
| 	case 1: | ||||
| 		if (pr) | ||||
| 			printk("Videostream: ASPECT: 1:1"); | ||||
| 		vi->aspect_ratio = 100; | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		if (pr) | ||||
| 			printk("Videostream: ASPECT: 4:3"); | ||||
| 		vi->aspect_ratio = 133; | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		if (pr) | ||||
| 			printk("Videostream: ASPECT: 16:9"); | ||||
| 		vi->aspect_ratio = 177; | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		if (pr) | ||||
| 			printk("Videostream: ASPECT: 2.21:1"); | ||||
| 		vi->aspect_ratio = 221; | ||||
| 		break; | ||||
|  | ||||
| 	case 5 ... 15: | ||||
| 		if (pr) | ||||
| 			printk("Videostream: ASPECT: reserved"); | ||||
| 		vi->aspect_ratio = 0; | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		vi->aspect_ratio = 0; | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (pr) | ||||
| 		printk("  Size = %dx%d",vi->horizontal_size,vi->vertical_size); | ||||
|  | ||||
| 	sw = (int)(headr[3]&0x0F); | ||||
|  | ||||
| 	switch ( sw ) { | ||||
| 	case 1: | ||||
| 		if (pr) | ||||
| 			printk("  FRate: 23.976 fps"); | ||||
| 		vi->framerate = 23976; | ||||
| 		form = -1; | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		if (pr) | ||||
| 			printk("  FRate: 24 fps"); | ||||
| 		vi->framerate = 24000; | ||||
| 		form = -1; | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		if (pr) | ||||
| 			printk("  FRate: 25 fps"); | ||||
| 		vi->framerate = 25000; | ||||
| 		form = VIDEO_MODE_PAL; | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		if (pr) | ||||
| 			printk("  FRate: 29.97 fps"); | ||||
| 		vi->framerate = 29970; | ||||
| 		form = VIDEO_MODE_NTSC; | ||||
| 		break; | ||||
| 	case 5: | ||||
| 		if (pr) | ||||
| 			printk("  FRate: 30 fps"); | ||||
| 		vi->framerate = 30000; | ||||
| 		form = VIDEO_MODE_NTSC; | ||||
| 		break; | ||||
| 	case 6: | ||||
| 		if (pr) | ||||
| 			printk("  FRate: 50 fps"); | ||||
| 		vi->framerate = 50000; | ||||
| 		form = VIDEO_MODE_PAL; | ||||
| 		break; | ||||
| 	case 7: | ||||
| 		if (pr) | ||||
| 			printk("  FRate: 60 fps"); | ||||
| 		vi->framerate = 60000; | ||||
| 		form = VIDEO_MODE_NTSC; | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03); | ||||
|  | ||||
| 	vi->vbv_buffer_size | ||||
| 		= (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5); | ||||
|  | ||||
| 	if (pr){ | ||||
| 		printk("  BRate: %d Mbit/s",4*(vi->bit_rate)/10000); | ||||
| 		printk("  vbvbuffer %d",16*1024*(vi->vbv_buffer_size)); | ||||
| 		printk("\n"); | ||||
| 	} | ||||
|  | ||||
| 	vi->video_format = form; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #if 0 | ||||
| static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr) | ||||
| { | ||||
| 	u8 *headr; | ||||
| 	int found = 0; | ||||
| 	int c = 0; | ||||
|  | ||||
| 	while (found < 4 && c+4 < count){ | ||||
| 		u8 *b; | ||||
|  | ||||
| 		b = mbuf+c; | ||||
| 		if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01 | ||||
| 		     && b[3] == 0xb3) found = 4; | ||||
| 		else { | ||||
| 			c++; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (! found) return -1; | ||||
| 	c += 4; | ||||
| 	if (c+12 >= count) return -1; | ||||
| 	headr = mbuf+c; | ||||
| 	if (read_sequence_header(headr, vi, pr) < 0) return -1; | ||||
| 	vi->off = c-4; | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| #if 0 | ||||
| static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) | ||||
| { | ||||
| 	u8 *headr; | ||||
| 	int found = 0; | ||||
| 	int c = 0; | ||||
| 	int fr = 0; | ||||
|  | ||||
| 	while (found < 2 && c < count){ | ||||
| 		u8 b[2]; | ||||
| 		memcpy( b, mbuf+c, 2); | ||||
|  | ||||
| 		if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8) | ||||
| 			found = 2; | ||||
| 		else { | ||||
| 			c++; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!found) return -1; | ||||
|  | ||||
| 	if (c+3 >= count) return -1; | ||||
| 	headr = mbuf+c; | ||||
|  | ||||
| 	ai->layer = (headr[1] & 0x06) >> 1; | ||||
|  | ||||
| 	if (pr) | ||||
| 		printk("Audiostream: Layer: %d", 4-ai->layer); | ||||
|  | ||||
|  | ||||
| 	ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000; | ||||
|  | ||||
| 	if (pr){ | ||||
| 		if (ai->bit_rate == 0) | ||||
| 			printk("  Bit rate: free"); | ||||
| 		else if (ai->bit_rate == 0xf) | ||||
| 			printk("  BRate: reserved"); | ||||
| 		else | ||||
| 			printk("  BRate: %d kb/s", ai->bit_rate/1000); | ||||
| 	} | ||||
|  | ||||
| 	fr = (headr[2] & 0x0c ) >> 2; | ||||
| 	ai->frequency = freq[fr]*100; | ||||
| 	if (pr){ | ||||
| 		if (ai->frequency == 3) | ||||
| 			printk("  Freq: reserved\n"); | ||||
| 		else | ||||
| 			printk("  Freq: %d kHz\n",ai->frequency); | ||||
|  | ||||
| 	} | ||||
| 	ai->off = c; | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr) | ||||
| { | ||||
| 	u8 *headr; | ||||
| 	int found = 0; | ||||
| 	int c = 0; | ||||
| 	u8 frame = 0; | ||||
| 	int fr = 0; | ||||
|  | ||||
| 	while ( !found  && c < count){ | ||||
| 		u8 *b = mbuf+c; | ||||
|  | ||||
| 		if ( b[0] == 0x0b &&  b[1] == 0x77 ) | ||||
| 			found = 1; | ||||
| 		else { | ||||
| 			c++; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (!found) return -1; | ||||
| 	if (pr) | ||||
| 		printk("Audiostream: AC3"); | ||||
|  | ||||
| 	ai->off = c; | ||||
| 	if (c+5 >= count) return -1; | ||||
|  | ||||
| 	ai->layer = 0;  // 0 for AC3 | ||||
| 	headr = mbuf+c+2; | ||||
|  | ||||
| 	frame = (headr[2]&0x3f); | ||||
| 	ai->bit_rate = ac3_bitrates[frame >> 1]*1000; | ||||
|  | ||||
| 	if (pr) | ||||
| 		printk("  BRate: %d kb/s", (int) ai->bit_rate/1000); | ||||
|  | ||||
| 	ai->frequency = (headr[2] & 0xc0 ) >> 6; | ||||
| 	fr = (headr[2] & 0xc0 ) >> 6; | ||||
| 	ai->frequency = freq[fr]*100; | ||||
| 	if (pr) printk ("  Freq: %d Hz\n", (int) ai->frequency); | ||||
|  | ||||
|  | ||||
| 	ai->framesize = ac3_frames[fr][frame >> 1]; | ||||
| 	if ((frame & 1) &&  (fr == 1)) ai->framesize++; | ||||
| 	ai->framesize = ai->framesize << 1; | ||||
| 	if (pr) printk ("  Framesize %d\n",(int) ai->framesize); | ||||
|  | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_filter_get_ac3info); | ||||
|  | ||||
|  | ||||
| #if 0 | ||||
| static u8 *skip_pes_header(u8 **bufp) | ||||
| { | ||||
| 	u8 *inbuf = *bufp; | ||||
| 	u8 *buf = inbuf; | ||||
| 	u8 *pts = NULL; | ||||
| 	int skip = 0; | ||||
|  | ||||
| 	static const int mpeg1_skip_table[16] = { | ||||
| 		1, 0xffff,      5,     10, 0xffff, 0xffff, 0xffff, 0xffff, | ||||
| 		0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff | ||||
| 	}; | ||||
|  | ||||
|  | ||||
| 	if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */ | ||||
| 		if (buf[7] & PTS_ONLY) | ||||
| 			pts = buf+9; | ||||
| 		else pts = NULL; | ||||
| 		buf = inbuf + 9 + inbuf[8]; | ||||
| 	} else {        /* mpeg1 */ | ||||
| 		for (buf = inbuf + 6; *buf == 0xff; buf++) | ||||
| 			if (buf == inbuf + 6 + 16) { | ||||
| 				break; | ||||
| 			} | ||||
| 		if ((*buf & 0xc0) == 0x40) | ||||
| 			buf += 2; | ||||
| 		skip = mpeg1_skip_table [*buf >> 4]; | ||||
| 		if (skip == 5 || skip == 10) pts = buf; | ||||
| 		else pts = NULL; | ||||
|  | ||||
| 		buf += mpeg1_skip_table [*buf >> 4]; | ||||
| 	} | ||||
|  | ||||
| 	*bufp = buf; | ||||
| 	return pts; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| static void initialize_quant_matrix( u32 *matrix ) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	matrix[0]  = 0x08101013; | ||||
| 	matrix[1]  = 0x10131616; | ||||
| 	matrix[2]  = 0x16161616; | ||||
| 	matrix[3]  = 0x1a181a1b; | ||||
| 	matrix[4]  = 0x1b1b1a1a; | ||||
| 	matrix[5]  = 0x1a1a1b1b; | ||||
| 	matrix[6]  = 0x1b1d1d1d; | ||||
| 	matrix[7]  = 0x2222221d; | ||||
| 	matrix[8]  = 0x1d1d1b1b; | ||||
| 	matrix[9]  = 0x1d1d2020; | ||||
| 	matrix[10] = 0x22222526; | ||||
| 	matrix[11] = 0x25232322; | ||||
| 	matrix[12] = 0x23262628; | ||||
| 	matrix[13] = 0x28283030; | ||||
| 	matrix[14] = 0x2e2e3838; | ||||
| 	matrix[15] = 0x3a454553; | ||||
|  | ||||
| 	for ( i = 16 ; i < 32 ; i++ ) | ||||
| 		matrix[i] = 0x10101010; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| static void initialize_mpg_picture(struct mpg_picture *pic) | ||||
| { | ||||
| 	int i; | ||||
|  | ||||
| 	/* set MPEG1 */ | ||||
| 	pic->mpeg1_flag = 1; | ||||
| 	pic->profile_and_level = 0x4A ;        /* MP@LL */ | ||||
| 	pic->progressive_sequence = 1; | ||||
| 	pic->low_delay = 0; | ||||
|  | ||||
| 	pic->sequence_display_extension_flag = 0; | ||||
| 	for ( i = 0 ; i < 4 ; i++ ){ | ||||
| 		pic->frame_centre_horizontal_offset[i] = 0; | ||||
| 		pic->frame_centre_vertical_offset[i] = 0; | ||||
| 	} | ||||
| 	pic->last_frame_centre_horizontal_offset = 0; | ||||
| 	pic->last_frame_centre_vertical_offset = 0; | ||||
|  | ||||
| 	pic->picture_display_extension_flag[0] = 0; | ||||
| 	pic->picture_display_extension_flag[1] = 0; | ||||
| 	pic->sequence_header_flag = 0; | ||||
| 	pic->gop_flag = 0; | ||||
| 	pic->sequence_end_flag = 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic ) | ||||
| { | ||||
| 	int16_t last_h_offset; | ||||
| 	int16_t last_v_offset; | ||||
|  | ||||
| 	int16_t *p_h_offset; | ||||
| 	int16_t *p_v_offset; | ||||
|  | ||||
| 	if ( pic->mpeg1_flag ){ | ||||
| 		pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE; | ||||
| 		pic->top_field_first = 0; | ||||
| 		pic->repeat_first_field = 0; | ||||
| 		pic->progressive_frame = 1; | ||||
| 		pic->picture_coding_parameter = 0x000010; | ||||
| 	} | ||||
|  | ||||
| 	/* Reset flag */ | ||||
| 	pic->picture_display_extension_flag[field_type] = 0; | ||||
|  | ||||
| 	last_h_offset = pic->last_frame_centre_horizontal_offset; | ||||
| 	last_v_offset = pic->last_frame_centre_vertical_offset; | ||||
| 	if ( field_type == FIRST_FIELD ){ | ||||
| 		p_h_offset = pic->frame_centre_horizontal_offset; | ||||
| 		p_v_offset = pic->frame_centre_vertical_offset; | ||||
| 		*p_h_offset = last_h_offset; | ||||
| 		*(p_h_offset + 1) = last_h_offset; | ||||
| 		*(p_h_offset + 2) = last_h_offset; | ||||
| 		*p_v_offset = last_v_offset; | ||||
| 		*(p_v_offset + 1) = last_v_offset; | ||||
| 		*(p_v_offset + 2) = last_v_offset; | ||||
| 	} else { | ||||
| 		pic->frame_centre_horizontal_offset[3] = last_h_offset; | ||||
| 		pic->frame_centre_vertical_offset[3] = last_v_offset; | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type) | ||||
| { | ||||
| 	pic->picture_header = 0; | ||||
| 	pic->sequence_header_data | ||||
| 		= ( INIT_HORIZONTAL_SIZE << 20 ) | ||||
| 			| ( INIT_VERTICAL_SIZE << 8 ) | ||||
| 			| ( INIT_ASPECT_RATIO << 4 ) | ||||
| 			| ( INIT_FRAME_RATE ); | ||||
| 	pic->mpeg1_flag = 0; | ||||
| 	pic->vinfo.horizontal_size | ||||
| 		= INIT_DISP_HORIZONTAL_SIZE; | ||||
| 	pic->vinfo.vertical_size | ||||
| 		= INIT_DISP_VERTICAL_SIZE; | ||||
| 	pic->picture_display_extension_flag[field_type] | ||||
| 		= 0; | ||||
| 	pic->pts_flag[field_type] = 0; | ||||
|  | ||||
| 	pic->sequence_gop_header = 0; | ||||
| 	pic->picture_header = 0; | ||||
| 	pic->sequence_header_flag = 0; | ||||
| 	pic->gop_flag = 0; | ||||
| 	pic->sequence_end_flag = 0; | ||||
| 	pic->sequence_display_extension_flag = 0; | ||||
| 	pic->last_frame_centre_horizontal_offset = 0; | ||||
| 	pic->last_frame_centre_vertical_offset = 0; | ||||
| 	pic->channel = chan; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, | ||||
| 			    dvb_filter_pes2ts_cb_t *cb, void *priv) | ||||
| { | ||||
| 	unsigned char *buf=p2ts->buf; | ||||
|  | ||||
| 	buf[0]=0x47; | ||||
| 	buf[1]=(pid>>8); | ||||
| 	buf[2]=pid&0xff; | ||||
| 	p2ts->cc=0; | ||||
| 	p2ts->cb=cb; | ||||
| 	p2ts->priv=priv; | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_filter_pes2ts_init); | ||||
|  | ||||
| int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, | ||||
| 		      int len, int payload_start) | ||||
| { | ||||
| 	unsigned char *buf=p2ts->buf; | ||||
| 	int ret=0, rest; | ||||
|  | ||||
| 	//len=6+((pes[4]<<8)|pes[5]); | ||||
|  | ||||
| 	if (payload_start) | ||||
| 		buf[1]|=0x40; | ||||
| 	else | ||||
| 		buf[1]&=~0x40; | ||||
| 	while (len>=184) { | ||||
| 		buf[3]=0x10|((p2ts->cc++)&0x0f); | ||||
| 		memcpy(buf+4, pes, 184); | ||||
| 		if ((ret=p2ts->cb(p2ts->priv, buf))) | ||||
| 			return ret; | ||||
| 		len-=184; pes+=184; | ||||
| 		buf[1]&=~0x40; | ||||
| 	} | ||||
| 	if (!len) | ||||
| 		return 0; | ||||
| 	buf[3]=0x30|((p2ts->cc++)&0x0f); | ||||
| 	rest=183-len; | ||||
| 	if (rest) { | ||||
| 		buf[5]=0x00; | ||||
| 		if (rest-1) | ||||
| 			memset(buf+6, 0xff, rest-1); | ||||
| 	} | ||||
| 	buf[4]=rest; | ||||
| 	memcpy(buf+5+rest, pes, len); | ||||
| 	return p2ts->cb(p2ts->priv, buf); | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_filter_pes2ts); | ||||
							
								
								
									
										246
									
								
								dvb-core/dvb_filter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								dvb-core/dvb_filter.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,246 @@ | ||||
| /* | ||||
|  * dvb_filter.h | ||||
|  * | ||||
|  * Copyright (C) 2003 Convergence GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef _DVB_FILTER_H_ | ||||
| #define _DVB_FILTER_H_ | ||||
|  | ||||
| #include <linux/slab.h> | ||||
|  | ||||
| #include "demux.h" | ||||
|  | ||||
| typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *); | ||||
|  | ||||
| struct dvb_filter_pes2ts { | ||||
| 	unsigned char buf[188]; | ||||
| 	unsigned char cc; | ||||
| 	dvb_filter_pes2ts_cb_t *cb; | ||||
| 	void *priv; | ||||
| }; | ||||
|  | ||||
| void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid, | ||||
| 			    dvb_filter_pes2ts_cb_t *cb, void *priv); | ||||
|  | ||||
| int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes, | ||||
| 		      int len, int payload_start); | ||||
|  | ||||
|  | ||||
| #define PROG_STREAM_MAP  0xBC | ||||
| #define PRIVATE_STREAM1  0xBD | ||||
| #define PADDING_STREAM   0xBE | ||||
| #define PRIVATE_STREAM2  0xBF | ||||
| #define AUDIO_STREAM_S   0xC0 | ||||
| #define AUDIO_STREAM_E   0xDF | ||||
| #define VIDEO_STREAM_S   0xE0 | ||||
| #define VIDEO_STREAM_E   0xEF | ||||
| #define ECM_STREAM       0xF0 | ||||
| #define EMM_STREAM       0xF1 | ||||
| #define DSM_CC_STREAM    0xF2 | ||||
| #define ISO13522_STREAM  0xF3 | ||||
| #define PROG_STREAM_DIR  0xFF | ||||
|  | ||||
| #define DVB_PICTURE_START    0x00 | ||||
| #define DVB_USER_START       0xb2 | ||||
| #define DVB_SEQUENCE_HEADER  0xb3 | ||||
| #define DVB_SEQUENCE_ERROR   0xb4 | ||||
| #define DVB_EXTENSION_START  0xb5 | ||||
| #define DVB_SEQUENCE_END     0xb7 | ||||
| #define DVB_GOP_START        0xb8 | ||||
| #define DVB_EXCEPT_SLICE     0xb0 | ||||
|  | ||||
| #define SEQUENCE_EXTENSION           0x01 | ||||
| #define SEQUENCE_DISPLAY_EXTENSION   0x02 | ||||
| #define PICTURE_CODING_EXTENSION     0x08 | ||||
| #define QUANT_MATRIX_EXTENSION       0x03 | ||||
| #define PICTURE_DISPLAY_EXTENSION    0x07 | ||||
|  | ||||
| #define I_FRAME 0x01 | ||||
| #define B_FRAME 0x02 | ||||
| #define P_FRAME 0x03 | ||||
|  | ||||
| /* Initialize sequence_data */ | ||||
| #define INIT_HORIZONTAL_SIZE        720 | ||||
| #define INIT_VERTICAL_SIZE          576 | ||||
| #define INIT_ASPECT_RATIO          0x02 | ||||
| #define INIT_FRAME_RATE            0x03 | ||||
| #define INIT_DISP_HORIZONTAL_SIZE   540 | ||||
| #define INIT_DISP_VERTICAL_SIZE     576 | ||||
|  | ||||
|  | ||||
| //flags2 | ||||
| #define PTS_DTS_FLAGS    0xC0 | ||||
| #define ESCR_FLAG        0x20 | ||||
| #define ES_RATE_FLAG     0x10 | ||||
| #define DSM_TRICK_FLAG   0x08 | ||||
| #define ADD_CPY_FLAG     0x04 | ||||
| #define PES_CRC_FLAG     0x02 | ||||
| #define PES_EXT_FLAG     0x01 | ||||
|  | ||||
| //pts_dts flags | ||||
| #define PTS_ONLY         0x80 | ||||
| #define PTS_DTS          0xC0 | ||||
|  | ||||
| #define TS_SIZE        188 | ||||
| #define TRANS_ERROR    0x80 | ||||
| #define PAY_START      0x40 | ||||
| #define TRANS_PRIO     0x20 | ||||
| #define PID_MASK_HI    0x1F | ||||
| //flags | ||||
| #define TRANS_SCRMBL1  0x80 | ||||
| #define TRANS_SCRMBL2  0x40 | ||||
| #define ADAPT_FIELD    0x20 | ||||
| #define PAYLOAD        0x10 | ||||
| #define COUNT_MASK     0x0F | ||||
|  | ||||
| // adaptation flags | ||||
| #define DISCON_IND     0x80 | ||||
| #define RAND_ACC_IND   0x40 | ||||
| #define ES_PRI_IND     0x20 | ||||
| #define PCR_FLAG       0x10 | ||||
| #define OPCR_FLAG      0x08 | ||||
| #define SPLICE_FLAG    0x04 | ||||
| #define TRANS_PRIV     0x02 | ||||
| #define ADAP_EXT_FLAG  0x01 | ||||
|  | ||||
| // adaptation extension flags | ||||
| #define LTW_FLAG       0x80 | ||||
| #define PIECE_RATE     0x40 | ||||
| #define SEAM_SPLICE    0x20 | ||||
|  | ||||
|  | ||||
| #define MAX_PLENGTH 0xFFFF | ||||
| #define MMAX_PLENGTH (256*MAX_PLENGTH) | ||||
|  | ||||
| #ifndef IPACKS | ||||
| #define IPACKS 2048 | ||||
| #endif | ||||
|  | ||||
| struct ipack { | ||||
| 	int size; | ||||
| 	int found; | ||||
| 	u8 *buf; | ||||
| 	u8 cid; | ||||
| 	u32 plength; | ||||
| 	u8 plen[2]; | ||||
| 	u8 flag1; | ||||
| 	u8 flag2; | ||||
| 	u8 hlength; | ||||
| 	u8 pts[5]; | ||||
| 	u16 *pid; | ||||
| 	int mpeg; | ||||
| 	u8 check; | ||||
| 	int which; | ||||
| 	int done; | ||||
| 	void *data; | ||||
| 	void (*func)(u8 *buf,  int size, void *priv); | ||||
| 	int count; | ||||
| 	int repack_subids; | ||||
| }; | ||||
|  | ||||
| struct dvb_video_info { | ||||
| 	u32 horizontal_size; | ||||
| 	u32 vertical_size; | ||||
| 	u32 aspect_ratio; | ||||
| 	u32 framerate; | ||||
| 	u32 video_format; | ||||
| 	u32 bit_rate; | ||||
| 	u32 comp_bit_rate; | ||||
| 	u32 vbv_buffer_size; | ||||
| 	s16 vbv_delay; | ||||
| 	u32 CSPF; | ||||
| 	u32 off; | ||||
| }; | ||||
|  | ||||
| #define OFF_SIZE 4 | ||||
| #define FIRST_FIELD 0 | ||||
| #define SECOND_FIELD 1 | ||||
| #define VIDEO_FRAME_PICTURE 0x03 | ||||
|  | ||||
| struct mpg_picture { | ||||
| 	int       channel; | ||||
| 	struct dvb_video_info vinfo; | ||||
| 	u32      *sequence_gop_header; | ||||
| 	u32      *picture_header; | ||||
| 	s32       time_code; | ||||
| 	int       low_delay; | ||||
| 	int       closed_gop; | ||||
| 	int       broken_link; | ||||
| 	int       sequence_header_flag; | ||||
| 	int       gop_flag; | ||||
| 	int       sequence_end_flag; | ||||
|  | ||||
| 	u8        profile_and_level; | ||||
| 	s32       picture_coding_parameter; | ||||
| 	u32       matrix[32]; | ||||
| 	s8        matrix_change_flag; | ||||
|  | ||||
| 	u8        picture_header_parameter; | ||||
|   /* bit 0 - 2: bwd f code | ||||
|      bit 3    : fpb vector | ||||
|      bit 4 - 6: fwd f code | ||||
|      bit 7    : fpf vector */ | ||||
|  | ||||
| 	int       mpeg1_flag; | ||||
| 	int       progressive_sequence; | ||||
| 	int       sequence_display_extension_flag; | ||||
| 	u32       sequence_header_data; | ||||
| 	s16       last_frame_centre_horizontal_offset; | ||||
| 	s16       last_frame_centre_vertical_offset; | ||||
|  | ||||
| 	u32       pts[2]; /* [0] 1st field, [1] 2nd field */ | ||||
| 	int       top_field_first; | ||||
| 	int       repeat_first_field; | ||||
| 	int       progressive_frame; | ||||
| 	int       bank; | ||||
| 	int       forward_bank; | ||||
| 	int       backward_bank; | ||||
| 	int       compress; | ||||
| 	s16       frame_centre_horizontal_offset[OFF_SIZE]; | ||||
| 		  /* [0-2] 1st field, [3] 2nd field */ | ||||
| 	s16       frame_centre_vertical_offset[OFF_SIZE]; | ||||
| 		  /* [0-2] 1st field, [3] 2nd field */ | ||||
| 	s16       temporal_reference[2]; | ||||
| 		  /* [0] 1st field, [1] 2nd field */ | ||||
|  | ||||
| 	s8        picture_coding_type[2]; | ||||
| 		  /* [0] 1st field, [1] 2nd field */ | ||||
| 	s8        picture_structure[2]; | ||||
| 		  /* [0] 1st field, [1] 2nd field */ | ||||
| 	s8        picture_display_extension_flag[2]; | ||||
| 		  /* [0] 1st field, [1] 2nd field */ | ||||
| 		  /* picture_display_extenion() 0:no 1:exit*/ | ||||
| 	s8        pts_flag[2]; | ||||
| 		  /* [0] 1st field, [1] 2nd field */ | ||||
| }; | ||||
|  | ||||
| struct dvb_audio_info { | ||||
| 	int layer; | ||||
| 	u32 bit_rate; | ||||
| 	u32 frequency; | ||||
| 	u32 mode; | ||||
| 	u32 mode_extension ; | ||||
| 	u32 emphasis; | ||||
| 	u32 framesize; | ||||
| 	u32 off; | ||||
| }; | ||||
|  | ||||
| int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr); | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										2713
									
								
								dvb-core/dvb_frontend.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2713
									
								
								dvb-core/dvb_frontend.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										441
									
								
								dvb-core/dvb_frontend.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								dvb-core/dvb_frontend.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,441 @@ | ||||
| /* | ||||
|  * dvb_frontend.h | ||||
|  * | ||||
|  * Copyright (C) 2001 convergence integrated media GmbH | ||||
|  * Copyright (C) 2004 convergence GmbH | ||||
|  * | ||||
|  * Written by Ralph Metzler | ||||
|  * Overhauled by Holger Waechtler | ||||
|  * Kernel I2C stuff by Michael Hunold <hunold@convergence.de> | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef _DVB_FRONTEND_H_ | ||||
| #define _DVB_FRONTEND_H_ | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/sched.h> | ||||
| #include <linux/ioctl.h> | ||||
| #include <linux/i2c.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/mutex.h> | ||||
| #include <linux/slab.h> | ||||
|  | ||||
| #include <linux/dvb/frontend.h> | ||||
|  | ||||
| #include "dvbdev.h" | ||||
|  | ||||
| /* | ||||
|  * Maximum number of Delivery systems per frontend. It | ||||
|  * should be smaller or equal to 32 | ||||
|  */ | ||||
| #define MAX_DELSYS	8 | ||||
|  | ||||
| struct dvb_frontend_tune_settings { | ||||
| 	int min_delay_ms; | ||||
| 	int step_size; | ||||
| 	int max_drift; | ||||
| }; | ||||
|  | ||||
| struct dvb_frontend; | ||||
|  | ||||
| struct dvb_tuner_info { | ||||
| 	char name[128]; | ||||
|  | ||||
| 	u32 frequency_min; | ||||
| 	u32 frequency_max; | ||||
| 	u32 frequency_step; | ||||
|  | ||||
| 	u32 bandwidth_min; | ||||
| 	u32 bandwidth_max; | ||||
| 	u32 bandwidth_step; | ||||
| }; | ||||
|  | ||||
| struct analog_parameters { | ||||
| 	unsigned int frequency; | ||||
| 	unsigned int mode; | ||||
| 	unsigned int audmode; | ||||
| 	u64 std; | ||||
| }; | ||||
|  | ||||
| enum dvbfe_modcod { | ||||
| 	DVBFE_MODCOD_DUMMY_PLFRAME	= 0, | ||||
| 	DVBFE_MODCOD_QPSK_1_4, | ||||
| 	DVBFE_MODCOD_QPSK_1_3, | ||||
| 	DVBFE_MODCOD_QPSK_2_5, | ||||
| 	DVBFE_MODCOD_QPSK_1_2, | ||||
| 	DVBFE_MODCOD_QPSK_3_5, | ||||
| 	DVBFE_MODCOD_QPSK_2_3, | ||||
| 	DVBFE_MODCOD_QPSK_3_4, | ||||
| 	DVBFE_MODCOD_QPSK_4_5, | ||||
| 	DVBFE_MODCOD_QPSK_5_6, | ||||
| 	DVBFE_MODCOD_QPSK_8_9, | ||||
| 	DVBFE_MODCOD_QPSK_9_10, | ||||
| 	DVBFE_MODCOD_8PSK_3_5, | ||||
| 	DVBFE_MODCOD_8PSK_2_3, | ||||
| 	DVBFE_MODCOD_8PSK_3_4, | ||||
| 	DVBFE_MODCOD_8PSK_5_6, | ||||
| 	DVBFE_MODCOD_8PSK_8_9, | ||||
| 	DVBFE_MODCOD_8PSK_9_10, | ||||
| 	DVBFE_MODCOD_16APSK_2_3, | ||||
| 	DVBFE_MODCOD_16APSK_3_4, | ||||
| 	DVBFE_MODCOD_16APSK_4_5, | ||||
| 	DVBFE_MODCOD_16APSK_5_6, | ||||
| 	DVBFE_MODCOD_16APSK_8_9, | ||||
| 	DVBFE_MODCOD_16APSK_9_10, | ||||
| 	DVBFE_MODCOD_32APSK_3_4, | ||||
| 	DVBFE_MODCOD_32APSK_4_5, | ||||
| 	DVBFE_MODCOD_32APSK_5_6, | ||||
| 	DVBFE_MODCOD_32APSK_8_9, | ||||
| 	DVBFE_MODCOD_32APSK_9_10, | ||||
| 	DVBFE_MODCOD_RESERVED_1, | ||||
| 	DVBFE_MODCOD_BPSK_1_3, | ||||
| 	DVBFE_MODCOD_BPSK_1_4, | ||||
| 	DVBFE_MODCOD_RESERVED_2 | ||||
| }; | ||||
|  | ||||
| enum tuner_param { | ||||
| 	DVBFE_TUNER_FREQUENCY		= (1 <<  0), | ||||
| 	DVBFE_TUNER_TUNERSTEP		= (1 <<  1), | ||||
| 	DVBFE_TUNER_IFFREQ		= (1 <<  2), | ||||
| 	DVBFE_TUNER_BANDWIDTH		= (1 <<  3), | ||||
| 	DVBFE_TUNER_REFCLOCK		= (1 <<  4), | ||||
| 	DVBFE_TUNER_IQSENSE		= (1 <<  5), | ||||
| 	DVBFE_TUNER_DUMMY		= (1 << 31) | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * ALGO_HW: (Hardware Algorithm) | ||||
|  * ---------------------------------------------------------------- | ||||
|  * Devices that support this algorithm do everything in hardware | ||||
|  * and no software support is needed to handle them. | ||||
|  * Requesting these devices to LOCK is the only thing required, | ||||
|  * device is supposed to do everything in the hardware. | ||||
|  * | ||||
|  * ALGO_SW: (Software Algorithm) | ||||
|  * ---------------------------------------------------------------- | ||||
|  * These are dumb devices, that require software to do everything | ||||
|  * | ||||
|  * ALGO_CUSTOM: (Customizable Agorithm) | ||||
|  * ---------------------------------------------------------------- | ||||
|  * Devices having this algorithm can be customized to have specific | ||||
|  * algorithms in the frontend driver, rather than simply doing a | ||||
|  * software zig-zag. In this case the zigzag maybe hardware assisted | ||||
|  * or it maybe completely done in hardware. In all cases, usage of | ||||
|  * this algorithm, in conjunction with the search and track | ||||
|  * callbacks, utilizes the driver specific algorithm. | ||||
|  * | ||||
|  * ALGO_RECOVERY: (Recovery Algorithm) | ||||
|  * ---------------------------------------------------------------- | ||||
|  * These devices have AUTO recovery capabilities from LOCK failure | ||||
|  */ | ||||
| enum dvbfe_algo { | ||||
| 	DVBFE_ALGO_HW			= (1 <<  0), | ||||
| 	DVBFE_ALGO_SW			= (1 <<  1), | ||||
| 	DVBFE_ALGO_CUSTOM		= (1 <<  2), | ||||
| 	DVBFE_ALGO_RECOVERY		= (1 << 31) | ||||
| }; | ||||
|  | ||||
| struct tuner_state { | ||||
| 	u32 frequency; | ||||
| 	u32 tunerstep; | ||||
| 	u32 ifreq; | ||||
| 	u32 bandwidth; | ||||
| 	u32 iqsense; | ||||
| 	u32 refclock; | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * search callback possible return status | ||||
|  * | ||||
|  * DVBFE_ALGO_SEARCH_SUCCESS | ||||
|  * The frontend search algorithm completed and returned successfully | ||||
|  * | ||||
|  * DVBFE_ALGO_SEARCH_ASLEEP | ||||
|  * The frontend search algorithm is sleeping | ||||
|  * | ||||
|  * DVBFE_ALGO_SEARCH_FAILED | ||||
|  * The frontend search for a signal failed | ||||
|  * | ||||
|  * DVBFE_ALGO_SEARCH_INVALID | ||||
|  * The frontend search algorith was probably supplied with invalid | ||||
|  * parameters and the search is an invalid one | ||||
|  * | ||||
|  * DVBFE_ALGO_SEARCH_ERROR | ||||
|  * The frontend search algorithm failed due to some error | ||||
|  * | ||||
|  * DVBFE_ALGO_SEARCH_AGAIN | ||||
|  * The frontend search algorithm was requested to search again | ||||
|  */ | ||||
| enum dvbfe_search { | ||||
| 	DVBFE_ALGO_SEARCH_SUCCESS	= (1 <<  0), | ||||
| 	DVBFE_ALGO_SEARCH_ASLEEP	= (1 <<  1), | ||||
| 	DVBFE_ALGO_SEARCH_FAILED	= (1 <<  2), | ||||
| 	DVBFE_ALGO_SEARCH_INVALID	= (1 <<  3), | ||||
| 	DVBFE_ALGO_SEARCH_AGAIN		= (1 <<  4), | ||||
| 	DVBFE_ALGO_SEARCH_ERROR		= (1 << 31), | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct dvb_tuner_ops { | ||||
|  | ||||
| 	struct dvb_tuner_info info; | ||||
|  | ||||
| 	int (*release)(struct dvb_frontend *fe); | ||||
| 	int (*init)(struct dvb_frontend *fe); | ||||
| 	int (*sleep)(struct dvb_frontend *fe); | ||||
|  | ||||
| 	/** This is for simple PLLs - set all parameters in one go. */ | ||||
| 	int (*set_params)(struct dvb_frontend *fe); | ||||
| 	int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p); | ||||
|  | ||||
| 	/** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */ | ||||
| 	int (*calc_regs)(struct dvb_frontend *fe, u8 *buf, int buf_len); | ||||
|  | ||||
| 	/** This is to allow setting tuner-specific configs */ | ||||
| 	int (*set_config)(struct dvb_frontend *fe, void *priv_cfg); | ||||
|  | ||||
| 	int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency); | ||||
| 	int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); | ||||
| 	int (*get_if_frequency)(struct dvb_frontend *fe, u32 *frequency); | ||||
|  | ||||
| #define TUNER_STATUS_LOCKED 1 | ||||
| #define TUNER_STATUS_STEREO 2 | ||||
| 	int (*get_status)(struct dvb_frontend *fe, u32 *status); | ||||
| 	int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength); | ||||
| 	int (*get_afc)(struct dvb_frontend *fe, s32 *afc); | ||||
|  | ||||
| 	/** These are provided separately from set_params in order to facilitate silicon | ||||
| 	 * tuners which require sophisticated tuning loops, controlling each parameter separately. */ | ||||
| 	int (*set_frequency)(struct dvb_frontend *fe, u32 frequency); | ||||
| 	int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth); | ||||
|  | ||||
| 	/* | ||||
| 	 * These are provided separately from set_params in order to facilitate silicon | ||||
| 	 * tuners which require sophisticated tuning loops, controlling each parameter separately. | ||||
| 	 */ | ||||
| 	int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); | ||||
| 	int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); | ||||
| }; | ||||
|  | ||||
| struct analog_demod_info { | ||||
| 	char *name; | ||||
| }; | ||||
|  | ||||
| struct analog_demod_ops { | ||||
|  | ||||
| 	struct analog_demod_info info; | ||||
|  | ||||
| 	void (*set_params)(struct dvb_frontend *fe, | ||||
| 			   struct analog_parameters *params); | ||||
| 	int  (*has_signal)(struct dvb_frontend *fe, u16 *signal); | ||||
| 	int  (*get_afc)(struct dvb_frontend *fe, s32 *afc); | ||||
| 	void (*tuner_status)(struct dvb_frontend *fe); | ||||
| 	void (*standby)(struct dvb_frontend *fe); | ||||
| 	void (*release)(struct dvb_frontend *fe); | ||||
| 	int  (*i2c_gate_ctrl)(struct dvb_frontend *fe, int enable); | ||||
|  | ||||
| 	/** This is to allow setting tuner-specific configuration */ | ||||
| 	int (*set_config)(struct dvb_frontend *fe, void *priv_cfg); | ||||
| }; | ||||
|  | ||||
| struct dtv_frontend_properties; | ||||
|  | ||||
| struct dvb_frontend_ops { | ||||
|  | ||||
| 	struct dvb_frontend_info info; | ||||
|  | ||||
| 	u8 delsys[MAX_DELSYS]; | ||||
|  | ||||
| 	void (*release)(struct dvb_frontend* fe); | ||||
| 	void (*release_sec)(struct dvb_frontend* fe); | ||||
|  | ||||
| 	int (*init)(struct dvb_frontend* fe); | ||||
| 	int (*sleep)(struct dvb_frontend* fe); | ||||
|  | ||||
| 	int (*write)(struct dvb_frontend* fe, const u8 buf[], int len); | ||||
|  | ||||
| 	/* if this is set, it overrides the default swzigzag */ | ||||
| 	int (*tune)(struct dvb_frontend* fe, | ||||
| 		    bool re_tune, | ||||
| 		    unsigned int mode_flags, | ||||
| 		    unsigned int *delay, | ||||
| 		    fe_status_t *status); | ||||
| 	/* get frontend tuning algorithm from the module */ | ||||
| 	enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe); | ||||
|  | ||||
| 	/* these two are only used for the swzigzag code */ | ||||
| 	int (*set_frontend)(struct dvb_frontend *fe); | ||||
| 	int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings); | ||||
|  | ||||
| 	int (*get_frontend)(struct dvb_frontend *fe); | ||||
|  | ||||
| 	int (*read_status)(struct dvb_frontend* fe, fe_status_t* status); | ||||
| 	int (*read_ber)(struct dvb_frontend* fe, u32* ber); | ||||
| 	int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength); | ||||
| 	int (*read_snr)(struct dvb_frontend* fe, u16* snr); | ||||
| 	int (*read_ucblocks)(struct dvb_frontend* fe, u32* ucblocks); | ||||
|  | ||||
| 	int (*diseqc_reset_overload)(struct dvb_frontend* fe); | ||||
| 	int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd); | ||||
| 	int (*diseqc_recv_slave_reply)(struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply); | ||||
| 	int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd); | ||||
| 	int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); | ||||
| 	int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); | ||||
| 	int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg); | ||||
| 	int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd); | ||||
| 	int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable); | ||||
| 	int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire); | ||||
| 	int (*set_lna)(struct dvb_frontend *); | ||||
| 	int (*set_input)(struct dvb_frontend *, int); | ||||
|  | ||||
| 	/* These callbacks are for devices that implement their own | ||||
| 	 * tuning algorithms, rather than a simple swzigzag | ||||
| 	 */ | ||||
| 	enum dvbfe_search (*search)(struct dvb_frontend *fe); | ||||
|  | ||||
| 	struct dvb_tuner_ops tuner_ops; | ||||
| 	struct analog_demod_ops analog_ops; | ||||
|  | ||||
| 	int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp); | ||||
| 	int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp); | ||||
|  | ||||
| 	u8 xbar[3]; | ||||
| }; | ||||
|  | ||||
| #ifdef __DVB_CORE__ | ||||
| #define MAX_EVENT 8 | ||||
|  | ||||
| struct dvb_fe_events { | ||||
| 	struct dvb_frontend_event events[MAX_EVENT]; | ||||
| 	int			  eventw; | ||||
| 	int			  eventr; | ||||
| 	int			  overflow; | ||||
| 	wait_queue_head_t	  wait_queue; | ||||
| 	struct mutex		  mtx; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| struct dtv_frontend_properties { | ||||
|  | ||||
| 	/* Cache State */ | ||||
| 	u32			state; | ||||
|  | ||||
| 	u32			frequency; | ||||
| 	fe_modulation_t		modulation; | ||||
|  | ||||
| 	fe_sec_voltage_t	voltage; | ||||
| 	fe_sec_tone_mode_t	sectone; | ||||
| 	fe_spectral_inversion_t	inversion; | ||||
| 	fe_code_rate_t		fec_inner; | ||||
| 	fe_transmit_mode_t	transmission_mode; | ||||
| 	u32			bandwidth_hz;	/* 0 = AUTO */ | ||||
| 	fe_guard_interval_t	guard_interval; | ||||
| 	fe_hierarchy_t		hierarchy; | ||||
| 	u32			symbol_rate; | ||||
| 	fe_code_rate_t		code_rate_HP; | ||||
| 	fe_code_rate_t		code_rate_LP; | ||||
|  | ||||
| 	fe_pilot_t		pilot; | ||||
| 	fe_rolloff_t		rolloff; | ||||
|  | ||||
| 	fe_delivery_system_t	delivery_system; | ||||
|  | ||||
| 	enum fe_interleaving	interleaving; | ||||
|  | ||||
| 	/* ISDB-T specifics */ | ||||
| 	u8			isdbt_partial_reception; | ||||
| 	u8			isdbt_sb_mode; | ||||
| 	u8			isdbt_sb_subchannel; | ||||
| 	u32			isdbt_sb_segment_idx; | ||||
| 	u32			isdbt_sb_segment_count; | ||||
| 	u8			isdbt_layer_enabled; | ||||
| 	struct { | ||||
| 	    u8			segment_count; | ||||
| 	    fe_code_rate_t	fec; | ||||
| 	    fe_modulation_t	modulation; | ||||
| 	    u8			interleaving; | ||||
| 	} layer[3]; | ||||
|  | ||||
| 	/* Multistream specifics */ | ||||
| 	u32			stream_id; | ||||
|  | ||||
| 	/* ATSC-MH specifics */ | ||||
| 	u8			atscmh_fic_ver; | ||||
| 	u8			atscmh_parade_id; | ||||
| 	u8			atscmh_nog; | ||||
| 	u8			atscmh_tnog; | ||||
| 	u8			atscmh_sgn; | ||||
| 	u8			atscmh_prc; | ||||
|  | ||||
| 	u8			atscmh_rs_frame_mode; | ||||
| 	u8			atscmh_rs_frame_ensemble; | ||||
| 	u8			atscmh_rs_code_mode_pri; | ||||
| 	u8			atscmh_rs_code_mode_sec; | ||||
| 	u8			atscmh_sccc_block_mode; | ||||
| 	u8			atscmh_sccc_code_mode_a; | ||||
| 	u8			atscmh_sccc_code_mode_b; | ||||
| 	u8			atscmh_sccc_code_mode_c; | ||||
| 	u8			atscmh_sccc_code_mode_d; | ||||
|  | ||||
| 	u32			lna; | ||||
| 	s32                     input; | ||||
| 	 | ||||
| 	/* statistics data */ | ||||
| 	struct dtv_fe_stats	strength; | ||||
| 	struct dtv_fe_stats	cnr; | ||||
| 	struct dtv_fe_stats	pre_bit_error; | ||||
| 	struct dtv_fe_stats	pre_bit_count; | ||||
| 	struct dtv_fe_stats	post_bit_error; | ||||
| 	struct dtv_fe_stats	post_bit_count; | ||||
| 	struct dtv_fe_stats	block_error; | ||||
| 	struct dtv_fe_stats	block_count; | ||||
| }; | ||||
|  | ||||
| struct dvb_frontend { | ||||
| 	struct dvb_frontend_ops ops; | ||||
| 	struct dvb_adapter *dvb; | ||||
| 	void *demodulator_priv; | ||||
| 	void *tuner_priv; | ||||
| 	void *frontend_priv; | ||||
| 	void *sec_priv; | ||||
| 	void *analog_demod_priv; | ||||
| 	struct dtv_frontend_properties dtv_property_cache; | ||||
| #define DVB_FRONTEND_COMPONENT_TUNER 0 | ||||
| #define DVB_FRONTEND_COMPONENT_DEMOD 1 | ||||
| 	int (*callback)(void *adapter_priv, int component, int cmd, int arg); | ||||
| 	int id; | ||||
| }; | ||||
|  | ||||
| extern int dvb_register_frontend(struct dvb_adapter *dvb, | ||||
| 				 struct dvb_frontend *fe); | ||||
|  | ||||
| extern int dvb_unregister_frontend(struct dvb_frontend *fe); | ||||
|  | ||||
| extern void dvb_frontend_detach(struct dvb_frontend *fe); | ||||
|  | ||||
| extern void dvb_frontend_reinitialise(struct dvb_frontend *fe); | ||||
| extern int dvb_frontend_suspend(struct dvb_frontend *fe); | ||||
| extern int dvb_frontend_resume(struct dvb_frontend *fe); | ||||
|  | ||||
| extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec); | ||||
| extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										145
									
								
								dvb-core/dvb_math.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								dvb-core/dvb_math.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,145 @@ | ||||
| /* | ||||
|  * dvb-math provides some complex fixed-point math | ||||
|  * operations shared between the dvb related stuff | ||||
|  * | ||||
|  * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com) | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Lesser General Public License as | ||||
|  * published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||
|  */ | ||||
|  | ||||
| #include <linux/bitops.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <asm/bug.h> | ||||
| #include "dvb_math.h" | ||||
|  | ||||
| static const unsigned short logtable[256] = { | ||||
| 	0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7, | ||||
| 	0x0b5d, 0x0cc3, 0x0e27, 0x0f8a, 0x10eb, 0x124b, 0x13aa, 0x1508, | ||||
| 	0x1664, 0x17bf, 0x1919, 0x1a71, 0x1bc8, 0x1d1e, 0x1e73, 0x1fc6, | ||||
| 	0x2119, 0x226a, 0x23ba, 0x2508, 0x2656, 0x27a2, 0x28ed, 0x2a37, | ||||
| 	0x2b80, 0x2cc8, 0x2e0f, 0x2f54, 0x3098, 0x31dc, 0x331e, 0x345f, | ||||
| 	0x359f, 0x36de, 0x381b, 0x3958, 0x3a94, 0x3bce, 0x3d08, 0x3e41, | ||||
| 	0x3f78, 0x40af, 0x41e4, 0x4319, 0x444c, 0x457f, 0x46b0, 0x47e1, | ||||
| 	0x4910, 0x4a3f, 0x4b6c, 0x4c99, 0x4dc5, 0x4eef, 0x5019, 0x5142, | ||||
| 	0x526a, 0x5391, 0x54b7, 0x55dc, 0x5700, 0x5824, 0x5946, 0x5a68, | ||||
| 	0x5b89, 0x5ca8, 0x5dc7, 0x5ee5, 0x6003, 0x611f, 0x623a, 0x6355, | ||||
| 	0x646f, 0x6588, 0x66a0, 0x67b7, 0x68ce, 0x69e4, 0x6af8, 0x6c0c, | ||||
| 	0x6d20, 0x6e32, 0x6f44, 0x7055, 0x7165, 0x7274, 0x7383, 0x7490, | ||||
| 	0x759d, 0x76aa, 0x77b5, 0x78c0, 0x79ca, 0x7ad3, 0x7bdb, 0x7ce3, | ||||
| 	0x7dea, 0x7ef0, 0x7ff6, 0x80fb, 0x81ff, 0x8302, 0x8405, 0x8507, | ||||
| 	0x8608, 0x8709, 0x8809, 0x8908, 0x8a06, 0x8b04, 0x8c01, 0x8cfe, | ||||
| 	0x8dfa, 0x8ef5, 0x8fef, 0x90e9, 0x91e2, 0x92db, 0x93d2, 0x94ca, | ||||
| 	0x95c0, 0x96b6, 0x97ab, 0x98a0, 0x9994, 0x9a87, 0x9b7a, 0x9c6c, | ||||
| 	0x9d5e, 0x9e4f, 0x9f3f, 0xa02e, 0xa11e, 0xa20c, 0xa2fa, 0xa3e7, | ||||
| 	0xa4d4, 0xa5c0, 0xa6ab, 0xa796, 0xa881, 0xa96a, 0xaa53, 0xab3c, | ||||
| 	0xac24, 0xad0c, 0xadf2, 0xaed9, 0xafbe, 0xb0a4, 0xb188, 0xb26c, | ||||
| 	0xb350, 0xb433, 0xb515, 0xb5f7, 0xb6d9, 0xb7ba, 0xb89a, 0xb97a, | ||||
| 	0xba59, 0xbb38, 0xbc16, 0xbcf4, 0xbdd1, 0xbead, 0xbf8a, 0xc065, | ||||
| 	0xc140, 0xc21b, 0xc2f5, 0xc3cf, 0xc4a8, 0xc580, 0xc658, 0xc730, | ||||
| 	0xc807, 0xc8de, 0xc9b4, 0xca8a, 0xcb5f, 0xcc34, 0xcd08, 0xcddc, | ||||
| 	0xceaf, 0xcf82, 0xd054, 0xd126, 0xd1f7, 0xd2c8, 0xd399, 0xd469, | ||||
| 	0xd538, 0xd607, 0xd6d6, 0xd7a4, 0xd872, 0xd93f, 0xda0c, 0xdad9, | ||||
| 	0xdba5, 0xdc70, 0xdd3b, 0xde06, 0xded0, 0xdf9a, 0xe063, 0xe12c, | ||||
| 	0xe1f5, 0xe2bd, 0xe385, 0xe44c, 0xe513, 0xe5d9, 0xe69f, 0xe765, | ||||
| 	0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83, | ||||
| 	0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387, | ||||
| 	0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973, | ||||
| 	0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47 | ||||
| }; | ||||
|  | ||||
| unsigned int intlog2(u32 value) | ||||
| { | ||||
| 	/** | ||||
| 	 *	returns: log2(value) * 2^24 | ||||
| 	 *	wrong result if value = 0 (log2(0) is undefined) | ||||
| 	 */ | ||||
| 	unsigned int msb; | ||||
| 	unsigned int logentry; | ||||
| 	unsigned int significand; | ||||
| 	unsigned int interpolation; | ||||
|  | ||||
| 	if (unlikely(value == 0)) { | ||||
| 		WARN_ON(1); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	/* first detect the msb (count begins at 0) */ | ||||
| 	msb = fls(value) - 1; | ||||
|  | ||||
| 	/** | ||||
| 	 *	now we use a logtable after the following method: | ||||
| 	 * | ||||
| 	 *	log2(2^x * y) * 2^24 = x * 2^24 + log2(y) * 2^24 | ||||
| 	 *	where x = msb and therefore 1 <= y < 2 | ||||
| 	 *	first y is determined by shifting the value left | ||||
| 	 *	so that msb is bit 31 | ||||
| 	 *		0x00231f56 -> 0x8C7D5800 | ||||
| 	 *	the result is y * 2^31 -> "significand" | ||||
| 	 *	then the highest 9 bits are used for a table lookup | ||||
| 	 *	the highest bit is discarded because it's always set | ||||
| 	 *	the highest nine bits in our example are 100011000 | ||||
| 	 *	so we would use the entry 0x18 | ||||
| 	 */ | ||||
| 	significand = value << (31 - msb); | ||||
| 	logentry = (significand >> 23) & 0xff; | ||||
|  | ||||
| 	/** | ||||
| 	 *	last step we do is interpolation because of the | ||||
| 	 *	limitations of the log table the error is that part of | ||||
| 	 *	the significand which isn't used for lookup then we | ||||
| 	 *	compute the ratio between the error and the next table entry | ||||
| 	 *	and interpolate it between the log table entry used and the | ||||
| 	 *	next one the biggest error possible is 0x7fffff | ||||
| 	 *	(in our example it's 0x7D5800) | ||||
| 	 *	needed value for next table entry is 0x800000 | ||||
| 	 *	so the interpolation is | ||||
| 	 *	(error / 0x800000) * (logtable_next - logtable_current) | ||||
| 	 *	in the implementation the division is moved to the end for | ||||
| 	 *	better accuracy there is also an overflow correction if | ||||
| 	 *	logtable_next is 256 | ||||
| 	 */ | ||||
| 	interpolation = ((significand & 0x7fffff) * | ||||
| 			((logtable[(logentry + 1) & 0xff] - | ||||
| 			  logtable[logentry]) & 0xffff)) >> 15; | ||||
|  | ||||
| 	/* now we return the result */ | ||||
| 	return ((msb << 24) + (logtable[logentry] << 8) + interpolation); | ||||
| } | ||||
| EXPORT_SYMBOL(intlog2); | ||||
|  | ||||
| unsigned int intlog10(u32 value) | ||||
| { | ||||
| 	/** | ||||
| 	 *	returns: log10(value) * 2^24 | ||||
| 	 *	wrong result if value = 0 (log10(0) is undefined) | ||||
| 	 */ | ||||
| 	u64 log; | ||||
|  | ||||
| 	if (unlikely(value == 0)) { | ||||
| 		WARN_ON(1); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	log = intlog2(value); | ||||
|  | ||||
| 	/** | ||||
| 	 *	we use the following method: | ||||
| 	 *	log10(x) = log2(x) * log10(2) | ||||
| 	 */ | ||||
|  | ||||
| 	return (log * 646456993) >> 31; | ||||
| } | ||||
| EXPORT_SYMBOL(intlog10); | ||||
							
								
								
									
										58
									
								
								dvb-core/dvb_math.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								dvb-core/dvb_math.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| /* | ||||
|  * dvb-math provides some complex fixed-point math | ||||
|  * operations shared between the dvb related stuff | ||||
|  * | ||||
|  * Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com) | ||||
|  * | ||||
|  * This library is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Lesser General Public License as | ||||
|  * published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public | ||||
|  * License along with this library; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||
|  */ | ||||
|  | ||||
| #ifndef __DVB_MATH_H | ||||
| #define __DVB_MATH_H | ||||
|  | ||||
| #include <linux/types.h> | ||||
|  | ||||
| /** | ||||
|  * computes log2 of a value; the result is shifted left by 24 bits | ||||
|  * | ||||
|  * to use rational values you can use the following method: | ||||
|  *   intlog2(value) = intlog2(value * 2^x) - x * 2^24 | ||||
|  * | ||||
|  * example: intlog2(8) will give 3 << 24 = 3 * 2^24 | ||||
|  * example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24 | ||||
|  * example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24 | ||||
|  * | ||||
|  * @param value The value (must be != 0) | ||||
|  * @return log2(value) * 2^24 | ||||
|  */ | ||||
| extern unsigned int intlog2(u32 value); | ||||
|  | ||||
| /** | ||||
|  * computes log10 of a value; the result is shifted left by 24 bits | ||||
|  * | ||||
|  * to use rational values you can use the following method: | ||||
|  *   intlog10(value) = intlog10(value * 10^x) - x * 2^24 | ||||
|  * | ||||
|  * example: intlog10(1000) will give 3 << 24 = 3 * 2^24 | ||||
|  *   due to the implementation intlog10(1000) might be not exactly 3 * 2^24 | ||||
|  * | ||||
|  * look at intlog2 for similar examples | ||||
|  * | ||||
|  * @param value The value (must be != 0) | ||||
|  * @return log10(value) * 2^24 | ||||
|  */ | ||||
| extern unsigned int intlog10(u32 value); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										1547
									
								
								dvb-core/dvb_net.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1547
									
								
								dvb-core/dvb_net.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										67
									
								
								dvb-core/dvb_net.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								dvb-core/dvb_net.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| /* | ||||
|  * dvb_net.h | ||||
|  * | ||||
|  * Copyright (C) 2001 Ralph Metzler for convergence integrated media GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef _DVB_NET_H_ | ||||
| #define _DVB_NET_H_ | ||||
|  | ||||
| #include <linux/module.h> | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/inetdevice.h> | ||||
| #include <linux/etherdevice.h> | ||||
| #include <linux/skbuff.h> | ||||
|  | ||||
| #include "dvbdev.h" | ||||
|  | ||||
| #define DVB_NET_DEVICES_MAX 10 | ||||
|  | ||||
| #ifdef CONFIG_DVB_NET | ||||
|  | ||||
| struct dvb_net { | ||||
| 	struct dvb_device *dvbdev; | ||||
| 	struct net_device *device[DVB_NET_DEVICES_MAX]; | ||||
| 	int state[DVB_NET_DEVICES_MAX]; | ||||
| 	unsigned int exit:1; | ||||
| 	struct dmx_demux *demux; | ||||
| 	struct mutex ioctl_mutex; | ||||
| }; | ||||
|  | ||||
| void dvb_net_release(struct dvb_net *); | ||||
| int  dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *); | ||||
|  | ||||
| #else | ||||
|  | ||||
| struct dvb_net { | ||||
| 	struct dvb_device *dvbdev; | ||||
| }; | ||||
|  | ||||
| static inline void dvb_net_release(struct dvb_net *dvbnet) | ||||
| { | ||||
| } | ||||
|  | ||||
| static inline int dvb_net_init(struct dvb_adapter *adap, | ||||
| 			       struct dvb_net *dvbnet, struct dmx_demux *dmx) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #endif /* ifdef CONFIG_DVB_NET */ | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										259
									
								
								dvb-core/dvb_netstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								dvb-core/dvb_netstream.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,259 @@ | ||||
| /* | ||||
|  * dvb_netstream.c: support for DVB to network streaming hardware | ||||
|  * | ||||
|  * Copyright (C) 2012-2013 Marcus and Ralph Metzler | ||||
|  *                         for Digital Devices GmbH | ||||
|  *                          | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| #include <linux/net.h> | ||||
| #include "dvb_netstream.h" | ||||
|  | ||||
| static ssize_t ns_write(struct file *file, const char *buf, | ||||
| 			size_t count, loff_t *ppos) | ||||
| { | ||||
| 	pr_info("%s\n", __func__); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static ssize_t ns_read(struct file *file, char *buf, | ||||
| 		       size_t count, loff_t *ppos) | ||||
| { | ||||
| 	pr_info("%s\n", __func__); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static unsigned int ns_poll(struct file *file, poll_table *wait) | ||||
| { | ||||
| 	pr_info("%s\n", __func__); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int ns_stop(struct dvbnss *nss) | ||||
| { | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
|  | ||||
| 	mutex_lock(&ns->mutex); | ||||
| 	if (nss->running && ns->stop) { | ||||
| 		ns->stop(nss); | ||||
| 		nss->running = 0; | ||||
| 	} | ||||
| 	mutex_unlock(&ns->mutex); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int ns_release(struct inode *inode, struct file *file) | ||||
| { | ||||
| 	struct dvbnss *nss = file->private_data; | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
|  | ||||
| 	ns_stop(nss); | ||||
| 	if (ns->free) | ||||
| 		ns->free(nss); | ||||
| 	mutex_lock(&ns->mutex); | ||||
| 	list_del(&nss->nssl); | ||||
| 	mutex_unlock(&ns->mutex); | ||||
| 	vfree(nss); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int ns_open(struct inode *inode, struct file *file) | ||||
| { | ||||
| 	struct dvb_device *dvbdev = file->private_data; | ||||
| 	struct dvb_netstream *ns = dvbdev->priv; | ||||
| 	struct dvbnss *nss; | ||||
|  | ||||
| 	nss = vmalloc(sizeof(*nss)); | ||||
| 	if (!nss) | ||||
| 		return -ENOMEM; | ||||
| 	nss->ns = ns; | ||||
| 	if (ns->alloc && ns->alloc(nss) < 0) { | ||||
| 		vfree(nss); | ||||
| 		return -EBUSY; | ||||
| 	} | ||||
| 	file->private_data = nss; | ||||
| 	nss->running = 0; | ||||
| 	mutex_lock(&ns->mutex); | ||||
| 	list_add(&nss->nssl, &ns->nssl); | ||||
| 	mutex_unlock(&ns->mutex); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int set_net(struct dvbnss *nss, struct dvb_ns_params *p) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int do_ioctl(struct file *file, unsigned int cmd, void *parg) | ||||
| { | ||||
| 	struct dvbnss *nss = file->private_data; | ||||
| 	struct dvb_netstream *ns = nss->ns; | ||||
| 	/*unsigned long arg = (unsigned long) parg;*/ | ||||
| 	int ret = 0; | ||||
|  | ||||
| 	switch (cmd) { | ||||
| 	case NS_SET_RTCP_MSG: | ||||
| 	{ | ||||
| 		struct dvb_ns_rtcp *rtcpm = parg; | ||||
|  | ||||
| 		if (ns->set_rtcp_msg) | ||||
| 			ret = ns->set_rtcp_msg(nss, rtcpm->msg, rtcpm->len); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	case NS_SET_NET: | ||||
| 		memcpy(&nss->params, parg, sizeof(nss->params)); | ||||
| 		if (ns->set_net) | ||||
| 			ret = ns->set_net(nss); | ||||
| 		else | ||||
| 			ret = set_net(nss, (struct dvb_ns_params *) parg); | ||||
| 		break; | ||||
|  | ||||
| 	case NS_START: | ||||
| 		mutex_lock(&ns->mutex); | ||||
| 		if (nss->running) { | ||||
| 			ret = -EBUSY; | ||||
| 		} else if (ns->start) { | ||||
| 			ret = ns->start(nss); | ||||
| 			nss->running = 1; | ||||
| 		} | ||||
| 		mutex_unlock(&ns->mutex); | ||||
| 		break; | ||||
|  | ||||
| 	case NS_STOP: | ||||
| 		ns_stop(nss); | ||||
| 		break; | ||||
|  | ||||
| 	case NS_SET_PACKETS: | ||||
| 	{ | ||||
| 		struct dvb_ns_packet *packet =  parg; | ||||
|  | ||||
| 		if (ns->set_ts_packets) | ||||
| 			ret = ns->set_ts_packets(nss, packet->buf, | ||||
| 						 packet->count * 188); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	case NS_INSERT_PACKETS: | ||||
| 	{ | ||||
| 		u8 count = *(u8 *) parg; | ||||
|  | ||||
| 		if (ns->insert_ts_packets) | ||||
| 			ret = ns->insert_ts_packets(nss, count); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	case NS_SET_PID: | ||||
| 	{ | ||||
| 		u16 pid = *(u16 *) parg; | ||||
| 		u16 byte = (pid & 0x1fff) >> 3; | ||||
| 		u8 bit = 1 << (pid & 7); | ||||
|  | ||||
| 		if (pid & 0x2000) { | ||||
| 			if (pid & 0x8000) | ||||
| 				memset(nss->pids, 0xff, 0x400); | ||||
| 			else | ||||
| 				memset(nss->pids, 0x00, 0x400); | ||||
| 		} else { | ||||
| 			if (pid & 0x8000) | ||||
| 				nss->pids[byte] |= bit; | ||||
| 			else | ||||
| 				nss->pids[byte] &= ~bit; | ||||
| 		} | ||||
| 		if (ns->set_pid) | ||||
| 			ret = ns->set_pid(nss, pid); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	case NS_SET_PIDS: | ||||
| 		ret = copy_from_user(nss->pids, *(u8 **) parg, 0x400); | ||||
| 		if (ret < 0) | ||||
| 			return ret; | ||||
| 		if (ns->set_pids) | ||||
| 			ret = ns->set_pids(nss); | ||||
| 		break; | ||||
|  | ||||
| 	case NS_SET_CI: | ||||
| 	{ | ||||
| 		u8 ci = *(u8 *) parg; | ||||
|  | ||||
| 		if (nss->running) | ||||
| 			ret = -EBUSY; | ||||
| 		else if (ns->set_ci) | ||||
| 			ret = ns->set_ci(nss, ci); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	default: | ||||
| 		ret = -EINVAL; | ||||
| 		break; | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| static long ns_ioctl(struct file *file, | ||||
| 		     unsigned int cmd, unsigned long arg) | ||||
| { | ||||
| 	return dvb_usercopy(file, cmd, arg, do_ioctl); | ||||
| } | ||||
|  | ||||
| static const struct file_operations ns_fops = { | ||||
| 	.owner   = THIS_MODULE, | ||||
| 	.read    = ns_read, | ||||
| 	.write   = ns_write, | ||||
| 	.open    = ns_open, | ||||
| 	.release = ns_release, | ||||
| 	.poll    = ns_poll, | ||||
| 	.mmap    = 0, | ||||
| 	.unlocked_ioctl = ns_ioctl, | ||||
| }; | ||||
|  | ||||
| static struct dvb_device ns_dev = { | ||||
| 	.priv    = 0, | ||||
| 	.readers = 1, | ||||
| 	.writers = 1, | ||||
| 	.users   = 1, | ||||
| 	.fops    = &ns_fops, | ||||
| }; | ||||
|  | ||||
|  | ||||
| int dvb_netstream_init(struct dvb_adapter *dvb_adapter, | ||||
| 		       struct dvb_netstream *ns) | ||||
| { | ||||
| 	mutex_init(&ns->mutex); | ||||
| 	spin_lock_init(&ns->lock); | ||||
| 	ns->exit = 0; | ||||
| 	dvb_register_device(dvb_adapter, &ns->dvbdev, &ns_dev, ns, | ||||
| 			    DVB_DEVICE_NS); | ||||
| 	INIT_LIST_HEAD(&ns->nssl); | ||||
| 	return 0; | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_netstream_init); | ||||
|  | ||||
| void dvb_netstream_release(struct dvb_netstream *ns) | ||||
| { | ||||
| 	ns->exit = 1; | ||||
| 	if (ns->dvbdev->users > 1) { | ||||
| 		wait_event(ns->dvbdev->wait_queue, | ||||
| 			   ns->dvbdev->users == 1); | ||||
| 	} | ||||
| 	dvb_unregister_device(ns->dvbdev); | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_netstream_release); | ||||
							
								
								
									
										93
									
								
								dvb-core/dvb_netstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								dvb-core/dvb_netstream.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| /* | ||||
|  * dvb_netstream.c: support for DVB to network streaming hardware | ||||
|  * | ||||
|  * Copyright (C) 2012-2013 Marcus and Ralph Metzler | ||||
|  *                         for Digital Devices GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| #ifndef _DVB_NETSTREAM_H_ | ||||
| #define _DVB_NETSTREAM_H_ | ||||
|  | ||||
| #include <linux/sched.h> | ||||
| #include <linux/spinlock.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/vmalloc.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/poll.h> | ||||
| #include <linux/ioctl.h> | ||||
| #include <linux/wait.h> | ||||
| #include <linux/socket.h> | ||||
| #include <linux/in.h> | ||||
| #include <asm/uaccess.h> | ||||
| #include <linux/dvb/ns.h> | ||||
|  | ||||
| #include "dvbdev.h" | ||||
|  | ||||
| #define DVBNS_MAXPIDS 32 | ||||
|  | ||||
| struct dvbnss { | ||||
| 	struct dvb_netstream *ns; | ||||
| 	void *priv; | ||||
|  | ||||
| 	u8  pids[1024]; | ||||
| 	u8  packet[1328]; | ||||
| 	u32 pp; | ||||
|  | ||||
| 	struct socket *sock; | ||||
| 	struct sockaddr_in sadr; | ||||
| 	u32    sn; | ||||
|  | ||||
| 	struct dvb_ns_params params; | ||||
|  | ||||
| 	struct list_head nssl; | ||||
| 	int                running; | ||||
| }; | ||||
|  | ||||
| #define MAX_DVBNSS 32 | ||||
|  | ||||
| struct dvb_netstream { | ||||
| 	void              *priv; | ||||
|  | ||||
| 	struct mutex       mutex; | ||||
| 	spinlock_t         lock; | ||||
| 	struct dvb_device *dvbdev; | ||||
| 	int                exit; | ||||
|  | ||||
| 	struct list_head nssl; | ||||
|  | ||||
| 	int (*set_net)(struct dvbnss *); | ||||
| 	int (*set_pid)(struct dvbnss *, u16); | ||||
| 	int (*set_pids)(struct dvbnss *); | ||||
| 	int (*set_ci)(struct dvbnss *, u8); | ||||
| 	int (*set_rtcp_msg)(struct dvbnss *, u8 *, u32); | ||||
| 	int (*set_ts_packets)(struct dvbnss *, u8 *, u32); | ||||
| 	int (*insert_ts_packets)(struct dvbnss *, u8); | ||||
| 	int (*start)(struct dvbnss *); | ||||
| 	int (*stop)(struct dvbnss *); | ||||
| 	int (*alloc)(struct dvbnss *); | ||||
| 	void (*free)(struct dvbnss *); | ||||
| }; | ||||
|  | ||||
|  | ||||
| void dvb_netstream_release(struct dvb_netstream *); | ||||
| int  dvb_netstream_init(struct dvb_adapter *, struct dvb_netstream *); | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										299
									
								
								dvb-core/dvb_ringbuffer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								dvb-core/dvb_ringbuffer.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,299 @@ | ||||
| /* | ||||
|  * | ||||
|  * dvb_ringbuffer.c: ring buffer implementation for the dvb driver | ||||
|  * | ||||
|  * Copyright (C) 2003 Oliver Endriss | ||||
|  * Copyright (C) 2004 Andrew de Quincey | ||||
|  * | ||||
|  * based on code originally found in av7110.c & dvb_ci.c: | ||||
|  * Copyright (C) 1999-2003 Ralph  Metzler | ||||
|  *                       & Marcus Metzler for convergence integrated media GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
|  | ||||
|  | ||||
| #include <linux/errno.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/sched.h> | ||||
| #include <linux/string.h> | ||||
| #include <asm/uaccess.h> | ||||
|  | ||||
| #include "dvb_ringbuffer.h" | ||||
|  | ||||
| #define PKT_READY 0 | ||||
| #define PKT_DISPOSED 1 | ||||
|  | ||||
|  | ||||
| void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len) | ||||
| { | ||||
| 	rbuf->pread=rbuf->pwrite=0; | ||||
| 	rbuf->data=data; | ||||
| 	rbuf->size=len; | ||||
| 	rbuf->error=0; | ||||
|  | ||||
| 	init_waitqueue_head(&rbuf->queue); | ||||
|  | ||||
| 	spin_lock_init(&(rbuf->lock)); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf) | ||||
| { | ||||
| 	return (rbuf->pread==rbuf->pwrite); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf) | ||||
| { | ||||
| 	ssize_t free; | ||||
|  | ||||
| 	free = rbuf->pread - rbuf->pwrite; | ||||
| 	if (free <= 0) | ||||
| 		free += rbuf->size; | ||||
| 	return free-1; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf) | ||||
| { | ||||
| 	ssize_t avail; | ||||
|  | ||||
| 	avail = rbuf->pwrite - rbuf->pread; | ||||
| 	if (avail < 0) | ||||
| 		avail += rbuf->size; | ||||
| 	return avail; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf) | ||||
| { | ||||
| 	rbuf->pread = rbuf->pwrite; | ||||
| 	rbuf->error = 0; | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_ringbuffer_flush); | ||||
|  | ||||
| void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf) | ||||
| { | ||||
| 	rbuf->pread = rbuf->pwrite = 0; | ||||
| 	rbuf->error = 0; | ||||
| } | ||||
|  | ||||
| void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf) | ||||
| { | ||||
| 	unsigned long flags; | ||||
|  | ||||
| 	spin_lock_irqsave(&rbuf->lock, flags); | ||||
| 	dvb_ringbuffer_flush(rbuf); | ||||
| 	spin_unlock_irqrestore(&rbuf->lock, flags); | ||||
|  | ||||
| 	wake_up(&rbuf->queue); | ||||
| } | ||||
|  | ||||
| ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len) | ||||
| { | ||||
| 	size_t todo = len; | ||||
| 	size_t split; | ||||
|  | ||||
| 	split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; | ||||
| 	if (split > 0) { | ||||
| 		if (copy_to_user(buf, rbuf->data+rbuf->pread, split)) | ||||
| 			return -EFAULT; | ||||
| 		buf += split; | ||||
| 		todo -= split; | ||||
| 		rbuf->pread = 0; | ||||
| 	} | ||||
| 	if (copy_to_user(buf, rbuf->data+rbuf->pread, todo)) | ||||
| 		return -EFAULT; | ||||
|  | ||||
| 	rbuf->pread = (rbuf->pread + todo) % rbuf->size; | ||||
|  | ||||
| 	return len; | ||||
| } | ||||
|  | ||||
| void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len) | ||||
| { | ||||
| 	size_t todo = len; | ||||
| 	size_t split; | ||||
|  | ||||
| 	split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0; | ||||
| 	if (split > 0) { | ||||
| 		memcpy(buf, rbuf->data+rbuf->pread, split); | ||||
| 		buf += split; | ||||
| 		todo -= split; | ||||
| 		rbuf->pread = 0; | ||||
| 	} | ||||
| 	memcpy(buf, rbuf->data+rbuf->pread, todo); | ||||
|  | ||||
| 	rbuf->pread = (rbuf->pread + todo) % rbuf->size; | ||||
| } | ||||
|  | ||||
|  | ||||
| ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len) | ||||
| { | ||||
| 	size_t todo = len; | ||||
| 	size_t split; | ||||
|  | ||||
| 	split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0; | ||||
|  | ||||
| 	if (split > 0) { | ||||
| 		memcpy(rbuf->data+rbuf->pwrite, buf, split); | ||||
| 		buf += split; | ||||
| 		todo -= split; | ||||
| 		rbuf->pwrite = 0; | ||||
| 	} | ||||
| 	memcpy(rbuf->data+rbuf->pwrite, buf, todo); | ||||
| 	rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size; | ||||
|  | ||||
| 	return len; | ||||
| } | ||||
|  | ||||
| ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len) | ||||
| { | ||||
| 	int status; | ||||
| 	ssize_t oldpwrite = rbuf->pwrite; | ||||
|  | ||||
| 	DVB_RINGBUFFER_WRITE_BYTE(rbuf, len >> 8); | ||||
| 	DVB_RINGBUFFER_WRITE_BYTE(rbuf, len & 0xff); | ||||
| 	DVB_RINGBUFFER_WRITE_BYTE(rbuf, PKT_READY); | ||||
| 	status = dvb_ringbuffer_write(rbuf, buf, len); | ||||
|  | ||||
| 	if (status < 0) rbuf->pwrite = oldpwrite; | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx, | ||||
| 				int offset, u8 __user *buf, size_t len) | ||||
| { | ||||
| 	size_t todo; | ||||
| 	size_t split; | ||||
| 	size_t pktlen; | ||||
|  | ||||
| 	pktlen = rbuf->data[idx] << 8; | ||||
| 	pktlen |= rbuf->data[(idx + 1) % rbuf->size]; | ||||
| 	if (offset > pktlen) return -EINVAL; | ||||
| 	if ((offset + len) > pktlen) len = pktlen - offset; | ||||
|  | ||||
| 	idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size; | ||||
| 	todo = len; | ||||
| 	split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; | ||||
| 	if (split > 0) { | ||||
| 		if (copy_to_user(buf, rbuf->data+idx, split)) | ||||
| 			return -EFAULT; | ||||
| 		buf += split; | ||||
| 		todo -= split; | ||||
| 		idx = 0; | ||||
| 	} | ||||
| 	if (copy_to_user(buf, rbuf->data+idx, todo)) | ||||
| 		return -EFAULT; | ||||
|  | ||||
| 	return len; | ||||
| } | ||||
|  | ||||
| ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | ||||
| 				int offset, u8* buf, size_t len) | ||||
| { | ||||
| 	size_t todo; | ||||
| 	size_t split; | ||||
| 	size_t pktlen; | ||||
|  | ||||
| 	pktlen = rbuf->data[idx] << 8; | ||||
| 	pktlen |= rbuf->data[(idx + 1) % rbuf->size]; | ||||
| 	if (offset > pktlen) return -EINVAL; | ||||
| 	if ((offset + len) > pktlen) len = pktlen - offset; | ||||
|  | ||||
| 	idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size; | ||||
| 	todo = len; | ||||
| 	split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0; | ||||
| 	if (split > 0) { | ||||
| 		memcpy(buf, rbuf->data+idx, split); | ||||
| 		buf += split; | ||||
| 		todo -= split; | ||||
| 		idx = 0; | ||||
| 	} | ||||
| 	memcpy(buf, rbuf->data+idx, todo); | ||||
| 	return len; | ||||
| } | ||||
|  | ||||
| void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx) | ||||
| { | ||||
| 	size_t pktlen; | ||||
|  | ||||
| 	rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED; | ||||
|  | ||||
| 	// clean up disposed packets | ||||
| 	while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) { | ||||
| 		if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) { | ||||
| 			pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8; | ||||
| 			pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1); | ||||
| 			DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE); | ||||
| 		} else { | ||||
| 			// first packet is not disposed, so we stop cleaning now | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen) | ||||
| { | ||||
| 	int consumed; | ||||
| 	int curpktlen; | ||||
| 	int curpktstatus; | ||||
|  | ||||
| 	if (idx == -1) { | ||||
| 	       idx = rbuf->pread; | ||||
| 	} else { | ||||
| 		curpktlen = rbuf->data[idx] << 8; | ||||
| 		curpktlen |= rbuf->data[(idx + 1) % rbuf->size]; | ||||
| 		idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size; | ||||
| 	} | ||||
|  | ||||
| 	consumed = (idx - rbuf->pread) % rbuf->size; | ||||
|  | ||||
| 	while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) { | ||||
|  | ||||
| 		curpktlen = rbuf->data[idx] << 8; | ||||
| 		curpktlen |= rbuf->data[(idx + 1) % rbuf->size]; | ||||
| 		curpktstatus = rbuf->data[(idx + 2) % rbuf->size]; | ||||
|  | ||||
| 		if (curpktstatus == PKT_READY) { | ||||
| 			*pktlen = curpktlen; | ||||
| 			return idx; | ||||
| 		} | ||||
|  | ||||
| 		consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE; | ||||
| 		idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size; | ||||
| 	} | ||||
|  | ||||
| 	// no packets available | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| EXPORT_SYMBOL(dvb_ringbuffer_init); | ||||
| EXPORT_SYMBOL(dvb_ringbuffer_empty); | ||||
| EXPORT_SYMBOL(dvb_ringbuffer_free); | ||||
| EXPORT_SYMBOL(dvb_ringbuffer_avail); | ||||
| EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup); | ||||
| EXPORT_SYMBOL(dvb_ringbuffer_read_user); | ||||
| EXPORT_SYMBOL(dvb_ringbuffer_read); | ||||
| EXPORT_SYMBOL(dvb_ringbuffer_write); | ||||
							
								
								
									
										186
									
								
								dvb-core/dvb_ringbuffer.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										186
									
								
								dvb-core/dvb_ringbuffer.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,186 @@ | ||||
| /* | ||||
|  * | ||||
|  * dvb_ringbuffer.h: ring buffer implementation for the dvb driver | ||||
|  * | ||||
|  * Copyright (C) 2003 Oliver Endriss | ||||
|  * Copyright (C) 2004 Andrew de Quincey | ||||
|  * | ||||
|  * based on code originally found in av7110.c & dvb_ci.c: | ||||
|  * Copyright (C) 1999-2003 Ralph Metzler & Marcus Metzler | ||||
|  *                         for convergence integrated media GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
|  */ | ||||
|  | ||||
| #ifndef _DVB_RINGBUFFER_H_ | ||||
| #define _DVB_RINGBUFFER_H_ | ||||
|  | ||||
| #include <linux/spinlock.h> | ||||
| #include <linux/wait.h> | ||||
|  | ||||
| struct dvb_ringbuffer { | ||||
| 	u8               *data; | ||||
| 	ssize_t           size; | ||||
| 	ssize_t           pread; | ||||
| 	ssize_t           pwrite; | ||||
| 	int               error; | ||||
|  | ||||
| 	wait_queue_head_t queue; | ||||
| 	spinlock_t        lock; | ||||
| }; | ||||
|  | ||||
| #define DVB_RINGBUFFER_PKTHDRSIZE 3 | ||||
|  | ||||
|  | ||||
| /* | ||||
| ** Notes: | ||||
| ** ------ | ||||
| ** (1) For performance reasons read and write routines don't check buffer sizes | ||||
| **     and/or number of bytes free/available. This has to be done before these | ||||
| **     routines are called. For example: | ||||
| ** | ||||
| **     *** write <buflen> bytes *** | ||||
| **     free = dvb_ringbuffer_free(rbuf); | ||||
| **     if (free >= buflen) | ||||
| **         count = dvb_ringbuffer_write(rbuf, buffer, buflen); | ||||
| **     else | ||||
| **         ... | ||||
| ** | ||||
| **     *** read min. 1000, max. <bufsize> bytes *** | ||||
| **     avail = dvb_ringbuffer_avail(rbuf); | ||||
| **     if (avail >= 1000) | ||||
| **         count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize)); | ||||
| **     else | ||||
| **         ... | ||||
| ** | ||||
| ** (2) If there is exactly one reader and one writer, there is no need | ||||
| **     to lock read or write operations. | ||||
| **     Two or more readers must be locked against each other. | ||||
| **     Flushing the buffer counts as a read operation. | ||||
| **     Resetting the buffer counts as a read and write operation. | ||||
| **     Two or more writers must be locked against each other. | ||||
| */ | ||||
|  | ||||
| /* initialize ring buffer, lock and queue */ | ||||
| extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len); | ||||
|  | ||||
| /* test whether buffer is empty */ | ||||
| extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf); | ||||
|  | ||||
| /* return the number of free bytes in the buffer */ | ||||
| extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf); | ||||
|  | ||||
| /* return the number of bytes waiting in the buffer */ | ||||
| extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf); | ||||
|  | ||||
|  | ||||
| /* | ||||
| ** Reset the read and write pointers to zero and flush the buffer | ||||
| ** This counts as a read and write operation | ||||
| */ | ||||
| extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf); | ||||
|  | ||||
|  | ||||
| /* read routines & macros */ | ||||
| /* ---------------------- */ | ||||
| /* flush buffer */ | ||||
| extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf); | ||||
|  | ||||
| /* flush buffer protected by spinlock and wake-up waiting task(s) */ | ||||
| extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); | ||||
|  | ||||
| /* peek at byte <offs> in the buffer */ | ||||
| #define DVB_RINGBUFFER_PEEK(rbuf,offs)	\ | ||||
| 			(rbuf)->data[((rbuf)->pread+(offs))%(rbuf)->size] | ||||
|  | ||||
| /* advance read ptr by <num> bytes */ | ||||
| #define DVB_RINGBUFFER_SKIP(rbuf,num)	\ | ||||
| 			(rbuf)->pread=((rbuf)->pread+(num))%(rbuf)->size | ||||
|  | ||||
| /* | ||||
| ** read <len> bytes from ring buffer into <buf> | ||||
| ** <usermem> specifies whether <buf> resides in user space | ||||
| ** returns number of bytes transferred or -EFAULT | ||||
| */ | ||||
| extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, | ||||
| 				   u8 __user *buf, size_t len); | ||||
| extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, | ||||
| 				   u8 *buf, size_t len); | ||||
|  | ||||
|  | ||||
| /* write routines & macros */ | ||||
| /* ----------------------- */ | ||||
| /* write single byte to ring buffer */ | ||||
| #define DVB_RINGBUFFER_WRITE_BYTE(rbuf,byte)	\ | ||||
| 			{ (rbuf)->data[(rbuf)->pwrite]=(byte); \ | ||||
| 			(rbuf)->pwrite=((rbuf)->pwrite+1)%(rbuf)->size; } | ||||
| /* | ||||
| ** write <len> bytes to ring buffer | ||||
| ** <usermem> specifies whether <buf> resides in user space | ||||
| ** returns number of bytes transferred or -EFAULT | ||||
| */ | ||||
| extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, | ||||
| 				    size_t len); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Write a packet into the ringbuffer. | ||||
|  * | ||||
|  * <rbuf> Ringbuffer to write to. | ||||
|  * <buf> Buffer to write. | ||||
|  * <len> Length of buffer (currently limited to 65535 bytes max). | ||||
|  * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. | ||||
|  */ | ||||
| extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, | ||||
| 					size_t len); | ||||
|  | ||||
| /** | ||||
|  * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this | ||||
|  * does NOT update the read pointer in the ringbuffer. You must use | ||||
|  * dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required. | ||||
|  * | ||||
|  * <rbuf> Ringbuffer concerned. | ||||
|  * <idx> Packet index as returned by dvb_ringbuffer_pkt_next(). | ||||
|  * <offset> Offset into packet to read from. | ||||
|  * <buf> Destination buffer for data. | ||||
|  * <len> Size of destination buffer. | ||||
|  * <usermem> Set to 1 if <buf> is in userspace. | ||||
|  * returns Number of bytes read, or -EFAULT. | ||||
|  */ | ||||
| extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx, | ||||
| 				       int offset, u8 __user *buf, size_t len); | ||||
| extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, | ||||
| 				       int offset, u8 *buf, size_t len); | ||||
|  | ||||
| /** | ||||
|  * Dispose of a packet in the ring buffer. | ||||
|  * | ||||
|  * <rbuf> Ring buffer concerned. | ||||
|  * <idx> Packet index as returned by dvb_ringbuffer_pkt_next(). | ||||
|  */ | ||||
| extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx); | ||||
|  | ||||
| /** | ||||
|  * Get the index of the next packet in a ringbuffer. | ||||
|  * | ||||
|  * <rbuf> Ringbuffer concerned. | ||||
|  * <idx> Previous packet index, or -1 to return the first packet index. | ||||
|  * <pktlen> On success, will be updated to contain the length of the packet in bytes. | ||||
|  * returns Packet index (if >=0), or -1 if no packets available. | ||||
|  */ | ||||
| extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen); | ||||
|  | ||||
|  | ||||
| #endif /* _DVB_RINGBUFFER_H_ */ | ||||
							
								
								
									
										514
									
								
								dvb-core/dvbdev.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										514
									
								
								dvb-core/dvbdev.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,514 @@ | ||||
| /* | ||||
|  * dvbdev.c | ||||
|  * | ||||
|  * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de> | ||||
|  *                  & Marcus Metzler <marcus@convergence.de> | ||||
|  *                    for convergence integrated media GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU Lesser General Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/string.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/device.h> | ||||
| #include <linux/fs.h> | ||||
| #include <linux/cdev.h> | ||||
| #include <linux/mutex.h> | ||||
| #include <linux/version.h> | ||||
| #include "dvbdev.h" | ||||
|  | ||||
| static DEFINE_MUTEX(dvbdev_mutex); | ||||
| static int dvbdev_debug; | ||||
|  | ||||
| module_param(dvbdev_debug, int, 0644); | ||||
| MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off)."); | ||||
|  | ||||
| #define dprintk if (dvbdev_debug) printk | ||||
|  | ||||
| static LIST_HEAD(dvb_adapter_list); | ||||
| static DEFINE_MUTEX(dvbdev_register_lock); | ||||
|  | ||||
| static const char * const dnames[] = { | ||||
| 	"video", "audio", "sec", "frontend", "demux", "dvr", "ca", | ||||
| 	"net", "osd", "ci", "mod", "ns", "nsd" | ||||
| }; | ||||
|  | ||||
| #ifdef CONFIG_DVB_DYNAMIC_MINORS | ||||
| #define MAX_DVB_MINORS		256 | ||||
| #define DVB_MAX_IDS		MAX_DVB_MINORS | ||||
| #else | ||||
| #define DVB_MAX_IDS		4 | ||||
| #define nums2minor(num,type,id)	((num << 6) | (id << 4) | type) | ||||
| #define MAX_DVB_MINORS		(DVB_MAX_ADAPTERS*64) | ||||
| #endif | ||||
|  | ||||
| static struct class *dvb_class; | ||||
|  | ||||
| static struct dvb_device *dvb_minors[MAX_DVB_MINORS]; | ||||
| static DECLARE_RWSEM(minor_rwsem); | ||||
|  | ||||
| static int dvb_device_open(struct inode *inode, struct file *file) | ||||
| { | ||||
| 	struct dvb_device *dvbdev; | ||||
|  | ||||
| 	mutex_lock(&dvbdev_mutex); | ||||
| 	down_read(&minor_rwsem); | ||||
| 	dvbdev = dvb_minors[iminor(inode)]; | ||||
|  | ||||
| 	if (dvbdev && dvbdev->fops) { | ||||
| 		int err = 0; | ||||
| 		const struct file_operations *old_fops; | ||||
|  | ||||
| 		file->private_data = dvbdev; | ||||
| 		old_fops = file->f_op; | ||||
| 		file->f_op = fops_get(dvbdev->fops); | ||||
| 		if (file->f_op == NULL) { | ||||
| 			file->f_op = old_fops; | ||||
| 			goto fail; | ||||
| 		} | ||||
| 		if(file->f_op->open) | ||||
| 			err = file->f_op->open(inode,file); | ||||
| 		if (err) { | ||||
| 			fops_put(file->f_op); | ||||
| 			file->f_op = fops_get(old_fops); | ||||
| 		} | ||||
| 		fops_put(old_fops); | ||||
| 		up_read(&minor_rwsem); | ||||
| 		mutex_unlock(&dvbdev_mutex); | ||||
| 		return err; | ||||
| 	} | ||||
| fail: | ||||
| 	up_read(&minor_rwsem); | ||||
| 	mutex_unlock(&dvbdev_mutex); | ||||
| 	return -ENODEV; | ||||
| } | ||||
|  | ||||
|  | ||||
| static const struct file_operations dvb_device_fops = | ||||
| { | ||||
| 	.owner =	THIS_MODULE, | ||||
| 	.open =		dvb_device_open, | ||||
| 	.llseek =	noop_llseek, | ||||
| }; | ||||
|  | ||||
| static struct cdev dvb_device_cdev; | ||||
|  | ||||
| int dvb_generic_open(struct inode *inode, struct file *file) | ||||
| { | ||||
| 	struct dvb_device *dvbdev = file->private_data; | ||||
|  | ||||
| 	if (!dvbdev) | ||||
| 		return -ENODEV; | ||||
|  | ||||
| 	if (!dvbdev->users) | ||||
| 		return -EBUSY; | ||||
|  | ||||
| 	if ((file->f_flags & O_ACCMODE) == O_RDONLY) { | ||||
| 		if (!dvbdev->readers) | ||||
| 			return -EBUSY; | ||||
| 		dvbdev->readers--; | ||||
| 	} else { | ||||
| 		if (!dvbdev->writers) | ||||
| 			return -EBUSY; | ||||
| 		dvbdev->writers--; | ||||
| 	} | ||||
|  | ||||
| 	dvbdev->users--; | ||||
| 	return 0; | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_generic_open); | ||||
|  | ||||
|  | ||||
| int dvb_generic_release(struct inode *inode, struct file *file) | ||||
| { | ||||
| 	struct dvb_device *dvbdev = file->private_data; | ||||
|  | ||||
| 	if (!dvbdev) | ||||
| 		return -ENODEV; | ||||
|  | ||||
| 	if ((file->f_flags & O_ACCMODE) == O_RDONLY) { | ||||
| 		dvbdev->readers++; | ||||
| 	} else { | ||||
| 		dvbdev->writers++; | ||||
| 	} | ||||
|  | ||||
| 	dvbdev->users++; | ||||
| 	return 0; | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_generic_release); | ||||
|  | ||||
|  | ||||
| long dvb_generic_ioctl(struct file *file, | ||||
| 		       unsigned int cmd, unsigned long arg) | ||||
| { | ||||
| 	struct dvb_device *dvbdev = file->private_data; | ||||
|  | ||||
| 	if (!dvbdev) | ||||
| 		return -ENODEV; | ||||
|  | ||||
| 	if (!dvbdev->kernel_ioctl) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	return dvb_usercopy(file, cmd, arg, dvbdev->kernel_ioctl); | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_generic_ioctl); | ||||
|  | ||||
|  | ||||
| static int dvbdev_get_free_id (struct dvb_adapter *adap, int type) | ||||
| { | ||||
| 	u32 id = 0; | ||||
|  | ||||
| 	while (id < DVB_MAX_IDS) { | ||||
| 		struct dvb_device *dev; | ||||
| 		list_for_each_entry(dev, &adap->device_list, list_head) | ||||
| 			if (dev->type == type && dev->id == id) | ||||
| 				goto skip; | ||||
| 		return id; | ||||
| skip: | ||||
| 		id++; | ||||
| 	} | ||||
| 	return -ENFILE; | ||||
| } | ||||
|  | ||||
|  | ||||
| int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, | ||||
| 			const struct dvb_device *template, void *priv, int type) | ||||
| { | ||||
| 	struct dvb_device *dvbdev; | ||||
| 	struct file_operations *dvbdevfops; | ||||
| 	struct device *clsdev; | ||||
| 	int minor; | ||||
| 	int id; | ||||
|  | ||||
| 	mutex_lock(&dvbdev_register_lock); | ||||
|  | ||||
| 	if ((id = dvbdev_get_free_id (adap, type)) < 0){ | ||||
| 		mutex_unlock(&dvbdev_register_lock); | ||||
| 		*pdvbdev = NULL; | ||||
| 		printk(KERN_ERR "%s: couldn't find free device id\n", __func__); | ||||
| 		return -ENFILE; | ||||
| 	} | ||||
|  | ||||
| 	*pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL); | ||||
|  | ||||
| 	if (!dvbdev){ | ||||
| 		mutex_unlock(&dvbdev_register_lock); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
|  | ||||
| 	dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL); | ||||
|  | ||||
| 	if (!dvbdevfops){ | ||||
| 		kfree (dvbdev); | ||||
| 		mutex_unlock(&dvbdev_register_lock); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
|  | ||||
| 	memcpy(dvbdev, template, sizeof(struct dvb_device)); | ||||
| 	dvbdev->type = type; | ||||
| 	dvbdev->id = id; | ||||
| 	dvbdev->adapter = adap; | ||||
| 	dvbdev->priv = priv; | ||||
| 	dvbdev->fops = dvbdevfops; | ||||
| 	init_waitqueue_head (&dvbdev->wait_queue); | ||||
|  | ||||
| 	memcpy(dvbdevfops, template->fops, sizeof(struct file_operations)); | ||||
| 	dvbdevfops->owner = adap->module; | ||||
|  | ||||
| 	list_add_tail (&dvbdev->list_head, &adap->device_list); | ||||
|  | ||||
| 	down_write(&minor_rwsem); | ||||
| #ifdef CONFIG_DVB_DYNAMIC_MINORS | ||||
| 	for (minor = 0; minor < MAX_DVB_MINORS; minor++) | ||||
| 		if (dvb_minors[minor] == NULL) | ||||
| 			break; | ||||
|  | ||||
| 	if (minor == MAX_DVB_MINORS) { | ||||
| 		kfree(dvbdevfops); | ||||
| 		kfree(dvbdev); | ||||
| 		up_write(&minor_rwsem); | ||||
| 		mutex_unlock(&dvbdev_register_lock); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| #else | ||||
| 	minor = nums2minor(adap->num, type, id); | ||||
| #endif | ||||
|  | ||||
| 	dvbdev->minor = minor; | ||||
| 	dvb_minors[minor] = dvbdev; | ||||
| 	up_write(&minor_rwsem); | ||||
|  | ||||
| 	mutex_unlock(&dvbdev_register_lock); | ||||
|  | ||||
| 	clsdev = device_create(dvb_class, adap->device, | ||||
| 			       MKDEV(DVB_MAJOR, minor), | ||||
| 			       dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id); | ||||
| 	if (IS_ERR(clsdev)) { | ||||
| 		printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n", | ||||
| 		       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev)); | ||||
| 		return PTR_ERR(clsdev); | ||||
| 	} | ||||
|  | ||||
| 	dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", | ||||
| 		adap->num, dnames[type], id, minor, minor); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_register_device); | ||||
|  | ||||
|  | ||||
| void dvb_unregister_device(struct dvb_device *dvbdev) | ||||
| { | ||||
| 	if (!dvbdev) | ||||
| 		return; | ||||
|  | ||||
| 	down_write(&minor_rwsem); | ||||
| 	dvb_minors[dvbdev->minor] = NULL; | ||||
| 	up_write(&minor_rwsem); | ||||
|  | ||||
| 	device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); | ||||
|  | ||||
| 	list_del (&dvbdev->list_head); | ||||
| 	kfree (dvbdev->fops); | ||||
| 	kfree (dvbdev); | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_unregister_device); | ||||
|  | ||||
| static int dvbdev_check_free_adapter_num(int num) | ||||
| { | ||||
| 	struct list_head *entry; | ||||
| 	list_for_each(entry, &dvb_adapter_list) { | ||||
| 		struct dvb_adapter *adap; | ||||
| 		adap = list_entry(entry, struct dvb_adapter, list_head); | ||||
| 		if (adap->num == num) | ||||
| 			return 0; | ||||
| 	} | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int dvbdev_get_free_adapter_num (void) | ||||
| { | ||||
| 	int num = 0; | ||||
|  | ||||
| 	while (num < DVB_MAX_ADAPTERS) { | ||||
| 		if (dvbdev_check_free_adapter_num(num)) | ||||
| 			return num; | ||||
| 		num++; | ||||
| 	} | ||||
|  | ||||
| 	return -ENFILE; | ||||
| } | ||||
|  | ||||
|  | ||||
| int dvb_register_adapter(struct dvb_adapter *adap, const char *name, | ||||
| 			 struct module *module, struct device *device, | ||||
| 			 short *adapter_nums) | ||||
| { | ||||
| 	int i, num; | ||||
|  | ||||
| 	mutex_lock(&dvbdev_register_lock); | ||||
|  | ||||
| 	for (i = 0; i < DVB_MAX_ADAPTERS; ++i) { | ||||
| 		num = adapter_nums[i]; | ||||
| 		if (num >= 0  &&  num < DVB_MAX_ADAPTERS) { | ||||
| 		/* use the one the driver asked for */ | ||||
| 			if (dvbdev_check_free_adapter_num(num)) | ||||
| 				break; | ||||
| 		} else { | ||||
| 			num = dvbdev_get_free_adapter_num(); | ||||
| 			break; | ||||
| 		} | ||||
| 		num = -1; | ||||
| 	} | ||||
|  | ||||
| 	if (num < 0) { | ||||
| 		mutex_unlock(&dvbdev_register_lock); | ||||
| 		return -ENFILE; | ||||
| 	} | ||||
|  | ||||
| 	memset (adap, 0, sizeof(struct dvb_adapter)); | ||||
| 	INIT_LIST_HEAD (&adap->device_list); | ||||
|  | ||||
| 	printk(KERN_INFO "DVB: registering new adapter (%s)\n", name); | ||||
|  | ||||
| 	adap->num = num; | ||||
| 	adap->name = name; | ||||
| 	adap->module = module; | ||||
| 	adap->device = device; | ||||
| 	adap->mfe_shared = 0; | ||||
| 	adap->mfe_dvbdev = NULL; | ||||
| 	mutex_init (&adap->mfe_lock); | ||||
|  | ||||
| 	list_add_tail (&adap->list_head, &dvb_adapter_list); | ||||
|  | ||||
| 	mutex_unlock(&dvbdev_register_lock); | ||||
|  | ||||
| 	return num; | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_register_adapter); | ||||
|  | ||||
|  | ||||
| int dvb_unregister_adapter(struct dvb_adapter *adap) | ||||
| { | ||||
| 	mutex_lock(&dvbdev_register_lock); | ||||
| 	list_del (&adap->list_head); | ||||
| 	mutex_unlock(&dvbdev_register_lock); | ||||
| 	return 0; | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_unregister_adapter); | ||||
|  | ||||
| /* if the miracle happens and "generic_usercopy()" is included into | ||||
|    the kernel, then this can vanish. please don't make the mistake and | ||||
|    define this as video_usercopy(). this will introduce a dependecy | ||||
|    to the v4l "videodev.o" module, which is unnecessary for some | ||||
|    cards (ie. the budget dvb-cards don't need the v4l module...) */ | ||||
| int dvb_usercopy(struct file *file, | ||||
| 		     unsigned int cmd, unsigned long arg, | ||||
| 		     int (*func)(struct file *file, | ||||
| 		     unsigned int cmd, void *arg)) | ||||
| { | ||||
| 	char    sbuf[128]; | ||||
| 	void    *mbuf = NULL; | ||||
| 	void    *parg = NULL; | ||||
| 	int     err  = -EINVAL; | ||||
|  | ||||
| 	/*  Copy arguments into temp kernel buffer  */ | ||||
| 	switch (_IOC_DIR(cmd)) { | ||||
| 	case _IOC_NONE: | ||||
| 		/* | ||||
| 		 * For this command, the pointer is actually an integer | ||||
| 		 * argument. | ||||
| 		 */ | ||||
| 		parg = (void *) arg; | ||||
| 		break; | ||||
| 	case _IOC_READ: /* some v4l ioctls are marked wrong ... */ | ||||
| 	case _IOC_WRITE: | ||||
| 	case (_IOC_WRITE | _IOC_READ): | ||||
| 		if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { | ||||
| 			parg = sbuf; | ||||
| 		} else { | ||||
| 			/* too big to allocate from stack */ | ||||
| 			mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); | ||||
| 			if (NULL == mbuf) | ||||
| 				return -ENOMEM; | ||||
| 			parg = mbuf; | ||||
| 		} | ||||
|  | ||||
| 		err = -EFAULT; | ||||
| 		if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) | ||||
| 			goto out; | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	/* call driver */ | ||||
| 	/* this lock is much too coarse */ | ||||
| 	//mutex_lock(&dvbdev_mutex); | ||||
| 	if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD) | ||||
| 		err = -ENOTTY; | ||||
| 	//mutex_unlock(&dvbdev_mutex); | ||||
|  | ||||
| 	if (err < 0) | ||||
| 		goto out; | ||||
|  | ||||
| 	/*  Copy results into user buffer  */ | ||||
| 	switch (_IOC_DIR(cmd)) | ||||
| 	{ | ||||
| 	case _IOC_READ: | ||||
| 	case (_IOC_WRITE | _IOC_READ): | ||||
| 		if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) | ||||
| 			err = -EFAULT; | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| out: | ||||
| 	kfree(mbuf); | ||||
| 	return err; | ||||
| } | ||||
| EXPORT_SYMBOL(dvb_usercopy); | ||||
|  | ||||
| static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env) | ||||
| { | ||||
| 	struct dvb_device *dvbdev = dev_get_drvdata(dev); | ||||
|  | ||||
| 	add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num); | ||||
| 	add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]); | ||||
| 	add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) | ||||
| static char *dvb_devnode(struct device *dev, mode_t *mode) | ||||
| #else | ||||
| static char *dvb_devnode(struct device *dev, umode_t *mode) | ||||
| #endif | ||||
| { | ||||
| 	struct dvb_device *dvbdev = dev_get_drvdata(dev); | ||||
|  | ||||
| 	return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d", | ||||
| 		dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id); | ||||
| } | ||||
|  | ||||
|  | ||||
| static int __init init_dvbdev(void) | ||||
| { | ||||
| 	int retval; | ||||
| 	dev_t dev = MKDEV(DVB_MAJOR, 0); | ||||
|  | ||||
| 	if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) { | ||||
| 		printk(KERN_ERR "dvb-core: unable to get major %d\n", DVB_MAJOR); | ||||
| 		return retval; | ||||
| 	} | ||||
|  | ||||
| 	cdev_init(&dvb_device_cdev, &dvb_device_fops); | ||||
| 	if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) { | ||||
| 		printk(KERN_ERR "dvb-core: unable register character device\n"); | ||||
| 		goto error; | ||||
| 	} | ||||
|  | ||||
| 	dvb_class = class_create(THIS_MODULE, "dvb"); | ||||
| 	if (IS_ERR(dvb_class)) { | ||||
| 		retval = PTR_ERR(dvb_class); | ||||
| 		goto error; | ||||
| 	} | ||||
| 	dvb_class->dev_uevent = dvb_uevent; | ||||
| 	dvb_class->devnode = dvb_devnode; | ||||
| 	return 0; | ||||
|  | ||||
| error: | ||||
| 	cdev_del(&dvb_device_cdev); | ||||
| 	unregister_chrdev_region(dev, MAX_DVB_MINORS); | ||||
| 	return retval; | ||||
| } | ||||
|  | ||||
|  | ||||
| static void __exit exit_dvbdev(void) | ||||
| { | ||||
| 	class_destroy(dvb_class); | ||||
| 	cdev_del(&dvb_device_cdev); | ||||
| 	unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS); | ||||
| } | ||||
|  | ||||
| subsys_initcall(init_dvbdev); | ||||
| module_exit(exit_dvbdev); | ||||
|  | ||||
| MODULE_DESCRIPTION("DVB Core Driver"); | ||||
| MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler"); | ||||
| MODULE_LICENSE("GPL"); | ||||
							
								
								
									
										150
									
								
								dvb-core/dvbdev.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								dvb-core/dvbdev.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,150 @@ | ||||
| /* | ||||
|  * dvbdev.h | ||||
|  * | ||||
|  * Copyright (C) 2000 Ralph Metzler & Marcus Metzler | ||||
|  *                    for convergence integrated media GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Lesser Public License | ||||
|  * as published by the Free Software Foundation; either version 2.1 | ||||
|  * 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 Lesser General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #ifndef _DVBDEV_H_ | ||||
| #define _DVBDEV_H_ | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/poll.h> | ||||
| #include <linux/fs.h> | ||||
| #include <linux/list.h> | ||||
|  | ||||
| #define DVB_MAJOR 212 | ||||
|  | ||||
| #if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0 | ||||
|   #define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS | ||||
| #else | ||||
|   #define DVB_MAX_ADAPTERS 8 | ||||
| #endif | ||||
|  | ||||
| #define DVB_UNSET (-1) | ||||
|  | ||||
| #define DVB_DEVICE_VIDEO      0 | ||||
| #define DVB_DEVICE_AUDIO      1 | ||||
| #define DVB_DEVICE_SEC        2 | ||||
| #define DVB_DEVICE_FRONTEND   3 | ||||
| #define DVB_DEVICE_DEMUX      4 | ||||
| #define DVB_DEVICE_DVR        5 | ||||
| #define DVB_DEVICE_CA         6 | ||||
| #define DVB_DEVICE_NET        7 | ||||
| #define DVB_DEVICE_OSD        8 | ||||
| #define DVB_DEVICE_CI         9 | ||||
| #define DVB_DEVICE_MOD       10 | ||||
| #define DVB_DEVICE_NS        11 | ||||
| #define DVB_DEVICE_NSD       12 | ||||
|  | ||||
| #define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \ | ||||
| 	static short adapter_nr[] = \ | ||||
| 		{[0 ... (DVB_MAX_ADAPTERS - 1)] = DVB_UNSET }; \ | ||||
| 	module_param_array(adapter_nr, short, NULL, 0444); \ | ||||
| 	MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers") | ||||
|  | ||||
| struct dvb_frontend; | ||||
|  | ||||
| struct dvb_adapter { | ||||
| 	int num; | ||||
| 	struct list_head list_head; | ||||
| 	struct list_head device_list; | ||||
| 	const char *name; | ||||
| 	u8 proposed_mac [6]; | ||||
| 	void* priv; | ||||
|  | ||||
| 	struct device *device; | ||||
|  | ||||
| 	struct module *module; | ||||
|  | ||||
| 	int mfe_shared;			/* indicates mutually exclusive frontends */ | ||||
| 	struct dvb_device *mfe_dvbdev;	/* frontend device in use */ | ||||
| 	struct mutex mfe_lock;		/* access lock for thread creation */ | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct dvb_device { | ||||
| 	struct list_head list_head; | ||||
| 	const struct file_operations *fops; | ||||
| 	struct dvb_adapter *adapter; | ||||
| 	int type; | ||||
| 	int minor; | ||||
| 	u32 id; | ||||
|  | ||||
| 	/* in theory, 'users' can vanish now, | ||||
| 	   but I don't want to change too much now... */ | ||||
| 	int readers; | ||||
| 	int writers; | ||||
| 	int users; | ||||
|  | ||||
| 	wait_queue_head_t	  wait_queue; | ||||
| 	/* don't really need those !? -- FIXME: use video_usercopy  */ | ||||
| 	int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg); | ||||
|  | ||||
| 	void *priv; | ||||
| }; | ||||
|  | ||||
|  | ||||
| extern int dvb_register_adapter(struct dvb_adapter *adap, const char *name, | ||||
| 				struct module *module, struct device *device, | ||||
| 				short *adapter_nums); | ||||
| extern int dvb_unregister_adapter (struct dvb_adapter *adap); | ||||
|  | ||||
| extern int dvb_register_device (struct dvb_adapter *adap, | ||||
| 				struct dvb_device **pdvbdev, | ||||
| 				const struct dvb_device *template, | ||||
| 				void *priv, | ||||
| 				int type); | ||||
|  | ||||
| extern void dvb_unregister_device (struct dvb_device *dvbdev); | ||||
|  | ||||
| extern int dvb_generic_open (struct inode *inode, struct file *file); | ||||
| extern int dvb_generic_release (struct inode *inode, struct file *file); | ||||
| extern long dvb_generic_ioctl (struct file *file, | ||||
| 			      unsigned int cmd, unsigned long arg); | ||||
|  | ||||
| /* we don't mess with video_usercopy() any more, | ||||
| we simply define out own dvb_usercopy(), which will hopefully become | ||||
| generic_usercopy()  someday... */ | ||||
|  | ||||
| extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, | ||||
| 			    int (*func)(struct file *file, unsigned int cmd, void *arg)); | ||||
|  | ||||
| /** generic DVB attach function. */ | ||||
| #ifdef CONFIG_MEDIA_ATTACH | ||||
| #define dvb_attach(FUNCTION, ARGS...) ({ \ | ||||
| 	void *__r = NULL; \ | ||||
| 	typeof(&FUNCTION) __a = symbol_request(FUNCTION); \ | ||||
| 	if (__a) { \ | ||||
| 		__r = (void *) __a(ARGS); \ | ||||
| 		if (__r == NULL) \ | ||||
| 			symbol_put(FUNCTION); \ | ||||
| 	} else { \ | ||||
| 		printk(KERN_ERR "DVB: Unable to find symbol "#FUNCTION"()\n"); \ | ||||
| 	} \ | ||||
| 	__r; \ | ||||
| }) | ||||
|  | ||||
| #else | ||||
| #define dvb_attach(FUNCTION, ARGS...) ({ \ | ||||
| 	FUNCTION(ARGS); \ | ||||
| }) | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif /* #ifndef _DVBDEV_H_ */ | ||||
							
								
								
									
										37
									
								
								frontends/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								frontends/Makefile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| # | ||||
| # Makefile for the kernel DVB frontend device drivers. | ||||
| # | ||||
|  | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_LNBP21  | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_STV090x  | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_STV6110x  | ||||
| #EXTRA_CFLAGS += -DCONFIG_DVB_STV0367 | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_STV0367DD | ||||
| #EXTRA_CFLAGS += -DCONFIG_DVB_TDA18212 | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_TDA18212DD | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843 | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_STV6111 | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_STV0910 | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_LNBH25 | ||||
| EXTRA_CFLAGS += -DCONFIG_DVB_MXL5XX | ||||
| EXTRA_CFLAGS += -DDBVALS | ||||
| NOSTDINC_FLAGS += -I$(SUBDIRS)/include -I$(SUBDIRS)/dvb-core | ||||
|  | ||||
| drxk-objs := drxk_hard.o  | ||||
| obj-$(CONFIG_DVB_DRXK) += drxk.o | ||||
|  | ||||
| obj-$(CONFIG_DVB_LNBP21) += lnbp21.o | ||||
| obj-$(CONFIG_DVB_STV090x) += stv090x.o | ||||
| obj-$(CONFIG_DVB_STV6110x) += stv6110x.o | ||||
| obj-$(CONFIG_DVB_CXD2099) += cxd2099.o | ||||
| obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o | ||||
| #obj-$(CONFIG_DVB_STV0367) += stv0367.o | ||||
| obj-$(CONFIG_DVB_STV0367DD) += stv0367dd.o | ||||
| #obj-$(CONFIG_DVB_TDA18212) += tda18212.o | ||||
| obj-$(CONFIG_DVB_TDA18212DD) += tda18212dd.o | ||||
| obj-$(CONFIG_DVB_CXD2843) += cxd2843.o | ||||
| obj-$(CONFIG_DVB_STV6111) += stv6111.o | ||||
| obj-$(CONFIG_DVB_STV0910) += stv0910.o | ||||
| obj-$(CONFIG_DVB_LNBH25) += lnbh25.o | ||||
| obj-$(CONFIG_DVB_MXL5XX) += mxl5xx.o  | ||||
|  | ||||
							
								
								
									
										726
									
								
								frontends/cxd2099.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										726
									
								
								frontends/cxd2099.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,726 @@ | ||||
| /* | ||||
|  * cxd2099.c: Driver for the CXD2099AR Common Interface Controller | ||||
|  * | ||||
|  * Copyright (C) 2010-2013 Digital Devices GmbH | ||||
|  * | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| #include <linux/version.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/moduleparam.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/i2c.h> | ||||
| #include <linux/wait.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/mutex.h> | ||||
| #include <linux/io.h> | ||||
|  | ||||
| #include "cxd2099.h" | ||||
|  | ||||
| //#define BUFFER_MODE 1 | ||||
|  | ||||
| static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount); | ||||
|  | ||||
| struct cxd { | ||||
| 	struct dvb_ca_en50221 en; | ||||
|  | ||||
| 	struct i2c_adapter *i2c; | ||||
| 	struct cxd2099_cfg cfg; | ||||
|  | ||||
| 	u8     regs[0x23]; | ||||
| 	u8     lastaddress; | ||||
| 	u8     clk_reg_f; | ||||
| 	u8     clk_reg_b; | ||||
| 	int    mode; | ||||
| 	int    ready; | ||||
| 	int    dr; | ||||
| 	int    write_busy; | ||||
| 	int    slot_stat; | ||||
|  | ||||
| 	u8     amem[1024]; | ||||
| 	int    amem_read; | ||||
|  | ||||
| 	int    cammode; | ||||
| 	struct mutex lock; | ||||
|  | ||||
| 	u8     rbuf[1028]; | ||||
| 	u8     wbuf[1028]; | ||||
| }; | ||||
|  | ||||
| static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr, | ||||
| 			 u8 reg, u8 data) | ||||
| { | ||||
| 	u8 m[2] = {reg, data}; | ||||
| 	struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 2}; | ||||
|  | ||||
| 	if (i2c_transfer(adapter, &msg, 1) != 1) { | ||||
| 		pr_err("Failed to write to I2C register %02x@%02x!\n", | ||||
| 		       reg, adr); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int i2c_write(struct i2c_adapter *adapter, u8 adr, | ||||
| 		     u8 *data, u16 len) | ||||
| { | ||||
| 	struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len}; | ||||
|  | ||||
| 	if (i2c_transfer(adapter, &msg, 1) != 1) { | ||||
| 		pr_err("Failed to write to I2C!\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, | ||||
| 			u8 reg, u8 *val) | ||||
| { | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||||
| 				   .buf = ®, .len = 1}, | ||||
| 				  {.addr = adr, .flags = I2C_M_RD, | ||||
| 				   .buf = val, .len = 1} }; | ||||
|  | ||||
| 	if (i2c_transfer(adapter, msgs, 2) != 2) { | ||||
| 		pr_err("error in i2c_read_reg\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int i2c_read(struct i2c_adapter *adapter, u8 adr, | ||||
| 		    u8 reg, u8 *data, u16 n) | ||||
| { | ||||
| 	struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, | ||||
| 				   .buf = ®, .len = 1}, | ||||
| 				  {.addr = adr, .flags = I2C_M_RD, | ||||
| 				   .buf = data, .len = n} }; | ||||
| 	 | ||||
| 	if (i2c_transfer(adapter, msgs, 2) != 2) { | ||||
| 		pr_err("error in i2c_read\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int read_block(struct cxd *ci, u8 adr, u8 *data, u16 n) | ||||
| { | ||||
| 	int status = 0; | ||||
|  | ||||
| 	if (ci->lastaddress != adr) | ||||
| 		status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, adr); | ||||
| 	if (!status) { | ||||
| 		ci->lastaddress = adr; | ||||
|  | ||||
| 		while (n) { | ||||
| 			int len = n; | ||||
| 			 | ||||
| 			if (ci->cfg.max_i2c && | ||||
| 			    len > ci->cfg.max_i2c) | ||||
| 				len = ci->cfg.max_i2c; | ||||
| 			status = i2c_read(ci->i2c, ci->cfg.adr, 1, data, len); | ||||
| 			if (status) | ||||
| 				return status; | ||||
| 			data += len; | ||||
| 			n -= len; | ||||
| 		} | ||||
| 	} | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| static int read_reg(struct cxd *ci, u8 reg, u8 *val) | ||||
| { | ||||
| 	return read_block(ci, reg, val, 1); | ||||
| } | ||||
|  | ||||
|  | ||||
| static int read_pccard(struct cxd *ci, u16 address, u8 *data, u8 n) | ||||
| { | ||||
| 	int status; | ||||
| 	u8 addr[3] = {2, address & 0xff, address >> 8}; | ||||
|  | ||||
| 	status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3); | ||||
| 	if (!status) | ||||
| 		status = i2c_read(ci->i2c, ci->cfg.adr, 3, data, n); | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| static int write_pccard(struct cxd *ci, u16 address, u8 *data, u8 n) | ||||
| { | ||||
| 	int status; | ||||
| 	u8 addr[3] = {2, address & 0xff, address >> 8}; | ||||
|  | ||||
| 	status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3); | ||||
| 	if (!status) { | ||||
| 		u8 buf[256] = {3}; | ||||
|  | ||||
| 		memcpy(buf + 1, data, n); | ||||
| 		status = i2c_write(ci->i2c, ci->cfg.adr, buf, n+1); | ||||
| 	} | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| static int read_io(struct cxd *ci, u16 address, u8 *val) | ||||
| { | ||||
| 	int status; | ||||
| 	u8 addr[3] = {2, address & 0xff, address >> 8}; | ||||
|  | ||||
| 	status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3); | ||||
| 	if (!status) | ||||
| 		status = i2c_read(ci->i2c, ci->cfg.adr, 3, val, 1); | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| static int write_io(struct cxd *ci, u16 address, u8 val) | ||||
| { | ||||
| 	int status; | ||||
| 	u8 addr[3] = {2, address & 0xff, address >> 8}; | ||||
| 	u8 buf[2] = {3, val}; | ||||
|  | ||||
| 	status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3); | ||||
| 	if (!status) | ||||
| 		status = i2c_write(ci->i2c, ci->cfg.adr, buf, 2); | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| static int read_io_data(struct cxd *ci, u8 *data, u16 n) | ||||
| { | ||||
| 	int status; | ||||
| 	u8 addr[3] = { 2, 0, 0 }; | ||||
|  | ||||
| 	status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3); | ||||
| 	if (!status) | ||||
| 		status = i2c_read(ci->i2c, ci->cfg.adr, 3, data, n); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int write_io_data(struct cxd *ci, u8 *data, u16 n) | ||||
| { | ||||
| 	int status; | ||||
| 	u8 addr[3] = {2, 0, 0}; | ||||
|  | ||||
| 	status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3); | ||||
| 	if (!status) { | ||||
| 		u8 buf[256] = {3}; | ||||
|  | ||||
| 		memcpy(buf + 1, data, n); | ||||
| 		status = i2c_write(ci->i2c, ci->cfg.adr, buf, n + 1); | ||||
| 	} | ||||
| 	return 0; | ||||
|  | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask) | ||||
| { | ||||
| 	int status = 0; | ||||
|  | ||||
| 	if (ci->lastaddress != reg) | ||||
| 		status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, reg); | ||||
| 	if (!status && reg >= 6 && reg <= 8 && mask != 0xff) | ||||
| 		status = i2c_read_reg(ci->i2c, ci->cfg.adr, 1, &ci->regs[reg]); | ||||
| 	ci->lastaddress = reg; | ||||
| 	ci->regs[reg] = (ci->regs[reg] & (~mask)) | val; | ||||
| 	if (!status) | ||||
| 		status = i2c_write_reg(ci->i2c, ci->cfg.adr, 1, ci->regs[reg]); | ||||
| 	if (reg == 0x20) | ||||
| 		ci->regs[reg] &= 0x7f; | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| static int write_reg(struct cxd *ci, u8 reg, u8 val) | ||||
| { | ||||
| 	return write_regm(ci, reg, val, 0xff); | ||||
| } | ||||
|  | ||||
| #ifdef BUFFER_MODE | ||||
| static int write_block(struct cxd *ci, u8 adr, u8 *data, u16 n) | ||||
| { | ||||
| 	int status = 0; | ||||
| 	u8 *buf = ci->wbuf; | ||||
|  | ||||
| 	if (ci->lastaddress != adr) | ||||
| 		status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, adr); | ||||
| 	if (status) | ||||
| 		return status; | ||||
| 	printk("write_block %d\n", n); | ||||
|  | ||||
| 	ci->lastaddress = adr; | ||||
| 	buf[0] = 1; | ||||
| 	while (n) { | ||||
| 		int len = n; | ||||
| 		 | ||||
| 		if (ci->cfg.max_i2c && | ||||
| 		    len + 1 > ci->cfg.max_i2c) | ||||
| 			len = ci->cfg.max_i2c - 1; | ||||
| 		printk("write %d\n", len); | ||||
| 		memcpy(buf + 1, data, len); | ||||
| 		status = i2c_write(ci->i2c, ci->cfg.adr, buf, len + 1); | ||||
| 		if (status) | ||||
| 			return status; | ||||
| 		n -= len; | ||||
| 		data += len; | ||||
| 	} | ||||
| 	return status; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static void set_mode(struct cxd *ci, int mode) | ||||
| { | ||||
| 	if (mode == ci->mode) | ||||
| 		return; | ||||
|  | ||||
| 	switch (mode) { | ||||
| 	case 0x00: /* IO mem */ | ||||
| 		write_regm(ci, 0x06, 0x00, 0x07); | ||||
| 		break; | ||||
| 	case 0x01: /* ATT mem */ | ||||
| 		write_regm(ci, 0x06, 0x02, 0x07); | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	ci->mode = mode; | ||||
| } | ||||
|  | ||||
| static void cam_mode(struct cxd *ci, int mode) | ||||
| { | ||||
| 	u8 dummy; | ||||
|  | ||||
| 	if (mode == ci->cammode) | ||||
| 		return; | ||||
|  | ||||
| 	switch (mode) { | ||||
| 	case 0x00: | ||||
| 		write_regm(ci, 0x20, 0x80, 0x80); | ||||
| 		break; | ||||
| 	case 0x01: | ||||
| 		if (!ci->en.read_data) | ||||
| 			return; | ||||
| 		ci->write_busy = 0; | ||||
| 		pr_info("enable cam buffer mode\n"); | ||||
| 		write_reg(ci, 0x0d, 0x00); | ||||
| 		write_reg(ci, 0x0e, 0x01); | ||||
| 		write_regm(ci, 0x08, 0x40, 0x40); | ||||
| 		read_reg(ci, 0x12, &dummy); | ||||
| 		write_regm(ci, 0x08, 0x80, 0x80); | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	ci->cammode = mode; | ||||
| } | ||||
|  | ||||
| #define CHK_ERROR(s) if ((status = s)) break | ||||
|  | ||||
| static int init(struct cxd *ci) | ||||
| { | ||||
| 	int status; | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	ci->mode = -1; | ||||
| 	do { | ||||
| 		CHK_ERROR(write_reg(ci, 0x00, 0x00)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x01, 0x00)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x02, 0x10)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x03, 0x00)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x05, 0xFF)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x06, 0x1F)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x07, 0x1F)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x08, 0x28)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x14, 0x20)); | ||||
|  | ||||
| 		/* TOSTRT = 8, Mode B (gated clock), falling Edge, | ||||
| 		   Serial, POL=HIGH, MSB */ | ||||
| 		CHK_ERROR(write_reg(ci, 0x0A, 0xA7)); | ||||
|  | ||||
| 		CHK_ERROR(write_reg(ci, 0x0B, 0x33)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x0C, 0x33)); | ||||
|  | ||||
| 		CHK_ERROR(write_regm(ci, 0x14, 0x00, 0x0F)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x15, ci->clk_reg_b)); | ||||
| 		CHK_ERROR(write_regm(ci, 0x16, 0x00, 0x0F)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x17, ci->clk_reg_f)); | ||||
|  | ||||
| 		if (ci->cfg.clock_mode == 2) { | ||||
| 			/* bitrate*2^13/ 72000 */ | ||||
| 			u32 reg = ((ci->cfg.bitrate << 13) + 71999) / 72000; | ||||
| 			 | ||||
| 			if (ci->cfg.polarity) { | ||||
| 				CHK_ERROR(write_reg(ci, 0x09, 0x6f)); | ||||
| 			} else { | ||||
| 				CHK_ERROR(write_reg(ci, 0x09, 0x6d)); | ||||
| 			} | ||||
| 			CHK_ERROR(write_reg(ci, 0x20, 0x08)); | ||||
| 			CHK_ERROR(write_reg(ci, 0x21, (reg >> 8) & 0xff)); | ||||
| 			CHK_ERROR(write_reg(ci, 0x22, reg & 0xff)); | ||||
| 		} else if (ci->cfg.clock_mode == 1) { | ||||
| 			if (ci->cfg.polarity) { | ||||
| 				CHK_ERROR(write_reg(ci, 0x09, 0x6f)); /* D */ | ||||
| 			} else { | ||||
| 				CHK_ERROR(write_reg(ci, 0x09, 0x6d)); | ||||
| 			} | ||||
| 			CHK_ERROR(write_reg(ci, 0x20, 0x68)); | ||||
| 			CHK_ERROR(write_reg(ci, 0x21, 0x00)); | ||||
| 			CHK_ERROR(write_reg(ci, 0x22, 0x02)); | ||||
| 		} else { | ||||
| 			if (ci->cfg.polarity) { | ||||
| 				CHK_ERROR(write_reg(ci, 0x09, 0x4f)); /* C */ | ||||
| 			} else { | ||||
| 				CHK_ERROR(write_reg(ci, 0x09, 0x4d)); | ||||
| 			} | ||||
| 			CHK_ERROR(write_reg(ci, 0x20, 0x28)); | ||||
| 			CHK_ERROR(write_reg(ci, 0x21, 0x00)); | ||||
| 			CHK_ERROR(write_reg(ci, 0x22, 0x07)); | ||||
| 		} | ||||
|  | ||||
| 		CHK_ERROR(write_regm(ci, 0x20, 0x80, 0x80)); | ||||
| 		CHK_ERROR(write_regm(ci, 0x03, 0x02, 0x02)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x01, 0x04)); | ||||
| 		CHK_ERROR(write_reg(ci, 0x00, 0x31)); | ||||
|  | ||||
| 		/* Put TS in bypass */ | ||||
| 		CHK_ERROR(write_regm(ci, 0x09, 0x08, 0x08)); | ||||
| 		ci->cammode = -1; | ||||
| 		cam_mode(ci, 0); | ||||
| 	} while (0); | ||||
| 	mutex_unlock(&ci->lock); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int read_attribute_mem(struct dvb_ca_en50221 *ca, | ||||
| 			      int slot, int address) | ||||
| { | ||||
| 	struct cxd *ci = ca->data; | ||||
| #if 0 | ||||
| 	if (ci->amem_read) { | ||||
| 		if (address <= 0 || address > 1024) | ||||
| 			return -EIO; | ||||
| 		return ci->amem[address]; | ||||
| 	} | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	write_regm(ci, 0x06, 0x00, 0x05); | ||||
| 	read_pccard(ci, 0, &ci->amem[0], 128); | ||||
| 	read_pccard(ci, 128, &ci->amem[0], 128); | ||||
| 	read_pccard(ci, 256, &ci->amem[0], 128); | ||||
| 	read_pccard(ci, 384, &ci->amem[0], 128); | ||||
| 	write_regm(ci, 0x06, 0x05, 0x05); | ||||
| 	mutex_unlock(&ci->lock); | ||||
| 	return ci->amem[address]; | ||||
| #else | ||||
| 	u8 val; | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	set_mode(ci, 1); | ||||
| 	read_pccard(ci, address, &val, 1); | ||||
| 	mutex_unlock(&ci->lock); | ||||
| 	return val; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, | ||||
| 			       int address, u8 value) | ||||
| { | ||||
| 	struct cxd *ci = ca->data; | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	set_mode(ci, 1); | ||||
| 	write_pccard(ci, address, &value, 1); | ||||
| 	mutex_unlock(&ci->lock); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int read_cam_control(struct dvb_ca_en50221 *ca, | ||||
| 			    int slot, u8 address) | ||||
| { | ||||
| 	struct cxd *ci = ca->data; | ||||
| 	u8 val; | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	set_mode(ci, 0); | ||||
| 	read_io(ci, address, &val); | ||||
| 	mutex_unlock(&ci->lock); | ||||
| 	return val; | ||||
| } | ||||
|  | ||||
| static int write_cam_control(struct dvb_ca_en50221 *ca, int slot, | ||||
| 			     u8 address, u8 value) | ||||
| { | ||||
| 	struct cxd *ci = ca->data; | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	set_mode(ci, 0); | ||||
| 	write_io(ci, address, value); | ||||
| 	mutex_unlock(&ci->lock); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int slot_reset(struct dvb_ca_en50221 *ca, int slot) | ||||
| { | ||||
| 	struct cxd *ci = ca->data; | ||||
|  | ||||
| 	if (ci->cammode) | ||||
| 		read_data(ca, slot, ci->rbuf, 0); | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| #if 0 | ||||
| 	write_reg(ci, 0x00, 0x21); | ||||
| 	write_reg(ci, 0x06, 0x1F); | ||||
| 	write_reg(ci, 0x00, 0x31); | ||||
| #else | ||||
| #if 0 | ||||
| 	write_reg(ci, 0x06, 0x1F); | ||||
| 	write_reg(ci, 0x06, 0x2F); | ||||
| #else | ||||
| 	cam_mode(ci, 0); | ||||
| 	write_reg(ci, 0x00, 0x21); | ||||
| 	write_reg(ci, 0x06, 0x1F); | ||||
| 	/*msleep(300);*/ | ||||
| 	write_reg(ci, 0x00, 0x31); | ||||
| 	write_regm(ci, 0x20, 0x80, 0x80); | ||||
| 	write_reg(ci, 0x03, 0x02); | ||||
| 	ci->ready = 0; | ||||
| #endif | ||||
| #endif | ||||
| 	ci->mode = -1; | ||||
| 	{ | ||||
| 		int i; | ||||
| #if 0 | ||||
| 		u8 val; | ||||
| #endif | ||||
| 		for (i = 0; i < 100; i++) { | ||||
| 			msleep(20); | ||||
| #if 0 | ||||
| 			read_reg(ci, 0x06, &val); | ||||
| 			pr_info(KERN_INFO "%d:%02x\n", i, val); | ||||
| 			if (!(val&0x10)) | ||||
| 				break; | ||||
| #else | ||||
| 			if (ci->ready) | ||||
| 				break; | ||||
| #endif | ||||
| 		} | ||||
| 	} | ||||
| 	mutex_unlock(&ci->lock); | ||||
| 	/* msleep(500); */ | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot) | ||||
| { | ||||
| 	struct cxd *ci = ca->data; | ||||
|  | ||||
| 	pr_info("slot_shutdown\n"); | ||||
| 	if (ci->cammode) | ||||
| 		read_data(ca, slot, ci->rbuf, 0); | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	write_reg(ci, 0x00, 0x21); | ||||
| 	write_reg(ci, 0x06, 0x1F); | ||||
| 	msleep(300); | ||||
|  | ||||
| 	write_regm(ci, 0x09, 0x08, 0x08); | ||||
| 	write_regm(ci, 0x20, 0x80, 0x80); /* Reset CAM Mode */ | ||||
| 	write_regm(ci, 0x06, 0x07, 0x07); /* Clear IO Mode */ | ||||
|  | ||||
| 	ci->mode = -1; | ||||
| 	ci->write_busy = 0; | ||||
| 	mutex_unlock(&ci->lock); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) | ||||
| { | ||||
| 	struct cxd *ci = ca->data; | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	write_regm(ci, 0x09, 0x00, 0x08); | ||||
| 	set_mode(ci, 0); | ||||
| 	cam_mode(ci, 1); | ||||
| 	mutex_unlock(&ci->lock); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int campoll(struct cxd *ci) | ||||
| { | ||||
| 	u8 istat; | ||||
|  | ||||
| 	read_reg(ci, 0x04, &istat); | ||||
| 	if (!istat) | ||||
| 		return 0; | ||||
| 	write_reg(ci, 0x05, istat); | ||||
|  | ||||
| 	if (istat & 0x40) | ||||
| 		ci->dr = 1; | ||||
| 	if (istat & 0x20) | ||||
| 		ci->write_busy = 0; | ||||
| 	if (istat & 2) { | ||||
| 		u8 slotstat; | ||||
|  | ||||
| 		read_reg(ci, 0x01, &slotstat); | ||||
| 		if (!(2 & slotstat)) { | ||||
| 			if (!ci->slot_stat) { | ||||
| 				ci->slot_stat |= | ||||
| 					DVB_CA_EN50221_POLL_CAM_PRESENT; | ||||
| 				write_regm(ci, 0x03, 0x08, 0x08); | ||||
| 			} | ||||
|  | ||||
| 		} else { | ||||
| 			if (ci->slot_stat) { | ||||
| 				ci->slot_stat = 0; | ||||
| 				write_regm(ci, 0x03, 0x00, 0x08); | ||||
| 				pr_info("NO CAM\n"); | ||||
| 				ci->ready = 0; | ||||
| 			} | ||||
| 		} | ||||
| 		if ((istat & 8) && | ||||
| 		    (ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT)) { | ||||
| 			ci->ready = 1; | ||||
| 			ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY; | ||||
| 		} | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) | ||||
| { | ||||
| 	struct cxd *ci = ca->data; | ||||
| 	u8 slotstat; | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	campoll(ci); | ||||
| 	read_reg(ci, 0x01, &slotstat); | ||||
| 	mutex_unlock(&ci->lock); | ||||
|  | ||||
| 	return ci->slot_stat; | ||||
| } | ||||
|  | ||||
| static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount) | ||||
| { | ||||
| 	struct cxd *ci = ca->data; | ||||
| 	u8 msb, lsb; | ||||
| 	u16 len; | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	campoll(ci); | ||||
| 	mutex_unlock(&ci->lock); | ||||
|  | ||||
| 	if (!ci->dr) | ||||
| 		return 0; | ||||
|  | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	read_reg(ci, 0x0f, &msb); | ||||
| 	read_reg(ci, 0x10, &lsb); | ||||
| 	len = ((u16) msb << 8) | lsb; | ||||
| 	if (len > ecount || len < 2) { | ||||
| 		/* read it anyway or cxd may hang */ | ||||
| 		read_block(ci, 0x12, ci->rbuf, len); | ||||
| 		mutex_unlock(&ci->lock); | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 	read_block(ci, 0x12, ebuf, len); | ||||
| 	ci->dr = 0; | ||||
| 	mutex_unlock(&ci->lock); | ||||
| #if 0 | ||||
| 	pr_info("read_data %d\n", len); | ||||
| 	{ | ||||
| 		int i; | ||||
|  | ||||
| 		for (i = 0; i < len; i++) | ||||
| 			pr_info("%02x ", ebuf[i]); | ||||
| 		pr_info("\n"); | ||||
| 	} | ||||
| #endif | ||||
| 	return len; | ||||
| } | ||||
|  | ||||
| #ifdef BUFFER_MODE | ||||
|  | ||||
| static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount) | ||||
| { | ||||
| 	struct cxd *ci = ca->data; | ||||
|  | ||||
| 	if (ci->write_busy) | ||||
| 		return -EAGAIN; | ||||
| 	mutex_lock(&ci->lock); | ||||
| 	write_reg(ci, 0x0d, ecount >> 8); | ||||
| 	write_reg(ci, 0x0e, ecount & 0xff); | ||||
| 	write_block(ci, 0x11, ebuf, ecount); | ||||
| 	ci->write_busy = 1; | ||||
| 	mutex_unlock(&ci->lock); | ||||
| 	return ecount; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static struct dvb_ca_en50221 en_templ = { | ||||
| 	.read_attribute_mem  = read_attribute_mem, | ||||
| 	.write_attribute_mem = write_attribute_mem, | ||||
| 	.read_cam_control    = read_cam_control, | ||||
| 	.write_cam_control   = write_cam_control, | ||||
| 	.slot_reset          = slot_reset, | ||||
| 	.slot_shutdown       = slot_shutdown, | ||||
| 	.slot_ts_enable      = slot_ts_enable, | ||||
| 	.poll_slot_status    = poll_slot_status, | ||||
| #ifdef BUFFER_MODE | ||||
| 	.read_data           = read_data, | ||||
| 	.write_data          = write_data, | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg, | ||||
| 				      void *priv, | ||||
| 				      struct i2c_adapter *i2c) | ||||
| { | ||||
| 	struct cxd *ci = 0; | ||||
| 	u8 val; | ||||
|  | ||||
| 	if (i2c_read_reg(i2c, cfg->adr, 0, &val) < 0) { | ||||
| 		pr_info("No CXD2099 detected at %02x\n", cfg->adr); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	ci = kzalloc(sizeof(struct cxd), GFP_KERNEL); | ||||
| 	if (!ci) | ||||
| 		return 0; | ||||
|  | ||||
| 	mutex_init(&ci->lock); | ||||
| 	memcpy(&ci->cfg, cfg, sizeof(struct cxd2099_cfg)); | ||||
| 	ci->i2c = i2c; | ||||
| 	ci->lastaddress = 0xff; | ||||
| 	ci->clk_reg_b = 0x4a; | ||||
| 	ci->clk_reg_f = 0x1b; | ||||
|  | ||||
| 	memcpy(&ci->en, &en_templ, sizeof(en_templ)); | ||||
| 	ci->en.data = ci; | ||||
| 	init(ci); | ||||
| 	pr_info("Attached CXD2099AR at %02x\n", ci->cfg.adr); | ||||
| 	return &ci->en; | ||||
| } | ||||
| EXPORT_SYMBOL(cxd2099_attach); | ||||
|  | ||||
| MODULE_DESCRIPTION("cxd2099"); | ||||
| MODULE_AUTHOR("Ralph Metzler"); | ||||
| MODULE_LICENSE("GPL"); | ||||
							
								
								
									
										43
									
								
								frontends/cxd2099.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								frontends/cxd2099.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| /* | ||||
|  * cxd2099.h: Driver for the CXD2099AR Common Interface Controller | ||||
|  * | ||||
|  * Copyright (C) 2010-2011 Digital Devices GmbH | ||||
|  * | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| #ifndef _CXD2099_H_ | ||||
| #define _CXD2099_H_ | ||||
|  | ||||
| #include <dvb_ca_en50221.h> | ||||
|  | ||||
| struct cxd2099_cfg { | ||||
| 	u32 bitrate; | ||||
| 	u8  adr; | ||||
| 	u8  polarity; | ||||
| 	u8  clock_mode; | ||||
|  | ||||
| 	u32 max_i2c; | ||||
| }; | ||||
|  | ||||
| struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg, | ||||
| 				      void *priv, struct i2c_adapter *i2c); | ||||
|  | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										2042
									
								
								frontends/cxd2843.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2042
									
								
								frontends/cxd2843.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										30
									
								
								frontends/cxd2843.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								frontends/cxd2843.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| #ifndef _CXD2843_H_ | ||||
| #define _CXD2843_H_ | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/i2c.h> | ||||
|  | ||||
| struct cxd2843_cfg { | ||||
| 	u8  adr; | ||||
| 	u32 ts_clock; | ||||
| 	u8  parallel; | ||||
| }; | ||||
|  | ||||
| #if defined(CONFIG_DVB_CXD2843) || \ | ||||
| 	(defined(CONFIG_DVB_CXD2843_MODULE) && defined(MODULE)) | ||||
|  | ||||
| extern struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c, | ||||
| 					   struct cxd2843_cfg *cfg); | ||||
|  | ||||
| #else | ||||
|  | ||||
| static inline struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c, | ||||
| 					   struct cxd2843_cfg *cfg) | ||||
| { | ||||
| 	pr_warn("%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										10
									
								
								frontends/drxk.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								frontends/drxk.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| #ifndef _DRXK_H_ | ||||
| #define _DRXK_H_ | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/i2c.h> | ||||
|  | ||||
| extern struct dvb_frontend *drxk_attach(struct i2c_adapter *i2c,  | ||||
| 					u8 adr, | ||||
| 					struct dvb_frontend **fe_t); | ||||
| #endif | ||||
							
								
								
									
										
											BIN
										
									
								
								frontends/drxk_a3.mc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								frontends/drxk_a3.mc
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										5097
									
								
								frontends/drxk_hard.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5097
									
								
								frontends/drxk_hard.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										343
									
								
								frontends/drxk_hard.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										343
									
								
								frontends/drxk_hard.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,343 @@ | ||||
| #include "drxk_map.h" | ||||
|  | ||||
| #define DRXK_VERSION_MAJOR 0 | ||||
| #define DRXK_VERSION_MINOR 9 | ||||
| #define DRXK_VERSION_PATCH 4300 | ||||
|  | ||||
| #define HI_I2C_DELAY        42 | ||||
| #define HI_I2C_BRIDGE_DELAY 350 | ||||
| #define DRXK_MAX_RETRIES    100 | ||||
|  | ||||
| #define DRIVER_4400 1 | ||||
|  | ||||
| #define DRXX_JTAGID   0x039210D9 | ||||
| #define DRXX_J_JTAGID 0x239310D9 | ||||
| #define DRXX_K_JTAGID 0x039210D9 | ||||
|  | ||||
| #define DRX_UNKNOWN     254 | ||||
| #define DRX_AUTO        255 | ||||
|  | ||||
| #define DRX_SCU_READY   0 | ||||
| #define DRXK_MAX_WAITTIME (200) | ||||
| #define SCU_RESULT_OK      0 | ||||
| #define SCU_RESULT_UNKSTD -2 | ||||
| #define SCU_RESULT_UNKCMD -1 | ||||
|  | ||||
| #ifndef DRXK_OFDM_TR_SHUTDOWN_TIMEOUT | ||||
| #define DRXK_OFDM_TR_SHUTDOWN_TIMEOUT (200) | ||||
| #endif | ||||
|  | ||||
| #define DRXK_8VSB_MPEG_BIT_RATE     19392658UL  /*bps*/ | ||||
| #define DRXK_DVBT_MPEG_BIT_RATE     32000000UL  /*bps*/ | ||||
| #define DRXK_QAM16_MPEG_BIT_RATE    27000000UL  /*bps*/ | ||||
| #define DRXK_QAM32_MPEG_BIT_RATE    33000000UL  /*bps*/ | ||||
| #define DRXK_QAM64_MPEG_BIT_RATE    40000000UL  /*bps*/ | ||||
| #define DRXK_QAM128_MPEG_BIT_RATE   46000000UL  /*bps*/ | ||||
| #define DRXK_QAM256_MPEG_BIT_RATE   52000000UL  /*bps*/ | ||||
| #define DRXK_MAX_MPEG_BIT_RATE      52000000UL  /*bps*/ | ||||
|  | ||||
| #define   IQM_CF_OUT_ENA_OFDM__M                                            0x4 | ||||
| #define     IQM_FS_ADJ_SEL_B_QAM                                            0x1 | ||||
| #define     IQM_FS_ADJ_SEL_B_OFF                                            0x0 | ||||
| #define     IQM_FS_ADJ_SEL_B_VSB                                            0x2 | ||||
| #define     IQM_RC_ADJ_SEL_B_OFF                                            0x0 | ||||
| #define     IQM_RC_ADJ_SEL_B_QAM                                            0x1 | ||||
| #define     IQM_RC_ADJ_SEL_B_VSB                                            0x2 | ||||
|  | ||||
| enum OperationMode { | ||||
| 	OM_NONE, | ||||
| 	OM_QAM_ITU_A, | ||||
| 	OM_QAM_ITU_B, | ||||
| 	OM_QAM_ITU_C, | ||||
| 	OM_DVBT | ||||
| }; | ||||
|  | ||||
| typedef enum { | ||||
| 	DRX_POWER_UP = 0, | ||||
| 	DRX_POWER_MODE_1, | ||||
| 	DRX_POWER_MODE_2, | ||||
| 	DRX_POWER_MODE_3, | ||||
| 	DRX_POWER_MODE_4, | ||||
| 	DRX_POWER_MODE_5, | ||||
| 	DRX_POWER_MODE_6, | ||||
| 	DRX_POWER_MODE_7, | ||||
| 	DRX_POWER_MODE_8, | ||||
|  | ||||
| 	DRX_POWER_MODE_9, | ||||
| 	DRX_POWER_MODE_10, | ||||
| 	DRX_POWER_MODE_11, | ||||
| 	DRX_POWER_MODE_12, | ||||
| 	DRX_POWER_MODE_13, | ||||
| 	DRX_POWER_MODE_14, | ||||
| 	DRX_POWER_MODE_15, | ||||
| 	DRX_POWER_MODE_16, | ||||
| 	DRX_POWER_DOWN = 255 | ||||
| }DRXPowerMode_t, *pDRXPowerMode_t; | ||||
|  | ||||
|  | ||||
| /** /brief Intermediate power mode for DRXK, power down OFDM clock domain */ | ||||
| #ifndef DRXK_POWER_DOWN_OFDM | ||||
| #define DRXK_POWER_DOWN_OFDM        DRX_POWER_MODE_1 | ||||
| #endif | ||||
|  | ||||
| /** /brief Intermediate power mode for DRXK, power down core (sysclk) */ | ||||
| #ifndef DRXK_POWER_DOWN_CORE | ||||
| #define DRXK_POWER_DOWN_CORE        DRX_POWER_MODE_9 | ||||
| #endif | ||||
|  | ||||
| /** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */ | ||||
| #ifndef DRXK_POWER_DOWN_PLL | ||||
| #define DRXK_POWER_DOWN_PLL         DRX_POWER_MODE_10 | ||||
| #endif | ||||
|  | ||||
|  | ||||
| enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF }; | ||||
| enum EDrxkState { DRXK_UNINITIALIZED = 0, DRXK_STOPPED, DRXK_DTV_STARTED, DRXK_ATV_STARTED, DRXK_POWERED_DOWN }; | ||||
| enum EDrxkCoefArrayIndex { | ||||
| 	DRXK_COEF_IDX_MN = 0, | ||||
| 	DRXK_COEF_IDX_FM    , | ||||
| 	DRXK_COEF_IDX_L     , | ||||
| 	DRXK_COEF_IDX_LP    , | ||||
| 	DRXK_COEF_IDX_BG    , | ||||
| 	DRXK_COEF_IDX_DK    , | ||||
| 	DRXK_COEF_IDX_I     , | ||||
| 	DRXK_COEF_IDX_MAX | ||||
| }; | ||||
| enum EDrxkSifAttenuation { | ||||
| 	DRXK_SIF_ATTENUATION_0DB, | ||||
| 	DRXK_SIF_ATTENUATION_3DB, | ||||
| 	DRXK_SIF_ATTENUATION_6DB, | ||||
| 	DRXK_SIF_ATTENUATION_9DB | ||||
| }; | ||||
| enum EDrxkConstellation { | ||||
| 	DRX_CONSTELLATION_BPSK = 0, | ||||
| 	DRX_CONSTELLATION_QPSK, | ||||
| 	DRX_CONSTELLATION_PSK8, | ||||
| 	DRX_CONSTELLATION_QAM16, | ||||
| 	DRX_CONSTELLATION_QAM32, | ||||
| 	DRX_CONSTELLATION_QAM64, | ||||
| 	DRX_CONSTELLATION_QAM128, | ||||
| 	DRX_CONSTELLATION_QAM256, | ||||
| 	DRX_CONSTELLATION_QAM512, | ||||
| 	DRX_CONSTELLATION_QAM1024, | ||||
| 	DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN, | ||||
| 	DRX_CONSTELLATION_AUTO    = DRX_AUTO | ||||
| }; | ||||
| enum EDrxkInterleaveMode { | ||||
| 	DRXK_QAM_I12_J17    = 16, | ||||
| 	DRXK_QAM_I_UNKNOWN  = DRX_UNKNOWN | ||||
| }; | ||||
| enum { | ||||
| 	DRXK_SPIN_A1 = 0, | ||||
| 	DRXK_SPIN_A2, | ||||
| 	DRXK_SPIN_A3, | ||||
| 	DRXK_SPIN_UNKNOWN | ||||
| }; | ||||
|  | ||||
| enum DRXKCfgDvbtSqiSpeed { | ||||
| 	DRXK_DVBT_SQI_SPEED_FAST = 0, | ||||
| 	DRXK_DVBT_SQI_SPEED_MEDIUM, | ||||
| 	DRXK_DVBT_SQI_SPEED_SLOW, | ||||
| 	DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN | ||||
| } ; | ||||
|  | ||||
| enum DRXFftmode_t { | ||||
| 	DRX_FFTMODE_2K = 0, | ||||
| 	DRX_FFTMODE_4K, | ||||
| 	DRX_FFTMODE_8K, | ||||
| 	DRX_FFTMODE_UNKNOWN = DRX_UNKNOWN, | ||||
| 	DRX_FFTMODE_AUTO    = DRX_AUTO | ||||
| }; | ||||
|  | ||||
| enum DRXMPEGStrWidth_t { | ||||
| 	DRX_MPEG_STR_WIDTH_1, | ||||
| 	DRX_MPEG_STR_WIDTH_8 | ||||
| }; | ||||
|  | ||||
| enum DRXQamLockRange_t { | ||||
| 	DRX_QAM_LOCKRANGE_NORMAL, | ||||
| 	DRX_QAM_LOCKRANGE_EXTENDED | ||||
| }; | ||||
|  | ||||
| struct DRXKCfgDvbtEchoThres_t { | ||||
| 	u16             threshold; | ||||
| 	enum DRXFftmode_t      fftMode; | ||||
| } ; | ||||
|  | ||||
| struct SCfgAgc | ||||
| { | ||||
| 	enum AGC_CTRL_MODE     ctrlMode;        /* off, user, auto */ | ||||
| 	u16            outputLevel;     /* range dependent on AGC */ | ||||
| 	u16            minOutputLevel;  /* range dependent on AGC */ | ||||
| 	u16            maxOutputLevel;  /* range dependent on AGC */ | ||||
| 	u16            speed;           /* range dependent on AGC */ | ||||
| 	u16            top;             /* rf-agc take over point */ | ||||
| 	u16            cutOffCurrent;   /* rf-agc is accelerated if output current | ||||
| 					      is below cut-off current                */ | ||||
| 	u16            IngainTgtMax; | ||||
| 	u16            FastClipCtrlDelay; | ||||
| }; | ||||
|  | ||||
| struct SCfgPreSaw | ||||
| { | ||||
| 	u16        reference; /* pre SAW reference value, range 0 .. 31 */ | ||||
| 	bool          usePreSaw; /* TRUE algorithms must use pre SAW sense */ | ||||
| }; | ||||
|  | ||||
| struct DRXKOfdmScCmd_t | ||||
| { | ||||
| 	u16 cmd;        /**< Command number */ | ||||
| 	u16 subcmd;     /**< Sub-command parameter*/ | ||||
| 	u16 param0;     /**< General purpous param */ | ||||
| 	u16 param1;     /**< General purpous param */ | ||||
| 	u16 param2;     /**< General purpous param */ | ||||
| 	u16 param3;     /**< General purpous param */ | ||||
| 	u16 param4;     /**< General purpous param */ | ||||
| }; | ||||
|  | ||||
| struct drxk_state { | ||||
| 	struct dvb_frontend c_frontend; | ||||
| 	struct dvb_frontend t_frontend; | ||||
| #ifndef USE_API3 | ||||
| 	struct dtv_frontend_properties props; | ||||
| #else | ||||
| 	struct dvb_frontend_parameters param; | ||||
| #endif | ||||
| 	struct device *dev; | ||||
|  | ||||
| 	struct i2c_adapter *i2c; | ||||
| 	u8     demod_address; | ||||
| 	void  *priv; | ||||
|  | ||||
| 	struct mutex mutex; | ||||
| 	struct mutex ctlock; | ||||
|  | ||||
| 	u32           m_Instance;             ///< Channel 1,2,3 or 4 | ||||
|  | ||||
| 	int             m_ChunkSize; | ||||
| 	u8 Chunk[256]; | ||||
|  | ||||
| 	bool            m_hasLNA; | ||||
| 	bool            m_hasDVBT; | ||||
| 	bool            m_hasDVBC; | ||||
| 	bool            m_hasAudio; | ||||
| 	bool            m_hasATV; | ||||
| 	bool            m_hasOOB; | ||||
| 	bool            m_hasSAWSW;           /**< TRUE if mat_tx is available */ | ||||
| 	bool            m_hasGPIO1;           /**< TRUE if mat_rx is available */ | ||||
| 	bool            m_hasGPIO2;            /**< TRUE if GPIO is available */ | ||||
| 	bool            m_hasIRQN;            /**< TRUE if IRQN is available */ | ||||
| 	u16          m_oscClockFreq; | ||||
| 	u16          m_HICfgTimingDiv; | ||||
| 	u16          m_HICfgBridgeDelay; | ||||
| 	u16          m_HICfgWakeUpKey; | ||||
| 	u16          m_HICfgTimeout; | ||||
| 	u16          m_HICfgCtrl; | ||||
| 	s32            m_sysClockFreq     ;    ///< system clock frequency in kHz | ||||
|  | ||||
| 	enum EDrxkState      m_DrxkState;            ///< State of Drxk (init,stopped,started) | ||||
| 	enum OperationMode   m_OperationMode;        ///< digital standards | ||||
| 	struct SCfgAgc         m_vsbRfAgcCfg;          ///< settings for VSB RF-AGC | ||||
| 	struct SCfgAgc         m_vsbIfAgcCfg;          ///< settings for VSB IF-AGC | ||||
| 	u16          m_vsbPgaCfg;            ///< settings for VSB PGA | ||||
| 	struct SCfgPreSaw      m_vsbPreSawCfg;         ///< settings for pre SAW sense | ||||
| 	s32            m_Quality83percent;     ///< MER level (*0.1 dB) for 83% quality indication | ||||
| 	s32            m_Quality93percent;     ///< MER level (*0.1 dB) for 93% quality indication | ||||
| 	bool            m_smartAntInverted; | ||||
| 	bool            m_bDebugEnableBridge; | ||||
| 	bool            m_bPDownOpenBridge;     ///< only open DRXK bridge before power-down once it has been accessed | ||||
| 	bool            m_bPowerDown;           ///< Power down when not used | ||||
|  | ||||
| 	u32           m_IqmFsRateOfs;         ///< frequency shift as written to DRXK register (28bit fixpoint) | ||||
|  | ||||
| 	bool            m_enableMPEGOutput;     /**< If TRUE, enable MPEG output */ | ||||
| 	bool            m_insertRSByte;         /**< If TRUE, insert RS byte */ | ||||
| 	bool            m_enableParallel;       /**< If TRUE, parallel out otherwise serial */ | ||||
| 	bool            m_invertDATA;           /**< If TRUE, invert DATA signals */ | ||||
| 	bool            m_invertERR;            /**< If TRUE, invert ERR signal */ | ||||
| 	bool            m_invertSTR;            /**< If TRUE, invert STR signals */ | ||||
| 	bool            m_invertVAL;            /**< If TRUE, invert VAL signals */ | ||||
| 	bool            m_invertCLK;            /**< If TRUE, invert CLK signals */ | ||||
| 	bool            m_DVBCStaticCLK; | ||||
| 	bool            m_DVBTStaticCLK;            /**< If TRUE, static MPEG clockrate will | ||||
| 						       be used, otherwise clockrate will | ||||
| 						       adapt to the bitrate of the TS */ | ||||
| 	u32           m_DVBTBitrate; | ||||
| 	u32           m_DVBCBitrate; | ||||
|  | ||||
| 	u8            m_TSDataStrength; | ||||
| 	u8            m_TSClockkStrength; | ||||
|  | ||||
| 	enum DRXMPEGStrWidth_t  m_widthSTR;          /**< MPEG start width**/ | ||||
| 	u32           m_mpegTsStaticBitrate;  /**< Maximum bitrate in b/s in case | ||||
| 						 static clockrate is selected */ | ||||
|  | ||||
| 	//LARGE_INTEGER   m_StartTime;            ///< Contains the time of the last demod start | ||||
| 	s32            m_MpegLockTimeOut;      ///< WaitForLockStatus Timeout (counts from start time) | ||||
| 	s32            m_DemodLockTimeOut;     ///< WaitForLockStatus Timeout (counts from start time) | ||||
|  | ||||
| 	bool            m_disableTEIhandling; | ||||
|  | ||||
| 	bool            m_RfAgcPol; | ||||
| 	bool            m_IfAgcPol; | ||||
|  | ||||
| 	struct SCfgAgc         m_atvRfAgcCfg;          ///< settings for ATV RF-AGC | ||||
| 	struct SCfgAgc         m_atvIfAgcCfg;          ///< settings for ATV IF-AGC | ||||
| 	struct SCfgPreSaw      m_atvPreSawCfg;         ///< settings for ATV pre SAW sense | ||||
| 	bool         m_phaseCorrectionBypass; | ||||
| 	s16          m_atvTopVidPeak; | ||||
| 	u16          m_atvTopNoiseTh; | ||||
| 	enum EDrxkSifAttenuation m_sifAttenuation; | ||||
| 	bool            m_enableCVBSOutput; | ||||
| 	bool            m_enableSIFOutput; | ||||
| 	bool            m_bMirrorFreqSpect; | ||||
| 	enum EDrxkConstellation  m_Constellation;    ///< Constellation type of the channel | ||||
| 	u32           m_CurrSymbolRate;       ///< Current QAM symbol rate | ||||
| 	struct SCfgAgc         m_qamRfAgcCfg;          ///< settings for QAM RF-AGC | ||||
| 	struct SCfgAgc         m_qamIfAgcCfg;          ///< settings for QAM IF-AGC | ||||
| 	u16          m_qamPgaCfg;            ///< settings for QAM PGA | ||||
| 	struct SCfgPreSaw      m_qamPreSawCfg;         ///< settings for QAM pre SAW sense | ||||
| 	enum EDrxkInterleaveMode m_qamInterleaveMode; ///< QAM Interleave mode | ||||
| 	u16          m_fecRsPlen; | ||||
| 	u16          m_fecRsPrescale; | ||||
|  | ||||
| 	enum DRXKCfgDvbtSqiSpeed m_sqiSpeed; | ||||
|  | ||||
| 	u16          m_GPIO; | ||||
| 	u16          m_GPIOCfg; | ||||
|  | ||||
| 	struct SCfgAgc         m_dvbtRfAgcCfg;          ///< settings for QAM RF-AGC | ||||
| 	struct SCfgAgc         m_dvbtIfAgcCfg;          ///< settings for QAM IF-AGC | ||||
| 	struct SCfgPreSaw      m_dvbtPreSawCfg;         ///< settings for QAM pre SAW sense | ||||
|  | ||||
| 	u16          m_agcFastClipCtrlDelay; | ||||
| 	bool            m_adcCompPassed; | ||||
| 	u16          m_adcCompCoef[64]; | ||||
| 	u16          m_adcState; | ||||
|  | ||||
| 	u8 *m_microcode; | ||||
| 	int   m_microcode_length; | ||||
| 	bool            m_DRXK_A1_PATCH_CODE; | ||||
| 	bool            m_DRXK_A1_ROM_CODE; | ||||
| 	bool            m_DRXK_A2_ROM_CODE; | ||||
| 	bool            m_DRXK_A3_ROM_CODE; | ||||
| 	bool            m_DRXK_A2_PATCH_CODE; | ||||
| 	bool            m_DRXK_A3_PATCH_CODE; | ||||
|  | ||||
| 	bool            m_rfmirror; | ||||
| 	u8              m_deviceSpin; | ||||
| 	u32             m_iqmRcRate; | ||||
|  | ||||
| 	u16          m_AntennaDVBC; | ||||
| 	u16          m_AntennaDVBT; | ||||
| 	u16          m_AntennaSwitchDVBTDVBC; | ||||
|  | ||||
| 	DRXPowerMode_t m_currentPowerMode; | ||||
| }; | ||||
|  | ||||
| #define NEVER_LOCK 0 | ||||
| #define NOT_LOCKED 1 | ||||
| #define DEMOD_LOCK 2 | ||||
| #define FEC_LOCK   3 | ||||
| #define MPEG_LOCK  4 | ||||
|  | ||||
							
								
								
									
										16438
									
								
								frontends/drxk_map.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16438
									
								
								frontends/drxk_map.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										4340
									
								
								frontends/drxk_map_b.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4340
									
								
								frontends/drxk_map_b.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										55
									
								
								frontends/lnbh24.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								frontends/lnbh24.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| /* | ||||
|  * lnbh24.h - driver for lnb supply and control ic lnbh24 | ||||
|  * | ||||
|  * Copyright (C) 2009 NetUP Inc. | ||||
|  * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| #ifndef _LNBH24_H | ||||
| #define _LNBH24_H | ||||
|  | ||||
| /* system register bits */ | ||||
| #define LNBH24_OLF	0x01 | ||||
| #define LNBH24_OTF	0x02 | ||||
| #define LNBH24_EN	0x04 | ||||
| #define LNBH24_VSEL	0x08 | ||||
| #define LNBH24_LLC	0x10 | ||||
| #define LNBH24_TEN	0x20 | ||||
| #define LNBH24_TTX	0x40 | ||||
| #define LNBH24_PCL	0x80 | ||||
|  | ||||
| #include <linux/dvb/frontend.h> | ||||
|  | ||||
| #if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \ | ||||
| 							&& defined(MODULE)) | ||||
| /* override_set and override_clear control which | ||||
|    system register bits (above) to always set & clear */ | ||||
| extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, | ||||
| 				struct i2c_adapter *i2c, u8 override_set, | ||||
| 				u8 override_clear, u8 i2c_addr); | ||||
| #else | ||||
| static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, | ||||
| 				struct i2c_adapter *i2c, u8 override_set, | ||||
| 				u8 override_clear, u8 i2c_addr) | ||||
| { | ||||
| 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										157
									
								
								frontends/lnbh25.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								frontends/lnbh25.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | ||||
| /* | ||||
|  * Driver for the ST LNBH25 | ||||
|  * | ||||
|  * Copyright (C) 2014 Digital Devices GmbH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2 only, as published by the Free Software Foundation. | ||||
|  * | ||||
|  * | ||||
|  * 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., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include <linux/delay.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/string.h> | ||||
| #include <linux/slab.h> | ||||
|  | ||||
| #include "dvb_frontend.h" | ||||
| #include "lnbh25.h" | ||||
|  | ||||
| struct lnbh25 { | ||||
| 	struct i2c_adapter	*i2c; | ||||
| 	u8			 adr; | ||||
| 	u8                       reg[4]; | ||||
| 	u8                       boost; | ||||
| }; | ||||
|  | ||||
| static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) | ||||
| { | ||||
| 	struct i2c_msg msg = {.addr = adr, .flags = 0, | ||||
| 			      .buf = data, .len = len}; | ||||
|  | ||||
| 	if (i2c_transfer(adap, &msg, 1) != 1) { | ||||
| 		pr_err("lnbh25: i2c_write error\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int lnbh25_write_regs(struct lnbh25 *lnbh, int reg, int len) | ||||
| { | ||||
| 	u8 d[5]; | ||||
|  | ||||
| 	memcpy(&d[1], &lnbh->reg[reg], len); | ||||
| 	d[0] = reg + 2; | ||||
| 	return i2c_write(lnbh->i2c, lnbh->adr, d, len + 1); | ||||
| } | ||||
|  | ||||
| static int lnbh25_set_voltage(struct dvb_frontend *fe, | ||||
| 			      fe_sec_voltage_t voltage) | ||||
| { | ||||
| 	struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv; | ||||
| 	u8 oldreg0 = lnbh->reg[0]; | ||||
|  | ||||
| 	switch (voltage) { | ||||
| 	case SEC_VOLTAGE_OFF: | ||||
| 		lnbh->reg[0] = 0x00; | ||||
| 		lnbh->reg[1] &= ~0x01;    /* Disable Tone */ | ||||
| 		lnbh->reg[2] = 0x00; | ||||
| 		return lnbh25_write_regs(lnbh, 0, 3); | ||||
| 	case SEC_VOLTAGE_13: | ||||
| 		lnbh->reg[0] = lnbh->boost + 1; | ||||
| 		break; | ||||
| 	case SEC_VOLTAGE_18: | ||||
| 		lnbh->reg[0] = lnbh->boost + 8; | ||||
| 		break; | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	}; | ||||
|  | ||||
| 	if (lnbh->reg[0] == 0x00) { | ||||
| 		lnbh->reg[2] = 4; | ||||
| 		lnbh25_write_regs(lnbh, 2, 2); | ||||
| 	} else if (lnbh->reg[2] != 0x00) { | ||||
| 		lnbh->reg[2] = 0; | ||||
| 		lnbh25_write_regs(lnbh, 2, 2); | ||||
| 	} | ||||
| 	lnbh->reg[1] |= 0x01; | ||||
| 	lnbh25_write_regs(lnbh, 0, 3); | ||||
| 	if (oldreg0 == 0)  | ||||
| 		msleep(100); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int lnbh25_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) | ||||
| { | ||||
| 	struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv; | ||||
|  | ||||
| 	lnbh->boost = arg ? 3 : 0; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int lnbh25_set_tone(struct dvb_frontend *fe, | ||||
| 			   fe_sec_tone_mode_t tone) | ||||
| { | ||||
| 	/* struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv; */ | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int lnbh25_init(struct lnbh25 *lnbh) | ||||
| { | ||||
| 	return lnbh25_write_regs(lnbh, 0, 2); | ||||
| } | ||||
|  | ||||
| static void lnbh25_release(struct dvb_frontend *fe) | ||||
| { | ||||
| 	kfree(fe->sec_priv); | ||||
| 	fe->sec_priv = NULL; | ||||
| } | ||||
|  | ||||
| struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, | ||||
| 				   struct i2c_adapter *i2c, | ||||
| 				   u8 adr) | ||||
| { | ||||
| 	struct lnbh25 *lnbh = kzalloc(sizeof(struct lnbh25), GFP_KERNEL); | ||||
| 	if (!lnbh) | ||||
| 		return NULL; | ||||
|  | ||||
| 	lnbh->i2c = i2c; | ||||
| 	lnbh->adr = adr; | ||||
| 	lnbh->boost = 3; | ||||
|  | ||||
| 	if (lnbh25_init(lnbh)) { | ||||
| 		kfree(lnbh); | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	fe->sec_priv = lnbh; | ||||
| 	fe->ops.set_voltage = lnbh25_set_voltage; | ||||
| 	fe->ops.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage; | ||||
| 	fe->ops.release_sec = lnbh25_release; | ||||
|  | ||||
| 	pr_info("LNB25 on %02x\n", lnbh->adr); | ||||
|  | ||||
| 	return fe; | ||||
| } | ||||
| EXPORT_SYMBOL(lnbh25_attach); | ||||
|  | ||||
| MODULE_DESCRIPTION("LNBH25"); | ||||
| MODULE_AUTHOR("Ralph Metzler"); | ||||
| MODULE_LICENSE("GPL"); | ||||
							
								
								
									
										28
									
								
								frontends/lnbh25.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								frontends/lnbh25.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| /* | ||||
|  * lnbh25.h | ||||
|  */ | ||||
|  | ||||
| #ifndef _LNBH25_H | ||||
| #define _LNBH25_H | ||||
|  | ||||
| #include <linux/dvb/frontend.h> | ||||
|  | ||||
| #if defined(CONFIG_DVB_LNBH25) || \ | ||||
| 	(defined(CONFIG_DVB_LNBH25_MODULE) && defined(MODULE)) | ||||
|  | ||||
| extern struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, | ||||
| 					  struct i2c_adapter *i2c, | ||||
| 					  u8 i2c_addr); | ||||
| #else | ||||
|  | ||||
| static inline struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, | ||||
| 						 struct i2c_adapter *i2c, | ||||
| 						 u8 i2c_addr) | ||||
| { | ||||
| 	pr_warn("%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										194
									
								
								frontends/lnbp21.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										194
									
								
								frontends/lnbp21.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,194 @@ | ||||
| /* | ||||
|  * lnbp21.c - driver for lnb supply and control ic lnbp21 | ||||
|  * | ||||
|  * Copyright (C) 2006, 2009 Oliver Endriss <o.endriss@gmx.de> | ||||
|  * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> | ||||
|  * | ||||
|  * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  * | ||||
|  * | ||||
|  * the project's page is at http://www.linuxtv.org | ||||
|  */ | ||||
| #include <linux/delay.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/init.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/string.h> | ||||
| #include <linux/slab.h> | ||||
|  | ||||
| #include "dvb_frontend.h" | ||||
| #include "lnbp21.h" | ||||
| #include "lnbh24.h" | ||||
|  | ||||
| struct lnbp21 { | ||||
| 	u8			config; | ||||
| 	u8			override_or; | ||||
| 	u8			override_and; | ||||
| 	struct i2c_adapter	*i2c; | ||||
| 	u8			i2c_addr; | ||||
| }; | ||||
|  | ||||
| static int lnbp21_set_voltage(struct dvb_frontend *fe, | ||||
| 					fe_sec_voltage_t voltage) | ||||
| { | ||||
| 	struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; | ||||
| 	struct i2c_msg msg = {	.addr = lnbp21->i2c_addr, .flags = 0, | ||||
| 				.buf = &lnbp21->config, | ||||
| 				.len = sizeof(lnbp21->config) }; | ||||
|  | ||||
| 	lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN); | ||||
|  | ||||
| 	 | ||||
| 	if ((lnbp21->config & LNBP21_EN) == 0) | ||||
| 		lnbp21->config |= 0x80; | ||||
| 	else | ||||
| 		lnbp21->config &= 0x7f; | ||||
|  | ||||
| 	switch(voltage) { | ||||
| 	case SEC_VOLTAGE_OFF: | ||||
| 		break; | ||||
| 	case SEC_VOLTAGE_13: | ||||
| 		lnbp21->config |= LNBP21_EN; | ||||
| 		break; | ||||
| 	case SEC_VOLTAGE_18: | ||||
| 		lnbp21->config |= (LNBP21_EN | LNBP21_VSEL); | ||||
| 		break; | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	}; | ||||
|  | ||||
| 	lnbp21->config |= lnbp21->override_or; | ||||
| 	lnbp21->config &= lnbp21->override_and; | ||||
|  | ||||
| 	return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||||
| } | ||||
|  | ||||
| static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) | ||||
| { | ||||
| 	struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; | ||||
| 	struct i2c_msg msg = {	.addr = lnbp21->i2c_addr, .flags = 0, | ||||
| 				.buf = &lnbp21->config, | ||||
| 				.len = sizeof(lnbp21->config) }; | ||||
|  | ||||
| 	if (arg) | ||||
| 		lnbp21->config |= LNBP21_LLC; | ||||
| 	else | ||||
| 		lnbp21->config &= ~LNBP21_LLC; | ||||
|  | ||||
| 	lnbp21->config |= lnbp21->override_or; | ||||
| 	lnbp21->config &= lnbp21->override_and; | ||||
|  | ||||
| 	return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||||
| } | ||||
|  | ||||
| static int lnbp21_set_tone(struct dvb_frontend *fe, | ||||
| 				fe_sec_tone_mode_t tone) | ||||
| { | ||||
| 	struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv; | ||||
| 	struct i2c_msg msg = {	.addr = lnbp21->i2c_addr, .flags = 0, | ||||
| 				.buf = &lnbp21->config, | ||||
| 				.len = sizeof(lnbp21->config) }; | ||||
|  | ||||
| 	switch (tone) { | ||||
| 	case SEC_TONE_OFF: | ||||
| 		lnbp21->config &= ~LNBP21_TEN; | ||||
| 		break; | ||||
| 	case SEC_TONE_ON: | ||||
| 		lnbp21->config |= LNBP21_TEN; | ||||
| 		break; | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	}; | ||||
|  | ||||
| 	lnbp21->config |= lnbp21->override_or; | ||||
| 	lnbp21->config &= lnbp21->override_and; | ||||
|  | ||||
| 	return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO; | ||||
| } | ||||
|  | ||||
| static void lnbp21_release(struct dvb_frontend *fe) | ||||
| { | ||||
| 	/* LNBP power off */ | ||||
| 	lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); | ||||
|  | ||||
| 	/* free data */ | ||||
| 	kfree(fe->sec_priv); | ||||
| 	fe->sec_priv = NULL; | ||||
| } | ||||
|  | ||||
| static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe, | ||||
| 				struct i2c_adapter *i2c, u8 override_set, | ||||
| 				u8 override_clear, u8 i2c_addr, u8 config) | ||||
| { | ||||
| 	struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); | ||||
| 	if (!lnbp21) | ||||
| 		return NULL; | ||||
|  | ||||
| 	/* default configuration */ | ||||
| 	lnbp21->config = config; | ||||
| 	lnbp21->i2c = i2c; | ||||
| 	lnbp21->i2c_addr = i2c_addr; | ||||
| 	fe->sec_priv = lnbp21; | ||||
|  | ||||
| 	/* bits which should be forced to '1' */ | ||||
| 	lnbp21->override_or = override_set; | ||||
|  | ||||
| 	/* bits which should be forced to '0' */ | ||||
| 	lnbp21->override_and = ~override_clear; | ||||
|  | ||||
| 	/* detect if it is present or not */ | ||||
| 	if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) { | ||||
| 		kfree(lnbp21); | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	/* install release callback */ | ||||
| 	fe->ops.release_sec = lnbp21_release; | ||||
|  | ||||
| 	/* override frontend ops */ | ||||
| 	fe->ops.set_voltage = lnbp21_set_voltage; | ||||
| 	fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; | ||||
| 	if (!(override_clear & LNBH24_TEN)) /*22kHz logic controlled by demod*/ | ||||
| 		fe->ops.set_tone = lnbp21_set_tone; | ||||
| 	printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr); | ||||
|  | ||||
| 	return fe; | ||||
| } | ||||
|  | ||||
| struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe, | ||||
| 				struct i2c_adapter *i2c, u8 override_set, | ||||
| 				u8 override_clear, u8 i2c_addr) | ||||
| { | ||||
| 	return lnbx2x_attach(fe, i2c, override_set, override_clear, | ||||
| 			     i2c_addr, LNBH24_TTX); | ||||
| } | ||||
| EXPORT_SYMBOL(lnbh24_attach); | ||||
|  | ||||
| struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, | ||||
| 				struct i2c_adapter *i2c, u8 override_set, | ||||
| 				u8 override_clear) | ||||
| { | ||||
| 	return lnbx2x_attach(fe, i2c, override_set, override_clear, | ||||
| 			     0x08, LNBP21_ISEL); | ||||
| } | ||||
| EXPORT_SYMBOL(lnbp21_attach); | ||||
|  | ||||
| MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24"); | ||||
| MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin"); | ||||
| MODULE_LICENSE("GPL"); | ||||
							
								
								
									
										75
									
								
								frontends/lnbp21.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								frontends/lnbp21.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| /* | ||||
|  * lnbp21.h - driver for lnb supply and control ic lnbp21 | ||||
|  * | ||||
|  * Copyright (C) 2006 Oliver Endriss | ||||
|  * | ||||
|  * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  * | ||||
|  * | ||||
|  * the project's page is at http://www.linuxtv.org | ||||
|  */ | ||||
|  | ||||
| #ifndef _LNBP21_H | ||||
| #define _LNBP21_H | ||||
|  | ||||
| /* system register bits */ | ||||
| /* [RO] 0=OK; 1=over current limit flag */ | ||||
| #define LNBP21_OLF	0x01 | ||||
| /* [RO] 0=OK; 1=over temperature flag (150 C) */ | ||||
| #define LNBP21_OTF	0x02 | ||||
| /* [RW] 0=disable LNB power, enable loopthrough | ||||
| 	1=enable LNB power, disable loopthrough */ | ||||
| #define LNBP21_EN	0x04 | ||||
| /* [RW] 0=low voltage (13/14V, vert pol) | ||||
| 	1=high voltage (18/19V,horiz pol) */ | ||||
| #define LNBP21_VSEL	0x08 | ||||
| /* [RW] increase LNB voltage by 1V: | ||||
| 	0=13/18V; 1=14/19V */ | ||||
| #define LNBP21_LLC	0x10 | ||||
| /* [RW] 0=tone controlled by DSQIN pin | ||||
| 	1=tone enable, disable DSQIN */ | ||||
| #define LNBP21_TEN	0x20 | ||||
| /* [RW] current limit select: | ||||
| 	0:Iout=500-650mA Isc=300mA | ||||
| 	1:Iout=400-550mA Isc=200mA */ | ||||
| #define LNBP21_ISEL	0x40 | ||||
| /* [RW] short-circuit protect: | ||||
| 	0=pulsed (dynamic) curr limiting | ||||
| 	1=static curr limiting */ | ||||
| #define LNBP21_PCL	0x80 | ||||
|  | ||||
| #include <linux/dvb/frontend.h> | ||||
|  | ||||
| #if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \ | ||||
| 							&& defined(MODULE)) | ||||
| /* override_set and override_clear control which | ||||
|  system register bits (above) to always set & clear */ | ||||
| extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, | ||||
| 				struct i2c_adapter *i2c, u8 override_set, | ||||
| 				u8 override_clear); | ||||
| #else | ||||
| static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, | ||||
| 				struct i2c_adapter *i2c, u8 override_set, | ||||
| 				u8 override_clear) | ||||
| { | ||||
| 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										1735
									
								
								frontends/mxl5xx.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1735
									
								
								frontends/mxl5xx.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										39
									
								
								frontends/mxl5xx.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								frontends/mxl5xx.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| #ifndef _MXL5XX_H_ | ||||
| #define _MXL5XX_H_ | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/i2c.h> | ||||
|  | ||||
| struct mxl5xx_cfg { | ||||
| 	u8   adr; | ||||
| 	u8   type; | ||||
| 	u32  cap; | ||||
| 	u32  clk; | ||||
| 	u32  ts_clk; | ||||
| 	 | ||||
| 	u8  *fw; | ||||
| 	u32  fw_len; | ||||
|  | ||||
| 	int (*fw_read)(void *priv, u8 *buf, u32 len); | ||||
| 	void *fw_priv; | ||||
| }; | ||||
|  | ||||
| #if defined(CONFIG_DVB_MXL5XX) || \ | ||||
| 	(defined(CONFIG_DVB_MXL5XX_MODULE) && defined(MODULE)) | ||||
|  | ||||
| extern struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, | ||||
| 					  struct mxl5xx_cfg *cfg, | ||||
| 					  u32 demod, u32 tuner); | ||||
| #else | ||||
|  | ||||
| static inline struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, | ||||
| 						 struct mxl5xx_cfg *cfg, | ||||
| 						 u32 demod, u32 tuner) | ||||
| { | ||||
| 	pr_warn("%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										819
									
								
								frontends/mxl5xx_defs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										819
									
								
								frontends/mxl5xx_defs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,819 @@ | ||||
| /* | ||||
|  * Defines for the Maxlinear MX58x family of tuners/demods | ||||
|  * | ||||
|  * Copyright (C) 2014 Digital Devices GmbH | ||||
|  * | ||||
|  * based on code: | ||||
|  * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved | ||||
|  * which was released under GPL V2 | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License | ||||
|  * version 2, as published by the Free Software Foundation. | ||||
|  */ | ||||
|  | ||||
| typedef enum  | ||||
| { | ||||
|   MXL_DISABLE = 0, | ||||
|   MXL_ENABLE  = 1,   | ||||
|          | ||||
|   MXL_FALSE = 0, | ||||
|   MXL_TRUE  = 1,   | ||||
|  | ||||
|   MXL_INVALID = 0, | ||||
|   MXL_VALID   = 1, | ||||
|  | ||||
|   MXL_NO      = 0, | ||||
|   MXL_YES     = 1,   | ||||
|    | ||||
|   MXL_OFF     = 0, | ||||
|   MXL_ON      = 1   | ||||
| } MXL_BOOL_E; | ||||
|  | ||||
| // Firmware-Host Command IDs | ||||
| typedef enum | ||||
| { | ||||
|   //--Device command IDs-- | ||||
|   MXL_HYDRA_DEV_NO_OP_CMD = 0, //No OP | ||||
|  | ||||
|   MXL_HYDRA_DEV_SET_POWER_MODE_CMD = 1, | ||||
|   MXL_HYDRA_DEV_SET_OVERWRITE_DEF_CMD = 2, | ||||
|  | ||||
|   // Host-used CMD, not used by firmware | ||||
|   MXL_HYDRA_DEV_FIRMWARE_DOWNLOAD_CMD = 3, | ||||
|  | ||||
|   // Additional CONTROL types from DTV | ||||
|   MXL_HYDRA_DEV_SET_BROADCAST_PID_STB_ID_CMD = 4, | ||||
|   MXL_HYDRA_DEV_GET_PMM_SLEEP_CMD = 5, | ||||
|  | ||||
|   //--Tuner command IDs-- | ||||
|   MXL_HYDRA_TUNER_TUNE_CMD = 6, | ||||
|   MXL_HYDRA_TUNER_GET_STATUS_CMD = 7, | ||||
|  | ||||
|   //--Demod command IDs-- | ||||
|   MXL_HYDRA_DEMOD_SET_PARAM_CMD = 8, | ||||
|   MXL_HYDRA_DEMOD_GET_STATUS_CMD = 9, | ||||
|  | ||||
|   MXL_HYDRA_DEMOD_RESET_FEC_COUNTER_CMD = 10, | ||||
|  | ||||
|   MXL_HYDRA_DEMOD_SET_PKT_NUM_CMD = 11, | ||||
|  | ||||
|   MXL_HYDRA_DEMOD_SET_IQ_SOURCE_CMD = 12, | ||||
|   MXL_HYDRA_DEMOD_GET_IQ_DATA_CMD = 13, | ||||
|  | ||||
|   MXL_HYDRA_DEMOD_GET_M68HC05_VER_CMD = 14, | ||||
|  | ||||
|   MXL_HYDRA_DEMOD_SET_ERROR_COUNTER_MODE_CMD = 15, | ||||
|  | ||||
|   //--- ABORT channel tune | ||||
|   MXL_HYDRA_ABORT_TUNE_CMD = 16, // Abort current tune command. | ||||
|  | ||||
|   //--SWM/FSK command IDs-- | ||||
|   MXL_HYDRA_FSK_RESET_CMD = 17, | ||||
|   MXL_HYDRA_FSK_MSG_CMD = 18, | ||||
|   MXL_HYDRA_FSK_SET_OP_MODE_CMD = 19, | ||||
|  | ||||
|   //--DiSeqC command IDs-- | ||||
|   MXL_HYDRA_DISEQC_MSG_CMD = 20, | ||||
|   MXL_HYDRA_DISEQC_COPY_MSG_TO_MAILBOX = 21, | ||||
|   MXL_HYDRA_DISEQC_CFG_MSG_CMD = 22, | ||||
|  | ||||
|   //--- FFT Debug Command IDs-- | ||||
|   MXL_HYDRA_REQ_FFT_SPECTRUM_CMD = 23, | ||||
|  | ||||
|   // -- Demod scramblle code | ||||
|   MXL_HYDRA_DEMOD_SCRAMBLE_CODE_CMD = 24, | ||||
|  | ||||
|   //---For host to know how many commands in total--- | ||||
|   MXL_HYDRA_LAST_HOST_CMD = 25, | ||||
|  | ||||
|   MXL_HYDRA_DEMOD_INTR_TYPE_CMD = 47, | ||||
|   MXL_HYDRA_DEV_INTR_CLEAR_CMD = 48, | ||||
|   MXL_HYDRA_TUNER_SPECTRUM_REQ_CMD = 53, | ||||
|   MXL_HYDRA_TUNER_ACTIVATE_CMD = 55, | ||||
|   MXL_HYDRA_DEV_CFG_POWER_MODE_CMD = 56, | ||||
|   MXL_HYDRA_DEV_XTAL_CAP_CMD = 57, | ||||
|   MXL_HYDRA_DEV_CFG_SKU_CMD = 58, | ||||
|   MXL_HYDRA_TUNER_SPECTRUM_MIN_GAIN_CMD = 59, | ||||
|   MXL_HYDRA_DISEQC_CONT_TONE_CFG = 60, | ||||
|   MXL_HYDRA_DEV_RF_WAKE_UP_CMD = 61, | ||||
|   MXL_HYDRA_DEMOD_CFG_EQ_CTRL_PARAM_CMD = 62, | ||||
|   MXL_HYDRA_DEMOD_FREQ_OFFSET_SEARCH_RANGE_CMD = 63, | ||||
|   MXL_HYDRA_DEV_REQ_PWR_FROM_ADCRSSI_CMD = 64, | ||||
|  | ||||
|   MXL_XCPU_PID_FLT_CFG_CMD = 65, | ||||
|   MXL_XCPU_SHMEM_TEST_CMD = 66, | ||||
|   MXL_XCPU_ABORT_TUNE_CMD = 67, | ||||
|   MXL_XCPU_CHAN_TUNE_CMD = 68, | ||||
|   MXL_XCPU_FLT_BOND_HDRS_CMD = 69, | ||||
|  | ||||
|   MXL_HYDRA_DEV_BROADCAST_WAKE_UP_CMD = 70, | ||||
|   MXL_HYDRA_FSK_CFG_FSK_FREQ_CMD = 71, | ||||
|   MXL_HYDRA_FSK_POWER_DOWN_CMD = 72, | ||||
|   MXL_XCPU_CLEAR_CB_STATS_CMD = 73, | ||||
|   MXL_XCPU_CHAN_BOND_RESTART_CMD = 74 | ||||
| } MXL_HYDRA_HOST_CMD_ID_E; | ||||
|  | ||||
| #define MXL_ENABLE_BIG_ENDIAN        (0) | ||||
|  | ||||
| #define MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH   248 | ||||
|  | ||||
| #define MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN        (248) | ||||
|  | ||||
| #define MXL_HYDRA_CAP_MIN     10 | ||||
| #define MXL_HYDRA_CAP_MAX     33 | ||||
|  | ||||
| #define MXL_HYDRA_PLID_REG_READ       0xFB   // Read register PLID | ||||
| #define MXL_HYDRA_PLID_REG_WRITE      0xFC   // Write register PLID | ||||
|  | ||||
| #define MXL_HYDRA_PLID_CMD_READ       0xFD   // Command Read PLID | ||||
| #define MXL_HYDRA_PLID_CMD_WRITE      0xFE   // Command Write PLID | ||||
|  | ||||
| #define MXL_HYDRA_REG_SIZE_IN_BYTES   4      // Hydra register size in bytes | ||||
| #define MXL_HYDRA_I2C_HDR_SIZE        (2 * sizeof(u8))   // PLID + LEN(0xFF) | ||||
| #define MXL_HYDRA_CMD_HEADER_SIZE     (MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE) | ||||
|  | ||||
| #define MXL_HYDRA_SKU_ID_581 0 | ||||
| #define MXL_HYDRA_SKU_ID_584 1 | ||||
| #define MXL_HYDRA_SKU_ID_585 2 | ||||
| #define MXL_HYDRA_SKU_ID_544 3 | ||||
| #define MXL_HYDRA_SKU_ID_561 4 | ||||
| #define MXL_HYDRA_SKU_ID_582 5 | ||||
| #define MXL_HYDRA_SKU_ID_568 6 | ||||
|  | ||||
| // macro for register write data buffer size (PLID + LEN (0xFF) + RegAddr + RegData) | ||||
| #define MXL_HYDRA_REG_WRITE_LEN       (MXL_HYDRA_I2C_HDR_SIZE + (2 * MXL_HYDRA_REG_SIZE_IN_BYTES))  | ||||
|  | ||||
| // maro to extract a single byte from 4-byte(32-bit) data | ||||
| #define GET_BYTE(x,n)  (((x) >> (8*(n))) & 0xFF) | ||||
|  | ||||
| #define MAX_CMD_DATA 512 | ||||
|  | ||||
| #define MXL_GET_REG_MASK_32(lsbLoc,numOfBits) ((0xFFFFFFFF >> (32 - (numOfBits))) << (lsbLoc)) | ||||
|  | ||||
| #define GET_REG_FIELD_DATA(fieldName, dataPtr) read_by_mnemonic(state, fieldName, dataPtr); | ||||
| #define SET_REG_FIELD_DATA(fieldName, data) update_by_mnemonic(state, fieldName, data); | ||||
|  | ||||
| #define FW_DL_SIGN (0xDEADBEEF) | ||||
|  | ||||
| #define MBIN_FORMAT_VERSION               '1' | ||||
| #define MBIN_FILE_HEADER_ID               'M' | ||||
| #define MBIN_SEGMENT_HEADER_ID            'S' | ||||
| #define MBIN_MAX_FILE_LENGTH              (1<<23) | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| 	u8 id;                  | ||||
| 	u8 fmtVersion;          | ||||
| 	u8 headerLen;           | ||||
| 	u8 numSegments;         | ||||
| 	u8 entryAddress[4];     | ||||
| 	u8 imageSize24[3];      | ||||
| 	u8 imageChecksum;       | ||||
| 	u8 reserved[4];         | ||||
| } MBIN_FILE_HEADER_T; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| 	MBIN_FILE_HEADER_T  header;     | ||||
| 	u8 data[1];                  | ||||
| } MBIN_FILE_T; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| 	u8 id;                       | ||||
| 	u8 len24[3];                 | ||||
| 	u8 address[4];               | ||||
| } MBIN_SEGMENT_HEADER_T; | ||||
|  | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| 	MBIN_SEGMENT_HEADER_T header;   | ||||
| 	u8 data[1];                  | ||||
| } MBIN_SEGMENT_T; | ||||
|  | ||||
|  | ||||
| typedef enum { MXL_CMD_WRITE = 0, MXL_CMD_READ} MXL_CMD_TYPE_E; | ||||
|  | ||||
| #define BUILD_HYDRA_CMD(cmdID, reqType, size, dataPtr, cmdBuff)		\ | ||||
| 	do {								\ | ||||
| 		cmdBuff[0] = ((reqType == MXL_CMD_WRITE) ? MXL_HYDRA_PLID_CMD_WRITE : MXL_HYDRA_PLID_CMD_READ); \ | ||||
| 		cmdBuff[1] = (size > 251) ? 0xff : (u8) (size + 4);	\ | ||||
| 		cmdBuff[2] = size;					\ | ||||
| 		cmdBuff[3] = cmdID;					\ | ||||
| 		cmdBuff[4] = 0x00;					\ | ||||
| 		cmdBuff[5] = 0x00;					\ | ||||
| 		convert_endian(MXL_ENABLE_BIG_ENDIAN, size, (u8 *)dataPtr); \ | ||||
| 		memcpy((void *)&cmdBuff[6], dataPtr, size);		\ | ||||
| 	} while(0) //; | ||||
|  | ||||
| typedef struct { | ||||
| 	u32 regAddr; | ||||
| 	u8 lsbPos; | ||||
| 	u8 numOfBits; | ||||
| } MXL_REG_FIELD_T; | ||||
|  | ||||
| typedef struct { | ||||
| 	u32 dataSize; | ||||
| 	u8 data[MAX_CMD_DATA]; | ||||
| } MXL_DEV_CMD_DATA_T; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_SKU_TYPE_MIN = 0x00, | ||||
|   MXL_HYDRA_SKU_TYPE_581 = 0x00, | ||||
|   MXL_HYDRA_SKU_TYPE_584 = 0x01, | ||||
|   MXL_HYDRA_SKU_TYPE_585 = 0x02, | ||||
|   MXL_HYDRA_SKU_TYPE_544 = 0x03, | ||||
|   MXL_HYDRA_SKU_TYPE_561 = 0x04, | ||||
|   MXL_HYDRA_SKU_TYPE_5xx = 0x05, | ||||
|   MXL_HYDRA_SKU_TYPE_5yy = 0x06, | ||||
|   MXL_HYDRA_SKU_TYPE_511 = 0x07, | ||||
|   MXL_HYDRA_SKU_TYPE_561_DE = 0x08, | ||||
|   MXL_HYDRA_SKU_TYPE_582 = 0x09, | ||||
|   MXL_HYDRA_SKU_TYPE_541 = 0x0A, | ||||
|   MXL_HYDRA_SKU_TYPE_568 = 0x0B, | ||||
|   MXL_HYDRA_SKU_TYPE_542 = 0x0C, | ||||
|   MXL_HYDRA_SKU_TYPE_MAX = 0x0D, | ||||
| } MXL_HYDRA_SKU_TYPE_E; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   MXL_HYDRA_SKU_TYPE_E skuType; | ||||
| } MXL_HYDRA_SKU_COMMAND_T; | ||||
|  | ||||
|  | ||||
| typedef  enum  | ||||
| { | ||||
|   MXL_HYDRA_DEMOD_ID_0 = 0, | ||||
|   MXL_HYDRA_DEMOD_ID_1, | ||||
|   MXL_HYDRA_DEMOD_ID_2, | ||||
|   MXL_HYDRA_DEMOD_ID_3, | ||||
|   MXL_HYDRA_DEMOD_ID_4, | ||||
|   MXL_HYDRA_DEMOD_ID_5, | ||||
|   MXL_HYDRA_DEMOD_ID_6, | ||||
|   MXL_HYDRA_DEMOD_ID_7, | ||||
|   MXL_HYDRA_DEMOD_MAX | ||||
| } MXL_HYDRA_DEMOD_ID_E; | ||||
|  | ||||
| #define MXL_DEMOD_SCRAMBLE_SEQ_LEN  12 | ||||
|  | ||||
| #define MAX_STEP_SIZE_24_XTAL_102_05_KHZ  195 | ||||
| #define MAX_STEP_SIZE_24_XTAL_204_10_KHZ  215 | ||||
| #define MAX_STEP_SIZE_24_XTAL_306_15_KHZ  203 | ||||
| #define MAX_STEP_SIZE_24_XTAL_408_20_KHZ  177 | ||||
|  | ||||
| #define MAX_STEP_SIZE_27_XTAL_102_05_KHZ  195 | ||||
| #define MAX_STEP_SIZE_27_XTAL_204_10_KHZ  215 | ||||
| #define MAX_STEP_SIZE_27_XTAL_306_15_KHZ  203 | ||||
| #define MAX_STEP_SIZE_27_XTAL_408_20_KHZ  177 | ||||
|  | ||||
| #define MXL_HYDRA_SPECTRUM_MIN_FREQ_KHZ  300000 | ||||
| #define MXL_HYDRA_SPECTRUM_MAX_FREQ_KHZ 2350000 | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   DMD_STANDARD_ADDR = 0, | ||||
|   DMD_SPECTRUM_INVERSION_ADDR, | ||||
|   DMD_SPECTRUM_ROLL_OFF_ADDR, | ||||
|   DMD_SYMBOL_RATE_ADDR, | ||||
|   DMD_MODULATION_SCHEME_ADDR, | ||||
|   DMD_FEC_CODE_RATE_ADDR, | ||||
|   DMD_SNR_ADDR, | ||||
|   DMD_FREQ_OFFSET_ADDR, | ||||
|   DMD_CTL_FREQ_OFFSET_ADDR, | ||||
|   DMD_STR_FREQ_OFFSET_ADDR, | ||||
|   DMD_FTL_FREQ_OFFSET_ADDR, | ||||
|   DMD_STR_NBC_SYNC_LOCK_ADDR, | ||||
|   DMD_CYCLE_SLIP_COUNT_ADDR, | ||||
|   DMD_DISPLAY_IQ_ADDR, | ||||
|   DMD_DVBS2_CRC_ERRORS_ADDR, | ||||
|   DMD_DVBS2_PER_COUNT_ADDR, | ||||
|   DMD_DVBS2_PER_WINDOW_ADDR, | ||||
|   DMD_DVBS_CORR_RS_ERRORS_ADDR, | ||||
|   DMD_DVBS_UNCORR_RS_ERRORS_ADDR, | ||||
|   DMD_DVBS_BER_COUNT_ADDR, | ||||
|   DMD_DVBS_BER_WINDOW_ADDR, | ||||
|   DMD_TUNER_ID_ADDR, | ||||
|   DMD_DVBS2_PILOT_ON_OFF_ADDR, | ||||
|   DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR, | ||||
|  | ||||
|   MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE, | ||||
| } MXL_DEMOD_CHAN_PARAMS_OFFSET_E; | ||||
|  | ||||
| typedef enum  | ||||
| { | ||||
|   MXL_HYDRA_TUNER_ID_0 = 0, | ||||
|   MXL_HYDRA_TUNER_ID_1, | ||||
|   MXL_HYDRA_TUNER_ID_2, | ||||
|   MXL_HYDRA_TUNER_ID_3, | ||||
|   MXL_HYDRA_TUNER_MAX | ||||
| } MXL_HYDRA_TUNER_ID_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_DSS = 0,   | ||||
|   MXL_HYDRA_DVBS, | ||||
|   MXL_HYDRA_DVBS2, | ||||
| } MXL_HYDRA_BCAST_STD_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_FEC_AUTO = 0, | ||||
|   MXL_HYDRA_FEC_1_2, | ||||
|   MXL_HYDRA_FEC_3_5, | ||||
|   MXL_HYDRA_FEC_2_3, | ||||
|   MXL_HYDRA_FEC_3_4,  | ||||
|   MXL_HYDRA_FEC_4_5, | ||||
|   MXL_HYDRA_FEC_5_6, | ||||
|   MXL_HYDRA_FEC_6_7,  | ||||
|   MXL_HYDRA_FEC_7_8, | ||||
|   MXL_HYDRA_FEC_8_9, | ||||
|   MXL_HYDRA_FEC_9_10, | ||||
| } MXL_HYDRA_FEC_E; | ||||
|  | ||||
| typedef enum  | ||||
| { | ||||
|   MXL_HYDRA_MOD_AUTO = 0, | ||||
|   MXL_HYDRA_MOD_QPSK, | ||||
|   MXL_HYDRA_MOD_8PSK | ||||
| } MXL_HYDRA_MODULATION_E; | ||||
|  | ||||
| typedef enum  | ||||
| { | ||||
|   MXL_HYDRA_SPECTRUM_AUTO = 0, | ||||
|   MXL_HYDRA_SPECTRUM_INVERTED, | ||||
|   MXL_HYDRA_SPECTRUM_NON_INVERTED, | ||||
| } MXL_HYDRA_SPECTRUM_E; | ||||
|  | ||||
| typedef enum  | ||||
| { | ||||
|   MXL_HYDRA_ROLLOFF_AUTO  = 0, | ||||
|   MXL_HYDRA_ROLLOFF_0_20, | ||||
|   MXL_HYDRA_ROLLOFF_0_25, | ||||
|   MXL_HYDRA_ROLLOFF_0_35 | ||||
| } MXL_HYDRA_ROLLOFF_E; | ||||
|  | ||||
| typedef enum  | ||||
| { | ||||
|   MXL_HYDRA_PILOTS_OFF  = 0, | ||||
|   MXL_HYDRA_PILOTS_ON, | ||||
|   MXL_HYDRA_PILOTS_AUTO | ||||
| } MXL_HYDRA_PILOTS_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_FORMATTER = 0, | ||||
|   MXL_HYDRA_LEGACY_FEC, | ||||
|   MXL_HYDRA_FREQ_RECOVERY, | ||||
|   MXL_HYDRA_NBC, | ||||
|   MXL_HYDRA_CTL,  | ||||
|   MXL_HYDRA_EQ, | ||||
| } MXL_HYDRA_CONSTELLATION_SRC_E; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   int agcLock;     // AGC lock info | ||||
|   int fecLock;     // Demod FEC block lock info | ||||
| } MXL_HYDRA_DEMOD_LOCK_T; | ||||
|  | ||||
| typedef struct  | ||||
| { | ||||
|   u32 rsErrors;          // RS decoder err counter | ||||
|   u32 berWindow;         // Ber Windows | ||||
|   u32 berCount;          // BER count | ||||
|   u32 berWindow_Iter1;   // Ber Windows - post viterbi | ||||
|   u32 berCount_Iter1;    // BER count - post viterbi | ||||
| } MXL_HYDRA_DEMOD_STATUS_DVBS_T; | ||||
|  | ||||
| typedef struct  | ||||
| { | ||||
|   u32 rsErrors;    // RS decoder err counter | ||||
|   u32 berWindow;   // Ber Windows | ||||
|   u32 berCount;    // BER count | ||||
| } MXL_HYDRA_DEMOD_STATUS_DSS_T; | ||||
|  | ||||
| typedef struct  | ||||
| { | ||||
|   u32 crcErrors;         // CRC error counter | ||||
|   u32 packetErrorCount;  // Number of packet errors  | ||||
|   u32 totalPackets;      // Total packets    | ||||
| } MXL_HYDRA_DEMOD_STATUS_DVBS2_T; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   MXL_HYDRA_BCAST_STD_E standardMask;                // Standard DVB-S, DVB-S2 or DSS | ||||
|  | ||||
|   union | ||||
|   { | ||||
|     MXL_HYDRA_DEMOD_STATUS_DVBS_T demodStatus_DVBS;    // DVB-S demod status | ||||
|     MXL_HYDRA_DEMOD_STATUS_DVBS2_T demodStatus_DVBS2;  // DVB-S2 demod status | ||||
|     MXL_HYDRA_DEMOD_STATUS_DSS_T demodStatus_DSS;      // DSS demod status | ||||
|   } u; | ||||
|  | ||||
| } MXL_HYDRA_DEMOD_STATUS_T; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   s32 carrierOffsetInHz;       // CRL offset info | ||||
|   s32 symbolOffsetInSymbol;    // SRL offset info  | ||||
| } MXL_HYDRA_DEMOD_SIG_OFFSET_INFO_T; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   u8 scrambleSequence[MXL_DEMOD_SCRAMBLE_SEQ_LEN];   // scramble sequence | ||||
|   u32 scrambleCode;                                  // scramble gold code  | ||||
| } MXL_HYDRA_DEMOD_SCRAMBLE_INFO_T; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_STEP_SIZE_24_XTAL_102_05KHZ,  // 102.05 KHz for 24 MHz XTAL  | ||||
|   MXL_HYDRA_STEP_SIZE_24_XTAL_204_10KHZ,  // 204.10 KHz for 24 MHz XTAL  | ||||
|   MXL_HYDRA_STEP_SIZE_24_XTAL_306_15KHZ,  // 306.15 KHz for 24 MHz XTAL  | ||||
|   MXL_HYDRA_STEP_SIZE_24_XTAL_408_20KHZ,  // 408.20 KHz for 24 MHz XTAL  | ||||
|  | ||||
|   MXL_HYDRA_STEP_SIZE_27_XTAL_102_05KHZ,  // 102.05 KHz for 27 MHz XTAL  | ||||
|   MXL_HYDRA_STEP_SIZE_27_XTAL_204_35KHZ,  // 204.35 KHz for 27 MHz XTAL  | ||||
|   MXL_HYDRA_STEP_SIZE_27_XTAL_306_52KHZ,  // 306.52 KHz for 27 MHz XTAL  | ||||
|   MXL_HYDRA_STEP_SIZE_27_XTAL_408_69KHZ,  // 408.69 KHz for 27 MHz XTAL  | ||||
|  | ||||
| } MXL_HYDRA_SPECTRUM_STEP_SIZE_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_SPECTRUM_RESOLUTION_00_1_DB, // 0.1 dB | ||||
|   MXL_HYDRA_SPECTRUM_RESOLUTION_01_0_DB, // 1.0 dB | ||||
|   MXL_HYDRA_SPECTRUM_RESOLUTION_05_0_DB, // 5.0 dB | ||||
|   MXL_HYDRA_SPECTRUM_RESOLUTION_10_0_DB, // 10 dB | ||||
| } MXL_HYDRA_SPECTRUM_RESOLUTION_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|     MXL_SPECTRUM_NO_ERROR, | ||||
|     MXL_SPECTRUM_INVALID_PARAMETER, | ||||
|     MXL_SPECTRUM_INVALID_STEP_SIZE, | ||||
|     MXL_SPECTRUM_BW_CANNOT_BE_COVERED, | ||||
|     MXL_SPECTRUM_DEMOD_BUSY, | ||||
|     MXL_SPECTRUM_TUNER_NOT_ENABLED, | ||||
|   | ||||
| } MXL_HYDRA_SPECTRUM_ERROR_CODE_E; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   u32 tunerIndex;        // TUNER Ctrl: one of MXL58x_TUNER_ID_E  | ||||
|   u32 demodIndex;        // DEMOD Ctrl: one of MXL58x_DEMOD_ID_E   | ||||
|   MXL_HYDRA_SPECTRUM_STEP_SIZE_E stepSizeInKHz; | ||||
|   u32 startingFreqInkHz; | ||||
|   u32 totalSteps; | ||||
|   MXL_HYDRA_SPECTRUM_RESOLUTION_E spectrumDivision; | ||||
| } MXL_HYDRA_SPECTRUM_REQ_T; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|  MXL_HYDRA_SEARCH_MAX_OFFSET = 0, // DMD searches for max freq offset (i.e. 5MHz) | ||||
|  MXL_HYDRA_SEARCH_BW_PLUS_ROLLOFF, // DMD searches for BW + ROLLOFF/2 | ||||
| } MXL_HYDRA_SEARCH_FREQ_OFFSET_TYPE_E; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   u32 demodIndex; | ||||
|   MXL_HYDRA_SEARCH_FREQ_OFFSET_TYPE_E searchType; | ||||
| } MXL58x_CFG_FREQ_OFF_SEARCH_RANGE_T; | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| // there are two slices | ||||
| // slice0 - TS0, TS1, TS2 & TS3 | ||||
| // slice1 - TS4, TS5, TS6 & TS7 | ||||
| #define MXL_HYDRA_TS_SLICE_MAX  2 | ||||
|  | ||||
| #define MAX_FIXED_PID_NUM   32 | ||||
|  | ||||
| #define MXL_HYDRA_NCO_CLK   418 // 418 MHz | ||||
|  | ||||
| #define MXL_HYDRA_MAX_TS_CLOCK  139 // 139 MHz | ||||
|  | ||||
| #define MXL_HYDRA_TS_FIXED_PID_FILT_SIZE          32 | ||||
|  | ||||
| #define MXL_HYDRA_SHARED_PID_FILT_SIZE_DEFAULT    33   // Shared PID filter size in 1-1 mux mode | ||||
| #define MXL_HYDRA_SHARED_PID_FILT_SIZE_2_TO_1     66   // Shared PID filter size in 2-1 mux mode | ||||
| #define MXL_HYDRA_SHARED_PID_FILT_SIZE_4_TO_1     132  // Shared PID filter size in 4-1 mux mode | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_SOFTWARE_PID_BANK = 0, | ||||
|   MXL_HYDRA_HARDWARE_PID_BANK, | ||||
| } MXL_HYDRA_PID_BANK_TYPE_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_TS_MUX_PID_REMAP = 0,    | ||||
|   MXL_HYDRA_TS_MUX_PREFIX_EXTRA_HEADER = 1,    | ||||
| } MXL_HYDRA_TS_MUX_MODE_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_TS_MUX_DISABLE = 0,  // No Mux ( 1 TSIF to 1 TSIF) | ||||
|   MXL_HYDRA_TS_MUX_2_TO_1,       // Mux 2 TSIF to 1 TSIF | ||||
|   MXL_HYDRA_TS_MUX_4_TO_1,       // Mux 4 TSIF to 1 TSIF | ||||
| } MXL_HYDRA_TS_MUX_TYPE_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_TS_GROUP_0_3 = 0,     // TS group 0 to 3 (TS0, TS1, TS2 & TS3) | ||||
|   MXL_HYDRA_TS_GROUP_4_7,         // TS group 0 to 3 (TS4, TS5, TS6 & TS7) | ||||
| } MXL_HYDRA_TS_GROUP_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_TS_PIDS_ALLOW_ALL = 0,    // Allow all pids | ||||
|   MXL_HYDRA_TS_PIDS_DROP_ALL,         // Drop all pids | ||||
|   MXL_HYDRA_TS_INVALIDATE_PID_FILTER, // Delete current PD filter in the device | ||||
|  | ||||
| } MXL_HYDRA_TS_PID_FLT_CTRL_E; | ||||
|  | ||||
| typedef enum | ||||
| {  | ||||
|   MXL_HYDRA_TS_PID_FIXED = 0, | ||||
|   MXL_HYDRA_TS_PID_REGULAR, | ||||
| } MXL_HYDRA_TS_PID_TYPE_E; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| 	u16 originalPid;           // pid from TS | ||||
| 	u16 remappedPid;           // remapped pid | ||||
| 	MXL_BOOL_E enable;            // enable or disable pid | ||||
| 	MXL_BOOL_E allowOrDrop;       // allow or drop pid | ||||
| 	MXL_BOOL_E enablePidRemap;    // enable or disable pid remap | ||||
| 	u8 bondId;                 // Bond ID in A0 always 0 - Only for 568 Sku | ||||
| 	u8 destId;                 // Output port ID for the PID - Only for 568 Sku | ||||
| } MXL_HYDRA_TS_PID_T; | ||||
|  | ||||
| typedef struct | ||||
| {   | ||||
|   MXL_BOOL_E enable; | ||||
|   u8 numByte; | ||||
|   u8 header[12]; | ||||
| } MXL_HYDRA_TS_MUX_PREFIX_HEADER_T; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_PID_BANK_A = 0, | ||||
|   MXL_HYDRA_PID_BANK_B, | ||||
| } MXL_HYDRA_PID_FILTER_BANK_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_MPEG_SERIAL_MSB_1ST = 0, | ||||
|   MXL_HYDRA_MPEG_SERIAL_LSB_1ST, | ||||
|    | ||||
|   MXL_HYDRA_MPEG_SYNC_WIDTH_BIT = 0, | ||||
|   MXL_HYDRA_MPEG_SYNC_WIDTH_BYTE | ||||
| } MXL_HYDRA_MPEG_DATA_FMT_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_MPEG_MODE_SERIAL_4_WIRE = 0,   // MPEG 4 Wire serial mode | ||||
|   MXL_HYDRA_MPEG_MODE_SERIAL_3_WIRE,       // MPEG 3 Wire serial mode   | ||||
|   MXL_HYDRA_MPEG_MODE_SERIAL_2_WIRE,       // MPEG 2 Wire serial mode | ||||
|   MXL_HYDRA_MPEG_MODE_PARALLEL             // MPEG parallel mode - valid only for MxL581 | ||||
| } MXL_HYDRA_MPEG_MODE_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_MPEG_CLK_CONTINUOUS = 0,  // Continuous MPEG clock | ||||
|   MXL_HYDRA_MPEG_CLK_GAPPED,          // Gapped (gated) MPEG clock | ||||
| } MXL_HYDRA_MPEG_CLK_TYPE_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_MPEG_ACTIVE_LOW = 0, | ||||
|   MXL_HYDRA_MPEG_ACTIVE_HIGH, | ||||
|  | ||||
|   MXL_HYDRA_MPEG_CLK_NEGATIVE = 0, | ||||
|   MXL_HYDRA_MPEG_CLK_POSITIVE, | ||||
|  | ||||
|   MXL_HYDRA_MPEG_CLK_IN_PHASE = 0, | ||||
|   MXL_HYDRA_MPEG_CLK_INVERTED, | ||||
| } MXL_HYDRA_MPEG_CLK_FMT_E; | ||||
|  | ||||
| typedef enum   | ||||
| { | ||||
|   MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_0_DEG = 0,        | ||||
|   MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_90_DEG, | ||||
|   MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_180_DEG, | ||||
|   MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_270_DEG | ||||
| } MXL_HYDRA_MPEG_CLK_PHASE_E; | ||||
|  | ||||
| typedef enum   | ||||
| { | ||||
|   MXL_HYDRA_MPEG_ERR_REPLACE_SYNC = 0,        | ||||
|   MXL_HYDRA_MPEG_ERR_REPLACE_VALID,        | ||||
|   MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED | ||||
| } MXL_HYDRA_MPEG_ERR_INDICATION_E; | ||||
|  | ||||
| typedef struct | ||||
| {  | ||||
|   int                        enable;               // Enable or Disable MPEG OUT | ||||
|   MXL_HYDRA_MPEG_CLK_TYPE_E         mpegClkType;          // Continuous or gapped | ||||
|   MXL_HYDRA_MPEG_CLK_FMT_E          mpegClkPol;           // MPEG Clk polarity | ||||
|   u8                             maxMpegClkRate;       // Max MPEG Clk rate (0  104 MHz, 139 MHz)  | ||||
|   MXL_HYDRA_MPEG_CLK_PHASE_E        mpegClkPhase;         // MPEG Clk phase  | ||||
|   MXL_HYDRA_MPEG_DATA_FMT_E         lsbOrMsbFirst;        // LSB first or MSB first in TS transmission | ||||
|   MXL_HYDRA_MPEG_DATA_FMT_E         mpegSyncPulseWidth;   // MPEG SYNC pulse width (1-bit or 1-byte)   | ||||
|   MXL_HYDRA_MPEG_CLK_FMT_E          mpegValidPol;         // MPEG VALID polarity | ||||
|   MXL_HYDRA_MPEG_CLK_FMT_E          mpegSyncPol;          // MPEG SYNC polarity  | ||||
|   MXL_HYDRA_MPEG_MODE_E             mpegMode;             // config 4/3/2-wire serial or parallel TS out | ||||
|   MXL_HYDRA_MPEG_ERR_INDICATION_E   mpegErrorIndication;  // Enable or Disable MPEG error indication | ||||
| } MXL_HYDRA_MPEGOUT_PARAM_T; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_EXT_TS_IN_0 = 0, | ||||
|   MXL_HYDRA_EXT_TS_IN_1, | ||||
|   MXL_HYDRA_EXT_TS_IN_2, | ||||
|   MXL_HYDRA_EXT_TS_IN_3, | ||||
|   MXL_HYDRA_EXT_TS_IN_MAX | ||||
|  | ||||
| } MXL_HYDRA_EXT_TS_IN_ID_E; | ||||
|  | ||||
| typedef  enum | ||||
| { | ||||
|   MXL_HYDRA_TS_OUT_0 = 0, | ||||
|   MXL_HYDRA_TS_OUT_1, | ||||
|   MXL_HYDRA_TS_OUT_2, | ||||
|   MXL_HYDRA_TS_OUT_3, | ||||
|   MXL_HYDRA_TS_OUT_4, | ||||
|   MXL_HYDRA_TS_OUT_5, | ||||
|   MXL_HYDRA_TS_OUT_6, | ||||
|   MXL_HYDRA_TS_OUT_7, | ||||
|   MXL_HYDRA_TS_OUT_MAX | ||||
|  | ||||
| } MXL_HYDRA_TS_OUT_ID_E; | ||||
|  | ||||
| typedef  enum  | ||||
| { | ||||
|   MXL_HYDRA_TS_DRIVE_STRENGTH_1x = 0, | ||||
|   MXL_HYDRA_TS_DRIVE_STRENGTH_2x, | ||||
|   MXL_HYDRA_TS_DRIVE_STRENGTH_3x, | ||||
|   MXL_HYDRA_TS_DRIVE_STRENGTH_4x, | ||||
|   MXL_HYDRA_TS_DRIVE_STRENGTH_5x, | ||||
|   MXL_HYDRA_TS_DRIVE_STRENGTH_6x, | ||||
|   MXL_HYDRA_TS_DRIVE_STRENGTH_7x, | ||||
|   MXL_HYDRA_TS_DRIVE_STRENGTH_8x | ||||
|  | ||||
| } MXL_HYDRA_TS_DRIVE_STRENGTH_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_DEVICE_581 = 0, | ||||
|   MXL_HYDRA_DEVICE_584, | ||||
|   MXL_HYDRA_DEVICE_585, | ||||
|   MXL_HYDRA_DEVICE_544, | ||||
|   MXL_HYDRA_DEVICE_561, | ||||
|   MXL_HYDRA_DEVICE_TEST, | ||||
|   MXL_HYDRA_DEVICE_582, | ||||
|   MXL_HYDRA_DEVICE_541, | ||||
|   MXL_HYDRA_DEVICE_568, | ||||
|   MXL_HYDRA_DEVICE_542, | ||||
|   MXL_HYDRA_DEVICE_541S, | ||||
|   MXL_HYDRA_DEVICE_561S, | ||||
|   MXL_HYDRA_DEVICE_581S, | ||||
|   MXL_HYDRA_DEVICE_MAX | ||||
| } MXL_HYDRA_DEVICE_E; | ||||
|  | ||||
|  | ||||
| // Demod IQ data | ||||
| typedef struct | ||||
| { | ||||
|   u32 demodId;        | ||||
|   u32 sourceOfIQ;                  // ==0, it means I/Q comes from Formatter | ||||
|                                       // ==1, Legacy FEC | ||||
|                                       // ==2, Frequency Recovery | ||||
|                                       // ==3, NBC | ||||
|                                       // ==4, CTL | ||||
|                                       // ==5, EQ | ||||
|                                       // ==6, FPGA | ||||
| } MXL_HYDRA_DEMOD_IQ_SRC_T; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   u32 demodId; | ||||
| } MXL_HYDRA_DEMOD_ABORT_TUNE_T; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   u8 tunerId; | ||||
|   u8 enable; | ||||
| } MxL_HYDRA_TUNER_CMD; | ||||
|  | ||||
| // Demod Para for Channel Tune | ||||
| typedef struct | ||||
| { | ||||
|   u32 tunerIndex; | ||||
|   u32 demodIndex; | ||||
|   u32 frequencyInHz;     // Frequency | ||||
|   u32 standard;          // one of MXL_HYDRA_BCAST_STD_E  | ||||
|   u32 spectrumInversion; // Input : Spectrum inversion. | ||||
|   u32 rollOff;           /* rollOff (alpha) factor */ | ||||
|   u32 symbolRateInHz;    /* Symbol rate */ | ||||
|   u32 pilots;            /* TRUE = pilots enabled */ | ||||
|   u32 modulationScheme;  // Input : Modulation Scheme is one of MXL_HYDRA_MODULATION_E  | ||||
|   u32 fecCodeRate;       // Input : Forward error correction rate. Is one of MXL_HYDRA_FEC_E  | ||||
|   u32 maxCarrierOffsetInMHz; // Maximum carrier freq offset in MHz. Same as freqSearchRangeKHz, but in unit of MHz. | ||||
| } MXL_HYDRA_DEMOD_PARAM_T; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| 	u32 demodIndex; | ||||
| 	u8 scrambleSequence[12];       // scramble sequence | ||||
| 	u32 scrambleCode;              // scramble gold code  | ||||
| } MXL_HYDRA_DEMOD_SCRAMBLE_CODE_T; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   u32  intrType;   | ||||
|   u32  intrDurationInNanoSecs; | ||||
|   u32  intrMask; | ||||
| } MXL_INTR_CFG_T; | ||||
|  | ||||
| typedef struct  | ||||
| { | ||||
|    u8 powerMode;       // enumeration values are defined in MXL_HYDRA_PWR_MODE_E (device API.h) | ||||
| } MxL_HYDRA_POWER_MODE_CMD; | ||||
|  | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   u32  timeIntervalInSeconds; // in seconds | ||||
|   u32  tunerIndex; | ||||
|   s32  rssiThreshold; | ||||
|      | ||||
| } MXL_HYDRA_RF_WAKEUP_PARAM_T; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|   u32  tunerCount; | ||||
|   MXL_HYDRA_RF_WAKEUP_PARAM_T params; | ||||
| } MXL_HYDRA_RF_WAKEUP_CFG_T; | ||||
|  | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_AUX_CTRL_MODE_FSK = 0,  // Select FSK controller | ||||
|   MXL_HYDRA_AUX_CTRL_MODE_DISEQC,   // Select DiSEqC controller | ||||
| } MXL_HYDRA_AUX_CTRL_MODE_E; | ||||
|  | ||||
|  | ||||
| typedef enum | ||||
| {  | ||||
|   MXL_HYDRA_DISEQC_ENVELOPE_MODE = 0,  | ||||
|   MXL_HYDRA_DISEQC_TONE_MODE,          | ||||
| } MXL_HYDRA_DISEQC_OPMODE_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_DISEQC_1_X = 0,    // Config DiSEqC 1.x mode | ||||
|   MXL_HYDRA_DISEQC_2_X,        // Config DiSEqC 2.x mode                           | ||||
|   MXL_HYDRA_DISEQC_DISABLE     // Disable DiSEqC  | ||||
| } MXL_HYDRA_DISEQC_VER_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_DISEQC_CARRIER_FREQ_22KHZ= 0,   // DiSEqC signal frequency of 22 KHz | ||||
|   MXL_HYDRA_DISEQC_CARRIER_FREQ_33KHZ,      // DiSEqC signal frequency of 33 KHz                             | ||||
|   MXL_HYDRA_DISEQC_CARRIER_FREQ_44KHZ       // DiSEqC signal frequency of 44 KHz  | ||||
| } MXL_HYDRA_DISEQC_CARRIER_FREQ_E; | ||||
|  | ||||
| typedef enum  | ||||
| { | ||||
|   MXL_HYDRA_DISEQC_ID_0 = 0, | ||||
|   MXL_HYDRA_DISEQC_ID_1,  | ||||
|   MXL_HYDRA_DISEQC_ID_2, | ||||
|   MXL_HYDRA_DISEQC_ID_3 | ||||
| } MXL_HYDRA_DISEQC_ID_E; | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|   MXL_HYDRA_FSK_CFG_TYPE_39KPBS = 0,    // 39.0kbps   | ||||
|   MXL_HYDRA_FSK_CFG_TYPE_39_017KPBS,    // 39.017kbps   | ||||
|   MXL_HYDRA_FSK_CFG_TYPE_115_2KPBS      // 115.2kbps | ||||
| } MXL_HYDRA_FSK_OP_MODE_E; | ||||
|  | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
| 	u32 diseqcId;  // DSQ 0, 1, 2 or 3 | ||||
| 	u32 opMode;   // Envelope mode (0) or internal tone mode (1) | ||||
| 	u32 version;   // 0: 1.0 , 1: 1.1 , 2: Disable | ||||
| 	u32 centerFreq; // 0: 22KHz, 1: 33KHz and 2: 44 KHz | ||||
| }MXL58x_DSQ_OP_MODE_T; | ||||
|  | ||||
| typedef struct | ||||
| {   | ||||
| 	u32 diseqcId; | ||||
| 	u32 contToneFlag;  // 1: Enable , 0: Disable | ||||
| } MXL_HYDRA_DISEQC_CFG_CONT_TONE_T; | ||||
|  | ||||
							
								
								
									
										941
									
								
								frontends/mxl5xx_regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										941
									
								
								frontends/mxl5xx_regs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,941 @@ | ||||
| /* | ||||
| * Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved | ||||
| * | ||||
| * License type: GPLv2 | ||||
| * | ||||
| * 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. | ||||
| * | ||||
| * 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., | ||||
| * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA | ||||
| * | ||||
| * This program may alternatively be licensed under a proprietary license from | ||||
| * MaxLinear, Inc. | ||||
| * | ||||
| * See terms and conditions defined in file 'LICENSE.txt', which is part of this | ||||
| * source code package. | ||||
| */ | ||||
|  | ||||
| #ifndef __MXL58X_REGISTERS_H__ | ||||
| #define __MXL58X_REGISTERS_H__ | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| #define HYDRA_INTR_STATUS_REG               0x80030008 | ||||
| #define HYDRA_INTR_MASK_REG                 0x8003000C | ||||
|  | ||||
| #define HYDRA_CRYSTAL_SETTING               0x3FFFC5F0 // 0 - 24 MHz & 1 - 27 MHz | ||||
| #define HYDRA_CRYSTAL_CAP                   0x3FFFEDA4 // 0 - 24 MHz & 1 - 27 MHz | ||||
|  | ||||
| #define HYDRA_CPU_RESET_REG                 0x8003003C | ||||
| #define HYDRA_CPU_RESET_DATA                0x00000400 | ||||
|  | ||||
| #define HYDRA_RESET_TRANSPORT_FIFO_REG      0x80030028 | ||||
| #define HYDRA_RESET_TRANSPORT_FIFO_DATA     0x00000000 | ||||
|  | ||||
| #define HYDRA_RESET_BBAND_REG               0x80030024 | ||||
| #define HYDRA_RESET_BBAND_DATA              0x00000000 | ||||
|  | ||||
| #define HYDRA_RESET_XBAR_REG                0x80030020 | ||||
| #define HYDRA_RESET_XBAR_DATA               0x00000000 | ||||
|  | ||||
| #define HYDRA_MODULES_CLK_1_REG             0x80030014 | ||||
| #define HYDRA_DISABLE_CLK_1                 0x00000000 | ||||
|  | ||||
| #define HYDRA_MODULES_CLK_2_REG             0x8003001C | ||||
| #define HYDRA_DISABLE_CLK_2                 0x0000000B | ||||
|  | ||||
| #define HYDRA_PRCM_ROOT_CLK_REG             0x80030018 | ||||
| #define HYDRA_PRCM_ROOT_CLK_DISABLE         0x00000000 | ||||
|  | ||||
| #define HYDRA_CPU_RESET_CHECK_REG           0x80030008 | ||||
| #define HYDRA_CPU_RESET_CHECK_OFFSET        0x40000000  //  <bit 30> | ||||
|  | ||||
| #define HYDRA_SKU_ID_REG                    0x90000190 | ||||
|  | ||||
| #define FW_DL_SIGN_ADDR                     0x3FFFEAE0 | ||||
|  | ||||
| // Register to check if FW is running or not | ||||
| #define HYDRA_HEAR_BEAT                     0x3FFFEDDC | ||||
|  | ||||
| // Firmware version | ||||
| #define HYDRA_FIRMWARE_VERSION              0x3FFFEDB8 | ||||
| #define HYDRA_FW_RC_VERSION                 0x3FFFCFAC | ||||
|  | ||||
| // Firmware patch version | ||||
| #define HYDRA_FIRMWARE_PATCH_VERSION        0x3FFFEDC2 | ||||
|  | ||||
| // SOC operating temperature in C | ||||
| #define HYDRA_TEMPARATURE                   0x3FFFEDB4 | ||||
|  | ||||
| // Demod & Tuner status registers | ||||
| // Demod 0 status base address | ||||
| #define HYDRA_DEMOD_0_BASE_ADDR             0x3FFFC64C | ||||
|  | ||||
| // Tuner 0 status base address | ||||
| #define HYDRA_TUNER_0_BASE_ADDR             0x3FFFCE4C | ||||
|  | ||||
| #define POWER_FROM_ADCRSSI_READBACK         0x3FFFEB6C | ||||
|  | ||||
| // Macros to determine base address of respective demod or tuner | ||||
| #define HYDRA_DMD_STATUS_OFFSET(demodID)        ((demodID) * 0x100) | ||||
| #define HYDRA_TUNER_STATUS_OFFSET(tunerID)      ((tunerID) * 0x40) | ||||
|  | ||||
| // Demod status address offset from respective demod's base address | ||||
| #define HYDRA_DMD_AGC_DIG_LEVEL_ADDR_OFFSET               0x3FFFC64C | ||||
| #define HYDRA_DMD_LOCK_STATUS_ADDR_OFFSET                 0x3FFFC650 | ||||
| #define HYDRA_DMD_ACQ_STATUS_ADDR_OFFSET                  0x3FFFC654 | ||||
|  | ||||
| #define HYDRA_DMD_STANDARD_ADDR_OFFSET                    0x3FFFC658 | ||||
| #define HYDRA_DMD_SPECTRUM_INVERSION_ADDR_OFFSET          0x3FFFC65C | ||||
| #define HYDRA_DMD_SPECTRUM_ROLL_OFF_ADDR_OFFSET           0x3FFFC660 | ||||
| #define HYDRA_DMD_SYMBOL_RATE_ADDR_OFFSET                 0x3FFFC664 | ||||
| #define HYDRA_DMD_MODULATION_SCHEME_ADDR_OFFSET           0x3FFFC668 | ||||
| #define HYDRA_DMD_FEC_CODE_RATE_ADDR_OFFSET               0x3FFFC66C | ||||
|  | ||||
| #define HYDRA_DMD_SNR_ADDR_OFFSET                         0x3FFFC670 | ||||
| #define HYDRA_DMD_FREQ_OFFSET_ADDR_OFFSET                 0x3FFFC674 | ||||
| #define HYDRA_DMD_CTL_FREQ_OFFSET_ADDR_OFFSET             0x3FFFC678 | ||||
| #define HYDRA_DMD_STR_FREQ_OFFSET_ADDR_OFFSET             0x3FFFC67C | ||||
| #define HYDRA_DMD_FTL_FREQ_OFFSET_ADDR_OFFSET             0x3FFFC680 | ||||
| #define HYDRA_DMD_STR_NBC_SYNC_LOCK_ADDR_OFFSET           0x3FFFC684 | ||||
| #define HYDRA_DMD_CYCLE_SLIP_COUNT_ADDR_OFFSET            0x3FFFC688 | ||||
|  | ||||
| #define HYDRA_DMD_DISPLAY_I_ADDR_OFFSET                   0x3FFFC68C | ||||
| #define HYDRA_DMD_DISPLAY_Q_ADDR_OFFSET                   0x3FFFC68E | ||||
|  | ||||
| #define HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET            0x3FFFC690 | ||||
| #define HYDRA_DMD_DVBS2_PER_COUNT_ADDR_OFFSET             0x3FFFC694 | ||||
| #define HYDRA_DMD_DVBS2_PER_WINDOW_ADDR_OFFSET            0x3FFFC698 | ||||
|  | ||||
| #define HYDRA_DMD_DVBS_CORR_RS_ERRORS_ADDR_OFFSET         0x3FFFC69C | ||||
| #define HYDRA_DMD_DVBS_UNCORR_RS_ERRORS_ADDR_OFFSET       0x3FFFC6A0 | ||||
| #define HYDRA_DMD_DVBS_BER_COUNT_ADDR_OFFSET              0x3FFFC6A4 | ||||
| #define HYDRA_DMD_DVBS_BER_WINDOW_ADDR_OFFSET             0x3FFFC6A8 | ||||
|  | ||||
| // Debug-purpose DVB-S DMD 0 | ||||
| #define HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET     0x3FFFC6C8  // corrected RS Errors: 1st iteration | ||||
| #define HYDRA_DMD_DVBS_1ST_UNCORR_RS_ERRORS_ADDR_OFFSET   0x3FFFC6CC  // uncorrected RS Errors: 1st iteration | ||||
| #define HYDRA_DMD_DVBS_BER_COUNT_1ST_ADDR_OFFSET          0x3FFFC6D0 | ||||
| #define HYDRA_DMD_DVBS_BER_WINDOW_1ST_ADDR_OFFSET         0x3FFFC6D4 | ||||
|  | ||||
| #define HYDRA_DMD_TUNER_ID_ADDR_OFFSET                    0x3FFFC6AC | ||||
| #define HYDRA_DMD_DVBS2_PILOT_ON_OFF_ADDR_OFFSET          0x3FFFC6B0 | ||||
| #define HYDRA_DMD_FREQ_SEARCH_RANGE_KHZ_ADDR_OFFSET       0x3FFFC6B4 | ||||
| #define HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET                 0x3FFFC6B8 | ||||
| #define HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR          0x3FFFC704 | ||||
| #define HYDRA_DMD_STATUS_INPUT_POWER_ADDR                 0x3FFFC708 | ||||
|  | ||||
| // DVB-S new scaled_BER_count for a new BER API, see HYDRA-1343 "DVB-S post viterbi information" | ||||
| #define DMD0_STATUS_DVBS_1ST_SCALED_BER_COUNT_ADDR        0x3FFFC710 // DMD 0: 1st iteration BER count scaled by HYDRA_BER_COUNT_SCALING_FACTOR | ||||
| #define DMD0_STATUS_DVBS_SCALED_BER_COUNT_ADDR            0x3FFFC714 // DMD 0: 2nd iteration BER count scaled by HYDRA_BER_COUNT_SCALING_FACTOR | ||||
|  | ||||
| #define DMD0_SPECTRUM_MIN_GAIN_STATUS                     0x3FFFC73C | ||||
| #define DMD0_SPECTRUM_MIN_GAIN_WB_SAGC_VALUE              0x3FFFC740 | ||||
| #define DMD0_SPECTRUM_ MIN_GAIN_NB_SAGC_VALUE             0x3FFFC744 | ||||
|  | ||||
| #define HYDRA_DMD_STATUS_END_ADDR_OFFSET                  0x3FFFC748 | ||||
|  | ||||
| // Tuner status address offset from respective tuners's base address | ||||
| #define HYDRA_TUNER_DEMOD_ID_ADDR_OFFSET                  0x3FFFCE4C | ||||
| #define HYDRA_TUNER_AGC_LOCK_OFFSET                       0x3FFFCE50 | ||||
| #define HYDRA_TUNER_SPECTRUM_STATUS_OFFSET                0x3FFFCE54 | ||||
| #define HYDRA_TUNER_SPECTRUM_BIN_SIZE_OFFSET              0x3FFFCE58 | ||||
| #define HYDRA_TUNER_SPECTRUM_ADDRESS_OFFSET               0x3FFFCE5C | ||||
| #define HYDRA_TUNER_ENABLE_COMPLETE                       0x3FFFEB78 | ||||
|  | ||||
| #define HYDRA_DEMOD_STATUS_LOCK(devId, demodId)   write_register(devId, (HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET + HYDRA_DMD_STATUS_OFFSET(demodId)), MXL_YES) | ||||
| #define HYDRA_DEMOD_STATUS_UNLOCK(devId, demodId) write_register(devId, (HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET + HYDRA_DMD_STATUS_OFFSET(demodId)), MXL_NO) | ||||
|  | ||||
| #define HYDRA_TUNER_STATUS_LOCK(devId,tunerId)   MxLWare_HYDRA_WriteRegister(devId,(HYDRA_TUNER_STATUS_LOCK_ADDR_OFFSET + HYDRA_TUNER_STATUS_OFFSET(tunerId)), MXL_YES) | ||||
| #define HYDRA_TUNER_STATUS_UNLOCK(devId,tunerId) MxLWare_HYDRA_WriteRegister(devId,(HYDRA_TUNER_STATUS_LOCK_ADDR_OFFSET + HYDRA_TUNER_STATUS_OFFSET(tunerId)), MXL_NO) | ||||
|  | ||||
| #define HYDRA_VERSION                                     0x3FFFEDB8 | ||||
| #define HYDRA_DEMOD0_VERSION                              0x3FFFEDBC | ||||
| #define HYDRA_DEMOD1_VERSION                              0x3FFFEDC0 | ||||
| #define HYDRA_DEMOD2_VERSION                              0x3FFFEDC4 | ||||
| #define HYDRA_DEMOD3_VERSION                              0x3FFFEDC8 | ||||
| #define HYDRA_DEMOD4_VERSION                              0x3FFFEDCC | ||||
| #define HYDRA_DEMOD5_VERSION                              0x3FFFEDD0 | ||||
| #define HYDRA_DEMOD6_VERSION                              0x3FFFEDD4 | ||||
| #define HYDRA_DEMOD7_VERSION                              0x3FFFEDD8 | ||||
| #define HYDRA_HEAR_BEAT                                   0x3FFFEDDC | ||||
| #define HYDRA_SKU_MGMT                                    0x3FFFEBC0 | ||||
|  | ||||
| #define MXL_HYDRA_FPGA_A_ADDRESS                          0x91C00000 | ||||
| #define MXL_HYDRA_FPGA_B_ADDRESS                          0x91D00000 | ||||
|  | ||||
| // TS control base address | ||||
| #define HYDRA_TS_CTRL_BASE_ADDR                           0x90700000 | ||||
|  | ||||
| #define MPEG_MUX_MODE_SLICE0_REG            HYDRA_TS_CTRL_BASE_ADDR + 0x08 | ||||
| #define MPEG_MUX_MODE_SLICE0_OFFSET         (0),(2) | ||||
|  | ||||
| #define MPEG_MUX_MODE_SLICE1_REG            HYDRA_TS_CTRL_BASE_ADDR + 0x08 | ||||
| #define MPEG_MUX_MODE_SLICE1_OFFSET         (2),(2) | ||||
|  | ||||
| #define PID_BANK_SEL_SLICE0_REG             HYDRA_TS_CTRL_BASE_ADDR + 0x190 | ||||
| #define PID_BANK_SEL_SLICE1_REG             HYDRA_TS_CTRL_BASE_ADDR + 0x1B0 | ||||
|  | ||||
| #define SW_REGULAR_PID_SW_BANK_OFFSET       0,1 | ||||
| #define SW_FIXED_PID_SW_BANK_OFFSET         1,1 | ||||
|  | ||||
| #define HW_REGULAR_PID_BANK_OFFSET          8,4 | ||||
| #define HW_FIXED_PID_BANK_OFFSET            4,4 | ||||
|  | ||||
| #define MPEG_CLK_GATED_REG                  HYDRA_TS_CTRL_BASE_ADDR + 0x20 | ||||
| #define MPEG_CLK_GATED_OFFSET               0,1 | ||||
|  | ||||
| #define MPEG_CLK_ALWAYS_ON_REG              HYDRA_TS_CTRL_BASE_ADDR + 0x1D4 | ||||
| #define MPEG_CLK_ALWAYS_ON_OFFSET           0,1 | ||||
|  | ||||
| #define HYDRA_REGULAR_PID_BANK_A_REG        HYDRA_TS_CTRL_BASE_ADDR + 0x190 | ||||
| #define HYDRA_REGULAR_PID_BAN K_A_OFFSET     0,1 | ||||
|  | ||||
| #define HYDRA_FIXED_PID_BANK_A_REG          HYDRA_TS_CTRL_BASE_ADDR + 0x190 | ||||
| #define HYDRA_FIXED_PID_BANK_A_OFFSET       1,1 | ||||
|  | ||||
| #define HYDRA_REGULAR_PID_BANK_B_REG        HYDRA_TS_CTRL_BASE_ADDR + 0x1B0 | ||||
| #define HYDRA_REGULAR_PID_BANK_B_OFFSET     0,1 | ||||
|  | ||||
| #define HYDRA_FIXED_PID_BANK_B_REG          HYDRA_TS_CTRL_BASE_ADDR + 0x1B0 | ||||
| #define HYDRA_FIXED_PID_BANK_B_OFFSET       1,1 | ||||
|  | ||||
| #define FIXED_PID_TBL_REG_ADDRESS_0         HYDRA_TS_CTRL_BASE_ADDR + 0x9000 | ||||
| #define FIXED_PID_TBL_REG_ADDRESS_1         HYDRA_TS_CTRL_BASE_ADDR + 0x9100 | ||||
| #define FIXED_PID_TBL_REG_ADDRESS_2         HYDRA_TS_CTRL_BASE_ADDR + 0x9200 | ||||
| #define FIXED_PID_TBL_REG_ADDRESS_3         HYDRA_TS_CTRL_BASE_ADDR + 0x9300 | ||||
|  | ||||
| #define FIXED_PID_TBL_REG_ADDRESS_4         HYDRA_TS_CTRL_BASE_ADDR + 0xB000 | ||||
| #define FIXED_PID_TBL_REG_ADDRESS_5         HYDRA_TS_CTRL_BASE_ADDR + 0xB100 | ||||
| #define FIXED_PID_TBL_REG_ADDRESS_6         HYDRA_TS_CTRL_BASE_ADDR + 0xB200 | ||||
| #define FIXED_PID_TBL_REG_ADDRESS_7         HYDRA_TS_CTRL_BASE_ADDR + 0xB300 | ||||
|  | ||||
| #define REGULAR_PID_TBL_REG_ADDRESS_0       HYDRA_TS_CTRL_BASE_ADDR + 0x8000 | ||||
| #define REGULAR_PID_TBL_REG_ADDRESS_1       HYDRA_TS_CTRL_BASE_ADDR + 0x8200 | ||||
| #define REGULAR_PID_TBL_REG_ADDRESS_2       HYDRA_TS_CTRL_BASE_ADDR + 0x8400 | ||||
| #define REGULAR_PID_TBL_REG_ADDRESS_3       HYDRA_TS_CTRL_BASE_ADDR + 0x8600 | ||||
|  | ||||
| #define REGULAR_PID_TBL_REG_ADDRESS_4       HYDRA_TS_CTRL_BASE_ADDR + 0xA000 | ||||
| #define REGULAR_PID_TBL_REG_ADDRESS_5       HYDRA_TS_CTRL_BASE_ADDR + 0xA200 | ||||
| #define REGULAR_PID_TBL_REG_ADDRESS_6       HYDRA_TS_CTRL_BASE_ADDR + 0xA400 | ||||
| #define REGULAR_PID_TBL_REG_ADDRESS_7       HYDRA_TS_CTRL_BASE_ADDR + 0xA600 | ||||
|  | ||||
| #define PID_VALID_OFFSET                    0,1 | ||||
| #define PID_DROP_OFFSET                     1,1 | ||||
| #define PID_REMAP_ENABLE_OFFSET             2,1 | ||||
| #define PID_VALUE_OFFSET                    4,13 | ||||
| #define PID_MASK_OFFSET                     19,13 | ||||
|  | ||||
| #define REGULAR_PID_REMAP_VALUE_OFFSET      0,13 | ||||
| #define FIXED_PID_REMAP_VALUE_OFFSET        0,16 | ||||
| #define PID_DEMODID_OFFSET                  16,3 | ||||
|  | ||||
|  | ||||
| /////////////////////////////////////////////// | ||||
|  | ||||
| #if 0 | ||||
| #define AFE_REG_D2A_TA_ADC_CLK_OUT_FLIP 0x90200004,12,1 | ||||
| #define AFE_REG_D2A_TA_RFFE_LNACAPLOAD_1P8 0x90200028,24,4 | ||||
| #define AFE_REG_D2A_TA_RFFE_RF1_EN_1P8 0x90200028,5,1 | ||||
| #define AFE_REG_D2A_TA_RFFE_SPARE_1P8 0x90200028,8,8 | ||||
| #define AFE_REG_D2A_TB_ADC_CLK_OUT_FLIP 0x9020000C,23,1 | ||||
| #define AFE_REG_D2A_TB_RFFE_LNACAPLOAD_1P8 0x90200030,16,4 | ||||
| #define AFE_REG_D2A_TB_RFFE_RF1_EN_1P8 0x9020002C,21,1 | ||||
| #define AFE_REG_D2A_TB_RFFE_SPARE_1P8 0x90200030,0,8 | ||||
| #define AFE_REG_D2A_TC_ADC_CLK_OUT_FLIP 0x90200018,7,1 | ||||
| #define AFE_REG_D2A_TC_RFFE_LNACAPLOAD_1P8 0x90200038,2,4 | ||||
| #define AFE_REG_D2A_TC_RFFE_RF1_EN_1P8 0x90200034,14,1 | ||||
| #define AFE_REG_D2A_TC_RFFE_SPARE_1P8 0x90200034,17,8 | ||||
| #define AFE_REG_D2A_TD_ADC_CLK_OUT_FLIP 0x90200020,18,1 | ||||
| #define AFE_REG_D2A_TD_RFFE_LNACAPLOAD_1P8 0x9020003C,17,4 | ||||
| #define AFE_REG_D2A_TD_RFFE_RF1_EN_1P8 0x90200038,29,1 | ||||
| #define AFE_REG_D2A_TD_RFFE_SPARE_1P8 0x9020003C,1,8 | ||||
| #endif | ||||
| #define AFE_REG_D2A_XTAL_EN_CLKOUT_1P8 0x90200054,23,1 | ||||
|  | ||||
| #define   PAD_MUX_TS0_IN_CLK_PINMUX_SEL                          0x90000018,0,3 | ||||
| #define   PAD_MUX_TS0_IN_DATA_PINMUX_SEL                         0x90000018,4,3 | ||||
| #define   PAD_MUX_TS1_IN_CLK_PINMUX_SEL                          0x90000018,8,3 | ||||
| #define   PAD_MUX_TS1_IN_DATA_PINMUX_SEL                         0x90000018,12,3 | ||||
| #define   PAD_MUX_TS2_IN_CLK_PINMUX_SEL                          0x90000018,16,3 | ||||
| #define   PAD_MUX_TS2_IN_DATA_PINMUX_SEL                         0x90000018,20,3 | ||||
| #define   PAD_MUX_TS3_IN_CLK_PINMUX_SEL                          0x90000018,24,3 | ||||
| #define   PAD_MUX_TS3_IN_DATA_PINMUX_SEL                         0x90000018,28,3 | ||||
|  | ||||
| #define   PAD_MUX_GPIO_00_SYNC_BASEADDR                          0x90000188 | ||||
| #define   PAD_MUX_GPIO_01_SYNC_IN                                PAD_MUX_GPIO_00_SYNC_BASEADDR,1,1 | ||||
|  | ||||
| #define PRCM_AFE_SOC_ID 0x80030004,24,8 | ||||
|  | ||||
| #define PAD_MUX_UART_RX_C_PINMUX_BASEADDR 0x9000001C | ||||
| #define PAD_MUX_UART_RX_C_PINMUX_SEL PAD_MUX_UART_RX_C_PINMUX_BASEADDR,0,3 | ||||
| #define PAD_MUX_UART_RX_D_PINMUX_SEL PAD_MUX_UART_RX_C_PINMUX_BASEADDR,4,3 | ||||
| #define PAD_MUX_BOND_OPTION 0x90000190,0,3 | ||||
| #define PAD_MUX_DIGIO_01_PINMUX_SEL 0x9000016C,4,3 | ||||
| #define PAD_MUX_DIGIO_02_PINMUX_SEL 0x9000016C,8,3 | ||||
| #define PAD_MUX_DIGIO_03_PINMUX_SEL 0x9000016C,12,3 | ||||
| #define PAD_MUX_DIGIO_04_PINMUX_SEL 0x9000016C,16,3 | ||||
| #define PAD_MUX_DIGIO_05_PINMUX_SEL 0x9000016C,20,3 | ||||
| #define PAD_MUX_DIGIO_06_PINMUX_SEL 0x9000016C,24,3 | ||||
| #define PAD_MUX_DIGIO_07_PINMUX_SEL 0x9000016C,28,3 | ||||
| #define PAD_MUX_DIGIO_08_PINMUX_SEL 0x90000170,0,3 | ||||
| #define PAD_MUX_DIGIO_09_PINMUX_SEL 0x90000170,4,3 | ||||
| #define PAD_MUX_DIGIO_10_PINMUX_SEL 0x90000170,8,3 | ||||
| #define PAD_MUX_DIGIO_11_PINMUX_SEL 0x90000170,12,3 | ||||
| #define PAD_MUX_DIGIO_12_PINMUX_SEL 0x90000170,16,3 | ||||
| #define PAD_MUX_DIGIO_13_PINMUX_SEL 0x90000170,20,3 | ||||
| #define PAD_MUX_DIGIO_14_PINMUX_SEL 0x90000170,24,3 | ||||
| #define PAD_MUX_DIGIO_15_PINMUX_SEL 0x90000170,28,3 | ||||
| #define PAD_MUX_DIGIO_16_PINMUX_SEL 0x90000174,0,3 | ||||
| #define PAD_MUX_DIGIO_17_PINMUX_SEL 0x90000174,4,3 | ||||
| #define PAD_MUX_DIGIO_18_PINMUX_SEL 0x90000174,8,3 | ||||
| #define PAD_MUX_DIGIO_19_PINMUX_SEL 0x90000174,12,3 | ||||
| #define PAD_MUX_DIGIO_20_PINMUX_SEL 0x90000174,16,3 | ||||
| #define PAD_MUX_DIGIO_21_PINMUX_SEL 0x90000174,20,3 | ||||
| #define PAD_MUX_DIGIO_22_PINMUX_SEL 0x90000174,24,3 | ||||
| #define PAD_MUX_DIGIO_23_PINMUX_SEL 0x90000174,28,3 | ||||
| #define PAD_MUX_DIGIO_24_PINMUX_SEL 0x90000178,0,3 | ||||
| #define PAD_MUX_DIGIO_25_PINMUX_SEL 0x90000178,4,3 | ||||
| #define PAD_MUX_DIGIO_26_PINMUX_SEL 0x90000178,8,3 | ||||
| #define PAD_MUX_DIGIO_27_PINMUX_SEL 0x90000178,12,3 | ||||
| #define PAD_MUX_DIGIO_28_PINMUX_SEL 0x90000178,16,3 | ||||
| #define PAD_MUX_DIGIO_29_PINMUX_SEL 0x90000178,20,3 | ||||
| #define PAD_MUX_DIGIO_30_PINMUX_SEL 0x90000178,24,3 | ||||
| #define PAD_MUX_DIGIO_31_PINMUX_SEL 0x90000178,28,3 | ||||
| #define PAD_MUX_DIGIO_32_PINMUX_SEL 0x9000017C,0,3 | ||||
| #define PAD_MUX_DIGIO_33_PINMUX_SEL 0x9000017C,4,3 | ||||
| #define PAD_MUX_DIGIO_34_PINMUX_SEL 0x9000017C,8,3 | ||||
| #define PAD_MUX_EJTAG_TCK_PINMUX_SEL 0x90000020,0,3 | ||||
| #define PAD_MUX_EJTAG_TDI_PINMUX_SEL 0x90000020,8,3 | ||||
| #define PAD_MUX_EJTAG_TMS_PINMUX_SEL 0x90000020,4,3 | ||||
| #define PAD_MUX_EJTAG_TRSTN_PINMUX_SEL 0x90000020,12,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_00 0x90000194,0,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_05 0x90000194,20,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_06 0x90000194,24,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_11 0x90000198,12,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_12 0x90000198,16,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_13 0x90000198,20,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_14 0x90000198,24,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_16 0x9000019C,0,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_17 0x9000019C,4,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_18 0x9000019C,8,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_22 0x9000019C,24,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_23 0x9000019C,28,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_24 0x900001A0,0,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_25 0x900001A0,4,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_29 0x900001A0,20,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_30 0x900001A0,24,3 | ||||
| #define PAD_MUX_PAD_DRV_DIGIO_31 0x900001A0,28,3 | ||||
| #define PRCM_AFE_REG_CLOCK_ENABLE 0x80030014,9,1 | ||||
| #define PRCM_CHIP_VERSION 0x80030000,12,4 | ||||
| #define PRCM_AFE_CHIP_MMSK_VER 0x80030004,8,8 | ||||
| #define PRCM_PRCM_AFE_REG_SOFT_RST_N 0x8003003C,12,1 | ||||
| #define PRCM_PRCM_CPU_SOFT_RST_N 0x8003003C,0,1 | ||||
| #define PRCM_PRCM_DIGRF_APB_DATA_BB0 0x80030074,0,20 | ||||
| #define PRCM_PRCM_DIGRF_APB_DATA_BB1 0x80030078,0,20 | ||||
| #define PRCM_PRCM_DIGRF_APB_DATA_BB2 0x8003007C,0,20 | ||||
| #define PRCM_PRCM_DIGRF_APB_DATA_BB3 0x80030080,0,20 | ||||
| #define PRCM_PRCM_DIGRF_APB_DATA_BB4 0x80030084,0,20 | ||||
| #define PRCM_PRCM_DIGRF_APB_DATA_BB5 0x80030088,0,20 | ||||
| #define PRCM_PRCM_DIGRF_APB_DATA_BB6 0x8003008C,0,20 | ||||
| #define PRCM_PRCM_DIGRF_APB_DATA_BB7 0x80030090,0,20 | ||||
| #define PRCM_PRCM_DIGRF_CAPT_DONE 0x80030070,24,8 | ||||
| #define PRCM_PRCM_DIGRF_START_CAPT 0x80030064,2,1 | ||||
| #define PRCM_PRCM_PAD_MUX_SOFT_RST_N 0x8003003C,11,1 | ||||
| #define PRCM_PRCM_XPT_PARALLEL_FIFO_RST_N 0x80030028,20,1 | ||||
| #define XPT_APPEND_BYTES0 0x90700008,4,2 | ||||
| #define XPT_APPEND_BYTES1 0x90700008,6,2 | ||||
| #define XPT_CLOCK_POLARITY0 0x90700010,16,1 | ||||
| #define XPT_CLOCK_POLARITY1 0x90700010,17,1 | ||||
| #define XPT_CLOCK_POLARITY2 0x90700010,18,1 | ||||
| #define XPT_CLOCK_POLARITY3 0x90700010,19,1 | ||||
| #define XPT_CLOCK_POLARITY4 0x90700010,20,1 | ||||
| #define XPT_CLOCK_POLARITY5 0x90700010,21,1 | ||||
| #define XPT_CLOCK_POLARITY6 0x90700010,22,1 | ||||
| #define XPT_CLOCK_POLARITY7 0x90700010,23,1 | ||||
| #define XPT_DSS_DVB_ENCAP_EN0 0x90700000,16,1 | ||||
| #define XPT_DSS_DVB_ENCAP_EN1 0x90700000,17,1 | ||||
| #define XPT_DSS_DVB_ENCAP_EN2 0x90700000,18,1 | ||||
| #define XPT_DSS_DVB_ENCAP_EN3 0x90700000,19,1 | ||||
| #define XPT_DSS_DVB_ENCAP_EN4 0x90700000,20,1 | ||||
| #define XPT_DSS_DVB_ENCAP_EN5 0x90700000,21,1 | ||||
| #define XPT_DSS_DVB_ENCAP_EN6 0x90700000,22,1 | ||||
| #define XPT_DSS_DVB_ENCAP_EN7 0x90700000,23,1 | ||||
| #define XPT_DVB_MATCH_BYTE 0x9070017C,16,8 | ||||
| #define XPT_DVB_PACKET_SIZE0 0x90700180,0,8 | ||||
| #define XPT_DVB_PACKET_SIZE1 0x90700180,8,8 | ||||
| #define XPT_DVB_PACKET_SIZE2 0x90700180,16,8 | ||||
| #define XPT_DVB_PACKET_SIZE3 0x90700180,24,8 | ||||
| #define XPT_ENABLE_DVB_INPUT0 0x90700178,0,1 | ||||
| #define XPT_ENABLE_DVB_INPUT1 0x90700178,1,1 | ||||
| #define XPT_ENABLE_DVB_INPUT2 0x90700178,2,1 | ||||
| #define XPT_ENABLE_DVB_INPUT3 0x90700178,3,1 | ||||
| #define XPT_ENABLE_INPUT0 0x90700000,0,1 | ||||
| #define XPT_ENABLE_INPUT1 0x90700000,1,1 | ||||
| #define XPT_ENABLE_INPUT2 0x90700000,2,1 | ||||
| #define XPT_ENABLE_INPUT3 0x90700000,3,1 | ||||
| #define XPT_ENABLE_INPUT4 0x90700000,4,1 | ||||
| #define XPT_ENABLE_INPUT5 0x90700000,5,1 | ||||
| #define XPT_ENABLE_INPUT6 0x90700000,6,1 | ||||
| #define XPT_ENABLE_INPUT7 0x90700000,7,1 | ||||
| #define XPT_ENABLE_OUTPUT0 0x9070000C,0,1 | ||||
| #define XPT_ENABLE_OUTPUT1 0x9070000C,1,1 | ||||
| #define XPT_ENABLE_OUTPUT2 0x9070000C,2,1 | ||||
| #define XPT_ENABLE_OUTPUT3 0x9070000C,3,1 | ||||
| #define XPT_ENABLE_OUTPUT4 0x9070000C,4,1 | ||||
| #define XPT_ENABLE_OUTPUT5 0x9070000C,5,1 | ||||
| #define XPT_ENABLE_OUTPUT6 0x9070000C,6,1 | ||||
| #define XPT_ENABLE_OUTPUT7 0x9070000C,7,1 | ||||
| #define XPT_ENABLE_PARALLEL_OUTPUT 0x90700010,27,1 | ||||
| #define XPT_ENABLE_PCR_COUNT 0x90700184,1,1 | ||||
| #define XPT_ERROR_REPLACE_SYNC0 0x9070000C,24,1 | ||||
| #define XPT_ERROR_REPLACE_SYNC1 0x9070000C,25,1 | ||||
| #define XPT_ERROR_REPLACE_SYNC2 0x9070000C,26,1 | ||||
| #define XPT_ERROR_REPLACE_SYNC3 0x9070000C,27,1 | ||||
| #define XPT_ERROR_REPLACE_SYNC4 0x9070000C,28,1 | ||||
| #define XPT_ERROR_REPLACE_SYNC5 0x9070000C,29,1 | ||||
| #define XPT_ERROR_REPLACE_SYNC6 0x9070000C,30,1 | ||||
| #define XPT_ERROR_REPLACE_SYNC7 0x9070000C,31,1 | ||||
| #define XPT_ERROR_REPLACE_VALID0 0x90700014,8,1 | ||||
| #define XPT_ERROR_REPLACE_VALID1 0x90700014,9,1 | ||||
| #define XPT_ERROR_REPLACE_VALID2 0x90700014,10,1 | ||||
| #define XPT_ERROR_REPLACE_VALID3 0x90700014,11,1 | ||||
| #define XPT_ERROR_REPLACE_VALID4 0x90700014,12,1 | ||||
| #define XPT_ERROR_REPLACE_VALID5 0x90700014,13,1 | ||||
| #define XPT_ERROR_REPLACE_VALID6 0x90700014,14,1 | ||||
| #define XPT_ERROR_REPLACE_VALID7 0x90700014,15,1 | ||||
| #define XPT_INP0_MERGE_HDR0 0x90700058,0,32 | ||||
| #define XPT_INP0_MERGE_HDR1 0x9070005C,0,32 | ||||
| #define XPT_INP0_MERGE_HDR2 0x90700060,0,32 | ||||
| #define XPT_INP1_MERGE_HDR0 0x90700064,0,32 | ||||
| #define XPT_INP1_MERGE_HDR1 0x90700068,0,32 | ||||
| #define XPT_INP1_MERGE_HDR2 0x9070006C,0,32 | ||||
| #define XPT_INP2_MERGE_HDR0 0x90700070,0,32 | ||||
| #define XPT_INP2_MERGE_HDR1 0x90700074,0,32 | ||||
| #define XPT_INP2_MERGE_HDR2 0x90700078,0,32 | ||||
| #define XPT_INP3_MERGE_HDR0 0x9070007C,0,32 | ||||
| #define XPT_INP3_MERGE_HDR1 0x90700080,0,32 | ||||
| #define XPT_INP3_MERGE_HDR2 0x90700084,0,32 | ||||
| #define XPT_INP4_MERGE_HDR0 0x90700088,0,32 | ||||
| #define XPT_INP4_MERGE_HDR1 0x9070008C,0,32 | ||||
| #define XPT_INP4_MERGE_HDR2 0x90700090,0,32 | ||||
| #define XPT_INP5_MERGE_HDR0 0x90700094,0,32 | ||||
| #define XPT_INP5_MERGE_HDR1 0x90700098,0,32 | ||||
| #define XPT_INP5_MERGE_HDR2 0x9070009C,0,32 | ||||
| #define XPT_INP6_MERGE_HDR0 0x907000A0,0,32 | ||||
| #define XPT_INP6_MERGE_HDR1 0x907000A4,0,32 | ||||
| #define XPT_INP6_MERGE_HDR2 0x907000A8,0,32 | ||||
| #define XPT_INP7_MERGE_HDR0 0x907000AC,0,32 | ||||
| #define XPT_INP7_MERGE_HDR1 0x907000B0,0,32 | ||||
| #define XPT_INP7_MERGE_HDR2 0x907000B4,0,32 | ||||
| #define XPT_INP_MODE_DSS0 0x90700000,8,1 | ||||
| #define XPT_INP_MODE_DSS1 0x90700000,9,1 | ||||
| #define XPT_INP_MODE_DSS2 0x90700000,10,1 | ||||
| #define XPT_INP_MODE_DSS3 0x90700000,11,1 | ||||
| #define XPT_INP_MODE_DSS4 0x90700000,12,1 | ||||
| #define XPT_INP_MODE_DSS5 0x90700000,13,1 | ||||
| #define XPT_INP_MODE_DSS6 0x90700000,14,1 | ||||
| #define XPT_INP_MODE_DSS7 0x90700000,15,1 | ||||
| #define XPT_KNOWN_PID_MUX_SELECT0 0x90700190,8,4 | ||||
| #define XPT_KNOWN_PID_MUX_SELECT1 0x907001B0,8,4 | ||||
| #define XPT_LSB_FIRST0 0x9070000C,16,1 | ||||
| #define XPT_LSB_FIRST1 0x9070000C,17,1 | ||||
| #define XPT_LSB_FIRST2 0x9070000C,18,1 | ||||
| #define XPT_LSB_FIRST3 0x9070000C,19,1 | ||||
| #define XPT_LSB_FIRST4 0x9070000C,20,1 | ||||
| #define XPT_LSB_FIRST5 0x9070000C,21,1 | ||||
| #define XPT_LSB_FIRST6 0x9070000C,22,1 | ||||
| #define XPT_LSB_FIRST7 0x9070000C,23,1 | ||||
| #define XPT_MODE_27MHZ 0x90700184,0,1 | ||||
| #define XPT_NCO_COUNT_MIN 0x90700044,16,8 | ||||
| #define XPT_OUTPUT_MODE_DSS0 0x9070000C,8,1 | ||||
| #define XPT_OUTPUT_MODE_DSS1 0x9070000C,9,1 | ||||
| #define XPT_OUTPUT_MODE_DSS2 0x9070000C,10,1 | ||||
| #define XPT_OUTPUT_MODE_DSS3 0x9070000C,11,1 | ||||
| #define XPT_OUTPUT_MODE_DSS4 0x9070000C,12,1 | ||||
| #define XPT_OUTPUT_MODE_DSS5 0x9070000C,13,1 | ||||
| #define XPT_OUTPUT_MODE_DSS6 0x9070000C,14,1 | ||||
| #define XPT_OUTPUT_MODE_DSS7 0x9070000C,15,1 | ||||
| #define XPT_OUTPUT_MODE_MUXGATING0 0x90700020,0,1 | ||||
| #define XPT_OUTPUT_MODE_MUXGATING1 0x90700020,1,1 | ||||
| #define XPT_OUTPUT_MODE_MUXGATING2 0x90700020,2,1 | ||||
| #define XPT_OUTPUT_MODE_MUXGATING3 0x90700020,3,1 | ||||
| #define XPT_OUTPUT_MODE_MUXGATING4 0x90700020,4,1 | ||||
| #define XPT_OUTPUT_MODE_MUXGATING5 0x90700020,5,1 | ||||
| #define XPT_OUTPUT_MODE_MUXGATING6 0x90700020,6,1 | ||||
| #define XPT_OUTPUT_MODE_MUXGATING7 0x90700020,7,1 | ||||
| #define XPT_OUTPUT_MUXSELECT0 0x9070001C,0,3 | ||||
| #define XPT_OUTPUT_MUXSELECT1 0x9070001C,4,3 | ||||
| #define XPT_OUTPUT_MUXSELECT2 0x9070001C,8,3 | ||||
| #define XPT_OUTPUT_MUXSELECT3 0x9070001C,12,3 | ||||
| #define XPT_OUTPUT_MUXSELECT4 0x9070001C,16,3 | ||||
| #define XPT_OUTPUT_MUXSELECT5 0x9070001C,20,3 | ||||
| #define XPT_PCR_RTS_CORRECTION_ENABLE 0x90700008,14,1 | ||||
| #define XPT_PID_DEFAULT_DROP0 0x90700190,12,1 | ||||
| #define XPT_PID_DEFAULT_DROP1 0x90700190,13,1 | ||||
| #define XPT_PID_DEFAULT_DROP2 0x90700190,14,1 | ||||
| #define XPT_PID_DEFAULT_DROP3 0x90700190,15,1 | ||||
| #define XPT_PID_DEFAULT_DROP4 0x907001B0,12,1 | ||||
| #define XPT_PID_DEFAULT_DROP5 0x907001B0,13,1 | ||||
| #define XPT_PID_DEFAULT_DROP6 0x907001B0,14,1 | ||||
| #define XPT_PID_DEFAULT_DROP7 0x907001B0,15,1 | ||||
| #define XPT_PID_MUX_SELECT0 0x90700190,4,4 | ||||
| #define XPT_PID_MUX_SELECT1 0x907001B0,4,4 | ||||
| #define XPT_STREAM_MUXMODE0 0x90700008,0,2 | ||||
| #define XPT_STREAM_MUXMODE1 0x90700008,2,2 | ||||
| #define XPT_SYNC_FULL_BYTE0 0x90700010,0,1 | ||||
| #define XPT_SYNC_FULL_BYTE1 0x90700010,1,1 | ||||
| #define XPT_SYNC_FULL_BYTE2 0x90700010,2,1 | ||||
| #define XPT_SYNC_FULL_BYTE3 0x90700010,3,1 | ||||
| #define XPT_SYNC_FULL_BYTE4 0x90700010,4,1 | ||||
| #define XPT_SYNC_FULL_BYTE5 0x90700010,5,1 | ||||
| #define XPT_SYNC_FULL_BYTE6 0x90700010,6,1 | ||||
| #define XPT_SYNC_FULL_BYTE7 0x90700010,7,1 | ||||
| #define XPT_SYNC_LOCK_THRESHOLD 0x9070017C,0,8 | ||||
| #define XPT_SYNC_MISS_THRESHOLD 0x9070017C,8,8 | ||||
| #define XPT_SYNC_POLARITY0 0x90700010,8,1 | ||||
| #define XPT_SYNC_POLARITY1 0x90700010,9,1 | ||||
| #define XPT_SYNC_POLARITY2 0x90700010,10,1 | ||||
| #define XPT_SYNC_POLARITY3 0x90700010,11,1 | ||||
| #define XPT_SYNC_POLARITY4 0x90700010,12,1 | ||||
| #define XPT_SYNC_POLARITY5 0x90700010,13,1 | ||||
| #define XPT_SYNC_POLARITY6 0x90700010,14,1 | ||||
| #define XPT_SYNC_POLARITY7 0x90700010,15,1 | ||||
| #define XPT_TS_CLK_OUT_EN0 0x907001D4,0,1 | ||||
| #define XPT_TS_CLK_OUT_EN1 0x907001D4,1,1 | ||||
| #define XPT_TS_CLK_OUT_EN2 0x907001D4,2,1 | ||||
| #define XPT_TS_CLK_OUT_EN3 0x907001D4,3,1 | ||||
| #define XPT_TS_CLK_OUT_EN4 0x907001D4,4,1 | ||||
| #define XPT_TS_CLK_OUT_EN5 0x907001D4,5,1 | ||||
| #define XPT_TS_CLK_OUT_EN6 0x907001D4,6,1 | ||||
| #define XPT_TS_CLK_OUT_EN7 0x907001D4,7,1 | ||||
| #define XPT_TS_CLK_OUT_EN_PARALLEL 0x907001D4,8,1 | ||||
| #define XPT_TS_CLK_PHASE0 0x90700018,0,3 | ||||
| #define XPT_TS_CLK_PHASE1 0x90700018,4,3 | ||||
| #define XPT_TS_CLK_PHASE2 0x90700018,8,3 | ||||
| #define XPT_TS_CLK_PHASE3 0x90700018,12,3 | ||||
| #define XPT_TS_CLK_PHASE4 0x90700018,16,3 | ||||
| #define XPT_TS_CLK_PHASE5 0x90700018,20,3 | ||||
| #define XPT_TS_CLK_PHASE6 0x90700018,24,3 | ||||
| #define XPT_TS_CLK_PHASE7 0x90700018,28,3 | ||||
| #define XPT_VALID_POLARITY0 0x90700014,0,1 | ||||
| #define XPT_VALID_POLARITY1 0x90700014,1,1 | ||||
| #define XPT_VALID_POLARITY2 0x90700014,2,1 | ||||
| #define XPT_VALID_POLARITY3 0x90700014,3,1 | ||||
| #define XPT_VALID_POLARITY4 0x90700014,4,1 | ||||
| #define XPT_VALID_POLARITY5 0x90700014,5,1 | ||||
| #define XPT_VALID_POLARITY6 0x90700014,6,1 | ||||
| #define XPT_VALID_POLARITY7 0x90700014,7,1 | ||||
| #define XPT_ZERO_FILL_COUNT 0x90700008,8,6 | ||||
|  | ||||
| #define   XPT_PACKET_GAP_MIN_BASEADDR                            0x90700044 | ||||
| #define   XPT_PACKET_GAP_MIN_TIMER                               XPT_PACKET_GAP_MIN_BASEADDR,0,16 | ||||
| #define   XPT_NCO_COUNT_MIN0 XPT_PACKET_GAP_MIN_BASEADDR,16,8 | ||||
| #define   XPT_NCO_COUNT_BASEADDR                                 0x90700238 | ||||
| #define   XPT_NCO_COUNT_MIN1 XPT_NCO_COUNT_BASEADDR,0,8 | ||||
| #define   XPT_NCO_COUNT_MIN2 XPT_NCO_COUNT_BASEADDR,8,8 | ||||
| #define   XPT_NCO_COUNT_MIN3 XPT_NCO_COUNT_BASEADDR,16,8 | ||||
| #define   XPT_NCO_COUNT_MIN4 XPT_NCO_COUNT_BASEADDR,24,8 | ||||
|  | ||||
| #define   XPT_NCO_COUNT_BASEADDR1                                0x9070023C | ||||
| #define   XPT_NCO_COUNT_MIN5 XPT_NCO_COUNT_BASEADDR1,0,8 | ||||
| #define   XPT_NCO_COUNT_MIN6 XPT_NCO_COUNT_BASEADDR1,8,8 | ||||
| #define   XPT_NCO_COUNT_MIN7 XPT_NCO_COUNT_BASEADDR1,16,8 | ||||
|  | ||||
| // V2 DigRF status register | ||||
| #define   BB0_DIGRF_CAPT_DONE                                    0x908000CC,0,1 | ||||
| #define   PRCM_PRCM_CHIP_ID                                      0x80030000,0,12 | ||||
|  | ||||
| #define   XPT_PID_BASEADDR                                       0x90708000 | ||||
| #define   XPT_PID_VALID0                                         XPT_PID_BASEADDR,0,1 | ||||
| #define   XPT_PID_DROP0                                          XPT_PID_BASEADDR,1,1 | ||||
| #define   XPT_PID_REMAP0                                         XPT_PID_BASEADDR,2,1 | ||||
| #define   XPT_PID_VALUE0                                         XPT_PID_BASEADDR,4,13 | ||||
| #define   XPT_PID_MASK0                                          XPT_PID_BASEADDR,19,13 | ||||
|  | ||||
| #define   XPT_PID_REMAP_BASEADDR                                 0x90708004 | ||||
| #define   XPT_PID_REMAP_VALUE0                                   XPT_PID_REMAP_BASEADDR,0,13 | ||||
| #define   XPT_PID_PORT_ID0                                       XPT_PID_REMAP_BASEADDR,16,3 | ||||
|  | ||||
| #define   XPT_KNOWN_PID_BASEADDR                                 0x90709000 | ||||
| #define   XPT_KNOWN_PID_VALID0                                   XPT_KNOWN_PID_BASEADDR,0,1 | ||||
| #define   XPT_KNOWN_PID_DROP0                                    XPT_KNOWN_PID_BASEADDR,1,1 | ||||
| #define   XPT_KNOWN_PID_REMAP0                                   XPT_KNOWN_PID_BASEADDR,2,1 | ||||
| #define   XPT_KNOWN_PID_REMAP_VALUE0                             XPT_KNOWN_PID_BASEADDR,16,13 | ||||
|  | ||||
| #define   XPT_PID_BASEADDR1                                      0x9070A000 | ||||
| #define   XPT_PID_VALID1                                         XPT_PID_BASEADDR1,0,1 | ||||
| #define   XPT_PID_DROP1                                          XPT_PID_BASEADDR1,1,1 | ||||
| #define   XPT_PID_REMAP1                                         XPT_PID_BASEADDR1,2,1 | ||||
| #define   XPT_PID_VALUE1                                         XPT_PID_BASEADDR1,4,13 | ||||
| #define   XPT_PID_MASK1                                          XPT_PID_BASEADDR1,19,13 | ||||
|  | ||||
| #define   XPT_PID_REMAP_BASEADDR1                                0x9070A004 | ||||
| #define   XPT_PID_REMAP_VALUE1                                   XPT_PID_REMAP_BASEADDR1,0,13 | ||||
|  | ||||
| #define   XPT_KNOWN_PID_BASEADDR1                                0x9070B000 | ||||
| #define   XPT_KNOWN_PID_VALID1                                   XPT_KNOWN_PID_BASEADDR1,0,1 | ||||
| #define   XPT_KNOWN_PID_DROP1                                    XPT_KNOWN_PID_BASEADDR1,1,1 | ||||
| #define   XPT_KNOWN_PID_REMAP1                                   XPT_KNOWN_PID_BASEADDR1,2,1 | ||||
| #define   XPT_KNOWN_PID_REMAP_VALUE1                             XPT_KNOWN_PID_BASEADDR1,16,13 | ||||
|  | ||||
| #define   XPT_BERT_LOCK_BASEADDR                                 0x907000B8 | ||||
| #define   XPT_BERT_LOCK_THRESHOLD                                XPT_BERT_LOCK_BASEADDR,0,8 | ||||
| #define   XPT_BERT_LOCK_WINDOW                                   XPT_BERT_LOCK_BASEADDR,8,8 | ||||
|  | ||||
| #define   XPT_BERT_BASEADDR                                      0x907000BC | ||||
| #define   XPT_BERT_ENABLE0                                       XPT_BERT_BASEADDR,0,1 | ||||
| #define   XPT_BERT_ENABLE1                                       XPT_BERT_BASEADDR,1,1 | ||||
| #define   XPT_BERT_ENABLE2                                       XPT_BERT_BASEADDR,2,1 | ||||
| #define   XPT_BERT_ENABLE3                                       XPT_BERT_BASEADDR,3,1 | ||||
| #define   XPT_BERT_ENABLE4                                       XPT_BERT_BASEADDR,4,1 | ||||
| #define   XPT_BERT_ENABLE5                                       XPT_BERT_BASEADDR,5,1 | ||||
| #define   XPT_BERT_ENABLE6                                       XPT_BERT_BASEADDR,6,1 | ||||
| #define   XPT_BERT_ENABLE7                                       XPT_BERT_BASEADDR,7,1 | ||||
| #define   XPT_BERT_SEQUENCE_PN23_0                               XPT_BERT_BASEADDR,8,1 | ||||
| #define   XPT_BERT_SEQUENCE_PN23_1                               XPT_BERT_BASEADDR,9,1 | ||||
| #define   XPT_BERT_SEQUENCE_PN23_2                               XPT_BERT_BASEADDR,10,1 | ||||
| #define   XPT_BERT_SEQUENCE_PN23_3                               XPT_BERT_BASEADDR,11,1 | ||||
| #define   XPT_BERT_SEQUENCE_PN23_4                               XPT_BERT_BASEADDR,12,1 | ||||
| #define   XPT_BERT_SEQUENCE_PN23_5                               XPT_BERT_BASEADDR,13,1 | ||||
| #define   XPT_BERT_SEQUENCE_PN23_6                               XPT_BERT_BASEADDR,14,1 | ||||
| #define   XPT_BERT_SEQUENCE_PN23_7                               XPT_BERT_BASEADDR,15,1 | ||||
| #define   XPT_LOCK_RESYNC0                                       XPT_BERT_BASEADDR,16,1 | ||||
| #define   XPT_LOCK_RESYNC1                                       XPT_BERT_BASEADDR,17,1 | ||||
| #define   XPT_LOCK_RESYNC2                                       XPT_BERT_BASEADDR,18,1 | ||||
| #define   XPT_LOCK_RESYNC3                                       XPT_BERT_BASEADDR,19,1 | ||||
| #define   XPT_LOCK_RESYNC4                                       XPT_BERT_BASEADDR,20,1 | ||||
| #define   XPT_LOCK_RESYNC5                                       XPT_BERT_BASEADDR,21,1 | ||||
| #define   XPT_LOCK_RESYNC6                                       XPT_BERT_BASEADDR,22,1 | ||||
| #define   XPT_LOCK_RESYNC7                                       XPT_BERT_BASEADDR,23,1 | ||||
| #define   XPT_BERT_DATA_POLARITY0                                XPT_BERT_BASEADDR,24,1 | ||||
| #define   XPT_BERT_DATA_POLARITY1                                XPT_BERT_BASEADDR,25,1 | ||||
| #define   XPT_BERT_DATA_POLARITY2                                XPT_BERT_BASEADDR,26,1 | ||||
| #define   XPT_BERT_DATA_POLARITY3                                XPT_BERT_BASEADDR,27,1 | ||||
| #define   XPT_BERT_DATA_POLARITY4                                XPT_BERT_BASEADDR,28,1 | ||||
| #define   XPT_BERT_DATA_POLARITY5                                XPT_BERT_BASEADDR,29,1 | ||||
| #define   XPT_BERT_DATA_POLARITY6                                XPT_BERT_BASEADDR,30,1 | ||||
| #define   XPT_BERT_DATA_POLARITY7                                XPT_BERT_BASEADDR,31,1 | ||||
|  | ||||
| #define   XPT_BERT_INVERT_BASEADDR                               0x907000C0 | ||||
| #define   XPT_BERT_INVERT_DATA0                                  XPT_BERT_INVERT_BASEADDR,0,1 | ||||
| #define   XPT_BERT_INVERT_DATA1                                  XPT_BERT_INVERT_BASEADDR,1,1 | ||||
| #define   XPT_BERT_INVERT_DATA2                                  XPT_BERT_INVERT_BASEADDR,2,1 | ||||
| #define   XPT_BERT_INVERT_DATA3                                  XPT_BERT_INVERT_BASEADDR,3,1 | ||||
| #define   XPT_BERT_INVERT_DATA4                                  XPT_BERT_INVERT_BASEADDR,4,1 | ||||
| #define   XPT_BERT_INVERT_DATA5                                  XPT_BERT_INVERT_BASEADDR,5,1 | ||||
| #define   XPT_BERT_INVERT_DATA6                                  XPT_BERT_INVERT_BASEADDR,6,1 | ||||
| #define   XPT_BERT_INVERT_DATA7                                  XPT_BERT_INVERT_BASEADDR,7,1 | ||||
| #define   XPT_BERT_INVERT_SEQUENCE0                              XPT_BERT_INVERT_BASEADDR,8,1 | ||||
| #define   XPT_BERT_INVERT_SEQUENCE1                              XPT_BERT_INVERT_BASEADDR,9,1 | ||||
| #define   XPT_BERT_INVERT_SEQUENCE2                              XPT_BERT_INVERT_BASEADDR,10,1 | ||||
| #define   XPT_BERT_INVERT_SEQUENCE3                              XPT_BERT_INVERT_BASEADDR,11,1 | ||||
| #define   XPT_BERT_INVERT_SEQUENCE4                              XPT_BERT_INVERT_BASEADDR,12,1 | ||||
| #define   XPT_BERT_INVERT_SEQUENCE5                              XPT_BERT_INVERT_BASEADDR,13,1 | ||||
| #define   XPT_BERT_INVERT_SEQUENCE6                              XPT_BERT_INVERT_BASEADDR,14,1 | ||||
| #define   XPT_BERT_INVERT_SEQUENCE7                              XPT_BERT_INVERT_BASEADDR,15,1 | ||||
| #define   XPT_BERT_OUTPUT_POLARITY0                              XPT_BERT_INVERT_BASEADDR,16,1 | ||||
| #define   XPT_BERT_OUTPUT_POLARITY1                              XPT_BERT_INVERT_BASEADDR,17,1 | ||||
| #define   XPT_BERT_OUTPUT_POLARITY2                              XPT_BERT_INVERT_BASEADDR,18,1 | ||||
| #define   XPT_BERT_OUTPUT_POLARITY3                              XPT_BERT_INVERT_BASEADDR,19,1 | ||||
| #define   XPT_BERT_OUTPUT_POLARITY4                              XPT_BERT_INVERT_BASEADDR,20,1 | ||||
| #define   XPT_BERT_OUTPUT_POLARITY5                              XPT_BERT_INVERT_BASEADDR,21,1 | ||||
| #define   XPT_BERT_OUTPUT_POLARITY6                              XPT_BERT_INVERT_BASEADDR,22,1 | ||||
| #define   XPT_BERT_OUTPUT_POLARITY7                              XPT_BERT_INVERT_BASEADDR,23,1 | ||||
|  | ||||
| #define   XPT_BERT_HEADER_BASEADDR                               0x907000C4 | ||||
| #define   XPT_BERT_HEADER_MODE0                                  XPT_BERT_HEADER_BASEADDR,0,2 | ||||
| #define   XPT_BERT_HEADER_MODE1                                  XPT_BERT_HEADER_BASEADDR,2,2 | ||||
| #define   XPT_BERT_HEADER_MODE2                                  XPT_BERT_HEADER_BASEADDR,4,2 | ||||
| #define   XPT_BERT_HEADER_MODE3                                  XPT_BERT_HEADER_BASEADDR,6,2 | ||||
| #define   XPT_BERT_HEADER_MODE4                                  XPT_BERT_HEADER_BASEADDR,8,2 | ||||
| #define   XPT_BERT_HEADER_MODE5                                  XPT_BERT_HEADER_BASEADDR,10,2 | ||||
| #define   XPT_BERT_HEADER_MODE6                                  XPT_BERT_HEADER_BASEADDR,12,2 | ||||
| #define   XPT_BERT_HEADER_MODE7                                  XPT_BERT_HEADER_BASEADDR,14,2 | ||||
|  | ||||
| #define   XPT_BERT_BASEADDR1                                     0x907000C8 | ||||
| #define   XPT_BERT_LOCKED0                                       XPT_BERT_BASEADDR1,0,1 | ||||
| #define   XPT_BERT_LOCKED1                                       XPT_BERT_BASEADDR1,1,1 | ||||
| #define   XPT_BERT_LOCKED2                                       XPT_BERT_BASEADDR1,2,1 | ||||
| #define   XPT_BERT_LOCKED3                                       XPT_BERT_BASEADDR1,3,1 | ||||
| #define   XPT_BERT_LOCKED4                                       XPT_BERT_BASEADDR1,4,1 | ||||
| #define   XPT_BERT_LOCKED5                                       XPT_BERT_BASEADDR1,5,1 | ||||
| #define   XPT_BERT_LOCKED6                                       XPT_BERT_BASEADDR1,6,1 | ||||
| #define   XPT_BERT_LOCKED7                                       XPT_BERT_BASEADDR1,7,1 | ||||
| #define   XPT_BERT_BIT_COUNT_SAT0                                XPT_BERT_BASEADDR1,8,1 | ||||
| #define   XPT_BERT_BIT_COUNT_SAT1                                XPT_BERT_BASEADDR1,9,1 | ||||
| #define   XPT_BERT_BIT_COUNT_SAT2                                XPT_BERT_BASEADDR1,10,1 | ||||
| #define   XPT_BERT_BIT_COUNT_SAT3                                XPT_BERT_BASEADDR1,11,1 | ||||
| #define   XPT_BERT_BIT_COUNT_SAT4                                XPT_BERT_BASEADDR1,12,1 | ||||
| #define   XPT_BERT_BIT_COUNT_SAT5                                XPT_BERT_BASEADDR1,13,1 | ||||
| #define   XPT_BERT_BIT_COUNT_SAT6                                XPT_BERT_BASEADDR1,14,1 | ||||
| #define   XPT_BERT_BIT_COUNT_SAT7                                XPT_BERT_BASEADDR1,15,1 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT0_BASEADDR                           0x907000CC | ||||
| #define   XPT_BERT_BIT_COUNT0_LO                                 XPT_BERT_BIT_COUNT0_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT0_BASEADDR1                          0x907000D0 | ||||
| #define   XPT_BERT_BIT_COUNT0_HI                                 XPT_BERT_BIT_COUNT0_BASEADDR1,0,18 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT1_BASEADDR                           0x907000D4 | ||||
| #define   XPT_BERT_BIT_COUNT1_LO                                 XPT_BERT_BIT_COUNT1_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT1_BASEADDR1                          0x907000D8 | ||||
| #define   XPT_BERT_BIT_COUNT1_HI                                 XPT_BERT_BIT_COUNT1_BASEADDR1,0,18 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT2_BASEADDR                           0x907000DC | ||||
| #define   XPT_BERT_BIT_COUNT2_LO                                 XPT_BERT_BIT_COUNT2_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT2_BASEADDR1                          0x907000E0 | ||||
| #define   XPT_BERT_BIT_COUNT2_HI                                 XPT_BERT_BIT_COUNT2_BASEADDR1,0,18 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT3_BASEADDR                           0x907000E4 | ||||
| #define   XPT_BERT_BIT_COUNT3_LO                                 XPT_BERT_BIT_COUNT3_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT3_BASEADDR1                          0x907000E8 | ||||
| #define   XPT_BERT_BIT_COUNT3_HI                                 XPT_BERT_BIT_COUNT3_BASEADDR1,0,18 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT4_BASEADDR                           0x907000EC | ||||
| #define   XPT_BERT_BIT_COUNT4_LO                                 XPT_BERT_BIT_COUNT4_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT4_BASEADDR1                          0x907000F0 | ||||
| #define   XPT_BERT_BIT_COUNT4_HI                                 XPT_BERT_BIT_COUNT4_BASEADDR1,0,18 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT5_BASEADDR                           0x907000F4 | ||||
| #define   XPT_BERT_BIT_COUNT5_LO                                 XPT_BERT_BIT_COUNT5_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT5_BASEADDR1                          0x907000F8 | ||||
| #define   XPT_BERT_BIT_COUNT5_HI                                 XPT_BERT_BIT_COUNT5_BASEADDR1,0,18 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT6_BASEADDR                           0x907000FC | ||||
| #define   XPT_BERT_BIT_COUNT6_LO                                 XPT_BERT_BIT_COUNT6_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT6_BASEADDR1                          0x90700100 | ||||
| #define   XPT_BERT_BIT_COUNT6_HI                                 XPT_BERT_BIT_COUNT6_BASEADDR1,0,18 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT7_BASEADDR                           0x90700104 | ||||
| #define   XPT_BERT_BIT_COUNT7_LO                                 XPT_BERT_BIT_COUNT7_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_BIT_COUNT7_BASEADDR1                          0x90700108 | ||||
| #define   XPT_BERT_BIT_COUNT7_HI                                 XPT_BERT_BIT_COUNT7_BASEADDR1,0,18 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT0_BASEADDR                           0x9070010C | ||||
| #define   XPT_BERT_ERR_COUNT0_LO                                 XPT_BERT_ERR_COUNT0_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT0_BASEADDR1                          0x90700110 | ||||
| #define   XPT_BERT_ERR_COUNT0_HI                                 XPT_BERT_ERR_COUNT0_BASEADDR1,0,8 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT1_BASEADDR                           0x90700114 | ||||
| #define   XPT_BERT_ERR_COUNT1_LO                                 XPT_BERT_ERR_COUNT1_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT1_BASEADDR1                          0x90700118 | ||||
| #define   XPT_BERT_ERR_COUNT1_HI                                 XPT_BERT_ERR_COUNT1_BASEADDR1,0,8 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT2_BASEADDR                           0x9070011C | ||||
| #define   XPT_BERT_ERR_COUNT2_LO                                 XPT_BERT_ERR_COUNT2_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT2_BASEADDR1                          0x90700120 | ||||
| #define   XPT_BERT_ERR_COUNT2_HI                                 XPT_BERT_ERR_COUNT2_BASEADDR1,0,8 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT3_BASEADDR                           0x90700124 | ||||
| #define   XPT_BERT_ERR_COUNT3_LO                                 XPT_BERT_ERR_COUNT3_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT3_BASEADDR1                          0x90700128 | ||||
| #define   XPT_BERT_ERR_COUNT3_HI                                 XPT_BERT_ERR_COUNT3_BASEADDR1,0,8 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT4_BASEADDR                           0x9070012C | ||||
| #define   XPT_BERT_ERR_COUNT4_LO                                 XPT_BERT_ERR_COUNT4_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT4_BASEADDR1                          0x90700130 | ||||
| #define   XPT_BERT_ERR_COUNT4_HI                                 XPT_BERT_ERR_COUNT4_BASEADDR1,0,8 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT5_BASEADDR                           0x90700134 | ||||
| #define   XPT_BERT_ERR_COUNT5_LO                                 XPT_BERT_ERR_COUNT5_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT5_BASEADDR1                          0x90700138 | ||||
| #define   XPT_BERT_ERR_COUNT5_HI                                 XPT_BERT_ERR_COUNT5_BASEADDR1,0,8 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT6_BASEADDR                           0x9070013C | ||||
| #define   XPT_BERT_ERR_COUNT6_LO                                 XPT_BERT_ERR_COUNT6_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT6_BASEADDR1                          0x90700140 | ||||
| #define   XPT_BERT_ERR_COUNT6_HI                                 XPT_BERT_ERR_COUNT6_BASEADDR1,0,8 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT7_BASEADDR                           0x90700144 | ||||
| #define   XPT_BERT_ERR_COUNT7_LO                                 XPT_BERT_ERR_COUNT7_BASEADDR,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ERR_COUNT7_BASEADDR1                          0x90700148 | ||||
| #define   XPT_BERT_ERR_COUNT7_HI                                 XPT_BERT_ERR_COUNT7_BASEADDR1,0,8 | ||||
|  | ||||
| #define   XPT_BERT_ERROR_BASEADDR                                0x9070014C | ||||
| #define   XPT_BERT_ERROR_INSERT                                  XPT_BERT_ERROR_BASEADDR,0,24 | ||||
|  | ||||
| #define   XPT_BERT_ANALYZER_BASEADDR                             0x90700150 | ||||
| #define   XPT_BERT_ANALYZER_ENABLE                               XPT_BERT_ANALYZER_BASEADDR,0,1 | ||||
| #define   XPT_BERT_ANALYZER_PORT                                 XPT_BERT_ANALYZER_BASEADDR,4,3 | ||||
| #define   XPT_BERT_ANALYZER_ERR_THRES                            XPT_BERT_ANALYZER_BASEADDR,15,17 | ||||
|  | ||||
| #define   XPT_BERT_ANALYZER_BASEADDR1                            0x90700154 | ||||
| #define   XPT_BERT_ANALYZER_START                                XPT_BERT_ANALYZER_BASEADDR1,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ANALYZER_BASEADDR2                            0x90700158 | ||||
| #define   XPT_BERT_ANALYZER_TSTAMP0                              XPT_BERT_ANALYZER_BASEADDR2,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ANALYZER_BASEADDR3                            0x9070015C | ||||
| #define   XPT_BERT_ANALYZER_TSTAMP1                              XPT_BERT_ANALYZER_BASEADDR3,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ANALYZER_BASEADDR4                            0x90700160 | ||||
| #define   XPT_BERT_ANALYZER_TSTAMP2                              XPT_BERT_ANALYZER_BASEADDR4,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ANALYZER_BASEADDR5                            0x90700164 | ||||
| #define   XPT_BERT_ANALYZER_TSTAMP3                              XPT_BERT_ANALYZER_BASEADDR5,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ANALYZER_BASEADDR6                            0x90700168 | ||||
| #define   XPT_BERT_ANALYZER_TSTAMP4                              XPT_BERT_ANALYZER_BASEADDR6,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ANALYZER_BASEADDR7                            0x9070016C | ||||
| #define   XPT_BERT_ANALYZER_TSTAMP5                              XPT_BERT_ANALYZER_BASEADDR7,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ANALYZER_BASEADDR8                            0x90700170 | ||||
| #define   XPT_BERT_ANALYZER_TSTAMP6                              XPT_BERT_ANALYZER_BASEADDR8,0,32 | ||||
|  | ||||
| #define   XPT_BERT_ANALYZER_BASEADDR9                            0x90700174 | ||||
| #define   XPT_BERT_ANALYZER_TSTAMP7                              XPT_BERT_ANALYZER_BASEADDR9,0,32 | ||||
|  | ||||
| #define   XPT_DMD0_BASEADDR                                      0x9070024C | ||||
| #define   XPT_DMD0_SEL                                           XPT_DMD0_BASEADDR,0,3 | ||||
| #define   XPT_DMD1_SEL                                           XPT_DMD0_BASEADDR,4,3 | ||||
| #define   XPT_DMD2_SEL                                           XPT_DMD0_BASEADDR,8,3 | ||||
| #define   XPT_DMD3_SEL                                           XPT_DMD0_BASEADDR,12,3 | ||||
| #define   XPT_DMD4_SEL                                           XPT_DMD0_BASEADDR,16,3 | ||||
| #define   XPT_DMD5_SEL                                           XPT_DMD0_BASEADDR,20,3 | ||||
| #define   XPT_DMD6_SEL                                           XPT_DMD0_BASEADDR,24,3 | ||||
| #define   XPT_DMD7_SEL                                           XPT_DMD0_BASEADDR,28,3 | ||||
|  | ||||
| // V2 AGC Gain Freeze & step | ||||
| #define   DBG_ENABLE_DISABLE_AGC                                 (0x3FFFCF60) // 1: DISABLE, 0:ENABLE | ||||
| #define   WB_DFE0_DFE_FB_RF1_BASEADDR                            0x903004A4 | ||||
| #define   WB_DFE0_DFE_FB_RF1_BO                                  WB_DFE0_DFE_FB_RF1_BASEADDR,0,3 | ||||
| #define   WB_DFE0_DFE_FB_RF2_BO                                  WB_DFE0_DFE_FB_RF1_BASEADDR,4,4 | ||||
| #define   WB_DFE0_DFE_FB_LNA_BO                                  WB_DFE0_DFE_FB_RF1_BASEADDR,8,2 | ||||
|  | ||||
| #define   WB_DFE1_DFE_FB_RF1_BASEADDR                            0x904004A4 | ||||
| #define   WB_DFE1_DFE_FB_RF1_BO                                  WB_DFE1_DFE_FB_RF1_BASEADDR,0,3 | ||||
| #define   WB_DFE1_DFE_FB_RF2_BO                                  WB_DFE1_DFE_FB_RF1_BASEADDR,4,4 | ||||
| #define   WB_DFE1_DFE_FB_LNA_BO                                  WB_DFE1_DFE_FB_RF1_BASEADDR,8,2 | ||||
|  | ||||
| #define   WB_DFE2_DFE_FB_RF1_BASEADDR                            0x905004A4 | ||||
| #define   WB_DFE2_DFE_FB_RF1_BO                                  WB_DFE2_DFE_FB_RF1_BASEADDR,0,3 | ||||
| #define   WB_DFE2_DFE_FB_RF2_BO                                  WB_DFE2_DFE_FB_RF1_BASEADDR,4,4 | ||||
| #define   WB_DFE2_DFE_FB_LNA_BO                                  WB_DFE2_DFE_FB_RF1_BASEADDR,8,2 | ||||
|  | ||||
| #define   WB_DFE3_DFE_FB_RF1_BASEADDR                            0x906004A4 | ||||
| #define   WB_DFE3_DFE_FB_RF1_BO                                  WB_DFE3_DFE_FB_RF1_BASEADDR,0,3 | ||||
| #define   WB_DFE3_DFE_FB_RF2_BO                                  WB_DFE3_DFE_FB_RF1_BASEADDR,4,4 | ||||
| #define   WB_DFE3_DFE_FB_LNA_BO                                  WB_DFE3_DFE_FB_RF1_BASEADDR,8,2 | ||||
|  | ||||
| #define   AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR                0x90200104 | ||||
| #define   AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_2                       AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,0,1 | ||||
| #define   AFE_REG_D2A_TA_RFFE_RF1_BO_1P8_3                       AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,1,1 | ||||
| #define   AFE_REG_D2A_TB_RFFE_LNA_BO_1P8_2                       AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,2,1 | ||||
| #define   AFE_REG_D2A_TB_RFFE_RF1_BO_1P8_3                       AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,3,1 | ||||
| #define   AFE_REG_D2A_TC_RFFE_LNA_BO_1P8_2                       AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,4,1 | ||||
| #define   AFE_REG_D2A_TC_RFFE_RF1_BO_1P8_3                       AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,5,1 | ||||
| #define   AFE_REG_D2A_TD_RFFE_LNA_BO_1P8_2                       AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,6,1 | ||||
| #define   AFE_REG_D2A_TD_RFFE_RF1_BO_1P8_3                       AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,7,1 | ||||
|  | ||||
| #define   AFE_REG_AFE_REG_SPARE_BASEADDR                         0x902000A0 | ||||
| #define   AFE_REG_D2A_TA_RFFE_RF1_CAP_1P8                        AFE_REG_AFE_REG_SPARE_BASEADDR,13,5 | ||||
|  | ||||
| #define   AFE_REG_AFE_REG_SPARE_BASEADDR1                        0x902000B4 | ||||
| #define   AFE_REG_D2A_TB_RFFE_RF1_CAP_1P8                        AFE_REG_AFE_REG_SPARE_BASEADDR1,13,5 | ||||
|  | ||||
| #define   AFE_REG_AFE_REG_SPARE_BASEADDR2                        0x902000C4 | ||||
| #define   AFE_REG_D2A_TC_RFFE_RF1_CAP_1P8                        AFE_REG_AFE_REG_SPARE_BASEADDR2,13,5 | ||||
|  | ||||
| #define   AFE_REG_AFE_REG_SPARE_BASEADDR3                        0x902000D4 | ||||
| #define   AFE_REG_D2A_TD_RFFE_RF1_CAP_1P8                        AFE_REG_AFE_REG_SPARE_BASEADDR3,13,5 | ||||
|  | ||||
| #define   WB_DFE0_DFE_FB_AGC_BASEADDR                            0x90300498 | ||||
| #define   WB_DFE0_DFE_FB_AGC_APPLY                               WB_DFE0_DFE_FB_AGC_BASEADDR,0,1 | ||||
|  | ||||
| #define   WB_DFE1_DFE_FB_AGC_BASEADDR                            0x90400498 | ||||
| #define   WB_DFE1_DFE_FB_AGC_APPLY                               WB_DFE1_DFE_FB_AGC_BASEADDR,0,1 | ||||
|  | ||||
| #define   WB_DFE2_DFE_FB_AGC_BASEADDR                            0x90500498 | ||||
| #define   WB_DFE2_DFE_FB_AGC_APPLY                               WB_DFE2_DFE_FB_AGC_BASEADDR,0,1 | ||||
|  | ||||
| #define   WB_DFE3_DFE_FB_AGC_BASEADDR                            0x90600498 | ||||
| #define   WB_DFE3_DFE_FB_AGC_APPLY                               WB_DFE3_DFE_FB_AGC_BASEADDR,0,1 | ||||
|  | ||||
| #define   WDT_WD_INT_BASEADDR                                    0x8002000C | ||||
| #define   WDT_WD_INT_STATUS                                      WDT_WD_INT_BASEADDR,0,1 | ||||
|  | ||||
| #define   FSK_TX_FTM_BASEADDR                                    0x80090000 | ||||
| #define   FSK_TX_FTM_OE                                          FSK_TX_FTM_BASEADDR,12,1 | ||||
| #define   FSK_TX_FTM_TX_EN                                       FSK_TX_FTM_BASEADDR,10,1 | ||||
| #define   FSK_TX_FTM_FORCE_CARRIER_ON                            FSK_TX_FTM_BASEADDR,1,1 | ||||
| #define   FSK_TX_FTM_FORCE_MARK_SPACE                            FSK_TX_FTM_BASEADDR,0,1 | ||||
|  | ||||
| #define   FSK_TX_FTM_TX_CNT_BASEADDR                             0x80090018 | ||||
| #define   FSK_TX_FTM_TX_CNT_INT                                  FSK_TX_FTM_TX_CNT_BASEADDR,8,4 | ||||
| #define   FSK_TX_FTM_TX_INT_EN                                   FSK_TX_FTM_TX_CNT_BASEADDR,4,1 | ||||
| #define   FSK_TX_FTM_TX_INT_SRC_SEL                              FSK_TX_FTM_TX_CNT_BASEADDR,0,2 | ||||
|  | ||||
| #define   AFE_REG_D2A_FSK_BIAS_BASEADDR                          0x90200040 | ||||
| #define   AFE_REG_D2A_FSK_BIAS_EN                                AFE_REG_D2A_FSK_BIAS_BASEADDR,0,1 | ||||
| #define   AFE_REG_D2A_FSK_TEST_EN                                AFE_REG_D2A_FSK_BIAS_BASEADDR,10,1 | ||||
| #define   AFE_REG_D2A_FSK_TEST_MODE                              AFE_REG_D2A_FSK_BIAS_BASEADDR,11,4 | ||||
| #define   AFE_REG_D2A_FSK_TERM_INT_EN                            AFE_REG_D2A_FSK_BIAS_BASEADDR,15,1 | ||||
| #define   AFE_REG_D2A_FSK_RESETB_1P8                             AFE_REG_D2A_FSK_BIAS_BASEADDR,16,1 | ||||
| #define   AFE_REG_D2A_FSK_REG_EN_1P8                             AFE_REG_D2A_FSK_BIAS_BASEADDR,17,1 | ||||
| #define   AFE_REG_D2A_FSK_REG_EN_LKG_1P8                         AFE_REG_D2A_FSK_BIAS_BASEADDR,18,1 | ||||
| #define   AFE_REG_D2A_FSK_REG_AMP_1P8                            AFE_REG_D2A_FSK_BIAS_BASEADDR,19,3 | ||||
| #define   AFE_REG_D2A_FSK_REG_TEST_CTRL_1P8                      AFE_REG_D2A_FSK_BIAS_BASEADDR,22,2 | ||||
| #define   AFE_REG_D2A_DSQ_RX_MODE                                AFE_REG_D2A_FSK_BIAS_BASEADDR,24,1 | ||||
| #define   AFE_REG_D2A_DSQ_RX_EN                                  AFE_REG_D2A_FSK_BIAS_BASEADDR,25,1 | ||||
| #define   AFE_REG_D2A_DSQ_HYST                                   AFE_REG_D2A_FSK_BIAS_BASEADDR,26,2 | ||||
| #define   AFE_REG_D2A_DSQ_RESETB_1P8                             AFE_REG_D2A_FSK_BIAS_BASEADDR,28,1 | ||||
| #define   AFE_REG_D2A_FSK_CLKRX_ENA                              AFE_REG_D2A_FSK_BIAS_BASEADDR,29,1 | ||||
|  | ||||
| #define   DMD_TEI_BASEADDR                                       0x3FFFEBE0 | ||||
| #define   DMD_TEI_ENA                                            DMD_TEI_BASEADDR,0,1 | ||||
|  | ||||
| #define   xpt_shm_input_control0  0x90700270,0,8 | ||||
| #define   xpt_shm_input_control1  0x90700270,8,8 | ||||
| #define   xpt_shm_input_control2  0x90700270,16,8 | ||||
| #define   xpt_shm_input_control3  0x90700270,24,8 | ||||
| #define   xpt_shm_input_control4  0x90700274,0,8 | ||||
| #define   xpt_shm_input_control5  0x90700274,8,8 | ||||
| #define   xpt_shm_input_control6  0x90700274,16,8 | ||||
| #define   xpt_shm_input_control7  0x90700274,24,8 | ||||
|  | ||||
|  | ||||
| #define   xpt_shm_output_control0  0x90700278,0,8 | ||||
| #define   xpt_shm_output_control1  0x90700278,8,8 | ||||
| #define   xpt_shm_output_control2  0x90700278,16,8 | ||||
| #define   xpt_shm_output_control3  0x90700278,24,8 | ||||
| #define   xpt_shm_output_control4  0x9070027C,0,8 | ||||
| #define   xpt_shm_output_control5  0x9070027C,8,8 | ||||
| #define   xpt_shm_output_control6  0x9070027C,16,8 | ||||
| #define   xpt_shm_output_control7  0x9070027C,24,8 | ||||
|  | ||||
| #define   xpt_mode_27mhz           0x90700184,0,1 | ||||
| #define   xpt_enable_pcr_count     0x90700184,1,1 | ||||
|  | ||||
| #define   xcpu_ctrl_003c_reg       0x9072003C,0,4 | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif //__MXL58X_REGISTERS_H__ | ||||
							
								
								
									
										3472
									
								
								frontends/stv0367.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3472
									
								
								frontends/stv0367.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										89
									
								
								frontends/stv0367.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								frontends/stv0367.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | ||||
| /* | ||||
|  * stv0367.h | ||||
|  * | ||||
|  * Driver for ST STV0367 DVB-T & DVB-C demodulator IC. | ||||
|  * | ||||
|  * Copyright (C) ST Microelectronics. | ||||
|  * Copyright (C) 2010,2011 NetUP Inc. | ||||
|  * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru> | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
|  | ||||
| #ifndef STV0367_H | ||||
| #define STV0367_H | ||||
|  | ||||
| #include <linux/dvb/frontend.h> | ||||
| #include "dvb_frontend.h" | ||||
|  | ||||
| enum stv0367_ts_mode { | ||||
| 	STV0367_OUTPUTMODE_DEFAULT, | ||||
| 	STV0367_SERIAL_PUNCT_CLOCK, | ||||
| 	STV0367_SERIAL_CONT_CLOCK, | ||||
| 	STV0367_PARALLEL_PUNCT_CLOCK, | ||||
| 	STV0367_DVBCI_CLOCK | ||||
| }; | ||||
|  | ||||
| enum stv0367_clk_pol { | ||||
| 	STV0367_CLOCKPOLARITY_DEFAULT, | ||||
| 	STV0367_RISINGEDGE_CLOCK, | ||||
| 	STV0367_FALLINGEDGE_CLOCK | ||||
| }; | ||||
|  | ||||
| struct stv0367_config { | ||||
| 	u8 demod_address; | ||||
| 	u32 xtal; | ||||
| 	u32 if_khz;/*4500*/ | ||||
| 	int if_iq_mode; | ||||
| 	int ts_mode; | ||||
| 	int clk_pol; | ||||
| }; | ||||
|  | ||||
| enum stv0367_ter_if_iq_mode { | ||||
| 	FE_TER_NORMAL_IF_TUNER = 0, | ||||
| 	FE_TER_LONGPATH_IF_TUNER = 1, | ||||
| 	FE_TER_IQ_TUNER = 2 | ||||
|  | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| #if defined(CONFIG_DVB_STV0367) || (defined(CONFIG_DVB_STV0367_MODULE) \ | ||||
| 							&& defined(MODULE)) | ||||
| extern struct | ||||
| dvb_frontend *stv0367ter_attach(const struct stv0367_config *config, | ||||
| 					struct i2c_adapter *i2c); | ||||
| extern struct | ||||
| dvb_frontend *stv0367cab_attach(const struct stv0367_config *config, | ||||
| 					struct i2c_adapter *i2c); | ||||
| #else | ||||
| static inline struct | ||||
| dvb_frontend *stv0367ter_attach(const struct stv0367_config *config, | ||||
| 					struct i2c_adapter *i2c) | ||||
| { | ||||
| 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
| static inline struct | ||||
| dvb_frontend *stv0367cab_attach(const struct stv0367_config *config, | ||||
| 					struct i2c_adapter *i2c) | ||||
| { | ||||
| 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										191
									
								
								frontends/stv0367_priv.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								frontends/stv0367_priv.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,191 @@ | ||||
| /* | ||||
|  * stv0367_priv.h | ||||
|  * | ||||
|  * Driver for ST STV0367 DVB-T & DVB-C demodulator IC. | ||||
|  * | ||||
|  * Copyright (C) ST Microelectronics. | ||||
|  * Copyright (C) 2010,2011 NetUP Inc. | ||||
|  * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru> | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
| /* Common driver error constants */ | ||||
|  | ||||
| #ifndef STV0367_PRIV_H | ||||
| #define STV0367_PRIV_H | ||||
|  | ||||
| #ifndef TRUE | ||||
|     #define TRUE (1 == 1) | ||||
| #endif | ||||
| #ifndef FALSE | ||||
|     #define FALSE (!TRUE) | ||||
| #endif | ||||
|  | ||||
| #ifndef NULL | ||||
| #define NULL 0 | ||||
| #endif | ||||
|  | ||||
| /* MACRO definitions */ | ||||
| #define ABS(X) ((X) < 0 ? (-1 * (X)) : (X)) | ||||
| #define MAX(X, Y) ((X) >= (Y) ? (X) : (Y)) | ||||
| #define MIN(X, Y) ((X) <= (Y) ? (X) : (Y)) | ||||
| #define INRANGE(X, Y, Z) \ | ||||
| 	((((X) <= (Y)) && ((Y) <= (Z))) || \ | ||||
| 	(((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0) | ||||
|  | ||||
| #ifndef MAKEWORD | ||||
| #define MAKEWORD(X, Y) (((X) << 8) + (Y)) | ||||
| #endif | ||||
|  | ||||
| #define LSB(X) (((X) & 0xff)) | ||||
| #define MSB(Y) (((Y) >> 8) & 0xff) | ||||
| #define MMSB(Y)(((Y) >> 16) & 0xff) | ||||
|  | ||||
| enum stv0367_ter_signal_type { | ||||
| 	FE_TER_NOAGC = 0, | ||||
| 	FE_TER_AGCOK = 5, | ||||
| 	FE_TER_NOTPS = 6, | ||||
| 	FE_TER_TPSOK = 7, | ||||
| 	FE_TER_NOSYMBOL = 8, | ||||
| 	FE_TER_BAD_CPQ = 9, | ||||
| 	FE_TER_PRFOUNDOK = 10, | ||||
| 	FE_TER_NOPRFOUND = 11, | ||||
| 	FE_TER_LOCKOK = 12, | ||||
| 	FE_TER_NOLOCK = 13, | ||||
| 	FE_TER_SYMBOLOK = 15, | ||||
| 	FE_TER_CPAMPOK = 16, | ||||
| 	FE_TER_NOCPAMP = 17, | ||||
| 	FE_TER_SWNOK = 18 | ||||
| }; | ||||
|  | ||||
| enum stv0367_ter_bw { | ||||
| 	FE_TER_CHAN_BW_6M = 6, | ||||
| 	FE_TER_CHAN_BW_7M = 7, | ||||
| 	FE_TER_CHAN_BW_8M = 8 | ||||
| }; | ||||
|  | ||||
| #if 0 | ||||
| enum FE_TER_Rate_TPS { | ||||
| 	FE_TER_TPS_1_2 = 0, | ||||
| 	FE_TER_TPS_2_3 = 1, | ||||
| 	FE_TER_TPS_3_4 = 2, | ||||
| 	FE_TER_TPS_5_6 = 3, | ||||
| 	FE_TER_TPS_7_8 = 4 | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| enum stv0367_ter_mode { | ||||
| 	FE_TER_MODE_2K, | ||||
| 	FE_TER_MODE_8K, | ||||
| 	FE_TER_MODE_4K | ||||
| }; | ||||
| #if 0 | ||||
| enum FE_TER_Hierarchy_Alpha { | ||||
| 	FE_TER_HIER_ALPHA_NONE,	/* Regular modulation */ | ||||
| 	FE_TER_HIER_ALPHA_1,	/* Hierarchical modulation a = 1*/ | ||||
| 	FE_TER_HIER_ALPHA_2,	/* Hierarchical modulation a = 2*/ | ||||
| 	FE_TER_HIER_ALPHA_4	/* Hierarchical modulation a = 4*/ | ||||
| }; | ||||
| #endif | ||||
| enum stv0367_ter_hierarchy { | ||||
| 	FE_TER_HIER_NONE,	/*Hierarchy None*/ | ||||
| 	FE_TER_HIER_LOW_PRIO,	/*Hierarchy : Low Priority*/ | ||||
| 	FE_TER_HIER_HIGH_PRIO,	/*Hierarchy : High Priority*/ | ||||
| 	FE_TER_HIER_PRIO_ANY	/*Hierarchy  :Any*/ | ||||
| }; | ||||
|  | ||||
| #if 0 | ||||
| enum fe_stv0367_ter_spec { | ||||
| 	FE_TER_INVERSION_NONE = 0, | ||||
| 	FE_TER_INVERSION = 1, | ||||
| 	FE_TER_INVERSION_AUTO = 2, | ||||
| 	FE_TER_INVERSION_UNK  = 4 | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| enum FE_TER_FECRate { | ||||
| 	FE_TER_FEC_NONE = 0x00,	/* no FEC rate specified */ | ||||
| 	FE_TER_FEC_ALL = 0xFF,	 /* Logical OR of all FECs */ | ||||
| 	FE_TER_FEC_1_2 = 1, | ||||
| 	FE_TER_FEC_2_3 = (1 << 1), | ||||
| 	FE_TER_FEC_3_4 = (1 << 2), | ||||
| 	FE_TER_FEC_4_5 = (1 << 3), | ||||
| 	FE_TER_FEC_5_6 = (1 << 4), | ||||
| 	FE_TER_FEC_6_7 = (1 << 5), | ||||
| 	FE_TER_FEC_7_8 = (1 << 6), | ||||
| 	FE_TER_FEC_8_9 = (1 << 7) | ||||
| }; | ||||
|  | ||||
| enum FE_TER_Rate { | ||||
| 	FE_TER_FE_1_2 = 0, | ||||
| 	FE_TER_FE_2_3 = 1, | ||||
| 	FE_TER_FE_3_4 = 2, | ||||
| 	FE_TER_FE_5_6 = 3, | ||||
| 	FE_TER_FE_6_7 = 4, | ||||
| 	FE_TER_FE_7_8 = 5 | ||||
| }; | ||||
| #endif | ||||
|  | ||||
| enum stv0367_ter_force { | ||||
| 	FE_TER_FORCENONE = 0, | ||||
| 	FE_TER_FORCE_M_G = 1 | ||||
| }; | ||||
|  | ||||
| enum  stv0367cab_mod { | ||||
| 	FE_CAB_MOD_QAM4, | ||||
| 	FE_CAB_MOD_QAM16, | ||||
| 	FE_CAB_MOD_QAM32, | ||||
| 	FE_CAB_MOD_QAM64, | ||||
| 	FE_CAB_MOD_QAM128, | ||||
| 	FE_CAB_MOD_QAM256, | ||||
| 	FE_CAB_MOD_QAM512, | ||||
| 	FE_CAB_MOD_QAM1024 | ||||
| }; | ||||
| #if 0 | ||||
| enum { | ||||
| 	FE_CAB_FEC_A = 1,	/* J83 Annex A */ | ||||
| 	FE_CAB_FEC_B = (1 << 1),/* J83 Annex B */ | ||||
| 	FE_CAB_FEC_C = (1 << 2)	/* J83 Annex C */ | ||||
| } FE_CAB_FECType_t; | ||||
| #endif | ||||
| struct stv0367_cab_signal_info { | ||||
| 	int locked; | ||||
| 	u32 frequency; /* kHz */ | ||||
| 	u32 symbol_rate; /* Mbds */ | ||||
| 	enum stv0367cab_mod modulation; | ||||
| 	fe_spectral_inversion_t spect_inv; | ||||
| 	s32 Power_dBmx10;	/* Power of the RF signal (dBm x 10) */ | ||||
| 	u32	CN_dBx10;	/* Carrier to noise ratio (dB x 10) */ | ||||
| 	u32	BER;		/* Bit error rate (x 10000000)	*/ | ||||
| }; | ||||
|  | ||||
| enum stv0367_cab_signal_type { | ||||
| 	FE_CAB_NOTUNER, | ||||
| 	FE_CAB_NOAGC, | ||||
| 	FE_CAB_NOSIGNAL, | ||||
| 	FE_CAB_NOTIMING, | ||||
| 	FE_CAB_TIMINGOK, | ||||
| 	FE_CAB_NOCARRIER, | ||||
| 	FE_CAB_CARRIEROK, | ||||
| 	FE_CAB_NOBLIND, | ||||
| 	FE_CAB_BLINDOK, | ||||
| 	FE_CAB_NODEMOD, | ||||
| 	FE_CAB_DEMODOK, | ||||
| 	FE_CAB_DATAOK | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										3614
									
								
								frontends/stv0367_regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3614
									
								
								frontends/stv0367_regs.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2161
									
								
								frontends/stv0367dd.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2161
									
								
								frontends/stv0367dd.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										18
									
								
								frontends/stv0367dd.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								frontends/stv0367dd.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| #ifndef _STV0367DD_H_ | ||||
| #define _STV0367DD_H_ | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/i2c.h> | ||||
|  | ||||
| struct stv0367_cfg { | ||||
| 	u8  adr; | ||||
| 	u32 xtal; | ||||
| 	u8 parallel; | ||||
| 	u8 cont_clock; | ||||
| }; | ||||
|  | ||||
|  | ||||
| extern struct dvb_frontend *stv0367_attach(struct i2c_adapter *i2c, | ||||
| 					   struct stv0367_cfg *cfg, | ||||
| 					   struct dvb_frontend **fe_t); | ||||
| #endif | ||||
							
								
								
									
										3431
									
								
								frontends/stv0367dd_regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3431
									
								
								frontends/stv0367dd_regs.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										4936
									
								
								frontends/stv090x.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4936
									
								
								frontends/stv090x.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										134
									
								
								frontends/stv090x.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								frontends/stv090x.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,134 @@ | ||||
| /* | ||||
| 	STV0900/0903 Multistandard Broadcast Frontend driver | ||||
| 	Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||||
|  | ||||
| 	Copyright (C) ST Microelectronics | ||||
|  | ||||
| 	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. | ||||
| */ | ||||
|  | ||||
| #ifndef __STV090x_H | ||||
| #define __STV090x_H | ||||
|  | ||||
| enum stv090x_demodulator { | ||||
| 	STV090x_DEMODULATOR_0 = 1, | ||||
| 	STV090x_DEMODULATOR_1 | ||||
| }; | ||||
|  | ||||
| enum stv090x_device { | ||||
| 	STV0903	=  0, | ||||
| 	STV0900, | ||||
| }; | ||||
|  | ||||
| enum stv090x_mode { | ||||
| 	STV090x_DUAL = 0, | ||||
| 	STV090x_SINGLE | ||||
| }; | ||||
|  | ||||
| enum stv090x_tsmode { | ||||
| 	STV090x_TSMODE_SERIAL_PUNCTURED	= 1, | ||||
| 	STV090x_TSMODE_SERIAL_CONTINUOUS, | ||||
| 	STV090x_TSMODE_PARALLEL_PUNCTURED, | ||||
| 	STV090x_TSMODE_DVBCI | ||||
| }; | ||||
|  | ||||
| enum stv090x_clkmode { | ||||
| 	STV090x_CLK_INT = 0, /* Clk i/p = CLKI */ | ||||
| 	STV090x_CLK_EXT = 2 /* Clk i/p = XTALI */ | ||||
| }; | ||||
|  | ||||
| enum stv090x_i2crpt { | ||||
| 	STV090x_RPTLEVEL_256	= 0, | ||||
| 	STV090x_RPTLEVEL_128	= 1, | ||||
| 	STV090x_RPTLEVEL_64	= 2, | ||||
| 	STV090x_RPTLEVEL_32	= 3, | ||||
| 	STV090x_RPTLEVEL_16	= 4, | ||||
| 	STV090x_RPTLEVEL_8	= 5, | ||||
| 	STV090x_RPTLEVEL_4	= 6, | ||||
| 	STV090x_RPTLEVEL_2	= 7, | ||||
| }; | ||||
|  | ||||
| enum stv090x_adc_range { | ||||
| 	STV090x_ADC_2Vpp	= 0, | ||||
| 	STV090x_ADC_1Vpp	= 1 | ||||
| }; | ||||
|  | ||||
| struct stv090x_config { | ||||
| 	enum stv090x_device	device; | ||||
| 	enum stv090x_mode	demod_mode; | ||||
| 	enum stv090x_clkmode	clk_mode; | ||||
|  | ||||
| 	u32 xtal; /* default: 8000000 */ | ||||
| 	u8 address; /* default: 0x68 */ | ||||
|  | ||||
| 	u8 ts1_mode; | ||||
| 	u8 ts2_mode; | ||||
| 	u32 ts1_clk; | ||||
| 	u32 ts2_clk; | ||||
|  | ||||
| 	u8 ts1_tei : 1; | ||||
| 	u8 ts2_tei : 1; | ||||
|  | ||||
| 	enum stv090x_i2crpt	repeater_level; | ||||
|  | ||||
| 	u8			tuner_bbgain; /* default: 10db */ | ||||
| 	enum stv090x_adc_range	adc1_range; /* default: 2Vpp */ | ||||
| 	enum stv090x_adc_range	adc2_range; /* default: 2Vpp */ | ||||
|  | ||||
| 	bool diseqc_envelope_mode; | ||||
|  | ||||
| 	int (*tuner_init) (struct dvb_frontend *fe); | ||||
| 	int (*tuner_sleep) (struct dvb_frontend *fe); | ||||
| 	int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); | ||||
| 	int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); | ||||
| 	int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency); | ||||
| 	int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth); | ||||
| 	int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth); | ||||
| 	int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain); | ||||
| 	int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain); | ||||
| 	int (*tuner_set_refclk)  (struct dvb_frontend *fe, u32 refclk); | ||||
| 	int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status); | ||||
| 	void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock); | ||||
| }; | ||||
|  | ||||
| #if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE)) | ||||
|  | ||||
| extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | ||||
| 					   struct i2c_adapter *i2c, | ||||
| 					   enum stv090x_demodulator demod); | ||||
|  | ||||
| /* dir = 0 -> output, dir = 1 -> input/open-drain */ | ||||
| extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, | ||||
| 		u8 dir, u8 value, u8 xor_value); | ||||
|  | ||||
| #else | ||||
|  | ||||
| static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | ||||
| 						  struct i2c_adapter *i2c, | ||||
| 						  enum stv090x_demodulator demod) | ||||
| { | ||||
| 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, | ||||
| 		u8 opd, u8 value, u8 xor_value) | ||||
| { | ||||
| 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return -ENODEV; | ||||
| } | ||||
| #endif /* CONFIG_DVB_STV090x */ | ||||
|  | ||||
| #endif /* __STV090x_H */ | ||||
							
								
								
									
										279
									
								
								frontends/stv090x_priv.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								frontends/stv090x_priv.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,279 @@ | ||||
| /* | ||||
| 	STV0900/0903 Multistandard Broadcast Frontend driver | ||||
| 	Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||||
|  | ||||
| 	Copyright (C) ST Microelectronics | ||||
|  | ||||
| 	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. | ||||
| */ | ||||
|  | ||||
| #ifndef __STV090x_PRIV_H | ||||
| #define __STV090x_PRIV_H | ||||
|  | ||||
| #include "dvb_frontend.h" | ||||
|  | ||||
| #define FE_ERROR				0 | ||||
| #define FE_NOTICE				1 | ||||
| #define FE_INFO					2 | ||||
| #define FE_DEBUG				3 | ||||
| #define FE_DEBUGREG				4 | ||||
|  | ||||
| #define dprintk(__y, __z, format, arg...) do {						\ | ||||
| 	if (__z) {									\ | ||||
| 		if	((verbose > FE_ERROR) && (verbose > __y))			\ | ||||
| 			printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);		\ | ||||
| 		else if	((verbose > FE_NOTICE) && (verbose > __y))			\ | ||||
| 			printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);	\ | ||||
| 		else if ((verbose > FE_INFO) && (verbose > __y))			\ | ||||
| 			printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);		\ | ||||
| 		else if ((verbose > FE_DEBUG) && (verbose > __y))			\ | ||||
| 			printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);	\ | ||||
| 	} else {									\ | ||||
| 		if (verbose > __y)							\ | ||||
| 			printk(format, ##arg);						\ | ||||
| 	}										\ | ||||
| } while (0) | ||||
|  | ||||
| #define STV090x_READ_DEMOD(__state, __reg) ((			\ | ||||
| 	(__state)->demod == STV090x_DEMODULATOR_1)	?	\ | ||||
| 	stv090x_read_reg(__state, STV090x_P2_##__reg) :		\ | ||||
| 	stv090x_read_reg(__state, STV090x_P1_##__reg)) | ||||
|  | ||||
| #define STV090x_WRITE_DEMOD(__state, __reg, __data) ((		\ | ||||
| 	(__state)->demod == STV090x_DEMODULATOR_1)	?	\ | ||||
| 	stv090x_write_reg(__state, STV090x_P2_##__reg, __data) :\ | ||||
| 	stv090x_write_reg(__state, STV090x_P1_##__reg, __data)) | ||||
|  | ||||
| #define STV090x_ADDR_OFFST(__state, __x) ((			\ | ||||
| 	(__state->demod) == STV090x_DEMODULATOR_1)	?	\ | ||||
| 		STV090x_P1_##__x :				\ | ||||
| 		STV090x_P2_##__x) | ||||
|  | ||||
|  | ||||
| #define STV090x_SETFIELD(mask, bitf, val)	(mask = (mask & (~(((1 << STV090x_WIDTH_##bitf) - 1) <<\ | ||||
| 							 STV090x_OFFST_##bitf))) | \ | ||||
| 							 (val << STV090x_OFFST_##bitf)) | ||||
|  | ||||
| #define STV090x_GETFIELD(val, bitf)		((val >> STV090x_OFFST_##bitf) & ((1 << STV090x_WIDTH_##bitf) - 1)) | ||||
|  | ||||
|  | ||||
| #define STV090x_SETFIELD_Px(mask, bitf, val)	(mask = (mask & (~(((1 << STV090x_WIDTH_Px_##bitf) - 1) <<\ | ||||
| 							 STV090x_OFFST_Px_##bitf))) | \ | ||||
| 							 (val << STV090x_OFFST_Px_##bitf)) | ||||
|  | ||||
| #define STV090x_GETFIELD_Px(val, bitf)		((val >> STV090x_OFFST_Px_##bitf) & ((1 << STV090x_WIDTH_Px_##bitf) - 1)) | ||||
|  | ||||
| #define MAKEWORD16(__a, __b)			(((__a) << 8) | (__b)) | ||||
|  | ||||
| #define MSB(__x)				((__x >> 8) & 0xff) | ||||
| #define LSB(__x)				(__x & 0xff) | ||||
|  | ||||
|  | ||||
| #define STV090x_IQPOWER_THRESHOLD	  30 | ||||
| #define STV090x_SEARCH_AGC2_TH_CUT20	 700 | ||||
| #define STV090x_SEARCH_AGC2_TH_CUT30	1400 | ||||
|  | ||||
| #define STV090x_SEARCH_AGC2_TH(__ver)	\ | ||||
| 	((__ver <= 0x20) ?		\ | ||||
| 	STV090x_SEARCH_AGC2_TH_CUT20 :	\ | ||||
| 	STV090x_SEARCH_AGC2_TH_CUT30) | ||||
|  | ||||
| enum stv090x_signal_state { | ||||
| 	STV090x_NOAGC1, | ||||
| 	STV090x_NOCARRIER, | ||||
| 	STV090x_NODATA, | ||||
| 	STV090x_DATAOK, | ||||
| 	STV090x_RANGEOK, | ||||
| 	STV090x_OUTOFRANGE | ||||
| }; | ||||
|  | ||||
| enum stv090x_fec { | ||||
| 	STV090x_PR12 = 0, | ||||
| 	STV090x_PR23, | ||||
| 	STV090x_PR34, | ||||
| 	STV090x_PR45, | ||||
| 	STV090x_PR56, | ||||
| 	STV090x_PR67, | ||||
| 	STV090x_PR78, | ||||
| 	STV090x_PR89, | ||||
| 	STV090x_PR910, | ||||
| 	STV090x_PRERR | ||||
| }; | ||||
|  | ||||
| enum stv090x_modulation { | ||||
| 	STV090x_QPSK, | ||||
| 	STV090x_8PSK, | ||||
| 	STV090x_16APSK, | ||||
| 	STV090x_32APSK, | ||||
| 	STV090x_UNKNOWN | ||||
| }; | ||||
|  | ||||
| enum stv090x_frame { | ||||
| 	STV090x_LONG_FRAME, | ||||
| 	STV090x_SHORT_FRAME | ||||
| }; | ||||
|  | ||||
| enum stv090x_pilot { | ||||
| 	STV090x_PILOTS_OFF, | ||||
| 	STV090x_PILOTS_ON | ||||
| }; | ||||
|  | ||||
| enum stv090x_rolloff { | ||||
| 	STV090x_RO_35, | ||||
| 	STV090x_RO_25, | ||||
| 	STV090x_RO_20 | ||||
| }; | ||||
|  | ||||
| enum stv090x_inversion { | ||||
| 	STV090x_IQ_AUTO, | ||||
| 	STV090x_IQ_NORMAL, | ||||
| 	STV090x_IQ_SWAP | ||||
| }; | ||||
|  | ||||
| enum stv090x_modcod { | ||||
| 	STV090x_DUMMY_PLF = 0, | ||||
| 	STV090x_QPSK_14, | ||||
| 	STV090x_QPSK_13, | ||||
| 	STV090x_QPSK_25, | ||||
| 	STV090x_QPSK_12, | ||||
| 	STV090x_QPSK_35, | ||||
| 	STV090x_QPSK_23, | ||||
| 	STV090x_QPSK_34, | ||||
| 	STV090x_QPSK_45, | ||||
| 	STV090x_QPSK_56, | ||||
| 	STV090x_QPSK_89, | ||||
| 	STV090x_QPSK_910, | ||||
| 	STV090x_8PSK_35, | ||||
| 	STV090x_8PSK_23, | ||||
| 	STV090x_8PSK_34, | ||||
| 	STV090x_8PSK_56, | ||||
| 	STV090x_8PSK_89, | ||||
| 	STV090x_8PSK_910, | ||||
| 	STV090x_16APSK_23, | ||||
| 	STV090x_16APSK_34, | ||||
| 	STV090x_16APSK_45, | ||||
| 	STV090x_16APSK_56, | ||||
| 	STV090x_16APSK_89, | ||||
| 	STV090x_16APSK_910, | ||||
| 	STV090x_32APSK_34, | ||||
| 	STV090x_32APSK_45, | ||||
| 	STV090x_32APSK_56, | ||||
| 	STV090x_32APSK_89, | ||||
| 	STV090x_32APSK_910, | ||||
| 	STV090x_MODCODE_UNKNOWN | ||||
| }; | ||||
|  | ||||
| enum stv090x_search { | ||||
| 	STV090x_SEARCH_DSS = 0, | ||||
| 	STV090x_SEARCH_DVBS1, | ||||
| 	STV090x_SEARCH_DVBS2, | ||||
| 	STV090x_SEARCH_AUTO | ||||
| }; | ||||
|  | ||||
| enum stv090x_algo { | ||||
| 	STV090x_BLIND_SEARCH, | ||||
| 	STV090x_COLD_SEARCH, | ||||
| 	STV090x_WARM_SEARCH | ||||
| }; | ||||
|  | ||||
| enum stv090x_delsys { | ||||
| 	STV090x_ERROR = 0, | ||||
| 	STV090x_DVBS1 = 1, | ||||
| 	STV090x_DVBS2, | ||||
| 	STV090x_DSS | ||||
| }; | ||||
|  | ||||
| struct stv090x_long_frame_crloop { | ||||
| 	enum stv090x_modcod	modcod; | ||||
|  | ||||
| 	u8 crl_pilots_on_2; | ||||
| 	u8 crl_pilots_off_2; | ||||
| 	u8 crl_pilots_on_5; | ||||
| 	u8 crl_pilots_off_5; | ||||
| 	u8 crl_pilots_on_10; | ||||
| 	u8 crl_pilots_off_10; | ||||
| 	u8 crl_pilots_on_20; | ||||
| 	u8 crl_pilots_off_20; | ||||
| 	u8 crl_pilots_on_30; | ||||
| 	u8 crl_pilots_off_30; | ||||
| }; | ||||
|  | ||||
| struct stv090x_short_frame_crloop { | ||||
| 	enum stv090x_modulation	modulation; | ||||
|  | ||||
| 	u8 crl_2;  /*      SR <   3M */ | ||||
| 	u8 crl_5;  /*  3 < SR <=  7M */ | ||||
| 	u8 crl_10; /*  7 < SR <= 15M */ | ||||
| 	u8 crl_20; /* 10 < SR <= 25M */ | ||||
| 	u8 crl_30; /* 10 < SR <= 45M */ | ||||
| }; | ||||
|  | ||||
| struct stv090x_reg { | ||||
| 	u16 addr; | ||||
| 	u8  data; | ||||
| }; | ||||
|  | ||||
| struct stv090x_tab { | ||||
| 	s32 real; | ||||
| 	s32 read; | ||||
| }; | ||||
|  | ||||
| struct stv090x_internal { | ||||
| 	struct i2c_adapter 	*i2c_adap; | ||||
| 	u8			i2c_addr; | ||||
|  | ||||
| 	struct mutex		demod_lock; /* Lock access to shared register */ | ||||
| 	struct mutex		tuner_lock; /* Lock access to tuners */ | ||||
| 	s32			mclk; /* Masterclock Divider factor */ | ||||
| 	u32			dev_ver; | ||||
|  | ||||
| 	int			num_used; | ||||
| }; | ||||
|  | ||||
| struct stv090x_state { | ||||
| 	enum stv090x_device		device; | ||||
| 	enum stv090x_demodulator	demod; | ||||
| 	enum stv090x_mode		demod_mode; | ||||
| 	struct stv090x_internal		*internal; | ||||
|  | ||||
| 	struct i2c_adapter		*i2c; | ||||
| 	const struct stv090x_config	*config; | ||||
| 	struct dvb_frontend		frontend; | ||||
|  | ||||
| 	u32				*verbose; /* Cached module verbosity */ | ||||
|  | ||||
| 	enum stv090x_delsys		delsys; | ||||
| 	enum stv090x_fec		fec; | ||||
| 	enum stv090x_modulation		modulation; | ||||
| 	enum stv090x_modcod		modcod; | ||||
| 	enum stv090x_search		search_mode; | ||||
| 	enum stv090x_frame		frame_len; | ||||
| 	enum stv090x_pilot		pilots; | ||||
| 	enum stv090x_rolloff		rolloff; | ||||
| 	enum stv090x_inversion		inversion; | ||||
| 	enum stv090x_algo		algo; | ||||
|  | ||||
| 	u32				frequency; | ||||
| 	u32				srate; | ||||
|  | ||||
| 	s32				tuner_bw; | ||||
|  | ||||
| 	s32				search_range; | ||||
|  | ||||
| 	s32				DemodTimeout; | ||||
| 	s32				FecTimeout; | ||||
| }; | ||||
|  | ||||
| #endif /* __STV090x_PRIV_H */ | ||||
							
								
								
									
										2371
									
								
								frontends/stv090x_reg.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2371
									
								
								frontends/stv090x_reg.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1406
									
								
								frontends/stv0910.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1406
									
								
								frontends/stv0910.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										31
									
								
								frontends/stv0910.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								frontends/stv0910.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| #ifndef _STV0910_H_ | ||||
| #define _STV0910_H_ | ||||
|  | ||||
| #include <linux/types.h> | ||||
| #include <linux/i2c.h> | ||||
|  | ||||
| struct stv0910_cfg { | ||||
| 	u32 clk; | ||||
| 	u8  adr; | ||||
| 	u8  parallel; | ||||
| 	u8  rptlvl; | ||||
| }; | ||||
|  | ||||
| #if defined(CONFIG_DVB_STV0910) || \ | ||||
| 	(defined(CONFIG_DVB_STV0910_MODULE) && defined(MODULE)) | ||||
|  | ||||
| extern struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, | ||||
| 					   struct stv0910_cfg *cfg, int nr); | ||||
| #else | ||||
|  | ||||
| static inline struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, | ||||
| 						  struct stv0910_cfg *cfg, | ||||
| 						  int nr) | ||||
| { | ||||
| 	pr_warn("%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										3998
									
								
								frontends/stv0910_regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3998
									
								
								frontends/stv0910_regs.h
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										405
									
								
								frontends/stv6110x.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										405
									
								
								frontends/stv6110x.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,405 @@ | ||||
| /* | ||||
| 	STV6110(A) Silicon tuner driver | ||||
|  | ||||
| 	Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||||
|  | ||||
| 	Copyright (C) ST Microelectronics | ||||
|  | ||||
| 	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/kernel.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/string.h> | ||||
|  | ||||
| #include "dvb_frontend.h" | ||||
|  | ||||
| #include "stv6110x_reg.h" | ||||
| #include "stv6110x.h" | ||||
| #include "stv6110x_priv.h" | ||||
|  | ||||
| static unsigned int verbose; | ||||
| module_param(verbose, int, 0644); | ||||
| MODULE_PARM_DESC(verbose, "Set Verbosity level"); | ||||
|  | ||||
| static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data) | ||||
| { | ||||
| 	int ret; | ||||
| 	const struct stv6110x_config *config = stv6110x->config; | ||||
| 	u8 b0[] = { reg }; | ||||
| 	u8 b1[] = { 0 }; | ||||
| 	struct i2c_msg msg[] = { | ||||
| 		{ .addr = config->addr, .flags = 0, 	   .buf = b0, .len = 1 }, | ||||
| 		{ .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 } | ||||
| 	}; | ||||
|  | ||||
| 	ret = i2c_transfer(stv6110x->i2c, msg, 2); | ||||
| 	if (ret != 2) { | ||||
| 		dprintk(FE_ERROR, 1, "I/O Error"); | ||||
| 		return -EREMOTEIO; | ||||
| 	} | ||||
| 	*data = b1[0]; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len) | ||||
| { | ||||
| 	int ret; | ||||
| 	const struct stv6110x_config *config = stv6110x->config; | ||||
| 	u8 buf[len + 1]; | ||||
| 	struct i2c_msg msg = { | ||||
| 		.addr = config->addr, | ||||
| 		.flags = 0, | ||||
| 		.buf = buf, | ||||
| 		.len = len + 1 | ||||
| 	}; | ||||
|  | ||||
| 	if (start + len > 8) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| 	buf[0] = start; | ||||
| 	memcpy(&buf[1], data, len); | ||||
|  | ||||
| 	ret = i2c_transfer(stv6110x->i2c, &msg, 1); | ||||
| 	if (ret != 1) { | ||||
| 		dprintk(FE_ERROR, 1, "I/O Error"); | ||||
| 		return -EREMOTEIO; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data) | ||||
| { | ||||
| 	return stv6110x_write_regs(stv6110x, reg, &data, 1); | ||||
| } | ||||
|  | ||||
| static int stv6110x_init(struct dvb_frontend *fe) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
| 	int ret; | ||||
|  | ||||
| 	ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs, | ||||
| 				  ARRAY_SIZE(stv6110x->regs)); | ||||
| 	if (ret < 0) { | ||||
| 		dprintk(FE_ERROR, 1, "Initialization failed"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
| 	u32 rDiv, divider; | ||||
| 	s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000; | ||||
| 	u8 i; | ||||
|  | ||||
| 	STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16)); | ||||
|  | ||||
| 	if (frequency <= 1023000) { | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); | ||||
| 		pVal = 40; | ||||
| 	} else if (frequency <= 1300000) { | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1); | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); | ||||
| 		pVal = 40; | ||||
| 	} else if (frequency <= 2046000) { | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0); | ||||
| 		pVal = 20; | ||||
| 	} else { | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0); | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1); | ||||
| 		pVal = 20; | ||||
| 	} | ||||
|  | ||||
| 	for (rDiv = 0; rDiv <= 3; rDiv++) { | ||||
| 		pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv); | ||||
|  | ||||
| 		if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal)))) | ||||
| 			rDivOpt = rDiv; | ||||
|  | ||||
| 		pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt); | ||||
| 	} | ||||
|  | ||||
| 	divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz; | ||||
| 	divider = (divider + 5) / 10; | ||||
|  | ||||
| 	STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt); | ||||
| 	STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider)); | ||||
| 	STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider)); | ||||
|  | ||||
| 	/* VCO Auto calibration */ | ||||
| 	STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1); | ||||
|  | ||||
| 	stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]); | ||||
| 	stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]); | ||||
| 	stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]); | ||||
| 	stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]); | ||||
|  | ||||
| 	for (i = 0; i < TRIALS; i++) { | ||||
| 		stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); | ||||
| 		if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1])) | ||||
| 				break; | ||||
| 		msleep(1); | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
|  | ||||
| 	stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]); | ||||
| 	stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]); | ||||
|  | ||||
| 	*frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]), | ||||
| 				 STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz; | ||||
|  | ||||
| 	*frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) + | ||||
| 			     STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1]))); | ||||
|  | ||||
| 	*frequency >>= 2; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
| 	u32 halfbw; | ||||
| 	u8 i; | ||||
|  | ||||
| 	halfbw = bandwidth >> 1; | ||||
|  | ||||
| 	if (halfbw > 36000000) | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */ | ||||
| 	else if (halfbw < 5000000) | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */ | ||||
| 	else | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */ | ||||
|  | ||||
|  | ||||
| 	STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */ | ||||
| 	STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */ | ||||
|  | ||||
| 	stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]); | ||||
| 	stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]); | ||||
|  | ||||
| 	for (i = 0; i < TRIALS; i++) { | ||||
| 		stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); | ||||
| 		if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1])) | ||||
| 			break; | ||||
| 		msleep(1); | ||||
| 	} | ||||
| 	STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */ | ||||
| 	stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
|  | ||||
| 	stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]); | ||||
| 	*bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
|  | ||||
| 	/* setup divider */ | ||||
| 	switch (refclock) { | ||||
| 	default: | ||||
| 	case 1: | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); | ||||
| 		break; | ||||
| 	case 8: | ||||
| 	case 0: | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); | ||||
| 		break; | ||||
| 	} | ||||
| 	stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
|  | ||||
| 	stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]); | ||||
| 	*gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
|  | ||||
| 	STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2); | ||||
| 	stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
| 	int ret; | ||||
|  | ||||
| 	switch (mode) { | ||||
| 	case TUNER_SLEEP: | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0); | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0); | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0); | ||||
| 		break; | ||||
|  | ||||
| 	case TUNER_WAKE: | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1); | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1); | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]); | ||||
| 	if (ret < 0) { | ||||
| 		dprintk(FE_ERROR, 1, "I/O Error"); | ||||
| 		return -EIO; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_sleep(struct dvb_frontend *fe) | ||||
| { | ||||
| 	if (fe->tuner_priv) | ||||
| 		return stv6110x_set_mode(fe, TUNER_SLEEP); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
|  | ||||
| 	stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]); | ||||
|  | ||||
| 	if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1])) | ||||
| 		*status = TUNER_PHASELOCKED; | ||||
| 	else | ||||
| 		*status = 0; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int stv6110x_release(struct dvb_frontend *fe) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x = fe->tuner_priv; | ||||
|  | ||||
| 	fe->tuner_priv = NULL; | ||||
| 	kfree(stv6110x); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static struct dvb_tuner_ops stv6110x_ops = { | ||||
| 	.info = { | ||||
| 		.name		= "STV6110(A) Silicon Tuner", | ||||
| 		.frequency_min	=  950000, | ||||
| 		.frequency_max	= 2150000, | ||||
| 		.frequency_step	= 0, | ||||
| 	}, | ||||
| 	.release		= stv6110x_release | ||||
| }; | ||||
|  | ||||
| static struct stv6110x_devctl stv6110x_ctl = { | ||||
| 	.tuner_init		= stv6110x_init, | ||||
| 	.tuner_sleep		= stv6110x_sleep, | ||||
| 	.tuner_set_mode		= stv6110x_set_mode, | ||||
| 	.tuner_set_frequency	= stv6110x_set_frequency, | ||||
| 	.tuner_get_frequency	= stv6110x_get_frequency, | ||||
| 	.tuner_set_bandwidth	= stv6110x_set_bandwidth, | ||||
| 	.tuner_get_bandwidth	= stv6110x_get_bandwidth, | ||||
| 	.tuner_set_bbgain	= stv6110x_set_bbgain, | ||||
| 	.tuner_get_bbgain	= stv6110x_get_bbgain, | ||||
| 	.tuner_set_refclk	= stv6110x_set_refclock, | ||||
| 	.tuner_get_status	= stv6110x_get_status, | ||||
| }; | ||||
|  | ||||
| struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | ||||
| 					const struct stv6110x_config *config, | ||||
| 					struct i2c_adapter *i2c) | ||||
| { | ||||
| 	struct stv6110x_state *stv6110x; | ||||
| 	u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; | ||||
|  | ||||
| 	stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); | ||||
| 	if (!stv6110x) | ||||
| 		return NULL; | ||||
|  | ||||
| 	stv6110x->i2c		= i2c; | ||||
| 	stv6110x->config	= config; | ||||
| 	stv6110x->devctl	= &stv6110x_ctl; | ||||
| 	memcpy(stv6110x->regs, default_regs, 8); | ||||
|  | ||||
| 	/* setup divider */ | ||||
| 	switch (stv6110x->config->clk_div) { | ||||
| 	default: | ||||
| 	case 1: | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); | ||||
| 		break; | ||||
| 	case 8: | ||||
| 	case 0: | ||||
| 		STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	fe->tuner_priv		= stv6110x; | ||||
| 	fe->ops.tuner_ops	= stv6110x_ops; | ||||
|  | ||||
| 	printk(KERN_INFO "%s: Attaching STV6110x\n", __func__); | ||||
| 	return stv6110x->devctl; | ||||
| } | ||||
| EXPORT_SYMBOL(stv6110x_attach); | ||||
|  | ||||
| MODULE_AUTHOR("Manu Abraham"); | ||||
| MODULE_DESCRIPTION("STV6110x Silicon tuner"); | ||||
| MODULE_LICENSE("GPL"); | ||||
							
								
								
									
										73
									
								
								frontends/stv6110x.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								frontends/stv6110x.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| /* | ||||
| 	STV6110(A) Silicon tuner driver | ||||
|  | ||||
| 	Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||||
|  | ||||
| 	Copyright (C) ST Microelectronics | ||||
|  | ||||
| 	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. | ||||
| */ | ||||
|  | ||||
| #ifndef __STV6110x_H | ||||
| #define __STV6110x_H | ||||
|  | ||||
| struct stv6110x_config { | ||||
| 	u8	addr; | ||||
| 	u32	refclk; | ||||
| 	u8	clk_div; /* divisor value for the output clock */ | ||||
| }; | ||||
|  | ||||
| enum tuner_mode { | ||||
| 	TUNER_SLEEP = 1, | ||||
| 	TUNER_WAKE, | ||||
| }; | ||||
|  | ||||
| enum tuner_status { | ||||
| 	TUNER_PHASELOCKED = 1, | ||||
| }; | ||||
|  | ||||
| struct stv6110x_devctl { | ||||
| 	int (*tuner_init) (struct dvb_frontend *fe); | ||||
| 	int (*tuner_sleep) (struct dvb_frontend *fe); | ||||
| 	int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode); | ||||
| 	int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency); | ||||
| 	int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency); | ||||
| 	int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth); | ||||
| 	int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth); | ||||
| 	int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain); | ||||
| 	int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain); | ||||
| 	int (*tuner_set_refclk)  (struct dvb_frontend *fe, u32 refclk); | ||||
| 	int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status); | ||||
| }; | ||||
|  | ||||
|  | ||||
| #if defined(CONFIG_DVB_STV6110x) || (defined(CONFIG_DVB_STV6110x_MODULE) && defined(MODULE)) | ||||
|  | ||||
| extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | ||||
| 					       const struct stv6110x_config *config, | ||||
| 					       struct i2c_adapter *i2c); | ||||
|  | ||||
| #else | ||||
| static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, | ||||
| 						      const struct stv6110x_config *config, | ||||
| 						      struct i2c_adapter *i2c) | ||||
| { | ||||
| 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| #endif /* CONFIG_DVB_STV6110x */ | ||||
|  | ||||
| #endif /* __STV6110x_H */ | ||||
							
								
								
									
										76
									
								
								frontends/stv6110x_priv.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								frontends/stv6110x_priv.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| /* | ||||
| 	STV6110(A) Silicon tuner driver | ||||
|  | ||||
| 	Copyright (C) Manu Abraham <abraham.manu@gmail.com> | ||||
|  | ||||
| 	Copyright (C) ST Microelectronics | ||||
|  | ||||
| 	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. | ||||
| */ | ||||
|  | ||||
| #ifndef __STV6110x_PRIV_H | ||||
| #define __STV6110x_PRIV_H | ||||
|  | ||||
| #define FE_ERROR				0 | ||||
| #define FE_NOTICE				1 | ||||
| #define FE_INFO					2 | ||||
| #define FE_DEBUG				3 | ||||
| #define FE_DEBUGREG				4 | ||||
|  | ||||
| #define dprintk(__y, __z, format, arg...) do {						\ | ||||
| 	if (__z) {									\ | ||||
| 		if	((verbose > FE_ERROR) && (verbose > __y))			\ | ||||
| 			printk(KERN_ERR "%s: " format "\n", __func__ , ##arg);		\ | ||||
| 		else if	((verbose > FE_NOTICE) && (verbose > __y))			\ | ||||
| 			printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg);	\ | ||||
| 		else if ((verbose > FE_INFO) && (verbose > __y))			\ | ||||
| 			printk(KERN_INFO "%s: " format "\n", __func__ , ##arg);		\ | ||||
| 		else if ((verbose > FE_DEBUG) && (verbose > __y))			\ | ||||
| 			printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg);	\ | ||||
| 	} else {									\ | ||||
| 		if (verbose > __y)							\ | ||||
| 			printk(format, ##arg);						\ | ||||
| 	}										\ | ||||
| } while (0) | ||||
|  | ||||
|  | ||||
| #define STV6110x_SETFIELD(mask, bitf, val)				\ | ||||
| 	(mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) <<	\ | ||||
| 				  STV6110x_OFFST_##bitf))) | 		\ | ||||
| 			  (val << STV6110x_OFFST_##bitf)) | ||||
|  | ||||
| #define STV6110x_GETFIELD(bitf, val)					\ | ||||
| 	((val >> STV6110x_OFFST_##bitf) & 				\ | ||||
| 	((1 << STV6110x_WIDTH_##bitf) - 1)) | ||||
|  | ||||
| #define MAKEWORD16(a, b)			(((a) << 8) | (b)) | ||||
|  | ||||
| #define LSB(x)					((x & 0xff)) | ||||
| #define MSB(y)					((y >> 8) & 0xff) | ||||
|  | ||||
| #define TRIALS					10 | ||||
| #define R_DIV(__div)				(1 << (__div + 1)) | ||||
| #define REFCLOCK_kHz				(stv6110x->config->refclk /    1000) | ||||
| #define REFCLOCK_MHz				(stv6110x->config->refclk / 1000000) | ||||
|  | ||||
| struct stv6110x_state { | ||||
| 	struct i2c_adapter		*i2c; | ||||
| 	const struct stv6110x_config	*config; | ||||
| 	u8 				regs[8]; | ||||
|  | ||||
| 	struct stv6110x_devctl		*devctl; | ||||
| }; | ||||
|  | ||||
| #endif /* __STV6110x_PRIV_H */ | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user