mirror of
				https://github.com/DigitalDevices/dddvb.git
				synced 2025-03-01 10:35:23 +00:00 
			
		
		
		
	Merge branch 'internal'
This commit is contained in:
		| @@ -1,3 +1,6 @@ | ||||
| 0.9.24 2016.08.03 | ||||
| - suport new V2 modulator cards | ||||
|  | ||||
| 0.9.19c 2015.07.20 | ||||
| - MAX S8: | ||||
|   do not turn on diseqc and tuners on init | ||||
|   | ||||
							
								
								
									
										89
									
								
								apps/cit.c
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								apps/cit.c
									
									
									
									
									
								
							| @@ -9,6 +9,9 @@ | ||||
| #include <fcntl.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <pthread.h> | ||||
| #include <getopt.h> | ||||
|  | ||||
| uint32_t adapter = 0, device = 0, snum = 256, rnum = 256; | ||||
|  | ||||
| uint8_t fill[188]={0x47, 0x1f, 0xff, 0x10, | ||||
|    0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, | ||||
| @@ -68,24 +71,34 @@ void proc_buf(uint8_t *buf, uint32_t *d) | ||||
| 	} else { | ||||
| 		if (memcmp(ts+8, buf+8, 180)) | ||||
| 			printf("error\n"); | ||||
| 		if (!(c&0xffff)) | ||||
| 			printf("R %08x\n", c); | ||||
| 		if (!(c&0xffff)) { | ||||
| 			printf("R %08x\r", c); | ||||
| 			fflush(0); | ||||
| 		} | ||||
| 	} | ||||
| 	(*d)++; | ||||
| } | ||||
|  | ||||
| void *get_ts(void *a) | ||||
| { | ||||
| 	uint8_t buf[188*1024]; | ||||
| 	uint8_t *buf; | ||||
| 	int len, off; | ||||
|  | ||||
| 	int fdi=open("/dev/dvb/adapter2/ci0", O_RDONLY); | ||||
| 	int fdi; | ||||
| 	char fname[80]; | ||||
| 	uint32_t d=0; | ||||
|  | ||||
| 	buf = malloc(188*rnum); | ||||
| 	if (!buf) | ||||
| 		return NULL; | ||||
| 	sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device); | ||||
| 	fdi = open(fname, O_RDONLY); | ||||
|  | ||||
| 	while (1) { | ||||
| 		len=read(fdi, buf, 188*1024); | ||||
| 		memset(buf, 0, 188*rnum); | ||||
| 		len=read(fdi, buf, 188*rnum); | ||||
| 		if (len<0) | ||||
| 			continue; | ||||
| 		//printf("read %u\n", len); | ||||
| 		if (buf[0]!=0x47) { | ||||
| 			read(fdi, buf, 1); | ||||
| 			continue; | ||||
| @@ -96,20 +109,23 @@ void *get_ts(void *a) | ||||
| 	}	 | ||||
| } | ||||
|  | ||||
| #define SNUM 233 | ||||
| //671 | ||||
| void send(void) | ||||
|  | ||||
| int send(void) | ||||
| { | ||||
| 	uint8_t buf[188*SNUM], *cts; | ||||
| 	uint8_t *buf, *cts; | ||||
| 	int i; | ||||
| 	uint32_t c=0; | ||||
| 	int fdo; | ||||
|  | ||||
| 	fdo=open("/dev/dvb/adapter2/ci0", O_WRONLY); | ||||
|  | ||||
| 	char fname[80]; | ||||
| 	 | ||||
| 	buf = malloc(188*snum); | ||||
| 	if (!buf) | ||||
| 		return -1; | ||||
| 	sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device); | ||||
| 	fdo=open(fname, O_WRONLY); | ||||
|  | ||||
| 	while (1) { | ||||
| 		for (i=0; i<SNUM; i++) { | ||||
| 		for (i=0; i<snum; i++) { | ||||
| 			cts=buf+i*188; | ||||
| 			memcpy(cts, ts, 188); | ||||
| 			cts[4]=(c>>24); | ||||
| @@ -122,15 +138,54 @@ void send(void) | ||||
| 			//usleep(100000+0xffff&rand()); | ||||
| 			//usleep(1000); | ||||
| 		} | ||||
| 		write(fdo, buf, 188*SNUM); | ||||
| 		write(fdo, buf, 188*snum); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| int main() | ||||
| int main(int argc, char **argv) | ||||
| { | ||||
| 	pthread_t th; | ||||
|  | ||||
| 	 | ||||
| 	while (1) { | ||||
|                 int option_index = 0; | ||||
| 		int c; | ||||
|                 static struct option long_options[] = { | ||||
| 			{"adapter", required_argument, 0, 'a'}, | ||||
| 			{"device", required_argument, 0, 'd'}, | ||||
| 			{"snum", required_argument, 0, 's'}, | ||||
| 			{"rnum", required_argument, 0, 'r'}, | ||||
| 			{"help", no_argument , 0, 'h'}, | ||||
| 			{0, 0, 0, 0} | ||||
| 		}; | ||||
|                 c = getopt_long(argc, argv,  | ||||
| 				"a:d:h", | ||||
| 				long_options, &option_index); | ||||
| 		if (c==-1) | ||||
|  			break; | ||||
| 		 | ||||
| 		switch (c) { | ||||
| 		case 'd': | ||||
| 			device = strtoul(optarg, NULL, 10); | ||||
| 			break; | ||||
| 		case 'a': | ||||
| 			adapter = strtoul(optarg, NULL, 10); | ||||
| 			break; | ||||
| 		case 's': | ||||
| 			snum = strtoul(optarg, NULL, 10); | ||||
| 			break; | ||||
| 		case 'r': | ||||
| 			rnum = strtoul(optarg, NULL, 10); | ||||
| 			break; | ||||
| 		case 'h': | ||||
| 		default: | ||||
| 			break; | ||||
| 			 | ||||
| 		} | ||||
| 	} | ||||
| 	if (optind < argc) { | ||||
| 		printf("Warning: unused arguments\n"); | ||||
| 	} | ||||
| 	memset(ts+8, 180, 0x5a); | ||||
| 	pthread_create(&th, NULL, get_ts, NULL); | ||||
| 	usleep(10000); | ||||
|   | ||||
| @@ -145,7 +145,6 @@ int ReadFlash(int ddb, int argc, char *argv[], uint32_t Flags) | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int FlashDetect(int dev) | ||||
| { | ||||
| 	uint8_t Cmd = 0x9F; | ||||
| @@ -765,7 +764,6 @@ uint32_t   GetFPGA_ID(uint8_t * Buffer) | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| int FlashProg(int dev,int argc, char* argv[],uint32_t Flags) | ||||
| { | ||||
| 	uint8_t * Buffer = NULL; | ||||
| @@ -1652,6 +1650,60 @@ int lic_erase(int dev, int argc, char* argv[], uint32_t Flags) | ||||
| 	return err; | ||||
| } | ||||
|  | ||||
| static int read_sfpd(int dev, uint8_t adr, uint8_t *val) | ||||
| { | ||||
| 	uint8_t cmd[5] = { 0x5a, 0, 0, adr, 00 };      | ||||
| 	int r; | ||||
| 	 | ||||
| 	r = FlashIO(dev, cmd, 5, val, 1); | ||||
| 	if (r < 0) | ||||
| 		return r; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int read_sst_id(int dev, uint8_t *id) | ||||
| { | ||||
| 	uint8_t cmd[2] = { 0x88, 0 }; | ||||
| 	uint8_t buf[9]; | ||||
| 	int r; | ||||
| 	 | ||||
| 	r = FlashIO(dev, cmd, 2, buf, 9); | ||||
| 	if (r < 0) | ||||
| 		return r; | ||||
| 	memcpy(id, buf + 1, 8); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int read_id(int dev, int argc, char* argv[], uint32_t Flags) | ||||
| { | ||||
| 	int Flash = FlashDetect(dev); | ||||
| 	uint8_t Cmd;; | ||||
| 	uint8_t Id[8]; | ||||
| 	uint32_t len, i, adr; | ||||
| 	 | ||||
|  | ||||
| 	switch(Flash) { | ||||
|         case SPANSION_S25FL116K: | ||||
|         case SPANSION_S25FL132K: | ||||
|         case SPANSION_S25FL164K: | ||||
| 		for (i = 0; i < 8; i++) | ||||
| 			read_sfpd(dev, 0xf8 + i, &Id[i]); | ||||
| 		len = 8; | ||||
| 		break; | ||||
| 	case SSTI_SST25VF064C: | ||||
| 		read_sst_id(dev, Id); | ||||
| 		len = 8; | ||||
| 		break; | ||||
|         default: | ||||
| 		printf("Unsupported Flash\n"); | ||||
| 		break; | ||||
| 	} | ||||
| 	printf("ID: "); | ||||
| 	for (i = 0; i < 8; i++) | ||||
| 		printf("%02x ", Id[i]); | ||||
| 	printf("\n"); | ||||
|  | ||||
| } | ||||
|  | ||||
| struct SCommand CommandTable[] =  | ||||
| { | ||||
| @@ -1661,7 +1713,7 @@ struct SCommand CommandTable[] = | ||||
| 	{ "register",   GetSetRegister,     1,   "Get/Set Register     : reg <regname>|<[0x]regnum> [[0x]value(32)]" }, | ||||
| 	 | ||||
| 	{ "flashread",    ReadFlash,        1,   "Read Flash           : flashread <start> <count>" }, | ||||
| 	{ "flashio",      FlashIO,          1,   "Flash IO             : flashio <write data>.. <read count>" }, | ||||
| 	{ "flashio",      FlashIOC,          1,   "Flash IO             : flashio <write data>.. <read count>" }, | ||||
| 	{ "flashprog",    FlashProg,        1,   "Flash Programming    : flashprog <FileName> [<address>]" }, | ||||
| 	{ "flashprog",    FlashProg,        1,   "Flash Programming    : flashprog -SubVendorID <id>" }, | ||||
| 	{ "flashprog",    FlashProg,        1,   "Flash Programming    : flashprog -Jump <address>" }, | ||||
| @@ -1676,6 +1728,7 @@ struct SCommand CommandTable[] = | ||||
| 	{ "licimport",   lic_import,       1,   "License Import           : licimport" }, | ||||
| 	{ "licexport",   lic_export,       1,   "License Export           : licexport" }, | ||||
| 	{ "licerase",    lic_erase,        1,   "License Erase            : licerase"  }, | ||||
| 	{ "read_id",    read_id,        1,      "Read Unique ID           : read_id"  }, | ||||
|  	{ NULL,NULL,0 } | ||||
| }; | ||||
|  | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -247,7 +247,9 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c, | ||||
| 	adap->class = I2C_CLASS_TV_ANALOG; | ||||
| #endif | ||||
| #endif | ||||
| 	strcpy(adap->name, "ddbridge"); | ||||
| 	/*strcpy(adap->name, "ddbridge");*/ | ||||
| 	snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x", | ||||
| 		 dev->nr, i2c->link, i); | ||||
| 	adap->algo = &ddb_i2c_algo; | ||||
| 	adap->algo_data = (void *)i2c; | ||||
| 	adap->dev.parent = dev->dev; | ||||
| @@ -257,7 +259,7 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c, | ||||
| static int ddb_i2c_init(struct ddb *dev) | ||||
| { | ||||
| 	int stat = 0; | ||||
| 	u32 i, j, num = 0, l; | ||||
| 	u32 i, j, num = 0, l, base; | ||||
| 	struct ddb_i2c *i2c; | ||||
| 	struct i2c_adapter *adap; | ||||
| 	struct ddb_regmap *regmap; | ||||
| @@ -268,12 +270,13 @@ static int ddb_i2c_init(struct ddb *dev) | ||||
| 		regmap = dev->link[l].info->regmap; | ||||
| 		if (!regmap || !regmap->i2c) | ||||
| 			continue; | ||||
| 		base = regmap->irq_base_i2c; | ||||
| 		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; | ||||
| 			dev->handler_data[l][i + base] = (unsigned long) i2c; | ||||
| 			dev->handler[l][i + base] = i2c_handler; | ||||
| 			stat = ddb_i2c_add(dev, i2c, regmap, l, i, num); | ||||
| 			if (stat) | ||||
| 				break; | ||||
|   | ||||
| @@ -28,6 +28,10 @@ | ||||
|  | ||||
| #include <linux/dvb/mod.h> | ||||
|  | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| inline s64 ConvertPCR(s64 a) | ||||
| { | ||||
| 	s32 ext; | ||||
| @@ -72,6 +76,81 @@ inline s64 RoundPCRDown(s64 a) | ||||
| 	return a & ~(HW_LSB_MASK - 1); | ||||
| } | ||||
|  | ||||
| // Calculating KF, LF from Symbolrate | ||||
| // | ||||
| //  Symbolrate is usually calculated as (M/N) * 10.24 MS/s | ||||
| //   | ||||
| //   Common Values for M,N  | ||||
| //     J.83 Annex A, | ||||
| //     Euro Docsis  6.952 MS/s : M =   869, N =  1280 | ||||
| //                  6.900 MS/s : M =   345, N =   512 | ||||
| //                  6.875 MS/s : M =  1375, N =  2048 | ||||
| //                  6.111 MS/s : M =  6111, N = 10240 | ||||
| //     J.83 Annex B ** | ||||
| //      QAM64       5.056941   : M =   401, N =   812 | ||||
| //      QAM256      5.360537   : M =    78, N =   149 | ||||
| //     J.83 Annex C ** | ||||
| //                  5.309734   : M =  1889, N =  3643 | ||||
| // | ||||
| //    For the present hardware  | ||||
| //      KF' = 256 * M  | ||||
| //      LF' = 225 * N  | ||||
| //       or | ||||
| //      KF' = Symbolrate in Hz | ||||
| //      LF' = 9000000 | ||||
| // | ||||
| //      KF  = KF' / gcd(KF',LF') | ||||
| //      LF  = LF' / gcd(KF',LF') | ||||
| // Note: LF must not be a power of 2. | ||||
| //       Maximum value for KF,LF = 13421727 ( 0x7FFFFFF ) | ||||
| //    ** using these M,N values will result in a small err (<5ppm) | ||||
| //       calculating KF,LF directly gives the exact normative result | ||||
| //       but with rather large KF,LF values | ||||
|  | ||||
| static inline u32 gcd(u32 u,u32 v) | ||||
| { | ||||
|     int s = 0; | ||||
|     while (((u|v)&1) == 0) { | ||||
| 	    s += 1; | ||||
| 	    u >>= 1; | ||||
| 	    v >>= 1; | ||||
|     } | ||||
|     while ((u&1) == 0) | ||||
| 	    u >>= 1; | ||||
|     do { | ||||
| 	    while ( (v&1) == 0 ) v >>= 1; | ||||
| 	    if( u > v ) { | ||||
| 		    u32 t = v; | ||||
| 		    v = u; | ||||
| 		    u = t; | ||||
| 	    } | ||||
| 	    v = v - u; | ||||
|     } while(v != 0); | ||||
|     return u << s; | ||||
| } | ||||
|  | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| static int mod_SendChannelCommand(struct ddb *dev, u32 Channel, u32 Command) | ||||
| { | ||||
| 	u32 ControlReg = ddbreadl(dev, CHANNEL_CONTROL(Channel)); | ||||
| 	 | ||||
| 	ControlReg = (ControlReg & ~CHANNEL_CONTROL_CMD_MASK)|Command; | ||||
| 	ddbwritel(dev, ControlReg, CHANNEL_CONTROL(Channel)); | ||||
| 	while(1) { | ||||
| 		ControlReg = ddbreadl(dev, CHANNEL_CONTROL(Channel)); | ||||
| 		if (ControlReg == 0xFFFFFFFF) | ||||
| 			return -EIO; | ||||
| 		if((ControlReg & CHANNEL_CONTROL_CMD_STATUS) == 0) | ||||
| 			break; | ||||
| 	} | ||||
| 	if (ControlReg & CHANNEL_CONTROL_ERROR_CMD) | ||||
| 		return -EINVAL; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int mod_busy(struct ddb *dev, int chan) | ||||
| { | ||||
| 	u32 creg; | ||||
| @@ -89,10 +168,12 @@ static int mod_busy(struct ddb *dev, int chan) | ||||
| void ddbridge_mod_output_stop(struct ddb_output *output) | ||||
| { | ||||
| 	struct ddb *dev = output->port->dev; | ||||
| 	struct mod_state *mod = &dev->mod[output->nr]; | ||||
| 	struct ddb_mod *mod = &dev->mod[output->nr]; | ||||
|  | ||||
| 	mod->State = CM_IDLE; | ||||
| 	mod->Control = 0; | ||||
| 	if (dev->link[0].info->version == 2) | ||||
| 		mod_SendChannelCommand(dev, output->nr, CHANNEL_CONTROL_CMD_FREE); | ||||
| 	ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); | ||||
| #if 0 | ||||
| 	udelay(10); | ||||
| @@ -108,7 +189,7 @@ static void mod_set_incs(struct ddb_output *output) | ||||
| { | ||||
| 	s64 pcr; | ||||
| 	struct ddb *dev = output->port->dev; | ||||
| 	struct mod_state *mod = &dev->mod[output->nr]; | ||||
| 	struct ddb_mod *mod = &dev->mod[output->nr]; | ||||
|  | ||||
| 	pcr = ConvertPCR(mod->PCRIncrement); | ||||
| 	ddbwritel(dev,	pcr & 0xffffffff, | ||||
| @@ -137,8 +218,10 @@ static u32 qamtab[6] = { 0x000, 0x600, 0x601, 0x602, 0x903, 0x604 }; | ||||
| void ddbridge_mod_output_start(struct ddb_output *output) | ||||
| { | ||||
| 	struct ddb *dev = output->port->dev; | ||||
| 	struct mod_state *mod = &dev->mod[output->nr]; | ||||
|  | ||||
| 	u32 Channel = output->nr; | ||||
| 	struct ddb_mod *mod = &dev->mod[output->nr]; | ||||
| 	u32 Symbolrate = 6900000; | ||||
| 	 | ||||
| 	/*PCRIncrement = RoundPCR(PCRIncrement);*/ | ||||
| 	/*PCRDecrement = RoundPCR(PCRDecrement);*/ | ||||
|  | ||||
| @@ -164,18 +247,55 @@ void ddbridge_mod_output_start(struct ddb_output *output) | ||||
| 	udelay(10); | ||||
| 	ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); | ||||
|  | ||||
| 	/* QAM: 600 601 602 903 604 = 16 32 64 128 256 */ | ||||
| 	/* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */ | ||||
| 	ddbwritel(dev, qamtab[mod->modulation], CHANNEL_SETTINGS(output->nr)); | ||||
| 	pr_info("CHANNEL_BASE = %08x\n", CHANNEL_BASE); | ||||
| 	pr_info("CHANNEL_CONTROL = %08x\n", CHANNEL_CONTROL(Channel)); | ||||
| 	if (dev->link[0].info->version == 2) { | ||||
| 		u32 Output = ((dev->mod_base.frequency - 114000000)/8000000 + Channel) % 96; | ||||
| 		u32 KF = Symbolrate; | ||||
| 		u32 LF = 9000000UL; | ||||
| 		u32 d = gcd(KF,LF); | ||||
| 		u32 checkLF; | ||||
|  | ||||
| 		mod->modulation = QAM_256 - 1; | ||||
| 		ddbwritel(dev, mod->modulation, CHANNEL_SETTINGS(Channel)); | ||||
| 		ddbwritel(dev, Output, CHANNEL_SETTINGS2(Channel)); | ||||
| 		 | ||||
| 		KF = KF / d; | ||||
| 		LF = LF / d; | ||||
| 		 | ||||
| 		while( (KF > KFLF_MAX) || (LF > KFLF_MAX) ) { | ||||
| 			KF >>= 1; | ||||
| 			LF >>= 1; | ||||
| 		} | ||||
| 		 | ||||
| 		checkLF = LF; | ||||
| 		while ((checkLF & 1) == 0) | ||||
| 			checkLF >>= 1; | ||||
| 		if (checkLF <= 1) | ||||
| 			return -EINVAL; | ||||
|  | ||||
| 		pr_info("KF=%u LF=%u Output=%u mod=%u\n", KF, LF, Output, mod->modulation); | ||||
| 		ddbwritel(dev, KF, CHANNEL_KF(Channel)); | ||||
| 		ddbwritel(dev, LF, CHANNEL_LF(Channel)); | ||||
| 		 | ||||
| 		if (mod_SendChannelCommand(dev, Channel, CHANNEL_CONTROL_CMD_SETUP)) | ||||
| 			return -EINVAL; | ||||
| 		mod->Control = CHANNEL_CONTROL_ENABLE_DVB; | ||||
| 	} else { | ||||
| 		/* QAM: 600 601 602 903 604 = 16 32 64 128 256 */ | ||||
| 		/* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */ | ||||
| 		ddbwritel(dev, qamtab[mod->modulation], CHANNEL_SETTINGS(output->nr)); | ||||
| 		mod->Control = (CHANNEL_CONTROL_ENABLE_IQ | CHANNEL_CONTROL_ENABLE_DVB); | ||||
| 	} | ||||
| 	mod_set_rateinc(dev, output->nr); | ||||
| 	mod_set_incs(output); | ||||
|  | ||||
| 	mod->Control = (CHANNEL_CONTROL_ENABLE_IQ | | ||||
| 			CHANNEL_CONTROL_ENABLE_DVB | | ||||
| 			CHANNEL_CONTROL_ENABLE_SOURCE); | ||||
| 	mod->Control |= CHANNEL_CONTROL_ENABLE_SOURCE; | ||||
|  | ||||
| 	ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr)); | ||||
| 	if (dev->link[0].info->version == 2) | ||||
| 		if (mod_SendChannelCommand(dev, Channel, CHANNEL_CONTROL_CMD_UNMUTE)) | ||||
| 			return -EINVAL; | ||||
| 	pr_info("mod_output_start %d.%d\n", dev->nr, output->nr); | ||||
| } | ||||
|  | ||||
| @@ -183,6 +303,195 @@ void ddbridge_mod_output_start(struct ddb_output *output) | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| static int mod_write_max2871(struct ddb *dev, u32 val) | ||||
| { | ||||
| 	ddbwritel(dev, val, MAX2871_OUTDATA); | ||||
| 	ddbwritel(dev, MAX2871_CONTROL_CE | MAX2871_CONTROL_WRITE, MAX2871_CONTROL); | ||||
| 	while(1) { | ||||
| 		u32 ControlReg = ddbreadl(dev, MAX2871_CONTROL); | ||||
| 		if (ControlReg == 0xFFFFFFFF) | ||||
| 			return -EIO; | ||||
| 		if ((ControlReg & MAX2871_CONTROL_WRITE) == 0) | ||||
| 			break; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int mod_setup_max2871(struct ddb *dev) | ||||
| { | ||||
| 	int status = 0; | ||||
| 	int i; | ||||
| 	 | ||||
| 	ddbwritel(dev, MAX2871_CONTROL_CE, MAX2871_CONTROL); | ||||
| 	for (i = 0; i < 2; i++) { | ||||
| 		status = mod_write_max2871(dev, 0x00440005); | ||||
| 		if (status) | ||||
| 			break; | ||||
| 		status = mod_write_max2871(dev, 0x6199003C); | ||||
| 		if (status) | ||||
| 			break; | ||||
| 		status = mod_write_max2871(dev, 0x000000CB); | ||||
| 		if (status) | ||||
| 			break; | ||||
| 		status = mod_write_max2871(dev, 0x510061C2); | ||||
| 		if (status) | ||||
| 			break; | ||||
| 		status = mod_write_max2871(dev, 0x600080A1); | ||||
| 		if (status) | ||||
| 			break; | ||||
| 		status = mod_write_max2871(dev, 0x00730040); | ||||
| 		if (status) | ||||
| 			break; | ||||
| 		msleep(30); | ||||
| 	} while(0); | ||||
|  | ||||
| 	if (status == 0) { | ||||
| 		u32 ControlReg = ddbreadl(dev, MAX2871_CONTROL); | ||||
| 		 | ||||
| 		if ((ControlReg & MAX2871_CONTROL_LOCK) == 0) | ||||
| 			status = -EIO; | ||||
| 	} | ||||
|  | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan, u32 MaxUsedChannels) | ||||
| { | ||||
| 	int status = 0; | ||||
| 	u32 Capacity; | ||||
| 	u32 tmp = ddbreadl(dev, FSM_STATUS); | ||||
| 	 | ||||
| 	if ((tmp & FSM_STATUS_READY) == 0) { | ||||
| 		status = mod_setup_max2871(dev); | ||||
| 		if (status) | ||||
| 			return status; | ||||
| 		ddbwritel(dev, FSM_CMD_RESET, FSM_CONTROL); | ||||
| 		msleep(10); | ||||
| 		 | ||||
| 		tmp = ddbreadl(dev, FSM_STATUS); | ||||
| 		if ((tmp & FSM_STATUS_READY) == 0) | ||||
| 			return -1; | ||||
| 	} | ||||
| 	Capacity = ddbreadl(dev, FSM_CAPACITY); | ||||
| 	if (((tmp & FSM_STATUS_QAMREADY) != 0) && | ||||
| 	    ((Capacity & FSM_CAPACITY_INUSE) != 0)) | ||||
| 		return -EBUSY; | ||||
| 	 | ||||
| 	ddbwritel(dev, FSM_CMD_SETUP, FSM_CONTROL); | ||||
| 	msleep(10); | ||||
| 	tmp = ddbreadl(dev, FSM_STATUS); | ||||
| 	 | ||||
| 	if ((tmp & FSM_STATUS_QAMREADY) == 0) | ||||
| 		return -1; | ||||
| 	 | ||||
| 	if (MaxUsedChannels == 0) | ||||
| 		MaxUsedChannels = (Capacity & FSM_CAPACITY_CUR) >> 16; | ||||
|  | ||||
| 	pr_info("max used chan = %u\n", MaxUsedChannels); | ||||
| 	if (MaxUsedChannels <= 1 ) | ||||
| 		ddbwritel(dev, FSM_GAIN_N1, FSM_GAIN); | ||||
| 	else if (MaxUsedChannels <= 2) | ||||
| 		ddbwritel(dev, FSM_GAIN_N2, FSM_GAIN); | ||||
| 	else if (MaxUsedChannels <= 4)  | ||||
| 		ddbwritel(dev, FSM_GAIN_N4, FSM_GAIN); | ||||
| 	else if (MaxUsedChannels <= 8) | ||||
| 		ddbwritel(dev, FSM_GAIN_N8, FSM_GAIN); | ||||
| 	else if (MaxUsedChannels <= 16) | ||||
| 		ddbwritel(dev, FSM_GAIN_N16, FSM_GAIN); | ||||
| 	else if (MaxUsedChannels <= 24) | ||||
| 		ddbwritel(dev, FSM_GAIN_N24, FSM_GAIN); | ||||
| 	else | ||||
| 		ddbwritel(dev, FSM_GAIN_N96, FSM_GAIN); | ||||
|  | ||||
| 	ddbwritel(dev, FSM_CONTROL_ENABLE, FSM_CONTROL); | ||||
|  | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| static int mod_set_vga(struct ddb *dev, u32 Gain) | ||||
| { | ||||
| 	if( Gain > 255 ) | ||||
| 		return -EINVAL; | ||||
| 	ddbwritel(dev, Gain, RF_VGA); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int mod_get_vga(struct ddb *dev, u32 *pGain) | ||||
| { | ||||
| 	*pGain = ddbreadl(dev, RF_VGA); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void mod_TemperatureMonitorSetFan(struct ddb *dev) | ||||
| { | ||||
| 	u32 tqam, pwm; | ||||
| 	 | ||||
| 	if ((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0) { | ||||
| 		pr_info("Over temperature condition\n"); | ||||
| 		dev->mod_base.OverTemperatureError = 1; | ||||
| 	} | ||||
| 	tqam  = (ddbreadl(dev, TEMPMON2_QAMCORE) >> 8) & 0xFF; | ||||
| 	if (tqam & 0x80) | ||||
| 		tqam = 0; | ||||
| 	 | ||||
| 	pwm = (ddbreadl(dev, TEMPMON_FANCONTROL) >> 8) & 0x0F; | ||||
| 	if (pwm > 10) | ||||
| 		pwm = 10;    | ||||
| 	 | ||||
| 	if (tqam >= dev->mod_base.temp_tab[pwm]) { | ||||
| 		while( pwm < 10 && tqam >= dev->mod_base.temp_tab[pwm + 1]) | ||||
| 			pwm += 1; | ||||
| 	} else { | ||||
| 		while( pwm > 1 && tqam < dev->mod_base.temp_tab[pwm - 2]) | ||||
| 			pwm -= 1; | ||||
| 	} | ||||
| 	ddbwritel(dev, (pwm << 8), TEMPMON_FANCONTROL); | ||||
| } | ||||
|  | ||||
|  | ||||
| static void mod_temp_handler(unsigned long data) | ||||
| { | ||||
| 	struct ddb *dev = (struct ddb *) data; | ||||
|  | ||||
| 	pr_info("mod_temp_handler\n"); | ||||
|  | ||||
| 	spin_lock(&dev->mod_base.temp_lock); | ||||
| 	mod_TemperatureMonitorSetFan(dev); | ||||
| 	spin_unlock(&dev->mod_base.temp_lock); | ||||
| } | ||||
|  | ||||
| static int mod_TemperatureMonitorInit(struct ddb *dev, int FirstTime) { | ||||
| 	int status = 0; | ||||
| 	 | ||||
| 	spin_lock_irq(&dev->mod_base.temp_lock); | ||||
| 	if (FirstTime) { | ||||
| 		static u8 TemperatureTable[11] = {30,35,40,45,50,55,60,65,70,75,80}; | ||||
| 		 | ||||
| 		memcpy(dev->mod_base.temp_tab, TemperatureTable, sizeof(TemperatureTable)); | ||||
| 	} | ||||
| 	dev->handler[0][8] = mod_temp_handler; | ||||
| 	dev->handler_data[0][8] = (unsigned long) dev; | ||||
| 	ddbwritel(dev, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN | | ||||
| 			TEMPMON_CONTROL_INTENABLE), | ||||
| 		  TEMPMON_CONTROL); | ||||
| 	ddbwritel(dev, (3 << 8), TEMPMON_FANCONTROL); | ||||
| 	 | ||||
| 	dev->mod_base.OverTemperatureError = | ||||
| 		((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0); | ||||
| 	if (dev->mod_base.OverTemperatureError)	{ | ||||
| 		pr_info("Over temperature condition\n"); | ||||
| 		status = -1; | ||||
| 	} | ||||
| 	mod_TemperatureMonitorSetFan(dev); | ||||
| 	spin_unlock_irq(&dev->mod_base.temp_lock); | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| static void mod_write_dac_register(struct ddb *dev, u8 Index, u8 Value) | ||||
| { | ||||
| 	u32 RegValue = 0; | ||||
| @@ -804,7 +1113,7 @@ static int set_base_frequency(struct ddb *dev, u32 freq) | ||||
| 	return mod_set_down(dev, down, 8, Ext); | ||||
| } | ||||
|  | ||||
| static int mod_init(struct ddb *dev, u32 Frequency) | ||||
| static int mod_init_1(struct ddb *dev, u32 Frequency) | ||||
| { | ||||
| 	int stat = 0; | ||||
| 	u8 *buffer; | ||||
| @@ -906,7 +1215,7 @@ void ddbridge_mod_rate_handler(unsigned long data) | ||||
| 	struct ddb_output *output = (struct ddb_output *) data; | ||||
| 	struct ddb_dma *dma = output->dma; | ||||
| 	struct ddb *dev = output->port->dev; | ||||
| 	struct mod_state *mod = &dev->mod[output->nr]; | ||||
| 	struct ddb_mod *mod = &dev->mod[output->nr]; | ||||
|  | ||||
| 	u32 chan = output->nr; | ||||
| 	u32 OutPacketCount; | ||||
| @@ -1081,7 +1390,7 @@ void ddbridge_mod_rate_handler(unsigned long data) | ||||
| 		PCRAdjustExtFrac, PCRCorr, mod->PCRIncrement); | ||||
| } | ||||
|  | ||||
| int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg) | ||||
| static int mod_ioctl_1(struct file *file, unsigned int cmd, void *parg) | ||||
| { | ||||
| 	struct dvb_device *dvbdev = file->private_data; | ||||
| 	struct ddb_output *output = dvbdev->priv; | ||||
| @@ -1146,7 +1455,114 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg) | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| static int mod_ioctl_2(struct file *file, unsigned int cmd, void *parg) | ||||
| { | ||||
| 	struct dvb_device *dvbdev = file->private_data; | ||||
| 	struct ddb_output *output = dvbdev->priv; | ||||
| 	struct ddb *dev = output->port->dev; | ||||
|  | ||||
| 	/* unsigned long arg = (unsigned long) parg; */ | ||||
| 	int ret = 0; | ||||
|  | ||||
| 	switch (cmd) { | ||||
| 	case DVB_MOD_SET: | ||||
| 	{ | ||||
| 		struct dvb_mod_params *mp = parg; | ||||
|  | ||||
| 		pr_info("set base freq\n"); | ||||
| 		dev->mod_base.frequency = mp->base_frequency; | ||||
| 		pr_info("set attenuator\n"); | ||||
| 		mod_set_attenuator(dev, mp->attenuator); | ||||
| 		break; | ||||
| 	} | ||||
| 	case DVB_MOD_CHANNEL_SET: | ||||
| 	{ | ||||
| 		struct dvb_mod_channel_params *cp = parg; | ||||
| 		int res; | ||||
| 		u32 ri; | ||||
|  | ||||
| 		pr_info("set modulation\n"); | ||||
| 		res = mod_set_modulation(dev, output->nr, cp->modulation); | ||||
| 		if (res) | ||||
| 			return res; | ||||
|  | ||||
| 		if (cp->input_bitrate > dev->mod[output->nr].obitrate) | ||||
| 			return -EINVAL; | ||||
| 		dev->mod[output->nr].ibitrate = cp->input_bitrate; | ||||
| 		dev->mod[output->nr].pcr_correction = cp->pcr_correction; | ||||
|  | ||||
| 		pr_info("ibitrate %llu\n", dev->mod[output->nr].ibitrate); | ||||
| 		pr_info("obitrate %llu\n", dev->mod[output->nr].obitrate); | ||||
| 		if (cp->input_bitrate != 0) { | ||||
| 			u64 d = dev->mod[output->nr].obitrate - | ||||
| 				dev->mod[output->nr].ibitrate; | ||||
|  | ||||
| 			d = div64_u64(d, dev->mod[output->nr].obitrate >> 24); | ||||
| 			if (d > 0xfffffe) | ||||
| 				ri = 0xfffffe; | ||||
| 			else | ||||
| 				ri = d; | ||||
| 		} else | ||||
| 			ri = 0; | ||||
| 		dev->mod[output->nr].rate_inc = ri; | ||||
| 		pr_info("ibr=%llu, obr=%llu, ri=0x%06x\n", | ||||
| 			dev->mod[output->nr].ibitrate >> 32, | ||||
| 			dev->mod[output->nr].obitrate >> 32, | ||||
| 			ri); | ||||
| 		break; | ||||
| 	} | ||||
| 	default: | ||||
| 		ret = -EINVAL; | ||||
| 		break; | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int mod_init_2(struct ddb *dev, u32 Frequency) | ||||
| { | ||||
| 	int status; | ||||
| 	int streams = dev->link[0].info->port_num; | ||||
|  | ||||
| 	dev->mod_base.frequency = Frequency; | ||||
| 	mod_TemperatureMonitorInit(dev, 1); | ||||
| 	status = mod_fsm_setup(dev, 0, 0); | ||||
|  | ||||
| 	if (streams <= 8) | ||||
| 		mod_set_vga(dev, RF_VGA_GAIN_N8); | ||||
| 	else if (streams <= 16) | ||||
| 		mod_set_vga(dev, RF_VGA_GAIN_N16); | ||||
| 	else | ||||
| 		mod_set_vga(dev, RF_VGA_GAIN_N24); | ||||
|  | ||||
| 	mod_set_attenuator(dev, 0); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg) | ||||
| { | ||||
| 	struct dvb_device *dvbdev = file->private_data; | ||||
| 	struct ddb_output *output = dvbdev->priv; | ||||
| 	struct ddb *dev = output->port->dev; | ||||
| 	 | ||||
| 	if (dev->link[0].info->version <= 0) | ||||
| 		return mod_ioctl_1(file, cmd, parg); | ||||
| 	if (dev->link[0].info->version == 2) | ||||
| 		return mod_ioctl_2(file, cmd, parg); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| int ddbridge_mod_init(struct ddb *dev) | ||||
| { | ||||
| 	return mod_init(dev, 722000000); | ||||
| 	spin_lock_init(&dev->mod_base.temp_lock); | ||||
| 	if (dev->link[0].info->version <= 1) | ||||
| 		return mod_init_1(dev, 722000000); | ||||
| 	if (dev->link[0].info->version == 2) | ||||
| 		return mod_init_2(dev, 114000000); | ||||
| 	return -1; | ||||
| } | ||||
|   | ||||
| @@ -201,10 +201,10 @@ static int ns_set_ci(struct dvbnss *nss, u8 ci) | ||||
| 	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)); | ||||
| 		  TS_CONTROL(dev->port[ciport].output)); | ||||
| 	usleep_range(1, 5); | ||||
| 	ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1d, | ||||
| 		  TS_OUTPUT_CONTROL(ciport)); | ||||
| 		  TS_CONTROL(dev->port[ciport].output)); | ||||
| 	dns->fe = dev->port[ciport].input[0]; | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| /* | ||||
|  * ddbridge-regs.h: Digital Devices PCIe bridge driver | ||||
|  * | ||||
|  * Copyright (C) 2010-2015 Digital Devices GmbH | ||||
|  * Copyright (C) 2010-2016 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 | ||||
| @@ -23,12 +23,11 @@ | ||||
|  | ||||
| /* Register Definitions */ | ||||
|  | ||||
| #define CUR_REGISTERMAP_VERSION     0x10003 | ||||
| #define CUR_REGISTERMAP_VERSION_CI  0x10000 | ||||
| #define CUR_REGISTERMAP_VERSION_MOD 0x10000 | ||||
| #define CUR_REGISTERMAP_VERSION_V1  0x00010001 | ||||
| #define CUR_REGISTERMAP_VERSION_V2  0x00020000 | ||||
|  | ||||
| #define HARDWARE_VERSION       0x00 | ||||
| #define REGISTERMAP_VERSION    0x04 | ||||
| #define HARDWARE_VERSION            0x00000000 | ||||
| #define REGISTERMAP_VERSION         0x00000004 | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| /* SPI Controller */ | ||||
| @@ -76,6 +75,8 @@ | ||||
|  | ||||
| #define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20) | ||||
| #define INTERRUPT_ACK    (INTERRUPT_BASE + 0x20) | ||||
| #define INTERRUPT_ACK1      (INTERRUPT_BASE + 0x24) | ||||
| #define INTERRUPT_ACK2      (INTERRUPT_BASE + 0x28) | ||||
|  | ||||
| #define INTMASK_CLOCKGEN    (0x00000001) | ||||
| #define INTMASK_TEMPMON     (0x00000002) | ||||
| @@ -105,6 +106,26 @@ | ||||
| #define INTMASK_TSOUTPUT4   (0x00080000) | ||||
|  | ||||
|  | ||||
| #define INTERRUPT_V2_CONTROL  (INTERRUPT_BASE + 0x00) | ||||
| #define INTERRUPT_V2_ENABLE_1 (INTERRUPT_BASE + 0x04) | ||||
| #define INTERRUPT_V2_ENABLE_2 (INTERRUPT_BASE + 0x08) | ||||
| #define INTERRUPT_V2_ENABLE_3 (INTERRUPT_BASE + 0x0c) | ||||
| #define INTERRUPT_V2_ENABLE_4 (INTERRUPT_BASE + 0x10) | ||||
| #define INTERRUPT_V2_ENABLE_5 (INTERRUPT_BASE + 0x14) | ||||
| #define INTERRUPT_V2_ENABLE_6 (INTERRUPT_BASE + 0x18) | ||||
| #define INTERRUPT_V2_ENABLE_7 (INTERRUPT_BASE + 0x1c) | ||||
|  | ||||
| #define INTERRUPT_V2_STATUS   (INTERRUPT_BASE + 0x20) | ||||
| #define INTERRUPT_V2_STATUS_1 (INTERRUPT_BASE + 0x24) | ||||
| #define INTERRUPT_V2_STATUS_2 (INTERRUPT_BASE + 0x28) | ||||
| #define INTERRUPT_V2_STATUS_3 (INTERRUPT_BASE + 0x2c) | ||||
| #define INTERRUPT_V2_STATUS_4 (INTERRUPT_BASE + 0x30) | ||||
| #define INTERRUPT_V2_STATUS_5 (INTERRUPT_BASE + 0x34) | ||||
| #define INTERRUPT_V2_STATUS_6 (INTERRUPT_BASE + 0x38) | ||||
| #define INTERRUPT_V2_STATUS_7 (INTERRUPT_BASE + 0x3c) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /* Modulator registers */ | ||||
|  | ||||
| @@ -128,23 +149,46 @@ | ||||
| /* Temperature Monitor ( 2x LM75A @ 0x90,0x92 I2c ) */ | ||||
| #define TEMPMON_BASE        (0xA0) | ||||
| #define TEMPMON_CONTROL    (TEMPMON_BASE + 0x00) | ||||
|  | ||||
| #define TEMPMON_CONTROL_SCAN        (0x00000001) | ||||
| #define TEMPMON_CONTROL_AUTOSCAN    (0x00000002) | ||||
| #define TEMPMON_CONTROL_INTENABLE   (0x00000004) | ||||
| #define TEMPMON_CONTROL_OVERTEMP    (0x00008000) | ||||
|  | ||||
|  | ||||
| /* SHORT Temperature in <20>C x 256 */ | ||||
| #define TEMPMON_CORE       (TEMPMON_BASE + 0x04) | ||||
| #define TEMPMON_SENSOR0    (TEMPMON_BASE + 0x04) | ||||
| #define TEMPMON_SENSOR1    (TEMPMON_BASE + 0x08) | ||||
| #define TEMPMON_SENSOR2    (TEMPMON_BASE + 0x0C) | ||||
|  | ||||
| #define TEMPMON_FANCONTROL  (TEMPMON_BASE + 0x10) | ||||
| #define TEMPMON_FANPWM      (0x00000F00)            // PWM speed in 10% steps | ||||
| #define TEMPMON_FANTACHO    (0x000000FF)            // Rotations in 100/min steps | ||||
|  | ||||
| // V1 Temperature Monitor | ||||
| // Temperature Monitor TEMPMON_CONTROL & 0x8000 == 0 : ( 2x LM75A @ 0x90,0x92 ) | ||||
| // Temperature Monitor TEMPMON_CONTROL & 0x8000 == 1 : ( 1x LM75A @ 0x90, 1x ADM1032 @ 0x9A ) | ||||
|  | ||||
| #define TEMPMON1_CORE       (TEMPMON_SENSOR0)    // SHORT Temperature in <20>C x 256 (ADM1032 ext) | ||||
| #define TEMPMON1_SENSOR1    (TEMPMON_BASE + 0x08)    // SHORT Temperature in <20>C x 256 (LM75A 0x90) | ||||
| #define TEMPMON1_SENSOR2    (TEMPMON_BASE + 0x0C)    // SHORT Temperature in <20>C x 256 (LM75A 0x92 or ADM1032 Int) | ||||
|  | ||||
| // V2 Temperature Monitor 2 ADM1032 | ||||
|  | ||||
| #define TEMPMON2_BOARD      (TEMPMON_SENSOR0)    // SHORT Temperature in <20>C x 256 (ADM1032 int) | ||||
| #define TEMPMON2_FPGACORE   (TEMPMON_SENSOR1)    // SHORT Temperature in <20>C x 256 (ADM1032 ext) | ||||
| #define TEMPMON2_QAMCORE    (TEMPMON_SENSOR2)    // SHORT Temperature in <20>C x 256 (ADM1032 ext) | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| /* 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) | ||||
| @@ -173,26 +217,17 @@ | ||||
| #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_CONTROL(_io)         (_io->regs + 0x00) | ||||
| #define TS_CONTROL2(_io)        (_io->regs + 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 DMA_BUFFER_CONTROL(_dma)       (_dma->regs + 0x00) | ||||
| #define DMA_BUFFER_ACK(_dma)           (_dma->regs + 0x04) | ||||
| #define DMA_BUFFER_CURRENT(_dma)       (_dma->regs + 0x08) | ||||
| #define DMA_BUFFER_SIZE(_dma)          (_dma->regs + 0x0c) | ||||
|  | ||||
|  | ||||
| /* ------------------------------------------------------------------------- */ | ||||
| @@ -263,6 +298,8 @@ | ||||
| #define CI_BLOCKIO_SEND_BUFFER(i)  \ | ||||
| 	(CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE + CI_BLOCKIO_BUFFER_SIZE) | ||||
|  | ||||
| // V1 | ||||
|  | ||||
| #define VCO1_BASE           (0xC0) | ||||
| #define VCO1_CONTROL        (VCO1_BASE + 0x00) | ||||
| #define VCO1_DATA           (VCO1_BASE + 0x04)  /* 24 Bit */ | ||||
| @@ -293,6 +330,53 @@ | ||||
| /* Muxout from VCO (usually = Lock) */ | ||||
| #define VCO3_CONTROL_MUXOUT (0x00000004) | ||||
|  | ||||
| // V2 | ||||
|  | ||||
| #define MAX2871_BASE            (0xC0) | ||||
| #define MAX2871_CONTROL         (MAX2871_BASE + 0x00) | ||||
| #define MAX2871_OUTDATA         (MAX2871_BASE + 0x04)  // 32 Bit | ||||
| #define MAX2871_INDATA          (MAX2871_BASE + 0x08)  // 32 Bit | ||||
| #define MAX2871_CONTROL_WRITE   (0x00000001)   // 1 = Trigger write, resets when done | ||||
| #define MAX2871_CONTROL_CE      (0x00000002)   // 0 = Put VCO into power down | ||||
| #define MAX2871_CONTROL_MUXOUT  (0x00000004)   // Muxout from VCO  | ||||
| #define MAX2871_CONTROL_LOCK    (0x00000008)   // Lock from VCO  | ||||
|  | ||||
| #define FSM_BASE                (0x200) | ||||
| #define FSM_CONTROL             (FSM_BASE + 0x00) | ||||
|  | ||||
| #define FSM_CONTROL_ENABLE      (0x00000100) | ||||
|  | ||||
| #define FSM_CMD_MASK            (0x00000087) | ||||
| #define FSM_CMD_STATUS          (0x00000080) | ||||
| #define FSM_CMD_RESET           (0x00000080) | ||||
| #define FSM_CMD_POWERDOWN       (0x00000081) | ||||
| #define FSM_CMD_SETUP           (0x00000082) | ||||
|  | ||||
| #define FSM_STATUS              (FSM_BASE + 0x00) | ||||
| #define FSM_STATUS_READY        (0x00010000) | ||||
| #define FSM_STATUS_QAMREADY     (0x00020000) | ||||
|  | ||||
|  | ||||
| #define FSM_CAPACITY            (FSM_BASE + 0x04) | ||||
| #define FSM_CAPACITY_MAX        (0x3F000000)   | ||||
| #define FSM_CAPACITY_CUR        (0x003F0000)   | ||||
| #define FSM_CAPACITY_INUSE      (0x0000003F)   | ||||
|  | ||||
| #define FSM_GAIN                (FSM_BASE + 0x10) | ||||
| #define FSM_GAINMASK            (0x000000FF) | ||||
|  | ||||
| #define FSM_GAIN_N1             (0x000000FE) | ||||
| #define FSM_GAIN_N2             (0x000000A1) | ||||
| #define FSM_GAIN_N4             (0x00000066) | ||||
| #define FSM_GAIN_N8             (0x00000048) | ||||
| #define FSM_GAIN_N16            (0x0000002D) | ||||
| #define FSM_GAIN_N24            (0x00000029) | ||||
| #define FSM_GAIN_N96            (0x00000011) | ||||
|  | ||||
|  | ||||
| // Attenuator/VGA | ||||
|  | ||||
| #define RF_ATTENUATOR   (0xD8) | ||||
| #define RF_ATTENUATOR   (0xD8) | ||||
| /*  0x00 =  0 dB | ||||
|     0x01 =  1 dB | ||||
| @@ -300,6 +384,20 @@ | ||||
|     0x1F = 31 dB | ||||
| */ | ||||
|  | ||||
| #define RF_VGA  (0xDC) | ||||
| /* Only V2 */ | ||||
| /* 8 bit range 0 - 31.75 dB Gain  */ | ||||
| 	 | ||||
| /* VGA Gain for same output level as V1 Modulator */ | ||||
| #define RF_VGA_GAIN_N8          (85) | ||||
| #define RF_VGA_GAIN_N16         (117) | ||||
| #define RF_VGA_GAIN_N24         (122) | ||||
|  | ||||
| #define RF_VGA_GAIN_MAX         (200) | ||||
|  | ||||
|  | ||||
| /* V1 only */ | ||||
|  | ||||
| #define RF_POWER        (0xE0) | ||||
| #define RF_POWER_BASE       (0xE0) | ||||
| #define RF_POWER_CONTROL    (RF_POWER_BASE + 0x00) | ||||
| @@ -343,7 +441,7 @@ | ||||
| #define IQOUTPUT_CONTROL_BYPASS_EQUALIZER   (0x00000010) | ||||
|  | ||||
|  | ||||
| /* Modulator Base */ | ||||
| /* Modulator Base  V1 */ | ||||
|  | ||||
| #define MODULATOR_BASE          (0x200) | ||||
| #define MODULATOR_CONTROL         (MODULATOR_BASE) | ||||
| @@ -361,9 +459,11 @@ | ||||
|  | ||||
| /* Modulator Channels */ | ||||
|  | ||||
| #define CHANNEL_BASE                (0x400) | ||||
| #define CHANNEL_BASE dev->link[0].info->regmap->channel->base | ||||
|  | ||||
| #define CHANNEL_CONTROL(i)          (CHANNEL_BASE + (i) * 64 + 0x00) | ||||
| #define CHANNEL_SETTINGS(i)         (CHANNEL_BASE + (i) * 64 + 0x04) | ||||
| #define CHANNEL_SETTINGS2(i)        (CHANNEL_BASE + (i) * 64 + 0x08) | ||||
| #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) | ||||
| @@ -373,6 +473,8 @@ | ||||
| #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_KF(i)               (CHANNEL_BASE + (i) * 64 + 0x30) | ||||
| #define CHANNEL_LF(i)               (CHANNEL_BASE + (i) * 64 + 0x34) | ||||
|  | ||||
| #define CHANNEL_CONTROL_RESET               (0x00000001) | ||||
| #define CHANNEL_CONTROL_ENABLE_DVB          (0x00000002) | ||||
| @@ -381,8 +483,17 @@ | ||||
| #define CHANNEL_CONTROL_ENABLE_PCRADJUST    (0x00000010) | ||||
| #define CHANNEL_CONTROL_FREEZE_STATUS       (0x00000100) | ||||
|  | ||||
| #define CHANNEL_CONTROL_CMD_MASK            (0x0000F000) | ||||
| #define CHANNEL_CONTROL_CMD_STATUS          (0x00008000) | ||||
| #define CHANNEL_CONTROL_CMD_FREE            (0x00008000) | ||||
| #define CHANNEL_CONTROL_CMD_SETUP           (0x00009000) | ||||
| #define CHANNEL_CONTROL_CMD_MUTE            (0x0000A000) | ||||
| #define CHANNEL_CONTROL_CMD_UNMUTE          (0x0000B000) | ||||
|  | ||||
| #define CHANNEL_CONTROL_RESET_ERROR         (0x00010000) | ||||
| #define CHANNEL_CONTROL_BUSY                (0x01000000) | ||||
| #define CHANNEL_CONTROL_ACTIVE              (0x00400000) | ||||
| #define CHANNEL_CONTROL_BUSY                (0x00800000) | ||||
| #define CHANNEL_CONTROL_ERROR_CMD           (0x10000000) | ||||
| #define CHANNEL_CONTROL_ERROR_SYNC          (0x20000000) | ||||
| #define CHANNEL_CONTROL_ERROR_UNDERRUN      (0x40000000) | ||||
| #define CHANNEL_CONTROL_ERROR_FATAL         (0x80000000) | ||||
| @@ -394,6 +505,14 @@ | ||||
| #define CHANNEL_SETTINGS_QAM128             (0x00000003) | ||||
| #define CHANNEL_SETTINGS_QAM256             (0x00000004) | ||||
|  | ||||
| #define CHANNEL_SETTINGS2_OUTPUT_MASK       (0x0000007F) | ||||
|  | ||||
| #define KFLF_MAX                            (0x07FFFFFFUL) | ||||
| #define KF_INIT(Symbolrate)                 (Symbolrate) | ||||
| #define LF_INIT(Symbolrate)                 (9000000UL) | ||||
| #define MIN_SYMBOLRATE                      (1000000) | ||||
| #define MAX_SYMBOLRATE                      (7100000) | ||||
|  | ||||
|  | ||||
| /* OCTONET */ | ||||
|  | ||||
|   | ||||
| @@ -24,7 +24,6 @@ | ||||
|  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | ||||
|  */ | ||||
|  | ||||
| /*#define DDB_ALT_DMA*/ | ||||
| #define DDB_USE_WORK | ||||
| /*#define DDB_TEST_THREADED*/ | ||||
|  | ||||
| @@ -58,6 +57,34 @@ static void ddb_unmap(struct ddb *dev) | ||||
| 	vfree(dev); | ||||
| } | ||||
|  | ||||
| static void __devexit ddb_irq_disable(struct ddb *dev) | ||||
| { | ||||
| 	if (dev->link[0].info->regmap->irq_version == 2) { | ||||
| 		ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL); | ||||
| 		ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1); | ||||
| 		ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_2); | ||||
| 		ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_3); | ||||
| 		ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_4); | ||||
| 		ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_5); | ||||
| 		ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_6); | ||||
| 		ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_7); | ||||
| 	} else { | ||||
| 		ddbwritel(dev, 0, INTERRUPT_ENABLE); | ||||
| 		ddbwritel(dev, 0, MSI1_ENABLE); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void __devexit ddb_irq_exit(struct ddb *dev) | ||||
| { | ||||
| 	ddb_irq_disable(dev); | ||||
| 	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 | ||||
| } | ||||
|  | ||||
| static void __devexit ddb_remove(struct pci_dev *pdev) | ||||
| { | ||||
| @@ -70,16 +97,7 @@ static void __devexit ddb_remove(struct pci_dev *pdev) | ||||
|  | ||||
| 	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_irq_exit(dev); | ||||
| 	ddb_ports_release(dev); | ||||
| 	ddb_buffers_free(dev); | ||||
|  | ||||
| @@ -93,16 +111,146 @@ static void __devexit ddb_remove(struct pci_dev *pdev) | ||||
| #define __devinitdata | ||||
| #endif | ||||
|  | ||||
| static int __devinit ddb_irq_msi(struct ddb *dev, int nr) | ||||
| { | ||||
| 	int stat; | ||||
|  | ||||
| #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, nr); | ||||
| 		if (stat >= 1) { | ||||
| 			dev->msi = stat; | ||||
| 			pr_info("DDBridge: using %d MSI interrupt(s)\n", | ||||
| 				dev->msi); | ||||
| 		} else | ||||
| 			pr_info("DDBridge: MSI not available.\n"); | ||||
| 		 | ||||
| #else | ||||
| 		stat = pci_enable_msi_block(dev->pdev, nr); | ||||
| 		if (stat == 0) { | ||||
| 			dev->msi = nr; | ||||
| 			pr_info("DDBridge: using %d MSI interrupts\n", nr); | ||||
| 		} else if (stat == 1) { | ||||
| 			stat = pci_enable_msi(dev->pdev); | ||||
| 			dev->msi = 1; | ||||
| 		} | ||||
| 		if (stat < 0)  | ||||
| 			pr_info("DDBridge: MSI not available.\n"); | ||||
| #endif | ||||
| 	} | ||||
| 	return stat; | ||||
| } | ||||
|  | ||||
| static int __devinit ddb_irq_init2(struct ddb *dev) | ||||
| { | ||||
| 	int stat; | ||||
| 	int irq_flag = IRQF_SHARED; | ||||
|  | ||||
| 	pr_info("init type 2 IRQ hardware block\n"); | ||||
|  | ||||
| 	ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL); | ||||
| 	ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1); | ||||
| 	ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_2); | ||||
| 	ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_3); | ||||
| 	ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_4); | ||||
| 	ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_5); | ||||
| 	ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_6); | ||||
| 	ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_7); | ||||
|  | ||||
| 	ddb_irq_msi(dev, 1); | ||||
| 	if (dev->msi) | ||||
| 		irq_flag = 0; | ||||
|  | ||||
| 	stat = request_irq(dev->pdev->irq, irq_handler_v2, | ||||
| 			   irq_flag, "ddbridge", (void *) dev); | ||||
| 	if (stat < 0) | ||||
| 		return stat; | ||||
| 	 | ||||
| 	ddbwritel(dev, 0x0000ff7f, INTERRUPT_V2_CONTROL); | ||||
| 	ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_1); | ||||
| 	ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_2); | ||||
| 	ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_3); | ||||
| 	ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_4); | ||||
| 	ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_5); | ||||
| 	ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_6); | ||||
| 	ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_7); | ||||
| 	return stat; | ||||
| } | ||||
| 	 | ||||
| static int __devinit ddb_irq_init(struct ddb *dev) | ||||
| { | ||||
| 	int stat; | ||||
| 	int irq_flag = IRQF_SHARED; | ||||
| 	 | ||||
| 	if (dev->link[0].info->regmap->irq_version == 2) | ||||
| 		return ddb_irq_init2(dev); | ||||
| 	 | ||||
| 	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); | ||||
|  | ||||
| 	ddb_irq_msi(dev, 2); | ||||
|  | ||||
| 	if (dev->msi) | ||||
| 		irq_flag = 0; | ||||
| 	if (dev->msi == 2) { | ||||
| 		stat = request_irq(dev->pdev->irq, irq_handler0, | ||||
| 				   irq_flag, "ddbridge", (void *) dev); | ||||
| 		if (stat < 0) | ||||
| 			return stat; | ||||
| 		stat = request_irq(dev->pdev->irq + 1, irq_handler1, | ||||
| 				   irq_flag, "ddbridge", (void *) dev); | ||||
| 		if (stat < 0) { | ||||
| 			free_irq(dev->pdev->irq, dev); | ||||
| 			return stat; | ||||
| 		} | ||||
| 	} 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) | ||||
| 			return stat; | ||||
| 	} | ||||
| 	/*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); | ||||
| 	} | ||||
| 	return stat; | ||||
| } | ||||
|  | ||||
| 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; | ||||
|  | ||||
| 	pci_set_master(pdev); | ||||
|  | ||||
| 	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) | ||||
| 		if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) | ||||
| 			return -ENODEV; | ||||
| 	 | ||||
| 	dev = vzalloc(sizeof(struct ddb)); | ||||
| 	if (dev == NULL) | ||||
| 		return -ENOMEM; | ||||
| @@ -144,75 +292,8 @@ static int __devinit ddb_probe(struct pci_dev *pdev, | ||||
| 		dev->link[0].ids.hwid, dev->link[0].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; | ||||
| 		ddb_reset_ios(dev); | ||||
| 	} | ||||
| 	ddbwritel(dev, 0, DMA_BASE_READ); | ||||
| 	if (dev->link[0].info->type != DDB_MOD) | ||||
| @@ -223,22 +304,14 @@ static int __devinit ddb_probe(struct pci_dev *pdev, | ||||
| 			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); | ||||
| 	} | ||||
| 	stat = ddb_irq_init(dev); | ||||
| 	if (stat < 0) | ||||
| 		goto fail0; | ||||
| 	 | ||||
| 	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); | ||||
| 	ddb_irq_disable(dev); | ||||
| fail0: | ||||
| 	pr_err("fail0\n"); | ||||
| 	if (dev->msi) | ||||
| @@ -256,37 +329,6 @@ fail: | ||||
| /****************************************************************************/ | ||||
| /****************************************************************************/ | ||||
|  | ||||
| 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", | ||||
| @@ -418,26 +460,6 @@ static struct ddb_info ddb_dvbct = { | ||||
|  | ||||
| /****************************************************************************/ | ||||
|  | ||||
| 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_ct_8 = { | ||||
| 	.type     = DDB_OCTOPUS_MAX_CT, | ||||
| 	.name     = "Digital Devices MAX CT8", | ||||
| 	.regmap   = &octopus_map, | ||||
| 	.port_num = 4, | ||||
| 	.i2c_mask = 0x0f, | ||||
| 	.board_control   = 0x0ff, | ||||
| 	.board_control_2 = 0xf00, | ||||
| 	.ts_quirks = TS_QUIRK_SERIAL, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_mod = { | ||||
| 	.type     = DDB_MOD, | ||||
| 	.name     = "Digital Devices DVB-C modulator", | ||||
| @@ -446,13 +468,48 @@ static struct ddb_info ddb_mod = { | ||||
| 	.temp_num = 1, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octopus_net = { | ||||
| 	.type     = DDB_OCTONET, | ||||
| 	.name     = "Digital Devices OctopusNet network DVB adapter", | ||||
| 	.regmap   = &octopus_net_map, | ||||
| static struct ddb_info ddb_mod_fsm_24 = { | ||||
| 	.type     = DDB_MOD, | ||||
| 	.version  = 2, | ||||
| 	.name     = "Digital Devices DVB-C modulator FSM-24", | ||||
| 	.regmap   = &octopus_mod_2_map, | ||||
| 	.port_num = 24, | ||||
| 	.temp_num = 1, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_mod_fsm_16 = { | ||||
| 	.type     = DDB_MOD, | ||||
| 	.version  = 2, | ||||
| 	.name     = "Digital Devices DVB-C modulator FSM-16", | ||||
| 	.regmap   = &octopus_mod_2_map, | ||||
| 	.port_num = 16, | ||||
| 	.temp_num = 1, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_mod_fsm_8 = { | ||||
| 	.type     = DDB_MOD, | ||||
| 	.name     = "Digital Devices DVB-C modulator FSM-8", | ||||
| 	.version  = 2, | ||||
| 	.regmap   = &octopus_mod_2_map, | ||||
| 	.port_num = 8, | ||||
| 	.temp_num = 1, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octopro_hdin = { | ||||
| 	.type     = DDB_OCTOPRO_HDIN, | ||||
| 	.name     = "Digital Devices OctopusNet Pro HDIN", | ||||
| 	.regmap   = &octopro_hdin_map, | ||||
| 	.port_num = 10, | ||||
| 	.i2c_mask = 0x3ff, | ||||
| 	.mdio_num = 1, | ||||
| }; | ||||
|  | ||||
| static struct ddb_info ddb_octopro = { | ||||
| 	.type     = DDB_OCTOPRO, | ||||
| 	.name     = "Digital Devices OctopusNet Pro", | ||||
| 	.regmap   = &octopro_map, | ||||
| 	.port_num = 10, | ||||
| 	.i2c_mask = 0x3ff, | ||||
| 	.ns_num   = 12, | ||||
| 	.mdio_num = 1, | ||||
| }; | ||||
|  | ||||
| @@ -493,7 +550,16 @@ static const struct pci_device_id ddb_id_tbl[] __devinitconst = { | ||||
| 	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), | ||||
| 	DDB_ID(DDVID, 0x0210, DDVID, 0x0001, ddb_mod_fsm_24), | ||||
| 	DDB_ID(DDVID, 0x0210, DDVID, 0x0002, ddb_mod_fsm_16), | ||||
| 	DDB_ID(DDVID, 0x0210, DDVID, 0x0003, ddb_mod_fsm_8), | ||||
| 	/* testing on OctopusNet Pro */ | ||||
| 	DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro_hdin), | ||||
| 	DDB_ID(DDVID, 0x0321, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	DDB_ID(DDVID, 0x0322, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro), | ||||
| 	DDB_ID(DDVID, 0x0323, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	DDB_ID(DDVID, 0x0328, PCI_ANY_ID, PCI_ANY_ID, ddb_none), | ||||
| 	DDB_ID(DDVID, 0x0329, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro_hdin), | ||||
| 	/* 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), | ||||
| @@ -521,7 +587,7 @@ static __init int module_init_ddbridge(void) | ||||
|  | ||||
| 	pr_info("Digital Devices PCIE bridge driver " | ||||
| 		DDBRIDGE_VERSION | ||||
| 		", Copyright (C) 2010-15 Digital Devices GmbH\n"); | ||||
| 		", Copyright (C) 2010-16 Digital Devices GmbH\n"); | ||||
| 	if (ddb_class_create() < 0) | ||||
| 		return -1; | ||||
| 	ddb_wq = create_workqueue("ddbridge"); | ||||
|   | ||||
| @@ -91,10 +91,10 @@ | ||||
| #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_I2C    32 | ||||
| #define DDB_MAX_PORT   32 | ||||
| #define DDB_MAX_INPUT  64 | ||||
| #define DDB_MAX_OUTPUT 32 | ||||
| #define DDB_MAX_LINK    4 | ||||
| #define DDB_LINK_SHIFT 28 | ||||
|  | ||||
| @@ -106,25 +106,30 @@ struct ddb_regset { | ||||
| 	u32 size; | ||||
| }; | ||||
|  | ||||
| struct ddb_ports { | ||||
| 	u32 base; | ||||
| 	u32 num; | ||||
| 	u32 size; | ||||
| }; | ||||
|  | ||||
| struct ddb_regmap { | ||||
| 	struct ddb_ports  *bc; | ||||
| 	u32 irq_version; | ||||
| 	u32 irq_base_i2c; | ||||
| 	u32 irq_base_idma; | ||||
| 	u32 irq_base_odma; | ||||
| 	u32 irq_base_gtl; | ||||
| 	u32 irq_base_rate; | ||||
| 	 | ||||
| 	struct ddb_regset *i2c; | ||||
| 	struct ddb_regset *i2c_buf; | ||||
| 	struct ddb_regset *dma; | ||||
| 	struct ddb_regset *dma_buf; | ||||
| 	struct ddb_regset *idma; | ||||
| 	struct ddb_regset *idma_buf; | ||||
| 	struct ddb_regset *odma; | ||||
| 	struct ddb_regset *odma_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 *ci; | ||||
| 	//struct ddb_regset *pid_filter; | ||||
| 	//struct ddb_regset *ns; | ||||
| 	struct ddb_regset *gtl; | ||||
| 	//struct ddb_regset *mdio; | ||||
| }; | ||||
|  | ||||
| struct ddb_ids { | ||||
| @@ -140,7 +145,7 @@ struct ddb_ids { | ||||
| }; | ||||
|  | ||||
| struct ddb_info { | ||||
| 	int   type; | ||||
| 	u32   type; | ||||
| #define DDB_NONE         0 | ||||
| #define DDB_OCTOPUS      1 | ||||
| #define DDB_OCTOPUS_CI   2 | ||||
| @@ -148,6 +153,9 @@ struct ddb_info { | ||||
| #define DDB_OCTONET      4 | ||||
| #define DDB_OCTOPUS_MAX  5 | ||||
| #define DDB_OCTOPUS_MAX_CT  6 | ||||
| #define DDB_OCTOPRO      7 | ||||
| #define DDB_OCTOPRO_HDIN 8 | ||||
| 	u32   version; | ||||
| 	char *name; | ||||
| 	u32   i2c_mask; | ||||
| 	u8    port_num; | ||||
| @@ -161,8 +169,9 @@ struct ddb_info { | ||||
| 	u8    mdio_num; | ||||
| 	u8    con_clock; /* use a continuous clock */ | ||||
| 	u8    ts_quirks; | ||||
| #define TS_QUIRK_SERIAL   1 | ||||
| #define TS_QUIRK_REVERSED 2 | ||||
| #define TS_QUIRK_SERIAL    1 | ||||
| #define TS_QUIRK_REVERSED  2 | ||||
| #define TS_QUIRK_NO_OUTPUT 4 | ||||
| 	struct ddb_regmap *regmap; | ||||
| }; | ||||
|  | ||||
| @@ -171,6 +180,15 @@ struct ddb_info { | ||||
|  | ||||
| #define DMA_MAX_BUFS 32      /* hardware table limit */ | ||||
|  | ||||
| #ifdef SMALL_DMA_BUFS | ||||
| #define INPUT_DMA_BUFS 32 | ||||
| #define INPUT_DMA_SIZE (32*47*21) | ||||
| #define INPUT_DMA_IRQ_DIV 1 | ||||
|  | ||||
| #define OUTPUT_DMA_BUFS 32 | ||||
| #define OUTPUT_DMA_SIZE (32*47*21) | ||||
| #define OUTPUT_DMA_IRQ_DIV 1 | ||||
| #else | ||||
| #define INPUT_DMA_BUFS 8 | ||||
| #define INPUT_DMA_SIZE (128*47*21) | ||||
| #define INPUT_DMA_IRQ_DIV 1 | ||||
| @@ -178,19 +196,22 @@ struct ddb_info { | ||||
| #define OUTPUT_DMA_BUFS 8 | ||||
| #define OUTPUT_DMA_SIZE (128*47*21) | ||||
| #define OUTPUT_DMA_IRQ_DIV 1 | ||||
| #endif | ||||
|  | ||||
| struct ddb; | ||||
| struct ddb_port; | ||||
|  | ||||
| struct ddb_dma { | ||||
| 	void                  *io; | ||||
| 	u32                    nr; | ||||
| 	u32                    regs; | ||||
| 	u32                    bufregs; | ||||
|  | ||||
| 	dma_addr_t             pbuf[DMA_MAX_BUFS]; | ||||
| 	u8                    *vbuf[DMA_MAX_BUFS]; | ||||
| 	u32                    num; | ||||
| 	u32                    size; | ||||
| 	u32                    div; | ||||
| 	u32                    bufreg; | ||||
| 	u32                    bufval; | ||||
|  | ||||
| #ifdef DDB_USE_WORK | ||||
| 	struct work_struct     work; | ||||
| @@ -242,6 +263,7 @@ struct ddb_ci { | ||||
| struct ddb_io { | ||||
| 	struct ddb_port       *port; | ||||
| 	u32                    nr; | ||||
| 	u32                    regs; | ||||
| 	struct ddb_dma        *dma; | ||||
| 	struct ddb_io         *redo; | ||||
| 	struct ddb_io         *redi; | ||||
| @@ -316,10 +338,21 @@ struct mod_base { | ||||
| 	u32                    frequency; | ||||
| 	u32                    flat_start; | ||||
| 	u32                    flat_end; | ||||
|  | ||||
| 	spinlock_t             temp_lock; | ||||
| 	int                    OverTemperatureError; | ||||
| 	u8                     temp_tab[11]; | ||||
| }; | ||||
|  | ||||
| struct mod_state { | ||||
| struct ddb_mod { | ||||
| 	struct ddb_port       *port; | ||||
| 	u32                    nr; | ||||
| 	u32                    regs; | ||||
| 	 | ||||
| 	u32                    frequency; | ||||
| 	u32                    modulation; | ||||
| 	u32                    symbolrate; | ||||
| 	 | ||||
| 	u64                    obitrate; | ||||
| 	u64                    ibitrate; | ||||
| 	u32                    pcr_correction; | ||||
| @@ -413,10 +446,11 @@ struct ddb { | ||||
| 	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]; | ||||
| 	struct ddb_dma         idma[DDB_MAX_INPUT]; | ||||
| 	struct ddb_dma         odma[DDB_MAX_OUTPUT]; | ||||
|  | ||||
| 	void                   (*handler[128])(unsigned long); | ||||
| 	unsigned long          handler_data[128]; | ||||
| 	void                   (*handler[4][256])(unsigned long); | ||||
| 	unsigned long          handler_data[4][256]; | ||||
|  | ||||
| 	struct device         *ddb_dev; | ||||
| 	u32                    ddb_dev_users; | ||||
| @@ -436,7 +470,7 @@ struct ddb { | ||||
| 	u8                     tsbuf[TS_CAPTURE_LEN]; | ||||
|  | ||||
| 	struct mod_base        mod_base; | ||||
| 	struct mod_state       mod[10]; | ||||
| 	struct ddb_mod         mod[24]; | ||||
| }; | ||||
|  | ||||
| static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr) | ||||
| @@ -486,6 +520,7 @@ static inline void gtlw(struct ddb_link *link) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #if 0 | ||||
| static u32 ddblreadl(struct ddb_link *link, u32 adr) | ||||
| { | ||||
| 	if (unlikely(link->nr)) { | ||||
| @@ -519,6 +554,7 @@ static void ddblwritel(struct ddb_link *link, u32 val, u32 adr) | ||||
| 	} | ||||
| 	writel(val, (char *) (link->dev->regs + (adr))); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static u32 ddbreadl(struct ddb *dev, u32 adr) | ||||
| { | ||||
| @@ -714,6 +750,6 @@ 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.23" | ||||
| #define DDBRIDGE_VERSION "0.9.24" | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| /* | ||||
|  * octonet.c: Digital Devices network tuner driver | ||||
|  * | ||||
|  * Copyright (C) 2012-15 Digital Devices GmbH | ||||
|  * Copyright (C) 2012-16 Digital Devices GmbH | ||||
|  *                       Marcus Metzler <mocm@metzlerbros.de> | ||||
|  *                       Ralph Metzler <rjkm@metzlerbros.de> | ||||
|  * | ||||
| @@ -25,7 +25,11 @@ | ||||
|  | ||||
| #include "ddbridge.h" | ||||
| #include "ddbridge-regs.h" | ||||
| #if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)) | ||||
| #include <asm-generic/pci-dma-compat.h> | ||||
| #else | ||||
| #include <linux/pci-dma-compat.h> | ||||
| #endif | ||||
|  | ||||
| static int adapter_alloc = 3; | ||||
| module_param(adapter_alloc, int, 0444); | ||||
| @@ -34,21 +38,13 @@ MODULE_PARM_DESC(adapter_alloc, | ||||
|  | ||||
| #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 = { | ||||
| 	.irq_version = 1, | ||||
| 	.irq_base_i2c = 0, | ||||
| 	.i2c = &octopus_i2c, | ||||
| 	.i2c_buf = &octopus_i2c_buf, | ||||
| 	.input = &octopus_input, | ||||
| 	.output = &octopus_output, | ||||
| }; | ||||
|  | ||||
| static struct ddb_regset octopus_gtl = { | ||||
| @@ -58,8 +54,13 @@ static struct ddb_regset octopus_gtl = { | ||||
| }; | ||||
|  | ||||
| static struct ddb_regmap octopus_net_gtl = { | ||||
| 	.irq_version = 1, | ||||
| 	.irq_base_i2c = 0, | ||||
| 	.irq_base_gtl = 10, | ||||
| 	.i2c = &octopus_i2c, | ||||
| 	.i2c_buf = &octopus_i2c_buf, | ||||
| 	.input = &octopus_input, | ||||
| 	.output = &octopus_output, | ||||
| 	.gtl = &octopus_gtl, | ||||
| }; | ||||
|  | ||||
| @@ -134,7 +135,6 @@ 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) | ||||
| @@ -185,9 +185,7 @@ static int __init octonet_probe(struct platform_device *pdev) | ||||
| 	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); | ||||
| 	ddb_reset_ios(dev); | ||||
|  | ||||
| 	irq = platform_get_irq(dev->pfdev, 0); | ||||
| 	if (irq < 0) | ||||
| @@ -236,7 +234,7 @@ static __init int init_octonet(void) | ||||
| 	int res; | ||||
|  | ||||
| 	pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION | ||||
| 		", Copyright (C) 2010-15 Digital Devices GmbH\n"); | ||||
| 		", Copyright (C) 2010-16 Digital Devices GmbH\n"); | ||||
| 	res = ddb_class_create(); | ||||
| 	if (res) | ||||
| 		return res; | ||||
|   | ||||
							
								
								
									
										22
									
								
								docs/ci
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								docs/ci
									
									
									
									
									
								
							| @@ -1,3 +1,5 @@ | ||||
| - General Information | ||||
|  | ||||
| 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. | ||||
| @@ -26,6 +28,24 @@ use the new interface. | ||||
| See docs/redirect for more info. | ||||
|  | ||||
|  | ||||
| - Clock Speed | ||||
|  | ||||
| The normal clock speed for the TS output is 72 MHz wich is the standard | ||||
| speed used for CI. | ||||
|  | ||||
| Packets are sent with an adjustable gap between the packets. | ||||
| The gap size is (gap value * 2) + 4 or 0 if the gap is disabled. | ||||
| So, the standard gap value of 4 leads to a gap of 12 bytes which means | ||||
| that the effective data rate is (72*188)/200 = 67.68 MBits/s. | ||||
|  | ||||
| Depending on the hardware, the clock speed can be changed with the | ||||
| ci_bitrate module parameter: | ||||
|  | ||||
| - Octopus CI, Octopus CI S2 Pro : supported | ||||
|  | ||||
| - old CI single flex modules: supported | ||||
|  | ||||
| - new dual CI flex module: not yet supported, use the standard 72000 kHz | ||||
|  | ||||
|  | ||||
|  | ||||
| Valid ranges for are from ... to 96000 KHz. | ||||
|   | ||||
| @@ -955,6 +955,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) | ||||
| 	} | ||||
|  | ||||
| 	c->stream_id = NO_STREAM_ID_FILTER; | ||||
| 	c->pls = NO_SCRAMBLING_CODE; | ||||
|  | ||||
| 	switch (c->delivery_system) { | ||||
| 	case SYS_DVBS: | ||||
| @@ -1031,6 +1032,7 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { | ||||
| 	_DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0), | ||||
| 	_DTV_CMD(DTV_LNA, 1, 0), | ||||
| 	_DTV_CMD(DTV_INPUT, 1, 0), | ||||
| 	_DTV_CMD(DTV_PLS, 1, 0), | ||||
|  | ||||
| 	/* Get */ | ||||
| 	_DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1), | ||||
| @@ -1462,6 +1464,10 @@ static int dtv_property_process_get(struct dvb_frontend *fe, | ||||
| 		tvp->u.buffer.len = 4; | ||||
| 		break; | ||||
|  | ||||
| 	case DTV_PLS: | ||||
| 		tvp->u.data = c->pls; | ||||
| 		break; | ||||
| 		 | ||||
| 	/* Fill quality measures */ | ||||
| 	case DTV_STAT_SIGNAL_STRENGTH: | ||||
| 		tvp->u.st = c->strength; | ||||
| @@ -1901,6 +1907,10 @@ static int dtv_property_process_set(struct dvb_frontend *fe, | ||||
| 			r = fe->ops.set_input(fe, c->input); | ||||
| 		break; | ||||
|  | ||||
| 	case DTV_PLS: | ||||
| 		c->pls = tvp->u.data; | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|   | ||||
| @@ -397,6 +397,7 @@ struct dtv_frontend_properties { | ||||
|  | ||||
| 	u32			lna; | ||||
| 	s32                     input; | ||||
| 	u32			pls; | ||||
| 	 | ||||
| 	/* statistics data */ | ||||
| 	struct dtv_fe_stats	strength; | ||||
|   | ||||
| @@ -35,8 +35,11 @@ | ||||
| #include <asm/div64.h> | ||||
|  | ||||
| #include "dvb_frontend.h" | ||||
| #include "dvb_math.h" | ||||
| #include "cxd2843.h" | ||||
|  | ||||
| #define Log10x100(x) ((s32)(((((u64) intlog2(x) * 0x1e1a5e2e) >> 47 ) + 1) >> 1)) | ||||
|  | ||||
| #define USE_ALGO 1 | ||||
|  | ||||
| enum demod_type { CXD2843, CXD2837, CXD2838 }; | ||||
| @@ -329,7 +332,7 @@ static inline u32 MulDiv32(u32 a, u32 b, u32 c) | ||||
| static int read_tps(struct cxd_state *state, u8 *tps) | ||||
| { | ||||
| 	if (state->last_status != 0x1f) | ||||
| 		return 0; | ||||
| 		return -1; | ||||
|  | ||||
| 	freeze_regst(state); | ||||
| 	readregst_unlocked(state, 0x10, 0x2f, tps, 7); | ||||
| @@ -337,6 +340,63 @@ static int read_tps(struct cxd_state *state, u8 *tps) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* Read DVBT2 OFDM Info */ | ||||
| /*  OFDMInfo[0] [5]    OFDM_MIXED        */ | ||||
| /*  OFDMInfo[0] [4]    OFDM_MISO         */ | ||||
| /*  OFDMInfo[0] [2:0]  OFDM_FFTSIZE[2:0] */ | ||||
| /*  OFDMInfo[1] [6:4]  OFDM_GI[2:0]      */ | ||||
| /*  OFDMInfo[1] [2:0]  OFDM_PP[2:0]      */ | ||||
| /*  OFDMInfo[2] [4]    OFDM_BWT_EXT      */ | ||||
| /*  OFDMInfo[2] [3:0]  OFDM_PAPR[3:0]    */ | ||||
| /*  OFDMInfo[3] [3:0]  OFDM_NDSYM[11:8] */ | ||||
| /*  OFDMInfo[4] [7:0]  OFDM_NDSYM[7:0]  */ | ||||
|  | ||||
| static int read_t2_ofdm_info(struct cxd_state *state, u8 *ofdm) | ||||
| { | ||||
| 	if (state->last_status != 0x1f) | ||||
| 		return -1; | ||||
|  | ||||
| 	freeze_regst(state); | ||||
| 	readregst_unlocked(state, 0x20, 0x5c, ofdm, 5); | ||||
| 	unfreeze_regst(state); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* Read DVBT2 QAM,  | ||||
|    Data PLP | ||||
|   0  [7:0]        L1POST_PLP_ID[7:0] | ||||
|   1  [2:0]        L1POST_PLP_TYPE[2:0] | ||||
|   2  [4:0]        L1POST_PLP_PAYLOAD_TYPE[4:0] | ||||
|   3  [0]          L1POST_FF_FLAG | ||||
|   4  [2:0]        L1POST_FIRST_RF_IDX[2:0] | ||||
|   5  [7:0]        L1POST_FIRST_FRAME_IDX[7:0] | ||||
|   6  [7:0]        L1POST_PLP_GROUP_ID[7:0] | ||||
|   7  [2:0]        L1POST_PLP_COD[2:0] | ||||
|   8  [2:0]        L1POST_PLP_MOD[2:0] | ||||
|   9  [0]          L1POST_PLP_ROTATION | ||||
|  10  [1:0]        L1POST_PLP_FEC_TYPE[1:0] | ||||
|  11  [1:0]        L1POST_PLP_NUM_BLOCKS_MAX[9:8] | ||||
|  12  [7:0]        L1POST_PLP_NUM_BLOCKS_MAX[7:0] | ||||
|  13  [7:0]        L1POST_FRAME_INTERVAL[7:0] | ||||
|  14  [7:0]        L1POST_TIME_IL_LENGTH[7:0] | ||||
|  15  [0]          L1POST_TIME_IL_TYPE | ||||
|  16  [0]          L1POST_IN_BAND_FLAG | ||||
|  17  [7:0]        L1POST_RESERVED_1[15:8] | ||||
|  18  [7:0]        L1POST_RESERVED_1[7:0] | ||||
|  19-37 same for common PLP | ||||
| */ | ||||
|  | ||||
| static int read_t2_tlp_info(struct cxd_state *state, u8 off, u8 count, u8 *tlp) | ||||
| { | ||||
| 	if (state->last_status != 0x1f) | ||||
| 		return -1; | ||||
|  | ||||
| 	freeze_regst(state); | ||||
| 	readregst_unlocked(state, 0x22, 0x54 + off, tlp, count); | ||||
| 	unfreeze_regst(state); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void Active_to_Sleep(struct cxd_state *state) | ||||
| { | ||||
| 	if (state->state <= Sleep) | ||||
| @@ -1174,7 +1234,7 @@ static int set_parameters(struct dvb_frontend *fe) | ||||
| 		fe->ops.tuner_ops.set_params(fe); | ||||
| 	state->bandwidth = fe->dtv_property_cache.bandwidth_hz; | ||||
| 	state->bw = (fe->dtv_property_cache.bandwidth_hz + 999999) / 1000000; | ||||
| 	if (fe->dtv_property_cache.stream_id == 0xffffffff) { | ||||
| 	if (fe->dtv_property_cache.stream_id == NO_STREAM_ID_FILTER) { | ||||
| 		state->DataSliceID = 0xffffffff; | ||||
| 		state->plp = 0xffffffff; | ||||
| 	} else { | ||||
| @@ -1273,18 +1333,20 @@ static int read_snr(struct dvb_frontend *fe, u16 *snr); | ||||
|  | ||||
| static int get_stats(struct dvb_frontend *fe) | ||||
| { | ||||
| 	struct cxd_state *state = fe->demodulator_priv; | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
| 	u16 val; | ||||
| 	s64 str; | ||||
|  | ||||
| 	if (fe->ops.tuner_ops.get_rf_strength) | ||||
| 		fe->ops.tuner_ops.get_rf_strength(fe, &val); | ||||
| 	else | ||||
| 		val = 0; | ||||
|  | ||||
| 	str = 1000 * (s64) (s16) val; | ||||
| 	str -= 108750; | ||||
| 	p->strength.len = 1; | ||||
| 	p->strength.stat[0].scale = FE_SCALE_DECIBEL; | ||||
| 	p->strength.stat[0].uvalue = 1000 * (s64) (s16) val; | ||||
| 	p->strength.stat[0].uvalue = str; | ||||
| 	 | ||||
| 	read_snr(fe, &val); | ||||
| 	p->cnr.len = 1; | ||||
| @@ -1313,6 +1375,12 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status) | ||||
| 			if (rdata & 0x20) | ||||
| 				*status |= 0x1f; | ||||
| 		} | ||||
| 		if (*status == 0x1f && state->FirstTimeLock) { | ||||
| 			readregst(state, 0x40, 0x19, &rdata, 1); | ||||
| 			rdata &= 0x07; | ||||
| 			state->BERScaleMax = ( rdata < 2 ) ? 18 : 19; | ||||
| 			state->FirstTimeLock = 0; | ||||
| 		} | ||||
| 		break; | ||||
| 	case ActiveT: | ||||
| 		readregst(state, 0x10, 0x10, &rdata, 1); | ||||
| @@ -1323,6 +1391,16 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status) | ||||
| 			if (rdata & 0x20) | ||||
| 				*status |= 0x1f; | ||||
| 		} | ||||
| 		if (*status == 0x1f && state->FirstTimeLock) { | ||||
| 			u8 tps[7]; | ||||
| 			 | ||||
| 			read_tps(state, tps); | ||||
| 			state->BERScaleMax = | ||||
| 				(((tps[0] >> 6) & 0x03) < 2 ) ? 17 : 18; | ||||
| 			if ((tps[0] & 7) < 2) | ||||
| 				state->BERScaleMax--; | ||||
| 			state->FirstTimeLock = 0; | ||||
| 		} | ||||
| 		break; | ||||
| 	case ActiveT2: | ||||
| 		readregst(state, 0x20, 0x10, &rdata, 1); | ||||
| @@ -1369,6 +1447,12 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status) | ||||
| 			if (rdata & 0x01) | ||||
| 				*status |= 0x18; | ||||
| 		} | ||||
| 		if (*status == 0x1f && state->FirstTimeLock) { | ||||
| 			/* readregst(state, 0x40, 0x19, &rdata, 1); */ | ||||
| 			/* rdata &= 0x07; */ | ||||
| 			/* state->BERScaleMax = ( rdata < 2 ) ? 18 : 19; */ | ||||
| 			state->FirstTimeLock = 0; | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| @@ -1407,8 +1491,44 @@ static int get_ber_t(struct cxd_state *state, u32 *n, u32 *d) | ||||
|  | ||||
| static int get_ber_t2(struct cxd_state *state, u32 *n, u32 *d) | ||||
| { | ||||
| 	u8 BERRegs[4]; | ||||
| 	u8 Scale; | ||||
| 	u8 FECType; | ||||
| 	u8 CodeRate; | ||||
| 	static const u32 nBCHBitsLookup[2][8] = { | ||||
| 		/* R1_2   R3_5   R2_3   R3_4   R4_5   R5_6   R1_3   R2_5 */ | ||||
| 		{7200,  9720,  10800, 11880, 12600, 13320, 5400,  6480}, /* 16K FEC */ | ||||
| 		{32400, 38880, 43200, 48600, 51840, 54000, 21600, 25920} /* 64k FEC */ | ||||
| 	}; | ||||
| 	 | ||||
| 	*n = 0; | ||||
| 	*d = 1; | ||||
| 	freeze_regst(state); | ||||
| 	readregst(state, 0x24, 0x40, BERRegs, 4); | ||||
| 	readregst(state, 0x22, 0x5e, &FECType, 1); | ||||
| 	readregst(state, 0x22, 0x5b, &CodeRate, 1); | ||||
|  | ||||
| 	FECType &= 0x03; | ||||
| 	CodeRate &= 0x07; | ||||
| 	unfreeze_regst(state); | ||||
| 	if (FECType > 1) | ||||
| 		return 0; | ||||
|  | ||||
|  | ||||
| 	readregst(state, 0x20, 0x72, &Scale, 1); | ||||
| 	Scale &= 0x0F; | ||||
|         if (BERRegs[0] & 0x01) { | ||||
| 		state->LastBERNominator = (((u32) BERRegs[1] & 0x3F) << 16) | | ||||
| 			(((u32) BERRegs[2]) << 8) | BERRegs[3]; | ||||
| 		state->LastBERDenominator = nBCHBitsLookup[FECType][CodeRate] << Scale; | ||||
| 		if (state->LastBERNominator < 256 && | ||||
| 		    Scale < state->BERScaleMax) { | ||||
| 			writebitst(state, 0x20, 0x72, Scale + 1, 0x0F); | ||||
| 		} else if (state->LastBERNominator > 512 && Scale > 8) | ||||
| 			writebitst(state, 0x20, 0x72, Scale - 1, 0x0F); | ||||
| 	} | ||||
| 	*n = state->LastBERNominator; | ||||
| 	*d = state->LastBERDenominator; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -1458,7 +1578,7 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber) | ||||
| { | ||||
| 	struct cxd_state *state = fe->demodulator_priv; | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
| 	u32 n, d; | ||||
| 	u32 n = 0, d = 1; | ||||
| 	int s = 0; | ||||
|  | ||||
| 	*ber = 0; | ||||
| @@ -1504,57 +1624,63 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static s32 Log10x100(u32 x) | ||||
| { | ||||
| 	static u32 LookupTable[100] = { | ||||
| 		101157945, 103514217, 105925373, 108392691, 110917482, | ||||
| 		113501082, 116144861, 118850223, 121618600, 124451461, | ||||
| 		127350308, 130316678, 133352143, 136458314, 139636836, | ||||
| 		142889396, 146217717, 149623566, 153108746, 156675107, | ||||
| 		160324539, 164058977, 167880402, 171790839, 175792361, | ||||
| 		179887092, 184077200, 188364909, 192752491, 197242274, | ||||
| 		201836636, 206538016, 211348904, 216271852, 221309471, | ||||
| 		226464431, 231739465, 237137371, 242661010, 248313311, | ||||
| 		254097271, 260015956, 266072506, 272270131, 278612117, | ||||
| 		285101827, 291742701, 298538262, 305492111, 312607937, | ||||
| 		319889511, 327340695, 334965439, 342767787, 350751874, | ||||
| 		358921935, 367282300, 375837404, 384591782, 393550075, | ||||
| 		402717034, 412097519, 421696503, 431519077, 441570447, | ||||
| 		451855944, 462381021, 473151259, 484172368, 495450191, | ||||
| 		506990708, 518800039, 530884444, 543250331, 555904257, | ||||
| 		568852931, 582103218, 595662144, 609536897, 623734835, | ||||
| 		638263486, 653130553, 668343918, 683911647, 699841996, | ||||
| 		716143410, 732824533, 749894209, 767361489, 785235635, | ||||
| 		803526122, 822242650, 841395142, 860993752, 881048873, | ||||
| 		901571138, 922571427, 944060876, 966050879, 988553095, | ||||
| 	}; | ||||
| 	s32 y; | ||||
| 	int i; | ||||
|  | ||||
| 	if (x == 0) | ||||
| 		return 0; | ||||
| 	y = 800; | ||||
| 	if (x >= 1000000000) { | ||||
| 		x /= 10; | ||||
| 		y += 100; | ||||
| 	} | ||||
|  | ||||
| 	while (x < 100000000) { | ||||
| 		x *= 10; | ||||
| 		y -= 100; | ||||
| 	} | ||||
| 	i = 0; | ||||
| 	while (i < 100 && x > LookupTable[i]) | ||||
| 		i += 1; | ||||
| 	y += i; | ||||
| 	return y; | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| +NTSTATUS CCXD2843ER::GetT2PLPIds(DD_T2_PLPIDS* pT2_PLPIDS) | ||||
|  { | ||||
|      NTSTATUS status = STATUS_SUCCESS; | ||||
| -    *pReturned = 0; | ||||
| + | ||||
|      if( m_DemodState != ActiveT2 ) return STATUS_NOT_IMPLEMENTED; | ||||
| -    if( m_LastLockStatus < TSLock || m_LastLockStatus == Unlock ) return status; | ||||
| +    if( m_LastLockStatus < TSLock ) return status; | ||||
|   | ||||
|      do | ||||
|      { | ||||
| +        BYTE tmp; | ||||
| + | ||||
|          CHK_ERROR(FreezeRegsT()); | ||||
|   | ||||
| +        CHK_ERROR(ReadRegT(0x20,0x5C,&tmp)); // OFDM Info | ||||
| + | ||||
| +        if( tmp & 0x20 ) pT2_PLPIDS->Flags |= DD_T2_PLPIDS_FEF; | ||||
| +        if( m_T2Profile == T2P_Lite ) pT2_PLPIDS->Flags |= DD_T2_PLPIDS_LITE; | ||||
| + | ||||
| +        CHK_ERROR(ReadRegT(0x22,0x54,&tmp)); | ||||
| +        pT2_PLPIDS->PLPID = tmp; | ||||
| + | ||||
| +        CHK_ERROR(ReadRegT(0x22,0x54 + 19 + 13,&tmp));    // Interval | ||||
| +        if( tmp > 0 ) | ||||
| +        { | ||||
| +            CHK_ERROR(ReadRegT(0x22,0x54 + 19,&tmp)); | ||||
| +            pT2_PLPIDS->CommonPLPID = tmp; | ||||
| +        } | ||||
| + | ||||
|          BYTE nPids = 0; | ||||
|          CHK_ERROR(ReadRegT(0x22,0x7F,&nPids)); | ||||
|   | ||||
| -        pValues[0] = nPids; | ||||
| -        if( nPids >= nValues ) nPids = BYTE(nValues-1); | ||||
| +        pT2_PLPIDS->NumPLPS = nPids; | ||||
| +        CHK_ERROR(ReadRegT(0x22,0x80,&pT2_PLPIDS->PLPList[0], nPids > 128 ? 128 : nPids)); | ||||
|   | ||||
| -        CHK_ERROR(ReadRegT(0x22,0x80,&pValues[1], nPids > 128 ? 128 : nPids)); | ||||
| - | ||||
|          if( nPids > 128 ) | ||||
|          { | ||||
| -            CHK_ERROR(ReadRegT(0x23,0x10,&pValues[129], nPids - 128)); | ||||
| +            CHK_ERROR(ReadRegT(0x23,0x10,&pT2_PLPIDS->PLPList[128], nPids - 128)); | ||||
|          } | ||||
|   | ||||
| -        *pReturned = nPids + 1; | ||||
| + | ||||
|      } | ||||
|      while(0); | ||||
|      UnFreezeRegsT(); | ||||
|  | ||||
| static void GetPLPIds(struct cxd_state *state, u32 nValues, | ||||
| 		      u8 *Values, u32 *Returned) | ||||
| { | ||||
| 	u8 nPids = 0; | ||||
| 	u8 nPids = 0, tmp; | ||||
|  | ||||
| 	*Returned = 0; | ||||
| 	if (state->state != ActiveT2) | ||||
| @@ -1780,6 +1906,110 @@ static int get_algo(struct dvb_frontend *fe) | ||||
| 	return DVBFE_ALGO_HW; | ||||
| } | ||||
|  | ||||
| static int get_fe_t2(struct cxd_state *state) | ||||
| { | ||||
| 	struct dvb_frontend *fe = &state->frontend; | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
| 	u8 ofdm[5], modcod[2]; | ||||
| 	 | ||||
| 	freeze_regst(state); | ||||
| 	readregst_unlocked(state, 0x20, 0x5c, ofdm, 5); | ||||
| 	readregst_unlocked(state, 0x22, 0x5b, modcod, 2); | ||||
| 	unfreeze_regst(state); | ||||
| 	 | ||||
|         switch (modcod[0] & 0x07) { | ||||
| 	case 0: | ||||
| 		p->fec_inner = FEC_1_2; | ||||
| 		break; | ||||
| 	case 1: | ||||
| 		p->fec_inner = FEC_3_5; | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		p->fec_inner = FEC_2_3; | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		p->fec_inner = FEC_3_4; | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		p->fec_inner = FEC_4_5; | ||||
| 		break; | ||||
| 	case 5: | ||||
| 		p->fec_inner = FEC_5_6; | ||||
| 		break; | ||||
| 	case 6: | ||||
| 		p->fec_inner = FEC_1_3; | ||||
| 		break; | ||||
| 	case 7: | ||||
| 		p->fec_inner = FEC_2_5; | ||||
| 		break; | ||||
| 	} | ||||
| 	 | ||||
|         switch (modcod[1] & 0x07) { | ||||
| 	case 0: | ||||
| 		p->modulation = QPSK; | ||||
| 		break; | ||||
| 	case 1: | ||||
| 		p->modulation = QAM_16; | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		p->modulation = QAM_64; | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		p->modulation = QAM_256; | ||||
| 		break; | ||||
| 	} | ||||
| 	 | ||||
| 	switch (ofdm[0] & 0x07) { | ||||
| 	case 0: | ||||
| 		p->transmission_mode = TRANSMISSION_MODE_2K; | ||||
| 		break; | ||||
| 	case 1: | ||||
| 		p->transmission_mode = TRANSMISSION_MODE_8K; | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		p->transmission_mode = TRANSMISSION_MODE_4K; | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		p->transmission_mode = TRANSMISSION_MODE_1K; | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		p->transmission_mode = TRANSMISSION_MODE_16K; | ||||
| 		break; | ||||
| 	case 5: | ||||
| 		p->transmission_mode = TRANSMISSION_MODE_32K; | ||||
| 		break; | ||||
| 	case 6: | ||||
| 		p->transmission_mode = TRANSMISSION_MODE_64K; | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
|         switch ((ofdm[1] >> 4) & 0x07) { | ||||
| 	case 0: | ||||
| 		p->guard_interval = GUARD_INTERVAL_1_32; | ||||
| 		break; | ||||
| 	case 1: | ||||
| 		p->guard_interval = GUARD_INTERVAL_1_16; | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		p->guard_interval = GUARD_INTERVAL_1_8; | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		p->guard_interval = GUARD_INTERVAL_1_4; | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		p->guard_interval = GUARD_INTERVAL_1_128; | ||||
| 		break; | ||||
| 	case 5: | ||||
| 		p->guard_interval = GUARD_INTERVAL_19_128; | ||||
| 		break; | ||||
| 	case 6: | ||||
| 		p->guard_interval = GUARD_INTERVAL_19_256; | ||||
| 		break; | ||||
| 	} | ||||
| 	 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int get_fe_t(struct cxd_state *state) | ||||
| { | ||||
| 	struct dvb_frontend *fe = &state->frontend; | ||||
| @@ -1907,6 +2137,7 @@ static int get_frontend(struct dvb_frontend *fe) | ||||
| 		get_fe_t(state); | ||||
| 		break; | ||||
| 	case ActiveT2: | ||||
| 		get_fe_t2(state); | ||||
| 		break; | ||||
| 	case ActiveC: | ||||
| 		get_fe_c(state); | ||||
|   | ||||
| @@ -4866,10 +4866,6 @@ static int drxk_set_parameters (struct dvb_frontend *fe, | ||||
| 				struct dvb_frontend_parameters *p) | ||||
| #endif | ||||
| { | ||||
| #ifndef USE_API3 | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
| 	u32 delsys  = p->delivery_system, old_delsys; | ||||
| #endif | ||||
| 	struct drxk_state *state = fe->demodulator_priv; | ||||
| 	u32 IF; | ||||
|  | ||||
| @@ -4896,7 +4892,7 @@ static int drxk_set_parameters (struct dvb_frontend *fe, | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int drxk_c_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | ||||
| static int drxk_c_get_frontend(struct dvb_frontend *fe) | ||||
| { | ||||
| 	//struct drxk_state *state = fe->demodulator_priv; | ||||
| 	//printk("%s\n", __FUNCTION__); | ||||
| @@ -4990,7 +4986,7 @@ static int drxk_t_sleep(struct dvb_frontend* fe) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int drxk_t_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | ||||
| static int drxk_t_get_frontend(struct dvb_frontend *fe) | ||||
| { | ||||
| 	//struct drxk_state *state = fe->demodulator_priv; | ||||
| 	//printk("%s\n", __FUNCTION__); | ||||
|   | ||||
| @@ -193,7 +193,8 @@ static int read_register_unlocked(struct mxl *state, u32 reg, u32 *val) | ||||
| 	if (stat) | ||||
| 		pr_err("i2c read error 1\n"); | ||||
| 	if (!stat) | ||||
| 		stat = i2cread(state, (u8 *) val, MXL_HYDRA_REG_SIZE_IN_BYTES); | ||||
| 		stat = i2cread(state, (u8 *) val, | ||||
| 			       MXL_HYDRA_REG_SIZE_IN_BYTES); | ||||
| 	le32_to_cpus(val); | ||||
| 	if (stat) | ||||
| 		pr_err("i2c read error 2\n"); | ||||
| @@ -218,7 +219,8 @@ static int send_command(struct mxl *state, u32 size, u8 *buf) | ||||
| 			mutex_unlock(&state->base->i2c_lock); | ||||
| 			usleep_range(1000, 2000); | ||||
| 			mutex_lock(&state->base->i2c_lock); | ||||
| 			read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR, &val); | ||||
| 			read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR, | ||||
| 					       &val); | ||||
| 		} | ||||
| 		if (!count) { | ||||
| 			pr_info("mxl5xx: send_command busy\n"); | ||||
| @@ -247,7 +249,8 @@ static int write_register(struct mxl *state, u32 reg, u32 val) | ||||
| 	return stat; | ||||
| } | ||||
|  | ||||
| static int write_register_block(struct mxl *state, u32 reg, u32 size, u8 *data) | ||||
| static int write_register_block(struct mxl *state, u32 reg, | ||||
| 				u32 size, u8 *data) | ||||
| { | ||||
| 	int stat; | ||||
| 	u8 *buf = state->base->buf; | ||||
| @@ -308,7 +311,8 @@ static int read_register(struct mxl *state, u32 reg, u32 *val) | ||||
| 	if (stat) | ||||
| 		pr_err("i2c read error 1\n"); | ||||
| 	if (!stat) | ||||
| 		stat = i2cread(state, (u8 *) val, MXL_HYDRA_REG_SIZE_IN_BYTES); | ||||
| 		stat = i2cread(state, (u8 *) val, | ||||
| 			       MXL_HYDRA_REG_SIZE_IN_BYTES); | ||||
| 	mutex_unlock(&state->base->i2c_lock); | ||||
| 	le32_to_cpus(val); | ||||
| 	if (stat) | ||||
| @@ -443,8 +447,10 @@ static int CfgDemodAbortTune(struct mxl *state) | ||||
| 	u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN]; | ||||
| 	 | ||||
| 	abortTuneCmd.demodId = state->demod; | ||||
| 	BUILD_HYDRA_CMD(MXL_HYDRA_ABORT_TUNE_CMD, MXL_CMD_WRITE, cmdSize, &abortTuneCmd, cmdBuff); | ||||
| 	return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); | ||||
| 	BUILD_HYDRA_CMD(MXL_HYDRA_ABORT_TUNE_CMD, MXL_CMD_WRITE, | ||||
| 			cmdSize, &abortTuneCmd, cmdBuff); | ||||
| 	return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, | ||||
| 			    &cmdBuff[0]); | ||||
| } | ||||
|  | ||||
| static int reset_fec_counter(struct mxl *state) | ||||
| @@ -456,7 +462,8 @@ static int reset_fec_counter(struct mxl *state) | ||||
| 	 | ||||
| 	BUILD_HYDRA_CMD(MXL_HYDRA_DEMOD_RESET_FEC_COUNTER_CMD, | ||||
| 			MXL_CMD_WRITE, cmdSize, &demodIndex, cmdBuff); | ||||
| 	return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); | ||||
| 	return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, | ||||
| 			    &cmdBuff[0]); | ||||
| } | ||||
|  | ||||
| static int send_master_cmd(struct dvb_frontend *fe, | ||||
| @@ -517,14 +524,16 @@ static int set_parameters(struct dvb_frontend *fe) | ||||
| 	demodChanCfg.fecCodeRate = MXL_HYDRA_FEC_AUTO; | ||||
|  | ||||
| 	mutex_lock(&state->base->tune_lock); | ||||
| 	if (time_after(jiffies + msecs_to_jiffies(200), state->base->next_tune)) | ||||
| 	if (time_after(jiffies + msecs_to_jiffies(200), | ||||
| 		       state->base->next_tune)) | ||||
| 		while (time_before(jiffies, state->base->next_tune)) | ||||
| 			msleep(10); | ||||
| 	state->base->next_tune = jiffies + msecs_to_jiffies(100); | ||||
| 	state->tuner_in_use = state->tuner; | ||||
| 	BUILD_HYDRA_CMD(MXL_HYDRA_DEMOD_SET_PARAM_CMD, MXL_CMD_WRITE, | ||||
| 			cmdSize, &demodChanCfg, cmdBuff); | ||||
| 	stat = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); | ||||
| 	stat = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, | ||||
| 			    &cmdBuff[0]); | ||||
| 	mutex_unlock(&state->base->tune_lock); | ||||
| 	return stat; | ||||
| } | ||||
| @@ -634,7 +643,7 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber) | ||||
| { | ||||
| 	struct mxl *state = fe->demodulator_priv; | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
| 	u32 reg[8], reg2[4]; | ||||
| 	u32 reg[8], reg2[4], n = 0, d = 0; | ||||
| 	int stat; | ||||
| 	 | ||||
| 	*ber = 0; | ||||
| @@ -645,11 +654,12 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber) | ||||
| 				    HYDRA_DMD_STATUS_OFFSET(state->demod)), | ||||
| 				   (7 * sizeof(u32)), | ||||
| 				   (u8 *) ®[0]); | ||||
| 	stat = read_register_block(state, | ||||
| 				   (HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET + | ||||
| 				    HYDRA_DMD_STATUS_OFFSET(state->demod)), | ||||
| 				   (4 * sizeof(u32)), | ||||
| 				   (u8 *) ®2[0]); | ||||
| 	stat = read_register_block( | ||||
| 		state, | ||||
| 		(HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET + | ||||
| 		 HYDRA_DMD_STATUS_OFFSET(state->demod)), | ||||
| 		(4 * sizeof(u32)), | ||||
| 		(u8 *) ®2[0]); | ||||
| 	HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); | ||||
| 	mutex_unlock(&state->base->status_lock); | ||||
| 	 | ||||
| @@ -670,9 +680,9 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber) | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	pr_info("mxl5xx: ber %08x %08x %08x %08x %08x %08x %08x\n", | ||||
| 	pr_debug("mxl5xx: ber %08x %08x %08x %08x %08x %08x %08x\n", | ||||
| 		reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6]); | ||||
| 	pr_info("mxl5xx: ber2 %08x %08x %08x %08x\n", | ||||
| 	pr_debug("mxl5xx: ber2 %08x %08x %08x %08x\n", | ||||
| 		reg[0], reg[1], reg[2], reg[3]); | ||||
|         //pre_bit_error, pre_bit_count | ||||
| 	//post_bit_error, post_bit_count; | ||||
| @@ -755,7 +765,7 @@ static int get_frontend(struct dvb_frontend *fe) | ||||
| 	HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod); | ||||
| 	mutex_unlock(&state->base->status_lock); | ||||
| 	 | ||||
| 	pr_info("mxl5xx: freq=%u delsys=%u srate=%u\n", | ||||
| 	pr_debug("mxl5xx: freq=%u delsys=%u srate=%u\n", | ||||
| 		freq * 1000, regData[DMD_STANDARD_ADDR], | ||||
| 		regData[DMD_SYMBOL_RATE_ADDR]); | ||||
| 	p->symbol_rate = regData[DMD_SYMBOL_RATE_ADDR]; | ||||
| @@ -769,7 +779,8 @@ static int get_frontend(struct dvb_frontend *fe) | ||||
| 	case SYS_DSS: | ||||
| 		break; | ||||
| 	case SYS_DVBS2: | ||||
| 		switch ((MXL_HYDRA_PILOTS_E ) regData[DMD_DVBS2_PILOT_ON_OFF_ADDR]) { | ||||
| 		switch ((MXL_HYDRA_PILOTS_E ) | ||||
| 			regData[DMD_DVBS2_PILOT_ON_OFF_ADDR]) { | ||||
| 		case MXL_HYDRA_PILOTS_OFF: | ||||
| 			p->pilot = PILOT_OFF; | ||||
| 			break; | ||||
| @@ -780,7 +791,8 @@ static int get_frontend(struct dvb_frontend *fe) | ||||
| 			break; | ||||
| 		} | ||||
| 	case SYS_DVBS: | ||||
| 		switch ((MXL_HYDRA_MODULATION_E) regData[DMD_MODULATION_SCHEME_ADDR]) { | ||||
| 		switch ((MXL_HYDRA_MODULATION_E) | ||||
| 			regData[DMD_MODULATION_SCHEME_ADDR]) { | ||||
| 		case MXL_HYDRA_MOD_QPSK: | ||||
| 			p->modulation = QPSK; | ||||
| 			break; | ||||
| @@ -790,7 +802,8 @@ static int get_frontend(struct dvb_frontend *fe) | ||||
| 		default: | ||||
| 			break; | ||||
| 		} | ||||
| 		switch ((MXL_HYDRA_ROLLOFF_E) regData[DMD_SPECTRUM_ROLL_OFF_ADDR]) { | ||||
| 		switch ((MXL_HYDRA_ROLLOFF_E) | ||||
| 			regData[DMD_SPECTRUM_ROLL_OFF_ADDR]) { | ||||
| 		case MXL_HYDRA_ROLLOFF_0_20: | ||||
| 			p->rolloff = ROLLOFF_20; | ||||
| 			break; | ||||
| @@ -903,12 +916,14 @@ static int write_fw_segment(struct mxl *state, | ||||
| 	u32 origSize = 0; | ||||
| 	u8 *wBufPtr = NULL; | ||||
| 	u32 blockSize = ((MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH - | ||||
| 			  (MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4; | ||||
| 			  (MXL_HYDRA_I2C_HDR_SIZE + | ||||
| 			   MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4; | ||||
| 	u8 wMsgBuffer[MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH - | ||||
| 		      (MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)]; | ||||
|  | ||||
| 	do { | ||||
| 		size = origSize = (((u32)(dataCount + blockSize)) > totalSize) ? | ||||
| 		size = origSize = | ||||
| 			(((u32)(dataCount + blockSize)) > totalSize) ? | ||||
| 			(totalSize - dataCount) : blockSize; | ||||
| 		 | ||||
| 		if (origSize & 3)  | ||||
| @@ -929,8 +944,8 @@ static int write_fw_segment(struct mxl *state, | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr, u32 mbinBufferSize) | ||||
| 				 | ||||
| static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr, | ||||
| 				u32 mbinBufferSize) | ||||
| { | ||||
| 	int status; | ||||
| 	u32 index = 0; | ||||
| @@ -955,26 +970,31 @@ static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr, u32 mbinBu | ||||
| 			       __func__, segmentPtr->header.id); | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
| 		segLength  = get_big_endian(24, &(segmentPtr->header.len24[0])); | ||||
| 		segAddress = get_big_endian(32, &(segmentPtr->header.address[0])); | ||||
| 		segLength  = get_big_endian(24, | ||||
| 					    &(segmentPtr->header.len24[0])); | ||||
| 		segAddress = get_big_endian(32, | ||||
| 					    &(segmentPtr->header.address[0])); | ||||
| 		 | ||||
| 		if (state->base->type == MXL_HYDRA_DEVICE_568) { | ||||
| 			if ((((segAddress & 0x90760000) == 0x90760000) || | ||||
| 			     ((segAddress & 0x90740000) == 0x90740000)) && | ||||
| 			    (xcpuFwFlag == MXL_FALSE)) { | ||||
| 				SET_REG_FIELD_DATA(PRCM_PRCM_CPU_SOFT_RST_N, 1); | ||||
| 				SET_REG_FIELD_DATA(PRCM_PRCM_CPU_SOFT_RST_N, | ||||
| 						   1); | ||||
| 				msleep(200); | ||||
| 				write_register(state, 0x90720000, 0); | ||||
| 				msleep(10); | ||||
| 				xcpuFwFlag = MXL_TRUE; | ||||
| 			} | ||||
| 			status = write_fw_segment(state, segAddress, | ||||
| 						  segLength, (u8 *) segmentPtr->data); | ||||
| 						  segLength, | ||||
| 						  (u8 *) segmentPtr->data); | ||||
| 		} else { | ||||
| 			if (((segAddress & 0x90760000) != 0x90760000) && | ||||
| 			    ((segAddress & 0x90740000) != 0x90740000)) | ||||
| 				status = write_fw_segment(state, segAddress, | ||||
| 							  segLength, (u8 *) segmentPtr->data); | ||||
| 							  segLength, | ||||
| 							  (u8 *) segmentPtr->data); | ||||
| 		} | ||||
| 		if (status) | ||||
| 			return status; | ||||
| @@ -1037,14 +1057,17 @@ static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len) | ||||
| 	if (status) | ||||
| 		return status; | ||||
|  | ||||
| 	/* Disable clock to Baseband, Wideband, SerDes, Alias ext & Transport modules */ | ||||
| 	status = write_register(state, HYDRA_MODULES_CLK_2_REG, HYDRA_DISABLE_CLK_2); | ||||
| 	/* Disable clock to Baseband, Wideband, SerDes, | ||||
| 	   Alias ext & Transport modules */ | ||||
| 	status = write_register(state, HYDRA_MODULES_CLK_2_REG, | ||||
| 				HYDRA_DISABLE_CLK_2); | ||||
| 	if (status) | ||||
| 		return status; | ||||
| 	/* Clear Software & Host interrupt status - (Clear on read) */ | ||||
| 	status = read_register(state, HYDRA_PRCM_ROOT_CLK_REG, ®Data); | ||||
| 	if (status) | ||||
| 		return status; | ||||
|  | ||||
| 	status = do_firmware_download(state, mbin, mbin_len); | ||||
| 	if (status) | ||||
| 		return status; | ||||
| @@ -1081,13 +1104,15 @@ static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len) | ||||
|  | ||||
| 	pr_info("mxl5xx: Hydra FW alive. Hail!\n"); | ||||
|  | ||||
| 	/* sometimes register values are wrong shortly after first heart beats */ | ||||
| 	/* sometimes register values are wrong shortly | ||||
| 	   after first heart beats */ | ||||
| 	msleep(50); | ||||
|  | ||||
| 	devSkuCfg.skuType = state->base->sku_type; | ||||
| 	BUILD_HYDRA_CMD(MXL_HYDRA_DEV_CFG_SKU_CMD, MXL_CMD_WRITE, | ||||
| 			cmdSize, &devSkuCfg, cmdBuff); | ||||
| 	status = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); | ||||
| 	status = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, | ||||
| 			      &cmdBuff[0]); | ||||
|  | ||||
| 	return status; | ||||
| } | ||||
| @@ -1117,19 +1142,32 @@ static int cfg_ts_pad_mux(struct mxl *state, MXL_BOOL_E enableSerialTS) | ||||
| 	case MXL_HYDRA_DEVICE_541S: | ||||
| 	case MXL_HYDRA_DEVICE_561S: | ||||
| 	case MXL_HYDRA_DEVICE_581S: | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_14_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_15_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_16_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_17_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_18_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_19_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_20_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_21_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_22_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_23_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_24_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_25_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_26_PINMUX_SEL, padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_14_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_15_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_16_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_17_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_18_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_19_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_20_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_21_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_22_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_23_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_24_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_25_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_26_PINMUX_SEL, | ||||
| 					     padMuxValue); | ||||
| 		break; | ||||
|  | ||||
| 	case MXL_HYDRA_DEVICE_544: | ||||
| @@ -1313,7 +1351,7 @@ static int enable_tuner(struct mxl *state, u32 tuner, u32 enable) | ||||
| 	if (!count) | ||||
| 		return -1; | ||||
| 	read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val); | ||||
| 	pr_info("mxl5xx: tuner %u ready = %u\n", tuner , (val >> tuner) & 1); | ||||
| 	/*pr_info("mxl5xx: tuner %u ready = %u\n", tuner , (val >> tuner) & 1);*/ | ||||
| #endif | ||||
| 	 | ||||
| 	return 0; | ||||
| @@ -1348,8 +1386,10 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId, | ||||
| 		{XPT_TS_CLK_PHASE4}, {XPT_TS_CLK_PHASE5}, | ||||
| 		{XPT_TS_CLK_PHASE6}, {XPT_TS_CLK_PHASE7} }; | ||||
| 	MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = { | ||||
| 		{XPT_LSB_FIRST0}, {XPT_LSB_FIRST1}, {XPT_LSB_FIRST2}, {XPT_LSB_FIRST3}, | ||||
| 		{XPT_LSB_FIRST4}, {XPT_LSB_FIRST5}, {XPT_LSB_FIRST6}, {XPT_LSB_FIRST7} }; | ||||
| 		{XPT_LSB_FIRST0}, {XPT_LSB_FIRST1}, | ||||
| 		{XPT_LSB_FIRST2}, {XPT_LSB_FIRST3}, | ||||
| 		{XPT_LSB_FIRST4}, {XPT_LSB_FIRST5}, | ||||
| 		{XPT_LSB_FIRST6}, {XPT_LSB_FIRST7} }; | ||||
| 	MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = { | ||||
| 		{XPT_SYNC_FULL_BYTE0}, {XPT_SYNC_FULL_BYTE1}, | ||||
| 		{XPT_SYNC_FULL_BYTE2}, {XPT_SYNC_FULL_BYTE3}, | ||||
| @@ -1384,16 +1424,17 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId, | ||||
| 	MXL_REG_FIELD_T mxl561_xpt_ts_sync[MXL_HYDRA_DEMOD_ID_6] = { | ||||
| 		{PAD_MUX_DIGIO_25_PINMUX_SEL}, {PAD_MUX_DIGIO_20_PINMUX_SEL}, | ||||
| 		{PAD_MUX_DIGIO_17_PINMUX_SEL}, {PAD_MUX_DIGIO_11_PINMUX_SEL}, | ||||
| 		{PAD_MUX_DIGIO_08_PINMUX_SEL}, {PAD_MUX_DIGIO_03_PINMUX_SEL} }; | ||||
| 		{PAD_MUX_DIGIO_08_PINMUX_SEL}, {PAD_MUX_DIGIO_03_PINMUX_SEL}}; | ||||
| 	MXL_REG_FIELD_T mxl561_xpt_ts_valid[MXL_HYDRA_DEMOD_ID_6] = { | ||||
| 		{PAD_MUX_DIGIO_26_PINMUX_SEL}, {PAD_MUX_DIGIO_19_PINMUX_SEL}, | ||||
| 		{PAD_MUX_DIGIO_18_PINMUX_SEL}, {PAD_MUX_DIGIO_10_PINMUX_SEL}, | ||||
| 		{PAD_MUX_DIGIO_09_PINMUX_SEL}, {PAD_MUX_DIGIO_02_PINMUX_SEL} }; | ||||
| 		{PAD_MUX_DIGIO_09_PINMUX_SEL}, {PAD_MUX_DIGIO_02_PINMUX_SEL}}; | ||||
|  | ||||
| 	demodId = state->base->ts_map[demodId]; | ||||
| 	 | ||||
| 	if (MXL_ENABLE == mpegOutParamPtr->enable) { | ||||
| 		if (mpegOutParamPtr->mpegMode == MXL_HYDRA_MPEG_MODE_PARALLEL)	{ | ||||
| 		if (mpegOutParamPtr->mpegMode == | ||||
| 		    MXL_HYDRA_MPEG_MODE_PARALLEL) { | ||||
| #if 0 | ||||
| 			for (i = MXL_HYDRA_DEMOD_ID_0; i < MXL_HYDRA_DEMOD_MAX; i++) { | ||||
| 				mxlStatus |= MxLWare_Hydra_UpdateByMnemonic(devId, | ||||
| @@ -1527,11 +1568,12 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId, | ||||
| 	} | ||||
|  | ||||
| 	if (mpegOutParamPtr->mpegMode != MXL_HYDRA_MPEG_MODE_PARALLEL) { | ||||
| 		status |= update_by_mnemonic(state, | ||||
| 					     xpt_enable_output[demodId].regAddr, | ||||
| 					     xpt_enable_output[demodId].lsbPos, | ||||
| 					     xpt_enable_output[demodId].numOfBits, | ||||
| 					     mpegOutParamPtr->enable); | ||||
| 		status |= | ||||
| 			update_by_mnemonic(state, | ||||
| 					   xpt_enable_output[demodId].regAddr, | ||||
| 					   xpt_enable_output[demodId].lsbPos, | ||||
| 					   xpt_enable_output[demodId].numOfBits, | ||||
| 					   mpegOutParamPtr->enable); | ||||
| 	} | ||||
| 	return status; | ||||
| } | ||||
| @@ -1569,7 +1611,8 @@ static int config_dis(struct mxl *state, u32 id) | ||||
|  | ||||
| 	BUILD_HYDRA_CMD(MXL_HYDRA_DISEQC_CFG_MSG_CMD, | ||||
| 			MXL_CMD_WRITE, cmdSize, &diseqcMsg, cmdBuff); | ||||
| 	return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]); | ||||
| 	return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, | ||||
| 			    &cmdBuff[0]); | ||||
| } | ||||
|  | ||||
| static int load_fw(struct mxl *state, struct mxl5xx_cfg *cfg) | ||||
|   | ||||
| @@ -36,6 +36,8 @@ | ||||
| #include "stv090x.h" | ||||
| #include "stv090x_priv.h" | ||||
|  | ||||
| /* Max transfer size done by I2C transfer functions */ | ||||
| #define MAX_XFER_SIZE  64 | ||||
| #define ERRCTRL1_DVBS1 0x76 | ||||
| #define ERRCTRL1_DVBS2 0x67 | ||||
|  | ||||
| @@ -728,8 +730,16 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8 | ||||
| { | ||||
| 	const struct stv090x_config *config = state->config; | ||||
| 	int ret; | ||||
| 	u8 buf[2 + count]; | ||||
| 	struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count }; | ||||
| 	u8 buf[MAX_XFER_SIZE]; | ||||
| 	struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, | ||||
| 				   .buf = buf, .len = 2 + count }; | ||||
|  | ||||
| 	if (2 + count > sizeof(buf)) { | ||||
| 		printk(KERN_WARNING | ||||
| 		       "%s: i2c wr reg=%04x: len=%d is too big!\n", | ||||
| 		       KBUILD_MODNAME, reg, count); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| 	buf[0] = reg >> 8; | ||||
| 	buf[1] = reg & 0xff; | ||||
| @@ -2144,7 +2154,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) | ||||
|  | ||||
| 	u32 reg; | ||||
| 	s32 car_step, steps, cur_step, dir, freq, timeout_lock; | ||||
| 	int lock = 0; | ||||
| 	int lock; | ||||
|  | ||||
| 	if (state->srate >= 10000000) | ||||
| 		timeout_lock = timeout_dmd / 3; | ||||
| @@ -2152,100 +2162,97 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd) | ||||
| 		timeout_lock = timeout_dmd / 2; | ||||
|  | ||||
| 	lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */ | ||||
| 	if (!lock) { | ||||
| 		if (state->srate >= 10000000) { | ||||
| 			if (stv090x_chk_tmg(state)) { | ||||
| 				if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) | ||||
| 					goto err; | ||||
| 				if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) | ||||
| 					goto err; | ||||
| 				lock = stv090x_get_dmdlock(state, timeout_dmd); | ||||
| 			} else { | ||||
| 				lock = 0; | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (state->srate <= 4000000) | ||||
| 				car_step = 1000; | ||||
| 			else if (state->srate <= 7000000) | ||||
| 				car_step = 2000; | ||||
| 			else if (state->srate <= 10000000) | ||||
| 				car_step = 3000; | ||||
| 			else | ||||
| 				car_step = 5000; | ||||
| 	if (lock) | ||||
| 		return lock; | ||||
|  | ||||
| 			steps  = (state->search_range / 1000) / car_step; | ||||
| 			steps /= 2; | ||||
| 			steps  = 2 * (steps + 1); | ||||
| 			if (steps < 0) | ||||
| 				steps = 2; | ||||
| 			else if (steps > 12) | ||||
| 				steps = 12; | ||||
|  | ||||
| 			cur_step = 1; | ||||
| 			dir = 1; | ||||
|  | ||||
| 			if (!lock) { | ||||
| 				freq = state->frequency; | ||||
| 				state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate; | ||||
| 				while ((cur_step <= steps) && (!lock)) { | ||||
| 					if (dir > 0) | ||||
| 						freq += cur_step * car_step; | ||||
| 					else | ||||
| 						freq -= cur_step * car_step; | ||||
|  | ||||
| 					/* Setup tuner */ | ||||
| 					if (stv090x_i2c_gate_ctrl(state, 1) < 0) | ||||
| 						goto err; | ||||
|  | ||||
| 					if (state->config->tuner_set_frequency) { | ||||
| 						if (state->config->tuner_set_frequency(fe, freq) < 0) | ||||
| 							goto err_gateoff; | ||||
| 					} | ||||
|  | ||||
| 					if (state->config->tuner_set_bandwidth) { | ||||
| 						if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) | ||||
| 							goto err_gateoff; | ||||
| 					} | ||||
|  | ||||
| 					if (stv090x_i2c_gate_ctrl(state, 0) < 0) | ||||
| 						goto err; | ||||
|  | ||||
| 					msleep(50); | ||||
|  | ||||
| 					if (stv090x_i2c_gate_ctrl(state, 1) < 0) | ||||
| 						goto err; | ||||
|  | ||||
| 					if (state->config->tuner_get_status) { | ||||
| 						if (state->config->tuner_get_status(fe, ®) < 0) | ||||
| 							goto err_gateoff; | ||||
| 					} | ||||
|  | ||||
| 					if (reg) | ||||
| 						dprintk(FE_DEBUG, 1, "Tuner phase locked"); | ||||
| 					else | ||||
| 						dprintk(FE_DEBUG, 1, "Tuner unlocked"); | ||||
|  | ||||
| 					if (stv090x_i2c_gate_ctrl(state, 0) < 0) | ||||
| 						goto err; | ||||
|  | ||||
| 					STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); | ||||
| 					if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) | ||||
| 						goto err; | ||||
| 					if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) | ||||
| 						goto err; | ||||
| 					if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) | ||||
| 						goto err; | ||||
| 					if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) | ||||
| 						goto err; | ||||
| 					lock = stv090x_get_dmdlock(state, (timeout_dmd / 3)); | ||||
|  | ||||
| 					dir *= -1; | ||||
| 					cur_step++; | ||||
| 				} | ||||
| 			} | ||||
| 	if (state->srate >= 10000000) { | ||||
| 		if (stv090x_chk_tmg(state)) { | ||||
| 			if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) | ||||
| 				goto err; | ||||
| 			if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) | ||||
| 				goto err; | ||||
| 			return stv090x_get_dmdlock(state, timeout_dmd); | ||||
| 		} | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (state->srate <= 4000000) | ||||
| 		car_step = 1000; | ||||
| 	else if (state->srate <= 7000000) | ||||
| 		car_step = 2000; | ||||
| 	else if (state->srate <= 10000000) | ||||
| 		car_step = 3000; | ||||
| 	else | ||||
| 		car_step = 5000; | ||||
|  | ||||
| 	steps  = (state->search_range / 1000) / car_step; | ||||
| 	steps /= 2; | ||||
| 	steps  = 2 * (steps + 1); | ||||
| 	if (steps < 0) | ||||
| 		steps = 2; | ||||
| 	else if (steps > 12) | ||||
| 		steps = 12; | ||||
|  | ||||
| 	cur_step = 1; | ||||
| 	dir = 1; | ||||
|  | ||||
| 	freq = state->frequency; | ||||
| 	state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate; | ||||
| 	while ((cur_step <= steps) && (!lock)) { | ||||
| 		if (dir > 0) | ||||
| 			freq += cur_step * car_step; | ||||
| 		else | ||||
| 			freq -= cur_step * car_step; | ||||
|  | ||||
| 		/* Setup tuner */ | ||||
| 		if (stv090x_i2c_gate_ctrl(state, 1) < 0) | ||||
| 			goto err; | ||||
|  | ||||
| 		if (state->config->tuner_set_frequency) { | ||||
| 			if (state->config->tuner_set_frequency(fe, freq) < 0) | ||||
| 				goto err_gateoff; | ||||
| 		} | ||||
|  | ||||
| 		if (state->config->tuner_set_bandwidth) { | ||||
| 			if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0) | ||||
| 				goto err_gateoff; | ||||
| 		} | ||||
|  | ||||
| 		if (stv090x_i2c_gate_ctrl(state, 0) < 0) | ||||
| 			goto err; | ||||
|  | ||||
| 		msleep(50); | ||||
|  | ||||
| 		if (stv090x_i2c_gate_ctrl(state, 1) < 0) | ||||
| 			goto err; | ||||
|  | ||||
| 		if (state->config->tuner_get_status) { | ||||
| 			if (state->config->tuner_get_status(fe, ®) < 0) | ||||
| 				goto err_gateoff; | ||||
| 		} | ||||
|  | ||||
| 		if (reg) | ||||
| 			dprintk(FE_DEBUG, 1, "Tuner phase locked"); | ||||
| 		else | ||||
| 			dprintk(FE_DEBUG, 1, "Tuner unlocked"); | ||||
|  | ||||
| 		if (stv090x_i2c_gate_ctrl(state, 0) < 0) | ||||
| 			goto err; | ||||
|  | ||||
| 		STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c); | ||||
| 		if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0) | ||||
| 			goto err; | ||||
| 		if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0) | ||||
| 			goto err; | ||||
| 		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0) | ||||
| 			goto err; | ||||
| 		if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0) | ||||
| 			goto err; | ||||
| 		lock = stv090x_get_dmdlock(state, (timeout_dmd / 3)); | ||||
|  | ||||
| 		dir *= -1; | ||||
| 		cur_step++; | ||||
| 	} | ||||
| 	return lock; | ||||
|  | ||||
| err_gateoff: | ||||
| @@ -2661,14 +2668,9 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st | ||||
| 			return STV090x_RANGEOK; | ||||
| 		else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000)) | ||||
| 			return STV090x_RANGEOK; | ||||
| 		else | ||||
| 			return STV090x_OUTOFRANGE; /* Out of Range */ | ||||
| 	} else { | ||||
| 	} else | ||||
| 		if (abs(offst_freq) <= ((state->search_range / 2000) + 500)) | ||||
| 			return STV090x_RANGEOK; | ||||
| 		else | ||||
| 			return STV090x_OUTOFRANGE; | ||||
| 	} | ||||
|  | ||||
| 	return STV090x_OUTOFRANGE; | ||||
|  | ||||
| @@ -2787,6 +2789,12 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod | ||||
| 				aclc = car_loop[i].crl_pilots_off_30; | ||||
| 		} | ||||
| 	} else { /* 16APSK and 32APSK */ | ||||
| 		/* | ||||
| 		 * This should never happen in practice, except if | ||||
| 		 * something is really wrong at the car_loop table. | ||||
| 		 */ | ||||
| 		if (i >= 11) | ||||
| 			i = 10; | ||||
| 		if (state->srate <= 3000000) | ||||
| 			aclc = car_loop_apsk_low[i].crl_pilots_on_2; | ||||
| 		else if (state->srate <= 7000000) | ||||
| @@ -3435,6 +3443,48 @@ err: | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static int stv090x_set_pls(struct stv090x_state *state, u8 pls_mode, u32 pls_code) | ||||
| { | ||||
| 	dprintk(FE_DEBUG, 1, "Set PLS code %d (mode %d)", pls_code, pls_mode); | ||||
| 	if (STV090x_WRITE_DEMOD(state, PLROOT2, (pls_mode << 2) | (pls_code >> 16)) < 0) | ||||
| 		goto err; | ||||
| 	if (STV090x_WRITE_DEMOD(state, PLROOT1, (pls_code >> 8) & 0xff) < 0) | ||||
| 		goto err; | ||||
| 	if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code & 0xff) < 0) | ||||
| 		goto err; | ||||
| 	return 0; | ||||
| err: | ||||
| 	dprintk(FE_ERROR, 1, "I/O error"); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static int stv090x_set_mis(struct stv090x_state *state, u32 mis) | ||||
| { | ||||
| 	u32 reg; | ||||
|  | ||||
| 	if (mis == NO_STREAM_ID_FILTER) { | ||||
| 		dprintk(FE_DEBUG, 1, "Disable MIS filtering"); | ||||
| 		reg = STV090x_READ_DEMOD(state, PDELCTRL1); | ||||
| 		STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x00); | ||||
| 		if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) | ||||
| 			goto err; | ||||
| 	} else { | ||||
| 		dprintk(FE_DEBUG, 1, "Enable MIS filtering - %d", mis); | ||||
| 		reg = STV090x_READ_DEMOD(state, PDELCTRL1); | ||||
| 		STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x01); | ||||
| 		if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0) | ||||
| 			goto err; | ||||
| 		if (STV090x_WRITE_DEMOD(state, ISIENTRY, mis & 0xff) < 0) | ||||
| 			goto err; | ||||
| 		if (STV090x_WRITE_DEMOD(state, ISIBITENA, 0xff) < 0) | ||||
| 			goto err; | ||||
| 	} | ||||
| 	return 0; | ||||
| err: | ||||
| 	dprintk(FE_ERROR, 1, "I/O error"); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| #ifndef USE_API3 | ||||
| static enum dvbfe_search stv090x_search(struct dvb_frontend *fe) | ||||
| #else | ||||
| @@ -3443,14 +3493,27 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron | ||||
| { | ||||
| 	struct stv090x_state *state = fe->demodulator_priv; | ||||
| 	struct dtv_frontend_properties *props = &fe->dtv_property_cache; | ||||
|  | ||||
| 	u32 pls = 1; | ||||
| 	 | ||||
| #ifndef USE_API3 | ||||
| 	if (props->frequency == 0) | ||||
| #else | ||||
| 		return DVBFE_ALGO_SEARCH_INVALID; | ||||
| #endif | ||||
|  | ||||
| 	state->delsys = props->delivery_system; | ||||
| 	switch (props->delivery_system) { | ||||
| 	case SYS_DSS: | ||||
| 		state->delsys = STV090x_DSS; | ||||
| 		break; | ||||
| 	case SYS_DVBS: | ||||
| 		state->delsys = STV090x_DVBS1; | ||||
| 		break; | ||||
| 	case SYS_DVBS2: | ||||
| 		state->delsys = STV090x_DVBS2; | ||||
| 		break; | ||||
| 	default: | ||||
| 		return DVBFE_ALGO_SEARCH_INVALID; | ||||
| 	} | ||||
| #ifndef USE_API3 | ||||
| 	state->frequency = props->frequency; | ||||
| 	state->srate = props->symbol_rate; | ||||
| @@ -3469,6 +3532,16 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron | ||||
| 		state->search_range = 5000000; | ||||
| 	} | ||||
|  | ||||
| 	/* Backwards compatibility to "crazy" API. | ||||
| 	   PRBS X root cannot be 0, so this should always work.	*/ | ||||
|         if ((props->stream_id != NO_STREAM_ID_FILTER) && | ||||
| 	    (props->stream_id & 0xffffff00))  | ||||
| 			pls = props->stream_id >> 8; | ||||
|         if (props->pls != NO_SCRAMBLING_CODE)  | ||||
| 		pls = props->pls | 0x40000; /* props->pls is always gold code */ | ||||
| 	stv090x_set_pls(state, (pls >> 18) & 3, pls & 0x3ffff); | ||||
| 	stv090x_set_mis(state, props->stream_id); | ||||
|  | ||||
| 	if (stv090x_algo(state) == STV090x_RANGEOK) { | ||||
| 		dprintk(FE_DEBUG, 1, "Search success!"); | ||||
| 		return DVBFE_ALGO_SEARCH_SUCCESS; | ||||
| @@ -3585,7 +3658,6 @@ static int stv090x_read_ber(struct dvb_frontend *fe, u32 *ber) | ||||
| { | ||||
|         struct stv090x_state *state = fe->demodulator_priv; | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
|  | ||||
|         u32 reg, h, m, l; | ||||
|         enum fe_status status; | ||||
|  | ||||
| @@ -3605,6 +3677,14 @@ static int stv090x_read_ber(struct dvb_frontend *fe, u32 *ber) | ||||
|  | ||||
| 		*ber = ((h << 16) | (m << 8) | l); | ||||
|         } | ||||
| #if 0 | ||||
| 	p->pre_bit_error.len = 1; | ||||
| 	p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER; | ||||
| 	p->pre_bit_error.stat[0].uvalue = n; | ||||
| 	p->pre_bit_count.len = 1; | ||||
| 	p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER; | ||||
| 	p->pre_bit_count.stat[0].uvalue = d; | ||||
| #endif | ||||
|         return 0; | ||||
| } | ||||
|  | ||||
| @@ -3723,6 +3803,9 @@ static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||||
| 	p->strength.stat[0].uvalue = 1000 * (s64) (s32) str; | ||||
| #ifdef DBVALS  | ||||
| 	*strength = str; | ||||
| 	p->strength.len = 1; | ||||
| 	p->strength.stat[0].scale = FE_SCALE_DECIBEL; | ||||
| 	p->strength.stat[0].uvalue = 10 * (s64) str; | ||||
| #else | ||||
| 	*strength = (str + 100) * 0xFFFF / 100; | ||||
| #endif | ||||
| @@ -3813,7 +3896,6 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| #ifdef DBVALS | ||||
| 	*cnr = cnr_db; | ||||
| #endif | ||||
| @@ -3823,7 +3905,7 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | ||||
| static int stv090x_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone) | ||||
| { | ||||
| 	struct stv090x_state *state = fe->demodulator_priv; | ||||
| 	u32 reg; | ||||
| @@ -3921,7 +4003,8 @@ err: | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst) | ||||
| static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, | ||||
| 				     enum fe_sec_mini_cmd burst) | ||||
| { | ||||
| 	struct stv090x_state *state = fe->demodulator_priv; | ||||
| 	u32 reg, idle = 0, fifo_full = 1; | ||||
| @@ -4032,12 +4115,12 @@ static int stv090x_sleep(struct dvb_frontend *fe) | ||||
| 		reg = stv090x_read_reg(state, STV090x_TSTTNR1); | ||||
| 		STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); | ||||
| 		if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) | ||||
| 			goto err; | ||||
| 			goto err_unlock; | ||||
| 		/* power off DiSEqC 1 */ | ||||
| 		reg = stv090x_read_reg(state, STV090x_TSTTNR2); | ||||
| 		STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0); | ||||
| 		if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0) | ||||
| 			goto err; | ||||
| 			goto err_unlock; | ||||
|  | ||||
| 		/* check whether path 2 is already sleeping, that is when | ||||
| 		   ADC2 is off */ | ||||
| @@ -4056,7 +4139,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) | ||||
| 		if (full_standby) | ||||
| 			STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); | ||||
| 		if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) | ||||
| 			goto err; | ||||
| 			goto err_unlock; | ||||
| 		reg = stv090x_read_reg(state, STV090x_STOPCLK2); | ||||
| 		/* sampling 1 clock */ | ||||
| 		STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1); | ||||
| @@ -4067,7 +4150,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) | ||||
| 		if (full_standby) | ||||
| 			STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); | ||||
| 		if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) | ||||
| 			goto err; | ||||
| 			goto err_unlock; | ||||
| 		break; | ||||
|  | ||||
| 	case STV090x_DEMODULATOR_1: | ||||
| @@ -4075,12 +4158,12 @@ static int stv090x_sleep(struct dvb_frontend *fe) | ||||
| 		reg = stv090x_read_reg(state, STV090x_TSTTNR3); | ||||
| 		STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0); | ||||
| 		if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0) | ||||
| 			goto err; | ||||
| 			goto err_unlock; | ||||
| 		/* power off DiSEqC 2 */ | ||||
| 		reg = stv090x_read_reg(state, STV090x_TSTTNR4); | ||||
| 		STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0); | ||||
| 		if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0) | ||||
| 			goto err; | ||||
| 			goto err_unlock; | ||||
|  | ||||
| 		/* check whether path 1 is already sleeping, that is when | ||||
| 		   ADC1 is off */ | ||||
| @@ -4099,7 +4182,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) | ||||
| 		if (full_standby) | ||||
| 			STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1); | ||||
| 		if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0) | ||||
| 			goto err; | ||||
| 			goto err_unlock; | ||||
| 		reg = stv090x_read_reg(state, STV090x_STOPCLK2); | ||||
| 		/* sampling 2 clock */ | ||||
| 		STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1); | ||||
| @@ -4110,7 +4193,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) | ||||
| 		if (full_standby) | ||||
| 			STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1); | ||||
| 		if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0) | ||||
| 			goto err; | ||||
| 			goto err_unlock; | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| @@ -4123,7 +4206,7 @@ static int stv090x_sleep(struct dvb_frontend *fe) | ||||
| 		reg = stv090x_read_reg(state, STV090x_SYNTCTRL); | ||||
| 		STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01); | ||||
| 		if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) | ||||
| 			goto err; | ||||
| 			goto err_unlock; | ||||
| 	} | ||||
|  | ||||
| 	mutex_unlock(&state->internal->demod_lock); | ||||
| @@ -4131,8 +4214,10 @@ static int stv090x_sleep(struct dvb_frontend *fe) | ||||
|  | ||||
| err_gateoff: | ||||
| 	stv090x_i2c_gate_ctrl(state, 0); | ||||
| err: | ||||
| 	goto err; | ||||
| err_unlock: | ||||
| 	mutex_unlock(&state->internal->demod_lock); | ||||
| err: | ||||
| 	dprintk(FE_ERROR, 1, "I/O error"); | ||||
| 	return -1; | ||||
| } | ||||
| @@ -4393,7 +4478,7 @@ err: | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static int stv090x_set_tspath(struct stv090x_state *state) | ||||
| static int stv0900_set_tspath(struct stv090x_state *state) | ||||
| { | ||||
| 	u32 reg; | ||||
|  | ||||
| @@ -4643,8 +4728,6 @@ static int stv090x_set_tspath(struct stv090x_state *state) | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	printk("TSCFGH resets\n"); | ||||
|  | ||||
| 	reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); | ||||
| 	STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); | ||||
| 	if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) | ||||
| @@ -4667,6 +4750,121 @@ err: | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static int stv0903_set_tspath(struct stv090x_state *state) | ||||
| { | ||||
| 	u32 reg; | ||||
|  | ||||
| 	if (state->internal->dev_ver >= 0x20) { | ||||
| 		switch (state->config->ts1_mode) { | ||||
| 		case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||||
| 		case STV090x_TSMODE_DVBCI: | ||||
| 			stv090x_write_reg(state, STV090x_TSGENERAL, 0x00); | ||||
| 			break; | ||||
|  | ||||
| 		case STV090x_TSMODE_SERIAL_PUNCTURED: | ||||
| 		case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||||
| 		default: | ||||
| 			stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c); | ||||
| 			break; | ||||
| 		} | ||||
| 	} else { | ||||
| 		switch (state->config->ts1_mode) { | ||||
| 		case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||||
| 		case STV090x_TSMODE_DVBCI: | ||||
| 			stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10); | ||||
| 			break; | ||||
|  | ||||
| 		case STV090x_TSMODE_SERIAL_PUNCTURED: | ||||
| 		case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||||
| 		default: | ||||
| 			stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	switch (state->config->ts1_mode) { | ||||
| 	case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||||
| 		reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); | ||||
| 		STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); | ||||
| 		STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); | ||||
| 		if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||||
| 			goto err; | ||||
| 		break; | ||||
|  | ||||
| 	case STV090x_TSMODE_DVBCI: | ||||
| 		reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); | ||||
| 		STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); | ||||
| 		STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); | ||||
| 		if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||||
| 			goto err; | ||||
| 		break; | ||||
|  | ||||
| 	case STV090x_TSMODE_SERIAL_PUNCTURED: | ||||
| 		reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); | ||||
| 		STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); | ||||
| 		STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); | ||||
| 		if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||||
| 			goto err; | ||||
| 		break; | ||||
|  | ||||
| 	case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||||
| 		reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); | ||||
| 		STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); | ||||
| 		STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); | ||||
| 		if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||||
| 			goto err; | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
|  | ||||
| 	if (state->config->ts1_clk > 0) { | ||||
| 		u32 speed; | ||||
|  | ||||
| 		switch (state->config->ts1_mode) { | ||||
| 		case STV090x_TSMODE_PARALLEL_PUNCTURED: | ||||
| 		case STV090x_TSMODE_DVBCI: | ||||
| 		default: | ||||
| 			speed = state->internal->mclk / | ||||
| 				(state->config->ts1_clk / 4); | ||||
| 			if (speed < 0x08) | ||||
| 				speed = 0x08; | ||||
| 			if (speed > 0xFF) | ||||
| 				speed = 0xFF; | ||||
| 			break; | ||||
| 		case STV090x_TSMODE_SERIAL_PUNCTURED: | ||||
| 		case STV090x_TSMODE_SERIAL_CONTINUOUS: | ||||
| 			speed = state->internal->mclk / | ||||
| 				(state->config->ts1_clk / 32); | ||||
| 			if (speed < 0x20) | ||||
| 				speed = 0x20; | ||||
| 			if (speed > 0xFF) | ||||
| 				speed = 0xFF; | ||||
| 			break; | ||||
| 		} | ||||
| 		reg = stv090x_read_reg(state, STV090x_P1_TSCFGM); | ||||
| 		STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3); | ||||
| 		if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0) | ||||
| 			goto err; | ||||
| 		if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0) | ||||
| 			goto err; | ||||
| 	} | ||||
|  | ||||
| 	reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); | ||||
| 	STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01); | ||||
| 	if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||||
| 		goto err; | ||||
| 	STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00); | ||||
| 	if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) | ||||
| 		goto err; | ||||
|  | ||||
| 	return 0; | ||||
| err: | ||||
| 	dprintk(FE_ERROR, 1, "I/O error"); | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| static int stv090x_init(struct dvb_frontend *fe) | ||||
| { | ||||
| 	struct stv090x_state *state = fe->demodulator_priv; | ||||
| @@ -4730,8 +4928,13 @@ static int stv090x_init(struct dvb_frontend *fe) | ||||
| 		goto err; | ||||
|  | ||||
| #if 0 | ||||
| 	if (stv090x_set_tspath(state) < 0) | ||||
| 		goto err; | ||||
| 	if (state->device == STV0900) { | ||||
| 		if (stv0900_set_tspath(state) < 0) | ||||
| 			goto err; | ||||
| 	} else { | ||||
| 		if (stv0903_set_tspath(state) < 0) | ||||
| 			goto err; | ||||
| 	} | ||||
| #endif | ||||
| 	return 0; | ||||
|  | ||||
| @@ -4772,23 +4975,26 @@ static int stv090x_setup(struct dvb_frontend *fe) | ||||
| 	/* Stop Demod */ | ||||
| 	if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0) | ||||
| 		goto err; | ||||
| 	if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0) | ||||
| 		goto err; | ||||
| 	if (state->device == STV0900) | ||||
| 		if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0) | ||||
| 			goto err; | ||||
|  | ||||
| 	msleep(5); | ||||
|  | ||||
| 	/* Set No Tuner Mode */ | ||||
| 	if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0) | ||||
| 		goto err; | ||||
| 	if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0) | ||||
| 		goto err; | ||||
| 	if (state->device == STV0900) | ||||
| 		if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0) | ||||
| 			goto err; | ||||
|  | ||||
| 	/* I2C repeater OFF */ | ||||
| 	STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level); | ||||
| 	if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0) | ||||
| 		goto err; | ||||
| 	if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0) | ||||
| 		goto err; | ||||
| 	if (state->device == STV0900) | ||||
| 		if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0) | ||||
| 			goto err; | ||||
|  | ||||
| 	if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */ | ||||
| 		goto err; | ||||
| @@ -4848,8 +5054,13 @@ static int stv090x_setup(struct dvb_frontend *fe) | ||||
| 	if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) | ||||
| 		goto err; | ||||
|  | ||||
| 	if (stv090x_set_tspath(state) < 0) | ||||
| 		goto err; | ||||
| 	if (state->device == STV0900) { | ||||
| 		if (stv0900_set_tspath(state) < 0) | ||||
| 			goto err; | ||||
| 	} else { | ||||
| 		if (stv0903_set_tspath(state) < 0) | ||||
| 			goto err; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| err: | ||||
| @@ -4857,8 +5068,8 @@ err: | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value, | ||||
| 		u8 xor_value) | ||||
| static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, | ||||
| 			    u8 value, u8 xor_value) | ||||
| { | ||||
| 	struct stv090x_state *state = fe->demodulator_priv; | ||||
| 	u8 reg = 0; | ||||
| @@ -4869,7 +5080,69 @@ int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value, | ||||
|  | ||||
| 	return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg); | ||||
| } | ||||
| EXPORT_SYMBOL(stv090x_set_gpio); | ||||
|  | ||||
| static int stv090x_get_frontend(struct dvb_frontend *fe) | ||||
| { | ||||
| 	struct stv090x_state *state = fe->demodulator_priv; | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
| 	u8 tmp; | ||||
| 	u32 reg = 0; | ||||
| 	 | ||||
| 	if (state->rec_mode == 2) { | ||||
| 		u32 mc; | ||||
| 		enum fe_modulation modcod2mod[0x20] = { | ||||
| 			QPSK, QPSK, QPSK, QPSK, | ||||
| 			QPSK, QPSK, QPSK, QPSK, | ||||
| 			QPSK, QPSK, QPSK, QPSK, | ||||
| 			PSK_8, PSK_8, PSK_8, PSK_8, | ||||
| 			PSK_8, PSK_8, APSK_16, APSK_16, | ||||
| 			APSK_16, APSK_16, APSK_16, APSK_16, | ||||
| 			APSK_32, APSK_32, APSK_32, APSK_32, | ||||
| 			APSK_32,  | ||||
| 		}; | ||||
| 		enum fe_code_rate modcod2fec[0x20] = { | ||||
| 			FEC_NONE, FEC_1_4, FEC_1_3, FEC_2_5, | ||||
| 			FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4, | ||||
| 			FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10, | ||||
| 			FEC_3_5, FEC_2_3, FEC_3_4, FEC_5_6, | ||||
| 			FEC_8_9, FEC_9_10, FEC_2_3, FEC_3_4, | ||||
| 			FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10, | ||||
| 			FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9, | ||||
| 			FEC_9_10 | ||||
| 		};		 | ||||
| 		mc = state->modcod; | ||||
| 		p->pilot = (state->pilots & 0x01) ? PILOT_ON : PILOT_OFF; | ||||
| 		p->modulation = modcod2mod[mc]; | ||||
| 		p->fec_inner = modcod2fec[mc];	 | ||||
|         } else if (state->rec_mode == 1) { | ||||
| 		reg = STV090x_READ_DEMOD(state, VITCURPUN); | ||||
| 		switch( reg & 0x1F ) { | ||||
|                 case 0x0d: | ||||
| 			p->fec_inner = FEC_1_2; | ||||
| 			break; | ||||
|                 case 0x12: | ||||
| 			p->fec_inner = FEC_2_3; | ||||
| 			break; | ||||
|                 case 0x15: | ||||
| 			p->fec_inner = FEC_3_4; | ||||
| 			break; | ||||
|                 case 0x18: | ||||
| 			p->fec_inner = FEC_5_6; | ||||
| 			break; | ||||
|                 case 0x1a: | ||||
| 			p->fec_inner = FEC_7_8; | ||||
| 			break; | ||||
| 		default: | ||||
| 			p->fec_inner = FEC_NONE; | ||||
| 			break; | ||||
| 		} | ||||
| 		p->rolloff = ROLLOFF_35; | ||||
| 	} else { | ||||
| 		 | ||||
| 	} | ||||
| 	 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int get_frontend(struct dvb_frontend *fe) | ||||
| { | ||||
| @@ -4960,7 +5233,7 @@ static struct dvb_frontend_ops stv090x_ops = { | ||||
|  | ||||
| 	.sleep				= stv090x_sleep, | ||||
| 	.get_frontend_algo		= stv090x_frontend_algo, | ||||
| 	.get_frontend                   = get_frontend, | ||||
| 	.get_frontend                   = stv090x_get_frontend, | ||||
|  | ||||
| 	.diseqc_send_master_cmd		= stv090x_send_diseqc_msg, | ||||
| 	.diseqc_send_burst		= stv090x_send_diseqc_burst, | ||||
| @@ -4976,7 +5249,7 @@ static struct dvb_frontend_ops stv090x_ops = { | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | ||||
| struct dvb_frontend *stv090x_attach(struct stv090x_config *config, | ||||
| 				    struct i2c_adapter *i2c, | ||||
| 				    enum stv090x_demodulator demod) | ||||
| { | ||||
| @@ -5030,10 +5303,15 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (state->internal->dev_ver >= 0x30) | ||||
| 		state->frontend.ops.info.caps |= FE_CAN_MULTISTREAM; | ||||
|  | ||||
| 	/* workaround for stuck DiSEqC output */ | ||||
| 	if (config->diseqc_envelope_mode) | ||||
| 		stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A); | ||||
|  | ||||
| 	config->set_gpio = stv090x_set_gpio; | ||||
|  | ||||
| 	dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x", | ||||
| 	       state->device == STV0900 ? "STV0900" : "STV0903", | ||||
| 	       demod, | ||||
|   | ||||
| @@ -101,18 +101,18 @@ struct stv090x_config { | ||||
| 	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); | ||||
|  | ||||
|         /* dir = 0 -> output, dir = 1 -> input/open-drain */ | ||||
| 	int (*set_gpio)(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value, | ||||
| 			u8 xor_value); | ||||
| }; | ||||
|  | ||||
| #if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE)) | ||||
|  | ||||
| extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | ||||
| extern struct dvb_frontend *stv090x_attach(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, | ||||
| @@ -123,12 +123,6 @@ static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *c | ||||
| 	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 */ | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| /* | ||||
|  * Driver for the ST STV0910 DVB-S/S2 demodulator. | ||||
|  * | ||||
|  * Copyright (C) 2014-2015 Ralph Metzler <rjkm@metzlerbros.de> | ||||
|  * Copyright (C) 2014-2016 Ralph Metzler <rjkm@metzlerbros.de> | ||||
|  *                         Marcus Metzler <mocm@metzlerbros.de> | ||||
|  *                         developed for Digital Devices GmbH | ||||
|  * | ||||
| @@ -38,6 +38,7 @@ | ||||
| #include "stv0910_regs.h" | ||||
|  | ||||
|  | ||||
| #define EXT_CLOCK   30000000 | ||||
| #define TUNING_DELAY    200 | ||||
| #define BER_SRC_S    0x20 | ||||
| #define BER_SRC_S2   0x20 | ||||
| @@ -123,9 +124,17 @@ struct stv { | ||||
| 	u32                     Pilots; | ||||
| 	enum FE_STV0910_RollOff FERollOff; | ||||
|  | ||||
| 	int   isStandardBroadcast; | ||||
| 	int   isVCM; | ||||
| 	 | ||||
| 	u32   CurScramblingCode; | ||||
| 	u32   ScramblingCode; | ||||
| 	 | ||||
| 	u32   LastBERNumerator; | ||||
| 	u32   LastBERDenominator; | ||||
| 	u8    BERScale; | ||||
|  | ||||
| 	u8    VTH[6]; | ||||
| }; | ||||
|  | ||||
| struct SInitTable { | ||||
| @@ -193,6 +202,19 @@ static int read_regs(struct stv *state, u16 reg, u8 *val, int len) | ||||
| 			       reg, val, len); | ||||
| } | ||||
|  | ||||
| static int write_shared_reg(struct stv *state, u16 reg, u8 mask, u8 val) | ||||
| { | ||||
| 	int status; | ||||
| 	u8 tmp; | ||||
|  | ||||
| 	mutex_lock(&state->base->reg_lock); | ||||
| 	status = read_reg(state, reg, &tmp); | ||||
| 	if (!status) | ||||
| 		status = write_reg(state, reg, (tmp & ~mask) | (val & mask)); | ||||
| 	mutex_unlock(&state->base->reg_lock); | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| struct SLookup S1_SN_Lookup[] = { | ||||
| 	{   0,    9242  },  /*C/N=  0dB*/ | ||||
| 	{  05,    9105  },  /*C/N=0.5dB*/ | ||||
| @@ -452,24 +474,45 @@ static int GetCurSymbolRate(struct stv *state, u32 *pSymbolRate) | ||||
|  | ||||
| static int GetSignalParameters(struct stv *state) | ||||
| { | ||||
| 	u8 tmp; | ||||
| 	 | ||||
| 	if (!state->Started) | ||||
| 		return -1; | ||||
|  | ||||
| 	 | ||||
| 	if (state->ReceiveMode == Mode_DVBS2) { | ||||
| 		u8 tmp; | ||||
| 		u8 rolloff; | ||||
|  | ||||
| 		read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp); | ||||
| 		state->ModCod = (enum FE_STV0910_ModCod) ((tmp & 0x7c) >> 2); | ||||
| 		state->Pilots = (tmp & 0x01) != 0; | ||||
| 		state->FECType = (enum DVBS2_FECType) ((tmp & 0x02) >> 1); | ||||
|  | ||||
| #if 0 | ||||
| 		read_reg(state, RSTV0910_P2_TMGOBS + state->regoff, &rolloff); | ||||
| 		rolloff = rolloff >> 6; | ||||
| 		state->FERollOff = (enum FE_STV0910_RollOff) rolloff; | ||||
|  | ||||
| #endif | ||||
| 	} else if (state->ReceiveMode == Mode_DVBS) { | ||||
| 		/* todo */ | ||||
| 		read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp); | ||||
| 		state->PunctureRate = FEC_NONE; | ||||
| 		switch (tmp & 0x1F) { | ||||
| 		case 0x0d: | ||||
| 			state->PunctureRate = FEC_1_2; | ||||
| 			break; | ||||
| 		case 0x12: | ||||
| 			state->PunctureRate = FEC_2_3; | ||||
| 			break; | ||||
| 		case 0x15: | ||||
| 			state->PunctureRate = FEC_3_4; | ||||
| 			break; | ||||
| 		case 0x18: | ||||
| 			state->PunctureRate = FEC_5_6; | ||||
| 			break; | ||||
| 		case 0x1A: | ||||
| 			state->PunctureRate = FEC_7_8; | ||||
| 			break; | ||||
| 		} | ||||
| 		state->isVCM = 0; | ||||
| 		state->isStandardBroadcast = 1; | ||||
| 		state->FERollOff = FE_SAT_35; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| @@ -485,18 +528,20 @@ static int TrackingOptimization(struct stv *state) | ||||
|  | ||||
| 	switch (state->ReceiveMode) { | ||||
| 	case Mode_DVBS: | ||||
| 		tmp |= 0x40; break; | ||||
| 		tmp |= 0x40; | ||||
| 		break; | ||||
| 	case Mode_DVBS2: | ||||
| 		tmp |= 0x80; break; | ||||
| 		tmp |= 0x80; | ||||
| 		break; | ||||
| 	default: | ||||
| 		tmp |= 0xC0; break; | ||||
| 		tmp |= 0xC0; | ||||
| 		break; | ||||
| 	} | ||||
| 	write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, tmp); | ||||
|  | ||||
| 	if (state->ReceiveMode == Mode_DVBS2) { | ||||
| 		/* force to PRE BCH Rate */ | ||||
| 		write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff, | ||||
| 			  BER_SRC_S2 | state->BERScale); | ||||
| 		/*Disable Reed-Solomon */   | ||||
| 		write_shared_reg(state, RSTV0910_TSTTSRS, state->nr ? 0x02 : 0x01, 0x03); | ||||
|  | ||||
| 		if (state->FECType == DVBS2_64K) { | ||||
| 			u8 aclc = get_optim_cloop(state, state->ModCod, | ||||
| @@ -523,29 +568,6 @@ static int TrackingOptimization(struct stv *state) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if (state->ReceiveMode == Mode_DVBS) { | ||||
| 		u8 tmp; | ||||
|  | ||||
| 		read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp); | ||||
| 		state->PunctureRate = FEC_NONE; | ||||
| 		switch (tmp & 0x1F) { | ||||
| 		case 0x0d: | ||||
| 			state->PunctureRate = FEC_1_2; | ||||
| 			break; | ||||
| 		case 0x12: | ||||
| 			state->PunctureRate = FEC_2_3; | ||||
| 			break; | ||||
| 		case 0x15: | ||||
| 			state->PunctureRate = FEC_3_4; | ||||
| 			break; | ||||
| 		case 0x18: | ||||
| 			state->PunctureRate = FEC_5_6; | ||||
| 			break; | ||||
| 		case 0x1A: | ||||
| 			state->PunctureRate = FEC_7_8; | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -558,7 +580,7 @@ static s32 TableLookup(struct SLookup *Table, | ||||
| 	int i; | ||||
| 	s32 RegDiff; | ||||
| 	 | ||||
| 	// Assumes Table[0].RegValue > Table[imax].RegValue  | ||||
| 	/* Assumes Table[0].RegValue > Table[imax].RegValue */ | ||||
| 	if( RegValue >= Table[0].RegValue ) | ||||
| 		Value = Table[0].Value; | ||||
| 	else if( RegValue <= Table[imax].RegValue ) | ||||
| @@ -686,11 +708,12 @@ static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType) | ||||
| 	return 64800; | ||||
| } | ||||
|  | ||||
| static int GetBitErrorRateS2(struct stv *state, u32 *BERNumerator, | ||||
| static int GetBitErrorRateS2(struct stv *state, | ||||
| 			     u32 *BERNumerator, | ||||
| 			     u32 *BERDenominator) | ||||
| { | ||||
| 	u8 Regs[3]; | ||||
|  | ||||
| 	 | ||||
| 	int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff, | ||||
| 			       Regs, 3); | ||||
|  | ||||
| @@ -828,12 +851,118 @@ static int Stop(struct stv *state) | ||||
| } | ||||
|  | ||||
|  | ||||
| static int init_search_param(struct stv *state) | ||||
| { | ||||
| 	u8 tmp; | ||||
| 	 | ||||
| 	read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp); | ||||
|         tmp |= 0x20; // Filter_en (no effect if SIS=non-MIS | ||||
| 	write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp); | ||||
| 	 | ||||
| 	read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, &tmp); | ||||
|         tmp &= ~0x02; // frame mode = 0 | ||||
| 	write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, tmp); | ||||
| 	 | ||||
| 	write_reg(state, RSTV0910_P2_UPLCCST0 + state->regoff, 0xe0); | ||||
| 	write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0x00); | ||||
|  | ||||
| 	read_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, &tmp); | ||||
|         tmp &= ~0x01;	// nosync = 0, in case next signal is standard TS | ||||
| 	write_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, tmp); | ||||
| 	 | ||||
| 	read_reg(state, RSTV0910_P2_TSCFGL + state->regoff, &tmp); | ||||
|         tmp &= ~0x04;	// embindvb = 0 | ||||
| 	write_reg(state, RSTV0910_P2_TSCFGL + state->regoff, tmp); | ||||
| 	 | ||||
| 	read_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, &tmp); | ||||
|         tmp &= ~0x80;	// syncbyte = 0 | ||||
| 	write_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, tmp); | ||||
| 	 | ||||
| 	read_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, &tmp); | ||||
|         tmp &= ~0x08;	// token = 0 | ||||
| 	write_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, tmp); | ||||
| 	 | ||||
| 	read_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, &tmp); | ||||
|         tmp &= ~0x30;	// hysteresis threshold = 0 | ||||
| 	write_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, tmp); | ||||
| 	 | ||||
| 	read_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, &tmp); | ||||
|         tmp = (tmp & ~0x30) | 0x10;	// isi obs mode = 1, observe min ISI | ||||
| 	write_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, tmp); | ||||
| 	 | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int EnablePunctureRate(struct stv *state, enum fe_code_rate rate) | ||||
| { | ||||
| 	switch(rate) { | ||||
|         case FEC_1_2:  | ||||
| 		return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x01); | ||||
|         case FEC_2_3:  | ||||
| 		return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x02); | ||||
|         case FEC_3_4:  | ||||
| 		return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x04); | ||||
|         case FEC_5_6:  | ||||
| 		return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x08); | ||||
|         case FEC_7_8:  | ||||
| 		return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x20); | ||||
|         case FEC_NONE:  | ||||
|         default: | ||||
| 		return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2f); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static int set_vth_default(struct stv *state) | ||||
| { | ||||
| 	state->VTH[0] = 0xd7; | ||||
| 	state->VTH[1] = 0x85; | ||||
| 	state->VTH[2] = 0x58; | ||||
| 	state->VTH[3] = 0x3a; | ||||
| 	state->VTH[4] = 0x34; | ||||
| 	state->VTH[5] = 0x28; | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 0, state->VTH[0]); | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 1, state->VTH[1]); | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 2, state->VTH[2]); | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 3, state->VTH[3]); | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 4, state->VTH[4]); | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 5, state->VTH[5]); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int set_vth(struct stv *state) | ||||
| { | ||||
| 	static struct SLookup VTHLookupTable[] = { | ||||
| 		{250,	8780}, /*C/N=1.5dB*/ | ||||
| 		{100,	7405}, /*C/N=4.5dB*/ | ||||
| 		{40,	6330}, /*C/N=6.5dB*/ | ||||
| 		{12,	5224}, /*C/N=8.5dB*/ | ||||
| 		{5,	4236} /*C/N=10.5dB*/ | ||||
| 	}; | ||||
| 	int i; | ||||
| 	u8 tmp[2]; | ||||
| 	int status = read_regs(state, RSTV0910_P2_NNOSDATAT1 + state->regoff, tmp, 2); | ||||
| 	u16 RegValue = (tmp[0] << 8) | tmp[1]; | ||||
| 	s32 vth = TableLookup(VTHLookupTable, ARRAY_SIZE(VTHLookupTable), RegValue); | ||||
|  | ||||
|         for (i = 0; i < 6; i += 1) | ||||
| 		if (state->VTH[i] > vth) | ||||
| 			state->VTH[i] = vth; | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 0, state->VTH[0]); | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 1, state->VTH[1]); | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 2, state->VTH[2]); | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 3, state->VTH[3]); | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 4, state->VTH[4]); | ||||
| 	write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 5, state->VTH[5]); | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| static int Start(struct stv *state, struct dtv_frontend_properties *p) | ||||
| { | ||||
| 	s32 Freq; | ||||
| 	u8  regDMDCFGMD; | ||||
| 	u16 symb; | ||||
|  | ||||
| 	u32 ScramblingCode = 1; | ||||
| 	 | ||||
| 	if (p->symbol_rate < 100000 || p->symbol_rate > 70000000) | ||||
| 		return -EINVAL; | ||||
|  | ||||
| @@ -844,6 +973,34 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p) | ||||
| 	if (state->Started) | ||||
| 		write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5C); | ||||
|  | ||||
| 	init_search_param(state); | ||||
| 	 | ||||
|         if (p->stream_id != NO_STREAM_ID_FILTER) { | ||||
| 		/* Backwards compatibility to "crazy" API. | ||||
| 		   PRBS X root cannot be 0, so this should always work. | ||||
| 		*/ | ||||
| 		if (p->stream_id & 0xffffff00)  | ||||
| 			ScramblingCode = p->stream_id >> 8; | ||||
| 		write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff, p->stream_id & 0xff); | ||||
| 		write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0xff); | ||||
| 		//pr_info("ID=%08x\n", p->stream_id & 0xff); | ||||
|         } | ||||
|  | ||||
| 	/* props->pls is always gold code ! */ | ||||
|         if (p->pls != NO_SCRAMBLING_CODE) | ||||
| 		ScramblingCode = p->pls | 0x40000;  | ||||
|  | ||||
|         if (ScramblingCode != state->CurScramblingCode) { | ||||
| 		write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff, | ||||
| 			  ScramblingCode & 0xff); | ||||
| 		write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff, | ||||
| 			  (ScramblingCode >> 8) & 0xff); | ||||
| 		write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff, | ||||
| 			  (ScramblingCode >> 16) & 0x07); | ||||
| 		state->CurScramblingCode = ScramblingCode; | ||||
| 		//pr_info("PLS=%08x\n",  ScramblingCode); | ||||
|         } | ||||
|  | ||||
| 	if (p->symbol_rate <= 1000000) {  /*SR <=1Msps*/ | ||||
| 		state->DemodTimeout = 3000; | ||||
| 		state->FecTimeout = 2000; | ||||
| @@ -852,7 +1009,7 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p) | ||||
| 		state->FecTimeout = 1300; | ||||
| 	} else if (p->symbol_rate <= 5000000) {  /*2Msps< SR <=5Msps*/ | ||||
| 		state->DemodTimeout = 1000; | ||||
| 	    state->FecTimeout = 650; | ||||
| 		state->FecTimeout = 650; | ||||
| 	} else if (p->symbol_rate <= 10000000) {  /*5Msps< SR <=10Msps*/ | ||||
| 		state->DemodTimeout = 700; | ||||
| 		state->FecTimeout = 350; | ||||
| @@ -879,25 +1036,43 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p) | ||||
| 	read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, ®DMDCFGMD); | ||||
| 	write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, | ||||
| 		  regDMDCFGMD |= 0xC0); | ||||
|  | ||||
|         write_shared_reg(state, RSTV0910_TSTTSRS, state->nr ? 0x02 : 0x01, 0x00); | ||||
| 	 | ||||
| 	/* Disable DSS */ | ||||
| 	write_reg(state, RSTV0910_P2_FECM  + state->regoff, 0x00); | ||||
| 	write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2F); | ||||
|  | ||||
|         EnablePunctureRate(state, FEC_NONE); | ||||
| 	 | ||||
| 	/* 8PSK 3/5, 8PSK 2/3 Poff tracking optimization WA*/ | ||||
| 	write_reg(state, RSTV0910_P2_ACLC2S2Q + state->regoff, 0x0B); | ||||
| 	write_reg(state, RSTV0910_P2_ACLC2S28 + state->regoff, 0x0A); | ||||
| 	write_reg(state, RSTV0910_P2_BCLC2S2Q + state->regoff, 0x84); | ||||
| 	write_reg(state, RSTV0910_P2_BCLC2S28 + state->regoff, 0x84); | ||||
| 	write_reg(state, RSTV0910_P2_CARHDR + state->regoff, 0x1C); | ||||
| 	/* Reset demod */ | ||||
| 	write_reg(state, RSTV0910_P2_CARFREQ + state->regoff, 0x79); | ||||
| 	 | ||||
| 	write_reg(state, RSTV0910_P2_ACLC2S216A + state->regoff, 0x29); | ||||
| 	write_reg(state, RSTV0910_P2_ACLC2S232A + state->regoff, 0x09); | ||||
| 	write_reg(state, RSTV0910_P2_BCLC2S216A + state->regoff, 0x84); | ||||
| 	write_reg(state, RSTV0910_P2_BCLC2S232A + state->regoff, 0x84); | ||||
|  | ||||
| 	/* Reset CAR3, bug DVBS2->DVBS1 lock*/ | ||||
|         /* Note: The bit is only pulsed -> no lock on shared register needed */ | ||||
| 	write_reg(state, RSTV0910_TSTRES0, state->nr ? 0x04 : 0x08); | ||||
| 	write_reg(state, RSTV0910_TSTRES0, 0); | ||||
|  | ||||
| 	set_vth_default(state); | ||||
|  | ||||
|         /* Reset demod */ | ||||
| 	write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F); | ||||
|  | ||||
| 	write_reg(state, RSTV0910_P2_CARCFG + state->regoff, 0x46); | ||||
|  | ||||
| 	Freq = (state->SearchRange / 2000) + 600; | ||||
| 	if (p->symbol_rate <= 5000000) | ||||
| 		Freq -= (600 + 80); | ||||
| 		Freq = (state->SearchRange / 2000) + 80; | ||||
| 	else | ||||
| 		Freq = (state->SearchRange / 2000) + 1600; | ||||
| 	Freq = (Freq << 16) / (state->base->mclk / 1000); | ||||
|  | ||||
| 	write_reg(state, RSTV0910_P2_CFRUP1 + state->regoff, | ||||
| @@ -955,19 +1130,29 @@ static int probe(struct stv *state) | ||||
| 	/* Configure the I2C repeater to off */ | ||||
| 	write_reg(state, RSTV0910_P2_I2CRPT, 0x24); | ||||
| 	/* Set the I2C to oversampling ratio */ | ||||
| 	write_reg(state, RSTV0910_I2CCFG, 0x88); | ||||
| 	write_reg(state, RSTV0910_I2CCFG, 0x88); /* state->i2ccfg */ | ||||
|  | ||||
| 	write_reg(state, RSTV0910_OUTCFG,    0x00);  /* OUTCFG */ | ||||
| 	write_reg(state, RSTV0910_PADCFG,    0x05);  /* RF AGC Pads Dev = 05 */ | ||||
| 	write_reg(state, RSTV0910_PADCFG,    0x05);  /* RFAGC Pads Dev = 05 */ | ||||
| 	write_reg(state, RSTV0910_SYNTCTRL,  0x02);  /* SYNTCTRL */ | ||||
| 	write_reg(state, RSTV0910_TSGENERAL, state->tsgeneral);  /* TSGENERAL */ | ||||
| 	write_reg(state, RSTV0910_CFGEXT,    0x02);  /* CFGEXT */ | ||||
| 	write_reg(state, RSTV0910_GENCFG,    0x15);  /* GENCFG */ | ||||
|  | ||||
|  | ||||
| 	write_reg(state, RSTV0910_P1_CAR3CFG, 0x02); | ||||
| 	write_reg(state, RSTV0910_P2_CAR3CFG, 0x02); | ||||
| 	write_reg(state, RSTV0910_P1_DMDCFG4, 0x04); | ||||
| 	write_reg(state, RSTV0910_P2_DMDCFG4, 0x04); | ||||
| 	 | ||||
| 	write_reg(state, RSTV0910_TSTRES0, 0x80); /* LDPC Reset */ | ||||
| 	write_reg(state, RSTV0910_TSTRES0, 0x00); | ||||
|  | ||||
| 	write_reg(state, RSTV0910_P1_TSPIDFLT1, 0x00); | ||||
| 	write_reg(state, RSTV0910_P2_TSPIDFLT1, 0x00); | ||||
|  | ||||
| 	write_reg(state, RSTV0910_P1_TMGCFG2, 0x80); | ||||
| 	write_reg(state, RSTV0910_P2_TMGCFG2, 0x80); | ||||
|  | ||||
| 	set_mclock(state, 135000000); | ||||
|  | ||||
| 	/* TS output */ | ||||
| @@ -1054,12 +1239,31 @@ static int set_parameters(struct dvb_frontend *fe) | ||||
| 	return stat; | ||||
| } | ||||
|  | ||||
| static int get_frequency_offset(struct stv *state, s32 *off) | ||||
| { | ||||
| 	u8 cfr0, cfr1, cfr2; | ||||
| 	s32 derot; | ||||
|  | ||||
| 	read_reg(state, RSTV0910_P2_CFR2 + state->regoff, &cfr2); | ||||
| 	read_reg(state, RSTV0910_P2_CFR1 + state->regoff, &cfr1); | ||||
| 	read_reg(state, RSTV0910_P2_CFR0 + state->regoff, &cfr0); | ||||
| 	 | ||||
| 	derot = ((u32) cfr2 << 16) | ((u32)cfr1 << 8) | cfr0; | ||||
| 	if (derot & (1<<23)) | ||||
| 		derot |= 0xFF000000; | ||||
|         *off = - (s32) (((s64) derot * (s64) state->base->mclk) >> 24); | ||||
| 	//pr_info("foff = %d\n", *off); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int get_frontend(struct dvb_frontend *fe) | ||||
| { | ||||
| 	struct stv *state = fe->demodulator_priv; | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
| 	u8 tmp; | ||||
|  | ||||
| 	 | ||||
| 	if (state->ReceiveMode == Mode_DVBS2) { | ||||
| 		u32 mc; | ||||
| 		enum fe_modulation modcod2mod[0x20] = { | ||||
| @@ -1118,6 +1322,28 @@ static int get_frontend(struct dvb_frontend *fe) | ||||
| } | ||||
|  | ||||
|  | ||||
| static int ManageMatypeInfo(struct stv *state) | ||||
| { | ||||
| 	if (!state->Started) | ||||
| 		return -1; | ||||
|         if (state->ReceiveMode == Mode_DVBS2 ) { | ||||
| 		u8 BBHeader[2]; | ||||
| 		 | ||||
| 		read_regs(state, RSTV0910_P2_MATSTR1 + state->regoff, | ||||
| 			  BBHeader, 2); | ||||
| 		state->FERollOff = | ||||
| 			(enum FE_STV0910_RollOff) (BBHeader[0] & 0x03); | ||||
| 		state->isVCM = (BBHeader[0] & 0x10) == 0; | ||||
| 		state->isStandardBroadcast = (BBHeader[0] & 0xFC) == 0xF0; | ||||
|         } else if (state->ReceiveMode == Mode_DVBS) { | ||||
| 		state->isVCM = 0; | ||||
| 		state->isStandardBroadcast = 1; | ||||
| 		state->FERollOff = FE_SAT_35; | ||||
|         } | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| static int read_snr(struct dvb_frontend *fe, u16 *snr); | ||||
| static int read_signal_strength(struct dvb_frontend *fe, u16 *strength); | ||||
| static int read_ber(struct dvb_frontend *fe, u32 *ber); | ||||
| @@ -1125,13 +1351,15 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber); | ||||
| static int read_status(struct dvb_frontend *fe, fe_status_t *status) | ||||
| { | ||||
| 	struct stv *state = fe->demodulator_priv; | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
| 	u8 DmdState = 0; | ||||
| 	u8 DStatus  = 0; | ||||
| 	enum ReceiveMode CurReceiveMode = Mode_None; | ||||
| 	u32 FECLock = 0; | ||||
| 	u16 val; | ||||
| 	u32 ber; | ||||
| 	s32 foff; | ||||
|  | ||||
| 	get_frequency_offset(state, &foff); | ||||
| 	 | ||||
| 	read_signal_strength(fe, &val); | ||||
|  | ||||
| @@ -1140,24 +1368,42 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status) | ||||
| 	read_ber(fe, &ber); | ||||
| 	 | ||||
| 	read_reg(state, RSTV0910_P2_DMDSTATE + state->regoff, &DmdState); | ||||
|  | ||||
| 	if (DmdState & 0x40) { | ||||
| 		read_reg(state, RSTV0910_P2_DSTATUS + state->regoff, &DStatus); | ||||
| 		read_reg(state, RSTV0910_P2_DSTATUS + state->regoff, | ||||
| 			 &DStatus); | ||||
| 		if (DStatus & 0x08) | ||||
| 			CurReceiveMode = (DmdState & 0x20) ? | ||||
| 				Mode_DVBS : Mode_DVBS2; | ||||
| 	} | ||||
| 	if (CurReceiveMode == Mode_None) { | ||||
| 		set_vth(state); | ||||
| 		//if( Time >= m_DemodTimeout ) *pLockStatus = NEVER_LOCK; | ||||
| 		*status = 0; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	*status |= 0x0f; | ||||
| 	if (state->ReceiveMode == Mode_None) { | ||||
| 		state->ReceiveMode = CurReceiveMode; | ||||
| 		state->DemodLockTime = jiffies; | ||||
| 		state->FirstTimeLock = 1; | ||||
|  | ||||
| 		GetSignalParameters(state); | ||||
| 		TrackingOptimization(state); | ||||
| 		 | ||||
| #if 0 | ||||
|             if( CurReceiveMode == Mode_DVBS2 && m_bPilots | ||||
| 		&& ( m_ModCod == FE_8PSK_23 || m_ModCod == FE_8PSK_35) ) | ||||
|             { | ||||
|                 LONG C_N; | ||||
|                 CHK_ERROR(GetSignalToNoise(&C_N)); | ||||
|                 if( C_N < 80 ) | ||||
|                 { | ||||
|                     CHK_ERROR(WriteReg(RSTV0910_P2_CARHDR + m_DemodOffset , 0x04)); | ||||
|                     CHK_ERROR(WriteReg(RSTV0910_P2_BCLC2S28 + m_DemodOffset , 0x31)); | ||||
|                 } | ||||
|             } | ||||
| #endif | ||||
|      | ||||
| 		write_reg(state, RSTV0910_P2_TSCFGH + state->regoff, | ||||
| 			  state->tscfgh); | ||||
| 		usleep_range(3000, 4000); | ||||
| @@ -1183,6 +1429,7 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status) | ||||
| 	} | ||||
|  | ||||
| 	if (!FECLock) | ||||
| 		//if( Time >= m_DemodLockTime + m_FecTimeout ) *pLockStatus = NEVER_LOCK; | ||||
| 		return 0; | ||||
|  | ||||
| 	*status |= 0x10; | ||||
| @@ -1191,10 +1438,23 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status) | ||||
| 		u8 tmp; | ||||
|  | ||||
| 		state->FirstTimeLock = 0; | ||||
| 		GetSignalParameters(state); | ||||
|  | ||||
| 		if (state->ReceiveMode == Mode_DVBS2) { | ||||
| 			/* FSTV0910_P2_MANUALSX_ROLLOFF, | ||||
| 		ManageMatypeInfo(state); | ||||
| 		 | ||||
| #if 0 | ||||
| 		ULONG Bitrate; | ||||
| 		CSTV0910::GetBitrate(&Bitrate); | ||||
| 		BYTE newTSSPEED = (Bitrate > 67000000) ? 0x30 : 0x40; | ||||
|             if (newTSSPEED != m_TSSPEED) | ||||
|             { | ||||
| 		    KdPrintEx((MSG_INFO "_%d " __FUNCTION__ " TSSPEED = %02X\n", m_Instance, newTSSPEED)); | ||||
|                 CHK_ERROR(WriteReg(RSTV0910_P2_TSSPEED + m_DemodOffset, newTSSPEED)); | ||||
|                 m_TSSPEED = newTSSPEED; | ||||
|             } | ||||
| 	     | ||||
| #endif | ||||
| 	    if (state->ReceiveMode == Mode_DVBS2) { | ||||
| 		    /* FSTV0910_P2_MANUALSX_ROLLOFF, | ||||
| 			   FSTV0910_P2_MANUALS2_ROLLOFF = 0 */ | ||||
| 			state->DEMOD &= ~0x84; | ||||
| 			write_reg(state, RSTV0910_P2_DEMOD + state->regoff, | ||||
| @@ -1203,11 +1463,13 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status) | ||||
| 				 &tmp); | ||||
| 			/*reset DVBS2 packet delinator error counter */ | ||||
| 			tmp |= 0x40; | ||||
| 			write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, | ||||
| 			write_reg(state, RSTV0910_P2_PDELCTRL2 + | ||||
| 				  state->regoff, | ||||
| 				  tmp); | ||||
| 			/*reset DVBS2 packet delinator error counter */ | ||||
| 			tmp &= ~0x40; | ||||
| 			write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, | ||||
| 			write_reg(state, RSTV0910_P2_PDELCTRL2 + | ||||
| 				  state->regoff, | ||||
| 				  tmp); | ||||
|  | ||||
| 			state->BERScale = 2; | ||||
| @@ -1230,8 +1492,25 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status) | ||||
| 		  infinit error count mode )*/ | ||||
| 		write_reg(state, RSTV0910_P2_ERRCTRL2 + state->regoff, 0xc1); | ||||
|  | ||||
| 		TrackingOptimization(state); | ||||
| 		set_vth_default(state); | ||||
| 		if (state->ReceiveMode == Mode_DVBS) | ||||
| 			EnablePunctureRate(state, state->PunctureRate); | ||||
| 	} | ||||
|  | ||||
| #if 0 | ||||
|         if( m_isVCM ) | ||||
|         { | ||||
| 		// Use highest signaled ModCod for quality | ||||
| 		BYTE tmp; | ||||
| 		CHK_ERROR(ReadReg(RSTV0910_P2_DMDMODCOD + | ||||
| 				  m_DemodOffset,&tmp)); | ||||
| 		FE_STV0910_ModCod ModCod = | ||||
| 			FE_STV0910_ModCod((tmp & 0x7c) >> 2); | ||||
|  | ||||
| 		if( ModCod > m_ModCod ) | ||||
| 			m_ModCod = ModCod; | ||||
|         } | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -1439,24 +1718,21 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||||
| { | ||||
| 	struct stv *state = fe->demodulator_priv; | ||||
| 	struct dtv_frontend_properties *p = &fe->dtv_property_cache; | ||||
| 	u8 Agc1, Agc0; | ||||
| 	u8 Reg[2]; | ||||
| 	s32 bbgain; | ||||
| 	s32 Power = 0; | ||||
| 	int i; | ||||
|  | ||||
| 	read_regs(state, RSTV0910_P2_AGCIQIN1 + state->regoff, Reg, 2); | ||||
| 	//KdPrintEx((MSG_INFO "_%d " __FUNCTION__ " AGCIQIN1 = %02x%02x\n",m_Instance,Reg[0],Reg[1])); | ||||
| 	 | ||||
| 	*strength = (((u32) Reg[0]) << 8) | Reg[1]; | ||||
| 	 | ||||
| 	for (i = 0; i < 5; i += 1) { | ||||
| 		read_regs(state, RSTV0910_P2_POWERI + state->regoff, Reg, 2); | ||||
| 		Power += (u32) Reg[0] * (u32) Reg[0] + (u32) Reg[1] * (u32) Reg[1]; | ||||
| 		Power += (u32) Reg[0] * (u32) Reg[0] + | ||||
| 			(u32) Reg[1] * (u32) Reg[1]; | ||||
| 		msleep(3); | ||||
| 	} | ||||
| 	Power /= 5; | ||||
| 	 | ||||
| 	bbgain = (465 - Log10x100(Power)) * 10; | ||||
| 	 | ||||
| 	if (fe->ops.tuner_ops.get_rf_strength) | ||||
| @@ -1464,7 +1740,6 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||||
| 	else | ||||
| 		*strength = 0; | ||||
|  | ||||
| 	printk("pwr = %d  bb = %d  str = %u\n", Power, bbgain, *strength); | ||||
| 	if (bbgain < (s32) *strength) | ||||
| 		*strength -= bbgain; | ||||
| 	else | ||||
| @@ -1473,7 +1748,8 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||||
| 	p->strength.len = 1; | ||||
| 	p->strength.stat[0].scale = FE_SCALE_DECIBEL; | ||||
| 	p->strength.stat[0].uvalue = 10 * (s64) (s16) *strength - 108750; | ||||
|  | ||||
| 	 | ||||
| 	/* *strength is in hundredth dBuv, uvalue is in thousandth dBm */ | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -1550,6 +1826,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, | ||||
| 	state->SearchRange = 16000000; | ||||
| 	state->DEMOD = 0x10;     /* Inversion : Auto with reset to 0 */ | ||||
| 	state->ReceiveMode   = Mode_None; | ||||
| 	state->CurScramblingCode = NO_SCRAMBLING_CODE; | ||||
|  | ||||
| 	base = match_base(i2c, cfg->adr); | ||||
| 	if (base) { | ||||
| @@ -1586,5 +1863,5 @@ fail: | ||||
| EXPORT_SYMBOL_GPL(stv0910_attach); | ||||
|  | ||||
| MODULE_DESCRIPTION("STV0910 driver"); | ||||
| MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel"); | ||||
| MODULE_AUTHOR("Ralph und Marcus Metzler, Manfred Voelkel"); | ||||
| MODULE_LICENSE("GPL"); | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -105,20 +105,20 @@ static int read_regs(struct stv *state, u8 reg, u8 *val, int len) | ||||
| 	return i2c_read(state->i2c, state->adr, ®, 1, val, len); | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| static void dump_regs(struct stv *state) | ||||
| { | ||||
| 	u8 d[11], *c = &state->reg[0]; | ||||
|  | ||||
| 	read_regs(state, 0, d, 11); | ||||
| #if 0 | ||||
| 	pr_info("stv6111_regs = %02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x\n", | ||||
| 		d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], | ||||
| 		d[8], d[9], d[10]); | ||||
| 	pr_info("reg[] =        %02x %02x %02x %02x  %02x %02x %02x %02x  %02x %02x %02x\n", | ||||
| 		c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], | ||||
| 		c[8], c[9], c[10]); | ||||
| #endif | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static int wait_for_call_done(struct stv *state, u8 mask) | ||||
| { | ||||
| @@ -184,7 +184,9 @@ static int attach_init(struct stv *state) | ||||
| { | ||||
| 	if (write_regs(state, 0, 11)) | ||||
| 		return -1; | ||||
| #if 0 | ||||
| 	dump_regs(state); | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -299,7 +301,9 @@ static int set_lof(struct stv *state, u32 LocalFrequency, u32 CutOffFrequency) | ||||
|  | ||||
| 	state->Frequency = Frequency; | ||||
| 	 | ||||
| #if 0 | ||||
| 	dump_regs(state); | ||||
| #endif | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| @@ -330,39 +334,6 @@ static int get_frequency(struct dvb_frontend *fe, u32 *frequency) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static u32 AGC_Gain[] = { | ||||
| 	000, /* 0.0 */ | ||||
| 	000, /* 0.1 */ | ||||
| 	1000, /* 0.2 */ | ||||
| 	2000, /* 0.3 */ | ||||
| 	3000, /* 0.4 */ | ||||
| 	4000, /* 0.5 */ | ||||
| 	5000, /* 0.6 */ | ||||
| 	6000, /* 0.7 */ | ||||
| 	7000, /* 0.8 */ | ||||
| 	14000, /* 0.9 */ | ||||
| 	20000, /* 1.0 */ | ||||
| 	27000, /* 1.1 */ | ||||
| 	32000, /* 1.2 */ | ||||
| 	37000, /* 1.3 */ | ||||
| 	42000, /* 1.4 */ | ||||
| 	47000, /* 1.5 */ | ||||
| 	50000, /* 1.6 */ | ||||
| 	53000, /* 1.7 */ | ||||
| 	56000, /* 1.8 */ | ||||
| 	58000, /* 1.9 */ | ||||
| 	60000, /* 2.0 */ | ||||
| 	62000, /* 2.1 */ | ||||
| 	63000, /* 2.2 */ | ||||
| 	64000, /* 2.3 */ | ||||
| 	64500, /* 2.4 */ | ||||
| 	65000, /* 2.5 */ | ||||
| 	65500, /* 2.6 */ | ||||
| 	66000, /* 2.7 */ | ||||
| 	66500, /* 2.8 */ | ||||
| 	67000, /* 2.9 */ | ||||
| }; | ||||
|  | ||||
| struct SLookup { | ||||
| 	s16 Value; | ||||
| 	u16 RegValue; | ||||
| @@ -618,7 +589,6 @@ static struct SLookup Gain_Channel_AGC_IIP3_LookUp[] = { | ||||
| 	{ 1325 , 0xFF00 }, | ||||
| }; | ||||
|  | ||||
| #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) | ||||
|  | ||||
| static s32 TableLookup(struct SLookup *Table, int TableSize, u16 RegValue) | ||||
| { | ||||
|   | ||||
| @@ -197,6 +197,7 @@ typedef enum fe_transmit_mode { | ||||
| 	TRANSMISSION_MODE_32K, | ||||
| 	TRANSMISSION_MODE_C1, | ||||
| 	TRANSMISSION_MODE_C3780, | ||||
| 	TRANSMISSION_MODE_64K, | ||||
| } fe_transmit_mode_t; | ||||
|  | ||||
| #if defined(__DVB_CORE__) || !defined (__KERNEL__) | ||||
| @@ -378,8 +379,9 @@ struct dvb_frontend_event { | ||||
| #define DTV_STAT_TOTAL_BLOCK_COUNT	69 | ||||
|  | ||||
| #define DTV_INPUT                       70 | ||||
| #define DTV_PLS                         71 | ||||
|  | ||||
| #define DTV_MAX_COMMAND		DTV_INPUT | ||||
| #define DTV_MAX_COMMAND		DTV_PLS | ||||
|  | ||||
| typedef enum fe_pilot { | ||||
| 	PILOT_ON, | ||||
| @@ -454,6 +456,7 @@ enum atscmh_rs_code_mode { | ||||
| }; | ||||
|  | ||||
| #define NO_STREAM_ID_FILTER	(~0U) | ||||
| #define NO_SCRAMBLING_CODE	(~0U) | ||||
| #define LNA_AUTO                (~0U) | ||||
|  | ||||
| struct dtv_cmds_h { | ||||
|   | ||||
| @@ -50,6 +50,11 @@ struct dvb_nsd_ts { | ||||
| 	__u16	 section_id; | ||||
| }; | ||||
|  | ||||
| struct dvb_ns_cap { | ||||
| 	__u8     streams_max; | ||||
| 	__u8     reserved[127]; | ||||
| }; | ||||
|  | ||||
| #define NS_SET_NET               _IOW('o', 192, struct dvb_ns_params) | ||||
| #define NS_START                 _IO('o', 193) | ||||
| #define NS_STOP                  _IO('o', 194) | ||||
| @@ -66,4 +71,6 @@ struct dvb_nsd_ts { | ||||
| #define NS_INSERT_PACKETS	 _IOW('o', 203, __u8) | ||||
| #define NS_SET_CI	         _IOW('o', 204, __u8) | ||||
|  | ||||
| #define NS_GET_CAP               _IOR('o', 204, struct dvb_ns_cap)) | ||||
|  | ||||
| #endif /*_UAPI_DVBNS_H_*/ | ||||
|   | ||||
| @@ -26,6 +26,10 @@ | ||||
|  | ||||
| #include <linux/compiler.h> | ||||
|  | ||||
| #ifndef __user | ||||
| #define __user | ||||
| #endif | ||||
|  | ||||
| typedef enum { | ||||
|   // All functions return -2 on "not open" | ||||
|   OSD_Close=1,    // () | ||||
|   | ||||
| @@ -30,6 +30,10 @@ | ||||
| #include <time.h> | ||||
| #endif | ||||
|  | ||||
| #ifndef __user | ||||
| #define __user | ||||
| #endif | ||||
|  | ||||
| typedef enum { | ||||
| 	VIDEO_FORMAT_4_3,     /* Select 4:3 format */ | ||||
| 	VIDEO_FORMAT_16_9,    /* Select 16:9 format. */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user