diff --git a/CHANGELOG b/CHANGELOG index 95a20cd..b184a06 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,7 @@ +0.9.29 compiles with most kernels up to 4.11.1 + +see git commit messages for newer changes + 0.9.24 2016.08.03 - suport new V2 modulator cards diff --git a/README.md b/README.md index 428e66e..ed0f5fb 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,13 @@ # DDBridge Driver -###Prepare for Building +### Patches +We can only accept patches which don't break compilation for older kernels (as far back as 2.6.37). + +### Prepare for Building TBD -###Building +### Building TBD diff --git a/apps/Makefile b/apps/Makefile index f553427..b229b86 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -1,22 +1,22 @@ -all: cit citin flashprog modt ddtest setmod ddflash +all: cit citin flashprog modt ddtest setmod ddflash setmod2 cit: cit.c - gcc -o cit cit.c -lpthread + $(CC) -o cit cit.c -lpthread modt: modt.c - gcc -o modt modt.c -lpthread + $(CC) -o modt modt.c -lpthread setmod: setmod.c - gcc -o setmod setmod.c -I../include/ + $(CC) -o setmod setmod.c -I../include/ setmod2: setmod2.c - gcc -o setmod2 setmod2.c -I../include/ + $(CC) -o setmod2 setmod2.c -I../include/ flashprog: flashprog.c - gcc -o flashprog flashprog.c + $(CC) -o flashprog flashprog.c ddtest: ddtest.c - gcc -o ddtest ddtest.c + $(CC) -o ddtest ddtest.c ddflash: ddflash.c - gcc -o ddflash ddflash.c + $(CC) -o ddflash ddflash.c diff --git a/apps/cit.c b/apps/cit.c index 2a3f6e7..4d8ab39 100644 --- a/apps/cit.c +++ b/apps/cit.c @@ -91,6 +91,7 @@ void *get_ts(void *a) if (!buf) return NULL; sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device); + printf("using %s for reading\n", fname); fdi = open(fname, O_RDONLY); while (1) { @@ -122,6 +123,7 @@ int send(void) if (!buf) return -1; sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device); + printf("using %s for writing\n", fname); fdo=open(fname, O_WRONLY); while (1) { diff --git a/apps/flash.c b/apps/flash.c new file mode 120000 index 0000000..fa8626c --- /dev/null +++ b/apps/flash.c @@ -0,0 +1 @@ +./octonet/flash.c \ No newline at end of file diff --git a/apps/flashprog.c b/apps/flashprog.c index 99d3553..99b3ea4 100644 --- a/apps/flashprog.c +++ b/apps/flashprog.c @@ -33,379 +33,7 @@ #include #include -#define DDB_MAGIC 'd' - -static uint32_t linknr = 0; - -struct ddb_id { - __u16 vendor; - __u16 device; - __u16 subvendor; - __u16 subdevice; - __u32 hw; - __u32 regmap; -}; - -struct ddb_flashio { - __u8 *write_buf; - __u32 write_len; - __u8 *read_buf; - __u32 read_len; - __u32 link; -}; - -#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio) -#define IOCTL_DDB_ID _IOR(DDB_MAGIC, 0x03, struct ddb_id) - - -int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen) -{ - struct ddb_flashio fio = { - .write_buf=wbuf, - .write_len=wlen, - .read_buf=rbuf, - .read_len=rlen, - .link=linknr, - }; - - return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio); -} - -enum { - UNKNOWN_FLASH = 0, - ATMEL_AT45DB642D = 1, - SSTI_SST25VF016B = 2, - SSTI_SST25VF032B = 3, - SSTI_SST25VF064C = 4, - SPANSION_S25FL116K = 5, -}; - - -int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len) -{ - uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff}; - - return flashio(ddb, cmd, 4, buf, len); -} - -int flashdump(int ddb, uint32_t addr, uint32_t len) -{ - int i, j; - uint8_t buf[32]; - int bl = sizeof(buf); - - for (j=0; j= 8192; - int i; - - if (BlockErase) { - for(i = 0; i < BufferSize; i += 8192 ) { - uint8_t Cmd[4]; - if( (i & 0xFFFF) == 0 ) - printf(" Erase %08x\n",FlashOffset + i); - Cmd[0] = 0x50; // Block Erase - Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - err = flashio(dev,Cmd,4,NULL,0); - if( err < 0 ) break; - - while( 1 ) - { - Cmd[0] = 0xD7; // Read Status register - err = flashio(dev,Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x80) == 0x80 ) break; - } - } - } - - for(i = 0; i < BufferSize; i += 1024 ) - { - uint8_t Cmd[4 + 1024]; - if( (i & 0xFFFF) == 0 ) - { - printf(" Program %08x\n",FlashOffset + i); - } - Cmd[0] = 0x84; // Buffer 1 - Cmd[1] = 0x00; - Cmd[2] = 0x00; - Cmd[3] = 0x00; - memcpy(&Cmd[4],&Buffer[i],1024); - - err = flashio(dev,Cmd,4 + 1024,NULL,0); - if( err < 0 ) break; - - Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase) - Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - - err = flashio(dev,Cmd,4,NULL,0); - if( err < 0 ) break; - - while( 1 ) - { - Cmd[0] = 0xD7; // Read Status register - err = flashio(dev,Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x80) == 0x80 ) break; - } - if( err < 0 ) break; - } - return err; -} - - -int FlashWritePageMode(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize, uint8_t LockBits) -{ - int err = 0, i, j; - uint8_t Cmd[260]; - - if( (BufferSize % 4096) != 0 ) - return -1; // Must be multiple of sector size - - do { - Cmd[0] = 0x50; // EWSR - err = flashio(dev, Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x01; // WRSR - Cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = flashio(dev, Cmd,2,NULL,0); - if( err < 0 ) break; - - for(i = 0; i < BufferSize; i += 4096 ) { - if( (i & 0xFFFF) == 0 ) { - printf(" Erase %08x\n",FlashOffset + i); - } - - Cmd[0] = 0x06; // WREN - err = flashio(dev, Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x20; // Sector erase ( 4Kb) - Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - err = flashio(dev, Cmd,4,NULL,0); - if( err < 0 ) break; - - while(1) - { - Cmd[0] = 0x05; // RDRS - err = flashio(dev, Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x01) == 0 ) break; - } - if( err < 0 ) break; - - } - if( err < 0 ) break; - - - for (j = BufferSize - 256; j >= 0; j -= 256 ) - { - if( (j & 0xFFFF) == 0 ) - { - printf(" Programm %08x\n",FlashOffset + j); - } - - Cmd[0] = 0x06; // WREN - err = flashio(dev, Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x02; // PP - Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - memcpy(&Cmd[4],&Buffer[j],256); - err = flashio(dev, Cmd,260,NULL,0); - if( err < 0 ) break; - - while(1) - { - Cmd[0] = 0x05; // RDRS - err = flashio(dev, Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x01) == 0 ) break; - } - if( err < 0 ) break; - - } - if( err < 0 ) break; - - Cmd[0] = 0x50; // EWSR - err = flashio(dev, Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x01; // WRSR - Cmd[1] = LockBits; // BPx = 0, Lock all blocks - err = flashio(dev, Cmd,2,NULL,0); - - } while(0); - return err; -} - - -int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize) -{ - int err = 0; - uint8_t Cmd[6]; - int i, j; - - // Must be multiple of sector size - if( (BufferSize % 4096) != 0 ) - return -1; - - do { - Cmd[0] = 0x50; // EWSR - err = flashio(dev,Cmd,1,NULL,0); - if( err < 0 ) - break; - - Cmd[0] = 0x01; // WRSR - Cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = flashio(dev,Cmd,2,NULL,0); - if( err < 0 ) - break; - - for(i = 0; i < BufferSize; i += 4096 ) { - if( (i & 0xFFFF) == 0 ) - printf(" Erase %08x\n",FlashOffset + i); - Cmd[0] = 0x06; // WREN - err = flashio(dev,Cmd,1,NULL,0); - if( err < 0 ) - break; - - Cmd[0] = 0x20; // Sector erase ( 4Kb) - Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - err = flashio(dev,Cmd,4,NULL,0); - if( err < 0 ) - break; - - while(1) { - Cmd[0] = 0x05; // RDRS - err = flashio(dev,Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x01) == 0 ) break; - } - if( err < 0 ) break; - } - if( err < 0 ) - break; - for(j = BufferSize - 4096; j >= 0; j -= 4096 ) { - if( (j & 0xFFFF) == 0 ) - printf(" Program %08x\n",FlashOffset + j); - - for(i = 0; i < 4096; i += 2 ) { - if( i == 0 ) { - Cmd[0] = 0x06; // WREN - err = flashio(dev,Cmd,1,NULL,0); - if( err < 0 ) - break; - - Cmd[0] = 0xAD; // AAI - Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - Cmd[4] = Buffer[j+i]; - Cmd[5] = Buffer[j+i+1]; - err = flashio(dev,Cmd,6,NULL,0); - } else { - Cmd[0] = 0xAD; // AAI - Cmd[1] = Buffer[j+i]; - Cmd[2] = Buffer[j+i+1]; - err = flashio(dev,Cmd,3,NULL,0); - } - if( err < 0 ) - break; - - while(1) { - Cmd[0] = 0x05; // RDRS - err = flashio(dev,Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x01) == 0 ) break; - } - if( err < 0 ) break; - } - if( err < 0 ) break; - - Cmd[0] = 0x04; // WDIS - err = flashio(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - } - if( err < 0 ) break; - - Cmd[0] = 0x50; // EWSR - err = flashio(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x01; // WRSR - Cmd[1] = 0x1C; // BPx = 0, Lock all blocks - err = flashio(dev,Cmd,2,NULL,0); - } while(0); - return err; -} +#include "flash.h" void get_id(int ddb, struct ddb_id *ddbid) { uint8_t id[4]; @@ -450,8 +78,8 @@ int main(int argc, char **argv) uint32_t FlashOffset = 0x10000; int ddb; int i, err; - int SectorSize=0; - int FlashSize=0; + uint32_t SectorSize=0; + uint32_t FlashSize=0; int Flash; uint32_t svid=0, jump=0, dump=0; @@ -459,6 +87,7 @@ int main(int argc, char **argv) int ddbnum = 0; int force = 0; + char *fname = NULL; while (1) { int option_index = 0; @@ -470,12 +99,15 @@ int main(int argc, char **argv) {0, 0, 0, 0} }; c = getopt_long(argc, argv, - "d:n:s:o:l:dfhj", + "d:n:s:o:l:dfhjb:", long_options, &option_index); if (c==-1) break; switch (c) { + case 'b': + fname = optarg; + break; case 'd': dump = strtoul(optarg, NULL, 16); break; @@ -513,32 +145,7 @@ int main(int argc, char **argv) printf("Could not open device\n"); return -1; } - Flash=FlashDetect(ddb); - - switch(Flash) { - case ATMEL_AT45DB642D: - SectorSize = 1024; - FlashSize = 0x800000; - break; - case SSTI_SST25VF016B: - SectorSize = 4096; - FlashSize = 0x200000; - break; - case SSTI_SST25VF032B: - SectorSize = 4096; - FlashSize = 0x400000; - break; - case SSTI_SST25VF064C: - SectorSize = 4096; - FlashSize = 0x800000; - break; - case SPANSION_S25FL116K: - SectorSize = 4096; - FlashSize = 0x200000; - break; - default: - return 0; - } + Flash = flashdetect(ddb, &SectorSize, &FlashSize); get_id(ddb, &ddbid); #if 1 @@ -553,27 +160,6 @@ int main(int argc, char **argv) return 0; } - if (ddbid.device == 0x0011) - type = 1; - if (ddbid.device == 0x0201) - type = 2; - if (ddbid.device == 0x02) - type = 3; - if (ddbid.device == 0x03) - type = 0; - if (ddbid.device == 0x07) - type = 4; - if (ddbid.device == 0x320) - type = 5; - if (ddbid.device == 0x13) - type = 6; - if (ddbid.device == 0x12) - type = 7; - if (ddbid.device == 0x08) - type = 8; - if (ddbid.device == 0x210) - type = 9; - if (!SectorSize) return 0; @@ -616,52 +202,68 @@ int main(int argc, char **argv) } else { int fh, i; int fsize; - char *fname; - switch (type) { - case 0: - fname="DVBBridgeV1B_DVBBridgeV1B.bit"; - printf("Octopus\n"); - break; - case 1: - fname="CIBridgeV1B_CIBridgeV1B.bit"; - printf("Octopus CI\n"); - break; - case 2: - fname="DVBModulatorV1B_DVBModulatorV1B.bit"; - printf("Modulator\n"); - break; - case 3: + if (!fname) + switch (ddbid.device) { + case 0x0002: fname="DVBBridgeV1A_DVBBridgeV1A.bit"; printf("Octopus 35\n"); break; - case 4: + case 0x0003: + fname="DVBBridgeV1B_DVBBridgeV1B.fpga"; + printf("Octopus\n"); + break; + case 0x0005: + fname="DVBBridgeV2A_DD01_0005_STD.fpga"; + printf("Octopus Classic\n"); + break; + case 0x0006: + fname="DVBBridgeV2A_DD01_0006_STD.fpga"; + printf("CineS2 V7\n"); + break; + case 0x0007: fname="DVBBridgeV2A_DD01_0007_MXL.fpga"; printf("Octopus 4/8\n"); break; - case 8: + case 0x0008: fname="DVBBridgeV2A_DD01_0008_CXD.fpga"; printf("Octopus 4/8\n"); break; - case 6: - fname="DVBBridgeV2B_DD01_0013_PRO.fpga"; - printf("Octopus PRO\n"); + case 0x0011: + fname="CIBridgeV1B_CIBridgeV1B.fpga"; + printf("Octopus CI\n"); break; - case 7: + case 0x0012: fname="DVBBridgeV2B_DD01_0012_STD.fpga"; printf("Octopus CI\n"); break; - case 9: + case 0x0013: + fname="DVBBridgeV2B_DD01_0013_PRO.fpga"; + printf("Octopus PRO\n"); + break; + case 0x0201: + fname="DVBModulatorV1B_DVBModulatorV1B.bit"; + printf("Modulator\n"); + break; + case 0x0203: + fname="DVBModulatorV1B_DD01_0203.fpga"; + printf("Modulator Test\n"); + break; + case 0x0210: fname="DVBModulatorV2A_DD01_0210.fpga"; printf("Modulator V2\n"); break; + case 0x0220: + fname="SDRModulatorV1A_DD01_0220.fpga"; + printf("SDRModulator\n"); + break; default: printf("UNKNOWN\n"); break; } fh = open(fname, O_RDONLY); if (fh < 0 ) { - printf("File not found \n"); + printf("File %s not found \n", fname); return 0; } printf("Using bitstream %s\n", fname); @@ -720,6 +322,7 @@ int main(int argc, char **argv) err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x3C); break; case SPANSION_S25FL116K: + case SPANSION_S25FL164K: err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C); break; } diff --git a/apps/octonet/ddflash.c b/apps/octonet/ddflash.c index 276e257..979b3cf 100644 --- a/apps/octonet/ddflash.c +++ b/apps/octonet/ddflash.c @@ -58,7 +58,6 @@ static int reboot(uint32_t off) struct ddflash { int fd; struct ddb_id id; - uint32_t type; uint32_t version; uint32_t flash_type; @@ -68,74 +67,9 @@ struct ddflash { uint32_t bufsize; uint32_t block_erase; - uint8_t * buffer; + uint8_t *buffer; }; -int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen) -{ - struct ddb_flashio fio = { - .write_buf=wbuf, - .write_len=wlen, - .read_buf=rbuf, - .read_len=rlen, - .link=0, - }; - - return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio); -} - -enum { - UNKNOWN_FLASH = 0, - ATMEL_AT45DB642D = 1, - SSTI_SST25VF016B = 2, - SSTI_SST25VF032B = 3, - SSTI_SST25VF064C = 4, - SPANSION_S25FL116K = 5, - SPANSION_S25FL132K = 6, - SPANSION_S25FL164K = 7, -}; - -static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len) -{ - uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff, - (addr >> 8) & 0xff, addr & 0xff}; - - return flashio(ddb, cmd, 4, buf, len); -} - -static int flashdump(struct ddflash *ddf, uint32_t addr, uint32_t len) -{ - int i, j; - uint8_t buf[32]; - int bl = sizeof(buf); - - for (j = 0; j < len; j += bl, addr += bl) { - flashread(ddf->fd, buf, addr, bl); - for (i = 0; i < bl; i++) { - printf("%02x ", buf[i]); - } - printf("\n"); - } -} - -void dump(const uint8_t *b, int l) -{ - int i, j; - - for (j = 0; j < l; j += 16, b += 16) { - for (i = 0; i < 16; i++) - if (i + j < l) - printf("%02x ", b[i]); - else - printf(" "); - printf(" | "); - for (i = 0; i < 16; i++) - if (i + j < l) - putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.'); - printf("\n"); - } -} - int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset, uint8_t LockBits, uint32_t fw_off) { @@ -492,7 +426,7 @@ static int flash_detect(struct ddflash *ddf) } if (ddf->sector_size) { ddf->buffer = malloc(ddf->sector_size); - printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer); + //printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer); if (!ddf->buffer) return -1; } @@ -500,172 +434,6 @@ static int flash_detect(struct ddflash *ddf) } -int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize) -{ - int err = 0; - int BlockErase = BufferSize >= 8192; - int i; - - if (BlockErase) { - for (i = 0; i < BufferSize; i += 8192 ) { - uint8_t cmd[4]; - if ((i & 0xFFFF) == 0 ) - printf(" Erase %08x\n",FlashOffset + i); - cmd[0] = 0x50; // Block Erase - cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - cmd[3] = 0x00; - err = flashio(dev,cmd,4,NULL,0); - if (err < 0 ) break; - - while( 1 ) - { - cmd[0] = 0xD7; // Read Status register - err = flashio(dev,cmd,1,&cmd[0],1); - if (err < 0 ) break; - if ((cmd[0] & 0x80) == 0x80 ) break; - } - } - } - - for (i = 0; i < BufferSize; i += 1024) { - uint8_t cmd[4 + 1024]; - if ((i & 0xFFFF) == 0 ) - { - printf(" Program %08x\n",FlashOffset + i); - } - cmd[0] = 0x84; // Buffer 1 - cmd[1] = 0x00; - cmd[2] = 0x00; - cmd[3] = 0x00; - memcpy(&cmd[4],&Buffer[i],1024); - - err = flashio(dev,cmd,4 + 1024,NULL,0); - if (err < 0 ) break; - - cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase) - cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - cmd[3] = 0x00; - - err = flashio(dev,cmd,4,NULL,0); - if (err < 0 ) break; - - while( 1 ) - { - cmd[0] = 0xD7; // Read Status register - err = flashio(dev,cmd,1,&cmd[0],1); - if (err < 0 ) break; - if ((cmd[0] & 0x80) == 0x80 ) break; - } - if (err < 0 ) break; - } - return err; -} - -int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize) -{ - int err = 0; - uint8_t cmd[6]; - int i, j; - - // Must be multiple of sector size - if ((BufferSize % 4096) != 0 ) - return -1; - - do { - cmd[0] = 0x50; // EWSR - err = flashio(dev,cmd,1,NULL,0); - if (err < 0 ) - break; - - cmd[0] = 0x01; // WRSR - cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = flashio(dev,cmd,2,NULL,0); - if (err < 0 ) - break; - - for (i = 0; i < BufferSize; i += 4096 ) { - if ((i & 0xFFFF) == 0 ) - printf(" Erase %08x\n",FlashOffset + i); - cmd[0] = 0x06; // WREN - err = flashio(dev,cmd,1,NULL,0); - if (err < 0 ) - break; - - cmd[0] = 0x20; // Sector erase ( 4Kb) - cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - cmd[3] = 0x00; - err = flashio(dev,cmd,4,NULL,0); - if (err < 0 ) - break; - - while(1) { - cmd[0] = 0x05; // RDRS - err = flashio(dev,cmd,1,&cmd[0],1); - if (err < 0 ) break; - if ((cmd[0] & 0x01) == 0 ) break; - } - if (err < 0 ) break; - } - if (err < 0 ) - break; - for (j = BufferSize - 4096; j >= 0; j -= 4096 ) { - if ((j & 0xFFFF) == 0 ) - printf(" Program %08x\n",FlashOffset + j); - - for (i = 0; i < 4096; i += 2 ) { - if (i == 0 ) { - cmd[0] = 0x06; // WREN - err = flashio(dev,cmd,1,NULL,0); - if (err < 0 ) - break; - - cmd[0] = 0xAD; // AAI - cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); - cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); - cmd[3] = 0x00; - cmd[4] = Buffer[j+i]; - cmd[5] = Buffer[j+i+1]; - err = flashio(dev,cmd,6,NULL,0); - } else { - cmd[0] = 0xAD; // AAI - cmd[1] = Buffer[j+i]; - cmd[2] = Buffer[j+i+1]; - err = flashio(dev,cmd,3,NULL,0); - } - if (err < 0 ) - break; - - while(1) { - cmd[0] = 0x05; // RDRS - err = flashio(dev,cmd,1,&cmd[0],1); - if (err < 0 ) break; - if ((cmd[0] & 0x01) == 0 ) break; - } - if (err < 0 ) break; - } - if (err < 0 ) break; - - cmd[0] = 0x04; // WDIS - err = flashio(dev,cmd,1,NULL,0); - if (err < 0 ) break; - - } - if (err < 0 ) break; - - cmd[0] = 0x50; // EWSR - err = flashio(dev,cmd,1,NULL,0); - if (err < 0 ) break; - - cmd[0] = 0x01; // WRSR - cmd[1] = 0x1C; // BPx = 0, Lock all blocks - err = flashio(dev,cmd,2,NULL,0); - } while(0); - return err; -} - static int get_id(struct ddflash *ddf) { uint8_t id[4]; @@ -677,19 +445,6 @@ static int get_id(struct ddflash *ddf) { ddf->id.subvendor, ddf->id.subdevice, ddf->id.hw, ddf->id.regmap); #endif - if (ddf->id.device == 0x0011) - ddf->type = 1; - if (ddf->id.device == 0x0201) - ddf->type = 2; - if (ddf->id.device == 0x02) - ddf->type = 3; - if (ddf->id.device == 0x03) - ddf->type = 0; - if (ddf->id.device == 0x0300) - ddf->type = 4; - if (ddf->id.device == 0x0320) - ddf->type = 5; - return 0; } @@ -755,7 +510,12 @@ static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off) goto out; } } else if (!strcasecmp(key, "Version")) { - sscanf(val, "%x", &version); + if (strchr(val,'.')) { + int major = 0, minor = 0; + sscanf(val,"%d.%d",&major,&minor); + version = (major << 16) + minor; + } else + sscanf(val, "%x", &version); } else if (!strcasecmp(key, "Length")) { sscanf(val, "%u", &length); } @@ -810,8 +570,13 @@ static int update_image(struct ddflash *ddf, char *fn, if (res < 0) goto out; res = flashwrite(ddf, fs, adr, len, fw_off); - if (res == 0) - res = 1; + if (res == 0) { + res = flashcmp(ddf, fs, adr, len, fw_off); + if (res == -2) { + res = 1; + } + } + out: close(fs); return res; @@ -852,18 +617,40 @@ static int update_flash(struct ddflash *ddf) if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1) stat |= 1; } else { - if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1) - stat |= 1; - if (res == -1) - if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1) - stat |= 1; - if (res == -1) - if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1) - stat |= 1; - if (res == -1) - if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1) + if (ddf->id.device == 0x0307) { + if (res == -1) + if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1) + stat |= 1; + if (res == -1) + if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1) + stat |= 1; + } else { + if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1) stat |= 1; + if (res == -1) + if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1) + stat |= 1; + } } +#if 1 + if ( (stat&1) && (ddf->id.hw & 0xffffff) <= 0x010001) { + if (ddf->id.device == 0x0307) { + if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1) + stat |= 1; + if (res == -1) + if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1) + stat |= 1; + } else { + if ((res = update_image(ddf, "/config/fpga.img", 0x160000, 0x80000, 1, 0)) == 1) + stat |= 1; + if (res == -1) + if ((res = update_image(ddf, "/boot/fpga.img", 0x160000, 0x80000, 1, 0)) == 1) + stat |= 1; + + } + } +#endif + break; case 0x320: //fname="/boot/DVBNetV1A_DD01_0300.bit"; diff --git a/apps/octonet/ddtest.c b/apps/octonet/ddtest.c index 3941029..221ff90 100644 --- a/apps/octonet/ddtest.c +++ b/apps/octonet/ddtest.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -12,8 +13,6 @@ #include "flash.h" -static uint32_t linknr = 0; - typedef int (*COMMAND_FUNCTION)(int dev, int argc, char* argv[], uint32_t Flags); enum { @@ -21,17 +20,6 @@ enum { SILENT_FLAG = 0x00000002, }; -enum { - UNKNOWN_FLASH = 0, - ATMEL_AT45DB642D = 1, - SSTI_SST25VF016B = 2, - SSTI_SST25VF032B = 3, - SSTI_SST25VF064C = 4, - SPANSION_S25FL116K = 5, - SPANSION_S25FL132K = 6, - SPANSION_S25FL164K = 7, -}; - struct SCommand { char* Name; @@ -42,94 +30,25 @@ struct SCommand // -------------------------------------------------------------------------------------------- -void Dump(const uint8_t *b, uint32_t start, int l) -{ - int i, j; - - for (j = 0; j < l; j += 16, b += 16) { - printf("%08x: ", start + j); - for (i = 0; i < 16; i++) - if (i + j < l) - printf("%02x ", b[i]); - else - printf(" "); - printf(" |"); - for (i = 0; i < 16; i++) - if (i + j < l) - putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.'); - printf("|\n"); - } -} - -int readreg(int dev, uint32_t RegAddress, uint32_t *pRegValue) -{ - struct ddb_reg reg = { .reg = RegAddress }; - int ret; - - ret = ioctl(dev, IOCTL_DDB_READ_REG, ®); - if (ret < 0) - return ret; - if (pRegValue) - *pRegValue = reg.val; - return 0; -} - -int writereg(int dev, uint32_t RegAddress, uint32_t RegValue) -{ - struct ddb_reg reg = { .reg = RegAddress, .val = RegValue}; - - return ioctl(dev, IOCTL_DDB_WRITE_REG, ®); -} - -int FlashIO(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen) -{ - struct ddb_flashio fio = { - .write_buf=wbuf, - .write_len=wlen, - .read_buf=rbuf, - .read_len=rlen, - .link=linknr, - }; - - return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio); -} - -int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len) -{ - int ret; - uint8_t cmd[4]; - uint32_t l; - - while (len) { - cmd[0] = 3; - cmd[1] = (addr >> 16) & 0xff; - cmd[2] = (addr >> 8) & 0xff; - cmd[3] = addr & 0xff; - - if (len > 1024) - l = 1024; - else - l = len; - ret = FlashIO(ddb, cmd, 4, buf, l); - if (ret < 0) - return ret; - addr += l; - buf += l; - len -= l; - } - return 0; -} int ReadFlash(int ddb, int argc, char *argv[], uint32_t Flags) { uint32_t Start; uint32_t Len; uint8_t *Buffer; + int fd; if (argc < 2 ) return -1; Start = strtoul(argv[0],NULL,16); Len = strtoul(argv[1],NULL,16); + if (argc == 3) { + fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC); + if (fd < 0) { + printf("Could not open file %s\n", argv[2]); + return -1; + } + } Buffer = malloc(Len); if (flashread(ddb, Buffer, Start, Len) < 0) { @@ -138,68 +57,43 @@ int ReadFlash(int ddb, int argc, char *argv[], uint32_t Flags) return 0; } - Dump(Buffer,Start,Len); + if (argc == 3) { + write(fd, Buffer, Len); + close(fd); + } else + Dump(Buffer,Start,Len); free(Buffer); return 0; } -int FlashDetect(int dev) +int ReadSave(int ddb, int argc, char *argv[], uint32_t Flags) { - uint8_t Cmd = 0x9F; - uint8_t Id[3]; - - int r = FlashIO(dev, &Cmd, 1, Id, 3); - if (r < 0) - return r; - - if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x41) - r = SSTI_SST25VF016B; - else if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4A) - r = SSTI_SST25VF032B; - else if ( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4B ) - r = SSTI_SST25VF064C; - else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x15 ) - r = SPANSION_S25FL116K; - else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x16 ) - r = SPANSION_S25FL132K; - else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x17 ) - r = SPANSION_S25FL164K; - else if ( Id[0] == 0x1F && Id[1] == 0x28) - r = ATMEL_AT45DB642D; - else - r = UNKNOWN_FLASH; - - switch(r) { - case UNKNOWN_FLASH : - printf("Unknown Flash Flash ID = %02x %02x %02x\n",Id[0],Id[1],Id[2]); - break; - case ATMEL_AT45DB642D : - printf("Flash: Atmel AT45DB642D 64 MBit\n"); - break; - case SSTI_SST25VF016B : - printf("Flash: SSTI SST25VF016B 16 MBit\n"); - break; - case SSTI_SST25VF032B : - printf("Flash: SSTI SST25VF032B 32 MBit\n"); - break; - case SSTI_SST25VF064C : - printf("Flash: SSTI SST25VF064C 64 MBit\n"); - break; - case SPANSION_S25FL116K : - printf("Flash: SPANSION S25FL116K 16 MBit\n"); - break; - case SPANSION_S25FL132K : - printf("Flash: SPANSION S25FL132K 32 MBit\n"); - break; - case SPANSION_S25FL164K : - printf("Flash: SPANSION S25FL164K 64 MBit\n"); - break; + uint32_t Start; + uint32_t Len; + uint8_t *Buffer; + int fd; + + if (argc < 3 ) + return -1; + Start = strtoul(argv[0],NULL,16); + Len = strtoul(argv[1],NULL,16); + + Buffer = malloc(Len); + if (flashread(ddb, Buffer, Start, Len) < 0) { + printf("flashread error\n"); + free(Buffer); + return 0; } - return r; + + + + free(Buffer); + return 0; } + int FlashChipEraseAtmel(int dev) { int err = 0; @@ -214,12 +108,12 @@ int FlashChipEraseAtmel(int dev) Cmd[1] = ( (( i ) >> 16) & 0xFF ); Cmd[2] = ( (( i ) >> 8) & 0xFF ); Cmd[3] = 0x00; - err = FlashIO(dev,Cmd,4,NULL,0); + err = flashio(dev,Cmd,4,NULL,0); if( err < 0 ) break; while (1) { Cmd[0] = 0xD7; // Read Status register - err = FlashIO(dev,Cmd,1,&Cmd[0],1); + err = flashio(dev,Cmd,1,&Cmd[0],1); if( err < 0 ) break; if( (Cmd[0] & 0x80) == 0x80 ) break; } @@ -237,25 +131,25 @@ int FlashChipEraseSSTI(int dev) do { Cmd[0] = 0x50; // EWSR - err = FlashIO(dev,Cmd,1,NULL,0); + err = flashio(dev,Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x01; // WRSR Cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = FlashIO(dev,Cmd,2,NULL,0); + err = flashio(dev,Cmd,2,NULL,0); if( err < 0 ) break; Cmd[0] = 0x06; // WREN - err = FlashIO(dev,Cmd,1,NULL,0); + err = flashio(dev,Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x60; // CHIP Erase - err = FlashIO(dev,Cmd,1,NULL,0); + err = flashio(dev,Cmd,1,NULL,0); if( err < 0 ) break; while(1) { Cmd[0] = 0x05; // RDRS - err = FlashIO(dev,Cmd,1,&Cmd[0],1); + err = flashio(dev,Cmd,1,&Cmd[0],1); if( err < 0 ) break; if( (Cmd[0] & 0x01) == 0 ) break; } @@ -263,12 +157,12 @@ int FlashChipEraseSSTI(int dev) break; Cmd[0] = 0x50; // EWSR - err = FlashIO(dev,Cmd,1,NULL,0); + err = flashio(dev,Cmd,1,NULL,0); if( err < 0 ) break; Cmd[0] = 0x01; // WRSR Cmd[1] = 0x1C; // BPx = 0, Lock all blocks - err = FlashIO(dev,Cmd,2,NULL,0); + err = flashio(dev,Cmd,2,NULL,0); } while(0); @@ -278,286 +172,6 @@ int FlashChipEraseSSTI(int dev) } -int FlashWriteAtmel(int dev,uint32_t FlashOffset,uint8_t * Buffer,int BufferSize) -{ - int err = 0, i; - int BlockErase = BufferSize >= 8192; - uint8_t Cmd[4]; - - if( BlockErase ) { - for(i = 0; i < BufferSize; i += 8192 ) { - if( (i & 0xFFFF) == 0 ) - { - printf(" Erase %08x\n",FlashOffset + i); - } - Cmd[0] = 0x50; // Block Erase - Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - err = FlashIO(dev,Cmd,4,NULL,0); - if( err < 0 ) break; - - while(1) { - Cmd[0] = 0xD7; // Read Status register - err = FlashIO(dev,Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x80) == 0x80 ) break; - } - } - } - - for(i = 0; i < BufferSize; i += 1024 ) - { - if( (i & 0xFFFF) == 0 ) - { - printf(" Programm %08x\n",FlashOffset + i); - } - uint8_t Cmd[4 + 1024]; - Cmd[0] = 0x84; // Buffer 1 - Cmd[1] = 0x00; - Cmd[2] = 0x00; - Cmd[3] = 0x00; - memcpy(&Cmd[4],&Buffer[i],1024); - - err = FlashIO(dev,Cmd,4 + 1024,NULL,0); - if( err < 0 ) break; - - Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase) - Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - - err = FlashIO(dev,Cmd,4,NULL,0); - if( err < 0 ) break; - - while(1) - { - Cmd[0] = 0xD7; // Read Status register - err = FlashIO(dev,Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x80) == 0x80 ) break; - } - if( err < 0 ) break; - } - return err; -} - -// ************************************************************************************** -// BUG: Erasing and writing an incomplete image will result in an failure to boot golden image. -// FIX: Write the new image from high to low addresses - -int FlashWriteSSTI(int dev,uint32_t FlashOffset,uint8_t * Buffer,int BufferSize) -{ - int err = 0, i, j; - uint8_t Cmd[6]; - - if( (BufferSize % 4096) != 0 ) return -1; // Must be multiple of sector size - - do - { - Cmd[0] = 0x50; // EWSR - err = FlashIO(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x01; // WRSR - Cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = FlashIO(dev,Cmd,2,NULL,0); - if( err < 0 ) break; - - for (i = 0; i < BufferSize; i += 4096 ) - { - if( (i & 0xFFFF) == 0 ) - { - printf(" Erase %08x\n",FlashOffset + i); - } - - Cmd[0] = 0x06; // WREN - err = FlashIO(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x20; // Sector erase ( 4Kb) - Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - err = FlashIO(dev,Cmd,4,NULL,0); - if( err < 0 ) break; - - while(1) - { - Cmd[0] = 0x05; // RDRS - err = FlashIO(dev,Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x01) == 0 ) break; - } - if( err < 0 ) break; - - } - if( err < 0 ) break; - - - for (j = BufferSize - 4096; j >= 0; j -= 4096 ) - { - if( (j & 0xFFFF) == 0 ) - { - printf(" Programm %08x\n",FlashOffset + j); - } - - for (i = 0; i < 4096; i += 2 ) - { - - if( i == 0 ) - { - Cmd[0] = 0x06; // WREN - err = FlashIO(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0xAD; // AAI - Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - Cmd[4] = Buffer[j+i]; - Cmd[5] = Buffer[j+i+1]; - err = FlashIO(dev,Cmd,6,NULL,0); - } - else - { - Cmd[0] = 0xAD; // AAI - Cmd[1] = Buffer[j+i]; - Cmd[2] = Buffer[j+i+1]; - err = FlashIO(dev,Cmd,3,NULL,0); - } - if( err < 0 ) break; - - while(1) - { - Cmd[0] = 0x05; // RDRS - err = FlashIO(dev,Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x01) == 0 ) break; - } - if( err < 0 ) break; - } - if( err < 0 ) break; - - Cmd[0] = 0x04; // WDIS - err = FlashIO(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - } - if( err < 0 ) break; - - - Cmd[0] = 0x50; // EWSR - err = FlashIO(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x01; // WRSR - Cmd[1] = 0x1C; // BPx = 0, Lock all blocks - err = FlashIO(dev,Cmd,2,NULL,0); - - } - while(0); - return err; -} - - - -int FlashWritePageMode(int dev, uint32_t FlashOffset, - uint8_t *Buffer,int BufferSize,uint8_t LockBits) -{ - int err = 0; - uint8_t Cmd[260]; - int i, j; - - if( (BufferSize % 4096) != 0 ) return -1; // Must be multiple of sector size - - do - { - Cmd[0] = 0x50; // EWSR - err = FlashIO(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x01; // WRSR - Cmd[1] = 0x00; // BPx = 0, Unlock all blocks - err = FlashIO(dev,Cmd,2,NULL,0); - if( err < 0 ) break; - - for(i = 0; i < BufferSize; i += 4096 ) - { - if( (i & 0xFFFF) == 0 ) - { - printf(" Erase %08x\n",FlashOffset + i); - } - - Cmd[0] = 0x06; // WREN - err = FlashIO(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x20; // Sector erase ( 4Kb) - Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - err = FlashIO(dev,Cmd,4,NULL,0); - if( err < 0 ) break; - - while(1) - { - Cmd[0] = 0x05; // RDRS - err = FlashIO(dev,Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x01) == 0 ) break; - } - if( err < 0 ) break; - - } - if( err < 0 ) break; - - - for(j = BufferSize - 256; j >= 0; j -= 256 ) - { - if( (j & 0xFFFF) == 0 ) - { - printf(" Programm %08x\n",FlashOffset + j); - } - - Cmd[0] = 0x06; // WREN - err = FlashIO(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x02; // PP - Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); - Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); - Cmd[3] = 0x00; - memcpy(&Cmd[4],&Buffer[j],256); - err = FlashIO(dev,Cmd,260,NULL,0); - if( err < 0 ) break; - - while(1) - { - Cmd[0] = 0x05; // RDRS - err = FlashIO(dev,Cmd,1,&Cmd[0],1); - if( err < 0 ) break; - if( (Cmd[0] & 0x01) == 0 ) break; - } - if( err < 0 ) break; - - } - if( err < 0 ) break; - - Cmd[0] = 0x50; // EWSR - err = FlashIO(dev,Cmd,1,NULL,0); - if( err < 0 ) break; - - Cmd[0] = 0x01; // WRSR - Cmd[1] = LockBits; // BPx = 0, Lock all blocks - err = FlashIO(dev,Cmd,2,NULL,0); - - } - while(0); - return err; -} - -// -------------------------------------------------------------------------------------------- int ReadDeviceMemory(int dev,int argc, char* argv[],uint32_t Flags) { @@ -693,7 +307,7 @@ int GetSetRegister(int dev,int argc, char* argv[],uint32_t Flags) // ----------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------- -int FlashIOC(int dev,int argc, char* argv[],uint32_t Flags) +int flashioc(int dev,int argc, char* argv[],uint32_t Flags) { uint8_t *Buffer; uint32_t tmp = 0, i; @@ -718,7 +332,7 @@ int FlashIOC(int dev,int argc, char* argv[],uint32_t Flags) Buffer[i] = (uint8_t) tmp; } - if( FlashIO(dev,Buffer,WriteLen,Buffer,ReadLen) < 0 ) + if( flashio(dev,Buffer,WriteLen,Buffer,ReadLen) < 0 ) { return 0; } @@ -1655,7 +1269,7 @@ 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); + r = flashio(dev, cmd, 5, val, 1); if (r < 0) return r; return 0; @@ -1667,7 +1281,7 @@ static int read_sst_id(int dev, uint8_t *id) uint8_t buf[9]; int r; - r = FlashIO(dev, cmd, 2, buf, 9); + r = flashio(dev, cmd, 2, buf, 9); if (r < 0) return r; memcpy(id, buf + 1, 8); @@ -1696,10 +1310,10 @@ int read_id(int dev, int argc, char* argv[], uint32_t Flags) break; default: printf("Unsupported Flash\n"); - break; + return -1; } printf("ID: "); - for (i = 0; i < 8; i++) + for (i = 0; i < len; i++) printf("%02x ", Id[i]); printf("\n"); @@ -1712,13 +1326,13 @@ struct SCommand CommandTable[] = { "memwrite", WriteDeviceMemory, 1, "Write Device Memory : memwrite .." }, { "register", GetSetRegister, 1, "Get/Set Register : reg |<[0x]regnum> [[0x]value(32)]" }, - { "flashread", ReadFlash, 1, "Read Flash : flashread " }, - { "flashio", FlashIOC, 1, "Flash IO : flashio .. " }, + { "flashread", ReadFlash, 1, "Read Flash : flashread []" }, + { "flashio", flashioc, 1, "Flash IO : flashio .. " }, { "flashprog", FlashProg, 1, "Flash Programming : flashprog [
]" }, { "flashprog", FlashProg, 1, "Flash Programming : flashprog -SubVendorID " }, { "flashprog", FlashProg, 1, "Flash Programming : flashprog -Jump
" }, { "flashverify", FlashVerify, 1, "Flash Verify : flashverify [
]" }, - { "flasherase", FlashErase, 1, "FlashErase : flasherase" }, + //{ "flasherase", FlashErase, 1, "FlashErase : flasherase" }, //{ "flashtest", FlashTest, 1, "FlashTest : flashtest" }, diff --git a/apps/octonet/flash.c b/apps/octonet/flash.c new file mode 100644 index 0000000..7ccfb61 --- /dev/null +++ b/apps/octonet/flash.c @@ -0,0 +1,614 @@ +enum { + UNKNOWN_FLASH = 0, + ATMEL_AT45DB642D = 1, + SSTI_SST25VF016B = 2, + SSTI_SST25VF032B = 3, + SSTI_SST25VF064C = 4, + SPANSION_S25FL116K = 5, + SPANSION_S25FL132K = 6, + SPANSION_S25FL164K = 7, +}; + +static uint32_t linknr = 0; + +int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen) +{ + struct ddb_flashio fio = { + .write_buf=wbuf, + .write_len=wlen, + .read_buf=rbuf, + .read_len=rlen, + .link=linknr, + }; + + return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio); +} + +int FlashDetect(int dev) +{ + uint8_t Cmd = 0x9F; + uint8_t Id[3]; + + int r = flashio(dev, &Cmd, 1, Id, 3); + if (r < 0) + return r; + + if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x41) + r = SSTI_SST25VF016B; + else if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4A) + r = SSTI_SST25VF032B; + else if ( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4B ) + r = SSTI_SST25VF064C; + else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x15 ) + r = SPANSION_S25FL116K; + else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x16 ) + r = SPANSION_S25FL132K; + else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x17 ) + r = SPANSION_S25FL164K; + else if ( Id[0] == 0x1F && Id[1] == 0x28) + r = ATMEL_AT45DB642D; + else + r = UNKNOWN_FLASH; + + switch(r) { + case UNKNOWN_FLASH : + printf("Unknown Flash Flash ID = %02x %02x %02x\n",Id[0],Id[1],Id[2]); + break; + case ATMEL_AT45DB642D : + printf("Flash: Atmel AT45DB642D 64 MBit\n"); + break; + case SSTI_SST25VF016B : + printf("Flash: SSTI SST25VF016B 16 MBit\n"); + break; + case SSTI_SST25VF032B : + printf("Flash: SSTI SST25VF032B 32 MBit\n"); + break; + case SSTI_SST25VF064C : + printf("Flash: SSTI SST25VF064C 64 MBit\n"); + break; + case SPANSION_S25FL116K : + printf("Flash: SPANSION S25FL116K 16 MBit\n"); + break; + case SPANSION_S25FL132K : + printf("Flash: SPANSION S25FL132K 32 MBit\n"); + break; + case SPANSION_S25FL164K : + printf("Flash: SPANSION S25FL164K 64 MBit\n"); + break; + } + return r; +} + + +static int flashdetect(int fd, uint32_t *sector_size, uint32_t *flash_size) +{ + uint8_t cmd = 0x9F; + uint8_t id[3]; + int flash_type; + + int r = flashio(fd, &cmd, 1, id, 3); + if (r < 0) + return r; + + if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x41) { + flash_type = SSTI_SST25VF016B; + printf("Flash: SSTI SST25VF016B 16 MBit\n"); + *sector_size = 4096; + *flash_size = 0x200000; + } else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4A) { + flash_type = SSTI_SST25VF032B; + printf("Flash: SSTI SST25VF032B 32 MBit\n"); + *sector_size = 4096; + *flash_size = 0x400000; + } else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4B) { + flash_type = SSTI_SST25VF064C; + printf("Flash: SSTI SST25VF064C 64 MBit\n"); + *sector_size = 4096; + *flash_size = 0x800000; + } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x15) { + flash_type = SPANSION_S25FL116K; + printf("Flash: SPANSION S25FL116K 16 MBit\n"); + *sector_size = 4096; + *flash_size = 0x200000; + } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x16) { + flash_type = SPANSION_S25FL132K; + printf("Flash: SPANSION S25FL132K 32 MBit\n"); + *sector_size = 4096; + *flash_size = 0x400000; + } else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x17) { + flash_type = SPANSION_S25FL164K; + printf("Flash: SPANSION S25FL164K 64 MBit\n"); + *sector_size = 4096; + *flash_size = 0x800000; + } else if (id[0] == 0x1F && id[1] == 0x28) { + flash_type = ATMEL_AT45DB642D; + printf("Flash: Atmel AT45DB642D 64 MBit\n"); + *sector_size = 1024; + *flash_size = 0x800000; + } else { + printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]); + return -1; + } + return flash_type; +} + + +#if 1 +int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len) +{ + int ret; + uint8_t cmd[4]; + uint32_t l; + + while (len) { + cmd[0] = 3; + cmd[1] = (addr >> 16) & 0xff; + cmd[2] = (addr >> 8) & 0xff; + cmd[3] = addr & 0xff; + + if (len > 1024) + l = 1024; + else + l = len; + ret = flashio(ddb, cmd, 4, buf, l); + if (ret < 0) + return ret; + addr += l; + buf += l; + len -= l; + } + return 0; +} +#else +static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len) +{ + uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff, + (addr >> 8) & 0xff, addr & 0xff}; + + return flashio(ddb, cmd, 4, buf, len); +} +#endif + +int flashdump(int ddb, uint32_t addr, uint32_t len) +{ + int i, j; + uint8_t buf[32]; + int bl = sizeof(buf); + + for (j=0; j 31 && b[i] < 127) ? b[i] : '.'); + printf("\n"); + } +} + +void Dump(const uint8_t *b, uint32_t start, int l) +{ + int i, j; + + for (j = 0; j < l; j += 16, b += 16) { + printf("%08x: ", start + j); + for (i = 0; i < 16; i++) + if (i + j < l) + printf("%02x ", b[i]); + else + printf(" "); + printf(" |"); + for (i = 0; i < 16; i++) + if (i + j < l) + putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.'); + printf("|\n"); + } +} + + + + +int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize) +{ + int err = 0; + int BlockErase = BufferSize >= 8192; + int i; + + if (BlockErase) { + for(i = 0; i < BufferSize; i += 8192 ) { + uint8_t Cmd[4]; + if( (i & 0xFFFF) == 0 ) + printf(" Erase %08x\n",FlashOffset + i); + Cmd[0] = 0x50; // Block Erase + Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); + Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); + Cmd[3] = 0x00; + err = flashio(dev,Cmd,4,NULL,0); + if( err < 0 ) break; + + while( 1 ) + { + Cmd[0] = 0xD7; // Read Status register + err = flashio(dev,Cmd,1,&Cmd[0],1); + if( err < 0 ) break; + if( (Cmd[0] & 0x80) == 0x80 ) break; + } + } + } + + for(i = 0; i < BufferSize; i += 1024 ) + { + uint8_t Cmd[4 + 1024]; + if( (i & 0xFFFF) == 0 ) + { + printf(" Program %08x\n",FlashOffset + i); + } + Cmd[0] = 0x84; // Buffer 1 + Cmd[1] = 0x00; + Cmd[2] = 0x00; + Cmd[3] = 0x00; + memcpy(&Cmd[4],&Buffer[i],1024); + + err = flashio(dev,Cmd,4 + 1024,NULL,0); + if( err < 0 ) break; + + Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase) + Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); + Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); + Cmd[3] = 0x00; + + err = flashio(dev,Cmd,4,NULL,0); + if( err < 0 ) break; + + while( 1 ) + { + Cmd[0] = 0xD7; // Read Status register + err = flashio(dev,Cmd,1,&Cmd[0],1); + if( err < 0 ) break; + if( (Cmd[0] & 0x80) == 0x80 ) break; + } + if( err < 0 ) break; + } + return err; +} + + +int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize) +{ + int err = 0; + uint8_t cmd[6]; + int i, j; + + // Must be multiple of sector size + if ((BufferSize % 4096) != 0 ) + return -1; + + do { + cmd[0] = 0x50; // EWSR + err = flashio(dev,cmd,1,NULL,0); + if (err < 0 ) + break; + + cmd[0] = 0x01; // WRSR + cmd[1] = 0x00; // BPx = 0, Unlock all blocks + err = flashio(dev,cmd,2,NULL,0); + if (err < 0 ) + break; + + for (i = 0; i < BufferSize; i += 4096 ) { + if ((i & 0xFFFF) == 0 ) + printf(" Erase %08x\n",FlashOffset + i); + cmd[0] = 0x06; // WREN + err = flashio(dev,cmd,1,NULL,0); + if (err < 0 ) + break; + + cmd[0] = 0x20; // Sector erase ( 4Kb) + cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); + cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); + cmd[3] = 0x00; + err = flashio(dev,cmd,4,NULL,0); + if (err < 0 ) + break; + + while(1) { + cmd[0] = 0x05; // RDRS + err = flashio(dev,cmd,1,&cmd[0],1); + if (err < 0 ) break; + if ((cmd[0] & 0x01) == 0 ) break; + } + if (err < 0 ) break; + } + if (err < 0 ) + break; + for (j = BufferSize - 4096; j >= 0; j -= 4096 ) { + if ((j & 0xFFFF) == 0 ) + printf(" Program %08x\n",FlashOffset + j); + + for (i = 0; i < 4096; i += 2 ) { + if (i == 0 ) { + cmd[0] = 0x06; // WREN + err = flashio(dev,cmd,1,NULL,0); + if (err < 0 ) + break; + + cmd[0] = 0xAD; // AAI + cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); + cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); + cmd[3] = 0x00; + cmd[4] = Buffer[j+i]; + cmd[5] = Buffer[j+i+1]; + err = flashio(dev,cmd,6,NULL,0); + } else { + cmd[0] = 0xAD; // AAI + cmd[1] = Buffer[j+i]; + cmd[2] = Buffer[j+i+1]; + err = flashio(dev,cmd,3,NULL,0); + } + if (err < 0 ) + break; + + while(1) { + cmd[0] = 0x05; // RDRS + err = flashio(dev,cmd,1,&cmd[0],1); + if (err < 0 ) break; + if ((cmd[0] & 0x01) == 0 ) break; + } + if (err < 0 ) break; + } + if (err < 0 ) break; + + cmd[0] = 0x04; // WDIS + err = flashio(dev,cmd,1,NULL,0); + if (err < 0 ) break; + + } + if (err < 0 ) break; + + cmd[0] = 0x50; // EWSR + err = flashio(dev,cmd,1,NULL,0); + if (err < 0 ) break; + + cmd[0] = 0x01; // WRSR + cmd[1] = 0x1C; // BPx = 0, Lock all blocks + err = flashio(dev,cmd,2,NULL,0); + } while(0); + return err; +} + +int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize) +{ + int err = 0; + uint8_t Cmd[6]; + int i, j; + + // Must be multiple of sector size + if( (BufferSize % 4096) != 0 ) + return -1; + + do { + Cmd[0] = 0x50; // EWSR + err = flashio(dev,Cmd,1,NULL,0); + if( err < 0 ) + break; + + Cmd[0] = 0x01; // WRSR + Cmd[1] = 0x00; // BPx = 0, Unlock all blocks + err = flashio(dev,Cmd,2,NULL,0); + if( err < 0 ) + break; + + for(i = 0; i < BufferSize; i += 4096 ) { + if( (i & 0xFFFF) == 0 ) + printf(" Erase %08x\n",FlashOffset + i); + Cmd[0] = 0x06; // WREN + err = flashio(dev,Cmd,1,NULL,0); + if( err < 0 ) + break; + + Cmd[0] = 0x20; // Sector erase ( 4Kb) + Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); + Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); + Cmd[3] = 0x00; + err = flashio(dev,Cmd,4,NULL,0); + if( err < 0 ) + break; + + while(1) { + Cmd[0] = 0x05; // RDRS + err = flashio(dev,Cmd,1,&Cmd[0],1); + if( err < 0 ) break; + if( (Cmd[0] & 0x01) == 0 ) break; + } + if( err < 0 ) break; + } + if( err < 0 ) + break; + for(j = BufferSize - 4096; j >= 0; j -= 4096 ) { + if( (j & 0xFFFF) == 0 ) + printf(" Program %08x\n",FlashOffset + j); + + for(i = 0; i < 4096; i += 2 ) { + if( i == 0 ) { + Cmd[0] = 0x06; // WREN + err = flashio(dev,Cmd,1,NULL,0); + if( err < 0 ) + break; + + Cmd[0] = 0xAD; // AAI + Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); + Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); + Cmd[3] = 0x00; + Cmd[4] = Buffer[j+i]; + Cmd[5] = Buffer[j+i+1]; + err = flashio(dev,Cmd,6,NULL,0); + } else { + Cmd[0] = 0xAD; // AAI + Cmd[1] = Buffer[j+i]; + Cmd[2] = Buffer[j+i+1]; + err = flashio(dev,Cmd,3,NULL,0); + } + if( err < 0 ) + break; + + while(1) { + Cmd[0] = 0x05; // RDRS + err = flashio(dev,Cmd,1,&Cmd[0],1); + if( err < 0 ) break; + if( (Cmd[0] & 0x01) == 0 ) break; + } + if( err < 0 ) break; + } + if( err < 0 ) break; + + Cmd[0] = 0x04; // WDIS + err = flashio(dev,Cmd,1,NULL,0); + if( err < 0 ) break; + + } + if( err < 0 ) break; + + Cmd[0] = 0x50; // EWSR + err = flashio(dev,Cmd,1,NULL,0); + if( err < 0 ) break; + + Cmd[0] = 0x01; // WRSR + Cmd[1] = 0x1C; // BPx = 0, Lock all blocks + err = flashio(dev,Cmd,2,NULL,0); + } while(0); + return err; +} + +int FlashWritePageMode(int dev, uint32_t FlashOffset, + uint8_t *Buffer,int BufferSize,uint8_t LockBits) +{ + int err = 0; + uint8_t Cmd[260]; + int i, j; + + if( (BufferSize % 4096) != 0 ) return -1; // Must be multiple of sector size + + do + { + Cmd[0] = 0x50; // EWSR + err = flashio(dev,Cmd,1,NULL,0); + if( err < 0 ) break; + + Cmd[0] = 0x01; // WRSR + Cmd[1] = 0x00; // BPx = 0, Unlock all blocks + err = flashio(dev,Cmd,2,NULL,0); + if( err < 0 ) break; + + for(i = 0; i < BufferSize; i += 4096 ) + { + if( (i & 0xFFFF) == 0 ) + { + printf(" Erase %08x\n",FlashOffset + i); + } + + Cmd[0] = 0x06; // WREN + err = flashio(dev,Cmd,1,NULL,0); + if( err < 0 ) break; + + Cmd[0] = 0x20; // Sector erase ( 4Kb) + Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF ); + Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF ); + Cmd[3] = 0x00; + err = flashio(dev,Cmd,4,NULL,0); + if( err < 0 ) break; + + while(1) + { + Cmd[0] = 0x05; // RDRS + err = flashio(dev,Cmd,1,&Cmd[0],1); + if( err < 0 ) break; + if( (Cmd[0] & 0x01) == 0 ) break; + } + if( err < 0 ) break; + + } + if( err < 0 ) break; + + + for(j = BufferSize - 256; j >= 0; j -= 256 ) + { + if( (j & 0xFFFF) == 0 ) + { + printf(" Programm %08x\n",FlashOffset + j); + } + + Cmd[0] = 0x06; // WREN + err = flashio(dev,Cmd,1,NULL,0); + if( err < 0 ) break; + + Cmd[0] = 0x02; // PP + Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF ); + Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF ); + Cmd[3] = 0x00; + memcpy(&Cmd[4],&Buffer[j],256); + err = flashio(dev,Cmd,260,NULL,0); + if( err < 0 ) break; + + while(1) + { + Cmd[0] = 0x05; // RDRS + err = flashio(dev,Cmd,1,&Cmd[0],1); + if( err < 0 ) break; + if( (Cmd[0] & 0x01) == 0 ) break; + } + if( err < 0 ) break; + + } + if( err < 0 ) break; + + Cmd[0] = 0x50; // EWSR + err = flashio(dev,Cmd,1,NULL,0); + if( err < 0 ) break; + + Cmd[0] = 0x01; // WRSR + Cmd[1] = LockBits; // BPx = 0, Lock all blocks + err = flashio(dev,Cmd,2,NULL,0); + + } + while(0); + return err; +} diff --git a/apps/octonet/flash.h b/apps/octonet/flash.h index 214d7b2..3b8c4c2 100644 --- a/apps/octonet/flash.h +++ b/apps/octonet/flash.h @@ -61,3 +61,5 @@ struct ddb_i2c_msg { #define IOCTL_DDB_WRITE_MDIO _IOR(DDB_MAGIC, 0x09, struct ddb_mdio) #define IOCTL_DDB_READ_I2C _IOWR(DDB_MAGIC, 0x0a, struct ddb_i2c_msg) #define IOCTL_DDB_WRITE_I2C _IOR(DDB_MAGIC, 0x0b, struct ddb_i2c_msg) + +#include "flash.c" diff --git a/apps/setmod2.c b/apps/setmod2.c index efd1e61..5d83ff7 100644 --- a/apps/setmod2.c +++ b/apps/setmod2.c @@ -39,9 +39,9 @@ int main() fd = open("/dev/dvb/adapter0/mod0", O_RDONLY); - set_property(fd, MOD_MODULATION, QAM_256); - set_property(fd, MOD_SYMBOL_RATE, 6900000); - set_property(fd, MOD_FREQUENCY, 114000000); + set_property(fd, MODULATOR_MODULATION, QAM_256); + set_property(fd, MODULATOR_SYMBOL_RATE, 6900000); + set_property(fd, MODULATOR_FREQUENCY, 114000000); close(fd); } diff --git a/ddbridge/ddbridge-core.c b/ddbridge/ddbridge-core.c index 33c1316..9b5eaad 100644 --- a/ddbridge/ddbridge-core.c +++ b/ddbridge/ddbridge-core.c @@ -46,6 +46,10 @@ static int fmode; module_param(fmode, int, 0444); MODULE_PARM_DESC(fmode, "frontend emulation mode"); +static int fmode_sat = -1; +module_param(fmode_sat, int, 0444); +MODULE_PARM_DESC(fmode_sat, "set frontend emulation mode sat"); + static int old_quattro; module_param(old_quattro, int, 0444); MODULE_PARM_DESC(old_quattro, "old quattro LNB input order "); @@ -66,6 +70,10 @@ static int no_init; module_param(no_init, int, 0444); MODULE_PARM_DESC(no_init, "do not initialize most devices"); +static int stv0910_single; +module_param(stv0910_single, int, 0444); +MODULE_PARM_DESC(no_init, "use stv0910 cards as single demods"); + #define DDB_MAX_ADAPTER 64 static struct ddb *ddbs[DDB_MAX_ADAPTER]; @@ -118,6 +126,12 @@ static struct ddb_regset octopus_mod_2_channel = { .size = 0x40, }; +static struct ddb_regset octopus_sdr_output = { + .base = 0x240, + .num = 0x14, + .size = 0x10, +}; + /****************************************************************************/ static struct ddb_regset octopus_input = { @@ -295,6 +309,16 @@ static struct ddb_regmap octopus_mod_2_map = { .channel = &octopus_mod_2_channel, }; +static struct ddb_regmap octopus_sdr_map = { + .irq_version = 2, + .irq_base_odma = 64, + .irq_base_rate = 32, + .output = &octopus_sdr_output, + .odma = &octopus_mod_2_odma, + .odma_buf = &octopus_mod_2_odma_buf, + .channel = &octopus_mod_2_channel, +}; + /****************************************************************************/ @@ -352,7 +376,7 @@ static struct ddb_info ddb_c2t2i_v0_8 = { .i2c_mask = 0x0f, .board_control = 0x0ff, .board_control_2 = 0xf00, - .ts_quirks = TS_QUIRK_SERIAL, + .ts_quirks = TS_QUIRK_SERIAL | TS_QUIRK_ALT_OSC, .tempmon_irq = 24, }; @@ -387,7 +411,7 @@ static void ddb_set_dma_table(struct ddb_io *io) ddbwritel(dev, mem & 0xffffffff, dma->bufregs + i * 8); ddbwritel(dev, mem >> 32, dma->bufregs + i * 8 + 4); } - dma->bufval = (dma->div << 16) | + dma->bufval = ((dma->div & 0x0f) << 16) | ((dma->num & 0x1f) << 11) | ((dma->size >> 7) & 0x7ff); } @@ -395,7 +419,7 @@ static void ddb_set_dma_table(struct ddb_io *io) static void ddb_set_dma_tables(struct ddb *dev) { u32 i; - + for (i = 0; i < DDB_MAX_PORT; i++) { if (dev->port[i].input[0]) ddb_set_dma_table(dev->port[i].input[0]); @@ -403,7 +427,7 @@ static void ddb_set_dma_tables(struct ddb *dev) ddb_set_dma_table(dev->port[i].input[1]); if (dev->port[i].output) ddb_set_dma_table(dev->port[i].output); - } + } } @@ -432,7 +456,7 @@ static int ddb_unredirect(struct ddb_port *port) struct ddb_input *oredi, *iredi = 0; struct ddb_output *iredo = 0; - /*pr_info("unredirect %d.%d\n", port->dev->nr, port->nr);*/ + /*pr_info("DDBridge: unredirect %d.%d\n", port->dev->nr, port->nr);*/ mutex_lock(&redirect_lock); if (port->output->dma->running) { mutex_unlock(&redirect_lock); @@ -628,13 +652,36 @@ static void ddb_buffers_free(struct ddb *dev) } } +/* + * Control: + * + * Bit 0 - Enable TS + * 1 - Reset + * 2 - clock enable + * 3 - clock phase + * 4 - gap enable + * 5 - send null packets on underrun + * 6 - enable clock gating + * 7 - set error bit on inserted null packets + * 8-10 - fine adjust clock delay + * 11- HS (high speed), if NCO mode=0: 0=72MHz 1=96Mhz + * 12- enable NCO mode + * + * Control 2: + * + * Bit 0-6 : gap_size, Gap = (gap_size * 2) + 4 + * 16-31: HS = 0: Speed = 72 * Value / 8192 MBit/s + * HS = 1: Speed = 72 * 8 / (Value + 1) MBit/s (only bit 19-16 used) + * + */ + static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags) { struct ddb *dev = output->port->dev; u32 bitrate = output->port->obr, max_bitrate = 72000; u32 gap = 4, nco = 0; - - *con = 0x1C; + + *con = 0x1C; if (output->port->gap != 0xffffffff) { flags |= 1; gap = output->port->gap; @@ -651,7 +698,8 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags) *con |= 0x800; else { *con |= 0x1000; - nco = (bitrate * 8192 + 71999) / 72000; + nco = (bitrate * + 8192 + 71999) / 72000; } } } else { @@ -660,7 +708,7 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags) if (bitrate <= 64000) { max_bitrate = 64000; nco = 8; - } else if( bitrate <= 72000) { + } else if (bitrate <= 72000) { max_bitrate = 72000; nco = 7; } else { @@ -689,7 +737,6 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags) gap = 127; } *con2 = (nco << 16) | gap; - return; } static void ddb_output_start(struct ddb_output *output) @@ -697,6 +744,7 @@ static void ddb_output_start(struct ddb_output *output) struct ddb *dev = output->port->dev; u32 con = 0x11c, con2 = 0; + pr_info("Channel Base = %08x\n", output->regs); if (output->dma) { spin_lock_irq(&output->dma->lock); output->dma->cbuf = 0; @@ -722,7 +770,7 @@ static void ddb_output_start(struct ddb_output *output) DMA_BUFFER_SIZE(output->dma)); ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma)); ddbwritel(dev, 1, DMA_BASE_READ); - ddbwritel(dev, 3, DMA_BUFFER_CONTROL(output->dma)); + ddbwritel(dev, 7, DMA_BUFFER_CONTROL(output->dma)); } if (output->port->class != DDB_PORT_MOD) ddbwritel(dev, con | 1, TS_CONTROL(output)); @@ -763,7 +811,8 @@ static void ddb_input_stop(struct ddb_input *input) spin_unlock_irq(&input->dma->lock); } /*printk("input_stop %u.%u.%u\n", - dev->nr, input->port->lnr, input->nr);*/ + * dev->nr, input->port->lnr, input->nr); + */ } static void ddb_input_start(struct ddb_input *input) @@ -928,7 +977,8 @@ static ssize_t ddb_output_write(struct ddb_output *output, dma_sync_single_for_device(dev->dev, output->dma->pbuf[ output->dma->cbuf], - output->dma->size, DMA_TO_DEVICE); + output->dma->size, + DMA_TO_DEVICE); left -= len; buf += len; output->dma->coff += len; @@ -1030,7 +1080,7 @@ static u32 ddb_input_avail(struct ddb_input *input) off = (stat & 0x7ff) << 7; if (ctrl & 4) { - pr_err("IA %d %d %08x\n", idx, off, ctrl); + pr_err("DDBridge: IA %d %d %08x\n", idx, off, ctrl); ddbwritel(dev, stat, DMA_BUFFER_ACK(input->dma)); return 0; } @@ -1058,8 +1108,10 @@ static size_t ddb_input_read(struct ddb_input *input, free = left; if (alt_dma) dma_sync_single_for_cpu(dev->dev, - input->dma->pbuf[input->dma->cbuf], - input->dma->size, DMA_FROM_DEVICE); + input->dma->pbuf[ + input->dma->cbuf], + input->dma->size, + DMA_FROM_DEVICE); ret = copy_to_user(buf, input->dma->vbuf[input->dma->cbuf] + input->dma->coff, free); if (ret) @@ -1308,7 +1360,7 @@ static int demod_attach_drxk(struct ddb_input *input) i2c, 0x29 + (input->nr & 1), &dvb->fe2); if (!fe) { - pr_err("No DRXK found!\n"); + pr_err("DDBridge: No DRXK found!\n"); return -ENODEV; } fe->sec_priv = input; @@ -1318,42 +1370,21 @@ static int demod_attach_drxk(struct ddb_input *input) } #endif -struct cxd2843_cfg cxd2843_0 = { - .adr = 0x6c, - .ts_clock = 1, -}; - -struct cxd2843_cfg cxd2843_1 = { - .adr = 0x6d, - .ts_clock = 1, -}; - -struct cxd2843_cfg cxd2843p_0 = { - .adr = 0x6c, - .parallel = 1, -}; - -struct cxd2843_cfg cxd2843p_1 = { - .adr = 0x6d, - .parallel = 1, -}; - -static int demod_attach_cxd2843(struct ddb_input *input, int par) +static int demod_attach_cxd2843(struct ddb_input *input, int par, int osc24) { struct i2c_adapter *i2c = &input->port->i2c->adap; struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; struct dvb_frontend *fe; + struct cxd2843_cfg cfg; + + cfg.adr = (input->nr & 1) ? 0x6d : 0x6c; + cfg.ts_clock = par ? 0 : 1; + cfg.parallel = par ? 1 : 0; + cfg.osc = osc24 ? 24000000 : 20500000; + fe = dvb->fe = dvb_attach(cxd2843_attach, i2c, &cfg); - if (par) - fe = dvb->fe = dvb_attach(cxd2843_attach, i2c, - (input->nr & 1) ? - &cxd2843p_1 : &cxd2843p_0); - else - fe = dvb->fe = dvb_attach(cxd2843_attach, i2c, - (input->nr & 1) ? - &cxd2843_1 : &cxd2843_0); if (!dvb->fe) { - pr_err("No cxd2837/38/43 found!\n"); + pr_err("DDBridge: No cxd2837/38/43/54 found!\n"); return -ENODEV; } fe->sec_priv = input; @@ -1376,7 +1407,7 @@ static int demod_attach_stv0367dd(struct ddb_input *input) &cfg, &dvb->fe2); if (!dvb->fe) { - pr_err("No stv0367 found!\n"); + pr_err("DDBridge: No stv0367 found!\n"); return -ENODEV; } fe->sec_priv = input; @@ -1397,7 +1428,7 @@ static int tuner_attach_tda18271(struct ddb_input *input) if (dvb->fe->ops.i2c_gate_ctrl) dvb->fe->ops.i2c_gate_ctrl(dvb->fe, 0); if (!fe) { - pr_err("No TDA18271 found!\n"); + pr_err("DDBridge: No TDA18271 found!\n"); return -ENODEV; } return 0; @@ -1412,7 +1443,7 @@ static int tuner_attach_tda18212dd(struct ddb_input *input) fe = dvb_attach(tda18212dd_attach, dvb->fe, i2c, (input->nr & 1) ? 0x63 : 0x60); if (!fe) { - pr_err("No TDA18212 found!\n"); + pr_err("DDBridge: No TDA18212 found!\n"); return -ENODEV; } return 0; @@ -1437,7 +1468,7 @@ static int tuner_attach_tda18212(struct ddb_input *input) cfg = (input->nr & 1) ? &tda18212_1 : &tda18212_0; fe = dvb_attach(tda18212_attach, dvb->fe, i2c, cfg); if (!fe) { - pr_err("No TDA18212 found!\n"); + pr_err("DDBridge: No TDA18212 found!\n"); return -ENODEV; } return 0; @@ -1514,13 +1545,13 @@ static int demod_attach_stv0900(struct ddb_input *input, int type) (input->nr & 1) ? STV090x_DEMODULATOR_1 : STV090x_DEMODULATOR_0); if (!dvb->fe) { - pr_err("No STV0900 found!\n"); + pr_err("DDBridge: No STV0900 found!\n"); return -ENODEV; } if (!dvb_attach(lnbh24_attach, dvb->fe, i2c, 0, 0, (input->nr & 1) ? (0x09 - type) : (0x0b - type))) { - pr_err("No LNBH24 found!\n"); + pr_err("DDBridge: No LNBH24 found!\n"); return -ENODEV; } return 0; @@ -1537,10 +1568,10 @@ static int tuner_attach_stv6110(struct ddb_input *input, int type) ctl = dvb_attach(stv6110x_attach, dvb->fe, tunerconf, i2c); if (!ctl) { - pr_err("No STV6110X found!\n"); + pr_err("DDBridge: No STV6110X found!\n"); return -ENODEV; } - pr_info("attach tuner input %d adr %02x\n", + pr_info("DDBridge: attach tuner input %d adr %02x\n", input->nr, tunerconf->addr); feconf->tuner_init = ctl->tuner_init; @@ -1571,6 +1602,8 @@ static int demod_attach_stv0910(struct ddb_input *input, int type) struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1]; struct stv0910_cfg cfg = stv0910_p; + if (stv0910_single) + cfg.single = 1; if (type) cfg.parallel = 2; dvb->fe = dvb_attach(stv0910_attach, i2c, &cfg, (input->nr & 1)); @@ -1580,14 +1613,14 @@ static int demod_attach_stv0910(struct ddb_input *input, int type) &cfg, (input->nr & 1)); } if (!dvb->fe) { - pr_err("No STV0910 found!\n"); + pr_err("DDBridge: No STV0910 found!\n"); return -ENODEV; } if (!dvb_attach(lnbh25_attach, dvb->fe, i2c, ((input->nr & 1) ? 0x0d : 0x0c))) { if (!dvb_attach(lnbh25_attach, dvb->fe, i2c, ((input->nr & 1) ? 0x09 : 0x08))) { - pr_err("No LNBH25 found!\n"); + pr_err("DDBridge: No LNBH25 found!\n"); return -ENODEV; } } @@ -1605,7 +1638,7 @@ static int tuner_attach_stv6111(struct ddb_input *input, int type) if (!fe) { fe = dvb_attach(stv6111_attach, dvb->fe, i2c, adr & ~4); if (!fe) { - pr_err("No STV6111 found at 0x%02x!\n", adr); + pr_err("DDBridge: No STV6111 found at 0x%02x!\n", adr); return -ENODEV; } } @@ -1627,7 +1660,8 @@ static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd) msleep(20); } if (c == 10) - pr_info("lnb_command lnb = %08x cmd = %08x\n", lnb, cmd); + pr_info("DDBridge: lnb_command lnb = %08x cmd = %08x\n", + lnb, cmd); return 0; } @@ -1656,6 +1690,31 @@ static int max_send_master_cmd(struct dvb_frontend *fe, return 0; } +static int lnb_send_diseqc(struct ddb *dev, u32 link, u32 input, + struct dvb_diseqc_master_cmd *cmd) +{ + u32 tag = DDB_LINK_TAG(link); + int i; + + ddbwritel(dev, 0, tag | LNB_BUF_LEVEL(input)); + for (i = 0; i < cmd->msg_len; i++) + ddbwritel(dev, cmd->msg[i], tag | LNB_BUF_WRITE(input)); + lnb_command(dev, link, input, LNB_CMD_DISEQC); + return 0; +} + +static int lnb_set_sat(struct ddb *dev, u32 link, + u32 input, u32 sat, u32 band, u32 hor) +{ + struct dvb_diseqc_master_cmd cmd = { + .msg = {0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, + .msg_len = 4 + }; + cmd.msg[3] = 0xf0 | (((sat << 2) & 0x0c) | + (band ? 1 : 0) | (hor ? 2 : 0)); + return lnb_send_diseqc(dev, link, input, &cmd); +} + static int lnb_set_tone(struct ddb *dev, u32 link, u32 input, fe_sec_tone_mode_t tone) { @@ -1894,7 +1953,7 @@ static int mxl_fw_read(void *priv, u8 *buf, u32 len) struct ddb_link *link = priv; struct ddb *dev = link->dev; - pr_info("Read mxl_fw from link %u\n", link->nr); + pr_info("DDBridge: Read mxl_fw from link %u\n", link->nr); return ddbridge_flashread(dev, link->nr, buf, 0xc0000, len); } @@ -1905,9 +1964,20 @@ static int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm) if (link->lnb.fmode == fm) return 0; - pr_info("Set fmode link %u = %u\n", l, fm); + pr_info("DDBridge: Set fmode link %u = %u\n", l, fm); mutex_lock(&link->lnb.lock); if (fm == 2 || fm == 1) { + if (fmode_sat >= 0) { + lnb_set_sat(dev, l, 0, fmode_sat, 0, 0); + if (old_quattro) { + lnb_set_sat(dev, l, 1, fmode_sat, 0, 1); + lnb_set_sat(dev, l, 2, fmode_sat, 1, 0); + } else { + lnb_set_sat(dev, l, 1, fmode_sat, 1, 0); + lnb_set_sat(dev, l, 2, fmode_sat, 0, 1); + } + lnb_set_sat(dev, l, 3, fmode_sat, 1, 1); + } lnb_set_tone(dev, l, 0, SEC_TONE_OFF); if (old_quattro) { lnb_set_tone(dev, l, 1, SEC_TONE_OFF); @@ -1953,7 +2023,7 @@ static int fe_attach_mxl5xx(struct ddb_input *input) tuner = 0; dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, demod, tuner); if (!dvb->fe) { - pr_err("No MXL5XX found!\n"); + pr_err("DDBridge: No MXL5XX found!\n"); return -ENODEV; } if (input->nr < 4) { @@ -1975,46 +2045,6 @@ static int fe_attach_mxl5xx(struct ddb_input *input) return 0; } -static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, - int (*start_feed)(struct dvb_demux_feed *), - int (*stop_feed)(struct dvb_demux_feed *), - void *priv) -{ - dvbdemux->priv = priv; - - dvbdemux->filternum = 256; - dvbdemux->feednum = 256; - dvbdemux->start_feed = start_feed; - dvbdemux->stop_feed = stop_feed; - dvbdemux->write_to_decoder = NULL; - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | - DMX_SECTION_FILTERING | - DMX_MEMORY_BASED_FILTERING); - return dvb_dmx_init(dvbdemux); -} - -static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, - struct dvb_demux *dvbdemux, - struct dmx_frontend *hw_frontend, - struct dmx_frontend *mem_frontend, - struct dvb_adapter *dvb_adapter) -{ - int ret; - - dmxdev->filternum = 256; - dmxdev->demux = &dvbdemux->dmx; - dmxdev->capabilities = 0; - ret = dvb_dmxdev_init(dmxdev, dvb_adapter); - if (ret < 0) - return ret; - - hw_frontend->source = DMX_FRONTEND_0; - dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); - mem_frontend->source = DMX_MEMORY_FE; - dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); - return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); -} - #if 0 static int start_input(struct ddb_input *input) { @@ -2086,12 +2116,13 @@ static void dvb_input_detach(struct ddb_input *input) case 0x20: dvb_net_release(&dvb->dvbnet); /* fallthrough */ - case 0x11: - dvbdemux->dmx.close(&dvbdemux->dmx); + case 0x12: dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &dvb->hw_frontend); dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, &dvb->mem_frontend); + /* fallthrough */ + case 0x11: dvb_dmxdev_release(&dvb->dmxdev); /* fallthrough */ case 0x10: @@ -2210,25 +2241,37 @@ static int dvb_input_attach(struct ddb_input *input) struct ddb_port *port = input->port; struct dvb_adapter *adap = dvb->adap; struct dvb_demux *dvbdemux = &dvb->demux; - int par = 0; + int par = 0, osc24 = 0; dvb->attached = 0x01; - ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", - start_feed, - stop_feed, input); + dvbdemux->priv = input; + dvbdemux->dmx.capabilities = DMX_TS_FILTERING | + DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING; + dvbdemux->start_feed = start_feed; + dvbdemux->stop_feed = stop_feed; + dvbdemux->filternum = dvbdemux->feednum = 256; + ret = dvb_dmx_init(dvbdemux); if (ret < 0) return ret; dvb->attached = 0x10; - ret = my_dvb_dmxdev_ts_card_init(&dvb->dmxdev, - &dvb->demux, - &dvb->hw_frontend, - &dvb->mem_frontend, adap); + dvb->dmxdev.filternum = 256; + dvb->dmxdev.demux = &dvbdemux->dmx; + ret = dvb_dmxdev_init(&dvb->dmxdev, adap); if (ret < 0) return ret; dvb->attached = 0x11; + dvb->mem_frontend.source = DMX_MEMORY_FE; + dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->mem_frontend); + dvb->hw_frontend.source = DMX_FRONTEND_0; + dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->hw_frontend); + ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &dvb->hw_frontend); + if (ret < 0) + return ret; + dvb->attached = 0x12; + ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux); if (ret < 0) return ret; @@ -2290,6 +2333,12 @@ static int dvb_input_attach(struct ddb_input *input) if (tuner_attach_tda18212dd(input) < 0) return -ENODEV; break; + case DDB_TUNER_DVBC2T2I_SONY_P: + if (input->port->dev->link[input->port->lnr].info->ts_quirks & + TS_QUIRK_ALT_OSC) + osc24 = 0; + else + osc24 = 1; case DDB_TUNER_DVBCT2_SONY_P: case DDB_TUNER_DVBC2T2_SONY_P: case DDB_TUNER_ISDBT_SONY_P: @@ -2298,10 +2347,17 @@ static int dvb_input_attach(struct ddb_input *input) par = 0; else par = 1; + if (demod_attach_cxd2843(input, par, osc24) < 0) + return -ENODEV; + if (tuner_attach_tda18212dd(input) < 0) + return -ENODEV; + break; + case DDB_TUNER_DVBC2T2I_SONY: + osc24 = 1; case DDB_TUNER_DVBCT2_SONY: case DDB_TUNER_DVBC2T2_SONY: case DDB_TUNER_ISDBT_SONY: - if (demod_attach_cxd2843(input, par) < 0) + if (demod_attach_cxd2843(input, 0, osc24) < 0) return -ENODEV; if (tuner_attach_tda18212dd(input) < 0) return -ENODEV; @@ -2310,6 +2366,7 @@ static int dvb_input_attach(struct ddb_input *input) return 0; } dvb->attached = 0x30; + if (dvb->fe) { if (dvb_register_frontend(adap, dvb->fe) < 0) return -ENODEV; @@ -2333,7 +2390,7 @@ static int port_has_encti(struct ddb_port *port) int ret = i2c_read_reg(&port->i2c->adap, 0x20, 0, &val); if (!ret) - pr_info("[0x20]=0x%02x\n", val); + pr_info("DDBridge: [0x20]=0x%02x\n", val); return ret ? 0 : 1; } @@ -2429,7 +2486,7 @@ static int init_xo2(struct ddb_port *port) return res; if (data[0] != 0x01) { - pr_info("Port %d: invalid XO2\n", port->nr); + pr_info("DDBridge: Port %d: invalid XO2\n", port->nr); return -1; } @@ -2448,7 +2505,7 @@ static int init_xo2(struct ddb_port *port) i2c_write_reg(i2c, 0x10, 0x09, xo2_speed); if (dev->link[port->lnr].info->con_clock) { - pr_info("Setting continuous clock for XO2\n"); + pr_info("DDBridge: Setting continuous clock for XO2\n"); i2c_write_reg(i2c, 0x10, 0x0a, 0x03); i2c_write_reg(i2c, 0x10, 0x0b, 0x03); } else { @@ -2475,11 +2532,12 @@ static int init_xo2_ci(struct ddb_port *port) return res; if (data[0] > 1) { - pr_info("Port %d: invalid XO2 CI %02x\n", + pr_info("DDBridge: Port %d: invalid XO2 CI %02x\n", port->nr, data[0]); return -1; } - pr_info("Port %d: DuoFlex CI %u.%u\n", port->nr, data[0], data[1]); + pr_info("DDBridge: Port %d: DuoFlex CI %u.%u\n", + port->nr, data[0], data[1]); i2c_read_reg(i2c, 0x10, 0x08, &val); if (val != 0) { @@ -2498,7 +2556,7 @@ static int init_xo2_ci(struct ddb_port *port) usleep_range(2000, 3000); if (dev->link[port->lnr].info->con_clock) { - pr_info("Setting continuous clock for DuoFLex CI\n"); + pr_info("DDBridge: Setting continuous clock for DuoFLex CI\n"); i2c_write_reg(i2c, 0x10, 0x0a, 0x03); i2c_write_reg(i2c, 0x10, 0x0b, 0x03); } else { @@ -2525,14 +2583,14 @@ static int port_has_cxd28xx(struct ddb_port *port, u8 *id) static char *xo2names[] = { "DUAL DVB-S2", "DUAL DVB-C/T/T2", "DUAL DVB-ISDBT", "DUAL DVB-C/C2/T/T2", - "DUAL ATSC", "DUAL DVB-C/C2/T/T2", + "DUAL ATSC", "DUAL DVB-C/C2/T/T2,ISDB-T", "", "" }; static char *xo2types[] = { "DVBS_ST", "DVBCT2_SONY", "ISDBT_SONY", "DVBC2T2_SONY", - "ATSC_ST", "DVBC2T2_ST" + "ATSC_ST", "DVBC2T2I_SONY" }; static void ddb_port_probe(struct ddb_port *port) @@ -2565,15 +2623,15 @@ static void ddb_port_probe(struct ddb_port *port) port->class = DDB_PORT_MOD; return; } - + if (dev->link[l].info->type == DDB_OCTOPRO_HDIN) { - if( port->nr == 0 ) { + if (port->nr == 0) { dev->link[l].info->type = DDB_OCTOPUS; port->name = "HDIN"; port->class = DDB_PORT_LOOP; } return; - } + } if (dev->link[l].info->type == DDB_OCTOPUS_MAX) { port->name = "DUAL DVB-S2 MAX"; @@ -2607,13 +2665,13 @@ static void ddb_port_probe(struct ddb_port *port) ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); } else { - pr_info(KERN_INFO "Port %d: Uninitialized DuoFlex\n", + pr_info("DDBridge: Port %d: Uninitialized DuoFlex\n", port->nr); return; } } else if (port_has_xo2(port, &type, &id)) { ddbwritel(dev, I2C_SPEED_400, port->i2c->regs + I2C_TIMING); - /*pr_info("XO2 ID %02x\n", id);*/ + pr_info("DDBridge: XO2 ID %02x\n", id); if (type == 2) { port->name = "DuoFlex CI"; port->class = DDB_PORT_CI; @@ -2652,8 +2710,8 @@ static void ddb_port_probe(struct ddb_port *port) break; case 0xc1: port->name = "DUAL DVB-C2T2 ISDB-T CXD2854"; - port->type = DDB_TUNER_DVBC2T2_SONY_P; - port->type_name = "DVBC2T2_ISDBT_SONY"; + port->type = DDB_TUNER_DVBC2T2I_SONY_P; + port->type_name = "DVBC2T2I_ISDBT_SONY"; break; default: return; @@ -2915,7 +2973,7 @@ static int slot_reset_xo2(struct dvb_ca_en50221 *ca, int slot) { struct ddb_ci *ci = ca->data; - pr_info("%s\n", __func__); + pr_info("DDBridge: %s\n", __func__); write_creg(ci, 0x01, 0x01); write_creg(ci, 0x04, 0x04); msleep(20); @@ -2929,7 +2987,7 @@ static int slot_shutdown_xo2(struct dvb_ca_en50221 *ca, int slot) { struct ddb_ci *ci = ca->data; - pr_info("%s\n", __func__); + pr_info("DDBridge: %s\n", __func__); /*i2c_write_reg(i2c, adr, 0x03, 0x60);*/ /*i2c_write_reg(i2c, adr, 0x00, 0xc0);*/ write_creg(ci, 0x10, 0xff); @@ -2941,7 +2999,7 @@ static int slot_ts_enable_xo2(struct dvb_ca_en50221 *ca, int slot) { struct ddb_ci *ci = ca->data; - pr_info("%s\n", __func__); + pr_info("DDBridge: %s\n", __func__); write_creg(ci, 0x00, 0x10); return 0; } @@ -3071,7 +3129,7 @@ static int ddb_port_attach(struct ddb_port *port) break; } if (ret < 0) - pr_err("port_attach on port %d failed\n", port->nr); + pr_err("DDBridge: port_attach on port %d failed\n", port->nr); return ret; } @@ -3083,12 +3141,12 @@ static int ddb_ports_attach(struct ddb *dev) dev->ns_num = dev->link[0].info->ns_num; for (i = 0; i < dev->ns_num; i++) dev->ns[i].nr = i; - pr_info("%d netstream channels\n", dev->ns_num); + pr_info("DDBridge: %d netstream channels\n", dev->ns_num); if (dev->port_num) { ret = dvb_register_adapters(dev); if (ret < 0) { - pr_err("Registering adapters failed. Check DVB_MAX_ADAPTERS in config.\n"); + pr_err("DDBridge: Registering adapters failed. Check DVB_MAX_ADAPTERS in config.\n"); return ret; } } @@ -3164,7 +3222,8 @@ static void input_write_dvb(struct ddb_input *input, dma = dma2 = input->dma; /* if there also is an output connected, do not ACK. - input_write_output will ACK. */ + * input_write_output will ACK. + */ if (input->redo) { dma2 = input->redo->dma; ack = 0; @@ -3172,14 +3231,14 @@ static void input_write_dvb(struct ddb_input *input, while (dma->cbuf != ((dma->stat >> 11) & 0x1f) || (4 & dma->ctrl)) { if (4 & dma->ctrl) { - /*pr_err("Overflow dma %d\n", dma->nr);*/ + /*pr_err("DDBridge: Overflow dma %d\n", dma->nr);*/ ack = 1; } if (alt_dma) dma_sync_single_for_cpu(dev->dev, dma2->pbuf[dma->cbuf], dma2->size, DMA_FROM_DEVICE); #if 0 - pr_info("%02x %02x %02x %02x \n", + pr_info("DDBridge: %02x %02x %02x %02x\n", dma2->vbuf[dma->cbuf][0], dma2->vbuf[dma->cbuf][1], dma2->vbuf[dma->cbuf][2], dma2->vbuf[dma->cbuf][3]); #endif @@ -3219,7 +3278,7 @@ static void input_tasklet(unsigned long data) #if 0 if (4 & dma->ctrl) - pr_err("Overflow dma %d\n", dma->nr); + pr_err("DDBridge: Overflow dma %d\n", dma->nr); #endif if (input->redi) input_write_dvb(input, input->redi); @@ -3236,8 +3295,9 @@ static void input_handler(unsigned long data) /* If there is no input connected, input_tasklet() will - just copy pointers and ACK. So, there is no need to go - through the tasklet scheduler. */ + * just copy pointers and ACK. So, there is no need to go + * through the tasklet scheduler. + */ #ifdef DDB_USE_WORK if (input->redi) queue_work(ddb_wq, &dma->work); @@ -3301,9 +3361,16 @@ static void ddb_dma_init(struct ddb_io *io, int nr, int out) if (out) { dma->regs = rm->odma->base + rm->odma->size * nr; dma->bufregs = rm->odma_buf->base + rm->odma_buf->size * nr; - dma->num = OUTPUT_DMA_BUFS; - dma->size = OUTPUT_DMA_SIZE; - dma->div = OUTPUT_DMA_IRQ_DIV; + if (io->port->dev->link[0].info->type == DDB_MOD && + io->port->dev->link[0].info->version == 3) { + dma->num = OUTPUT_DMA_BUFS_SDR; + dma->size = OUTPUT_DMA_SIZE_SDR; + dma->div = OUTPUT_DMA_IRQ_DIV_SDR; + } else { + dma->num = OUTPUT_DMA_BUFS; + dma->size = OUTPUT_DMA_SIZE; + dma->div = OUTPUT_DMA_IRQ_DIV; + } } else { #ifdef DDB_USE_WORK INIT_WORK(&dma->work, input_work); @@ -3317,8 +3384,8 @@ static void ddb_dma_init(struct ddb_io *io, int nr, int out) dma->div = INPUT_DMA_IRQ_DIV; } ddbwritel(io->port->dev, 0, DMA_BUFFER_ACK(dma)); - pr_info("init link %u, io %u, dma %u, dmaregs %08x bufregs %08x\n", - io->port->lnr, io->nr, nr, dma->regs, dma->bufregs); + pr_debug("DDBridge: init link %u, io %u, dma %u, dmaregs %08x bufregs %08x\n", + io->port->lnr, io->nr, nr, dma->regs, dma->bufregs); } static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr) @@ -3333,7 +3400,8 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr) rm = io_regmap(input, 1); input->regs = DDB_LINK_TAG(port->lnr) | (rm->input->base + rm->input->size * nr); - pr_info("init link %u, input %u, regs %08x\n", port->lnr, nr, input->regs); + pr_debug("DDBridge: init link %u, input %u, regs %08x\n", + port->lnr, nr, input->regs); if (dev->has_dma) { struct ddb_regmap *rm0 = io_regmap(input, 0); u32 base = rm0->irq_base_idma; @@ -3341,8 +3409,9 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr) if (port->lnr) dma_nr += 32 + (port->lnr - 1) * 8; - - pr_info("init link %u, input %u, handler %u\n", port->lnr, nr, dma_nr + base); + + pr_debug("DDBridge: init link %u, input %u, handler %u\n", + port->lnr, nr, dma_nr + base); dev->handler[0][dma_nr + base] = input_handler; dev->handler_data[0][dma_nr + base] = (unsigned long) input; ddb_dma_init(input, dma_nr, 0); @@ -3361,7 +3430,8 @@ static void ddb_output_init(struct ddb_port *port, int nr) rm = io_regmap(output, 1); output->regs = DDB_LINK_TAG(port->lnr) | (rm->output->base + rm->output->size * nr); - pr_info("init link %u, output %u, regs %08x\n", port->lnr, nr, output->regs); + pr_debug("DDBridge: init link %u, output %u, regs %08x\n", + port->lnr, nr, output->regs); if (dev->has_dma) { struct ddb_regmap *rm0 = io_regmap(output, 0); u32 base = rm0->irq_base_odma; @@ -3439,7 +3509,7 @@ static void ddb_ports_init(struct ddb *dev) port->name = "DuoFlex CI_B"; port->i2c = dev->port[p - 1].i2c; } - pr_info("Port %u: Link %u, Link Port %u (TAB %u): %s\n", + pr_info("DDBridge: Port %u: Link %u, Link Port %u (TAB %u): %s\n", port->pnr, port->lnr, port->nr, port->nr + 1, port->name); @@ -3528,18 +3598,18 @@ static void ddb_ports_release(struct ddb *dev) dev->handler[0][_nr](dev->handler_data[0][_nr]); } \ while (0) -#define IRQ_HANDLE_BYTE(_n) \ - if (s & (0x000000ff << ((_n) & 0x1f))) { \ - IRQ_HANDLE(0 + _n); \ - IRQ_HANDLE(1 + _n); \ - IRQ_HANDLE(2 + _n); \ - IRQ_HANDLE(3 + _n); \ - IRQ_HANDLE(4 + _n); \ - IRQ_HANDLE(5 + _n); \ - IRQ_HANDLE(6 + _n); \ - IRQ_HANDLE(7 + _n); \ +#define IRQ_HANDLE_BYTE(_n) { \ + if (s & (0x000000ff << ((_n) & 0x1f))) { \ + IRQ_HANDLE(0 + (_n)); \ + IRQ_HANDLE(1 + (_n)); \ + IRQ_HANDLE(2 + (_n)); \ + IRQ_HANDLE(3 + (_n)); \ + IRQ_HANDLE(4 + (_n)); \ + IRQ_HANDLE(5 + (_n)); \ + IRQ_HANDLE(6 + (_n)); \ + IRQ_HANDLE(7 + (_n)); \ + } \ } - static void irq_handle_msg(struct ddb *dev, u32 s) { @@ -3599,9 +3669,9 @@ static irqreturn_t irq_handler0(int irq, void *dev_id) do { if (s & 0x80000000) return IRQ_NONE; - if (!(s & 0xfff00)) + if (!(s & 0xfffff00)) return IRQ_NONE; - ddbwritel(dev, s & 0xfff00, INTERRUPT_ACK); + ddbwritel(dev, s & 0xfffff00, INTERRUPT_ACK); irq_handle_io(dev, s); } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); @@ -3660,20 +3730,20 @@ static irqreturn_t irq_handle_v2_n(struct ddb *dev, u32 n) if (!s) return IRQ_NONE; ddbwritel(dev, s, reg); - + if ((s & 0x000000ff)) { - IRQ_HANDLE( 0 + off); - IRQ_HANDLE( 1 + off); - IRQ_HANDLE( 2 + off); - IRQ_HANDLE( 3 + off); - IRQ_HANDLE( 4 + off); - IRQ_HANDLE( 5 + off); - IRQ_HANDLE( 6 + off); - IRQ_HANDLE( 7 + off); + IRQ_HANDLE(0 + off); + IRQ_HANDLE(1 + off); + IRQ_HANDLE(2 + off); + IRQ_HANDLE(3 + off); + IRQ_HANDLE(4 + off); + IRQ_HANDLE(5 + off); + IRQ_HANDLE(6 + off); + IRQ_HANDLE(7 + off); } if ((s & 0x0000ff00)) { - IRQ_HANDLE( 8 + off); - IRQ_HANDLE( 9 + off); + IRQ_HANDLE(8 + off); + IRQ_HANDLE(9 + off); IRQ_HANDLE(10 + off); IRQ_HANDLE(11 + off); IRQ_HANDLE(12 + off); @@ -3736,7 +3806,7 @@ static irqreturn_t irq_thread(int irq, void *dev_id) { /* struct ddb *dev = (struct ddb *) dev_id; */ - /*pr_info("%s\n", __func__);*/ + /*pr_info("DDBridge: %s\n", __func__);*/ return IRQ_HANDLED; } @@ -3803,9 +3873,9 @@ static int nsd_do_ioctl(struct file *file, unsigned int cmd, void *parg) return -EINVAL; ctrl = (input->port->lnr << 16) | ((input->nr & 7) << 8) | ((ts->filter_mask & 3) << 2); - /*pr_info("GET_TS %u.%u\n", input->port->lnr, input->nr);*/ + if (ddbreadl(dev, TS_CAPTURE_CONTROL) & 1) { - pr_info("ts capture busy\n"); + pr_info("DDBridge: ts capture busy\n"); return -EBUSY; } ddb_dvb_ns_input_start(input); @@ -3839,7 +3909,7 @@ static int nsd_do_ioctl(struct file *file, unsigned int cmd, void *parg) if (ctrl & 1) return -EBUSY; if (ctrl & (1 << 14)) { - /*pr_info("ts capture timeout\n");*/ + /*pr_info("DDBridge: ts capture timeout\n");*/ return -EAGAIN; } ddbcpyfrom(dev, dev->tsbuf, TS_CAPTURE_MEMORY, @@ -3853,10 +3923,10 @@ static int nsd_do_ioctl(struct file *file, unsigned int cmd, void *parg) { u32 ctrl = 0; - /*pr_info("cancel ts capture: 0x%x\n", ctrl);*/ + /*pr_info("DDBridge: cancel ts capture: 0x%x\n", ctrl);*/ ddbwritel(dev, ctrl, TS_CAPTURE_CONTROL); ctrl = ddbreadl(dev, TS_CAPTURE_CONTROL); - /*pr_info("control register is 0x%x\n", ctrl);*/ + /*pr_info("DDBridge: control register is 0x%x\n", ctrl);*/ break; } case NSD_STOP_GET_TS: @@ -3868,10 +3938,10 @@ static int nsd_do_ioctl(struct file *file, unsigned int cmd, void *parg) if (!input) return -EINVAL; if (ctrl & 1) { - pr_info("cannot stop ts capture, while it was neither finished nor canceled\n"); + pr_info("DDBridge: cannot stop ts capture, while it was neither finished nor canceled\n"); return -EBUSY; } - /*pr_info("ts capture stopped\n");*/ + /*pr_info("DDBridge: ts capture stopped\n");*/ ddb_dvb_ns_input_stop(input); break; } @@ -4404,7 +4474,7 @@ static ssize_t fan_store(struct device *device, struct device_attribute *d, const char *buf, size_t count) { struct ddb *dev = dev_get_drvdata(device); - unsigned val; + u32 val; if (sscanf(buf, "%u\n", &val) != 1) return -EINVAL; @@ -4434,18 +4504,18 @@ static ssize_t temp_show(struct device *device, s32 temp, temp2, temp3; int i; u8 tmp[2]; - - if (dev->link[0].info->type == DDB_MOD) { - if (dev->link[0].info->version == 2) { - temp = ddbreadl(dev, TEMPMON2_BOARD); + + if (link->info->type == DDB_MOD) { + if (link->info->version >= 2) { + temp = 0xffff & ddbreadl(dev, TEMPMON2_BOARD); temp = (temp * 1000) >> 8; - temp2 = ddbreadl(dev, TEMPMON2_FPGACORE); + temp2 = 0xffff & ddbreadl(dev, TEMPMON2_FPGACORE); temp2 = (temp2 * 1000) >> 8; - temp3 = ddbreadl(dev, TEMPMON2_QAMCORE); + temp3 = 0xffff & ddbreadl(dev, TEMPMON2_QAMCORE); temp3 = (temp3 * 1000) >> 8; - + return sprintf(buf, "%d %d %d\n", temp, temp2, temp3); } ddbwritel(dev, 1, TEMPMON_CONTROL); @@ -4465,14 +4535,14 @@ static ssize_t temp_show(struct device *device, } return sprintf(buf, "%d %d\n", temp, temp2); } - if (!dev->link[0].info->temp_num) + if (!link->info->temp_num) return sprintf(buf, "no sensor\n"); - adap = &dev->i2c[dev->link[0].info->temp_bus].adap; + adap = &dev->i2c[link->info->temp_bus].adap; if (i2c_read_regs(adap, 0x48, 0, tmp, 2) < 0) return sprintf(buf, "read_error\n"); temp = (tmp[0] << 3) | (tmp[1] >> 5); temp *= 125; - if (dev->link[0].info->temp_num == 2) { + if (link->info->temp_num == 2) { if (i2c_read_regs(adap, 0x49, 0, tmp, 2) < 0) return sprintf(buf, "read_error\n"); temp2 = (tmp[0] << 3) | (tmp[1] >> 5); @@ -4558,7 +4628,7 @@ static void ddb_set_led(struct ddb *dev, int num, int val) i2c_write_reg16(&dev->i2c[num].adap, 0x1f, 0xf00f, val ? 1 : 0); break; - case DDB_TUNER_XO2 ... DDB_TUNER_DVBC2T2_ST: + case DDB_TUNER_XO2 ... DDB_TUNER_DVBC2T2I_SONY: { u8 v; @@ -4580,7 +4650,7 @@ static ssize_t led_store(struct device *device, { struct ddb *dev = dev_get_drvdata(device); int num = attr->attr.name[3] - 0x30; - unsigned val; + u32 val; if (sscanf(buf, "%u\n", &val) != 1) return -EINVAL; @@ -4680,10 +4750,11 @@ static ssize_t redirect_store(struct device *device, res = ddb_redirect(i, p); if (res < 0) return res; - pr_info("redirect: %02x, %02x\n", i, p); + pr_info("DDBridge: redirect: %02x, %02x\n", i, p); return count; } +#if 0 /* A L P I AAAAAALLPPPPPPII */ /* AAAAAAAA LLLLLLLL PPPPPPII */ static ssize_t redirect2_show(struct device *device, @@ -4704,9 +4775,10 @@ static ssize_t redirect2_store(struct device *device, res = ddb_redirect(i, p); if (res < 0) return res; - pr_info("redirect: %02x, %02x\n", i, p); + pr_info("DDBridge: redirect: %02x, %02x\n", i, p); return count; } +#endif static ssize_t gap_show(struct device *device, struct device_attribute *attr, char *buf) @@ -4738,7 +4810,7 @@ static ssize_t obr_show(struct device *device, { struct ddb *dev = dev_get_drvdata(device); int num = attr->attr.name[3] - 0x30; - + return sprintf(buf, "%d\n", dev->port[num].obr); } @@ -4749,7 +4821,7 @@ static ssize_t obr_store(struct device *device, struct device_attribute *attr, struct ddb *dev = dev_get_drvdata(device); int num = attr->attr.name[3] - 0x30; unsigned int val; - + if (sscanf(buf, "%u\n", &val) != 1) return -EINVAL; if (val > 96000) @@ -4955,7 +5027,8 @@ static void ddb_device_attrs_del(struct ddb *dev) for (i = 0; i < 4; i++) if (dev->link[i].info && dev->link[i].info->tempmon_irq) - device_remove_file(dev->ddb_dev, &ddb_attrs_fanspeed[i]); + device_remove_file(dev->ddb_dev, + &ddb_attrs_fanspeed[i]); for (i = 0; i < dev->link[0].info->temp_num; i++) device_remove_file(dev->ddb_dev, &ddb_attrs_temp[i]); for (i = 0; i < dev->link[0].info->port_num; i++) @@ -5023,7 +5096,7 @@ static int ddb_device_create(struct ddb *dev) dev, "ddbridge%d", dev->nr); if (IS_ERR(dev->ddb_dev)) { res = PTR_ERR(dev->ddb_dev); - pr_info("Could not create ddbridge%d\n", dev->nr); + pr_info("DDBridge: Could not create ddbridge%d\n", dev->nr); goto fail; } res = ddb_device_attrs_add(dev); @@ -5057,7 +5130,7 @@ static void gtl_link_handler(unsigned long priv) struct ddb *dev = (struct ddb *) priv; u32 regs = dev->link[0].info->regmap->gtl->base; - pr_info("GT link change: %u\n", + pr_info("DDBridge: GT link change: %u\n", (1 & ddbreadl(dev, regs))); } @@ -5067,9 +5140,9 @@ static void link_tasklet(unsigned long data) struct ddb *dev = link->dev; u32 s, tag = DDB_LINK_TAG(link->nr); u32 l = link->nr; - + s = ddbreadl(dev, tag | INTERRUPT_STATUS); - pr_info("gtl_irq %08x = %08x\n", tag | INTERRUPT_STATUS, s); + pr_info("DDBridge: gtl_irq %08x = %08x\n", tag | INTERRUPT_STATUS, s); if (!s) return; @@ -5090,7 +5163,7 @@ static void gtl_irq_handler(unsigned long priv) while ((s = ddbreadl(dev, tag | INTERRUPT_STATUS))) { ddbwritel(dev, s, tag | INTERRUPT_ACK); - //pr_info("gtlirq %08x\n", s); + //pr_info("DDBridge: gtlirq %08x\n", s); LINK_IRQ_HANDLE(l, 0); LINK_IRQ_HANDLE(l, 1); LINK_IRQ_HANDLE(l, 2); @@ -5107,9 +5180,9 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l) struct ddb_link *link = &dev->link[l]; u32 regs = dev->link[0].info->regmap->gtl->base + (l - 1) * dev->link[0].info->regmap->gtl->size; - u32 id, base = dev->link[0].info->regmap->irq_base_gtl; + u32 id, subid, base = dev->link[0].info->regmap->irq_base_gtl; - pr_info("Checking GT link %u: regs = %08x\n", l, regs); + pr_info("DDBridge: Checking GT link %u: regs = %08x\n", l, regs); spin_lock_init(&link->lock); mutex_init(&link->lnb.lock); @@ -5135,12 +5208,27 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l) return -1; } id = ddbreadl(dev, DDB_LINK_TAG(l) | 8); + subid = ddbreadl(dev, DDB_LINK_TAG(l) | 12); switch (id) { case 0x0007dd01: link->info = &ddb_s2_48; break; case 0x0008dd01: - link->info = &ddb_c2t2_8; + switch (subid) { + case 0x0035dd01: + default: + link->info = &ddb_c2t2_8; + break; + case 0x0036dd01: + link->info = &ddb_isdbt_8; + break; + case 0x0037dd01: + link->info = &ddb_c2t2i_v0_8; + break; + case 0x0038dd01: + link->info = &ddb_c2t2i_8; + break; + } break; default: pr_info("DDBridge: Detected GT link but found invalid ID %08x. You might have to update (flash) the add-on card first.", @@ -5156,17 +5244,17 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l) dev->link[l].ids.hwid = ddbreadl(dev, DDB_LINK_TAG(l) | 0); dev->link[l].ids.regmapid = ddbreadl(dev, DDB_LINK_TAG(l) | 4); - dev->link[l].ids.vendor = id >> 16;; - dev->link[l].ids.device = id & 0xffff;; - //dev->link[l].ids.subvendor = id->subvendor; - //dev->link[l].ids.subdevice = id->subdevice; + dev->link[l].ids.vendor = id & 0xffff; + dev->link[l].ids.device = id >> 16; + dev->link[l].ids.subvendor = subid & 0xffff; + dev->link[l].ids.subdevice = subid >> 16; - pr_info("GTL %s\n", dev->link[l].info->name); + pr_info("DDBridge: GTL %s\n", dev->link[l].info->name); - pr_info("GTL HW %08x REGMAP %08x\n", + pr_info("DDBridge: GTL HW %08x REGMAP %08x\n", dev->link[l].ids.hwid, dev->link[l].ids.regmapid); - pr_info("GTL ID %08x\n", + pr_info("DDBridge: GTL ID %08x\n", ddbreadl(dev, DDB_LINK_TAG(l) | 8)); tasklet_init(&link->tasklet, link_tasklet, (unsigned long) link); @@ -5181,7 +5269,7 @@ static int ddb_gtl_init(struct ddb *dev) u32 l, base = dev->link[0].info->regmap->irq_base_gtl; dev->handler_data[0][base] = (unsigned long) dev; - dev->handler[0][base] = gtl_link_handler; + dev->handler[0][base] = gtl_link_handler; for (l = 1; l < dev->link[0].info->regmap->gtl->num + 1; l++) ddb_gtl_init_link(dev, l); return 0; @@ -5194,9 +5282,10 @@ static int ddb_gtl_init(struct ddb *dev) static void tempmon_setfan(struct ddb_link *link) { u32 temp, temp2, pwm; - - if ((ddblreadl(link, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0) { - pr_info("Over temperature condition\n"); + + if ((ddblreadl(link, TEMPMON_CONTROL) & + TEMPMON_CONTROL_OVERTEMP) != 0) { + pr_info("DDBridge: Over temperature condition\n"); link->OverTemperatureError = 1; } temp = (ddblreadl(link, TEMPMON_SENSOR0) >> 8) & 0xFF; @@ -5207,20 +5296,20 @@ static void tempmon_setfan(struct ddb_link *link) temp2 = 0; if (temp2 > temp) temp = temp2; - + pwm = (ddblreadl(link, TEMPMON_FANCONTROL) >> 8) & 0x0F; if (pwm > 10) - pwm = 10; - + pwm = 10; + if (temp >= link->temp_tab[pwm]) { - while( pwm < 10 && temp >= link->temp_tab[pwm + 1]) + while (pwm < 10 && temp >= link->temp_tab[pwm + 1]) pwm += 1; } else { - while( pwm > 1 && temp < link->temp_tab[pwm - 2]) + while (pwm > 1 && temp < link->temp_tab[pwm - 2]) pwm -= 1; } ddblwritel(link, (pwm << 8), TEMPMON_FANCONTROL); - } +} static void temp_handler(unsigned long data) @@ -5237,12 +5326,14 @@ static int tempmon_init(struct ddb_link *link, int FirstTime) struct ddb *dev = link->dev; int status = 0; u32 l = link->nr; - + spin_lock_irq(&link->temp_lock); if (FirstTime) { - static u8 TemperatureTable[11] = {30,35,40,45,50,55,60,65,70,75,80}; - - memcpy(link->temp_tab, TemperatureTable, sizeof(TemperatureTable)); + static u8 TemperatureTable[11] = { + 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80}; + + memcpy(link->temp_tab, TemperatureTable, + sizeof(TemperatureTable)); } dev->handler[l][link->info->tempmon_irq] = temp_handler; dev->handler_data[l][link->info->tempmon_irq] = (unsigned long) link; @@ -5250,11 +5341,12 @@ static int tempmon_init(struct ddb_link *link, int FirstTime) TEMPMON_CONTROL_INTENABLE), TEMPMON_CONTROL); ddblwritel(link, (3 << 8), TEMPMON_FANCONTROL); - + link->OverTemperatureError = - ((ddblreadl(link, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0); + ((ddblreadl(link, TEMPMON_CONTROL) & + TEMPMON_CONTROL_OVERTEMP) != 0); if (link->OverTemperatureError) { - pr_info("Over temperature condition\n"); + pr_info("DDBridge: Over temperature condition\n"); status = -1; } tempmon_setfan(link); @@ -5264,18 +5356,16 @@ static int tempmon_init(struct ddb_link *link, int FirstTime) static int ddb_init_tempmon(struct ddb_link *link) { - struct ddb *dev = link->dev; struct ddb_info *info = link->info; - + if (!info->tempmon_irq) - return; + return 0; if (info->type == DDB_OCTOPUS_MAX || info->type == DDB_OCTOPUS_MAX_CT) if (link->ids.regmapid < 0x00010002) - return; + return 0; spin_lock_init(&link->temp_lock); - printk("init_tempmon\n"); - tempmon_init(link, 1); + return tempmon_init(link, 1); } /****************************************************************************/ @@ -5293,6 +5383,11 @@ static int ddb_init_boards(struct ddb *dev) info = link->info; if (!info) continue; + pr_info("DDBridge: link %u vendor %04x device %04x subvendor %04x subdevice %04x\n", + l, + dev->link[l].ids.vendor, dev->link[l].ids.device, + dev->link[l].ids.subvendor, dev->link[l].ids.subdevice); + if (info->board_control) { ddbwritel(dev, 0, DDB_LINK_TAG(l) | BOARD_CONTROL); msleep(100); @@ -5314,7 +5409,7 @@ static int ddb_init(struct ddb *dev) mutex_init(&dev->link[0].flash_mutex); if (no_init) { ddb_device_create(dev); - return 0; + return 0; } if (dev->link[0].info->ns_num) { ddbwritel(dev, 1, ETHER_CONTROL); @@ -5322,7 +5417,7 @@ static int ddb_init(struct ddb *dev) ddbwritel(dev, 14 + (dev->vlan ? 4 : 0), ETHER_LENGTH); } mutex_init(&dev->link[0].lnb.lock); - + if (dev->link[0].info->regmap->gtl) ddb_gtl_init(dev); @@ -5332,15 +5427,11 @@ static int ddb_init(struct ddb *dev) goto fail; ddb_ports_init(dev); if (ddb_buffers_alloc(dev) < 0) { - pr_info(": Could not allocate buffer memory\n"); + pr_info("DDBridge: Could not allocate buffer memory\n"); goto fail2; } -#if 0 if (ddb_ports_attach(dev) < 0) goto fail3; -#else - ddb_ports_attach(dev); -#endif ddb_nsd_attach(dev); ddb_device_create(dev); @@ -5355,14 +5446,14 @@ static int ddb_init(struct ddb *dev) fail3: ddb_ports_detach(dev); - pr_err("fail3\n"); + pr_err("DDBridge: fail3\n"); ddb_ports_release(dev); fail2: - pr_err("fail2\n"); + pr_err("DDBridge: fail2\n"); ddb_buffers_free(dev); ddb_i2c_release(dev); fail: - pr_err("fail1\n"); + pr_err("DDBridge: fail1\n"); return -1; } @@ -5377,12 +5468,14 @@ static void ddb_reset_ios(struct ddb *dev) { u32 i; struct ddb_regmap *rm = dev->link[0].info->regmap; - + if (rm->input) for (i = 0; i < rm->input->num; i++) - ddb_reset_io(dev, rm->input->base + i * rm->input->size); + ddb_reset_io(dev, + rm->input->base + i * rm->input->size); if (rm->output) for (i = 0; i < rm->output->num; i++) - ddb_reset_io(dev, rm->output->base + i * rm->output->size); + ddb_reset_io(dev, + rm->output->base + i * rm->output->size); usleep_range(5000, 6000); } diff --git a/ddbridge/ddbridge-i2c.c b/ddbridge/ddbridge-i2c.c index d3fd477..f5374d1 100644 --- a/ddbridge/ddbridge-i2c.c +++ b/ddbridge/ddbridge-i2c.c @@ -1,7 +1,7 @@ /* * ddbridge-i2c.c: Digital Devices bridge i2c driver * - * Copyright (C) 2010-2015 Digital Devices GmbH + * Copyright (C) 2010-2017 Digital Devices GmbH * Ralph Metzler * Marcus Metzler * @@ -115,7 +115,7 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) stat = wait_for_completion_timeout(&i2c->completion, HZ); val = ddbreadl(dev, i2c->regs + I2C_COMMAND); if (stat == 0) { - pr_err("DDBridge I2C timeout, card %d, port %d, link %u\n", + pr_err("DDBridge: I2C timeout, card %d, port %d, link %u\n", dev->nr, i2c->nr, i2c->link); #if 1 { @@ -156,38 +156,43 @@ static int ddb_i2c_master_xfer(struct i2c_adapter *adapter, struct ddb *dev = i2c->dev; u8 addr = 0; - if (num != 1 && num != 2) - return -EIO; addr = msg[0].addr; if (msg[0].len > i2c->bsize) return -EIO; - if (num == 2 && msg[1].flags & I2C_M_RD && - !(msg[0].flags & I2C_M_RD)) { - if (msg[1].len > i2c->bsize) - return -EIO; - ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); - ddbwritel(dev, msg[0].len | (msg[1].len << 16), - i2c->regs + I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 1)) { - ddbcpyfrom(dev, msg[1].buf, - i2c->rbuf, - msg[1].len); - return num; - } - } - if (num == 1 && !(msg[0].flags & I2C_M_RD)) { - ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); - ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 2)) - return num; - } - if (num == 1 && (msg[0].flags & I2C_M_RD)) { - ddbwritel(dev, msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); - if (!ddb_i2c_cmd(i2c, addr, 3)) { + switch (num) { + case 1: + if (msg[0].flags & I2C_M_RD) { + ddbwritel(dev, msg[0].len << 16, + i2c->regs + I2C_TASKLENGTH); + if (ddb_i2c_cmd(i2c, addr, 3)) + break; ddbcpyfrom(dev, msg[0].buf, i2c->rbuf, msg[0].len); return num; } + ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); + ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH); + if (ddb_i2c_cmd(i2c, addr, 2)) + break; + return num; + case 2: + if ((msg[0].flags & I2C_M_RD) == I2C_M_RD) + break; + if ((msg[1].flags & I2C_M_RD) != I2C_M_RD) + break; + if (msg[1].len > i2c->bsize) + break; + ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len); + ddbwritel(dev, msg[0].len | (msg[1].len << 16), + i2c->regs + I2C_TASKLENGTH); + if (ddb_i2c_cmd(i2c, addr, 1)) + break; + ddbcpyfrom(dev, msg[1].buf, + i2c->rbuf, + msg[1].len); + return num; + default: + break; } return -EIO; } @@ -247,11 +252,10 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c, adap->class = I2C_CLASS_TV_ANALOG; #endif #endif - /*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->algo_data = (void *) i2c; adap->dev.parent = dev->dev; return i2c_add_adapter(adap); } diff --git a/ddbridge/ddbridge-i2c.h b/ddbridge/ddbridge-i2c.h index c20a2ba..0133e65 100644 --- a/ddbridge/ddbridge-i2c.h +++ b/ddbridge/ddbridge-i2c.h @@ -1,7 +1,7 @@ /* * ddbridge-i2c.h: Digital Devices bridge i2c driver * - * Copyright (C) 2010-2015 Digital Devices GmbH + * Copyright (C) 2010-2017 Digital Devices GmbH * Marcus Metzler * Ralph Metzler * diff --git a/ddbridge/ddbridge-mod.c b/ddbridge/ddbridge-mod.c index 6986acd..90a4062 100644 --- a/ddbridge/ddbridge-mod.c +++ b/ddbridge/ddbridge-mod.c @@ -1,7 +1,7 @@ /* * ddbridge.c: Digital Devices PCIe bridge driver * - * Copyright (C) 2010-2015 Digital Devices GmbH + * Copyright (C) 2010-2017 Digital Devices GmbH * Marcus Metzler * Ralph Metzler * @@ -76,57 +76,62 @@ 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 +/* 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) +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; + 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); } /****************************************************************************/ @@ -136,14 +141,14 @@ static inline u32 gcd(u32 u,u32 v) 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) { + while (1) { ControlReg = ddbreadl(dev, CHANNEL_CONTROL(Channel)); if (ControlReg == 0xFFFFFFFF) return -EIO; - if((ControlReg & CHANNEL_CONTROL_CMD_STATUS) == 0) + if ((ControlReg & CHANNEL_CONTROL_CMD_STATUS) == 0) break; } if (ControlReg & CHANNEL_CONTROL_ERROR_CMD) @@ -171,10 +176,11 @@ void ddbridge_mod_output_stop(struct ddb_output *output) struct ddb_mod *mod = &dev->mod[output->nr]; mod->State = CM_IDLE; - mod->Control = 0; + mod->Control &= 0xfffffff0; if (dev->link[0].info->version == 2) - mod_SendChannelCommand(dev, output->nr, CHANNEL_CONTROL_CMD_FREE); - ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); + mod_SendChannelCommand(dev, output->nr, + CHANNEL_CONTROL_CMD_FREE); + ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr)); #if 0 udelay(10); ddbwritel(dev, CHANNEL_CONTROL_RESET, CHANNEL_CONTROL(output->nr)); @@ -182,7 +188,7 @@ void ddbridge_mod_output_stop(struct ddb_output *output) ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); #endif mod_busy(dev, output->nr); - pr_info("mod_output_stop %d.%d\n", dev->nr, output->nr); + pr_info("DDBridge: mod_output_stop %d.%d\n", dev->nr, output->nr); } static void mod_set_incs(struct ddb_output *output) @@ -216,13 +222,13 @@ static void mod_set_rateinc(struct ddb *dev, u32 chan) static void mod_calc_rateinc(struct ddb_mod *mod) { u32 ri; - - pr_info("ibitrate %llu\n", mod->ibitrate); - pr_info("obitrate %llu\n", mod->obitrate); - + + pr_info("DDBridge: ibitrate %llu\n", mod->ibitrate); + pr_info("DDBridge: obitrate %llu\n", mod->obitrate); + if (mod->ibitrate != 0) { u64 d = mod->obitrate - mod->ibitrate; - + d = div64_u64(d, mod->obitrate >> 24); if (d > 0xfffffe) ri = 0xfffffe; @@ -231,14 +237,13 @@ static void mod_calc_rateinc(struct ddb_mod *mod) } else ri = 0; mod->rate_inc = ri; - pr_info("ibr=%llu, obr=%llu, ri=0x%06x\n", + pr_info("DDBridge: ibr=%llu, obr=%llu, ri=0x%06x\n", mod->ibitrate >> 32, mod->obitrate >> 32, ri); } static int mod_calc_obitrate(struct ddb_mod *mod) { - struct ddb *dev = mod->port->dev; - u64 ofac; + u64 ofac; ofac = (((u64) mod->symbolrate) << 32) * 188; ofac = div_u64(ofac, 204); @@ -249,7 +254,6 @@ static int mod_calc_obitrate(struct ddb_mod *mod) static int mod_set_symbolrate(struct ddb_mod *mod, u32 srate) { struct ddb *dev = mod->port->dev; - u64 ofac; if (dev->link[0].info->version < 2) { if (srate != 6900000) @@ -265,16 +269,17 @@ static int mod_set_symbolrate(struct ddb_mod *mod, u32 srate) static u32 qamtab[6] = { 0x000, 0x600, 0x601, 0x602, 0x903, 0x604 }; -static int mod_set_modulation(struct ddb_mod *mod, enum fe_modulation modulation) +static int mod_set_modulation(struct ddb_mod *mod, + enum fe_modulation modulation) { struct ddb *dev = mod->port->dev; - u64 ofac; if (modulation > QAM_256 || modulation < QAM_16) return -EINVAL; mod->modulation = modulation; - if (dev->link[0].info->version < 2) - ddbwritel(dev, qamtab[modulation], CHANNEL_SETTINGS(mod->nr)); + if (dev->link[0].info->version < 2) + ddbwritel(dev, qamtab[modulation], + CHANNEL_SETTINGS(mod->port->nr)); mod_calc_obitrate(mod); return 0; } @@ -282,7 +287,7 @@ static int mod_set_modulation(struct ddb_mod *mod, enum fe_modulation modulation static int mod_set_frequency(struct ddb_mod *mod, u32 frequency) { u32 freq = frequency / 1000000; - + if (frequency % 1000000) return -EINVAL; if ((freq - 114) % 8) @@ -309,9 +314,8 @@ int ddbridge_mod_output_start(struct ddb_output *output) struct ddb_mod *mod = &dev->mod[output->nr]; u32 Symbolrate = mod->symbolrate; - mod_calc_rateinc(mod); - /*PCRIncrement = RoundPCR(PCRIncrement);*/ - /*PCRDecrement = RoundPCR(PCRDecrement);*/ + if (dev->link[0].info->version < 3) + mod_calc_rateinc(mod); mod->LastInPacketCount = 0; mod->LastOutPacketCount = 0; @@ -329,62 +333,75 @@ int ddbridge_mod_output_start(struct ddb_output *output) mod->State = CM_STARTUP; mod->StateCounter = CM_STARTUP_DELAY; - ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); + if (dev->link[0].info->version == 3) + mod->Control = 0xfffffff0 & + ddbreadl(dev, CHANNEL_CONTROL(output->nr)); + else + mod->Control = 0; + ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr)); udelay(10); - ddbwritel(dev, CHANNEL_CONTROL_RESET, CHANNEL_CONTROL(output->nr)); + ddbwritel(dev, mod->Control | CHANNEL_CONTROL_RESET, + CHANNEL_CONTROL(output->nr)); udelay(10); - ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr)); + ddbwritel(dev, mod->Control, CHANNEL_CONTROL(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 Output = (mod->frequency - 114000000) / 8000000; u32 KF = Symbolrate; u32 LF = 9000000UL; - u32 d = gcd(KF,LF); + u32 d = gcd(KF, LF); u32 checkLF; ddbwritel(dev, mod->modulation - 1, CHANNEL_SETTINGS(Channel)); ddbwritel(dev, Output, CHANNEL_SETTINGS2(Channel)); - + KF = KF / d; LF = LF / d; - - while( (KF > KFLF_MAX) || (LF > KFLF_MAX) ) { + + 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); + pr_info("DDBridge: 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)) + + if (mod_SendChannelCommand(dev, Channel, + CHANNEL_CONTROL_CMD_SETUP)) return -EINVAL; - mod->Control = CHANNEL_CONTROL_ENABLE_DVB; - } else { + mod->Control |= CHANNEL_CONTROL_ENABLE_DVB; + } else if (dev->link[0].info->version == 1) { /* 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); + ddbwritel(dev, qamtab[mod->modulation], + CHANNEL_SETTINGS(output->nr)); + mod->Control |= (CHANNEL_CONTROL_ENABLE_IQ | + CHANNEL_CONTROL_ENABLE_DVB); + } else if (dev->link[0].info->version == 3) { + mod->Control |= (CHANNEL_CONTROL_ENABLE_IQ | + CHANNEL_CONTROL_ENABLE_DVB); + } + if (dev->link[0].info->version < 3) { + mod_set_rateinc(dev, output->nr); + mod_set_incs(output); } - mod_set_rateinc(dev, output->nr); - mod_set_incs(output); - 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)) + if (mod_SendChannelCommand(dev, Channel, + CHANNEL_CONTROL_CMD_UNMUTE)) return -EINVAL; - pr_info("mod_output_start %d.%d\n", dev->nr, output->nr); + pr_info("DDBridge: mod_output_start %d.%d ctrl=%08x\n", + dev->nr, output->nr, mod->Control); return 0; } @@ -395,9 +412,11 @@ int 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) { + 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) @@ -406,58 +425,62 @@ static int mod_write_max2871(struct ddb *dev, u32 val) return 0; } -static int mod_setup_max2871(struct ddb *dev) +static u32 max2871_fsm[6] = { + 0x00730040, 0x600080A1, 0x510061C2, 0x010000CB, 0x6199003C, 0x60440005, +}; + +static u32 max2871_sdr[6] = { + 0x007A8098, 0x600080C9, 0x510061C2, 0x010000CB, 0x6199003C, 0x60440005 +}; + +static int mod_setup_max2871(struct ddb *dev, u32 *reg) { 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); + int i, j; + u32 val; + ddbwritel(dev, MAX2871_CONTROL_CE, MAX2871_CONTROL); + msleep(30); + for (i = 0; i < 2; i++) { + for (j = 5; j >= 0; j--) { + val = reg[j]; + + if (j == 4) + val &= 0xFFFFFEDF; + status = mod_write_max2871(dev, reg[j]); + if (status) + break; + msleep(30); + } + } if (status == 0) { - u32 ControlReg = ddbreadl(dev, MAX2871_CONTROL); - + u32 ControlReg; + + if (reg[3] & (1 << 24)) + msleep(100); + ControlReg = ddbreadl(dev, MAX2871_CONTROL); + if ((ControlReg & MAX2871_CONTROL_LOCK) == 0) status = -EIO; + status = mod_write_max2871(dev, reg[4]); } - return status; } - -static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan, u32 MaxUsedChannels) +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); + status = mod_setup_max2871(dev, max2871_fsm); if (status) return status; ddbwritel(dev, FSM_CMD_RESET, FSM_CONTROL); - msleep(10); - + msleep(20); + tmp = ddbreadl(dev, FSM_STATUS); if ((tmp & FSM_STATUS_READY) == 0) return -1; @@ -466,23 +489,23 @@ static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan, u32 MaxUsedChannels if (((tmp & FSM_STATUS_QAMREADY) != 0) && ((Capacity & FSM_CAPACITY_INUSE) != 0)) return -EBUSY; - + ddbwritel(dev, FSM_CMD_SETUP, FSM_CONTROL); - msleep(10); + msleep(20); 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 ) + pr_info("DDBridge: 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) + else if (MaxUsedChannels <= 4) ddbwritel(dev, FSM_GAIN_N4, FSM_GAIN); else if (MaxUsedChannels <= 8) ddbwritel(dev, FSM_GAIN_N8, FSM_GAIN); @@ -500,83 +523,12 @@ static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan, u32 MaxUsedChannels static int mod_set_vga(struct ddb *dev, u32 Gain) { - if( Gain > 255 ) + 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; -} -#if 0 -static void TemperatureMonitorSetFan(struct ddb *dev) -{ - u32 tqam, pwm; - - if ((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0) { - pr_info("Over temperature condition\n"); - dev->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->temp_tab[pwm]) { - while( pwm < 10 && tqam >= dev->temp_tab[pwm + 1]) - pwm += 1; - } else { - while( pwm > 1 && tqam < dev->temp_tab[pwm - 2]) - pwm -= 1; - } - ddbwritel(dev, (pwm << 8), TEMPMON_FANCONTROL); -} - - -static void temp_handler(unsigned long data) -{ - struct ddb *dev = (struct ddb *) data; - - pr_info("temp_handler\n"); - - spin_lock(&dev->temp_lock); - TemperatureMonitorSetFan(dev); - spin_unlock(&dev->temp_lock); -} - -static int TemperatureMonitorInit(struct ddb *dev, int FirstTime) { - int status = 0; - - spin_lock_irq(&dev->temp_lock); - if (FirstTime) { - static u8 TemperatureTable[11] = {30,35,40,45,50,55,60,65,70,75,80}; - - memcpy(dev->temp_tab, TemperatureTable, sizeof(TemperatureTable)); - } - dev->handler[0][8] = 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->OverTemperatureError = - ((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0); - if (dev->OverTemperatureError) { - pr_info("Over temperature condition\n"); - status = -1; - } - TemperatureMonitorSetFan(dev); - spin_unlock_irq(&dev->temp_lock); - return status; -} -#endif /****************************************************************************/ /****************************************************************************/ /****************************************************************************/ @@ -727,7 +679,7 @@ static int mod_set_si598(struct ddb *dev, u32 freq) mod_si598_readreg(dev, 11, &Data[4]); mod_si598_readreg(dev, 12, &Data[5]); - pr_info(" Data = %02x %02x %02x %02x %02x %02x\n", + pr_info("DDBridge: Data = %02x %02x %02x %02x %02x %02x\n", Data[0], Data[1], Data[2], Data[3], Data[4], Data[5]); RFreq = (((u64)Data[1] & 0x3F) << 32) | ((u64)Data[2] << 24) | ((u64)Data[3] << 16) | ((u64)Data[4] << 8) | @@ -741,12 +693,13 @@ static int mod_set_si598(struct ddb *dev, u32 freq) ((u32)(Data[1] & 0xE0) >> 6)) + 1; fDCO = fOut * (u64)(HSDiv * N); m_fXtal = fDCO << 28; - pr_info("fxtal %016llx rfreq %016llx\n", m_fXtal, RFreq); + pr_info("DDBridge: fxtal %016llx rfreq %016llx\n", + m_fXtal, RFreq); m_fXtal += RFreq >> 1; m_fXtal = div64_u64(m_fXtal, RFreq); - pr_info("fOut = %d fXtal = %d fDCO = %d HDIV = %2d, N = %3d\n", + pr_info("DDBridge: fOut = %d fXtal = %d fDCO = %d HDIV = %2d, N = %3d\n", (u32) fOut, (u32) m_fXtal, (u32) fDCO, (u32) HSDiv, N); } @@ -757,7 +710,7 @@ static int mod_set_si598(struct ddb *dev, u32 freq) if (Div < MinDiv) Div = Div + 1; - pr_info(" fOut = %u MinDiv = %llu MaxDiv = %llu StartDiv = %llu\n", + pr_info("DDBridge: fOut = %u MinDiv = %llu MaxDiv = %llu StartDiv = %llu\n", fOut, MinDiv, MaxDiv, Div); if (Div <= 11) { @@ -776,7 +729,7 @@ static int mod_set_si598(struct ddb *dev, u32 freq) if (N > 128) break; } - pr_info(" %3d: %llu %llu %llu %u\n", + pr_info("DDBridge: %3d: %llu %llu %llu %u\n", retry, Div, HSDiv * N, HSDiv, N); if (HSDiv * N < MinDiv) Div = Div + 2; @@ -787,7 +740,7 @@ static int mod_set_si598(struct ddb *dev, u32 freq) retry = retry - 1; } if (retry == 0) { - pr_err(" FAIL\n"); + pr_err("DDBridge: FAIL\n"); return -EINVAL; } } @@ -802,16 +755,16 @@ static int mod_set_si598(struct ddb *dev, u32 freq) fDCO = (u64)fOut * (u64)N * (u64)HSDiv; - pr_info("fdco %16llx\n", fDCO); + pr_info("DDBridge: fdco %16llx\n", fDCO); RFreq = fDCO<<28; - pr_info("%16llx %16llx\n", fDCO, RFreq); + pr_info("DDBridge: %16llx %16llx\n", fDCO, RFreq); fxtal = m_fXtal; do_div(RFreq, fxtal); - pr_info("%16llx %d\n", RFreq, fxtal); + pr_info("DDBridge: %16llx %d\n", RFreq, fxtal); RF = RFreq; - pr_info("fOut = %u fXtal = %llu fDCO = %llu HSDIV = %llu, N = %u, RFreq = %llu\n", + pr_info("DDBridge: fOut = %u fXtal = %llu fDCO = %llu HSDIV = %llu, N = %u, RFreq = %llu\n", fOut, m_fXtal, fDCO, HSDiv, N, RFreq); Data[0] = (u8)(((HSDiv - 4) << 5) | ((N - 1) >> 2)); @@ -821,7 +774,7 @@ static int mod_set_si598(struct ddb *dev, u32 freq) Data[4] = (u8)((RF >> 8) & 0xFF); Data[5] = (u8)((RF) & 0xFF); - pr_info(" Data = %02x %02x %02x %02x %02x %02x\n", + pr_info("DDBridge: Data = %02x %02x %02x %02x %02x %02x\n", Data[0], Data[1], Data[2], Data[3], Data[4], Data[5]); mod_si598_writereg(dev, 7, Data[0]); mod_si598_writereg(dev, 8, Data[1]); @@ -942,9 +895,9 @@ static int mod_init_dac_input(struct ddb *dev) Seek = 1; for (Sample = 0; Sample < 32; Sample += 1) { /* printk(" %2d: %d %2d %2d\n", - Sample, SeekTable[Sample], SetTable[Sample], - HldTable[Sample]); - */ + * Sample, SeekTable[Sample], SetTable[Sample], + * HldTable[Sample]); + */ if (Sample1 == 0xFF && SeekTable[Sample] == 1 && Seek == 0) Sample1 = Sample; @@ -955,11 +908,11 @@ static int mod_init_dac_input(struct ddb *dev) } if (Sample1 == 0xFF || Sample2 == 0xFF) { - pr_err(" No valid window found\n"); + pr_err("DDBridge: No valid window found\n"); return -EINVAL; } - pr_err(" Window = %d - %d\n", Sample1, Sample2); + pr_err("DDBridge: Window = %d - %d\n", Sample1, Sample2); for (Sample = Sample1; Sample < Sample2; Sample += 1) { if (SetTable[Sample] < HldTable[Sample]) { @@ -970,15 +923,15 @@ static int mod_init_dac_input(struct ddb *dev) } } - pr_info("Select Sample %d\n", SelectSample); + pr_info("DDBridge: Select Sample %d\n", SelectSample); if (SelectSample == 0xFF) { - pr_err("No valid sample found\n"); + pr_err("DDBridge: No valid sample found\n"); return -EINVAL; } if (HldTable[SelectSample] + SetTable[SelectSample] < 8) { - pr_err("Too high jitter\n"); + pr_err("DDBridge: Too high jitter\n"); return -EINVAL; } @@ -993,10 +946,10 @@ static int mod_init_dac_input(struct ddb *dev) mod_read_dac_register(dev, 0x06, &ReadSeek); Seek &= ReadSeek; if ((Seek & 0x01) == 0) { - pr_err("Insufficient timing margin\n"); + pr_err("DDBridge: Insufficient timing margin\n"); return -EINVAL; } - pr_info("Done\n"); + pr_info("DDBridge: Done\n"); return 0; } @@ -1053,7 +1006,7 @@ static int mod_set_dac_clock(struct ddb *dev, u32 Frequency) ddbwritel(dev, DAC_CONTROL_RESET, DAC_CONTROL); msleep(20); if (mod_set_si598(dev, Frequency)) { - pr_err("mod_set_si598 failed\n"); + pr_err("DDBridge: mod_set_si598 failed\n"); return -1; } msleep(50); @@ -1068,7 +1021,7 @@ static int mod_set_dac_clock(struct ddb *dev, u32 Frequency) break; msleep(100); } - pr_info("mod_set_dac_clock OK\n"); + pr_info("DDBridge: mod_set_dac_clock OK\n"); return hr; } @@ -1174,18 +1127,18 @@ static int set_base_frequency(struct ddb *dev, u32 freq) u32 UP2Frequency = 1896; u32 down, freq10; - pr_info("set base to %u\n", freq); + pr_info("DDBridge: set base to %u\n", freq); dev->mod_base.frequency = freq; freq /= 1000000; freq10 = dev->mod_base.flat_start + 4; down = freq + 9 * 8 + freq10 + UP1Frequency + UP2Frequency; if ((freq10 + 9 * 8) > (dev->mod_base.flat_end - 4)) { - pr_err("Frequency out of range %d\n", freq10); + pr_err("DDBridge: Frequency out of range %d\n", freq10); return -EINVAL; } if (down % 8) { - pr_err(" Invalid Frequency %d\n", down); + pr_err("DDBridge: Invalid Frequency %d\n", down); return -EINVAL; } return mod_set_down(dev, down, 8, Ext); @@ -1214,12 +1167,12 @@ static int mod_init_1(struct ddb *dev, u32 Frequency) stat = -EINVAL; goto fail; } - pr_info("srate = %d\n", flash->DataSet[0].Symbolrate * 1000); + pr_info("DDBridge: srate = %d\n", flash->DataSet[0].Symbolrate * 1000); mod_output_enable(dev, 0); stat = mod_set_dac_clock(dev, flash->DataSet[0].DACFrequency * 1000); if (stat < 0) { - pr_err("setting DAC clock failed\n"); + pr_err("DDBridge: setting DAC clock failed\n"); goto fail; } mod_set_dac_current(dev, 512, 512); @@ -1236,16 +1189,17 @@ static int mod_init_1(struct ddb *dev, u32 Frequency) FrequencyCH10 = flash->DataSet[0].FlatStart + 4; DownFrequency = Frequency + 9 * 8 + FrequencyCH10 + UP1Frequency + UP2Frequency; - pr_info("CH10 = %d, Down = %d\n", FrequencyCH10, DownFrequency); + pr_info("DDBridge: CH10 = %d, Down = %d\n", + FrequencyCH10, DownFrequency); if ((FrequencyCH10 + 9 * 8) > (flash->DataSet[0].FlatEnd - 4)) { - pr_err("Frequency out of range %d\n", FrequencyCH10); + pr_err("DDBridge: Frequency out of range %d\n", FrequencyCH10); stat = -EINVAL; goto fail; } if (DownFrequency % 8 != 0) { - pr_err(" Invalid Frequency %d\n", DownFrequency); + pr_err("DDBridge: Invalid Frequency %d\n", DownFrequency); stat = -EINVAL; goto fail; } @@ -1260,7 +1214,7 @@ static int mod_init_1(struct ddb *dev, u32 Frequency) iqfreq = flash->DataSet[0].FrequencyFactor * (FrequencyCH10 + (9 - i) * 8); - iqfreq += (dev->link[0].ids.hwid == 0x0203dd01) ? 22 : 0 ; + iqfreq += (dev->link[0].ids.hwid == 0x0203dd01) ? 22 : 0; iqsteps = flash->DataSet[0].IQTableLength; mod_set_iq(dev, iqsteps, i, iqfreq); mod_set_modulation(mod, QAM_256); @@ -1274,7 +1228,7 @@ static int mod_init_1(struct ddb *dev, u32 Frequency) flash->DataSet[0].PostScaleQ); mod_pre_eq_gain(dev, flash->DataSet[0].PreScale); /*mod_pre_eq_gain(dev, 0x0680);*/ - pr_info("prescaler %04x\n", flash->DataSet[0].PreScale); + pr_info("DDBridge: prescaler %04x\n", flash->DataSet[0].PreScale); mod_set_channelsumshift(dev, 2); mod_output_enable(dev, 1); @@ -1288,10 +1242,10 @@ fail: #define FACTOR (1ULL << 22) /* - double Increment = FACTOR*PACKET_CLOCKS/double(m_OutputBitrate); - double Decrement = FACTOR*PACKET_CLOCKS/double(m_InputBitrate); - 27000000 * 1504 * 2^22 / (6900000 * 188 / 204) = 26785190066.1 -*/ + * double Increment = FACTOR*PACKET_CLOCKS/double(m_OutputBitrate); + * double Decrement = FACTOR*PACKET_CLOCKS/double(m_InputBitrate); + * 27000000 * 1504 * 2^22 / (6900000 * 188 / 204) = 26785190066.1 + */ void ddbridge_mod_rate_handler(unsigned long data) { @@ -1398,7 +1352,7 @@ void ddbridge_mod_rate_handler(unsigned long data) case CM_ADJUST: if (InPacketDiff < mod->MinInputPackets) { - pr_info("PCR Adjust reset IN: %u Min: %u\n", + pr_info("DDBridge: PCR Adjust reset IN: %u Min: %u\n", InPacketDiff, mod->MinInputPackets); mod->InPacketsSum = 0; mod->OutPacketsSum = 0; @@ -1439,7 +1393,7 @@ void ddbridge_mod_rate_handler(unsigned long data) mod->PCRIncrement += PCRIncrementDiff; pcr = ConvertPCR(mod->PCRIncrement); - pr_info("outl %016llx\n", pcr); + pr_info("DDBridge: outl %016llx\n", pcr); ddbwritel(dev, pcr & 0xffffffff, CHANNEL_PCR_ADJUST_OUTL(output->nr)); ddbwritel(dev, (pcr >> 32) & 0xffffffff, @@ -1466,32 +1420,107 @@ void ddbridge_mod_rate_handler(unsigned long data) spin_unlock(&dma->lock); - pr_info("chan %d out %016llx in %016llx indiff %08x\n", + pr_info("DDBridge: chan %d out %016llx in %016llx indiff %08x\n", chan, OutPackets, InPackets, InPacketDiff); - pr_info("cnt %d pcra %016llx pcraext %08x pcraextfrac %08x pcrcorr %08x pcri %016llx\n", + pr_info("DDBridge: cnt %d pcra %016llx pcraext %08x pcraextfrac %08x pcrcorr %08x pcri %016llx\n", mod->StateCounter, PCRAdjust, PCRAdjustExt, PCRAdjustExtFrac, PCRCorr, mod->PCRIncrement); } -static int mod_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp) +static int mod3_set_base_frequency(struct ddb *dev, u32 frequency) +{ + u64 tmp; + + if (frequency % 1000) + return -EINVAL; + if ((frequency < 114000000) || (frequency > 874000000)) + return -EINVAL; + dev->mod_base.frequency = frequency; + tmp = frequency; + tmp <<= 33; + tmp = div64_s64(tmp, 4915200000); + pr_info("set base frequency = %u regs = 0x%08llx\n", frequency, tmp); + ddbwritel(dev, (u32) tmp, RFDAC_FCW); + return 0; +} + +static void mod3_set_cfcw(struct ddb_mod *mod, u32 f) { struct ddb *dev = mod->port->dev; + s32 freq = f; + s32 dcf = dev->mod_base.frequency; + s64 tmp, srdac = 245760000; + u32 cfcw; - switch(tvp->cmd) { - case MOD_SYMBOL_RATE: + tmp = ((s64) (freq - dcf)) << 32; + tmp = div64_s64(tmp, srdac); + cfcw = (u32) tmp; + pr_info("f=%u cfcw = %08x nr = %u\n", f, cfcw, mod->port->nr); + ddbwritel(dev, cfcw, SDR_CHANNEL_CFCW(mod->port->nr)); +} + +static int mod3_set_frequency(struct ddb_mod *mod, u32 frequency) +{ +#if 0 + struct ddb *dev = mod->port->dev; + + if (frequency % 1000) + return -EINVAL; + if ((frequency < 114000000) || (frequency > 874000000)) + return -EINVAL; + if (frequency > dev->mod_base.frequency) + if (frequency - dev->mod_base.frequency > 100000000) + return -EINVAL; + else + if (dev->mod_base.frequency - frequency > 100000000) + return -EINVAL; +#endif + mod3_set_cfcw(mod, frequency); + return 0; +} + +static int mod3_set_ari(struct ddb_mod *mod, u32 rate) +{ + ddbwritel(mod->port->dev, rate, SDR_CHANNEL_ARICW(mod->port->nr)); + return 0; +} + + +static int mod3_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp) +{ + switch (tvp->cmd) { + case MODULATOR_OUTPUT_ARI: + return mod3_set_ari(mod, tvp->u.data); + + case MODULATOR_FREQUENCY: + return mod3_set_frequency(mod, tvp->u.data); + + case MODULATOR_BASE_FREQUENCY: + return mod3_set_base_frequency(mod->port->dev, tvp->u.data); + } + return -EINVAL; +} + +static int mod_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp) +{ + if (mod->port->dev->link[0].info->version == 3) + return mod3_prop_proc(mod, tvp); + switch (tvp->cmd) { + case MODULATOR_SYMBOL_RATE: return mod_set_symbolrate(mod, tvp->u.data); - case MOD_MODULATION: + case MODULATOR_MODULATION: return mod_set_modulation(mod, tvp->u.data); - case MOD_FREQUENCY: + case MODULATOR_FREQUENCY: return mod_set_frequency(mod, tvp->u.data); - case MOD_ATTENUATOR: + case MODULATOR_ATTENUATOR: return mod_set_attenuator(mod->port->dev, tvp->u.data); - case MOD_INPUT_BITRATE: + case MODULATOR_INPUT_BITRATE: return mod_set_ibitrate(mod, tvp->u.data); + } return 0; } @@ -1504,17 +1533,21 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg) struct ddb_mod *mod = &dev->mod[output->nr]; int ret = 0; + if (dev->link[0].info->version == 3 && cmd != FE_SET_PROPERTY) + return -EINVAL; switch (cmd) { case FE_SET_PROPERTY: { - struct dtv_properties *tvps = (struct dtv_properties __user *) parg; + struct dtv_properties *tvps = + (struct dtv_properties __user *) parg; struct dtv_property *tvp = NULL; int i; - + if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS)) return -EINVAL; - - tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL); + + tvp = kmalloc(tvps->num * sizeof(struct dtv_property), + GFP_KERNEL); if (!tvp) { ret = -ENOMEM; goto out; @@ -1525,11 +1558,12 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg) goto out; } for (i = 0; i < tvps->num; i++) { - if ((ret = mod_prop_proc(mod, tvp + i)) < 0) + ret = mod_prop_proc(mod, tvp + i); + if (ret < 0) goto out; (tvp + i)->result = ret; } - out: +out: kfree(tvp); return ret; } @@ -1542,7 +1576,18 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg) if (set_base_frequency(dev, mp->base_frequency)) return -EINVAL; } else { + int i, streams = dev->link[0].info->port_num; + dev->mod_base.frequency = mp->base_frequency; + for (i = 0; i < streams; i++) { + struct ddb_mod *mod = &dev->mod[i]; + + mod->port = &dev->port[i]; + mod_set_modulation(mod, QAM_256); + mod_set_symbolrate(mod, 6900000); + mod_set_frequency(mod, dev->mod_base.frequency + + i * 8000000); + } } mod_set_attenuator(dev, mp->attenuator); break; @@ -1577,13 +1622,18 @@ static int mod_init_2(struct ddb *dev, u32 Frequency) dev->mod_base.frequency = Frequency; status = mod_fsm_setup(dev, 0, 0); + if (status) { + pr_err("FSM setup failed!\n"); + return -1; + } + for (i = 0; i < streams; i++) { struct ddb_mod *mod = &dev->mod[i]; mod->port = &dev->port[i]; mod_set_modulation(mod, QAM_256); mod_set_symbolrate(mod, 6900000); - mod_set_frequency(mod, 114000000 + i * 8000000); + mod_set_frequency(mod, dev->mod_base.frequency + i * 8000000); } if (streams <= 8) mod_set_vga(dev, RF_VGA_GAIN_N8); @@ -1591,16 +1641,146 @@ static int mod_init_2(struct ddb *dev, u32 Frequency) mod_set_vga(dev, RF_VGA_GAIN_N16); else mod_set_vga(dev, RF_VGA_GAIN_N24); - + mod_set_attenuator(dev, 0); return 0; } + +/****************************************************************************/ + +static u32 vsb13500[64] = { + 0x0000000E, 0x00010004, 0x00020003, 0x00030009, + 0x0004FFFA, 0x00050002, 0x0006FFF8, 0x0007FFF0, + 0x00080000, 0x0009FFEA, 0x000A0001, 0x000B0003, + 0x000CFFF9, 0x000D0025, 0x000E0004, 0x000F001F, + 0x00100023, 0x0011FFEE, 0x00120020, 0x0013FFD0, + 0x0014FFD5, 0x0015FFED, 0x0016FF8B, 0x0017000B, + 0x0018FFC8, 0x0019FFF1, 0x001A009E, 0x001BFFEF, + 0x001C013B, 0x001D00CB, 0x001E0031, 0x001F05F6, + + 0x0040FFFF, 0x00410004, 0x0042FFF8, 0x0043FFFE, + 0x0044FFFA, 0x0045FFF3, 0x00460003, 0x0047FFF4, + 0x00480005, 0x0049000D, 0x004A0000, 0x004B0022, + 0x004C0005, 0x004D000D, 0x004E0013, 0x004FFFDF, + 0x00500007, 0x0051FFD4, 0x0052FFD2, 0x0053FFFD, + 0x0054FFB7, 0x00550021, 0x00560009, 0x00570010, + 0x00580097, 0x00590003, 0x005A009D, 0x005B004F, + 0x005CFF89, 0x005D0097, 0x005EFD42, 0x005FFCBE +}; + +static u32 stage2[16] = { + 0x0080FFFF, 0x00810000, 0x00820005, 0x00830000, + 0x0084FFF0, 0x00850000, 0x00860029, 0x00870000, + 0x0088FFA2, 0x0089FFFF, 0x008A00C9, 0x008B000C, + 0x008CFE49, 0x008DFF9B, 0x008E04D4, 0x008F07FF +}; + +static void mod_set_sdr_table(struct ddb_mod *mod, u32 *tab, u32 len) +{ + struct ddb *dev = mod->port->dev; + u32 i; + + for (i = 0; i < len; i++) + ddbwritel(dev, tab[i], SDR_CHANNEL_SETFIR(mod->port->nr)); +} + +static int rfdac_init(struct ddb *dev) +{ + int i; + u32 tmp; + + ddbwritel(dev, RFDAC_CMD_POWERDOWN, RFDAC_CONTROL); + for (i = 0; i < 10; i++) { + msleep(20); + tmp = ddbreadl(dev, RFDAC_CONTROL); + if ((tmp & RFDAC_CMD_STATUS) == 0x00) + break; + } + if (tmp & 0x80) + return -1; + pr_info("sync %d:%08x\n", i, tmp); + ddbwritel(dev, RFDAC_CMD_RESET, RFDAC_CONTROL); + for (i = 0; i < 10; i++) { + msleep(20); + tmp = ddbreadl(dev, RFDAC_CONTROL); + if ((tmp & RFDAC_CMD_STATUS) == 0x00) + break; + } + if (tmp & 0x80) + return -1; + pr_info("sync %d:%08x\n", i, tmp); + ddbwritel(dev, RFDAC_CMD_SETUP, RFDAC_CONTROL); + for (i = 0; i < 10; i++) { + msleep(20); + tmp = ddbreadl(dev, RFDAC_CONTROL); + if ((tmp & RFDAC_CMD_STATUS) == 0x00) + break; + } + if (tmp & 0x80) + return -1; + pr_info("sync %d:%08x\n", i, tmp); + ddbwritel(dev, 0x01, JESD204B_BASE); + for (i = 0; i < 400; i++) { + msleep(20); + tmp = ddbreadl(dev, JESD204B_BASE); + if ((tmp & 0xc0000000) == 0xc0000000) + break; + } + pr_info("sync %d:%08x\n", i, tmp); + if ((tmp & 0xc0000000) != 0xc0000000) + return -1; + return 0; +} + +static int mod_init_3(struct ddb *dev, u32 Frequency) +{ + int streams = dev->link[0].info->port_num; + int i, ret = 0; + + mod_set_vga(dev, 64); + ret = mod_setup_max2871(dev, max2871_sdr); + if (ret) + pr_err("DDBridge: PLL setup failed\n"); + ret = rfdac_init(dev); + if (ret) + ret = rfdac_init(dev); + if (ret) + pr_err("DDBridge: RFDAC setup failed\n"); + + for (i = 0; i < streams; i++) { + struct ddb_mod *mod = &dev->mod[i]; + + mod->port = &dev->port[i]; + mod_set_sdr_table(mod, vsb13500, 64); + mod_set_sdr_table(mod, stage2, 16); + } + ddbwritel(dev, 0x1800, 0x244); + ddbwritel(dev, 0x01, 0x240); + + mod3_set_base_frequency(dev, 602000000); + for (i = 0; i < streams; i++) { + struct ddb_mod *mod = &dev->mod[i]; + + ddbwritel(dev, 0x00, SDR_CHANNEL_CONTROL(i)); + ddbwritel(dev, 0x06, SDR_CHANNEL_CONFIG(i)); + ddbwritel(dev, 0x70800000, SDR_CHANNEL_ARICW(i)); + mod3_set_frequency(mod, Frequency + 7000000 * i); + + ddbwritel(dev, 0x00011f80, SDR_CHANNEL_RGAIN(i)); + ddbwritel(dev, 0x00001000, SDR_CHANNEL_FM1GAIN(i)); + ddbwritel(dev, 0x00000800, SDR_CHANNEL_FM2GAIN(i)); + } + return ret; +} + int ddbridge_mod_init(struct ddb *dev) { 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); + if (dev->link[0].info->version == 3) + return mod_init_3(dev, 503250000); return -1; } diff --git a/ddbridge/ddbridge-ns.c b/ddbridge/ddbridge-ns.c index 38522ae..b2bca85 100644 --- a/ddbridge/ddbridge-ns.c +++ b/ddbridge/ddbridge-ns.c @@ -1,7 +1,7 @@ /* * ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming * - * Copyright (C) 2010-2015 Marcus Metzler + * Copyright (C) 2010-2017Marcus Metzler * Ralph Metzler * Digital Devices GmbH * @@ -87,7 +87,6 @@ static int ns_alloc(struct dvbnss *nss) dev->ns[i].fe = input; nss->priv = &dev->ns[i]; ret = 0; - /*pr_info("%s i=%d fe=%d\n", __func__, i, input->nr); */ break; } ddbwritel(dev, 0x03, RTP_MASTER_CONTROL); @@ -198,7 +197,7 @@ static int ns_set_ci(struct dvbnss *nss, u8 ci) if (ciport < 0) return -EINVAL; - pr_info("input %d.%d to ci %d at port %d\n", + pr_info("DDBridge: 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_CONTROL(dev->port[ciport].output)); @@ -446,8 +445,6 @@ static int ns_start(struct dvbnss *nss) if (dns->fe != input) ddb_dvb_ns_input_start(dns->fe); ddb_dvb_ns_input_start(input); - /* printk("ns start ns %u, fe %u link %u\n", - dns->nr, dns->fe->nr, dns->fe->port->lnr); */ ddbwritel(dev, reg | (dns->fe->nr << 8) | (dns->fe->port->lnr << 16), STREAM_CONTROL(dns->nr)); return 0; diff --git a/ddbridge/ddbridge-regs.h b/ddbridge/ddbridge-regs.h index 22ba6f3..4935b12 100644 --- a/ddbridge/ddbridge-regs.h +++ b/ddbridge/ddbridge-regs.h @@ -1,7 +1,7 @@ /* * ddbridge-regs.h: Digital Devices PCIe bridge driver * - * Copyright (C) 2010-2016 Digital Devices GmbH + * Copyright (C) 2010-2017 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 @@ -25,6 +25,7 @@ #define CUR_REGISTERMAP_VERSION_V1 0x00010001 #define CUR_REGISTERMAP_VERSION_V2 0x00020000 +#define CUR_REGISTERMAP_VERSION_022X 0x00020001 #define HARDWARE_VERSION 0x00000000 #define REGISTERMAP_VERSION 0x00000004 @@ -57,9 +58,9 @@ /* ------------------------------------------------------------------------- */ /* Interrupt controller - How many MSI's are available depends on HW (Min 2 max 8) - How many are usable also depends on Host platform -*/ + * How many MSI's are available depends on HW (Min 2 max 8) + * How many are usable also depends on Host platform + */ #define INTERRUPT_BASE (0x40) @@ -166,19 +167,22 @@ #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 ) +/* 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 °C x 256 (ADM1032 ext) -#define TEMPMON1_SENSOR1 (TEMPMON_BASE + 0x08) // SHORT Temperature in °C x 256 (LM75A 0x90) -#define TEMPMON1_SENSOR2 (TEMPMON_BASE + 0x0C) // SHORT Temperature in °C x 256 (LM75A 0x92 or ADM1032 Int) +#define TEMPMON1_CORE (TEMPMON_SENSOR0) // u16 Temperature in °C x 256 (ADM1032 ext) +#define TEMPMON1_SENSOR1 (TEMPMON_BASE + 0x08) // SHORT Temperature in °C x 256 (LM75A 0x90) +#define TEMPMON1_SENSOR2 (TEMPMON_BASE + 0x0C) // SHORT Temperature in °C x 256 (LM75A 0x92 or ADM1032 Int) // V2 Temperature Monitor 2 ADM1032 #define TEMPMON2_BOARD (TEMPMON_SENSOR0) // SHORT Temperature in °C x 256 (ADM1032 int) #define TEMPMON2_FPGACORE (TEMPMON_SENSOR1) // SHORT Temperature in °C x 256 (ADM1032 ext) #define TEMPMON2_QAMCORE (TEMPMON_SENSOR2) // SHORT Temperature in °C x 256 (ADM1032 ext) +#define TEMPMON2_DACCORE (TEMPMON_SENSOR2) // SHORT Temperature in °C x 256 (ADM1032 ext) /* ------------------------------------------------------------------------- */ /* I2C Master Controller */ @@ -242,7 +246,7 @@ #define LNB_CMD_HIGH 4 #define LNB_CMD_OFF 5 #define LNB_CMD_DISEQC 6 -#define LNB_CMD_UNI 7 +#define LNB_CMD_SCIF 7 #define LNB_BUSY (1ULL << 4) #define LNB_TONE (1ULL << 15) @@ -330,16 +334,16 @@ /* Muxout from VCO (usually = Lock) */ #define VCO3_CONTROL_MUXOUT (0x00000004) -// V2 +/* 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_OUTDATA (MAX2871_BASE + 0x04) +#define MAX2871_INDATA (MAX2871_BASE + 0x08) #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 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) @@ -358,9 +362,9 @@ #define FSM_CAPACITY (FSM_BASE + 0x04) -#define FSM_CAPACITY_MAX (0x3F000000) -#define FSM_CAPACITY_CUR (0x003F0000) -#define FSM_CAPACITY_INUSE (0x0000003F) +#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) @@ -379,15 +383,15 @@ #define RF_ATTENUATOR (0xD8) #define RF_ATTENUATOR (0xD8) /* 0x00 = 0 dB - 0x01 = 1 dB - ... - 0x1F = 31 dB -*/ + * 0x01 = 1 dB + * ... + * 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) @@ -409,9 +413,9 @@ #define RF_POWER_CONTROL_VALID (0x00000500) -/* -------------------------------------------------------------------------- - Output control -*/ +/* + * Output control + */ #define IQOUTPUT_BASE (0x240) #define IQOUTPUT_CONTROL (IQOUTPUT_BASE + 0x00) @@ -552,3 +556,76 @@ +// V2 + +// MAX2871 same as DVB Modulator V2 + +#define RFDAC_BASE (0x200) +#define RFDAC_CONTROL (RFDAC_BASE + 0x00) + +#define RFDAC_CMD_MASK (0x00000087) +#define RFDAC_CMD_STATUS (0x00000080) +#define RFDAC_CMD_RESET (0x00000080) +#define RFDAC_CMD_POWERDOWN (0x00000081) +#define RFDAC_CMD_SETUP (0x00000082) + +#define RFDAC_STATUS (RFDAC_BASE + 0x00) +#define RFDAC_STATUS_READY (0x00010000) +#define RFDAC_STATUS_DACREADY (0x00020000) + +#define RFDAC_FCW (RFDAC_BASE + 0x10) + +// +// -------------------------------------------------------------------------- +// + +#define JESD204B_BASE (0x280) + +// Additional Status Bits + +#define DMA_PCIE_LANES_MASK (0x00070000) + + +// -------------------------------------------------------------------------- +// Modulator Channels, partially compatible to DVB Modulator V1 + +#define SDR_CHANNEL_BASE (0x800) + +#define SDR_CHANNEL_CONTROL(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x00) +#define SDR_CHANNEL_CONFIG(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x04) +#define SDR_CHANNEL_CFCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x08) +#define SDR_CHANNEL_ARICW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x0C) +#define SDR_CHANNEL_RGAIN(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x10) +#define SDR_CHANNEL_SETFIR(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x14) + +#define SDR_CHANNEL_FMDCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x20) +#define SDR_CHANNEL_FM1FCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x24) +#define SDR_CHANNEL_FM2FCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x28) +#define SDR_CHANNEL_FM1GAIN(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x2C) +#define SDR_CHANNEL_FM2GAIN(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x30) + +// Control and status bits +#define SDR_CONTROL_ENABLE_CHANNEL (0x00000004) +#define SDR_CONTROL_ENABLE_DMA (0x00000008) +#define SDR_STATUS_DMA_UNDERRUN (0x00010000) + +// Config +#define SDR_CONFIG_ENABLE_FM1 (0x00000002) +#define SDR_CONFIG_ENABLE_FM2 (0x00000004) +#define SDR_CONFIG_DISABLE_ARI (0x00000010) +#define SDR_CONFIG_DISABLE_VSB (0x00000020) + +// SET FIR +#define SDR_FIR_COEFF_MASK (0x00000FFF) +#define SDR_FIR_TAP_MASK (0x001F0000) +#define SDR_FIR_SELECT_MASK (0x00C00000) +#define SDR_VSB_LENGTH_MASK (0x01000000) + +#define SDR_SET_FIR(select, tap, coeff, vsblen) \ + ((((select)<<22)&SDR_FIR_SELECT_MASK)| \ + (((tap)<<16)&SDR_FIR_TAP_MASK)| \ + ((coeff)&SDR_FIR_COEFF_MASK)| \ + (((vsblen)<<24)&SDR_VSB_LENGTH_MASK)| \ + 0 \ + ) + diff --git a/ddbridge/ddbridge.c b/ddbridge/ddbridge.c index 45f3f7c..0ec1761 100644 --- a/ddbridge/ddbridge.c +++ b/ddbridge/ddbridge.c @@ -1,7 +1,7 @@ /* * ddbridge.c: Digital Devices PCIe bridge driver * - * Copyright (C) 2010-2015 Digital Devices GmbH + * Copyright (C) 2010-2017 Digital Devices GmbH * Ralph Metzler * Marcus Metzler * @@ -113,19 +113,23 @@ static void __devexit ddb_remove(struct pci_dev *pdev) static int __devinit ddb_irq_msi(struct ddb *dev, int nr) { - int stat; + int stat = 0; #ifdef CONFIG_PCI_MSI if (msi && pci_msi_enabled()) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) + stat = pci_alloc_irq_vectors(dev->pdev, 1, nr, PCI_IRQ_MSI); +#else stat = pci_enable_msi_range(dev->pdev, 1, nr); +#endif 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) { @@ -135,7 +139,7 @@ static int __devinit ddb_irq_msi(struct ddb *dev, int nr) stat = pci_enable_msi(dev->pdev); dev->msi = 1; } - if (stat < 0) + if (stat < 0) pr_info("DDBridge: MSI not available.\n"); #endif } @@ -147,7 +151,7 @@ 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"); + pr_info("DDBridge: init type 2 IRQ hardware block\n"); ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL); ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1); @@ -166,7 +170,7 @@ static int __devinit ddb_irq_init2(struct ddb *dev) 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); @@ -177,15 +181,15 @@ static int __devinit ddb_irq_init2(struct ddb *dev) 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); @@ -250,7 +254,7 @@ static int __devinit ddb_probe(struct pci_dev *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; @@ -267,8 +271,12 @@ static int __devinit ddb_probe(struct pci_dev *pdev, dev->link[0].ids.subdevice = id->subdevice; dev->link[0].dev = dev; +#ifdef NUM_IDS + dev->link[0].info = ddb_infos[id->driver_data]; +#else dev->link[0].info = (struct ddb_info *) id->driver_data; - pr_info("DDBridge driver detected: %s\n", dev->link[0].info->name); +#endif + pr_info("DDBridge: device name: %s\n", dev->link[0].info->name); dev->regs_len = pci_resource_len(dev->pdev, 0); dev->regs = ioremap(pci_resource_start(dev->pdev, 0), @@ -307,17 +315,17 @@ static int __devinit ddb_probe(struct pci_dev *pdev, stat = ddb_irq_init(dev); if (stat < 0) goto fail0; - + if (ddb_init(dev) == 0) return 0; - ddb_irq_disable(dev); + ddb_irq_exit(dev); fail0: - pr_err("fail0\n"); + pr_err("DDBridge: fail0\n"); if (dev->msi) pci_disable_msi(dev->pdev); fail: - pr_err("fail\n"); + pr_err("DDBridge: fail\n"); ddb_unmap(dev); pci_set_drvdata(pdev, NULL); @@ -395,6 +403,17 @@ static struct ddb_info ddb_v6_5 = { .i2c_mask = 0x0f, }; +static struct ddb_info ddb_v7a = { + .type = DDB_OCTOPUS, + .name = "Digital Devices Cine S2 V7 Advanced DVB adapter", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x0f, + .board_control = 2, + .board_control_2 = 4, + .ts_quirks = TS_QUIRK_REVERSED, +}; + static struct ddb_info ddb_v7 = { .type = DDB_OCTOPUS, .name = "Digital Devices Cine S2 V7 DVB adapter", @@ -450,6 +469,16 @@ static struct ddb_info ddb_ci_s2_pro = { .board_control_2 = 4, }; +static struct ddb_info ddb_ci_s2_pro_a = { + .type = DDB_OCTOPUS_CI, + .name = "Digital Devices Octopus CI S2 Pro Advanced", + .regmap = &octopus_map, + .port_num = 4, + .i2c_mask = 0x01, + .board_control = 2, + .board_control_2 = 4, +}; + static struct ddb_info ddb_dvbct = { .type = DDB_OCTOPUS, .name = "Digital Devices DVBCT V6.1 DVB adapter", @@ -498,6 +527,16 @@ static struct ddb_info ddb_mod_fsm_8 = { .tempmon_irq = 8, }; +static struct ddb_info ddb_sdr = { + .type = DDB_MOD, + .name = "Digital Devices SDR", + .version = 3, + .regmap = &octopus_sdr_map, + .port_num = 16, + .temp_num = 1, + .tempmon_irq = 8, +}; + static struct ddb_info ddb_octopro_hdin = { .type = DDB_OCTOPRO_HDIN, .name = "Digital Devices OctopusNet Pro HDIN", @@ -520,69 +559,83 @@ static struct ddb_info ddb_octopro = { /****************************************************************************/ /****************************************************************************/ -#define DDVID 0xdd01 /* Digital Devices Vendor ID */ +#define DDB_DEVICE(_device, _subdevice, _driver_data) { \ + PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, _subdevice), \ + .driver_data = (kernel_ulong_t) &_driver_data } -#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ - .vendor = _vend, .device = _dev, \ - .subvendor = _subvend, .subdevice = _subdev, \ - .driver_data = (unsigned long)&_driverdata } +#define DDB_DEVICE_ANY(_device) { \ + PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, PCI_ANY_ID), \ + .driver_data = (kernel_ulong_t) &ddb_none } -static const struct pci_device_id ddb_id_tbl[] __devinitconst = { - DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), - DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), - DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3), - DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), - DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem), - DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini), - DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini), - DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), - DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), - DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7), - DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), - DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), - DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7), - DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7), - DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7), - DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48), - DDB_ID(DDVID, 0x0008, DDVID, 0x0034, ddb_ct2_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0035, ddb_c2t2_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0036, ddb_isdbt_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0037, ddb_c2t2i_v0_8), - DDB_ID(DDVID, 0x0008, DDVID, 0x0038, ddb_c2t2i_8), - DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci), - DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis), - DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci), - DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro), - DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod), - DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod), - DDB_ID(DDVID, 0x0203, DDVID, 0x0001, ddb_mod), - 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), +static const struct pci_device_id ddb_id_table[] __devinitconst = { + DDB_DEVICE(0x0002, 0x0001, ddb_octopus), + DDB_DEVICE(0x0003, 0x0001, ddb_octopus), + DDB_DEVICE(0x0005, 0x0004, ddb_octopusv3), + DDB_DEVICE(0x0003, 0x0002, ddb_octopus_le), + DDB_DEVICE(0x0003, 0x0003, ddb_octopus_oem), + DDB_DEVICE(0x0003, 0x0010, ddb_octopus_mini), + DDB_DEVICE(0x0005, 0x0011, ddb_octopus_mini), + DDB_DEVICE(0x0003, 0x0020, ddb_v6), + DDB_DEVICE(0x0003, 0x0021, ddb_v6_5), + DDB_DEVICE(0x0006, 0x0022, ddb_v7), + DDB_DEVICE(0x0006, 0x0024, ddb_v7a), + DDB_DEVICE(0x0003, 0x0030, ddb_dvbct), + DDB_DEVICE(0x0003, 0xdb03, ddb_satixS2v3), + DDB_DEVICE(0x0006, 0x0031, ddb_ctv7), + DDB_DEVICE(0x0006, 0x0032, ddb_ctv7), + DDB_DEVICE(0x0006, 0x0033, ddb_ctv7), + DDB_DEVICE(0x0007, 0x0023, ddb_s2_48), + DDB_DEVICE(0x0008, 0x0034, ddb_ct2_8), + DDB_DEVICE(0x0008, 0x0035, ddb_c2t2_8), + DDB_DEVICE(0x0008, 0x0036, ddb_isdbt_8), + DDB_DEVICE(0x0008, 0x0037, ddb_c2t2i_v0_8), + DDB_DEVICE(0x0008, 0x0038, ddb_c2t2i_8), + DDB_DEVICE(0x0006, 0x0039, ddb_ctv7), + DDB_DEVICE(0x0011, 0x0040, ddb_ci), + DDB_DEVICE(0x0011, 0x0041, ddb_cis), + DDB_DEVICE(0x0012, 0x0042, ddb_ci), + DDB_DEVICE(0x0013, 0x0043, ddb_ci_s2_pro), + DDB_DEVICE(0x0013, 0x0044, ddb_ci_s2_pro_a), + DDB_DEVICE(0x0201, 0x0001, ddb_mod), + DDB_DEVICE(0x0201, 0x0002, ddb_mod), + DDB_DEVICE(0x0203, 0x0001, ddb_mod), + DDB_DEVICE(0x0210, 0x0001, ddb_mod_fsm_24), + DDB_DEVICE(0x0210, 0x0002, ddb_mod_fsm_16), + DDB_DEVICE(0x0210, 0x0003, ddb_mod_fsm_8), + DDB_DEVICE(0x0220, 0x0001, ddb_sdr), /* 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), + DDB_DEVICE(0x0320, PCI_ANY_ID, ddb_octopro_hdin), + DDB_DEVICE(0x0321, PCI_ANY_ID, ddb_none), + DDB_DEVICE(0x0322, PCI_ANY_ID, ddb_octopro), + DDB_DEVICE(0x0323, PCI_ANY_ID, ddb_none), + DDB_DEVICE(0x0328, PCI_ANY_ID, ddb_none), + DDB_DEVICE(0x0329, 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), - DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0008, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none), - DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_none), + DDB_DEVICE_ANY(0x0003), + DDB_DEVICE_ANY(0x0005), + DDB_DEVICE_ANY(0x0006), + DDB_DEVICE_ANY(0x0007), + DDB_DEVICE_ANY(0x0008), + DDB_DEVICE_ANY(0x0011), + DDB_DEVICE_ANY(0x0012), + DDB_DEVICE_ANY(0x0013), + DDB_DEVICE_ANY(0x0201), + DDB_DEVICE_ANY(0x0203), + DDB_DEVICE_ANY(0x0210), + DDB_DEVICE_ANY(0x0220), + DDB_DEVICE_ANY(0x0320), + DDB_DEVICE_ANY(0x0321), + DDB_DEVICE_ANY(0x0322), + DDB_DEVICE_ANY(0x0323), + DDB_DEVICE_ANY(0x0328), + DDB_DEVICE_ANY(0x0329), {0} }; -MODULE_DEVICE_TABLE(pci, ddb_id_tbl); +MODULE_DEVICE_TABLE(pci, ddb_id_table); static struct pci_driver ddb_pci_driver = { .name = "ddbridge", - .id_table = ddb_id_tbl, + .id_table = ddb_id_table, .probe = ddb_probe, .remove = ddb_remove, }; @@ -591,9 +644,9 @@ static __init int module_init_ddbridge(void) { int stat = -1; - pr_info("Digital Devices PCIE bridge driver " + pr_info("DDBridge: Digital Devices PCIE bridge driver " DDBRIDGE_VERSION - ", Copyright (C) 2010-16 Digital Devices GmbH\n"); + ", Copyright (C) 2010-17 Digital Devices GmbH\n"); if (ddb_class_create() < 0) return -1; ddb_wq = create_workqueue("ddbridge"); diff --git a/ddbridge/ddbridge.h b/ddbridge/ddbridge.h index e957476..28dd20d 100644 --- a/ddbridge/ddbridge.h +++ b/ddbridge/ddbridge.h @@ -1,7 +1,7 @@ /* * ddbridge.h: Digital Devices PCIe bridge driver * - * Copyright (C) 2010-2015 Digital Devices GmbH + * Copyright (C) 2010-2017 Digital Devices GmbH * Ralph Metzler * * This program is free software; you can redistribute it and/or @@ -55,7 +55,6 @@ #include #include -#include #include #include #include @@ -123,7 +122,7 @@ struct ddb_regmap { struct ddb_regset *input; struct ddb_regset *output; - + struct ddb_regset *channel; //struct ddb_regset *ci; //struct ddb_regset *pid_filter; @@ -172,22 +171,24 @@ struct ddb_info { #define TS_QUIRK_SERIAL 1 #define TS_QUIRK_REVERSED 2 #define TS_QUIRK_NO_OUTPUT 4 +#define TS_QUIRK_ALT_OSC 8 u32 tempmon_irq; struct ddb_regmap *regmap; }; /* DMA_SIZE MUST be smaller than 256k and - MUST be divisible by 188 and 128 !!! */ + * MUST be divisible by 188 and 128 !!! + */ #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_SIZE (128*47*5) #define INPUT_DMA_IRQ_DIV 1 #define OUTPUT_DMA_BUFS 32 -#define OUTPUT_DMA_SIZE (32*47*21) +#define OUTPUT_DMA_SIZE (128*47*5) #define OUTPUT_DMA_IRQ_DIV 1 #else #define INPUT_DMA_BUFS 8 @@ -198,6 +199,10 @@ struct ddb_info { #define OUTPUT_DMA_SIZE (128*47*21) #define OUTPUT_DMA_IRQ_DIV 1 #endif +#define OUTPUT_DMA_BUFS_SDR 32 +#define OUTPUT_DMA_SIZE_SDR (256*1024) +#define OUTPUT_DMA_IRQ_DIV_SDR 1 + struct ddb; struct ddb_port; @@ -317,6 +322,7 @@ struct ddb_port { #define DDB_CI_EXTERNAL_XO2 12 #define DDB_CI_EXTERNAL_XO2_B 13 #define DDB_TUNER_DVBS_STV0910_PR 14 +#define DDB_TUNER_DVBC2T2I_SONY_P 15 #define DDB_TUNER_XO2 32 #define DDB_TUNER_DVBS_STV0910 (DDB_TUNER_XO2 + 0) @@ -324,7 +330,7 @@ struct ddb_port { #define DDB_TUNER_ISDBT_SONY (DDB_TUNER_XO2 + 2) #define DDB_TUNER_DVBC2T2_SONY (DDB_TUNER_XO2 + 3) #define DDB_TUNER_ATSC_ST (DDB_TUNER_XO2 + 4) -#define DDB_TUNER_DVBC2T2_ST (DDB_TUNER_XO2 + 5) +#define DDB_TUNER_DVBC2T2I_SONY (DDB_TUNER_XO2 + 5) struct ddb_input *input[2]; struct ddb_output *output; @@ -343,13 +349,13 @@ struct mod_base { struct ddb_mod { struct ddb_port *port; - u32 nr; - u32 regs; - + //u32 nr; + //u32 regs; + u32 frequency; u32 modulation; u32 symbolrate; - + u64 obitrate; u64 ibitrate; u32 pcr_correction; @@ -676,15 +682,6 @@ static void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count) return memcpy_fromio(dst, (char *) (dev->regs + adr), count); } -#if 0 - -#define ddbcpyto(_dev, _adr, _src, _count) \ - memcpy_toio((char *) (_dev->regs + (_adr)), (_src), (_count)) - -#define ddbcpyfrom(_dev, _dst, _adr, _count) \ - memcpy_fromio((_dst), (char *) (_dev->regs + (_adr)), (_count)) -#endif - #define ddbmemset(_dev, _adr, _val, _count) \ memset_io((char *) (_dev->regs + (_adr)), (_val), (_count)) @@ -751,6 +748,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.26" +#define DDBRIDGE_VERSION "0.9.29" #endif diff --git a/ddbridge/octonet.c b/ddbridge/octonet.c index 35dfb33..fd686c6 100644 --- a/ddbridge/octonet.c +++ b/ddbridge/octonet.c @@ -1,7 +1,7 @@ /* * octonet.c: Digital Devices network tuner driver * - * Copyright (C) 2012-16 Digital Devices GmbH + * Copyright (C) 2012-17 Digital Devices GmbH * Marcus Metzler * Ralph Metzler * @@ -177,9 +177,9 @@ static int __init octonet_probe(struct platform_device *pdev) else dev->link[0].info = &ddb_octonet_tbd; - pr_info("HW %08x REGMAP %08x\n", + pr_info("DDBridge: HW %08x REGMAP %08x\n", dev->link[0].ids.hwid, dev->link[0].ids.regmapid); - pr_info("MAC %08x DEVID %08x\n", + pr_info("DDBridge: MAC %08x DEVID %08x\n", dev->link[0].ids.mac, dev->link[0].ids.devid); ddbwritel(dev, 0, ETHER_CONTROL); @@ -233,7 +233,7 @@ static __init int init_octonet(void) { int res; - pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION + pr_info("DDBridge: Digital Devices OctopusNet driver " DDBRIDGE_VERSION ", Copyright (C) 2010-16 Digital Devices GmbH\n"); res = ddb_class_create(); if (res) diff --git a/dvb-core/dvb_ca_en50221.c b/dvb-core/dvb_ca_en50221.c index 3738ff5..cefe881 100644 --- a/dvb-core/dvb_ca_en50221.c +++ b/dvb-core/dvb_ca_en50221.c @@ -35,7 +35,12 @@ #include #include #include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) +#include +#else #include +#endif #include #include "dvb_ca_en50221.h" diff --git a/dvb-core/dvb_demux.c b/dvb-core/dvb_demux.c index 3485655..43d4fcf 100644 --- a/dvb-core/dvb_demux.c +++ b/dvb-core/dvb_demux.c @@ -21,7 +21,12 @@ * */ +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) +#include +#else #include +#endif #include #include #include diff --git a/dvb-core/dvb_frontend.h b/dvb-core/dvb_frontend.h index a8df38f..1a1af78 100644 --- a/dvb-core/dvb_frontend.h +++ b/dvb-core/dvb_frontend.h @@ -29,7 +29,12 @@ #define _DVB_FRONTEND_H_ #include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)) +#include +#else #include +#endif #include #include #include diff --git a/dvb-core/dvbdev.h b/dvb-core/dvbdev.h index e534ef1..5a559e9 100644 --- a/dvb-core/dvbdev.h +++ b/dvb-core/dvbdev.h @@ -33,7 +33,7 @@ #if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0 #define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS #else - #define DVB_MAX_ADAPTERS 8 + #define DVB_MAX_ADAPTERS 64 #endif #define DVB_UNSET (-1) diff --git a/frontends/cxd2843.c b/frontends/cxd2843.c index 82bc7c5..f8dd623 100644 --- a/frontends/cxd2843.c +++ b/frontends/cxd2843.c @@ -96,7 +96,7 @@ static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len) struct i2c_msg msg = { .addr = adr, .flags = 0, .buf = data, .len = len}; if (i2c_transfer(adap, &msg, 1) != 1) { - pr_err("cxd2843: i2c_write error\n"); + pr_err("cxd2843: i2c_write error adr %02x data %02x\n", adr, data[0]); return -1; } return 0; @@ -270,9 +270,10 @@ static int writebitsx(struct cxd_state *cxd, u8 Bank, u8 Address, mutex_lock(&cxd->mutex); status = readregsx_unlocked(cxd, Bank, Address, &tmp, 1); if (status < 0) - return status; + goto out; tmp = (tmp & ~Mask) | Value; status = writeregsx_unlocked(cxd, Bank, Address, &tmp, 1); +out: mutex_unlock(&cxd->mutex); return status; } @@ -286,9 +287,10 @@ static int writebitst(struct cxd_state *cxd, u8 Bank, u8 Address, mutex_lock(&cxd->mutex); status = readregst_unlocked(cxd, Bank, Address, &Tmp, 1); if (status < 0) - return status; + goto out; Tmp = (Tmp & ~Mask) | Value; status = writeregst_unlocked(cxd, Bank, Address, &Tmp, 1); +out: mutex_unlock(&cxd->mutex); return status; } @@ -508,8 +510,12 @@ static void ActiveC2_to_Sleep(struct cxd_state *state) writebitst(state, 0x2B, 0x2B, 0x00, 0x1F); { u8 data[2] = { 0x75, 0x75 }; + u8 data24[2] = { 0x89, 0x89 }; - writeregst(state, 0x2D, 0x24, data, sizeof(data)); + if (state->is24MHz) + writeregst(state, 0x2D, 0x24, data24, sizeof(data24)); + else + writeregst(state, 0x2D, 0x24, data, sizeof(data)); } writeregx(state, 0x00, 0x18, 0x01); /* Disable ADC 4 */ @@ -554,62 +560,115 @@ static int ConfigureTS(struct cxd_state *state, return status; } +#if 0 +static int set_tr(struct cxd_state *state, u32 bw, u32 osc24) +{ + u64 tr = 7 *(osc24 ? 0x1800000000 : 0x1480000000); + + div64_32(tr, bw); + printk("TR %016llx\n", tr); + return 0; +} +#endif + static void BandSettingT(struct cxd_state *state, u32 iffreq) { u8 IF_data[3] = { (iffreq >> 16) & 0xff, (iffreq >> 8) & 0xff, iffreq & 0xff}; + u8 data[] = { 0x01, 0x14 }; + writeregst(state, 0x13, 0x9c, data, sizeof(data)); switch (state->bw) { default: case 8: { - u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; - u8 CL_data[] = { 0x01, 0xE0 }; u8 NF_data[] = { 0x01, 0x02 }; - writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + if (state->is24MHz) { + u8 TR_data[] = { 0x15, 0x00, 0x00, 0x00, 0x00 }; + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x00, 0x07); - writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + if (state->is24MHz) { + u8 CL_data[] = { 0x15, 0x28 }; + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } else { + u8 CL_data[] = { 0x01, 0xE0 }; + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); break; } case 7: { - u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 }; - u8 CL_data[] = { 0x12, 0xF8 }; u8 NF_data[] = { 0x00, 0x03 }; - writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + if (state->is24MHz) { + u8 TR_data[] = { 0x18, 0x00, 0x00, 0x00, 0x00 }; + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 }; + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x02, 0x07); - writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + if (state->is24MHz) { + u8 CL_data[] = { 0x1f, 0xf8 }; + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } else { + u8 CL_data[] = { 0x12, 0xF8 }; + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); break; } case 6: { - u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; - u8 CL_data[] = { 0x1F, 0xDC }; u8 NF_data[] = { 0x00, 0x03 }; - writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + if (state->is24MHz) { + u8 TR_data[] = { 0x1c, 0x00, 0x00, 0x00, 0x00 }; + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x04, 0x07); - writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + if (state->is24MHz) { + u8 CL_data[] = { 0x25, 0x4c }; + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } else { + u8 CL_data[] = { 0x1F, 0xDC }; + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); break; } case 5: { - static u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 }; - static u8 CL_data[] = { 0x26, 0x3C }; static u8 NF_data[] = { 0x00, 0x03 }; - writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + if (state->is24MHz) { + u8 TR_data[] = { 0x21, 0x99, 0x99, 0x99, 0x99 }; + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } else { + static u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 }; + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x06, 0x07); - writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + if (state->is24MHz) { + static u8 CL_data[] = { 0x2c, 0xc2 }; + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } else { + static u8 CL_data[] = { 0x26, 0x3C }; + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data)); break; } @@ -626,7 +685,7 @@ static void Sleep_to_ActiveT(struct cxd_state *state, u32 iffreq) writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */ writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ { - u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ + u8 data[2] = { 0x09, 0x54 }; /* 20.5/24 MHz */ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ @@ -634,7 +693,7 @@ static void Sleep_to_ActiveT(struct cxd_state *state, u32 iffreq) writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */ writebitst(state, 0x10, 0xD2, 0x0C, 0x1F); /* IF AGC Gain */ - writeregt(state, 0x11, 0x6A, 0x48); /* BB AGC Target Level */ + writeregt(state, 0x11, 0x6A, 0x50); /* BB AGC Target Level */ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ @@ -645,6 +704,13 @@ static void Sleep_to_ActiveT(struct cxd_state *state, u32 iffreq) writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ + if (state->is24MHz) { + u8 data[3] = { 0xdc, 0x6c, 0x00 }; + + writeregt(state, 0x10, 0xbf, 0x60); + writeregst(state, 0x18, 0x24, data, 3); + } + BandSettingT(state, iffreq); writebitst(state, 0x10, 0x60, 0x11, 0x1f); /* BER scaling */ @@ -662,10 +728,16 @@ static void BandSettingT2(struct cxd_state *state, u32 iffreq) default: case 8: { - u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; - /* Timing recovery */ - writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + if (state->is24MHz) { + u8 TR_data[] = { 0x15, 0x00, 0x00, 0x00, 0x00 }; + + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; + + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } /* Add EQ Optimisation for tuner here */ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); /* System Bandwidth */ @@ -674,36 +746,60 @@ static void BandSettingT2(struct cxd_state *state, u32 iffreq) break; case 7: { - u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 }; + if (state->is24MHz) { + u8 TR_data[] = { 0x18, 0x00, 0x00, 0x00, 0x00 }; - writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 }; + + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x02, 0x07); } break; case 6: { - u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; + if (state->is24MHz) { + u8 TR_data[] = { 0x1c, 0x00, 0x00, 0x00, 0x00 }; - writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; + + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x04, 0x07); } break; case 5: { - u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 }; + if (state->is24MHz) { + u8 TR_data[] = { 0x21, 0x99, 0x99, 0x99, 0x99 }; - writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 }; + + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x06, 0x07); } break; case 2: /* 1.7 MHz */ { - u8 TR_data[] = { 0x58, 0xE2, 0xAF, 0xE0, 0xBC }; + if (state->is24MHz) { + u8 TR_data[] = { 0x68, 0x0f, 0xa2, 0x32, 0xd0 }; - writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x58, 0xE2, 0xAF, 0xE0, 0xBC }; + + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x03, 0x07); } @@ -724,7 +820,7 @@ static void Sleep_to_ActiveT2(struct cxd_state *state, u32 iffreq) writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ { - u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ + u8 data[2] = { 0x09, 0x54 }; /* 20.5/24 MHz */ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ @@ -737,6 +833,7 @@ static void Sleep_to_ActiveT2(struct cxd_state *state, u32 iffreq) writeregt(state, 0x20, 0x8B, 0x3C); /* SNR Good count */ writebitst(state, 0x2B, 0x76, 0x20, 0x70); /* Noise Gain ACQ */ + writebitst(state, 0x23, 0xe6, 0x00, 0x03); writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ @@ -745,7 +842,34 @@ static void Sleep_to_ActiveT2(struct cxd_state *state, u32 iffreq) writeregt(state, 0x13, 0x86, 0x34); writebitst(state, 0x13, 0x9E, 0x09, 0x0F); writeregt(state, 0x13, 0x9F, 0xD8); + writebitst(state, 0x23, 0x11, 0x20, 0x3F); + + if (state->is24MHz ) { + static u8 data1[] = { 0xEB, 0x03, 0x3B }; + static u8 data2[] = { 0x5E, 0x5E, 0x47 }; + static u8 data3[] = { 0x3F, 0xFF }; + static u8 data4[] = { 0x0B, 0x72 }; + static u8 data5[] = { 0x93, 0xF3, 0x00 }; + static u8 data6[] = { 0x05, 0xB8, 0xD8 }; + static u8 data7[] = { 0x89, 0x89 }; + static u8 data8[] = { 0x24, 0x95 }; + + writeregst(state, 0x11, 0x33, data1, sizeof(data1)); + writeregst(state, 0x20, 0x95, data2, sizeof(data2)); + writeregt(state, 0x20, 0x99, 0x18); + writeregst(state, 0x20, 0xD9, data3, sizeof(data3)); + writeregst(state, 0x24, 0x34, data4, sizeof(data4)); + writeregst(state, 0x24, 0xD2, data5, sizeof(data5)); + writeregst(state, 0x24, 0xDD, data6, sizeof(data6)); + writeregt(state, 0x24, 0xE0, 0x00); + writeregt(state, 0x25, 0xED, 0x60); + writeregt(state, 0x27, 0xFA, 0x34); + writeregt(state, 0x2B, 0x4B, 0x2F); + writeregt(state, 0x2B, 0x9E, 0x0E); + writeregst(state, 0x2D, 0x24, data7, sizeof(data7)); + writeregst(state, 0x5E, 0x8C, data8, sizeof(data8)); + } BandSettingT2(state, iffreq); writebitst(state, 0x20, 0x72, 0x08, 0x0f); /* BER scaling */ @@ -777,7 +901,7 @@ static void Sleep_to_ActiveC(struct cxd_state *state, u32 iffreq) writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ { - u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ + u8 data[2] = { 0x09, 0x54 }; /* 20.5/24 MHz */ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ @@ -793,6 +917,18 @@ static void Sleep_to_ActiveC(struct cxd_state *state, u32 iffreq) writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */ writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ + if (state->is24MHz) { + u8 data1[2] = { 0x29, 0x09 }; + u8 data2[4] = { 0x08, 0x38, 0x83, 0x0E }; + u8 data3[3] = { 0xDC, 0x6C, 0x00 }; + u8 data4[2] = { 0x77, 0x00 }; + + writeregst(state,0x40,0x54,data1,2); + writeregst(state,0x40,0x8b,data2,4); + writeregt(state,0x40,0xBF,0x60); + writeregst(state,0x48,0x24,data3,2); + writeregst(state,0x49,0x11,data4,2); + } BandSettingC(state, iffreq); writebitst(state, 0x40, 0x60, 0x11, 0x1f); /* BER scaling */ @@ -810,28 +946,57 @@ static void BandSettingC2(struct cxd_state *state, u32 iffreq) default: case 8: { - u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; - u8 data[2] = { 0x11, 0x9E }; + if (state->is24MHz) { + u8 TR_data[] = { 0x15, 0x00, 0x00, 0x00, 0x00 }; + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } + writebitst(state, 0x27, 0x7a, 0x00, 0x0f); - writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x00, 0x07); - writeregst(state, 0x50, 0xEC, data, sizeof(data)); - writeregt(state, 0x50, 0xEF, 0x11); - writeregt(state, 0x50, 0xF1, 0x9E); + + if (state->is24MHz) { + u8 data[2] = { 0x14, 0xa0 }; + + writeregst(state, 0x50, 0xEC, data, sizeof(data)); + writeregt(state, 0x50, 0xEF, 0x14); + writeregt(state, 0x50, 0xF1, 0xa0); + } else { + u8 data[2] = { 0x11, 0x9E }; + + writeregst(state, 0x50, 0xEC, data, sizeof(data)); + writeregt(state, 0x50, 0xEF, 0x11); + writeregt(state, 0x50, 0xF1, 0x9E); + } } break; case 6: { - u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; - u8 data[2] = { 0x17, 0x70 }; - - writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + if (state->is24MHz) { + u8 TR_data[] = { 0x1c, 0x00, 0x00, 0x00, 0x00 }; + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; + writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x04, 0x07); - writeregst(state, 0x50, 0xEC, data, sizeof(data)); - writeregt(state, 0x50, 0xEF, 0x17); - writeregt(state, 0x50, 0xF1, 0x70); + if (state->is24MHz) { + u8 data[2] = { 0x1b, 0x70 }; + + writeregst(state, 0x50, 0xEC, data, sizeof(data)); + writeregt(state, 0x50, 0xEF, 0x1b); + writeregt(state, 0x50, 0xF1, 0x70); + } else { + u8 data[2] = { 0x17, 0x70 }; + + writeregst(state, 0x50, 0xEC, data, sizeof(data)); + writeregt(state, 0x50, 0xEF, 0x17); + writeregt(state, 0x50, 0xF1, 0x70); + } } break; } @@ -849,7 +1014,7 @@ static void Sleep_to_ActiveC2(struct cxd_state *state, u32 iffreq) writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ { - u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */ + u8 data[2] = { 0x09, 0x54 }; /* 20.5/24 MHz */ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ writeregst(state, 0x00, 0x43, data, sizeof(data)); @@ -891,7 +1056,23 @@ static void Sleep_to_ActiveC2(struct cxd_state *state, u32 iffreq) writeregst(state, 0x2D, 0x24, data, sizeof(data)); } - + if (state->is24MHz) { + u8 data1[3] = { 0xEB, 0x03, 0x3B }; + u8 data2[2] = { 0x3F, 0xFF }; + u8 data3[2] = { 0x0B, 0x72 }; + u8 data4[3] = { 0x93, 0xF3, 0x00 }; + u8 data5[4] = { 0x05, 0xB8, 0xD8, 0x00 }; + u8 data6[9] = { 0x18, 0x1E, 0x71, 0x5D, 0xA9, 0x5D, 0xA9, 0x46, 0x3F }; + + writeregst(state,0x11,0x33,data1,sizeof(data1)); + writeregst(state,0x20,0xD9,data2,sizeof(data2)); + writeregst(state,0x24,0x34,data3,sizeof(data3)); + writeregst(state,0x24,0xD2,data4,sizeof(data4)); + writeregst(state,0x24,0xDD,data5,sizeof(data5)); + writeregt(state,0x25,0xED,0x60); + writeregst(state,0x5E,0xDB,data6,sizeof(data6)); + } + BandSettingC2(state, iffreq); writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */ @@ -908,34 +1089,51 @@ static void BandSettingIT(struct cxd_state *state, u32 iffreq) default: case 8: { - u8 TR_data[] = { 0x0F, 0x22, 0x80, 0x00, 0x00 }; /* 20.5/41 */ - u8 CL_data[] = { 0x15, 0xA8 }; - - /*u8 TR_data[] = { 0x11, 0xB8, 0x00, 0x00, 0x00 }; */ /* 24 */ - writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + if (state->is24MHz) { + u8 TR_data[] = { 0x11, 0xb8, 0x00, 0x00, 0x00 }; /* 24 */ + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x0F, 0x22, 0x80, 0x00, 0x00 }; /* 20.5/41 */ + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } /* Add EQ Optimisation for tuner here */ writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x00, 0x07); /* System Bandwidth */ - /*u8 CL_data[] = { 0x13, 0xFC }; */ - writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + if (state->is24MHz) { + u8 CL_data[] = { 0x13, 0xfc }; + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } else { + u8 CL_data[] = { 0x15, 0xA8 }; + + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } writebitst(state, 0x12, 0x71, 0x03, 0x07); writeregt(state, 0x15, 0xbe, 0x03); } break; case 7: { - u8 TR_data[] = { 0x11, 0x4c, 0x00, 0x00, 0x00 }; - u8 CL_data[] = { 0x1B, 0x5D }; - - /*u8 TR_data[] = { 0x14, 0x40, 0x00, 0x00, 0x00 }; */ - writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + if (state->is24MHz) { + u8 TR_data[] = { 0x14, 0x40, 0x00, 0x00, 0x00 }; /* 24 */ + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x11, 0x4c, 0x00, 0x00, 0x00 }; + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x02, 0x07); - /*static u8 CL_data[] = { 0x1A, 0xFA };*/ - writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + if (state->is24MHz) { + u8 CL_data[] = { 0x1a, 0xfa }; + + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } else { + u8 CL_data[] = { 0x1B, 0x5D }; + + writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); + } writebitst(state, 0x12, 0x71, 0x03, 0x07); writeregt(state, 0x15, 0xbe, 0x02); @@ -943,22 +1141,30 @@ static void BandSettingIT(struct cxd_state *state, u32 iffreq) break; case 6: { - u8 TR_data[] = { 0x14, 0x2E, 0x00, 0x00, 0x00 }; - /*u8 TR_data[] = { 0x17, 0xA0, 0x00, 0x00, 0x00 }; */ - /*u8 CL_data[] = { 0x1F, 0x79 }; */ - - writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + if (state->is24MHz) { + u8 TR_data[] = { 0x17, 0xa0, 0x00, 0x00, 0x00 }; /* 24 */ + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } else { + u8 TR_data[] = { 0x14, 0x2E, 0x00, 0x00, 0x00 }; + writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); + } writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writebitst(state, 0x10, 0xD7, 0x04, 0x07); - if (state->is2k14) { - u8 CL_data[] = { 0x1a, 0xe2 }; - - writeregst(state, 0x10, 0xDd9, CL_data, sizeof(CL_data)); - } else { - u8 CL_data[] = { 0x1F, 0xec }; + if (state->is24MHz) { + u8 CL_data[] = { 0x1f, 0x79 }; writeregst(state, 0x10, 0xd9, CL_data, sizeof(CL_data)); + } else { + if (state->is2k14) { + u8 CL_data[] = { 0x1a, 0xe2 }; + + writeregst(state, 0x10, 0xd9, CL_data, sizeof(CL_data)); + } else { + u8 CL_data[] = { 0x1F, 0xec }; + + writeregst(state, 0x10, 0xd9, CL_data, sizeof(CL_data)); + } } writebitst(state, 0x12, 0x71, 0x07, 0x07); writeregt(state, 0x15, 0xbe, 0x02); @@ -969,12 +1175,6 @@ static void BandSettingIT(struct cxd_state *state, u32 iffreq) static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq) { - u8 data2[3] = { 0xB9, 0xBA, 0x63 }; /* 20.5/41 MHz */ - /*u8 data2[3] = { 0xB7,0x1B,0x00 }; */ /* 24 MHz */ - u8 TSIF_data[2] = { 0x61, 0x60 } ; /* 20.5/41 MHz */ - /*u8 TSIF_data[2] = { 0x60,0x00 } ; */ /* 24 MHz */ - - ConfigureTS(state, ActiveIT); /* writeregx(state, 0x00,0x17,0x01); */ /* 2838 has only one Mode */ @@ -989,7 +1189,7 @@ static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq) writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ { - u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz, 24 MHz */ + u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz/24 MHz */ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */ writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ @@ -998,6 +1198,9 @@ static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq) if (state->is2k14) { + writebitst(state, 0x10, 0xd2, 0x0c, 0x1f); + writeregt(state, 0x11, 0x6a, 0x50); + writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ writebitst(state, 0x18, 0x30, 0x01, 0x01); @@ -1018,16 +1221,19 @@ static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq) writebitst(state, 0x1e, 0x73, 0x68, 0xff); writebitst(state, 0x63, 0x81, 0x00, 0x01); } - //if( m_is24MHz ) - //{ - // static BYTE TSIF_data[2] = { 0x60,0x00 } ; // 24 MHz - // CHK_ERROR(WriteRegT(0x10,0xBF,TSIF_data,sizeof(TSIF_data))); - // static BYTE data[3] = { 0xB7,0x1B,0x00 }; // 24 MHz - // CHK_ERROR(WriteRegT(0x60,0xA8,data,sizeof(data))); - //} - //else - writeregst(state, 0x10, 0xBF, TSIF_data, sizeof(TSIF_data)); - writeregst(state, 0x60, 0xa8, data2, sizeof(data2)); + if (state->is24MHz) { + static u8 TSIF_data[2] = { 0x60,0x00 } ; // 24 MHz + static u8 data[3] = { 0xB7,0x1B,0x00 }; // 24 MHz + + writeregst(state, 0x10, 0xBF, TSIF_data, sizeof(TSIF_data)); + writeregst(state, 0x60, 0xA8, data, sizeof(data)); + } else { + u8 TSIF_data[2] = { 0x61, 0x60 } ; /* 20.5/41 MHz */ + u8 data[3] = { 0xB9, 0xBA, 0x63 }; /* 20.5/41 MHz */ + + writeregst(state, 0x10, 0xBF, TSIF_data, sizeof(TSIF_data)); + writeregst(state, 0x60, 0xa8, data, sizeof(data)); + } if (!state->is2k14) { writeregt(state, 0x10, 0xE2, 0xCE); /* OREG_PNC_DISABLE */ @@ -1042,11 +1248,11 @@ static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq) static void T2_SetParameters(struct cxd_state *state) { u8 Profile = 0x01; /* Profile Base */ - u8 notT2time = 12; /* early unlock detection time */ + u8 notT2time = state->is24MHz ? 24 : 12; /* early unlock detection time */ if (state->T2Profile == T2P_Lite) { Profile = 0x05; - notT2time = 40; + notT2time = state->is24MHz ? 46 : 40; } if (state->plp != 0xffffffff) { @@ -1182,7 +1388,7 @@ static int Start(struct cxd_state *state, u32 IntermediateFrequency) if (state->state < Sleep) return -EINVAL; - iffreq = MulDiv32(IntermediateFrequency, 16777216, 41000000); + iffreq = MulDiv32(IntermediateFrequency, 16777216, state->is24MHz ? 48000000 : 41000000); switch (state->omode) { case OM_DVBT: @@ -1368,9 +1574,16 @@ static void init(struct cxd_state *state) writeregx(state, 0x00, 0x10, 0x01); - writeregsx(state, 0x00, 0x13, data, 2); writeregx(state, 0x00, 0x15, 0x00); usleep_range(3000, 4000); + + writeregsx(state, 0x00, 0x13, data, 0); + if (state->is24MHz) + writeregx(state, 0x00, 0x12, 0x00); + + writeregx(state, 0x00, 0x14, state->is24MHz ? 0x03 : 0x00); + + writeregx(state, 0x00, 0x10, 0x00); usleep_range(2000, 3000); @@ -1382,6 +1595,12 @@ static void init(struct cxd_state *state) if (state->type == CXD2838) writeregt(state, 0x60, 0x5A, 0x00); + if (state->type == CXD2854) { + writeregt(state, 0x00, 0x63, 0x16); + writeregt(state, 0x00, 0x65, 0x27); + writeregt(state, 0x00, 0x69, 0x06); + } + writebitst(state, 0x10, 0xCB, 0x00, 0x40); writeregt(state, 0x10, 0xCD, state->IF_FS); @@ -1416,6 +1635,8 @@ static void init_state(struct cxd_state *state, struct cxd2843_cfg *cfg) cfg->ts_clock : 1; /* 1 = fastest (82 MBit/s), 5 = slowest */ /* IF Fullscale 0x50 = 1.4V, 0x39 = 1V, 0x28 = 0.7V */ state->IF_FS = 0x50; + state->is24MHz = (cfg->osc == 24000000) ? 1 : 0; + printk("is24Mhz = %u\n", state->is24MHz); } static int get_tune_settings(struct dvb_frontend *fe, @@ -1738,7 +1959,7 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) do { -+ BYTE tmp; ++ u8 tmp; + CHK_ERROR(FreezeRegsT()); @@ -1757,11 +1978,11 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) + pT2_PLPIDS->CommonPLPID = tmp; + } + - BYTE nPids = 0; + u8 nPids = 0; CHK_ERROR(ReadRegT(0x22,0x7F,&nPids)); - pValues[0] = nPids; -- if( nPids >= nValues ) nPids = BYTE(nValues-1); +- if( nPids >= nValues ) nPids = nValues - 1; + pT2_PLPIDS->NumPLPS = nPids; + CHK_ERROR(ReadRegT(0x22,0x80,&pT2_PLPIDS->PLPList[0], nPids > 128 ? 128 : nPids)); @@ -1815,11 +2036,14 @@ static void GetSignalToNoiseIT(struct cxd_state *state, u32 *SignalToNoise) u8 Data[2]; u32 reg; + *SignalToNoise = 0; freeze_regst(state); readregst_unlocked(state, 0x60, 0x28, Data, sizeof(Data)); unfreeze_regst(state); reg = (Data[0] << 8) | Data[1]; + if (reg == 0) + return; if (reg > 51441) reg = 51441; @@ -1837,11 +2061,14 @@ static void GetSignalToNoiseC2(struct cxd_state *state, u32 *SignalToNoise) u8 Data[2]; u32 reg; + *SignalToNoise = 0; freeze_regst(state); readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data)); unfreeze_regst(state); reg = (Data[0] << 8) | Data[1]; + if (reg == 0) + return; if (reg > 51441) reg = 51441; @@ -1854,11 +2081,14 @@ static void GetSignalToNoiseT2(struct cxd_state *state, u32 *SignalToNoise) u8 Data[2]; u32 reg; + *SignalToNoise = 0; freeze_regst(state); readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data)); unfreeze_regst(state); reg = (Data[0] << 8) | Data[1]; + if (reg == 0) + return; if (reg > 10876) reg = 10876; @@ -1870,11 +2100,14 @@ static void GetSignalToNoiseT(struct cxd_state *state, u32 *SignalToNoise) u8 Data[2]; u32 reg; + *SignalToNoise = 0; freeze_regst(state); readregst_unlocked(state, 0x10, 0x28, Data, sizeof(Data)); unfreeze_regst(state); reg = (Data[0] << 8) | Data[1]; + if (reg == 0) + return; if (reg > 4996) reg = 4996; @@ -1888,7 +2121,6 @@ static void GetSignalToNoiseC(struct cxd_state *state, u32 *SignalToNoise) u32 reg; *SignalToNoise = 0; - freeze_regst(state); readregst_unlocked(state, 0x40, 0x19, &Constellation, 1); readregst_unlocked(state, 0x40, 0x4C, Data, sizeof(Data)); @@ -2404,13 +2636,12 @@ static int probe(struct cxd_state *state) int status; status = readregst(state, 0x00, 0xFD, &ChipID, 1); - if (status) status = readregsx(state, 0x00, 0xFD, &ChipID, 1); if (status) return status; - /*printk("ChipID = %02X\n", ChipID);*/ + printk("ChipID = %02X\n", ChipID); switch (ChipID) { case 0xa4: state->type = CXD2843; @@ -2445,6 +2676,7 @@ struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c, { struct cxd_state *state = NULL; + pr_info("attach\n"); state = kzalloc(sizeof(struct cxd_state), GFP_KERNEL); if (!state) return NULL; diff --git a/frontends/cxd2843.h b/frontends/cxd2843.h index f3e355b..cfc6f04 100644 --- a/frontends/cxd2843.h +++ b/frontends/cxd2843.h @@ -8,6 +8,7 @@ struct cxd2843_cfg { u8 adr; u32 ts_clock; u8 parallel; + u32 osc; }; #if defined(CONFIG_DVB_CXD2843) || \ diff --git a/frontends/lnbh25.c b/frontends/lnbh25.c index ea730e6..c666ee1 100644 --- a/frontends/lnbh25.c +++ b/frontends/lnbh25.c @@ -146,7 +146,7 @@ struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, fe->ops.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage; fe->ops.release_sec = lnbh25_release; - pr_info("LNB25 on %02x\n", lnbh->adr); + pr_info("LNBH25 on %02x\n", lnbh->adr); return fe; } diff --git a/frontends/mxl5xx.c b/frontends/mxl5xx.c index 452e82a..f284c52 100644 --- a/frontends/mxl5xx.c +++ b/frontends/mxl5xx.c @@ -698,6 +698,10 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength) int stat; u32 regData = 0; +#if 0 + if (!firmware_is_alive(state)) + pr_info("FW dead!\n"); +#endif mutex_lock(&state->base->status_lock); HYDRA_DEMOD_STATUS_LOCK(state, state->demod); stat = read_register(state, (HYDRA_DMD_STATUS_INPUT_POWER_ADDR + @@ -837,8 +841,8 @@ static struct dvb_frontend_ops mxl_ops = { .xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */ .info = { .name = "MXL5XX", - .frequency_min = 950000, - .frequency_max = 2150000, + .frequency_min = 300000, + .frequency_max = 2350000, .frequency_stepsize = 0, .frequency_tolerance = 0, .symbol_rate_min = 1000000, @@ -1639,7 +1643,7 @@ static int load_fw(struct mxl *state, struct mxl5xx_cfg *cfg) static int validate_sku(struct mxl *state) { - u32 padMuxBond, prcmChipId, prcmSoCId; + u32 padMuxBond = 0, prcmChipId = 0, prcmSoCId = 0; int status; u32 type = state->base->type; diff --git a/frontends/stv0910.c b/frontends/stv0910.c index 2b4223d..5322eba 100644 --- a/frontends/stv0910.c +++ b/frontends/stv0910.c @@ -105,6 +105,7 @@ struct stv { u8 tscfgh; u8 tsgeneral; u8 tsspeed; + u8 single; unsigned long tune_time; s32 SearchRange; @@ -1137,7 +1138,10 @@ static int probe(struct stv *state) 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 */ + if (state->single) + write_reg(state, RSTV0910_GENCFG, 0x14); /* GENCFG */ + else + write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */ write_reg(state, RSTV0910_P1_TNRCFG2, 0x02); /* IQSWAP = 0 */ write_reg(state, RSTV0910_P2_TNRCFG2, 0x82); /* IQSWAP = 1 */ @@ -1830,7 +1834,8 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, state->DEMOD = 0x10; /* Inversion : Auto with reset to 0 */ state->ReceiveMode = Mode_None; state->CurScramblingCode = NO_SCRAMBLING_CODE; - + state->single = cfg->single ? 1 : 0; + base = match_base(i2c, cfg->adr); if (base) { base->count++; diff --git a/frontends/stv0910.h b/frontends/stv0910.h index a6fad29..338ae01 100644 --- a/frontends/stv0910.h +++ b/frontends/stv0910.h @@ -9,6 +9,7 @@ struct stv0910_cfg { u8 adr; u8 parallel; u8 rptlvl; + u8 single; }; #if defined(CONFIG_DVB_STV0910) || \ diff --git a/include/linux/dvb/mod.h b/include/linux/dvb/mod.h index a1b04ea..b950197 100644 --- a/include/linux/dvb/mod.h +++ b/include/linux/dvb/mod.h @@ -19,15 +19,16 @@ struct dvb_mod_channel_params { #define DVB_MOD_SET _IOW('o', 208, struct dvb_mod_params) #define DVB_MOD_CHANNEL_SET _IOW('o', 209, struct dvb_mod_channel_params) -#define MOD_UNDEFINED 0 -#define MOD_START 1 -#define MOD_STOP 2 -#define MOD_FREQUENCY 3 -#define MOD_MODULATION 4 -#define MOD_SYMBOL_RATE 5 /* Hz */ -#define MOD_ATTENUATOR 32 -#define MOD_INPUT_BITRATE 33 /* Hz */ -#define MOD_PCR_MODE 34 /* 1=pcr correction enabled */ - +#define MODULATOR_UNDEFINED 0 +#define MODULATOR_START 1 +#define MODULATOR_STOP 2 +#define MODULATOR_FREQUENCY 3 +#define MODULATOR_MODULATION 4 +#define MODULATOR_SYMBOL_RATE 5 /* Hz */ +#define MODULATOR_BASE_FREQUENCY 6 +#define MODULATOR_ATTENUATOR 32 +#define MODULATOR_INPUT_BITRATE 33 /* Hz */ +#define MODULATOR_PCR_MODE 34 /* 1=pcr correction enabled */ +#define MODULATOR_OUTPUT_ARI 64 #endif /*_UAPI_DVBMOD_H_*/