1
0
mirror of https://github.com/DigitalDevices/dddvb.git synced 2023-10-10 13:37:43 +02:00

Merge remote-tracking branch 'digitaldevices/master'

This commit is contained in:
André-Sebastian Liebe 2017-07-09 10:06:53 +02:00
commit 732ac44cf8
31 changed files with 2245 additions and 1955 deletions

View File

@ -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 0.9.24 2016.08.03
- suport new V2 modulator cards - suport new V2 modulator cards

View File

@ -1,10 +1,13 @@
# DDBridge Driver # 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 TBD
###Building ### Building
TBD TBD

View File

@ -1,22 +1,22 @@
all: cit citin flashprog modt ddtest setmod ddflash all: cit citin flashprog modt ddtest setmod ddflash setmod2
cit: cit.c cit: cit.c
gcc -o cit cit.c -lpthread $(CC) -o cit cit.c -lpthread
modt: modt.c modt: modt.c
gcc -o modt modt.c -lpthread $(CC) -o modt modt.c -lpthread
setmod: setmod.c setmod: setmod.c
gcc -o setmod setmod.c -I../include/ $(CC) -o setmod setmod.c -I../include/
setmod2: setmod2.c setmod2: setmod2.c
gcc -o setmod2 setmod2.c -I../include/ $(CC) -o setmod2 setmod2.c -I../include/
flashprog: flashprog.c flashprog: flashprog.c
gcc -o flashprog flashprog.c $(CC) -o flashprog flashprog.c
ddtest: ddtest.c ddtest: ddtest.c
gcc -o ddtest ddtest.c $(CC) -o ddtest ddtest.c
ddflash: ddflash.c ddflash: ddflash.c
gcc -o ddflash ddflash.c $(CC) -o ddflash ddflash.c

View File

@ -91,6 +91,7 @@ void *get_ts(void *a)
if (!buf) if (!buf)
return NULL; return NULL;
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device); sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
printf("using %s for reading\n", fname);
fdi = open(fname, O_RDONLY); fdi = open(fname, O_RDONLY);
while (1) { while (1) {
@ -122,6 +123,7 @@ int send(void)
if (!buf) if (!buf)
return -1; return -1;
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device); sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
printf("using %s for writing\n", fname);
fdo=open(fname, O_WRONLY); fdo=open(fname, O_WRONLY);
while (1) { while (1) {

1
apps/flash.c Symbolic link
View File

@ -0,0 +1 @@
./octonet/flash.c

View File

@ -33,379 +33,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/types.h> #include <linux/types.h>
#define DDB_MAGIC 'd' #include "flash.h"
static uint32_t linknr = 0;
struct ddb_id {
__u16 vendor;
__u16 device;
__u16 subvendor;
__u16 subdevice;
__u32 hw;
__u32 regmap;
};
struct ddb_flashio {
__u8 *write_buf;
__u32 write_len;
__u8 *read_buf;
__u32 read_len;
__u32 link;
};
#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio)
#define IOCTL_DDB_ID _IOR(DDB_MAGIC, 0x03, struct ddb_id)
int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen)
{
struct ddb_flashio fio = {
.write_buf=wbuf,
.write_len=wlen,
.read_buf=rbuf,
.read_len=rlen,
.link=linknr,
};
return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio);
}
enum {
UNKNOWN_FLASH = 0,
ATMEL_AT45DB642D = 1,
SSTI_SST25VF016B = 2,
SSTI_SST25VF032B = 3,
SSTI_SST25VF064C = 4,
SPANSION_S25FL116K = 5,
};
int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
{
uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,
(addr >> 8) & 0xff, addr & 0xff};
return flashio(ddb, cmd, 4, buf, len);
}
int flashdump(int ddb, uint32_t addr, uint32_t len)
{
int i, j;
uint8_t buf[32];
int bl = sizeof(buf);
for (j=0; j<len; j+=bl, addr+=bl) {
flashread(ddb, buf, addr, bl);
for (i=0; i<bl; i++) {
printf("%02x ", buf[i]);
}
printf("\n");
}
}
int FlashDetect(int dev)
{
uint8_t Cmd = 0x9F;
uint8_t Id[3];
int r = flashio(dev, &Cmd,1,Id,3);
if (r < 0)
return r;
if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x41 )
r = SSTI_SST25VF016B;
else if( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4A )
r = SSTI_SST25VF032B;
else if( Id[0] == 0x1F && Id[1] == 0x28 )
r = ATMEL_AT45DB642D;
else if( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4B )
r = SSTI_SST25VF064C;
else if( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x15 )
r = SPANSION_S25FL116K;
else
r = UNKNOWN_FLASH;
switch(r) {
case UNKNOWN_FLASH:
printf("Unknown Flash Flash ID = %02x %02x %02x\n",Id[0],Id[1],Id[2]);
break;
case ATMEL_AT45DB642D:
printf("Flash: Atmel AT45DB642D 64 MBit\n");
break;
case SSTI_SST25VF016B:
printf("Flash: SSTI SST25VF016B 16 MBit\n");
break;
case SSTI_SST25VF032B:
printf("Flash: SSTI SST25VF032B 32 MBit\n"); break;
case SSTI_SST25VF064C:
printf("Flash: SSTI SST25VF064C 64 MBit\n"); break;
case SPANSION_S25FL116K:
printf("Flash: SPANSION S25FL116K 16 MBit\n"); break;
}
return r;
}
int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize)
{
int err = 0;
int BlockErase = BufferSize >= 8192;
int i;
if (BlockErase) {
for(i = 0; i < BufferSize; i += 8192 ) {
uint8_t Cmd[4];
if( (i & 0xFFFF) == 0 )
printf(" Erase %08x\n",FlashOffset + i);
Cmd[0] = 0x50; // Block Erase
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while( 1 )
{
Cmd[0] = 0xD7; // Read Status register
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x80) == 0x80 ) break;
}
}
}
for(i = 0; i < BufferSize; i += 1024 )
{
uint8_t Cmd[4 + 1024];
if( (i & 0xFFFF) == 0 )
{
printf(" Program %08x\n",FlashOffset + i);
}
Cmd[0] = 0x84; // Buffer 1
Cmd[1] = 0x00;
Cmd[2] = 0x00;
Cmd[3] = 0x00;
memcpy(&Cmd[4],&Buffer[i],1024);
err = flashio(dev,Cmd,4 + 1024,NULL,0);
if( err < 0 ) break;
Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while( 1 )
{
Cmd[0] = 0xD7; // Read Status register
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x80) == 0x80 ) break;
}
if( err < 0 ) break;
}
return err;
}
int FlashWritePageMode(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize, uint8_t LockBits)
{
int err = 0, i, j;
uint8_t Cmd[260];
if( (BufferSize % 4096) != 0 )
return -1; // Must be multiple of sector size
do {
Cmd[0] = 0x50; // EWSR
err = flashio(dev, Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = flashio(dev, Cmd,2,NULL,0);
if( err < 0 ) break;
for(i = 0; i < BufferSize; i += 4096 ) {
if( (i & 0xFFFF) == 0 ) {
printf(" Erase %08x\n",FlashOffset + i);
}
Cmd[0] = 0x06; // WREN
err = flashio(dev, Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x20; // Sector erase ( 4Kb)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev, Cmd,4,NULL,0);
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0x05; // RDRS
err = flashio(dev, Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
for (j = BufferSize - 256; j >= 0; j -= 256 )
{
if( (j & 0xFFFF) == 0 )
{
printf(" Programm %08x\n",FlashOffset + j);
}
Cmd[0] = 0x06; // WREN
err = flashio(dev, Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x02; // PP
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
Cmd[3] = 0x00;
memcpy(&Cmd[4],&Buffer[j],256);
err = flashio(dev, Cmd,260,NULL,0);
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0x05; // RDRS
err = flashio(dev, Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x50; // EWSR
err = flashio(dev, Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = LockBits; // BPx = 0, Lock all blocks
err = flashio(dev, Cmd,2,NULL,0);
} while(0);
return err;
}
int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize)
{
int err = 0;
uint8_t Cmd[6];
int i, j;
// Must be multiple of sector size
if( (BufferSize % 4096) != 0 )
return -1;
do {
Cmd[0] = 0x50; // EWSR
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 )
break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = flashio(dev,Cmd,2,NULL,0);
if( err < 0 )
break;
for(i = 0; i < BufferSize; i += 4096 ) {
if( (i & 0xFFFF) == 0 )
printf(" Erase %08x\n",FlashOffset + i);
Cmd[0] = 0x06; // WREN
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 )
break;
Cmd[0] = 0x20; // Sector erase ( 4Kb)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 )
break;
while(1) {
Cmd[0] = 0x05; // RDRS
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 )
break;
for(j = BufferSize - 4096; j >= 0; j -= 4096 ) {
if( (j & 0xFFFF) == 0 )
printf(" Program %08x\n",FlashOffset + j);
for(i = 0; i < 4096; i += 2 ) {
if( i == 0 ) {
Cmd[0] = 0x06; // WREN
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 )
break;
Cmd[0] = 0xAD; // AAI
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
Cmd[3] = 0x00;
Cmd[4] = Buffer[j+i];
Cmd[5] = Buffer[j+i+1];
err = flashio(dev,Cmd,6,NULL,0);
} else {
Cmd[0] = 0xAD; // AAI
Cmd[1] = Buffer[j+i];
Cmd[2] = Buffer[j+i+1];
err = flashio(dev,Cmd,3,NULL,0);
}
if( err < 0 )
break;
while(1) {
Cmd[0] = 0x05; // RDRS
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x04; // WDIS
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x50; // EWSR
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x1C; // BPx = 0, Lock all blocks
err = flashio(dev,Cmd,2,NULL,0);
} while(0);
return err;
}
void get_id(int ddb, struct ddb_id *ddbid) { void get_id(int ddb, struct ddb_id *ddbid) {
uint8_t id[4]; uint8_t id[4];
@ -450,8 +78,8 @@ int main(int argc, char **argv)
uint32_t FlashOffset = 0x10000; uint32_t FlashOffset = 0x10000;
int ddb; int ddb;
int i, err; int i, err;
int SectorSize=0; uint32_t SectorSize=0;
int FlashSize=0; uint32_t FlashSize=0;
int Flash; int Flash;
uint32_t svid=0, jump=0, dump=0; uint32_t svid=0, jump=0, dump=0;
@ -459,6 +87,7 @@ int main(int argc, char **argv)
int ddbnum = 0; int ddbnum = 0;
int force = 0; int force = 0;
char *fname = NULL;
while (1) { while (1) {
int option_index = 0; int option_index = 0;
@ -470,12 +99,15 @@ int main(int argc, char **argv)
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
c = getopt_long(argc, argv, c = getopt_long(argc, argv,
"d:n:s:o:l:dfhj", "d:n:s:o:l:dfhjb:",
long_options, &option_index); long_options, &option_index);
if (c==-1) if (c==-1)
break; break;
switch (c) { switch (c) {
case 'b':
fname = optarg;
break;
case 'd': case 'd':
dump = strtoul(optarg, NULL, 16); dump = strtoul(optarg, NULL, 16);
break; break;
@ -513,32 +145,7 @@ int main(int argc, char **argv)
printf("Could not open device\n"); printf("Could not open device\n");
return -1; return -1;
} }
Flash=FlashDetect(ddb); Flash = flashdetect(ddb, &SectorSize, &FlashSize);
switch(Flash) {
case ATMEL_AT45DB642D:
SectorSize = 1024;
FlashSize = 0x800000;
break;
case SSTI_SST25VF016B:
SectorSize = 4096;
FlashSize = 0x200000;
break;
case SSTI_SST25VF032B:
SectorSize = 4096;
FlashSize = 0x400000;
break;
case SSTI_SST25VF064C:
SectorSize = 4096;
FlashSize = 0x800000;
break;
case SPANSION_S25FL116K:
SectorSize = 4096;
FlashSize = 0x200000;
break;
default:
return 0;
}
get_id(ddb, &ddbid); get_id(ddb, &ddbid);
#if 1 #if 1
@ -553,27 +160,6 @@ int main(int argc, char **argv)
return 0; 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) if (!SectorSize)
return 0; return 0;
@ -616,52 +202,68 @@ int main(int argc, char **argv)
} else { } else {
int fh, i; int fh, i;
int fsize; int fsize;
char *fname;
switch (type) { if (!fname)
case 0: switch (ddbid.device) {
fname="DVBBridgeV1B_DVBBridgeV1B.bit"; case 0x0002:
printf("Octopus\n");
break;
case 1:
fname="CIBridgeV1B_CIBridgeV1B.bit";
printf("Octopus CI\n");
break;
case 2:
fname="DVBModulatorV1B_DVBModulatorV1B.bit";
printf("Modulator\n");
break;
case 3:
fname="DVBBridgeV1A_DVBBridgeV1A.bit"; fname="DVBBridgeV1A_DVBBridgeV1A.bit";
printf("Octopus 35\n"); printf("Octopus 35\n");
break; 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"; fname="DVBBridgeV2A_DD01_0007_MXL.fpga";
printf("Octopus 4/8\n"); printf("Octopus 4/8\n");
break; break;
case 8: case 0x0008:
fname="DVBBridgeV2A_DD01_0008_CXD.fpga"; fname="DVBBridgeV2A_DD01_0008_CXD.fpga";
printf("Octopus 4/8\n"); printf("Octopus 4/8\n");
break; break;
case 6: case 0x0011:
fname="DVBBridgeV2B_DD01_0013_PRO.fpga"; fname="CIBridgeV1B_CIBridgeV1B.fpga";
printf("Octopus PRO\n"); printf("Octopus CI\n");
break; break;
case 7: case 0x0012:
fname="DVBBridgeV2B_DD01_0012_STD.fpga"; fname="DVBBridgeV2B_DD01_0012_STD.fpga";
printf("Octopus CI\n"); printf("Octopus CI\n");
break; 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"; fname="DVBModulatorV2A_DD01_0210.fpga";
printf("Modulator V2\n"); printf("Modulator V2\n");
break; break;
case 0x0220:
fname="SDRModulatorV1A_DD01_0220.fpga";
printf("SDRModulator\n");
break;
default: default:
printf("UNKNOWN\n"); printf("UNKNOWN\n");
break; break;
} }
fh = open(fname, O_RDONLY); fh = open(fname, O_RDONLY);
if (fh < 0 ) { if (fh < 0 ) {
printf("File not found \n"); printf("File %s not found \n", fname);
return 0; return 0;
} }
printf("Using bitstream %s\n", fname); printf("Using bitstream %s\n", fname);
@ -720,6 +322,7 @@ int main(int argc, char **argv)
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x3C); err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x3C);
break; break;
case SPANSION_S25FL116K: case SPANSION_S25FL116K:
case SPANSION_S25FL164K:
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C); err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C);
break; break;
} }

View File

@ -58,7 +58,6 @@ static int reboot(uint32_t off)
struct ddflash { struct ddflash {
int fd; int fd;
struct ddb_id id; struct ddb_id id;
uint32_t type;
uint32_t version; uint32_t version;
uint32_t flash_type; uint32_t flash_type;
@ -68,74 +67,9 @@ struct ddflash {
uint32_t bufsize; uint32_t bufsize;
uint32_t block_erase; 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, int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset,
uint8_t LockBits, uint32_t fw_off) uint8_t LockBits, uint32_t fw_off)
{ {
@ -492,7 +426,7 @@ static int flash_detect(struct ddflash *ddf)
} }
if (ddf->sector_size) { if (ddf->sector_size) {
ddf->buffer = malloc(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) if (!ddf->buffer)
return -1; 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) { static int get_id(struct ddflash *ddf) {
uint8_t id[4]; uint8_t id[4];
@ -677,19 +445,6 @@ static int get_id(struct ddflash *ddf) {
ddf->id.subvendor, ddf->id.subdevice, ddf->id.subvendor, ddf->id.subdevice,
ddf->id.hw, ddf->id.regmap); ddf->id.hw, ddf->id.regmap);
#endif #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; return 0;
} }
@ -755,6 +510,11 @@ static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off)
goto out; goto out;
} }
} else if (!strcasecmp(key, "Version")) { } else if (!strcasecmp(key, "Version")) {
if (strchr(val,'.')) {
int major = 0, minor = 0;
sscanf(val,"%d.%d",&major,&minor);
version = (major << 16) + minor;
} else
sscanf(val, "%x", &version); sscanf(val, "%x", &version);
} else if (!strcasecmp(key, "Length")) { } else if (!strcasecmp(key, "Length")) {
sscanf(val, "%u", &length); sscanf(val, "%u", &length);
@ -810,8 +570,13 @@ static int update_image(struct ddflash *ddf, char *fn,
if (res < 0) if (res < 0)
goto out; goto out;
res = flashwrite(ddf, fs, adr, len, fw_off); res = flashwrite(ddf, fs, adr, len, fw_off);
if (res == 0) if (res == 0) {
res = flashcmp(ddf, fs, adr, len, fw_off);
if (res == -2) {
res = 1; res = 1;
}
}
out: out:
close(fs); close(fs);
return res; 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) if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1)
stat |= 1; stat |= 1;
} else { } else {
if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1) if (ddf->id.device == 0x0307) {
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 == -1)
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1) if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
stat |= 1; stat |= 1;
if (res == -1) if (res == -1)
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1) if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
stat |= 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; break;
case 0x320: case 0x320:
//fname="/boot/DVBNetV1A_DD01_0300.bit"; //fname="/boot/DVBNetV1A_DD01_0300.bit";

View File

@ -1,3 +1,4 @@
#include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
@ -12,8 +13,6 @@
#include "flash.h" #include "flash.h"
static uint32_t linknr = 0;
typedef int (*COMMAND_FUNCTION)(int dev, int argc, char* argv[], uint32_t Flags); typedef int (*COMMAND_FUNCTION)(int dev, int argc, char* argv[], uint32_t Flags);
enum { enum {
@ -21,17 +20,6 @@ enum {
SILENT_FLAG = 0x00000002, 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 struct SCommand
{ {
char* Name; char* Name;
@ -42,94 +30,55 @@ 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, &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, &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) int ReadFlash(int ddb, int argc, char *argv[], uint32_t Flags)
{ {
uint32_t Start; uint32_t Start;
uint32_t Len; uint32_t Len;
uint8_t *Buffer; uint8_t *Buffer;
int fd;
if (argc < 2 ) if (argc < 2 )
return -1; return -1;
Start = strtoul(argv[0],NULL,16); Start = strtoul(argv[0],NULL,16);
Len = strtoul(argv[1],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) {
printf("flashread error\n");
free(Buffer);
return 0;
}
if (argc == 3) {
write(fd, Buffer, Len);
close(fd);
} else
Dump(Buffer,Start,Len);
free(Buffer);
return 0;
}
int ReadSave(int ddb, int argc, char *argv[], uint32_t Flags)
{
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); Buffer = malloc(Len);
if (flashread(ddb, Buffer, Start, Len) < 0) { if (flashread(ddb, Buffer, Start, Len) < 0) {
@ -138,68 +87,13 @@ int ReadFlash(int ddb, int argc, char *argv[], uint32_t Flags)
return 0; return 0;
} }
Dump(Buffer,Start,Len);
free(Buffer); free(Buffer);
return 0; return 0;
} }
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;
}
int FlashChipEraseAtmel(int dev) int FlashChipEraseAtmel(int dev)
{ {
int err = 0; int err = 0;
@ -214,12 +108,12 @@ int FlashChipEraseAtmel(int dev)
Cmd[1] = ( (( i ) >> 16) & 0xFF ); Cmd[1] = ( (( i ) >> 16) & 0xFF );
Cmd[2] = ( (( i ) >> 8) & 0xFF ); Cmd[2] = ( (( i ) >> 8) & 0xFF );
Cmd[3] = 0x00; Cmd[3] = 0x00;
err = FlashIO(dev,Cmd,4,NULL,0); err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 ) if( err < 0 )
break; break;
while (1) { while (1) {
Cmd[0] = 0xD7; // Read Status register 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( err < 0 ) break;
if( (Cmd[0] & 0x80) == 0x80 ) break; if( (Cmd[0] & 0x80) == 0x80 ) break;
} }
@ -237,25 +131,25 @@ int FlashChipEraseSSTI(int dev)
do { do {
Cmd[0] = 0x50; // EWSR Cmd[0] = 0x50; // EWSR
err = FlashIO(dev,Cmd,1,NULL,0); err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break; if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks 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; if( err < 0 ) break;
Cmd[0] = 0x06; // WREN Cmd[0] = 0x06; // WREN
err = FlashIO(dev,Cmd,1,NULL,0); err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break; if( err < 0 ) break;
Cmd[0] = 0x60; // CHIP Erase Cmd[0] = 0x60; // CHIP Erase
err = FlashIO(dev,Cmd,1,NULL,0); err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break; if( err < 0 ) break;
while(1) { while(1) {
Cmd[0] = 0x05; // RDRS 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( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break; if( (Cmd[0] & 0x01) == 0 ) break;
} }
@ -263,12 +157,12 @@ int FlashChipEraseSSTI(int dev)
break; break;
Cmd[0] = 0x50; // EWSR Cmd[0] = 0x50; // EWSR
err = FlashIO(dev,Cmd,1,NULL,0); err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break; if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x1C; // BPx = 0, Lock all blocks Cmd[1] = 0x1C; // BPx = 0, Lock all blocks
err = FlashIO(dev,Cmd,2,NULL,0); err = flashio(dev,Cmd,2,NULL,0);
} }
while(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) 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; uint8_t *Buffer;
uint32_t tmp = 0, i; 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; Buffer[i] = (uint8_t) tmp;
} }
if( FlashIO(dev,Buffer,WriteLen,Buffer,ReadLen) < 0 ) if( flashio(dev,Buffer,WriteLen,Buffer,ReadLen) < 0 )
{ {
return 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 }; uint8_t cmd[5] = { 0x5a, 0, 0, adr, 00 };
int r; int r;
r = FlashIO(dev, cmd, 5, val, 1); r = flashio(dev, cmd, 5, val, 1);
if (r < 0) if (r < 0)
return r; return r;
return 0; return 0;
@ -1667,7 +1281,7 @@ static int read_sst_id(int dev, uint8_t *id)
uint8_t buf[9]; uint8_t buf[9];
int r; int r;
r = FlashIO(dev, cmd, 2, buf, 9); r = flashio(dev, cmd, 2, buf, 9);
if (r < 0) if (r < 0)
return r; return r;
memcpy(id, buf + 1, 8); memcpy(id, buf + 1, 8);
@ -1696,10 +1310,10 @@ int read_id(int dev, int argc, char* argv[], uint32_t Flags)
break; break;
default: default:
printf("Unsupported Flash\n"); printf("Unsupported Flash\n");
break; return -1;
} }
printf("ID: "); printf("ID: ");
for (i = 0; i < 8; i++) for (i = 0; i < len; i++)
printf("%02x ", Id[i]); printf("%02x ", Id[i]);
printf("\n"); printf("\n");
@ -1712,13 +1326,13 @@ struct SCommand CommandTable[] =
{ "memwrite", WriteDeviceMemory, 1, "Write Device Memory : memwrite <start> <values(8)> .." }, { "memwrite", WriteDeviceMemory, 1, "Write Device Memory : memwrite <start> <values(8)> .." },
{ "register", GetSetRegister, 1, "Get/Set Register : reg <regname>|<[0x]regnum> [[0x]value(32)]" }, { "register", GetSetRegister, 1, "Get/Set Register : reg <regname>|<[0x]regnum> [[0x]value(32)]" },
{ "flashread", ReadFlash, 1, "Read Flash : flashread <start> <count>" }, { "flashread", ReadFlash, 1, "Read Flash : flashread <start> <count> [<Filename>]" },
{ "flashio", FlashIOC, 1, "Flash IO : flashio <write data>.. <read count>" }, { "flashio", flashioc, 1, "Flash IO : flashio <write data>.. <read count>" },
{ "flashprog", FlashProg, 1, "Flash Programming : flashprog <FileName> [<address>]" }, { "flashprog", FlashProg, 1, "Flash Programming : flashprog <FileName> [<address>]" },
{ "flashprog", FlashProg, 1, "Flash Programming : flashprog -SubVendorID <id>" }, { "flashprog", FlashProg, 1, "Flash Programming : flashprog -SubVendorID <id>" },
{ "flashprog", FlashProg, 1, "Flash Programming : flashprog -Jump <address>" }, { "flashprog", FlashProg, 1, "Flash Programming : flashprog -Jump <address>" },
{ "flashverify", FlashVerify, 1, "Flash Verify : flashverify <FileName> [<address>]" }, { "flashverify", FlashVerify, 1, "Flash Verify : flashverify <FileName> [<address>]" },
{ "flasherase", FlashErase, 1, "FlashErase : flasherase" }, //{ "flasherase", FlashErase, 1, "FlashErase : flasherase" },
//{ "flashtest", FlashTest, 1, "FlashTest : flashtest" }, //{ "flashtest", FlashTest, 1, "FlashTest : flashtest" },

614
apps/octonet/flash.c Normal file
View File

@ -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<len; j+=bl, addr+=bl) {
flashread(ddb, buf, addr, bl);
for (i=0; i<bl; i++) {
printf("%02x ", buf[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, &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, &reg);
}
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");
}
}
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;
}

View File

@ -61,3 +61,5 @@ struct ddb_i2c_msg {
#define IOCTL_DDB_WRITE_MDIO _IOR(DDB_MAGIC, 0x09, struct ddb_mdio) #define IOCTL_DDB_WRITE_MDIO _IOR(DDB_MAGIC, 0x09, struct ddb_mdio)
#define IOCTL_DDB_READ_I2C _IOWR(DDB_MAGIC, 0x0a, struct ddb_i2c_msg) #define IOCTL_DDB_READ_I2C _IOWR(DDB_MAGIC, 0x0a, struct ddb_i2c_msg)
#define IOCTL_DDB_WRITE_I2C _IOR(DDB_MAGIC, 0x0b, struct ddb_i2c_msg) #define IOCTL_DDB_WRITE_I2C _IOR(DDB_MAGIC, 0x0b, struct ddb_i2c_msg)
#include "flash.c"

View File

@ -39,9 +39,9 @@ int main()
fd = open("/dev/dvb/adapter0/mod0", O_RDONLY); fd = open("/dev/dvb/adapter0/mod0", O_RDONLY);
set_property(fd, MOD_MODULATION, QAM_256); set_property(fd, MODULATOR_MODULATION, QAM_256);
set_property(fd, MOD_SYMBOL_RATE, 6900000); set_property(fd, MODULATOR_SYMBOL_RATE, 6900000);
set_property(fd, MOD_FREQUENCY, 114000000); set_property(fd, MODULATOR_FREQUENCY, 114000000);
close(fd); close(fd);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* /*
* ddbridge-i2c.c: Digital Devices bridge i2c driver * ddbridge-i2c.c: Digital Devices bridge i2c driver
* *
* Copyright (C) 2010-2015 Digital Devices GmbH * Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de> * Ralph Metzler <rjkm@metzlerbros.de>
* Marcus Metzler <mocm@metzlerbros.de> * Marcus Metzler <mocm@metzlerbros.de>
* *
@ -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); stat = wait_for_completion_timeout(&i2c->completion, HZ);
val = ddbreadl(dev, i2c->regs + I2C_COMMAND); val = ddbreadl(dev, i2c->regs + I2C_COMMAND);
if (stat == 0) { 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); dev->nr, i2c->nr, i2c->link);
#if 1 #if 1
{ {
@ -156,38 +156,43 @@ static int ddb_i2c_master_xfer(struct i2c_adapter *adapter,
struct ddb *dev = i2c->dev; struct ddb *dev = i2c->dev;
u8 addr = 0; u8 addr = 0;
if (num != 1 && num != 2)
return -EIO;
addr = msg[0].addr; addr = msg[0].addr;
if (msg[0].len > i2c->bsize) if (msg[0].len > i2c->bsize)
return -EIO; return -EIO;
if (num == 2 && msg[1].flags & I2C_M_RD && switch (num) {
!(msg[0].flags & I2C_M_RD)) { case 1:
if (msg[1].len > i2c->bsize) if (msg[0].flags & I2C_M_RD) {
return -EIO; ddbwritel(dev, msg[0].len << 16,
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
ddbwritel(dev, msg[0].len | (msg[1].len << 16),
i2c->regs + I2C_TASKLENGTH); i2c->regs + I2C_TASKLENGTH);
if (!ddb_i2c_cmd(i2c, addr, 1)) { if (ddb_i2c_cmd(i2c, addr, 3))
ddbcpyfrom(dev, msg[1].buf, break;
i2c->rbuf,
msg[1].len);
return num;
}
}
if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH);
if (!ddb_i2c_cmd(i2c, addr, 2))
return num;
}
if (num == 1 && (msg[0].flags & I2C_M_RD)) {
ddbwritel(dev, msg[0].len << 16, i2c->regs + I2C_TASKLENGTH);
if (!ddb_i2c_cmd(i2c, addr, 3)) {
ddbcpyfrom(dev, msg[0].buf, ddbcpyfrom(dev, msg[0].buf,
i2c->rbuf, msg[0].len); i2c->rbuf, msg[0].len);
return num; 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; return -EIO;
} }
@ -247,11 +252,10 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
adap->class = I2C_CLASS_TV_ANALOG; adap->class = I2C_CLASS_TV_ANALOG;
#endif #endif
#endif #endif
/*strcpy(adap->name, "ddbridge");*/
snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x", snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x",
dev->nr, i2c->link, i); dev->nr, i2c->link, i);
adap->algo = &ddb_i2c_algo; adap->algo = &ddb_i2c_algo;
adap->algo_data = (void *)i2c; adap->algo_data = (void *) i2c;
adap->dev.parent = dev->dev; adap->dev.parent = dev->dev;
return i2c_add_adapter(adap); return i2c_add_adapter(adap);
} }

View File

@ -1,7 +1,7 @@
/* /*
* ddbridge-i2c.h: Digital Devices bridge i2c driver * ddbridge-i2c.h: Digital Devices bridge i2c driver
* *
* Copyright (C) 2010-2015 Digital Devices GmbH * Copyright (C) 2010-2017 Digital Devices GmbH
* Marcus Metzler <mocm@metzlerbros.de> * Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de> * Ralph Metzler <rjkm@metzlerbros.de>
* *

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
/* /*
* ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming * ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming
* *
* Copyright (C) 2010-2015 Marcus Metzler <mocm@metzlerbros.de> * Copyright (C) 2010-2017Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de> * Ralph Metzler <rjkm@metzlerbros.de>
* Digital Devices GmbH * Digital Devices GmbH
* *
@ -87,7 +87,6 @@ static int ns_alloc(struct dvbnss *nss)
dev->ns[i].fe = input; dev->ns[i].fe = input;
nss->priv = &dev->ns[i]; nss->priv = &dev->ns[i];
ret = 0; ret = 0;
/*pr_info("%s i=%d fe=%d\n", __func__, i, input->nr); */
break; break;
} }
ddbwritel(dev, 0x03, RTP_MASTER_CONTROL); ddbwritel(dev, 0x03, RTP_MASTER_CONTROL);
@ -198,7 +197,7 @@ static int ns_set_ci(struct dvbnss *nss, u8 ci)
if (ciport < 0) if (ciport < 0)
return -EINVAL; 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); input->port->lnr, input->nr, ci, ciport);
ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1c, ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1c,
TS_CONTROL(dev->port[ciport].output)); TS_CONTROL(dev->port[ciport].output));
@ -446,8 +445,6 @@ static int ns_start(struct dvbnss *nss)
if (dns->fe != input) if (dns->fe != input)
ddb_dvb_ns_input_start(dns->fe); ddb_dvb_ns_input_start(dns->fe);
ddb_dvb_ns_input_start(input); 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), ddbwritel(dev, reg | (dns->fe->nr << 8) | (dns->fe->port->lnr << 16),
STREAM_CONTROL(dns->nr)); STREAM_CONTROL(dns->nr));
return 0; return 0;

View File

@ -1,7 +1,7 @@
/* /*
* ddbridge-regs.h: Digital Devices PCIe bridge driver * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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_V1 0x00010001
#define CUR_REGISTERMAP_VERSION_V2 0x00020000 #define CUR_REGISTERMAP_VERSION_V2 0x00020000
#define CUR_REGISTERMAP_VERSION_022X 0x00020001
#define HARDWARE_VERSION 0x00000000 #define HARDWARE_VERSION 0x00000000
#define REGISTERMAP_VERSION 0x00000004 #define REGISTERMAP_VERSION 0x00000004
@ -57,9 +58,9 @@
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* Interrupt controller /* Interrupt controller
How many MSI's are available depends on HW (Min 2 max 8) * How many MSI's are available depends on HW (Min 2 max 8)
How many are usable also depends on Host platform * How many are usable also depends on Host platform
*/ */
#define INTERRUPT_BASE (0x40) #define INTERRUPT_BASE (0x40)
@ -166,11 +167,13 @@
#define TEMPMON_FANPWM (0x00000F00) // PWM speed in 10% steps #define TEMPMON_FANPWM (0x00000F00) // PWM speed in 10% steps
#define TEMPMON_FANTACHO (0x000000FF) // Rotations in 100/min steps #define TEMPMON_FANTACHO (0x000000FF) // Rotations in 100/min steps
// V1 Temperature Monitor /* V1 Temperature Monitor
// Temperature Monitor TEMPMON_CONTROL & 0x8000 == 0 : ( 2x LM75A @ 0x90,0x92 ) * Temperature Monitor TEMPMON_CONTROL & 0x8000 == 0 : ( 2x LM75A @ 0x90,0x92 )
// Temperature Monitor TEMPMON_CONTROL & 0x8000 == 1 : ( 1x LM75A @ 0x90, 1x ADM1032 @ 0x9A ) * 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_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_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_SENSOR2 (TEMPMON_BASE + 0x0C) // SHORT Temperature in °C x 256 (LM75A 0x92 or ADM1032 Int)
@ -179,6 +182,7 @@
#define TEMPMON2_BOARD (TEMPMON_SENSOR0) // SHORT Temperature in °C x 256 (ADM1032 int) #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_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_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 */ /* I2C Master Controller */
@ -242,7 +246,7 @@
#define LNB_CMD_HIGH 4 #define LNB_CMD_HIGH 4
#define LNB_CMD_OFF 5 #define LNB_CMD_OFF 5
#define LNB_CMD_DISEQC 6 #define LNB_CMD_DISEQC 6
#define LNB_CMD_UNI 7 #define LNB_CMD_SCIF 7
#define LNB_BUSY (1ULL << 4) #define LNB_BUSY (1ULL << 4)
#define LNB_TONE (1ULL << 15) #define LNB_TONE (1ULL << 15)
@ -330,12 +334,12 @@
/* Muxout from VCO (usually = Lock) */ /* Muxout from VCO (usually = Lock) */
#define VCO3_CONTROL_MUXOUT (0x00000004) #define VCO3_CONTROL_MUXOUT (0x00000004)
// V2 /* V2 */
#define MAX2871_BASE (0xC0) #define MAX2871_BASE (0xC0)
#define MAX2871_CONTROL (MAX2871_BASE + 0x00) #define MAX2871_CONTROL (MAX2871_BASE + 0x00)
#define MAX2871_OUTDATA (MAX2871_BASE + 0x04) // 32 Bit #define MAX2871_OUTDATA (MAX2871_BASE + 0x04)
#define MAX2871_INDATA (MAX2871_BASE + 0x08) // 32 Bit #define MAX2871_INDATA (MAX2871_BASE + 0x08)
#define MAX2871_CONTROL_WRITE (0x00000001) // 1 = Trigger write, resets when done #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_CE (0x00000002) // 0 = Put VCO into power down
#define MAX2871_CONTROL_MUXOUT (0x00000004) // Muxout from VCO #define MAX2871_CONTROL_MUXOUT (0x00000004) // Muxout from VCO
@ -379,10 +383,10 @@
#define RF_ATTENUATOR (0xD8) #define RF_ATTENUATOR (0xD8)
#define RF_ATTENUATOR (0xD8) #define RF_ATTENUATOR (0xD8)
/* 0x00 = 0 dB /* 0x00 = 0 dB
0x01 = 1 dB * 0x01 = 1 dB
... * ...
0x1F = 31 dB * 0x1F = 31 dB
*/ */
#define RF_VGA (0xDC) #define RF_VGA (0xDC)
/* Only V2 */ /* Only V2 */
@ -409,9 +413,9 @@
#define RF_POWER_CONTROL_VALID (0x00000500) #define RF_POWER_CONTROL_VALID (0x00000500)
/* -------------------------------------------------------------------------- /*
Output control * Output control
*/ */
#define IQOUTPUT_BASE (0x240) #define IQOUTPUT_BASE (0x240)
#define IQOUTPUT_CONTROL (IQOUTPUT_BASE + 0x00) #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 \
)

View File

@ -1,7 +1,7 @@
/* /*
* ddbridge.c: Digital Devices PCIe bridge driver * ddbridge.c: Digital Devices PCIe bridge driver
* *
* Copyright (C) 2010-2015 Digital Devices GmbH * Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de> * Ralph Metzler <rjkm@metzlerbros.de>
* Marcus Metzler <mocm@metzlerbros.de> * Marcus Metzler <mocm@metzlerbros.de>
* *
@ -113,12 +113,16 @@ static void __devexit ddb_remove(struct pci_dev *pdev)
static int __devinit ddb_irq_msi(struct ddb *dev, int nr) static int __devinit ddb_irq_msi(struct ddb *dev, int nr)
{ {
int stat; int stat = 0;
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
if (msi && pci_msi_enabled()) { if (msi && pci_msi_enabled()) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) #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); stat = pci_enable_msi_range(dev->pdev, 1, nr);
#endif
if (stat >= 1) { if (stat >= 1) {
dev->msi = stat; dev->msi = stat;
pr_info("DDBridge: using %d MSI interrupt(s)\n", pr_info("DDBridge: using %d MSI interrupt(s)\n",
@ -147,7 +151,7 @@ static int __devinit ddb_irq_init2(struct ddb *dev)
int stat; int stat;
int irq_flag = IRQF_SHARED; 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_CONTROL);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1); ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1);
@ -267,8 +271,12 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
dev->link[0].ids.subdevice = id->subdevice; dev->link[0].ids.subdevice = id->subdevice;
dev->link[0].dev = dev; 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; 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_len = pci_resource_len(dev->pdev, 0);
dev->regs = ioremap(pci_resource_start(dev->pdev, 0), dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
@ -311,13 +319,13 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
if (ddb_init(dev) == 0) if (ddb_init(dev) == 0)
return 0; return 0;
ddb_irq_disable(dev); ddb_irq_exit(dev);
fail0: fail0:
pr_err("fail0\n"); pr_err("DDBridge: fail0\n");
if (dev->msi) if (dev->msi)
pci_disable_msi(dev->pdev); pci_disable_msi(dev->pdev);
fail: fail:
pr_err("fail\n"); pr_err("DDBridge: fail\n");
ddb_unmap(dev); ddb_unmap(dev);
pci_set_drvdata(pdev, NULL); pci_set_drvdata(pdev, NULL);
@ -395,6 +403,17 @@ static struct ddb_info ddb_v6_5 = {
.i2c_mask = 0x0f, .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 = { static struct ddb_info ddb_v7 = {
.type = DDB_OCTOPUS, .type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V7 DVB adapter", .name = "Digital Devices Cine S2 V7 DVB adapter",
@ -450,6 +469,16 @@ static struct ddb_info ddb_ci_s2_pro = {
.board_control_2 = 4, .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 = { static struct ddb_info ddb_dvbct = {
.type = DDB_OCTOPUS, .type = DDB_OCTOPUS,
.name = "Digital Devices DVBCT V6.1 DVB adapter", .name = "Digital Devices DVBCT V6.1 DVB adapter",
@ -498,6 +527,16 @@ static struct ddb_info ddb_mod_fsm_8 = {
.tempmon_irq = 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 = { static struct ddb_info ddb_octopro_hdin = {
.type = DDB_OCTOPRO_HDIN, .type = DDB_OCTOPRO_HDIN,
.name = "Digital Devices OctopusNet Pro 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) { \ #define DDB_DEVICE_ANY(_device) { \
.vendor = _vend, .device = _dev, \ PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, PCI_ANY_ID), \
.subvendor = _subvend, .subdevice = _subdev, \ .driver_data = (kernel_ulong_t) &ddb_none }
.driver_data = (unsigned long)&_driverdata }
static const struct pci_device_id ddb_id_tbl[] __devinitconst = { static const struct pci_device_id ddb_id_table[] __devinitconst = {
DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), DDB_DEVICE(0x0002, 0x0001, ddb_octopus),
DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), DDB_DEVICE(0x0003, 0x0001, ddb_octopus),
DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3), DDB_DEVICE(0x0005, 0x0004, ddb_octopusv3),
DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), DDB_DEVICE(0x0003, 0x0002, ddb_octopus_le),
DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem), DDB_DEVICE(0x0003, 0x0003, ddb_octopus_oem),
DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini), DDB_DEVICE(0x0003, 0x0010, ddb_octopus_mini),
DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini), DDB_DEVICE(0x0005, 0x0011, ddb_octopus_mini),
DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), DDB_DEVICE(0x0003, 0x0020, ddb_v6),
DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5), DDB_DEVICE(0x0003, 0x0021, ddb_v6_5),
DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7), DDB_DEVICE(0x0006, 0x0022, ddb_v7),
DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct), DDB_DEVICE(0x0006, 0x0024, ddb_v7a),
DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3), DDB_DEVICE(0x0003, 0x0030, ddb_dvbct),
DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7), DDB_DEVICE(0x0003, 0xdb03, ddb_satixS2v3),
DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7), DDB_DEVICE(0x0006, 0x0031, ddb_ctv7),
DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7), DDB_DEVICE(0x0006, 0x0032, ddb_ctv7),
DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48), DDB_DEVICE(0x0006, 0x0033, ddb_ctv7),
DDB_ID(DDVID, 0x0008, DDVID, 0x0034, ddb_ct2_8), DDB_DEVICE(0x0007, 0x0023, ddb_s2_48),
DDB_ID(DDVID, 0x0008, DDVID, 0x0035, ddb_c2t2_8), DDB_DEVICE(0x0008, 0x0034, ddb_ct2_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0036, ddb_isdbt_8), DDB_DEVICE(0x0008, 0x0035, ddb_c2t2_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0037, ddb_c2t2i_v0_8), DDB_DEVICE(0x0008, 0x0036, ddb_isdbt_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0038, ddb_c2t2i_8), DDB_DEVICE(0x0008, 0x0037, ddb_c2t2i_v0_8),
DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci), DDB_DEVICE(0x0008, 0x0038, ddb_c2t2i_8),
DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis), DDB_DEVICE(0x0006, 0x0039, ddb_ctv7),
DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci), DDB_DEVICE(0x0011, 0x0040, ddb_ci),
DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro), DDB_DEVICE(0x0011, 0x0041, ddb_cis),
DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod), DDB_DEVICE(0x0012, 0x0042, ddb_ci),
DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod), DDB_DEVICE(0x0013, 0x0043, ddb_ci_s2_pro),
DDB_ID(DDVID, 0x0203, DDVID, 0x0001, ddb_mod), DDB_DEVICE(0x0013, 0x0044, ddb_ci_s2_pro_a),
DDB_ID(DDVID, 0x0210, DDVID, 0x0001, ddb_mod_fsm_24), DDB_DEVICE(0x0201, 0x0001, ddb_mod),
DDB_ID(DDVID, 0x0210, DDVID, 0x0002, ddb_mod_fsm_16), DDB_DEVICE(0x0201, 0x0002, ddb_mod),
DDB_ID(DDVID, 0x0210, DDVID, 0x0003, ddb_mod_fsm_8), 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 */ /* testing on OctopusNet Pro */
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro_hdin), DDB_DEVICE(0x0320, PCI_ANY_ID, ddb_octopro_hdin),
DDB_ID(DDVID, 0x0321, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE(0x0321, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0322, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro), DDB_DEVICE(0x0322, PCI_ANY_ID, ddb_octopro),
DDB_ID(DDVID, 0x0323, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE(0x0323, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0328, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE(0x0328, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0329, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro_hdin), DDB_DEVICE(0x0329, PCI_ANY_ID, ddb_octopro_hdin),
/* in case sub-ids got deleted in flash */ /* in case sub-ids got deleted in flash */
DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE_ANY(0x0003),
DDB_ID(DDVID, 0x0005, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE_ANY(0x0005),
DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE_ANY(0x0006),
DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE_ANY(0x0007),
DDB_ID(DDVID, 0x0008, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE_ANY(0x0008),
DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE_ANY(0x0011),
DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE_ANY(0x0012),
DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none), DDB_DEVICE_ANY(0x0013),
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_none), 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} {0}
}; };
MODULE_DEVICE_TABLE(pci, ddb_id_tbl); MODULE_DEVICE_TABLE(pci, ddb_id_table);
static struct pci_driver ddb_pci_driver = { static struct pci_driver ddb_pci_driver = {
.name = "ddbridge", .name = "ddbridge",
.id_table = ddb_id_tbl, .id_table = ddb_id_table,
.probe = ddb_probe, .probe = ddb_probe,
.remove = ddb_remove, .remove = ddb_remove,
}; };
@ -591,9 +644,9 @@ static __init int module_init_ddbridge(void)
{ {
int stat = -1; int stat = -1;
pr_info("Digital Devices PCIE bridge driver " pr_info("DDBridge: Digital Devices PCIE bridge driver "
DDBRIDGE_VERSION DDBRIDGE_VERSION
", Copyright (C) 2010-16 Digital Devices GmbH\n"); ", Copyright (C) 2010-17 Digital Devices GmbH\n");
if (ddb_class_create() < 0) if (ddb_class_create() < 0)
return -1; return -1;
ddb_wq = create_workqueue("ddbridge"); ddb_wq = create_workqueue("ddbridge");

View File

@ -1,7 +1,7 @@
/* /*
* ddbridge.h: Digital Devices PCIe bridge driver * ddbridge.h: Digital Devices PCIe bridge driver
* *
* Copyright (C) 2010-2015 Digital Devices GmbH * Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rmetzler@digitaldevices.de> * Ralph Metzler <rmetzler@digitaldevices.de>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -55,7 +55,6 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/sched.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <asm/dma.h> #include <asm/dma.h>
@ -172,22 +171,24 @@ struct ddb_info {
#define TS_QUIRK_SERIAL 1 #define TS_QUIRK_SERIAL 1
#define TS_QUIRK_REVERSED 2 #define TS_QUIRK_REVERSED 2
#define TS_QUIRK_NO_OUTPUT 4 #define TS_QUIRK_NO_OUTPUT 4
#define TS_QUIRK_ALT_OSC 8
u32 tempmon_irq; u32 tempmon_irq;
struct ddb_regmap *regmap; struct ddb_regmap *regmap;
}; };
/* DMA_SIZE MUST be smaller than 256k and /* 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 */ #define DMA_MAX_BUFS 32 /* hardware table limit */
#ifdef SMALL_DMA_BUFS #ifdef SMALL_DMA_BUFS
#define INPUT_DMA_BUFS 32 #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 INPUT_DMA_IRQ_DIV 1
#define OUTPUT_DMA_BUFS 32 #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 #define OUTPUT_DMA_IRQ_DIV 1
#else #else
#define INPUT_DMA_BUFS 8 #define INPUT_DMA_BUFS 8
@ -198,6 +199,10 @@ struct ddb_info {
#define OUTPUT_DMA_SIZE (128*47*21) #define OUTPUT_DMA_SIZE (128*47*21)
#define OUTPUT_DMA_IRQ_DIV 1 #define OUTPUT_DMA_IRQ_DIV 1
#endif #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;
struct ddb_port; struct ddb_port;
@ -317,6 +322,7 @@ struct ddb_port {
#define DDB_CI_EXTERNAL_XO2 12 #define DDB_CI_EXTERNAL_XO2 12
#define DDB_CI_EXTERNAL_XO2_B 13 #define DDB_CI_EXTERNAL_XO2_B 13
#define DDB_TUNER_DVBS_STV0910_PR 14 #define DDB_TUNER_DVBS_STV0910_PR 14
#define DDB_TUNER_DVBC2T2I_SONY_P 15
#define DDB_TUNER_XO2 32 #define DDB_TUNER_XO2 32
#define DDB_TUNER_DVBS_STV0910 (DDB_TUNER_XO2 + 0) #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_ISDBT_SONY (DDB_TUNER_XO2 + 2)
#define DDB_TUNER_DVBC2T2_SONY (DDB_TUNER_XO2 + 3) #define DDB_TUNER_DVBC2T2_SONY (DDB_TUNER_XO2 + 3)
#define DDB_TUNER_ATSC_ST (DDB_TUNER_XO2 + 4) #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_input *input[2];
struct ddb_output *output; struct ddb_output *output;
@ -343,8 +349,8 @@ struct mod_base {
struct ddb_mod { struct ddb_mod {
struct ddb_port *port; struct ddb_port *port;
u32 nr; //u32 nr;
u32 regs; //u32 regs;
u32 frequency; u32 frequency;
u32 modulation; u32 modulation;
@ -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); 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) \ #define ddbmemset(_dev, _adr, _val, _count) \
memset_io((char *) (_dev->regs + (_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); 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 #endif

View File

@ -1,7 +1,7 @@
/* /*
* octonet.c: Digital Devices network tuner driver * octonet.c: Digital Devices network tuner driver
* *
* Copyright (C) 2012-16 Digital Devices GmbH * Copyright (C) 2012-17 Digital Devices GmbH
* Marcus Metzler <mocm@metzlerbros.de> * Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de> * Ralph Metzler <rjkm@metzlerbros.de>
* *
@ -177,9 +177,9 @@ static int __init octonet_probe(struct platform_device *pdev)
else else
dev->link[0].info = &ddb_octonet_tbd; 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); 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); dev->link[0].ids.mac, dev->link[0].ids.devid);
ddbwritel(dev, 0, ETHER_CONTROL); ddbwritel(dev, 0, ETHER_CONTROL);
@ -233,7 +233,7 @@ static __init int init_octonet(void)
{ {
int res; 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"); ", Copyright (C) 2010-16 Digital Devices GmbH\n");
res = ddb_class_create(); res = ddb_class_create();
if (res) if (res)

View File

@ -35,7 +35,12 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
#include <linux/sched/signal.h>
#else
#include <linux/sched.h> #include <linux/sched.h>
#endif
#include <linux/kthread.h> #include <linux/kthread.h>
#include "dvb_ca_en50221.h" #include "dvb_ca_en50221.h"

View File

@ -21,7 +21,12 @@
* *
*/ */
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
#include <linux/sched/signal.h>
#else
#include <linux/sched.h> #include <linux/sched.h>
#endif
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>

View File

@ -29,7 +29,12 @@
#define _DVB_FRONTEND_H_ #define _DVB_FRONTEND_H_
#include <linux/types.h> #include <linux/types.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
#include <linux/sched/signal.h>
#else
#include <linux/sched.h> #include <linux/sched.h>
#endif
#include <linux/ioctl.h> #include <linux/ioctl.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/module.h> #include <linux/module.h>

View File

@ -33,7 +33,7 @@
#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0 #if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS #define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
#else #else
#define DVB_MAX_ADAPTERS 8 #define DVB_MAX_ADAPTERS 64
#endif #endif
#define DVB_UNSET (-1) #define DVB_UNSET (-1)

View File

@ -96,7 +96,7 @@ static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
struct i2c_msg msg = { struct i2c_msg msg = {
.addr = adr, .flags = 0, .buf = data, .len = len}; .addr = adr, .flags = 0, .buf = data, .len = len};
if (i2c_transfer(adap, &msg, 1) != 1) { 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 -1;
} }
return 0; return 0;
@ -270,9 +270,10 @@ static int writebitsx(struct cxd_state *cxd, u8 Bank, u8 Address,
mutex_lock(&cxd->mutex); mutex_lock(&cxd->mutex);
status = readregsx_unlocked(cxd, Bank, Address, &tmp, 1); status = readregsx_unlocked(cxd, Bank, Address, &tmp, 1);
if (status < 0) if (status < 0)
return status; goto out;
tmp = (tmp & ~Mask) | Value; tmp = (tmp & ~Mask) | Value;
status = writeregsx_unlocked(cxd, Bank, Address, &tmp, 1); status = writeregsx_unlocked(cxd, Bank, Address, &tmp, 1);
out:
mutex_unlock(&cxd->mutex); mutex_unlock(&cxd->mutex);
return status; return status;
} }
@ -286,9 +287,10 @@ static int writebitst(struct cxd_state *cxd, u8 Bank, u8 Address,
mutex_lock(&cxd->mutex); mutex_lock(&cxd->mutex);
status = readregst_unlocked(cxd, Bank, Address, &Tmp, 1); status = readregst_unlocked(cxd, Bank, Address, &Tmp, 1);
if (status < 0) if (status < 0)
return status; goto out;
Tmp = (Tmp & ~Mask) | Value; Tmp = (Tmp & ~Mask) | Value;
status = writeregst_unlocked(cxd, Bank, Address, &Tmp, 1); status = writeregst_unlocked(cxd, Bank, Address, &Tmp, 1);
out:
mutex_unlock(&cxd->mutex); mutex_unlock(&cxd->mutex);
return status; return status;
} }
@ -508,7 +510,11 @@ static void ActiveC2_to_Sleep(struct cxd_state *state)
writebitst(state, 0x2B, 0x2B, 0x00, 0x1F); writebitst(state, 0x2B, 0x2B, 0x00, 0x1F);
{ {
u8 data[2] = { 0x75, 0x75 }; u8 data[2] = { 0x75, 0x75 };
u8 data24[2] = { 0x89, 0x89 };
if (state->is24MHz)
writeregst(state, 0x2D, 0x24, data24, sizeof(data24));
else
writeregst(state, 0x2D, 0x24, data, sizeof(data)); writeregst(state, 0x2D, 0x24, data, sizeof(data));
} }
@ -554,62 +560,115 @@ static int ConfigureTS(struct cxd_state *state,
return status; 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) static void BandSettingT(struct cxd_state *state, u32 iffreq)
{ {
u8 IF_data[3] = { (iffreq >> 16) & 0xff, u8 IF_data[3] = { (iffreq >> 16) & 0xff,
(iffreq >> 8) & 0xff, iffreq & 0xff}; (iffreq >> 8) & 0xff, iffreq & 0xff};
u8 data[] = { 0x01, 0x14 };
writeregst(state, 0x13, 0x9c, data, sizeof(data));
switch (state->bw) { switch (state->bw) {
default: default:
case 8: case 8:
{ {
u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 };
u8 CL_data[] = { 0x01, 0xE0 };
u8 NF_data[] = { 0x01, 0x02 }; u8 NF_data[] = { 0x01, 0x02 };
if (state->is24MHz) {
u8 TR_data[] = { 0x15, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); 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)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x00, 0x07); writebitst(state, 0x10, 0xD7, 0x00, 0x07);
if (state->is24MHz) {
u8 CL_data[] = { 0x15, 0x28 };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); 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)); writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data));
break; break;
} }
case 7: case 7:
{ {
u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 };
u8 CL_data[] = { 0x12, 0xF8 };
u8 NF_data[] = { 0x00, 0x03 }; u8 NF_data[] = { 0x00, 0x03 };
if (state->is24MHz) {
u8 TR_data[] = { 0x18, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); 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)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x02, 0x07); writebitst(state, 0x10, 0xD7, 0x02, 0x07);
if (state->is24MHz) {
u8 CL_data[] = { 0x1f, 0xf8 };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); 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)); writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data));
break; break;
} }
case 6: case 6:
{ {
u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA };
u8 CL_data[] = { 0x1F, 0xDC };
u8 NF_data[] = { 0x00, 0x03 }; u8 NF_data[] = { 0x00, 0x03 };
if (state->is24MHz) {
u8 TR_data[] = { 0x1c, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); 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)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x04, 0x07); writebitst(state, 0x10, 0xD7, 0x04, 0x07);
if (state->is24MHz) {
u8 CL_data[] = { 0x25, 0x4c };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); 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)); writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data));
break; break;
} }
case 5: case 5:
{ {
static u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 };
static u8 CL_data[] = { 0x26, 0x3C };
static u8 NF_data[] = { 0x00, 0x03 }; static u8 NF_data[] = { 0x00, 0x03 };
if (state->is24MHz) {
u8 TR_data[] = { 0x21, 0x99, 0x99, 0x99, 0x99 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); 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)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x06, 0x07); writebitst(state, 0x10, 0xD7, 0x06, 0x07);
if (state->is24MHz) {
static u8 CL_data[] = { 0x2c, 0xc2 };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); 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)); writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data));
break; 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, 0x30, 0x00); /* Enable ADC Clock */
writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ 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 */ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */
writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ 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 */ writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */
writebitst(state, 0x10, 0xD2, 0x0C, 0x1F); /* IF AGC Gain */ 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 */ 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, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */
writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ 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); BandSettingT(state, iffreq);
writebitst(state, 0x10, 0x60, 0x11, 0x1f); /* BER scaling */ writebitst(state, 0x10, 0x60, 0x11, 0x1f); /* BER scaling */
@ -662,10 +728,16 @@ static void BandSettingT2(struct cxd_state *state, u32 iffreq)
default: default:
case 8: case 8:
{ {
/* Timing recovery */
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 }; u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 };
/* Timing recovery */
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
/* Add EQ Optimisation for tuner here */ /* Add EQ Optimisation for tuner here */
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
/* System Bandwidth */ /* System Bandwidth */
@ -674,36 +746,60 @@ static void BandSettingT2(struct cxd_state *state, u32 iffreq)
break; break;
case 7: case 7:
{ {
if (state->is24MHz) {
u8 TR_data[] = { 0x18, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 }; u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x02, 0x07); writebitst(state, 0x10, 0xD7, 0x02, 0x07);
} }
break; break;
case 6: case 6:
{ {
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 }; u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x04, 0x07); writebitst(state, 0x10, 0xD7, 0x04, 0x07);
} }
break; break;
case 5: case 5:
{ {
if (state->is24MHz) {
u8 TR_data[] = { 0x21, 0x99, 0x99, 0x99, 0x99 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 }; u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x06, 0x07); writebitst(state, 0x10, 0xD7, 0x06, 0x07);
} }
break; break;
case 2: /* 1.7 MHz */ case 2: /* 1.7 MHz */
{ {
if (state->is24MHz) {
u8 TR_data[] = { 0x68, 0x0f, 0xa2, 0x32, 0xd0 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x58, 0xE2, 0xAF, 0xE0, 0xBC }; u8 TR_data[] = { 0x58, 0xE2, 0xAF, 0xE0, 0xBC };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data)); writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x03, 0x07); 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 */ 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 */ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */
writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ 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 */ writeregt(state, 0x20, 0x8B, 0x3C); /* SNR Good count */
writebitst(state, 0x2B, 0x76, 0x20, 0x70); /* Noise Gain ACQ */ 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, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */
writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ 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); writeregt(state, 0x13, 0x86, 0x34);
writebitst(state, 0x13, 0x9E, 0x09, 0x0F); writebitst(state, 0x13, 0x9E, 0x09, 0x0F);
writeregt(state, 0x13, 0x9F, 0xD8); 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); BandSettingT2(state, iffreq);
writebitst(state, 0x20, 0x72, 0x08, 0x0f); /* BER scaling */ 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 */ 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 */ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */
writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ 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, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */
writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/ 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); BandSettingC(state, iffreq);
writebitst(state, 0x40, 0x60, 0x11, 0x1f); /* BER scaling */ writebitst(state, 0x40, 0x60, 0x11, 0x1f); /* BER scaling */
@ -810,29 +946,58 @@ static void BandSettingC2(struct cxd_state *state, u32 iffreq)
default: default:
case 8: case 8:
{ {
u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 }; if (state->is24MHz) {
u8 data[2] = { 0x11, 0x9E }; u8 TR_data[] = { 0x15, 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[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writebitst(state, 0x27, 0x7a, 0x00, 0x0f);
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x00, 0x07); writebitst(state, 0x10, 0xD7, 0x00, 0x07);
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)); writeregst(state, 0x50, 0xEC, data, sizeof(data));
writeregt(state, 0x50, 0xEF, 0x11); writeregt(state, 0x50, 0xEF, 0x11);
writeregt(state, 0x50, 0xF1, 0x9E); writeregt(state, 0x50, 0xF1, 0x9E);
} }
}
break; break;
case 6: case 6:
{ {
u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA }; if (state->is24MHz) {
u8 data[2] = { 0x17, 0x70 }; 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)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x04, 0x07); writebitst(state, 0x10, 0xD7, 0x04, 0x07);
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)); writeregst(state, 0x50, 0xEC, data, sizeof(data));
writeregt(state, 0x50, 0xEF, 0x17); writeregt(state, 0x50, 0xEF, 0x17);
writeregt(state, 0x50, 0xF1, 0x70); writeregt(state, 0x50, 0xF1, 0x70);
} }
}
break; break;
} }
} }
@ -849,7 +1014,7 @@ static void Sleep_to_ActiveC2(struct cxd_state *state, u32 iffreq)
writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */ 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 */ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */
writeregst(state, 0x00, 0x43, data, sizeof(data)); writeregst(state, 0x00, 0x43, data, sizeof(data));
@ -891,6 +1056,22 @@ static void Sleep_to_ActiveC2(struct cxd_state *state, u32 iffreq)
writeregst(state, 0x2D, 0x24, data, sizeof(data)); 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); BandSettingC2(state, iffreq);
@ -908,34 +1089,51 @@ static void BandSettingIT(struct cxd_state *state, u32 iffreq)
default: default:
case 8: case 8:
{ {
u8 TR_data[] = { 0x0F, 0x22, 0x80, 0x00, 0x00 }; /* 20.5/41 */ if (state->is24MHz) {
u8 CL_data[] = { 0x15, 0xA8 }; u8 TR_data[] = { 0x11, 0xb8, 0x00, 0x00, 0x00 }; /* 24 */
/*u8 TR_data[] = { 0x11, 0xB8, 0x00, 0x00, 0x00 }; */ /* 24 */
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); 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 */ /* Add EQ Optimisation for tuner here */
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x00, 0x07); /* System Bandwidth */ writebitst(state, 0x10, 0xD7, 0x00, 0x07); /* System Bandwidth */
/*u8 CL_data[] = { 0x13, 0xFC }; */ if (state->is24MHz) {
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); 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); writebitst(state, 0x12, 0x71, 0x03, 0x07);
writeregt(state, 0x15, 0xbe, 0x03); writeregt(state, 0x15, 0xbe, 0x03);
} }
break; break;
case 7: case 7:
{ {
u8 TR_data[] = { 0x11, 0x4c, 0x00, 0x00, 0x00 }; if (state->is24MHz) {
u8 CL_data[] = { 0x1B, 0x5D }; u8 TR_data[] = { 0x14, 0x40, 0x00, 0x00, 0x00 }; /* 24 */
/*u8 TR_data[] = { 0x14, 0x40, 0x00, 0x00, 0x00 }; */
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); 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)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x02, 0x07); writebitst(state, 0x10, 0xD7, 0x02, 0x07);
/*static u8 CL_data[] = { 0x1A, 0xFA };*/ if (state->is24MHz) {
u8 CL_data[] = { 0x1a, 0xfa };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data)); 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); writebitst(state, 0x12, 0x71, 0x03, 0x07);
writeregt(state, 0x15, 0xbe, 0x02); writeregt(state, 0x15, 0xbe, 0x02);
@ -943,23 +1141,31 @@ static void BandSettingIT(struct cxd_state *state, u32 iffreq)
break; break;
case 6: case 6:
{ {
u8 TR_data[] = { 0x14, 0x2E, 0x00, 0x00, 0x00 }; if (state->is24MHz) {
/*u8 TR_data[] = { 0x17, 0xA0, 0x00, 0x00, 0x00 }; */ u8 TR_data[] = { 0x17, 0xa0, 0x00, 0x00, 0x00 }; /* 24 */
/*u8 CL_data[] = { 0x1F, 0x79 }; */
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data)); 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)); writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x04, 0x07); writebitst(state, 0x10, 0xD7, 0x04, 0x07);
if (state->is24MHz) {
u8 CL_data[] = { 0x1f, 0x79 };
writeregst(state, 0x10, 0xd9, CL_data, sizeof(CL_data));
} else {
if (state->is2k14) { if (state->is2k14) {
u8 CL_data[] = { 0x1a, 0xe2 }; u8 CL_data[] = { 0x1a, 0xe2 };
writeregst(state, 0x10, 0xDd9, CL_data, sizeof(CL_data)); writeregst(state, 0x10, 0xd9, CL_data, sizeof(CL_data));
} else { } else {
u8 CL_data[] = { 0x1F, 0xec }; u8 CL_data[] = { 0x1F, 0xec };
writeregst(state, 0x10, 0xd9, CL_data, sizeof(CL_data)); writeregst(state, 0x10, 0xd9, CL_data, sizeof(CL_data));
} }
}
writebitst(state, 0x12, 0x71, 0x07, 0x07); writebitst(state, 0x12, 0x71, 0x07, 0x07);
writeregt(state, 0x15, 0xbe, 0x02); 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) 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); ConfigureTS(state, ActiveIT);
/* writeregx(state, 0x00,0x17,0x01); */ /* 2838 has only one Mode */ /* 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 */ 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 */ /*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */
writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */ 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) { if (state->is2k14) {
writebitst(state, 0x10, 0xd2, 0x0c, 0x1f);
writeregt(state, 0x11, 0x6a, 0x50);
writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */ writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */
writebitst(state, 0x18, 0x30, 0x01, 0x01); 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, 0x1e, 0x73, 0x68, 0xff);
writebitst(state, 0x63, 0x81, 0x00, 0x01); writebitst(state, 0x63, 0x81, 0x00, 0x01);
} }
//if( m_is24MHz ) if (state->is24MHz) {
//{ static u8 TSIF_data[2] = { 0x60,0x00 } ; // 24 MHz
// static BYTE TSIF_data[2] = { 0x60,0x00 } ; // 24 MHz static u8 data[3] = { 0xB7,0x1B,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, 0x10, 0xBF, TSIF_data, sizeof(TSIF_data));
writeregst(state, 0x60, 0xa8, data2, sizeof(data2)); 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) { if (!state->is2k14) {
writeregt(state, 0x10, 0xE2, 0xCE); /* OREG_PNC_DISABLE */ 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) static void T2_SetParameters(struct cxd_state *state)
{ {
u8 Profile = 0x01; /* Profile Base */ 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) { if (state->T2Profile == T2P_Lite) {
Profile = 0x05; Profile = 0x05;
notT2time = 40; notT2time = state->is24MHz ? 46 : 40;
} }
if (state->plp != 0xffffffff) { if (state->plp != 0xffffffff) {
@ -1182,7 +1388,7 @@ static int Start(struct cxd_state *state, u32 IntermediateFrequency)
if (state->state < Sleep) if (state->state < Sleep)
return -EINVAL; return -EINVAL;
iffreq = MulDiv32(IntermediateFrequency, 16777216, 41000000); iffreq = MulDiv32(IntermediateFrequency, 16777216, state->is24MHz ? 48000000 : 41000000);
switch (state->omode) { switch (state->omode) {
case OM_DVBT: case OM_DVBT:
@ -1368,9 +1574,16 @@ static void init(struct cxd_state *state)
writeregx(state, 0x00, 0x10, 0x01); writeregx(state, 0x00, 0x10, 0x01);
writeregsx(state, 0x00, 0x13, data, 2);
writeregx(state, 0x00, 0x15, 0x00); writeregx(state, 0x00, 0x15, 0x00);
usleep_range(3000, 4000); 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); writeregx(state, 0x00, 0x10, 0x00);
usleep_range(2000, 3000); usleep_range(2000, 3000);
@ -1382,6 +1595,12 @@ static void init(struct cxd_state *state)
if (state->type == CXD2838) if (state->type == CXD2838)
writeregt(state, 0x60, 0x5A, 0x00); 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); writebitst(state, 0x10, 0xCB, 0x00, 0x40);
writeregt(state, 0x10, 0xCD, state->IF_FS); 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 */ cfg->ts_clock : 1; /* 1 = fastest (82 MBit/s), 5 = slowest */
/* IF Fullscale 0x50 = 1.4V, 0x39 = 1V, 0x28 = 0.7V */ /* IF Fullscale 0x50 = 1.4V, 0x39 = 1V, 0x28 = 0.7V */
state->IF_FS = 0x50; 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, 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 do
{ {
+ BYTE tmp; + u8 tmp;
+ +
CHK_ERROR(FreezeRegsT()); CHK_ERROR(FreezeRegsT());
@ -1757,11 +1978,11 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+ pT2_PLPIDS->CommonPLPID = tmp; + pT2_PLPIDS->CommonPLPID = tmp;
+ } + }
+ +
BYTE nPids = 0; u8 nPids = 0;
CHK_ERROR(ReadRegT(0x22,0x7F,&nPids)); CHK_ERROR(ReadRegT(0x22,0x7F,&nPids));
- pValues[0] = nPids; - pValues[0] = nPids;
- if( nPids >= nValues ) nPids = BYTE(nValues-1); - if( nPids >= nValues ) nPids = nValues - 1;
+ pT2_PLPIDS->NumPLPS = nPids; + pT2_PLPIDS->NumPLPS = nPids;
+ CHK_ERROR(ReadRegT(0x22,0x80,&pT2_PLPIDS->PLPList[0], nPids > 128 ? 128 : 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]; u8 Data[2];
u32 reg; u32 reg;
*SignalToNoise = 0;
freeze_regst(state); freeze_regst(state);
readregst_unlocked(state, 0x60, 0x28, Data, sizeof(Data)); readregst_unlocked(state, 0x60, 0x28, Data, sizeof(Data));
unfreeze_regst(state); unfreeze_regst(state);
reg = (Data[0] << 8) | Data[1]; reg = (Data[0] << 8) | Data[1];
if (reg == 0)
return;
if (reg > 51441) if (reg > 51441)
reg = 51441; reg = 51441;
@ -1837,11 +2061,14 @@ static void GetSignalToNoiseC2(struct cxd_state *state, u32 *SignalToNoise)
u8 Data[2]; u8 Data[2];
u32 reg; u32 reg;
*SignalToNoise = 0;
freeze_regst(state); freeze_regst(state);
readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data)); readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data));
unfreeze_regst(state); unfreeze_regst(state);
reg = (Data[0] << 8) | Data[1]; reg = (Data[0] << 8) | Data[1];
if (reg == 0)
return;
if (reg > 51441) if (reg > 51441)
reg = 51441; reg = 51441;
@ -1854,11 +2081,14 @@ static void GetSignalToNoiseT2(struct cxd_state *state, u32 *SignalToNoise)
u8 Data[2]; u8 Data[2];
u32 reg; u32 reg;
*SignalToNoise = 0;
freeze_regst(state); freeze_regst(state);
readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data)); readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data));
unfreeze_regst(state); unfreeze_regst(state);
reg = (Data[0] << 8) | Data[1]; reg = (Data[0] << 8) | Data[1];
if (reg == 0)
return;
if (reg > 10876) if (reg > 10876)
reg = 10876; reg = 10876;
@ -1870,11 +2100,14 @@ static void GetSignalToNoiseT(struct cxd_state *state, u32 *SignalToNoise)
u8 Data[2]; u8 Data[2];
u32 reg; u32 reg;
*SignalToNoise = 0;
freeze_regst(state); freeze_regst(state);
readregst_unlocked(state, 0x10, 0x28, Data, sizeof(Data)); readregst_unlocked(state, 0x10, 0x28, Data, sizeof(Data));
unfreeze_regst(state); unfreeze_regst(state);
reg = (Data[0] << 8) | Data[1]; reg = (Data[0] << 8) | Data[1];
if (reg == 0)
return;
if (reg > 4996) if (reg > 4996)
reg = 4996; reg = 4996;
@ -1888,7 +2121,6 @@ static void GetSignalToNoiseC(struct cxd_state *state, u32 *SignalToNoise)
u32 reg; u32 reg;
*SignalToNoise = 0; *SignalToNoise = 0;
freeze_regst(state); freeze_regst(state);
readregst_unlocked(state, 0x40, 0x19, &Constellation, 1); readregst_unlocked(state, 0x40, 0x19, &Constellation, 1);
readregst_unlocked(state, 0x40, 0x4C, Data, sizeof(Data)); readregst_unlocked(state, 0x40, 0x4C, Data, sizeof(Data));
@ -2404,13 +2636,12 @@ static int probe(struct cxd_state *state)
int status; int status;
status = readregst(state, 0x00, 0xFD, &ChipID, 1); status = readregst(state, 0x00, 0xFD, &ChipID, 1);
if (status) if (status)
status = readregsx(state, 0x00, 0xFD, &ChipID, 1); status = readregsx(state, 0x00, 0xFD, &ChipID, 1);
if (status) if (status)
return status; return status;
/*printk("ChipID = %02X\n", ChipID);*/ printk("ChipID = %02X\n", ChipID);
switch (ChipID) { switch (ChipID) {
case 0xa4: case 0xa4:
state->type = CXD2843; state->type = CXD2843;
@ -2445,6 +2676,7 @@ struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c,
{ {
struct cxd_state *state = NULL; struct cxd_state *state = NULL;
pr_info("attach\n");
state = kzalloc(sizeof(struct cxd_state), GFP_KERNEL); state = kzalloc(sizeof(struct cxd_state), GFP_KERNEL);
if (!state) if (!state)
return NULL; return NULL;

View File

@ -8,6 +8,7 @@ struct cxd2843_cfg {
u8 adr; u8 adr;
u32 ts_clock; u32 ts_clock;
u8 parallel; u8 parallel;
u32 osc;
}; };
#if defined(CONFIG_DVB_CXD2843) || \ #if defined(CONFIG_DVB_CXD2843) || \

View File

@ -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.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage;
fe->ops.release_sec = lnbh25_release; fe->ops.release_sec = lnbh25_release;
pr_info("LNB25 on %02x\n", lnbh->adr); pr_info("LNBH25 on %02x\n", lnbh->adr);
return fe; return fe;
} }

View File

@ -698,6 +698,10 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
int stat; int stat;
u32 regData = 0; u32 regData = 0;
#if 0
if (!firmware_is_alive(state))
pr_info("FW dead!\n");
#endif
mutex_lock(&state->base->status_lock); mutex_lock(&state->base->status_lock);
HYDRA_DEMOD_STATUS_LOCK(state, state->demod); HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
stat = read_register(state, (HYDRA_DMD_STATUS_INPUT_POWER_ADDR + 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 */ .xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
.info = { .info = {
.name = "MXL5XX", .name = "MXL5XX",
.frequency_min = 950000, .frequency_min = 300000,
.frequency_max = 2150000, .frequency_max = 2350000,
.frequency_stepsize = 0, .frequency_stepsize = 0,
.frequency_tolerance = 0, .frequency_tolerance = 0,
.symbol_rate_min = 1000000, .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) static int validate_sku(struct mxl *state)
{ {
u32 padMuxBond, prcmChipId, prcmSoCId; u32 padMuxBond = 0, prcmChipId = 0, prcmSoCId = 0;
int status; int status;
u32 type = state->base->type; u32 type = state->base->type;

View File

@ -105,6 +105,7 @@ struct stv {
u8 tscfgh; u8 tscfgh;
u8 tsgeneral; u8 tsgeneral;
u8 tsspeed; u8 tsspeed;
u8 single;
unsigned long tune_time; unsigned long tune_time;
s32 SearchRange; s32 SearchRange;
@ -1137,6 +1138,9 @@ static int probe(struct stv *state)
write_reg(state, RSTV0910_SYNTCTRL, 0x02); /* SYNTCTRL */ write_reg(state, RSTV0910_SYNTCTRL, 0x02); /* SYNTCTRL */
write_reg(state, RSTV0910_TSGENERAL, state->tsgeneral); /* TSGENERAL */ write_reg(state, RSTV0910_TSGENERAL, state->tsgeneral); /* TSGENERAL */
write_reg(state, RSTV0910_CFGEXT, 0x02); /* CFGEXT */ write_reg(state, RSTV0910_CFGEXT, 0x02); /* CFGEXT */
if (state->single)
write_reg(state, RSTV0910_GENCFG, 0x14); /* GENCFG */
else
write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */ write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */
write_reg(state, RSTV0910_P1_TNRCFG2, 0x02); /* IQSWAP = 0 */ write_reg(state, RSTV0910_P1_TNRCFG2, 0x02); /* IQSWAP = 0 */
@ -1830,6 +1834,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c,
state->DEMOD = 0x10; /* Inversion : Auto with reset to 0 */ state->DEMOD = 0x10; /* Inversion : Auto with reset to 0 */
state->ReceiveMode = Mode_None; state->ReceiveMode = Mode_None;
state->CurScramblingCode = NO_SCRAMBLING_CODE; state->CurScramblingCode = NO_SCRAMBLING_CODE;
state->single = cfg->single ? 1 : 0;
base = match_base(i2c, cfg->adr); base = match_base(i2c, cfg->adr);
if (base) { if (base) {

View File

@ -9,6 +9,7 @@ struct stv0910_cfg {
u8 adr; u8 adr;
u8 parallel; u8 parallel;
u8 rptlvl; u8 rptlvl;
u8 single;
}; };
#if defined(CONFIG_DVB_STV0910) || \ #if defined(CONFIG_DVB_STV0910) || \

View File

@ -19,15 +19,16 @@ struct dvb_mod_channel_params {
#define DVB_MOD_SET _IOW('o', 208, struct dvb_mod_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 DVB_MOD_CHANNEL_SET _IOW('o', 209, struct dvb_mod_channel_params)
#define MOD_UNDEFINED 0 #define MODULATOR_UNDEFINED 0
#define MOD_START 1 #define MODULATOR_START 1
#define MOD_STOP 2 #define MODULATOR_STOP 2
#define MOD_FREQUENCY 3 #define MODULATOR_FREQUENCY 3
#define MOD_MODULATION 4 #define MODULATOR_MODULATION 4
#define MOD_SYMBOL_RATE 5 /* Hz */ #define MODULATOR_SYMBOL_RATE 5 /* Hz */
#define MOD_ATTENUATOR 32 #define MODULATOR_BASE_FREQUENCY 6
#define MOD_INPUT_BITRATE 33 /* Hz */ #define MODULATOR_ATTENUATOR 32
#define MOD_PCR_MODE 34 /* 1=pcr correction enabled */ #define MODULATOR_INPUT_BITRATE 33 /* Hz */
#define MODULATOR_PCR_MODE 34 /* 1=pcr correction enabled */
#define MODULATOR_OUTPUT_ARI 64
#endif /*_UAPI_DVBMOD_H_*/ #endif /*_UAPI_DVBMOD_H_*/