mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2025-03-01 10:35:23 +00:00
Compare commits
237 Commits
0.9.19c
...
0.9.31-int
Author | SHA1 | Date | |
---|---|---|---|
|
5751c3fb1a | ||
|
5c032058b9 | ||
|
a44dbc889b | ||
|
3d5fae7dd8 | ||
|
7602ecf3e5 | ||
|
bf0315bcc0 | ||
|
dcddb3437d | ||
|
665b5ef857 | ||
|
c063cffa63 | ||
|
640c15f4a7 | ||
|
d3ca949ec5 | ||
|
fd41904378 | ||
|
eb81f006e4 | ||
|
af554da865 | ||
|
d6f56c1807 | ||
|
31f22ef4de | ||
|
d4d0a9b84e | ||
|
24503d35ad | ||
|
3556d6464b | ||
|
862c7bfc60 | ||
|
fd21584ecc | ||
|
6814a8fa23 | ||
|
49d4bd0da8 | ||
|
6d1cfd4cd2 | ||
|
e68ce2ef62 | ||
|
023ae44411 | ||
|
7222bd58b3 | ||
|
f404b3fb6d | ||
|
de34e2ebbd | ||
|
774e92bd44 | ||
|
8c46d9a86a | ||
|
452771913e | ||
|
3285b6ade0 | ||
|
e6dd33deec | ||
|
93e42deeaa | ||
|
e415b6e203 | ||
|
1354b9021f | ||
|
4d17f2f5f0 | ||
|
5fa08eb288 | ||
|
933779aa24 | ||
|
01d35aad26 | ||
|
40c32767ec | ||
|
8704ceaf94 | ||
|
12b792ef3f | ||
|
3063b8e88b | ||
|
7d73553b61 | ||
|
5d4259f6f6 | ||
|
04294ab5ef | ||
|
4699a19bfb | ||
|
f44a9dfcbd | ||
|
b3b7a0ef2e | ||
|
8a98bd88cd | ||
|
bfd1f1979d | ||
|
8931ae4d9e | ||
|
4070713556 | ||
|
bba5fa5683 | ||
|
ae37a1e4e9 | ||
|
2aee51e447 | ||
|
264f08fbad | ||
|
6830f4df08 | ||
|
785d7c5126 | ||
|
52b81cfd8e | ||
|
263d593bcf | ||
|
f56ec446ae | ||
|
fa36763d43 | ||
|
08a6d78da7 | ||
|
b3806c61ce | ||
|
eb6652f18f | ||
|
21c69918d3 | ||
|
326e928f66 | ||
|
0e09153b1f | ||
|
adf4e40256 | ||
|
9dcd81fe42 | ||
|
a7ce2ef8da | ||
|
285d7aed49 | ||
|
9eb5458eeb | ||
|
d51a9db022 | ||
|
532afaa97c | ||
|
1984377f72 | ||
|
37de742aad | ||
|
4bfdb11762 | ||
|
1e99122d52 | ||
|
cd5de95023 | ||
|
c56f593a4c | ||
|
3a3a48654e | ||
|
1a80437b98 | ||
|
28a2aaa653 | ||
|
f6c7586815 | ||
|
d069dc051f | ||
|
9392ccec22 | ||
|
4c276fbc75 | ||
|
7cc9107597 | ||
|
1f77192d62 | ||
|
fc4a807b4e | ||
|
b6d5976e14 | ||
|
101289c77e | ||
|
26eedb3d26 | ||
|
d1387078f1 | ||
|
6bf258b54c | ||
|
4435efeab5 | ||
|
633797e05f | ||
|
4ee27ff317 | ||
|
7d7da35fb5 | ||
|
a3b517391a | ||
|
1171b345df | ||
|
7f746f0219 | ||
|
49a05e75af | ||
|
c546918e79 | ||
|
570a565f37 | ||
|
85b1447059 | ||
|
a4c275895d | ||
|
7a8d3f80c4 | ||
|
7db462ca68 | ||
|
cd229fabf5 | ||
|
5252c5318d | ||
|
95b9a644b6 | ||
|
4f452819df | ||
|
f20b16cd12 | ||
|
1f4ae2bd51 | ||
|
2ec7863b04 | ||
|
fb022009ee | ||
|
a98a7c95a8 | ||
|
bb191aa5d7 | ||
|
38f0e9611e | ||
|
4ed35e1de5 | ||
|
1567d804b1 | ||
|
8c82d0166c | ||
|
5c7b55490a | ||
|
e2db17b04e | ||
|
a1221c6e4e | ||
|
86d9ce8f11 | ||
|
f2091a50df | ||
|
131aaf361e | ||
|
c929aea04d | ||
|
16c0834b78 | ||
|
50fee67d49 | ||
|
9d0400d81a | ||
|
6f071763c3 | ||
|
98bdb95193 | ||
|
2c8fcc1df5 | ||
|
805a3ffeed | ||
|
ffdcd91a06 | ||
|
b36a6392cc | ||
|
0d27002a17 | ||
|
094e1f3e1f | ||
|
2d71c946d3 | ||
|
39ce49dbd8 | ||
|
8908df8098 | ||
|
421adf6872 | ||
|
154794ac51 | ||
|
6b73faeee5 | ||
|
80e0750c71 | ||
|
65f9f56cfe | ||
|
53c32d47e0 | ||
|
4db55036f3 | ||
|
eda007e71a | ||
|
6975dfdd5a | ||
|
0c6336292e | ||
|
a456f8d5d9 | ||
|
a8d5d5b50d | ||
|
d988c8562b | ||
|
aaf5707c45 | ||
|
1e9b7dc5cc | ||
|
40edadad3d | ||
|
535ffa6ca6 | ||
|
1b0df5fcfa | ||
|
5633c2f79d | ||
|
74f172a4fe | ||
|
cc6209af33 | ||
|
de16096894 | ||
|
a4062a1582 | ||
|
d180cb70e2 | ||
|
30ca8e9962 | ||
|
4591bab46b | ||
|
3c6028f485 | ||
|
6a49ab08ab | ||
|
8f30246ff1 | ||
|
92d8b37839 | ||
|
66c912d874 | ||
|
0b4d6d807a | ||
|
c4133d98c1 | ||
|
f111d6e097 | ||
|
7860d623e8 | ||
|
ab25eeefdf | ||
|
64f21d8f99 | ||
|
faee02e446 | ||
|
6d80791077 | ||
|
1d3bb91eb8 | ||
|
c18503fcad | ||
|
906efafd5e | ||
|
b479d9cdc2 | ||
|
6038e87250 | ||
|
1b0e822b07 | ||
|
cdaf838cb1 | ||
|
19fd6f1b26 | ||
|
472cacb0c4 | ||
|
fa66a70a35 | ||
|
b5a44d581d | ||
|
e8eaf4660c | ||
|
81966f8982 | ||
|
dd540699c3 | ||
|
a8ed36fef2 | ||
|
9ab1b7f533 | ||
|
197897731e | ||
|
781686c87d | ||
|
b354113d15 | ||
|
8d0bb02239 | ||
|
7eb4ff762c | ||
|
16f0d291b1 | ||
|
829929a41f | ||
|
af746a02dd | ||
|
e83dedf6b4 | ||
|
9bcb9a2c9a | ||
|
66be95a2b9 | ||
|
bb334ea229 | ||
|
535683dfb6 | ||
|
d10c83f16a | ||
|
18481e2ea6 | ||
|
8402c7ab05 | ||
|
e2145682e2 | ||
|
1173454c93 | ||
|
1aacccef7c | ||
|
dd78dae68b | ||
|
0393ab4db4 | ||
|
29dc0f9e31 | ||
|
411a142c21 | ||
|
5932c6c52f | ||
|
4209e3a03a | ||
|
71e4972863 | ||
|
4f53aa9a1b | ||
|
4e1b527c35 | ||
|
5c4db2b594 | ||
|
5ed590a3c7 | ||
|
5af6007152 | ||
|
151770c0d8 | ||
|
f2b6dbabd7 | ||
|
4c7e7afc84 |
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
#
|
||||
# Normal rules
|
||||
#
|
||||
|
||||
.*
|
||||
*.o
|
||||
*.o.*
|
||||
*.a
|
||||
*.s
|
||||
*.ko
|
||||
*.so
|
||||
*.so.dbg
|
||||
*.orig
|
||||
*~
|
||||
\#*#
|
@@ -1,3 +1,10 @@
|
||||
0.9.29 compiles with most kernels up to 4.11.1
|
||||
|
||||
see git commit messages for newer changes
|
||||
|
||||
0.9.24 2016.08.03
|
||||
- suport new V2 modulator cards
|
||||
|
||||
0.9.19c 2015.07.20
|
||||
- MAX S8:
|
||||
do not turn on diseqc and tuners on init
|
||||
|
5
Makefile
5
Makefile
@@ -1,4 +1,5 @@
|
||||
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
kernelver ?= $(shell uname -r)
|
||||
KDIR ?= /lib/modules/$(kernelver)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
MODDEFS := CONFIG_DVB_CORE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_CXD2099=m CONFIG_DVB_LNBP21=m CONFIG_DVB_STV090x=m CONFIG_DVB_STV6110x=m CONFIG_DVB_STV0367=m CONFIG_DVB_TDA18212=m CONFIG_DVB_STV0367DD=m CONFIG_DVB_TDA18212DD=m CONFIG_DVB_OCTONET=m CONFIG_DVB_CXD2843=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6111=m CONFIG_DVB_LNBH25=m CONFIG_DVB_MXL5XX=m
|
||||
@@ -14,6 +15,6 @@ install: all
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
|
||||
|
||||
clean:
|
||||
rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
|
||||
rm -rf */.*.o.d */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
|
||||
|
||||
|
||||
|
14
README.md
Normal file
14
README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# DDBridge Driver
|
||||
|
||||
### Patches
|
||||
We can only accept patches which don't break compilation for older kernels (as far back as 2.6.37).
|
||||
|
||||
### Prepare for Building
|
||||
|
||||
TBD
|
||||
|
||||
### Building
|
||||
|
||||
TBD
|
||||
|
||||
|
@@ -1,19 +1,25 @@
|
||||
all: cit citin flashprog modt ddtest setmod ddflash
|
||||
all: cit citin flashprog modt ddtest setmod ddflash setmod2 pls
|
||||
|
||||
cit: cit.c
|
||||
gcc -o cit cit.c -lpthread
|
||||
$(CC) -o cit cit.c -lpthread
|
||||
|
||||
modt: modt.c
|
||||
gcc -o modt modt.c -lpthread
|
||||
$(CC) -o modt modt.c -lpthread
|
||||
|
||||
setmod: setmod.c
|
||||
gcc -o setmod setmod.c -I../include/
|
||||
$(CC) -o setmod setmod.c -I../include/
|
||||
|
||||
setmod2: setmod2.c
|
||||
$(CC) -o setmod2 setmod2.c -I../include/
|
||||
|
||||
flashprog: flashprog.c
|
||||
gcc -o flashprog flashprog.c
|
||||
$(CC) -o flashprog flashprog.c
|
||||
|
||||
ddtest: ddtest.c
|
||||
gcc -o ddtest ddtest.c
|
||||
$(CC) -o ddtest ddtest.c
|
||||
|
||||
ddflash: ddflash.c
|
||||
gcc -o ddflash ddflash.c
|
||||
$(CC) -o ddflash ddflash.c
|
||||
|
||||
pls: pls.c
|
||||
$(CC) -o pls pls.c
|
||||
|
100
apps/cit.c
100
apps/cit.c
@@ -9,6 +9,9 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <pthread.h>
|
||||
#include <getopt.h>
|
||||
|
||||
uint32_t adapter = 0, device = 0, snum = 256, rnum = 256;
|
||||
|
||||
uint8_t fill[188]={0x47, 0x1f, 0xff, 0x10,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
@@ -68,24 +71,39 @@ void proc_buf(uint8_t *buf, uint32_t *d)
|
||||
} else {
|
||||
if (memcmp(ts+8, buf+8, 180))
|
||||
printf("error\n");
|
||||
if (!(c&0xffff))
|
||||
printf("R %08x\n", c);
|
||||
if (!(c&0xffff)) {
|
||||
printf("R %08x\r", c);
|
||||
fflush(0);
|
||||
}
|
||||
}
|
||||
(*d)++;
|
||||
}
|
||||
|
||||
void *get_ts(void *a)
|
||||
{
|
||||
uint8_t buf[188*1024];
|
||||
uint8_t *buf;
|
||||
int len, off;
|
||||
|
||||
int fdi=open("/dev/dvb/adapter2/ci0", O_RDONLY);
|
||||
int fdi;
|
||||
char fname[80];
|
||||
uint32_t d=0;
|
||||
|
||||
buf = malloc(188*rnum);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
|
||||
printf("using %s for reading\n", fname);
|
||||
fdi = open(fname, O_RDONLY);
|
||||
if (fdi == -1) {
|
||||
printf("Failed to open %s for read: %m\n", fname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
len=read(fdi, buf, 188*1024);
|
||||
memset(buf, 0, 188*rnum);
|
||||
len=read(fdi, buf, 188*rnum);
|
||||
if (len<0)
|
||||
continue;
|
||||
//printf("read %u\n", len);
|
||||
if (buf[0]!=0x47) {
|
||||
read(fdi, buf, 1);
|
||||
continue;
|
||||
@@ -96,20 +114,28 @@ void *get_ts(void *a)
|
||||
}
|
||||
}
|
||||
|
||||
#define SNUM 233
|
||||
//671
|
||||
void send(void)
|
||||
|
||||
int send(void)
|
||||
{
|
||||
uint8_t buf[188*SNUM], *cts;
|
||||
uint8_t *buf, *cts;
|
||||
int i;
|
||||
uint32_t c=0;
|
||||
int fdo;
|
||||
|
||||
fdo=open("/dev/dvb/adapter2/ci0", O_WRONLY);
|
||||
|
||||
char fname[80];
|
||||
|
||||
buf = malloc(188*snum);
|
||||
if (!buf)
|
||||
return -1;
|
||||
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
|
||||
printf("using %s for writing\n", fname);
|
||||
fdo=open(fname, O_WRONLY);
|
||||
if (fdo == -1) {
|
||||
printf("Failed to open %s to write: %m\n", fname);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
for (i=0; i<SNUM; i++) {
|
||||
for (i=0; i<snum; i++) {
|
||||
cts=buf+i*188;
|
||||
memcpy(cts, ts, 188);
|
||||
cts[4]=(c>>24);
|
||||
@@ -122,15 +148,57 @@ void send(void)
|
||||
//usleep(100000+0xffff&rand());
|
||||
//usleep(1000);
|
||||
}
|
||||
write(fdo, buf, 188*SNUM);
|
||||
write(fdo, buf, 188*snum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pthread_t th;
|
||||
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
int c;
|
||||
static struct option long_options[] = {
|
||||
{"adapter", required_argument, 0, 'a'},
|
||||
{"device", required_argument, 0, 'd'},
|
||||
{"snum", required_argument, 0, 's'},
|
||||
{"rnum", required_argument, 0, 'r'},
|
||||
{"help", no_argument , 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
c = getopt_long(argc, argv,
|
||||
"a:d:h",
|
||||
long_options, &option_index);
|
||||
if (c==-1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'd':
|
||||
device = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'a':
|
||||
adapter = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 's':
|
||||
snum = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'r':
|
||||
rnum = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'h':
|
||||
printf("cit -a<adapter> -d<device>\n");
|
||||
exit(-1);
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
if (optind < argc) {
|
||||
printf("Warning: unused arguments\n");
|
||||
}
|
||||
printf("adapter %d, device: %d\n", adapter, device);
|
||||
memset(ts+8, 180, 0x5a);
|
||||
pthread_create(&th, NULL, get_ts, NULL);
|
||||
usleep(10000);
|
||||
|
1
apps/flash.c
Symbolic link
1
apps/flash.c
Symbolic link
@@ -0,0 +1 @@
|
||||
./octonet/flash.c
|
497
apps/flashprog.c
497
apps/flashprog.c
@@ -33,379 +33,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#define DDB_MAGIC 'd'
|
||||
|
||||
static uint32_t linknr = 0;
|
||||
|
||||
struct ddb_id {
|
||||
__u16 vendor;
|
||||
__u16 device;
|
||||
__u16 subvendor;
|
||||
__u16 subdevice;
|
||||
__u32 hw;
|
||||
__u32 regmap;
|
||||
};
|
||||
|
||||
struct ddb_flashio {
|
||||
__u8 *write_buf;
|
||||
__u32 write_len;
|
||||
__u8 *read_buf;
|
||||
__u32 read_len;
|
||||
__u32 link;
|
||||
};
|
||||
|
||||
#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio)
|
||||
#define IOCTL_DDB_ID _IOR(DDB_MAGIC, 0x03, struct ddb_id)
|
||||
|
||||
|
||||
int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen)
|
||||
{
|
||||
struct ddb_flashio fio = {
|
||||
.write_buf=wbuf,
|
||||
.write_len=wlen,
|
||||
.read_buf=rbuf,
|
||||
.read_len=rlen,
|
||||
.link=linknr,
|
||||
};
|
||||
|
||||
return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio);
|
||||
}
|
||||
|
||||
enum {
|
||||
UNKNOWN_FLASH = 0,
|
||||
ATMEL_AT45DB642D = 1,
|
||||
SSTI_SST25VF016B = 2,
|
||||
SSTI_SST25VF032B = 3,
|
||||
SSTI_SST25VF064C = 4,
|
||||
SPANSION_S25FL116K = 5,
|
||||
};
|
||||
|
||||
|
||||
int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
|
||||
{
|
||||
uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,
|
||||
(addr >> 8) & 0xff, addr & 0xff};
|
||||
|
||||
return flashio(ddb, cmd, 4, buf, len);
|
||||
}
|
||||
|
||||
int flashdump(int ddb, uint32_t addr, uint32_t len)
|
||||
{
|
||||
int i, j;
|
||||
uint8_t buf[32];
|
||||
int bl = sizeof(buf);
|
||||
|
||||
for (j=0; j<len; j+=bl, addr+=bl) {
|
||||
flashread(ddb, buf, addr, bl);
|
||||
for (i=0; i<bl; i++) {
|
||||
printf("%02x ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int FlashDetect(int dev)
|
||||
{
|
||||
uint8_t Cmd = 0x9F;
|
||||
uint8_t Id[3];
|
||||
|
||||
int r = flashio(dev, &Cmd,1,Id,3);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x41 )
|
||||
r = SSTI_SST25VF016B;
|
||||
else if( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4A )
|
||||
r = SSTI_SST25VF032B;
|
||||
else if( Id[0] == 0x1F && Id[1] == 0x28 )
|
||||
r = ATMEL_AT45DB642D;
|
||||
else if( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4B )
|
||||
r = SSTI_SST25VF064C;
|
||||
else if( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x15 )
|
||||
r = SPANSION_S25FL116K;
|
||||
else
|
||||
r = UNKNOWN_FLASH;
|
||||
|
||||
switch(r) {
|
||||
case UNKNOWN_FLASH:
|
||||
printf("Unknown Flash Flash ID = %02x %02x %02x\n",Id[0],Id[1],Id[2]);
|
||||
break;
|
||||
case ATMEL_AT45DB642D:
|
||||
printf("Flash: Atmel AT45DB642D 64 MBit\n");
|
||||
break;
|
||||
case SSTI_SST25VF016B:
|
||||
printf("Flash: SSTI SST25VF016B 16 MBit\n");
|
||||
break;
|
||||
case SSTI_SST25VF032B:
|
||||
printf("Flash: SSTI SST25VF032B 32 MBit\n"); break;
|
||||
case SSTI_SST25VF064C:
|
||||
printf("Flash: SSTI SST25VF064C 64 MBit\n"); break;
|
||||
case SPANSION_S25FL116K:
|
||||
printf("Flash: SPANSION S25FL116K 16 MBit\n"); break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize)
|
||||
{
|
||||
int err = 0;
|
||||
int BlockErase = BufferSize >= 8192;
|
||||
int i;
|
||||
|
||||
if (BlockErase) {
|
||||
for(i = 0; i < BufferSize; i += 8192 ) {
|
||||
uint8_t Cmd[4];
|
||||
if( (i & 0xFFFF) == 0 )
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
Cmd[0] = 0x50; // Block Erase
|
||||
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
err = flashio(dev,Cmd,4,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
Cmd[0] = 0xD7; // Read Status register
|
||||
err = flashio(dev,Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x80) == 0x80 ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < BufferSize; i += 1024 )
|
||||
{
|
||||
uint8_t Cmd[4 + 1024];
|
||||
if( (i & 0xFFFF) == 0 )
|
||||
{
|
||||
printf(" Program %08x\n",FlashOffset + i);
|
||||
}
|
||||
Cmd[0] = 0x84; // Buffer 1
|
||||
Cmd[1] = 0x00;
|
||||
Cmd[2] = 0x00;
|
||||
Cmd[3] = 0x00;
|
||||
memcpy(&Cmd[4],&Buffer[i],1024);
|
||||
|
||||
err = flashio(dev,Cmd,4 + 1024,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase)
|
||||
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
|
||||
err = flashio(dev,Cmd,4,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
Cmd[0] = 0xD7; // Read Status register
|
||||
err = flashio(dev,Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x80) == 0x80 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int FlashWritePageMode(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize, uint8_t LockBits)
|
||||
{
|
||||
int err = 0, i, j;
|
||||
uint8_t Cmd[260];
|
||||
|
||||
if( (BufferSize % 4096) != 0 )
|
||||
return -1; // Must be multiple of sector size
|
||||
|
||||
do {
|
||||
Cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev, Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x01; // WRSR
|
||||
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
|
||||
err = flashio(dev, Cmd,2,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
for(i = 0; i < BufferSize; i += 4096 ) {
|
||||
if( (i & 0xFFFF) == 0 ) {
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
}
|
||||
|
||||
Cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev, Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x20; // Sector erase ( 4Kb)
|
||||
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
err = flashio(dev, Cmd,4,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
while(1)
|
||||
{
|
||||
Cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev, Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
|
||||
for (j = BufferSize - 256; j >= 0; j -= 256 )
|
||||
{
|
||||
if( (j & 0xFFFF) == 0 )
|
||||
{
|
||||
printf(" Programm %08x\n",FlashOffset + j);
|
||||
}
|
||||
|
||||
Cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev, Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x02; // PP
|
||||
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
memcpy(&Cmd[4],&Buffer[j],256);
|
||||
err = flashio(dev, Cmd,260,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
while(1)
|
||||
{
|
||||
Cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev, Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev, Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x01; // WRSR
|
||||
Cmd[1] = LockBits; // BPx = 0, Lock all blocks
|
||||
err = flashio(dev, Cmd,2,NULL,0);
|
||||
|
||||
} while(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize)
|
||||
{
|
||||
int err = 0;
|
||||
uint8_t Cmd[6];
|
||||
int i, j;
|
||||
|
||||
// Must be multiple of sector size
|
||||
if( (BufferSize % 4096) != 0 )
|
||||
return -1;
|
||||
|
||||
do {
|
||||
Cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev,Cmd,1,NULL,0);
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
Cmd[0] = 0x01; // WRSR
|
||||
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
|
||||
err = flashio(dev,Cmd,2,NULL,0);
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
for(i = 0; i < BufferSize; i += 4096 ) {
|
||||
if( (i & 0xFFFF) == 0 )
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
Cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev,Cmd,1,NULL,0);
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
Cmd[0] = 0x20; // Sector erase ( 4Kb)
|
||||
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
err = flashio(dev,Cmd,4,NULL,0);
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
Cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev,Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
}
|
||||
if( err < 0 )
|
||||
break;
|
||||
for(j = BufferSize - 4096; j >= 0; j -= 4096 ) {
|
||||
if( (j & 0xFFFF) == 0 )
|
||||
printf(" Program %08x\n",FlashOffset + j);
|
||||
|
||||
for(i = 0; i < 4096; i += 2 ) {
|
||||
if( i == 0 ) {
|
||||
Cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev,Cmd,1,NULL,0);
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
Cmd[0] = 0xAD; // AAI
|
||||
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
Cmd[4] = Buffer[j+i];
|
||||
Cmd[5] = Buffer[j+i+1];
|
||||
err = flashio(dev,Cmd,6,NULL,0);
|
||||
} else {
|
||||
Cmd[0] = 0xAD; // AAI
|
||||
Cmd[1] = Buffer[j+i];
|
||||
Cmd[2] = Buffer[j+i+1];
|
||||
err = flashio(dev,Cmd,3,NULL,0);
|
||||
}
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
Cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev,Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x04; // WDIS
|
||||
err = flashio(dev,Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev,Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x01; // WRSR
|
||||
Cmd[1] = 0x1C; // BPx = 0, Lock all blocks
|
||||
err = flashio(dev,Cmd,2,NULL,0);
|
||||
} while(0);
|
||||
return err;
|
||||
}
|
||||
#include "flash.h"
|
||||
|
||||
void get_id(int ddb, struct ddb_id *ddbid) {
|
||||
uint8_t id[4];
|
||||
@@ -450,8 +78,8 @@ int main(int argc, char **argv)
|
||||
uint32_t FlashOffset = 0x10000;
|
||||
int ddb;
|
||||
int i, err;
|
||||
int SectorSize=0;
|
||||
int FlashSize=0;
|
||||
uint32_t SectorSize=0;
|
||||
uint32_t FlashSize=0;
|
||||
int Flash;
|
||||
|
||||
uint32_t svid=0, jump=0, dump=0;
|
||||
@@ -459,6 +87,7 @@ int main(int argc, char **argv)
|
||||
|
||||
int ddbnum = 0;
|
||||
int force = 0;
|
||||
char *fname = NULL;
|
||||
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
@@ -470,12 +99,15 @@ int main(int argc, char **argv)
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
c = getopt_long(argc, argv,
|
||||
"d:n:s:o:l:dfhj",
|
||||
"d:n:s:o:l:dfhjb:",
|
||||
long_options, &option_index);
|
||||
if (c==-1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'b':
|
||||
fname = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
dump = strtoul(optarg, NULL, 16);
|
||||
break;
|
||||
@@ -513,32 +145,7 @@ int main(int argc, char **argv)
|
||||
printf("Could not open device\n");
|
||||
return -1;
|
||||
}
|
||||
Flash=FlashDetect(ddb);
|
||||
|
||||
switch(Flash) {
|
||||
case ATMEL_AT45DB642D:
|
||||
SectorSize = 1024;
|
||||
FlashSize = 0x800000;
|
||||
break;
|
||||
case SSTI_SST25VF016B:
|
||||
SectorSize = 4096;
|
||||
FlashSize = 0x200000;
|
||||
break;
|
||||
case SSTI_SST25VF032B:
|
||||
SectorSize = 4096;
|
||||
FlashSize = 0x400000;
|
||||
break;
|
||||
case SSTI_SST25VF064C:
|
||||
SectorSize = 4096;
|
||||
FlashSize = 0x800000;
|
||||
break;
|
||||
case SPANSION_S25FL116K:
|
||||
SectorSize = 4096;
|
||||
FlashSize = 0x200000;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
Flash = flashdetect(ddb, &SectorSize, &FlashSize);
|
||||
|
||||
get_id(ddb, &ddbid);
|
||||
#if 1
|
||||
@@ -553,23 +160,6 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ddbid.device == 0x0011)
|
||||
type = 1;
|
||||
if (ddbid.device == 0x0201)
|
||||
type = 2;
|
||||
if (ddbid.device == 0x02)
|
||||
type = 3;
|
||||
if (ddbid.device == 0x03)
|
||||
type = 0;
|
||||
if (ddbid.device == 0x07)
|
||||
type = 4;
|
||||
if (ddbid.device == 0x320)
|
||||
type = 5;
|
||||
if (ddbid.device == 0x13)
|
||||
type = 6;
|
||||
if (ddbid.device == 0x12)
|
||||
type = 7;
|
||||
|
||||
if (!SectorSize)
|
||||
return 0;
|
||||
|
||||
@@ -612,36 +202,60 @@ int main(int argc, char **argv)
|
||||
} else {
|
||||
int fh, i;
|
||||
int fsize;
|
||||
char *fname;
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
fname="DVBBridgeV1B_DVBBridgeV1B.bit";
|
||||
printf("Octopus\n");
|
||||
break;
|
||||
case 1:
|
||||
fname="CIBridgeV1B_CIBridgeV1B.bit";
|
||||
printf("Octopus CI\n");
|
||||
break;
|
||||
case 2:
|
||||
fname="DVBModulatorV1B_DVBModulatorV1B.bit";
|
||||
printf("Modulator\n");
|
||||
break;
|
||||
case 3:
|
||||
if (!fname)
|
||||
switch (ddbid.device) {
|
||||
case 0x0002:
|
||||
fname="DVBBridgeV1A_DVBBridgeV1A.bit";
|
||||
printf("Octopus 35\n");
|
||||
break;
|
||||
case 4:
|
||||
fname="DVBBridgeV2A_DD01_0007_MXL.bit";
|
||||
case 0x0003:
|
||||
fname="DVBBridgeV1B_DVBBridgeV1B.fpga";
|
||||
printf("Octopus\n");
|
||||
break;
|
||||
case 0x0005:
|
||||
fname="DVBBridgeV2A_DD01_0005_STD.fpga";
|
||||
printf("Octopus Classic\n");
|
||||
break;
|
||||
case 0x0006:
|
||||
fname="DVBBridgeV2A_DD01_0006_STD.fpga";
|
||||
printf("CineS2 V7\n");
|
||||
break;
|
||||
case 0x0007:
|
||||
fname="DVBBridgeV2A_DD01_0007_MXL.fpga";
|
||||
printf("Octopus 4/8\n");
|
||||
break;
|
||||
case 6:
|
||||
case 0x0008:
|
||||
fname="DVBBridgeV2A_DD01_0008_CXD.fpga";
|
||||
printf("Octopus 4/8\n");
|
||||
break;
|
||||
case 0x0011:
|
||||
fname="CIBridgeV1B_CIBridgeV1B.fpga";
|
||||
printf("Octopus CI\n");
|
||||
break;
|
||||
case 0x0012:
|
||||
fname="DVBBridgeV2B_DD01_0012_STD.fpga";
|
||||
printf("Octopus CI\n");
|
||||
break;
|
||||
case 0x0013:
|
||||
fname="DVBBridgeV2B_DD01_0013_PRO.fpga";
|
||||
printf("Octopus PRO\n");
|
||||
break;
|
||||
case 7:
|
||||
fname="DVBBridgeV2B_DD01_0012_STD.fpga";
|
||||
printf("Octopus CI\n");
|
||||
case 0x0201:
|
||||
fname="DVBModulatorV1B_DVBModulatorV1B.bit";
|
||||
printf("Modulator\n");
|
||||
break;
|
||||
case 0x0203:
|
||||
fname="DVBModulatorV1B_DD01_0203.fpga";
|
||||
printf("Modulator Test\n");
|
||||
break;
|
||||
case 0x0210:
|
||||
fname="DVBModulatorV2A_DD01_0210.fpga";
|
||||
printf("Modulator V2\n");
|
||||
break;
|
||||
case 0x0220:
|
||||
fname="SDRModulatorV1A_DD01_0220.fpga";
|
||||
printf("SDRModulator\n");
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN\n");
|
||||
@@ -649,7 +263,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
fh = open(fname, O_RDONLY);
|
||||
if (fh < 0 ) {
|
||||
printf("File not found \n");
|
||||
printf("File %s not found \n", fname);
|
||||
return 0;
|
||||
}
|
||||
printf("Using bitstream %s\n", fname);
|
||||
@@ -708,6 +322,7 @@ int main(int argc, char **argv)
|
||||
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x3C);
|
||||
break;
|
||||
case SPANSION_S25FL116K:
|
||||
case SPANSION_S25FL164K:
|
||||
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C);
|
||||
break;
|
||||
}
|
||||
|
@@ -17,3 +17,4 @@ octonet: octonet.c
|
||||
|
||||
octokey: octokey.c
|
||||
$(CC) -o octokey octokey.c
|
||||
|
||||
|
@@ -58,78 +58,139 @@ static int reboot(uint32_t off)
|
||||
struct ddflash {
|
||||
int fd;
|
||||
struct ddb_id id;
|
||||
uint32_t type;
|
||||
uint32_t version;
|
||||
|
||||
uint32_t flash_type;
|
||||
uint32_t sector_size;
|
||||
uint32_t size;
|
||||
|
||||
uint32_t bufsize;
|
||||
uint32_t block_erase;
|
||||
|
||||
uint8_t * buffer;
|
||||
uint8_t *buffer;
|
||||
};
|
||||
|
||||
int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen)
|
||||
{
|
||||
struct ddb_flashio fio = {
|
||||
.write_buf=wbuf,
|
||||
.write_len=wlen,
|
||||
.read_buf=rbuf,
|
||||
.read_len=rlen,
|
||||
.link=0,
|
||||
};
|
||||
|
||||
return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio);
|
||||
}
|
||||
|
||||
enum {
|
||||
UNKNOWN_FLASH = 0,
|
||||
ATMEL_AT45DB642D = 1,
|
||||
SSTI_SST25VF016B = 2,
|
||||
SSTI_SST25VF032B = 3,
|
||||
};
|
||||
|
||||
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 flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset,
|
||||
uint8_t LockBits, uint32_t fw_off)
|
||||
{
|
||||
int err = 0;
|
||||
uint8_t cmd[260];
|
||||
int i, j;
|
||||
uint8_t buf[32];
|
||||
int bl = sizeof(buf);
|
||||
uint32_t flen, blen;
|
||||
|
||||
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]);
|
||||
blen = flen = lseek(dev, 0, SEEK_END) - fw_off;
|
||||
if (blen % 0xff)
|
||||
blen = (blen + 0xff) & 0xffffff00;
|
||||
printf("blen = %u, flen = %u\n", blen, flen);
|
||||
|
||||
do {
|
||||
cmd[0] = 0x50; // EWSR
|
||||
err = flashio(ddf->fd, cmd, 1, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = 0x00; // BPx = 0, Unlock all blocks
|
||||
err = flashio(ddf->fd, cmd, 2, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
for (i = 0; i < flen; i += 4096) {
|
||||
if ((i & 0xFFFF) == 0)
|
||||
printf(" Erase %08x\n", FlashOffset + i);
|
||||
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(ddf->fd, cmd, 1, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
cmd[0] = 0x20; // Sector erase ( 4Kb)
|
||||
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
err = flashio(ddf->fd, cmd, 4, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
while (1) {
|
||||
cmd[0] = 0x05; // RDRS
|
||||
err = flashio(ddf->fd, cmd, 1, &cmd[0], 1);
|
||||
if (err < 0)
|
||||
break;
|
||||
if ((cmd[0] & 0x01) == 0)
|
||||
break;
|
||||
}
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
for (j = blen - 256; j >= 0; j -= 256 ) {
|
||||
uint32_t len = 256;
|
||||
ssize_t rlen;
|
||||
|
||||
if (lseek(dev, j + fw_off, SEEK_SET) < 0) {
|
||||
printf("seek error\n");
|
||||
return -1;
|
||||
}
|
||||
if (flen - j < 256) {
|
||||
len = flen - j;
|
||||
memset(ddf->buffer, 0xff, 256);
|
||||
}
|
||||
rlen = read(dev, ddf->buffer, len);
|
||||
if (rlen < 0 || rlen != len) {
|
||||
printf("file read error %d,%d at %u\n", rlen, errno, j);
|
||||
return -1;
|
||||
}
|
||||
printf ("write %u bytes at %08x\n", len, j);
|
||||
|
||||
|
||||
if ((j & 0xFFFF) == 0)
|
||||
printf(" Programm %08x\n", FlashOffset + j);
|
||||
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(ddf->fd, 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], ddf->buffer, 256);
|
||||
err = flashio(ddf->fd, cmd, 260, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
cmd[0] = 0x05; // RDRS
|
||||
err = flashio(ddf->fd, cmd,1, &cmd[0], 1);
|
||||
if (err < 0)
|
||||
break;
|
||||
if ((cmd[0] & 0x01) == 0)
|
||||
break;
|
||||
}
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
}
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
cmd[0] = 0x50; // EWSR
|
||||
err = flashio(ddf->fd, cmd, 1, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = LockBits; // BPx = 0, Lock all blocks
|
||||
err = flashio(ddf->fd, cmd, 2, NULL, 0);
|
||||
} while(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
void dump(const uint8_t *b, int l)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < l; j += 16, b += 16) {
|
||||
for (i = 0; i < 16; i++)
|
||||
if (i + j < l)
|
||||
printf("%02x ", b[i]);
|
||||
else
|
||||
printf(" ");
|
||||
printf(" | ");
|
||||
for (i = 0; i < 16; i++)
|
||||
if (i + j < l)
|
||||
putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.');
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int flashwrite_SSTI(struct ddflash *ddf, int fs, uint32_t FlashOffset, uint32_t maxlen, uint32_t fw_off)
|
||||
{
|
||||
@@ -261,7 +322,18 @@ static int flashwrite_SSTI(struct ddflash *ddf, int fs, uint32_t FlashOffset, ui
|
||||
|
||||
static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off)
|
||||
{
|
||||
flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off);
|
||||
switch (ddf->flash_type) {
|
||||
case SSTI_SST25VF016B:
|
||||
case SSTI_SST25VF032B:
|
||||
return flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off);
|
||||
case SSTI_SST25VF064C:
|
||||
return flashwrite_pagemode(ddf, fs, addr, 0x3c, fw_off);
|
||||
case SPANSION_S25FL116K:
|
||||
case SPANSION_S25FL132K:
|
||||
case SPANSION_S25FL164K:
|
||||
return flashwrite_pagemode(ddf, fs, addr, 0x1c, fw_off);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off)
|
||||
@@ -314,198 +386,54 @@ static int flash_detect(struct ddflash *ddf)
|
||||
return r;
|
||||
|
||||
if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x41) {
|
||||
r = SSTI_SST25VF016B;
|
||||
//printf("Flash: SSTI SST25VF016B 16 MBit\n");
|
||||
ddf->flash_type = SSTI_SST25VF016B;
|
||||
printf("Flash: SSTI SST25VF016B 16 MBit\n");
|
||||
ddf->sector_size = 4096;
|
||||
ddf->size = 0x200000;
|
||||
} else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4A) {
|
||||
r = SSTI_SST25VF032B;
|
||||
//printf("Flash: SSTI SST25VF032B 32 MBit\n");
|
||||
ddf->flash_type = SSTI_SST25VF032B;
|
||||
printf("Flash: SSTI SST25VF032B 32 MBit\n");
|
||||
ddf->sector_size = 4096;
|
||||
ddf->size = 0x400000;
|
||||
} else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4B) {
|
||||
ddf->flash_type = SSTI_SST25VF064C;
|
||||
printf("Flash: SSTI SST25VF064C 64 MBit\n");
|
||||
ddf->sector_size = 4096;
|
||||
ddf->size = 0x800000;
|
||||
} else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x15) {
|
||||
ddf->flash_type = SPANSION_S25FL116K;
|
||||
printf("Flash: SPANSION S25FL116K 16 MBit\n");
|
||||
ddf->sector_size = 4096;
|
||||
ddf->size = 0x200000;
|
||||
} else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x16) {
|
||||
ddf->flash_type = SPANSION_S25FL132K;
|
||||
printf("Flash: SPANSION S25FL132K 32 MBit\n");
|
||||
ddf->sector_size = 4096;
|
||||
ddf->size = 0x400000;
|
||||
} else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x17) {
|
||||
ddf->flash_type = SPANSION_S25FL164K;
|
||||
printf("Flash: SPANSION S25FL164K 64 MBit\n");
|
||||
ddf->sector_size = 4096;
|
||||
ddf->size = 0x800000;
|
||||
} else if (id[0] == 0x1F && id[1] == 0x28) {
|
||||
r = ATMEL_AT45DB642D;
|
||||
//printf("Flash: Atmel AT45DB642D 64 MBit\n");
|
||||
ddf->flash_type = ATMEL_AT45DB642D;
|
||||
printf("Flash: Atmel AT45DB642D 64 MBit\n");
|
||||
ddf->sector_size = 1024;
|
||||
ddf->size = 0x800000;
|
||||
} else {
|
||||
r = UNKNOWN_FLASH;
|
||||
//printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]);
|
||||
printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]);
|
||||
return -1;
|
||||
}
|
||||
if (ddf->sector_size) {
|
||||
ddf->buffer = malloc(ddf->sector_size);
|
||||
//printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);
|
||||
//printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);
|
||||
if (!ddf->buffer)
|
||||
return -1;
|
||||
}
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize)
|
||||
{
|
||||
int err = 0;
|
||||
int BlockErase = BufferSize >= 8192;
|
||||
int i;
|
||||
|
||||
if (BlockErase) {
|
||||
for (i = 0; i < BufferSize; i += 8192 ) {
|
||||
uint8_t cmd[4];
|
||||
if ((i & 0xFFFF) == 0 )
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
cmd[0] = 0x50; // Block Erase
|
||||
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
err = flashio(dev,cmd,4,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
cmd[0] = 0xD7; // Read Status register
|
||||
err = flashio(dev,cmd,1,&cmd[0],1);
|
||||
if (err < 0 ) break;
|
||||
if ((cmd[0] & 0x80) == 0x80 ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < BufferSize; i += 1024) {
|
||||
uint8_t cmd[4 + 1024];
|
||||
if ((i & 0xFFFF) == 0 )
|
||||
{
|
||||
printf(" Program %08x\n",FlashOffset + i);
|
||||
}
|
||||
cmd[0] = 0x84; // Buffer 1
|
||||
cmd[1] = 0x00;
|
||||
cmd[2] = 0x00;
|
||||
cmd[3] = 0x00;
|
||||
memcpy(&cmd[4],&Buffer[i],1024);
|
||||
|
||||
err = flashio(dev,cmd,4 + 1024,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase)
|
||||
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
|
||||
err = flashio(dev,cmd,4,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
cmd[0] = 0xD7; // Read Status register
|
||||
err = flashio(dev,cmd,1,&cmd[0],1);
|
||||
if (err < 0 ) break;
|
||||
if ((cmd[0] & 0x80) == 0x80 ) break;
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize)
|
||||
{
|
||||
int err = 0;
|
||||
uint8_t cmd[6];
|
||||
int i, j;
|
||||
|
||||
// Must be multiple of sector size
|
||||
if ((BufferSize % 4096) != 0 )
|
||||
return -1;
|
||||
|
||||
do {
|
||||
cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev,cmd,1,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = 0x00; // BPx = 0, Unlock all blocks
|
||||
err = flashio(dev,cmd,2,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
for (i = 0; i < BufferSize; i += 4096 ) {
|
||||
if ((i & 0xFFFF) == 0 )
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev,cmd,1,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
cmd[0] = 0x20; // Sector erase ( 4Kb)
|
||||
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
err = flashio(dev,cmd,4,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev,cmd,1,&cmd[0],1);
|
||||
if (err < 0 ) break;
|
||||
if ((cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
}
|
||||
if (err < 0 )
|
||||
break;
|
||||
for (j = BufferSize - 4096; j >= 0; j -= 4096 ) {
|
||||
if ((j & 0xFFFF) == 0 )
|
||||
printf(" Program %08x\n",FlashOffset + j);
|
||||
|
||||
for (i = 0; i < 4096; i += 2 ) {
|
||||
if (i == 0 ) {
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev,cmd,1,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
cmd[0] = 0xAD; // AAI
|
||||
cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
cmd[4] = Buffer[j+i];
|
||||
cmd[5] = Buffer[j+i+1];
|
||||
err = flashio(dev,cmd,6,NULL,0);
|
||||
} else {
|
||||
cmd[0] = 0xAD; // AAI
|
||||
cmd[1] = Buffer[j+i];
|
||||
cmd[2] = Buffer[j+i+1];
|
||||
err = flashio(dev,cmd,3,NULL,0);
|
||||
}
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev,cmd,1,&cmd[0],1);
|
||||
if (err < 0 ) break;
|
||||
if ((cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
|
||||
cmd[0] = 0x04; // WDIS
|
||||
err = flashio(dev,cmd,1,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
|
||||
cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev,cmd,1,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = 0x1C; // BPx = 0, Lock all blocks
|
||||
err = flashio(dev,cmd,2,NULL,0);
|
||||
} while(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int get_id(struct ddflash *ddf) {
|
||||
uint8_t id[4];
|
||||
|
||||
@@ -517,19 +445,6 @@ static int get_id(struct ddflash *ddf) {
|
||||
ddf->id.subvendor, ddf->id.subdevice,
|
||||
ddf->id.hw, ddf->id.regmap);
|
||||
#endif
|
||||
if (ddf->id.device == 0x0011)
|
||||
ddf->type = 1;
|
||||
if (ddf->id.device == 0x0201)
|
||||
ddf->type = 2;
|
||||
if (ddf->id.device == 0x02)
|
||||
ddf->type = 3;
|
||||
if (ddf->id.device == 0x03)
|
||||
ddf->type = 0;
|
||||
if (ddf->id.device == 0x0300)
|
||||
ddf->type = 4;
|
||||
if (ddf->id.device == 0x0320)
|
||||
ddf->type = 5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -595,7 +510,12 @@ static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off)
|
||||
goto out;
|
||||
}
|
||||
} else if (!strcasecmp(key, "Version")) {
|
||||
sscanf(val, "%x", &version);
|
||||
if (strchr(val,'.')) {
|
||||
int major = 0, minor = 0;
|
||||
sscanf(val,"%d.%d",&major,&minor);
|
||||
version = (major << 16) + minor;
|
||||
} else
|
||||
sscanf(val, "%x", &version);
|
||||
} else if (!strcasecmp(key, "Length")) {
|
||||
sscanf(val, "%u", &length);
|
||||
}
|
||||
@@ -650,8 +570,13 @@ static int update_image(struct ddflash *ddf, char *fn,
|
||||
if (res < 0)
|
||||
goto out;
|
||||
res = flashwrite(ddf, fs, adr, len, fw_off);
|
||||
if (res == 0)
|
||||
res = 1;
|
||||
if (res == 0) {
|
||||
res = flashcmp(ddf, fs, adr, len, fw_off);
|
||||
if (res == -2) {
|
||||
res = 1;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
close(fs);
|
||||
return res;
|
||||
@@ -692,18 +617,40 @@ static int update_flash(struct ddflash *ddf)
|
||||
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
} else {
|
||||
if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
if (ddf->id.device == 0x0307) {
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
} else {
|
||||
if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
}
|
||||
}
|
||||
#if 1
|
||||
if ( (stat&1) && (ddf->id.hw & 0xffffff) <= 0x010001) {
|
||||
if (ddf->id.device == 0x0307) {
|
||||
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
} else {
|
||||
if ((res = update_image(ddf, "/config/fpga.img", 0x160000, 0x80000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/boot/fpga.img", 0x160000, 0x80000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
case 0x320:
|
||||
//fname="/boot/DVBNetV1A_DD01_0300.bit";
|
||||
@@ -777,6 +724,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
flash = flash_detect(&ddf);
|
||||
if (flash < 0)
|
||||
return -1;
|
||||
get_id(&ddf);
|
||||
|
||||
res = update_flash(&ddf);
|
||||
|
File diff suppressed because it is too large
Load Diff
614
apps/octonet/flash.c
Normal file
614
apps/octonet/flash.c
Normal 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, ®);
|
||||
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, ®);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
}
|
@@ -61,3 +61,5 @@ struct ddb_i2c_msg {
|
||||
#define IOCTL_DDB_WRITE_MDIO _IOR(DDB_MAGIC, 0x09, struct ddb_mdio)
|
||||
#define IOCTL_DDB_READ_I2C _IOWR(DDB_MAGIC, 0x0a, struct ddb_i2c_msg)
|
||||
#define IOCTL_DDB_WRITE_I2C _IOR(DDB_MAGIC, 0x0b, struct ddb_i2c_msg)
|
||||
|
||||
#include "flash.c"
|
||||
|
167
apps/pls.c
Normal file
167
apps/pls.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* pls.c: Convert between Gold and Root Codes for DVB-S2 PLS
|
||||
*
|
||||
* Copyright (C) 2017 Marcus Metzler <mocm@metzlerbros.de>
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* According to ETSI EN 302 307 5.5.4 the PLS (Physical Layer
|
||||
Scrambling) for DVB-S2 consists of a complex randomization
|
||||
sequence which is ultimately derived from two recursively
|
||||
defined m-sequences (=MLS or maximum length sequences)
|
||||
x(i) and y(i) of polynomials over GF(2) with m=18
|
||||
(thus their length is 2^18 - 1).
|
||||
These m-sequences with sequence y starting from y(0) and
|
||||
sequence x starting from x(n) are combined to form a set
|
||||
of 2^18 - 1 different Gold code sequences.
|
||||
|
||||
This starting number n of sequence x selects which
|
||||
of those 2^18 - 1 Gold code sequences to use.
|
||||
As a DVB-S2 tuning parameter n is called the scrambling sequence index
|
||||
(cf. ETSI EN 300 468 table 41) or Gold sequence index,
|
||||
commonly also just called "Gold code".
|
||||
The 18 values of the sequence x starting from x(n)
|
||||
(x(n) ... x(n+17)) are also called the "Root code".
|
||||
So, Gold and Root codes are not different ways of PLS, they are
|
||||
just different ways to select the same sequence start point.
|
||||
|
||||
The initial values for x(i), i=0..18 are x(0)=1, x(1)=0, .., x(17)=0 .
|
||||
The polynomial used for the x sequence recursion is 1+x^7+x^18.
|
||||
If the lower 18 bits of a variable "uint32_t X" contain x(n) ... x(n+17),
|
||||
then we can simply calculate x(n+1) ... x(n+18) by doing:
|
||||
X = (((X ^ (X >> 7)) & 1) << 17) | (X >> 1);
|
||||
|
||||
So, if X contained the "Root code" corresponding to "Gold code" n,
|
||||
it will now contain the "Root code" corresponding to "Gold code" (n+1).
|
||||
Note that X=0 and n=2^18 - 1 do not exist (or rather the lattter is the same
|
||||
as n = 0) and for n=0 to 2^18 - 2 and X=1 to 2^18 - 1 there is a
|
||||
one-to-one correspondence (bijection).
|
||||
|
||||
Note that PLS has nothing to do with encryption for DRM purposes. It is used
|
||||
to minimize interference between transponders.
|
||||
|
||||
|
||||
"Combo code":
|
||||
There is no such thing as a combo code. It is the result of a bug in older
|
||||
STV090x drivers which resulted in a crazy race condition between a Gold->Root
|
||||
conversion in the STV and an ongoing I2C write.
|
||||
Better forget about it and determine the proper Root or Gold code.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
static uint32_t gold2root(uint32_t gold)
|
||||
{
|
||||
uint32_t x, g;
|
||||
|
||||
for (g = 0, x = 1; g < gold; g++)
|
||||
x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1);
|
||||
return x;
|
||||
}
|
||||
|
||||
static uint32_t root2gold(uint32_t root)
|
||||
{
|
||||
uint32_t x, g;
|
||||
|
||||
for (g = 0, x = 1; g < 0x3ffff; g++) {
|
||||
if (root == x)
|
||||
return g;
|
||||
x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1);
|
||||
}
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
uint32_t gold = 0xffffffff, root = 0xffffffff;
|
||||
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
int c;
|
||||
static struct option long_options[] = {
|
||||
{"gold", required_argument, 0, 'g'},
|
||||
{"root", required_argument, 0, 'r'},
|
||||
{"help", no_argument , 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
c = getopt_long(argc, argv,
|
||||
"r:g:h",
|
||||
long_options, &option_index);
|
||||
if (c==-1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'g':
|
||||
gold = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'r':
|
||||
root = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'h':
|
||||
printf("pls -g gold_code\n");
|
||||
printf("or\n");
|
||||
printf("pls -r root_code\n");
|
||||
exit(-1);
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
if (optind < argc) {
|
||||
printf("Warning: unused arguments\n");
|
||||
}
|
||||
if (gold != 0xffffffff && root != 0xffffffff) {
|
||||
printf("Only specify root or gold code\n");
|
||||
exit(-1);
|
||||
};
|
||||
if (gold != 0xffffffff) {
|
||||
if (gold < 0x3ffff) {
|
||||
root = gold2root(gold);
|
||||
printf("gold = %llu (0x%05x) root = %llu (0x%05x)\n",
|
||||
gold, gold, root, root);
|
||||
} else
|
||||
printf("Invalid gold code specified.\n");
|
||||
exit(0);
|
||||
}
|
||||
if (root != 0xffffffff) {
|
||||
if (root > 0 && root < 0x40000)
|
||||
gold = root2gold(root);
|
||||
if (gold != 0xffffffff)
|
||||
printf("gold = %llu (0x%05x) root = %llu (0x%05x)\n",
|
||||
gold, gold, root, root);
|
||||
else
|
||||
printf("Invalid root code specified.\n");
|
||||
exit(0);
|
||||
}
|
||||
printf("Specify either root or gold code with -r or -g.\n");
|
||||
}
|
47
apps/setmod2.c
Normal file
47
apps/setmod2.c
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <linux/dvb/mod.h>
|
||||
|
||||
static int set_property(int fd, uint32_t cmd, uint32_t data)
|
||||
{
|
||||
struct dtv_property p;
|
||||
struct dtv_properties c;
|
||||
int ret;
|
||||
|
||||
p.cmd = cmd;
|
||||
c.num = 1;
|
||||
c.props = &p;
|
||||
p.u.data = data;
|
||||
ret = ioctl(fd, FE_SET_PROPERTY, &c);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "FE_SET_PROPERTY returned %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int fd;
|
||||
struct dvb_mod_params mp;
|
||||
struct dvb_mod_channel_params mc;
|
||||
|
||||
fd = open("/dev/dvb/adapter0/mod0", O_RDONLY);
|
||||
|
||||
set_property(fd, MODULATOR_MODULATION, QAM_256);
|
||||
set_property(fd, MODULATOR_SYMBOL_RATE, 6900000);
|
||||
set_property(fd, MODULATOR_FREQUENCY, 114000000);
|
||||
close(fd);
|
||||
}
|
||||
|
@@ -1,8 +1,11 @@
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843 -DCONFIG_DVB_LNBP21 -DCONFIG_DVB_STV090x -DCONFIG_DVB_STV6110x -DCONFIG_DVB_DRXK -DCONFIG_DVB_STV0910 -DCONFIG_DVB_STV6111 -DCONFIG_DVB_LNBH25 -DCONFIG_DVB_MXL5XX
|
||||
|
||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o
|
||||
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o
|
||||
|
||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -Idrivers/media/dvb-frontends
|
||||
EXTRA_CFLAGS += -Idrivers/media/common/tuners
|
||||
NOSTDINC_FLAGS += -I$(SUBDIRS)/frontends -I$(SUBDIRS)/include -I$(SUBDIRS)/dvb-core
|
||||
EXTRA_CFLAGS += -Idrivers/media/common/tuners
|
||||
NOSTDINC_FLAGS += -I$(SUBDIRS)/frontends -I$(SUBDIRS)/include -I$(SUBDIRS)/dvb-core
|
46
ddbridge/Kconfig
Normal file
46
ddbridge/Kconfig
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
config DVB_DDBRIDGE
|
||||
tristate "Digital Devices bridge support"
|
||||
depends on MEDIA_PCI_SUPPORT && DVB_CORE && PCI && I2C
|
||||
select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_TDA18212DD if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_STV0367DD if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_CXD2843 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT
|
||||
---help---
|
||||
Support for cards with the Digital Devices PCI express bridge:
|
||||
- Octopus PCIe Bridge
|
||||
- Octopus mini PCIe Bridge
|
||||
- Octopus LE
|
||||
- DuoFlex S2 Octopus
|
||||
- DuoFlex CT Octopus
|
||||
- cineS2(v6)
|
||||
|
||||
Say Y if you own such a card and want to use it.
|
||||
|
||||
|
||||
config DVB_OCTONET
|
||||
tristate "Digital Devices octonet support"
|
||||
depends on MEDIA_DIGITAL_TV_SUPPORT && DVB_CORE && I2C
|
||||
select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_TDA18212DD if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_STV0367DD if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_CXD2843 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_STV0910 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_STV6111 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT
|
||||
select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT
|
||||
---help---
|
||||
Support for OctopusNet
|
||||
|
||||
Say Y if you own such a card and want to use it.
|
@@ -1,19 +1,14 @@
|
||||
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
#
|
||||
# Makefile for the ddbridge device driver
|
||||
#
|
||||
|
||||
MODDEFS := CONFIG_DVB_DDBRIDGE=m
|
||||
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o
|
||||
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MODDEFS) modules
|
||||
$(MAKE) -C apps
|
||||
|
||||
dep:
|
||||
DIR=`pwd`; (cd $(TOPDIR); make SUBDIRS=$$DIR dep)
|
||||
|
||||
install: all
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
|
||||
|
||||
clean:
|
||||
rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
|
||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||
|
||||
ccflags-y += -Idrivers/media/dvb-core/
|
||||
ccflags-y += -Idrivers/media/dvb-frontends/
|
||||
ccflags-y += -Idrivers/media/tuners/
|
||||
|
||||
|
14
ddbridge/Makefile.kernel
Normal file
14
ddbridge/Makefile.kernel
Normal file
@@ -0,0 +1,14 @@
|
||||
#
|
||||
# Makefile for the ddbridge device driver
|
||||
#
|
||||
|
||||
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o
|
||||
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o
|
||||
|
||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||
|
||||
ccflags-y += -Idrivers/media/dvb-core/
|
||||
ccflags-y += -Idrivers/media/dvb-frontends/
|
||||
ccflags-y += -Idrivers/media/tuners/
|
||||
|
File diff suppressed because it is too large
Load Diff
704
ddbridge/ddbridge-hw.c
Normal file
704
ddbridge/ddbridge-hw.c
Normal file
@@ -0,0 +1,704 @@
|
||||
/*
|
||||
* ddbridge.c: Digital Devices PCIe bridge driver
|
||||
*
|
||||
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include "ddbridge.h"
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_regset octopus_mod_odma = {
|
||||
.base = 0x300,
|
||||
.num = 0x0a,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_mod_odma_buf = {
|
||||
.base = 0x2000,
|
||||
.num = 0x0a,
|
||||
.size = 0x100,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_mod_channel = {
|
||||
.base = 0x400,
|
||||
.num = 0x0a,
|
||||
.size = 0x40,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_regset octopus_mod_2_odma = {
|
||||
.base = 0x400,
|
||||
.num = 0x18,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_mod_2_odma_buf = {
|
||||
.base = 0x8000,
|
||||
.num = 0x18,
|
||||
.size = 0x100,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_mod_2_channel = {
|
||||
.base = 0x800,
|
||||
.num = 0x18,
|
||||
.size = 0x40,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_sdr_output = {
|
||||
.base = 0x240,
|
||||
.num = 0x14,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_regset octopus_input = {
|
||||
.base = 0x200,
|
||||
.num = 0x08,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_output = {
|
||||
.base = 0x280,
|
||||
.num = 0x08,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_idma = {
|
||||
.base = 0x300,
|
||||
.num = 0x08,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_idma_buf = {
|
||||
.base = 0x2000,
|
||||
.num = 0x08,
|
||||
.size = 0x100,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_odma = {
|
||||
.base = 0x380,
|
||||
.num = 0x04,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_odma_buf = {
|
||||
.base = 0x2800,
|
||||
.num = 0x04,
|
||||
.size = 0x100,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_i2c = {
|
||||
.base = 0x80,
|
||||
.num = 0x04,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_i2c_buf = {
|
||||
.base = 0x1000,
|
||||
.num = 0x04,
|
||||
.size = 0x200,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_regset octopro_input = {
|
||||
.base = 0x400,
|
||||
.num = 0x14,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopro_output = {
|
||||
.base = 0x600,
|
||||
.num = 0x0a,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopro_idma = {
|
||||
.base = 0x800,
|
||||
.num = 0x40,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopro_idma_buf = {
|
||||
.base = 0x4000,
|
||||
.num = 0x40,
|
||||
.size = 0x100,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopro_odma = {
|
||||
.base = 0xc00,
|
||||
.num = 0x20,
|
||||
.size = 0x10,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopro_odma_buf = {
|
||||
.base = 0x8000,
|
||||
.num = 0x20,
|
||||
.size = 0x100,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopro_i2c = {
|
||||
.base = 0x200,
|
||||
.num = 0x0a,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopro_i2c_buf = {
|
||||
.base = 0x2000,
|
||||
.num = 0x0a,
|
||||
.size = 0x200,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopro_gtl = {
|
||||
.base = 0xe00,
|
||||
.num = 0x03,
|
||||
.size = 0x40,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
static struct ddb_regmap octopus_map = {
|
||||
.irq_version = 1,
|
||||
.irq_base_i2c = 0,
|
||||
.irq_base_idma = 8,
|
||||
.irq_base_odma = 16,
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
.idma = &octopus_idma,
|
||||
.idma_buf = &octopus_idma_buf,
|
||||
.odma = &octopus_odma,
|
||||
.odma_buf = &octopus_odma_buf,
|
||||
.input = &octopus_input,
|
||||
.output = &octopus_output,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopro_map = {
|
||||
.irq_version = 2,
|
||||
.irq_base_i2c = 32,
|
||||
.irq_base_idma = 64,
|
||||
.irq_base_odma = 128,
|
||||
.irq_base_gtl = 8,
|
||||
.i2c = &octopro_i2c,
|
||||
.i2c_buf = &octopro_i2c_buf,
|
||||
.idma = &octopro_idma,
|
||||
.idma_buf = &octopro_idma_buf,
|
||||
.odma = &octopro_odma,
|
||||
.odma_buf = &octopro_odma_buf,
|
||||
.input = &octopro_input,
|
||||
.output = &octopro_output,
|
||||
.gtl = &octopro_gtl,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopro_hdin_map = {
|
||||
.irq_version = 2,
|
||||
.irq_base_i2c = 32,
|
||||
.irq_base_idma = 64,
|
||||
.irq_base_odma = 128,
|
||||
.i2c = &octopro_i2c,
|
||||
.i2c_buf = &octopro_i2c_buf,
|
||||
.idma = &octopro_idma,
|
||||
.idma_buf = &octopro_idma_buf,
|
||||
.odma = &octopro_odma,
|
||||
.odma_buf = &octopro_odma_buf,
|
||||
.input = &octopro_input,
|
||||
.output = &octopro_output,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_mod_map = {
|
||||
.irq_version = 1,
|
||||
.irq_base_odma = 8,
|
||||
.irq_base_rate = 18,
|
||||
.output = &octopus_output,
|
||||
.odma = &octopus_mod_odma,
|
||||
.odma_buf = &octopus_mod_odma_buf,
|
||||
.channel = &octopus_mod_channel,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_mod_2_map = {
|
||||
.irq_version = 2,
|
||||
.irq_base_odma = 64,
|
||||
.irq_base_rate = 32,
|
||||
.output = &octopus_output,
|
||||
.odma = &octopus_mod_2_odma,
|
||||
.odma_buf = &octopus_mod_2_odma_buf,
|
||||
.channel = &octopus_mod_2_channel,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_sdr_map = {
|
||||
.irq_version = 2,
|
||||
.irq_base_odma = 64,
|
||||
.irq_base_rate = 32,
|
||||
.output = &octopus_sdr_output,
|
||||
.odma = &octopus_mod_2_odma,
|
||||
.odma_buf = &octopus_mod_2_odma_buf,
|
||||
.channel = &octopus_mod_2_channel,
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_info ddb_none = {
|
||||
.type = DDB_NONE,
|
||||
.name = "unknown Digital Devices device, install newer driver",
|
||||
.regmap = &octopus_map,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopusv3 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus V3 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_le = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus LE DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 2,
|
||||
.i2c_mask = 0x03,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_oem = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus OEM",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.led_num = 1,
|
||||
.fan_num = 1,
|
||||
.temp_num = 1,
|
||||
.temp_bus = 0,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_mini = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus Mini",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_v6 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine S2 V6 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x07,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_v6_5 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine S2 V6.5 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_v7a = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine S2 V7 Advanced DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 2,
|
||||
.board_control_2 = 4,
|
||||
.ts_quirks = TS_QUIRK_REVERSED,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_v7 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine S2 V7 DVB adapter",
|
||||
.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_ctv7 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine CT V7 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 3,
|
||||
.board_control_2 = 4,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_satixS2v3 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Mystique SaTiX-S2 V3 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x07,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ci = {
|
||||
.type = DDB_OCTOPUS_CI,
|
||||
.name = "Digital Devices Octopus CI",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x03,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_cis = {
|
||||
.type = DDB_OCTOPUS_CI,
|
||||
.name = "Digital Devices Octopus CI single",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x03,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ci_s2_pro = {
|
||||
.type = DDB_OCTOPUS_CI,
|
||||
.name = "Digital Devices Octopus CI S2 Pro",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 2,
|
||||
.board_control_2 = 4,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ci_s2_pro_a = {
|
||||
.type = DDB_OCTOPUS_CI,
|
||||
.name = "Digital Devices Octopus CI S2 Pro Advanced",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 2,
|
||||
.board_control_2 = 4,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_dvbct = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices DVBCT V6.1 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x07,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_info ddb_mod = {
|
||||
.type = DDB_MOD,
|
||||
.name = "Digital Devices DVB-C modulator",
|
||||
.regmap = &octopus_mod_map,
|
||||
.port_num = 10,
|
||||
.temp_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_mod_fsm_24 = {
|
||||
.type = DDB_MOD,
|
||||
.version = 2,
|
||||
.name = "Digital Devices DVB-C modulator FSM-24",
|
||||
.regmap = &octopus_mod_2_map,
|
||||
.port_num = 24,
|
||||
.temp_num = 1,
|
||||
.tempmon_irq = 8,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_mod_fsm_16 = {
|
||||
.type = DDB_MOD,
|
||||
.version = 2,
|
||||
.name = "Digital Devices DVB-C modulator FSM-16",
|
||||
.regmap = &octopus_mod_2_map,
|
||||
.port_num = 16,
|
||||
.temp_num = 1,
|
||||
.tempmon_irq = 8,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_mod_fsm_8 = {
|
||||
.type = DDB_MOD,
|
||||
.name = "Digital Devices DVB-C modulator FSM-8",
|
||||
.version = 2,
|
||||
.regmap = &octopus_mod_2_map,
|
||||
.port_num = 8,
|
||||
.temp_num = 1,
|
||||
.tempmon_irq = 8,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_sdr = {
|
||||
.type = DDB_MOD,
|
||||
.name = "Digital Devices SDR",
|
||||
.version = 3,
|
||||
.regmap = &octopus_sdr_map,
|
||||
.port_num = 16,
|
||||
.temp_num = 1,
|
||||
.tempmon_irq = 8,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopro_hdin = {
|
||||
.type = DDB_OCTOPRO_HDIN,
|
||||
.name = "Digital Devices OctopusNet Pro HDIN",
|
||||
.regmap = &octopro_hdin_map,
|
||||
.port_num = 10,
|
||||
.i2c_mask = 0x3ff,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopro = {
|
||||
.type = DDB_OCTOPRO,
|
||||
.name = "Digital Devices OctopusNet Pro",
|
||||
.regmap = &octopro_map,
|
||||
.port_num = 10,
|
||||
.i2c_mask = 0x3ff,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
|
||||
static struct ddb_info ddb_s2_48 = {
|
||||
.type = DDB_OCTOPUS_MAX,
|
||||
.name = "Digital Devices MAX S8 4/8",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 1,
|
||||
.tempmon_irq = 24,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ct2_8 = {
|
||||
.type = DDB_OCTOPUS_MAX_CT,
|
||||
.name = "Digital Devices MAX A8 CT2",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 0x0ff,
|
||||
.board_control_2 = 0xf00,
|
||||
.ts_quirks = TS_QUIRK_SERIAL,
|
||||
.tempmon_irq = 24,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_c2t2_8 = {
|
||||
.type = DDB_OCTOPUS_MAX_CT,
|
||||
.name = "Digital Devices MAX A8 C2T2",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 0x0ff,
|
||||
.board_control_2 = 0xf00,
|
||||
.ts_quirks = TS_QUIRK_SERIAL,
|
||||
.tempmon_irq = 24,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_isdbt_8 = {
|
||||
.type = DDB_OCTOPUS_MAX_CT,
|
||||
.name = "Digital Devices MAX A8 ISDBT",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 0x0ff,
|
||||
.board_control_2 = 0xf00,
|
||||
.ts_quirks = TS_QUIRK_SERIAL,
|
||||
.tempmon_irq = 24,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_c2t2i_v0_8 = {
|
||||
.type = DDB_OCTOPUS_MAX_CT,
|
||||
.name = "Digital Devices MAX A8 C2T2I V0",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 0x0ff,
|
||||
.board_control_2 = 0xf00,
|
||||
.ts_quirks = TS_QUIRK_SERIAL | TS_QUIRK_ALT_OSC,
|
||||
.tempmon_irq = 24,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_c2t2i_8 = {
|
||||
.type = DDB_OCTOPUS_MAX_CT,
|
||||
.name = "Digital Devices MAX A8 C2T2I",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 0x0ff,
|
||||
.board_control_2 = 0xf00,
|
||||
.ts_quirks = TS_QUIRK_SERIAL,
|
||||
.tempmon_irq = 24,
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_regmap octopus_net_map = {
|
||||
.irq_version = 1,
|
||||
.irq_base_i2c = 0,
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
.input = &octopus_input,
|
||||
.output = &octopus_output,
|
||||
};
|
||||
|
||||
|
||||
static struct ddb_regset octopus_gtl = {
|
||||
.base = 0x180,
|
||||
.num = 0x01,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_net_gtl = {
|
||||
.irq_version = 1,
|
||||
.irq_base_i2c = 0,
|
||||
.irq_base_gtl = 10,
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
.input = &octopus_input,
|
||||
.output = &octopus_output,
|
||||
.gtl = &octopus_gtl,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet network DVB adapter",
|
||||
.regmap = &octopus_net_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet_jse = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet network DVB adapter JSE",
|
||||
.regmap = &octopus_net_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.ns_num = 15,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet_gtl = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet GTL",
|
||||
.regmap = &octopus_net_gtl,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x05,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
.con_clock = 1,
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
struct ddb_device_id {
|
||||
u16 vendor;
|
||||
u16 device;
|
||||
u16 subvendor;
|
||||
u16 subdevice;
|
||||
struct ddb_info *info;
|
||||
};
|
||||
|
||||
#define DDB_DEVID(_device, _subdevice, _info) { \
|
||||
.vendor = 0xdd01, \
|
||||
.device = _device, \
|
||||
.subvendor = 0xdd01, \
|
||||
.subdevice = _subdevice, \
|
||||
.info = &_info }
|
||||
|
||||
static struct ddb_device_id ddb_device_ids[] = {
|
||||
/* OctopusNet */
|
||||
DDB_DEVID(0x0300, 0xffff, ddb_octonet),
|
||||
DDB_DEVID(0x0301, 0xffff, ddb_octonet_jse),
|
||||
DDB_DEVID(0x0307, 0xffff, ddb_octonet_gtl),
|
||||
/* PCIe devices */
|
||||
DDB_DEVID(0x0002, 0x0001, ddb_octopus),
|
||||
DDB_DEVID(0x0003, 0x0001, ddb_octopus),
|
||||
DDB_DEVID(0x0005, 0x0004, ddb_octopusv3),
|
||||
DDB_DEVID(0x0003, 0x0002, ddb_octopus_le),
|
||||
DDB_DEVID(0x0003, 0x0003, ddb_octopus_oem),
|
||||
DDB_DEVID(0x0003, 0x0010, ddb_octopus_mini),
|
||||
DDB_DEVID(0x0005, 0x0011, ddb_octopus_mini),
|
||||
DDB_DEVID(0x0003, 0x0020, ddb_v6),
|
||||
DDB_DEVID(0x0003, 0x0021, ddb_v6_5),
|
||||
DDB_DEVID(0x0006, 0x0022, ddb_v7),
|
||||
DDB_DEVID(0x0006, 0x0024, ddb_v7a),
|
||||
DDB_DEVID(0x0003, 0x0030, ddb_dvbct),
|
||||
DDB_DEVID(0x0003, 0xdb03, ddb_satixS2v3),
|
||||
DDB_DEVID(0x0006, 0x0031, ddb_ctv7),
|
||||
DDB_DEVID(0x0006, 0x0032, ddb_ctv7),
|
||||
DDB_DEVID(0x0006, 0x0033, ddb_ctv7),
|
||||
DDB_DEVID(0x0007, 0x0023, ddb_s2_48),
|
||||
DDB_DEVID(0x0008, 0x0034, ddb_ct2_8),
|
||||
DDB_DEVID(0x0008, 0x0035, ddb_c2t2_8),
|
||||
DDB_DEVID(0x0008, 0x0036, ddb_isdbt_8),
|
||||
DDB_DEVID(0x0008, 0x0037, ddb_c2t2i_v0_8),
|
||||
DDB_DEVID(0x0008, 0x0038, ddb_c2t2i_8),
|
||||
DDB_DEVID(0x0006, 0x0039, ddb_ctv7),
|
||||
DDB_DEVID(0x0011, 0x0040, ddb_ci),
|
||||
DDB_DEVID(0x0011, 0x0041, ddb_cis),
|
||||
DDB_DEVID(0x0012, 0x0042, ddb_ci),
|
||||
DDB_DEVID(0x0013, 0x0043, ddb_ci_s2_pro),
|
||||
DDB_DEVID(0x0013, 0x0044, ddb_ci_s2_pro_a),
|
||||
DDB_DEVID(0x0201, 0x0001, ddb_mod),
|
||||
DDB_DEVID(0x0201, 0x0002, ddb_mod),
|
||||
DDB_DEVID(0x0203, 0x0001, ddb_mod),
|
||||
DDB_DEVID(0x0210, 0x0001, ddb_mod_fsm_24),
|
||||
DDB_DEVID(0x0210, 0x0002, ddb_mod_fsm_16),
|
||||
DDB_DEVID(0x0210, 0x0003, ddb_mod_fsm_8),
|
||||
DDB_DEVID(0x0220, 0x0001, ddb_sdr),
|
||||
/* testing on OctopusNet Pro */
|
||||
DDB_DEVID(0x0320, 0xffff, ddb_octopro_hdin),
|
||||
DDB_DEVID(0x0321, 0xffff, ddb_none),
|
||||
DDB_DEVID(0x0322, 0xffff, ddb_octopro),
|
||||
DDB_DEVID(0x0323, 0xffff, ddb_none),
|
||||
DDB_DEVID(0x0328, 0xffff, ddb_none),
|
||||
DDB_DEVID(0x0329, 0xffff, ddb_octopro_hdin),
|
||||
};
|
||||
|
||||
struct ddb_info *get_ddb_info(u16 vendor, u16 device, u16 subvendor, u16 subdevice)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ddb_device_ids); i++) {
|
||||
struct ddb_device_id *id = &ddb_device_ids[i];
|
||||
|
||||
if (vendor == id->vendor &&
|
||||
device == id->device &&
|
||||
subvendor == id->subvendor &&
|
||||
((subdevice == id->subdevice) ||
|
||||
id->subdevice == 0xffff))
|
||||
return id->info;
|
||||
}
|
||||
return &ddb_none;
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ddbridge-i2c.c: Digital Devices bridge i2c driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
*
|
||||
@@ -23,87 +23,8 @@
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
static int i2c_io(struct i2c_adapter *adapter, u8 adr,
|
||||
u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = wbuf, .len = wlen },
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = rbuf, .len = rlen } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
|
||||
{
|
||||
struct i2c_msg msg = {.addr = adr, .flags = 0,
|
||||
.buf = data, .len = len};
|
||||
|
||||
return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
|
||||
{
|
||||
struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1 } };
|
||||
return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_read_regs(struct i2c_adapter *adapter,
|
||||
u8 adr, u8 reg, u8 *val, u8 len)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = ®, .len = 1 },
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = len } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_read_regs16(struct i2c_adapter *adapter,
|
||||
u8 adr, u16 reg, u8 *val, u8 len)
|
||||
{
|
||||
u8 reg16[2] = { reg >> 8, reg };
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = reg16, .len = 2 },
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = len } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = ®, .len = 1},
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1 } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
|
||||
u16 reg, u8 *val)
|
||||
{
|
||||
u8 msg[2] = {reg >> 8, reg & 0xff};
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = msg, .len = 2},
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1 } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr,
|
||||
u16 reg, u8 val)
|
||||
{
|
||||
u8 msg[3] = {reg >> 8, reg & 0xff, val};
|
||||
|
||||
return i2c_write(adap, adr, msg, 3);
|
||||
}
|
||||
|
||||
static int i2c_write_reg(struct i2c_adapter *adap, u8 adr,
|
||||
u8 reg, u8 val)
|
||||
{
|
||||
u8 msg[2] = {reg, val};
|
||||
|
||||
return i2c_write(adap, adr, msg, 2);
|
||||
}
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-io.h"
|
||||
|
||||
static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
|
||||
{
|
||||
@@ -113,20 +34,37 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
|
||||
|
||||
ddbwritel(dev, (adr << 9) | cmd, i2c->regs + I2C_COMMAND);
|
||||
stat = wait_for_completion_timeout(&i2c->completion, HZ);
|
||||
val = ddbreadl(dev, i2c->regs + I2C_COMMAND);
|
||||
if (stat == 0) {
|
||||
pr_err("DDBridge I2C timeout, card %d, port %d, link %u\n",
|
||||
pr_err("DDBridge: I2C timeout, card %d, port %d, link %u\n",
|
||||
dev->nr, i2c->nr, i2c->link);
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
{ /* MSI debugging*/
|
||||
#if 1
|
||||
{
|
||||
u32 istat = ddbreadl(dev, INTERRUPT_STATUS);
|
||||
|
||||
dev_err(dev->dev, "DDBridge IRS %08x\n", istat);
|
||||
ddbwritel(dev, istat, INTERRUPT_ACK);
|
||||
if (i2c->link) {
|
||||
u32 listat =
|
||||
ddbreadl(dev,
|
||||
DDB_LINK_TAG(i2c->link) |
|
||||
INTERRUPT_STATUS);
|
||||
dev_err(dev->dev,
|
||||
"DDBridge link %u IRS %08x\n",
|
||||
i2c->link, listat);
|
||||
}
|
||||
if (istat & 1) {
|
||||
ddbwritel(dev, istat & 1, INTERRUPT_ACK);
|
||||
} else {
|
||||
u32 mon = ddbreadl(dev,
|
||||
i2c->regs + I2C_MONITOR);
|
||||
|
||||
dev_err(dev->dev, "I2C cmd=%08x mon=%08x\n",
|
||||
val, mon);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return -EIO;
|
||||
}
|
||||
val = ddbreadl(dev, i2c->regs + I2C_COMMAND);
|
||||
if (val & 0x70000)
|
||||
return -EIO;
|
||||
return 0;
|
||||
@@ -138,39 +76,44 @@ static int ddb_i2c_master_xfer(struct i2c_adapter *adapter,
|
||||
struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter);
|
||||
struct ddb *dev = i2c->dev;
|
||||
u8 addr = 0;
|
||||
|
||||
if (num != 1 && num != 2)
|
||||
return -EIO;
|
||||
|
||||
addr = msg[0].addr;
|
||||
if (msg[0].len > i2c->bsize)
|
||||
return -EIO;
|
||||
if (num == 2 && msg[1].flags & I2C_M_RD &&
|
||||
!(msg[0].flags & I2C_M_RD)) {
|
||||
if (msg[1].len > i2c->bsize)
|
||||
return -EIO;
|
||||
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
|
||||
ddbwritel(dev, msg[0].len | (msg[1].len << 16),
|
||||
i2c->regs + I2C_TASKLENGTH);
|
||||
if (!ddb_i2c_cmd(i2c, addr, 1)) {
|
||||
ddbcpyfrom(dev, msg[1].buf,
|
||||
i2c->rbuf,
|
||||
msg[1].len);
|
||||
return num;
|
||||
}
|
||||
}
|
||||
if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
|
||||
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
|
||||
ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH);
|
||||
if (!ddb_i2c_cmd(i2c, addr, 2))
|
||||
return num;
|
||||
}
|
||||
if (num == 1 && (msg[0].flags & I2C_M_RD)) {
|
||||
ddbwritel(dev, msg[0].len << 16, i2c->regs + I2C_TASKLENGTH);
|
||||
if (!ddb_i2c_cmd(i2c, addr, 3)) {
|
||||
switch (num) {
|
||||
case 1:
|
||||
if (msg[0].flags & I2C_M_RD) {
|
||||
ddbwritel(dev, msg[0].len << 16,
|
||||
i2c->regs + I2C_TASKLENGTH);
|
||||
if (ddb_i2c_cmd(i2c, addr, 3))
|
||||
break;
|
||||
ddbcpyfrom(dev, msg[0].buf,
|
||||
i2c->rbuf, msg[0].len);
|
||||
return num;
|
||||
}
|
||||
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
|
||||
ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH);
|
||||
if (ddb_i2c_cmd(i2c, addr, 2))
|
||||
break;
|
||||
return num;
|
||||
case 2:
|
||||
if ((msg[0].flags & I2C_M_RD) == I2C_M_RD)
|
||||
break;
|
||||
if ((msg[1].flags & I2C_M_RD) != I2C_M_RD)
|
||||
break;
|
||||
if (msg[1].len > i2c->bsize)
|
||||
break;
|
||||
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
|
||||
ddbwritel(dev, msg[0].len | (msg[1].len << 16),
|
||||
i2c->regs + I2C_TASKLENGTH);
|
||||
if (ddb_i2c_cmd(i2c, addr, 1))
|
||||
break;
|
||||
ddbcpyfrom(dev, msg[1].buf,
|
||||
i2c->rbuf,
|
||||
msg[1].len);
|
||||
return num;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
@@ -185,7 +128,7 @@ struct i2c_algorithm ddb_i2c_algo = {
|
||||
.functionality = ddb_i2c_functionality,
|
||||
};
|
||||
|
||||
static void ddb_i2c_release(struct ddb *dev)
|
||||
void ddb_i2c_release(struct ddb *dev)
|
||||
{
|
||||
int i;
|
||||
struct ddb_i2c *i2c;
|
||||
@@ -207,19 +150,20 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
|
||||
struct ddb_regmap *regmap, int link, int i, int num)
|
||||
{
|
||||
struct i2c_adapter *adap;
|
||||
|
||||
|
||||
i2c->nr = i;
|
||||
i2c->dev = dev;
|
||||
i2c->link = link;
|
||||
i2c->bsize = regmap->i2c_buf->size;
|
||||
i2c->wbuf = DDB_LINK_TAG(link) | (regmap->i2c_buf->base + i2c->bsize * i);
|
||||
i2c->rbuf = i2c->wbuf;// + i2c->bsize / 2;
|
||||
i2c->regs = DDB_LINK_TAG(link) | (regmap->i2c->base + regmap->i2c->size * i);
|
||||
i2c->wbuf = DDB_LINK_TAG(link) |
|
||||
(regmap->i2c_buf->base + i2c->bsize * i);
|
||||
i2c->rbuf = i2c->wbuf;/* + i2c->bsize / 2; */
|
||||
i2c->regs = DDB_LINK_TAG(link) |
|
||||
(regmap->i2c->base + regmap->i2c->size * i);
|
||||
ddbwritel(dev, I2C_SPEED_100, i2c->regs + I2C_TIMING);
|
||||
ddbwritel(dev, ((i2c->rbuf & 0xffff) << 16) | (i2c->wbuf & 0xffff),
|
||||
i2c->regs + I2C_TASKADDRESS);
|
||||
init_completion(&i2c->completion);
|
||||
|
||||
adap = &i2c->adap;
|
||||
i2c_set_adapdata(adap, i2c);
|
||||
#ifdef I2C_ADAP_CLASS_TV_DIGITAL
|
||||
@@ -229,33 +173,35 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
|
||||
adap->class = I2C_CLASS_TV_ANALOG;
|
||||
#endif
|
||||
#endif
|
||||
strcpy(adap->name, "ddbridge");
|
||||
snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x",
|
||||
dev->nr, i2c->link, i);
|
||||
adap->algo = &ddb_i2c_algo;
|
||||
adap->algo_data = (void *)i2c;
|
||||
adap->algo_data = (void *) i2c;
|
||||
adap->dev.parent = dev->dev;
|
||||
return i2c_add_adapter(adap);
|
||||
}
|
||||
|
||||
static int ddb_i2c_init(struct ddb *dev)
|
||||
int ddb_i2c_init(struct ddb *dev)
|
||||
{
|
||||
int stat = 0;
|
||||
u32 i, j, num = 0, l;
|
||||
u32 i, j, num = 0, l, base;
|
||||
struct ddb_i2c *i2c;
|
||||
struct i2c_adapter *adap;
|
||||
struct ddb_regmap *regmap;
|
||||
|
||||
|
||||
for (l = 0; l < DDB_MAX_LINK; l++) {
|
||||
if (!dev->link[l].info)
|
||||
continue;
|
||||
regmap = dev->link[l].info->regmap;
|
||||
if (!regmap || !regmap->i2c)
|
||||
continue;
|
||||
base = regmap->irq_base_i2c;
|
||||
for (i = 0; i < regmap->i2c->num; i++) {
|
||||
if (!(dev->link[l].info->i2c_mask & (1 << i)))
|
||||
continue;
|
||||
i2c = &dev->i2c[num];
|
||||
dev->handler_data[i + l * 32] = (unsigned long) i2c;
|
||||
dev->handler[i + l * 32] = i2c_handler;
|
||||
dev->handler_data[l][i + base] = (unsigned long) i2c;
|
||||
dev->handler[l][i + base] = i2c_handler;
|
||||
stat = ddb_i2c_add(dev, i2c, regmap, l, i, num);
|
||||
if (stat)
|
||||
break;
|
||||
@@ -268,7 +214,7 @@ static int ddb_i2c_init(struct ddb *dev)
|
||||
adap = &i2c->adap;
|
||||
i2c_del_adapter(adap);
|
||||
}
|
||||
} else
|
||||
} else
|
||||
dev->i2c_num = num;
|
||||
return stat;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ddbridge-i2c.h: Digital Devices bridge i2c driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
*
|
||||
|
183
ddbridge/ddbridge-io.c
Normal file
183
ddbridge/ddbridge-io.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* ddbridge-io.c: Digital Devices bridge I/O functions
|
||||
*
|
||||
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-io.h"
|
||||
|
||||
u32 ddblreadl(struct ddb_link *link, u32 adr)
|
||||
{
|
||||
if (unlikely(link->nr)) {
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
|
||||
ddbwritel0(link, 3, link->regs + 0x10);
|
||||
gtlw(link);
|
||||
val = ddbreadl0(link, link->regs + 0x1c);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return val;
|
||||
}
|
||||
return readl((char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
void ddblwritel(struct ddb_link *link, u32 val, u32 adr)
|
||||
{
|
||||
if (unlikely(link->nr)) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
|
||||
ddbwritel0(link, val, link->regs + 0x18);
|
||||
ddbwritel0(link, 1, link->regs + 0x10);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return;
|
||||
}
|
||||
writel(val, (char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
u32 ddbreadl(struct ddb *dev, u32 adr)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000)) {
|
||||
unsigned long flags;
|
||||
u32 val, l = (adr >> DDB_LINK_SHIFT);
|
||||
struct ddb_link *link = &dev->link[l];
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
|
||||
ddbwritel0(link, 3, link->regs + 0x10);
|
||||
gtlw(link);
|
||||
val = ddbreadl0(link, link->regs + 0x1c);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return val;
|
||||
}
|
||||
return readl((char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
void ddbwritel(struct ddb *dev, u32 val, u32 adr)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000)) {
|
||||
unsigned long flags;
|
||||
u32 l = (adr >> DDB_LINK_SHIFT);
|
||||
struct ddb_link *link = &dev->link[l];
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
|
||||
ddbwritel0(link, val, link->regs + 0x18);
|
||||
ddbwritel0(link, 1, link->regs + 0x10);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return;
|
||||
}
|
||||
writel(val, (char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf,
|
||||
unsigned int count)
|
||||
{
|
||||
u32 val = 0, p = adr;
|
||||
u32 aa = p & 3;
|
||||
|
||||
if (aa) {
|
||||
while (p & 3 && count) {
|
||||
val >>= 8;
|
||||
val |= *buf << 24;
|
||||
p++;
|
||||
buf++;
|
||||
count--;
|
||||
}
|
||||
ddbwritel(dev, val, adr);
|
||||
}
|
||||
while (count >= 4) {
|
||||
val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
||||
ddbwritel(dev, val, p);
|
||||
p += 4;
|
||||
buf += 4;
|
||||
count -= 4;
|
||||
}
|
||||
if (count) {
|
||||
val = buf[0];
|
||||
if (count > 1)
|
||||
val |= buf[1] << 8;
|
||||
if (count > 2)
|
||||
val |= buf[2] << 16;
|
||||
ddbwritel(dev, val, p);
|
||||
}
|
||||
}
|
||||
|
||||
void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count)
|
||||
{
|
||||
u32 val = 0, p = adr;
|
||||
u32 a = p & 3;
|
||||
|
||||
if (a) {
|
||||
val = ddbreadl(dev, p) >> (8 * a);
|
||||
while (p & 3 && count) {
|
||||
*buf = val & 0xff;
|
||||
val >>= 8;
|
||||
p++;
|
||||
buf++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
while (count >= 4) {
|
||||
val = ddbreadl(dev, p);
|
||||
buf[0] = val & 0xff;
|
||||
buf[1] = (val >> 8) & 0xff;
|
||||
buf[2] = (val >> 16) & 0xff;
|
||||
buf[3] = (val >> 24) & 0xff;
|
||||
p += 4;
|
||||
buf += 4;
|
||||
count -= 4;
|
||||
}
|
||||
if (count) {
|
||||
val = ddbreadl(dev, p);
|
||||
buf[0] = val & 0xff;
|
||||
if (count > 1)
|
||||
buf[1] = (val >> 8) & 0xff;
|
||||
if (count > 2)
|
||||
buf[2] = (val >> 16) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000))
|
||||
return gtlcpyto(dev, adr, src, count);
|
||||
return memcpy_toio((char *) (dev->regs + adr), src, count);
|
||||
}
|
||||
|
||||
void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000))
|
||||
return gtlcpyfrom(dev, dst, adr, count);
|
||||
return memcpy_fromio(dst, (char *) (dev->regs + adr), count);
|
||||
}
|
||||
|
||||
|
||||
|
89
ddbridge/ddbridge-io.h
Normal file
89
ddbridge/ddbridge-io.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* ddbridge-io.h: Digital Devices bridge I/O functions
|
||||
*
|
||||
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
#ifndef _DDBRIDGE_IO_H_
|
||||
#define _DDBRIDGE_IO_H_
|
||||
|
||||
u32 ddblreadl(struct ddb_link *link, u32 adr);
|
||||
void ddblwritel(struct ddb_link *link, u32 val, u32 adr);
|
||||
u32 ddbreadl(struct ddb *dev, u32 adr);
|
||||
void ddbwritel(struct ddb *dev, u32 val, u32 adr);
|
||||
void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf,
|
||||
unsigned int count);
|
||||
void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count);
|
||||
void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count);
|
||||
void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count);
|
||||
|
||||
static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr)
|
||||
{
|
||||
writeb(val, (char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static inline u32 ddbreadb(struct ddb *dev, u32 adr)
|
||||
{
|
||||
return readb((char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static inline void ddbwritel0(struct ddb_link *link, u32 val, u32 adr)
|
||||
{
|
||||
writel(val, (char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static inline u32 ddbreadl0(struct ddb_link *link, u32 adr)
|
||||
{
|
||||
return readl((char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline void gtlw(struct ddb_link *link)
|
||||
{
|
||||
u32 count = 0;
|
||||
static u32 max;
|
||||
|
||||
while (1 & ddbreadl0(link, link->regs + 0x10)) {
|
||||
if (++count == 1024) {
|
||||
pr_info("LTO\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count > max) {
|
||||
max = count;
|
||||
pr_info("TO=%u\n", max);
|
||||
}
|
||||
if (ddbreadl0(link, link->regs + 0x10) & 0x8000)
|
||||
pr_err("link error\n");
|
||||
}
|
||||
#else
|
||||
static inline void gtlw(struct ddb_link *link)
|
||||
{
|
||||
while (1 & ddbreadl0(link, link->regs + 0x10))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define ddbmemset(_dev, _adr, _val, _count) \
|
||||
memset_io((char *) (_dev->regs + (_adr)), (_val), (_count))
|
||||
|
||||
#endif
|
388
ddbridge/ddbridge-main.c
Normal file
388
ddbridge/ddbridge-main.c
Normal file
@@ -0,0 +1,388 @@
|
||||
/*
|
||||
* ddbridge.c: Digital Devices PCIe bridge driver
|
||||
*
|
||||
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-io.h"
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
static int msi = 1;
|
||||
module_param(msi, int, 0444);
|
||||
MODULE_PARM_DESC(msi,
|
||||
" Control MSI interrupts: 0-disable, 1-enable (default)");
|
||||
#endif
|
||||
|
||||
extern struct workqueue_struct *ddb_wq;
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static void __devexit ddb_irq_disable(struct ddb *dev)
|
||||
{
|
||||
if (dev->link[0].info->regmap->irq_version == 2) {
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_2);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_3);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_4);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_5);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_6);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_7);
|
||||
} else {
|
||||
ddbwritel(dev, 0, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0, MSI1_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
static void __devexit ddb_irq_exit(struct ddb *dev)
|
||||
{
|
||||
ddb_irq_disable(dev);
|
||||
if (dev->msi == 2)
|
||||
free_irq(dev->pdev->irq + 1, dev);
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
if (dev->msi)
|
||||
pci_disable_msi(dev->pdev);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __devexit ddb_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev);
|
||||
|
||||
ddb_device_destroy(dev);
|
||||
ddb_nsd_detach(dev);
|
||||
ddb_ports_detach(dev);
|
||||
ddb_i2c_release(dev);
|
||||
|
||||
if (dev->link[0].info->ns_num)
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
ddb_irq_exit(dev);
|
||||
ddb_ports_release(dev);
|
||||
ddb_buffers_free(dev);
|
||||
|
||||
ddb_unmap(dev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
|
||||
#define __devinit
|
||||
#define __devinitdata
|
||||
#endif
|
||||
|
||||
static int __devinit ddb_irq_msi(struct ddb *dev, int nr)
|
||||
{
|
||||
int stat = 0;
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
if (msi && pci_msi_enabled()) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
|
||||
stat = pci_alloc_irq_vectors(dev->pdev, 1, nr, PCI_IRQ_MSI);
|
||||
#else
|
||||
stat = pci_enable_msi_range(dev->pdev, 1, nr);
|
||||
#endif
|
||||
if (stat >= 1) {
|
||||
dev->msi = stat;
|
||||
pr_info("DDBridge: using %d MSI interrupt(s)\n",
|
||||
dev->msi);
|
||||
} else
|
||||
pr_info("DDBridge: MSI not available.\n");
|
||||
|
||||
#else
|
||||
stat = pci_enable_msi_block(dev->pdev, nr);
|
||||
if (stat == 0) {
|
||||
dev->msi = nr;
|
||||
pr_info("DDBridge: using %d MSI interrupts\n", nr);
|
||||
} else if (stat == 1) {
|
||||
stat = pci_enable_msi(dev->pdev);
|
||||
dev->msi = 1;
|
||||
}
|
||||
if (stat < 0)
|
||||
pr_info("DDBridge: MSI not available.\n");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int __devinit ddb_irq_init2(struct ddb *dev)
|
||||
{
|
||||
int stat;
|
||||
int irq_flag = IRQF_SHARED;
|
||||
|
||||
pr_info("DDBridge: init type 2 IRQ hardware block\n");
|
||||
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_2);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_3);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_4);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_5);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_6);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_7);
|
||||
|
||||
ddb_irq_msi(dev, 1);
|
||||
if (dev->msi)
|
||||
irq_flag = 0;
|
||||
|
||||
stat = request_irq(dev->pdev->irq, irq_handler_v2,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0)
|
||||
return stat;
|
||||
|
||||
ddbwritel(dev, 0x0000ff7f, INTERRUPT_V2_CONTROL);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_1);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_2);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_3);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_4);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_5);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_6);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_7);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int __devinit ddb_irq_init(struct ddb *dev)
|
||||
{
|
||||
int stat;
|
||||
int irq_flag = IRQF_SHARED;
|
||||
|
||||
if (dev->link[0].info->regmap->irq_version == 2)
|
||||
return ddb_irq_init2(dev);
|
||||
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI2_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI3_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI4_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI5_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI6_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI7_ENABLE);
|
||||
|
||||
ddb_irq_msi(dev, 2);
|
||||
|
||||
if (dev->msi)
|
||||
irq_flag = 0;
|
||||
if (dev->msi == 2) {
|
||||
stat = request_irq(dev->pdev->irq, irq_handler0,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0)
|
||||
return stat;
|
||||
stat = request_irq(dev->pdev->irq + 1, irq_handler1,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0) {
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
return stat;
|
||||
}
|
||||
} else {
|
||||
#ifdef DDB_TEST_THREADED
|
||||
stat = request_threaded_irq(dev->pdev->irq, irq_handler,
|
||||
irq_thread,
|
||||
irq_flag,
|
||||
"ddbridge", (void *) dev);
|
||||
#else
|
||||
stat = request_irq(dev->pdev->irq, irq_handler,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
#endif
|
||||
if (stat < 0)
|
||||
return stat;
|
||||
}
|
||||
/*ddbwritel(dev, 0xffffffff, INTERRUPT_ACK);*/
|
||||
if (dev->msi == 2) {
|
||||
ddbwritel(dev, 0x0fffff00, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x0000000f, MSI1_ENABLE);
|
||||
} else {
|
||||
ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int __devinit ddb_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct ddb *dev;
|
||||
int stat = 0;
|
||||
|
||||
if (pci_enable_device(pdev) < 0)
|
||||
return -ENODEV;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
|
||||
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
|
||||
return -ENODEV;
|
||||
|
||||
dev = vzalloc(sizeof(struct ddb));
|
||||
if (dev == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&dev->mutex);
|
||||
dev->has_dma = 1;
|
||||
dev->pdev = pdev;
|
||||
dev->dev = &pdev->dev;
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
||||
dev->link[0].ids.vendor = id->vendor;
|
||||
dev->link[0].ids.device = id->device;
|
||||
dev->link[0].ids.subvendor = id->subvendor;
|
||||
dev->link[0].ids.subdevice = pdev->subsystem_device;
|
||||
|
||||
dev->link[0].dev = dev;
|
||||
dev->link[0].info = get_ddb_info(id->vendor, id->device,
|
||||
id->subvendor, pdev->subsystem_device);
|
||||
pr_info("DDBridge: device name: %s\n", dev->link[0].info->name);
|
||||
|
||||
dev->regs_len = pci_resource_len(dev->pdev, 0);
|
||||
dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
|
||||
pci_resource_len(dev->pdev, 0));
|
||||
|
||||
if (!dev->regs) {
|
||||
pr_err("DDBridge: not enough memory for register map\n");
|
||||
stat = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
if (ddbreadl(dev, 0) == 0xffffffff) {
|
||||
pr_err("DDBridge: cannot read registers\n");
|
||||
stat = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dev->link[0].ids.hwid = ddbreadl(dev, 0);
|
||||
dev->link[0].ids.regmapid = ddbreadl(dev, 4);
|
||||
|
||||
pr_info("DDBridge: HW %08x REGMAP %08x\n",
|
||||
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
|
||||
|
||||
if (dev->link[0].info->ns_num) {
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
ddb_reset_ios(dev);
|
||||
}
|
||||
ddbwritel(dev, 0, DMA_BASE_READ);
|
||||
if (dev->link[0].info->type != DDB_MOD)
|
||||
ddbwritel(dev, 0, DMA_BASE_WRITE);
|
||||
|
||||
if (dev->link[0].info->type == DDB_MOD) {
|
||||
if (dev->link[0].info->version <= 1)
|
||||
if (ddbreadl(dev, 0x1c) == 4)
|
||||
dev->link[0].info->port_num = 4;
|
||||
}
|
||||
|
||||
stat = ddb_irq_init(dev);
|
||||
if (stat < 0)
|
||||
goto fail0;
|
||||
|
||||
if (ddb_init(dev) == 0)
|
||||
return 0;
|
||||
|
||||
ddb_irq_exit(dev);
|
||||
fail0:
|
||||
pr_err("DDBridge: fail0\n");
|
||||
if (dev->msi)
|
||||
pci_disable_msi(dev->pdev);
|
||||
fail:
|
||||
pr_err("DDBridge: fail\n");
|
||||
|
||||
ddb_unmap(dev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
pci_disable_device(pdev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
#define DDB_DEVICE_ANY(_device) { PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, PCI_ANY_ID) }
|
||||
|
||||
static const struct pci_device_id ddb_id_table[] __devinitconst = {
|
||||
DDB_DEVICE_ANY(0x0002),
|
||||
DDB_DEVICE_ANY(0x0003),
|
||||
DDB_DEVICE_ANY(0x0005),
|
||||
DDB_DEVICE_ANY(0x0006),
|
||||
DDB_DEVICE_ANY(0x0007),
|
||||
DDB_DEVICE_ANY(0x0008),
|
||||
DDB_DEVICE_ANY(0x0011),
|
||||
DDB_DEVICE_ANY(0x0012),
|
||||
DDB_DEVICE_ANY(0x0013),
|
||||
DDB_DEVICE_ANY(0x0201),
|
||||
DDB_DEVICE_ANY(0x0203),
|
||||
DDB_DEVICE_ANY(0x0210),
|
||||
DDB_DEVICE_ANY(0x0220),
|
||||
DDB_DEVICE_ANY(0x0320),
|
||||
DDB_DEVICE_ANY(0x0321),
|
||||
DDB_DEVICE_ANY(0x0322),
|
||||
DDB_DEVICE_ANY(0x0323),
|
||||
DDB_DEVICE_ANY(0x0328),
|
||||
DDB_DEVICE_ANY(0x0329),
|
||||
{0}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ddb_id_table);
|
||||
|
||||
static struct pci_driver ddb_pci_driver = {
|
||||
.name = "ddbridge",
|
||||
.id_table = ddb_id_table,
|
||||
.probe = ddb_probe,
|
||||
.remove = ddb_remove,
|
||||
};
|
||||
|
||||
static __init int module_init_ddbridge(void)
|
||||
{
|
||||
int stat = -1;
|
||||
|
||||
pr_info("DDBridge: Digital Devices PCIE bridge driver "
|
||||
DDBRIDGE_VERSION
|
||||
", Copyright (C) 2010-17 Digital Devices GmbH\n");
|
||||
if (ddb_class_create() < 0)
|
||||
return -1;
|
||||
ddb_wq = create_workqueue("ddbridge");
|
||||
if (ddb_wq == NULL)
|
||||
goto exit1;
|
||||
stat = pci_register_driver(&ddb_pci_driver);
|
||||
if (stat < 0)
|
||||
goto exit2;
|
||||
return stat;
|
||||
exit2:
|
||||
destroy_workqueue(ddb_wq);
|
||||
exit1:
|
||||
ddb_class_destroy();
|
||||
return stat;
|
||||
}
|
||||
|
||||
static __exit void module_exit_ddbridge(void)
|
||||
{
|
||||
pci_unregister_driver(&ddb_pci_driver);
|
||||
destroy_workqueue(ddb_wq);
|
||||
ddb_class_destroy();
|
||||
}
|
||||
|
||||
module_init(module_init_ddbridge);
|
||||
module_exit(module_exit_ddbridge);
|
||||
|
||||
MODULE_DESCRIPTION("Digital Devices PCIe Bridge");
|
||||
MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DDBRIDGE_VERSION);
|
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 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>
|
||||
* Digital Devices GmbH
|
||||
*
|
||||
@@ -23,8 +23,8 @@
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
static int ddb_dvb_ns_input_start(struct ddb_input *input);
|
||||
static int ddb_dvb_ns_input_stop(struct ddb_input *input);
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-io.h"
|
||||
|
||||
static u16 calc_pcs(struct dvb_ns_params *p)
|
||||
{
|
||||
@@ -87,7 +87,6 @@ static int ns_alloc(struct dvbnss *nss)
|
||||
dev->ns[i].fe = input;
|
||||
nss->priv = &dev->ns[i];
|
||||
ret = 0;
|
||||
/*pr_info("%s i=%d fe=%d\n", __func__, i, input->nr); */
|
||||
break;
|
||||
}
|
||||
ddbwritel(dev, 0x03, RTP_MASTER_CONTROL);
|
||||
@@ -102,7 +101,7 @@ static int ns_set_pids(struct dvbnss *nss)
|
||||
struct ddb *dev = input->port->dev;
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
|
||||
if (dev->ids.devid == 0x0301dd01) {
|
||||
if (dev->link[0].ids.devid == 0x0301dd01) {
|
||||
u32 sys = 0;
|
||||
int pid, j = 1;
|
||||
|
||||
@@ -134,7 +133,7 @@ static int ns_set_pid(struct dvbnss *nss, u16 pid)
|
||||
u32 off = STREAM_PIDS(dns->nr);
|
||||
|
||||
#if 1
|
||||
if (dev->ids.devid == 0x0301dd01) {
|
||||
if (dev->link[0].ids.devid == 0x0301dd01) {
|
||||
if (pid & 0x2000) {
|
||||
if (pid & 0x8000)
|
||||
memset(nss->pids, 0xff, 0x400);
|
||||
@@ -197,11 +196,14 @@ static int ns_set_ci(struct dvbnss *nss, u8 ci)
|
||||
ciport = citoport(dev, ci);
|
||||
if (ciport < 0)
|
||||
return -EINVAL;
|
||||
|
||||
pr_info("input %d.%d to ci %d at port %d\n", input->port->lnr, input->nr, ci, ciport);
|
||||
ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1c, TS_OUTPUT_CONTROL(ciport));
|
||||
|
||||
pr_info("DDBridge: input %d.%d to ci %d at port %d\n",
|
||||
input->port->lnr, input->nr, ci, ciport);
|
||||
ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1c,
|
||||
TS_CONTROL(dev->port[ciport].output));
|
||||
usleep_range(1, 5);
|
||||
ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1d, TS_OUTPUT_CONTROL(ciport));
|
||||
ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1d,
|
||||
TS_CONTROL(dev->port[ciport].output));
|
||||
dns->fe = dev->port[ciport].input[0];
|
||||
return 0;
|
||||
}
|
||||
@@ -443,7 +445,6 @@ static int ns_start(struct dvbnss *nss)
|
||||
if (dns->fe != input)
|
||||
ddb_dvb_ns_input_start(dns->fe);
|
||||
ddb_dvb_ns_input_start(input);
|
||||
printk("ns start ns %u, fe %u link %u\n", dns->nr, dns->fe->nr, dns->fe->port->lnr);
|
||||
ddbwritel(dev, reg | (dns->fe->nr << 8) | (dns->fe->port->lnr << 16),
|
||||
STREAM_CONTROL(dns->nr));
|
||||
return 0;
|
||||
@@ -463,7 +464,7 @@ static int ns_stop(struct dvbnss *nss)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netstream_init(struct ddb_input *input)
|
||||
int netstream_init(struct ddb_input *input)
|
||||
{
|
||||
struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
|
||||
struct dvb_adapter *adap = dvb->adap;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ddbridge-regs.h: Digital Devices PCIe bridge driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
/* Register Definitions */
|
||||
|
||||
#define CUR_REGISTERMAP_VERSION 0x10003
|
||||
#define CUR_REGISTERMAP_VERSION_CI 0x10000
|
||||
#define CUR_REGISTERMAP_VERSION_MOD 0x10000
|
||||
#define CUR_REGISTERMAP_VERSION_V1 0x00010001
|
||||
#define CUR_REGISTERMAP_VERSION_V2 0x00020000
|
||||
#define CUR_REGISTERMAP_VERSION_022X 0x00020001
|
||||
|
||||
#define HARDWARE_VERSION 0x00
|
||||
#define REGISTERMAP_VERSION 0x04
|
||||
#define HARDWARE_VERSION 0x00000000
|
||||
#define REGISTERMAP_VERSION 0x00000004
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* SPI Controller */
|
||||
@@ -58,9 +58,9 @@
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Interrupt controller
|
||||
How many MSI's are available depends on HW (Min 2 max 8)
|
||||
How many are usable also depends on Host platform
|
||||
*/
|
||||
* How many MSI's are available depends on HW (Min 2 max 8)
|
||||
* How many are usable also depends on Host platform
|
||||
*/
|
||||
|
||||
#define INTERRUPT_BASE (0x40)
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
|
||||
#define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20)
|
||||
#define INTERRUPT_ACK (INTERRUPT_BASE + 0x20)
|
||||
#define INTERRUPT_ACK1 (INTERRUPT_BASE + 0x24)
|
||||
#define INTERRUPT_ACK2 (INTERRUPT_BASE + 0x28)
|
||||
|
||||
#define INTMASK_CLOCKGEN (0x00000001)
|
||||
#define INTMASK_TEMPMON (0x00000002)
|
||||
@@ -105,6 +107,26 @@
|
||||
#define INTMASK_TSOUTPUT4 (0x00080000)
|
||||
|
||||
|
||||
#define INTERRUPT_V2_CONTROL (INTERRUPT_BASE + 0x00)
|
||||
#define INTERRUPT_V2_ENABLE_1 (INTERRUPT_BASE + 0x04)
|
||||
#define INTERRUPT_V2_ENABLE_2 (INTERRUPT_BASE + 0x08)
|
||||
#define INTERRUPT_V2_ENABLE_3 (INTERRUPT_BASE + 0x0c)
|
||||
#define INTERRUPT_V2_ENABLE_4 (INTERRUPT_BASE + 0x10)
|
||||
#define INTERRUPT_V2_ENABLE_5 (INTERRUPT_BASE + 0x14)
|
||||
#define INTERRUPT_V2_ENABLE_6 (INTERRUPT_BASE + 0x18)
|
||||
#define INTERRUPT_V2_ENABLE_7 (INTERRUPT_BASE + 0x1c)
|
||||
|
||||
#define INTERRUPT_V2_STATUS (INTERRUPT_BASE + 0x20)
|
||||
#define INTERRUPT_V2_STATUS_1 (INTERRUPT_BASE + 0x24)
|
||||
#define INTERRUPT_V2_STATUS_2 (INTERRUPT_BASE + 0x28)
|
||||
#define INTERRUPT_V2_STATUS_3 (INTERRUPT_BASE + 0x2c)
|
||||
#define INTERRUPT_V2_STATUS_4 (INTERRUPT_BASE + 0x30)
|
||||
#define INTERRUPT_V2_STATUS_5 (INTERRUPT_BASE + 0x34)
|
||||
#define INTERRUPT_V2_STATUS_6 (INTERRUPT_BASE + 0x38)
|
||||
#define INTERRUPT_V2_STATUS_7 (INTERRUPT_BASE + 0x3c)
|
||||
|
||||
|
||||
|
||||
|
||||
/* Modulator registers */
|
||||
|
||||
@@ -126,25 +148,51 @@
|
||||
#define DAC_CONTROL_RESET (0x200)
|
||||
|
||||
/* Temperature Monitor ( 2x LM75A @ 0x90,0x92 I2c ) */
|
||||
#define TEMPMON_BASE (0xA0)
|
||||
#define TEMPMON_BASE (0x1c0)
|
||||
#define TEMPMON_CONTROL (TEMPMON_BASE + 0x00)
|
||||
|
||||
#define TEMPMON_CONTROL_SCAN (0x00000001)
|
||||
#define TEMPMON_CONTROL_AUTOSCAN (0x00000002)
|
||||
#define TEMPMON_CONTROL_INTENABLE (0x00000004)
|
||||
#define TEMPMON_CONTROL_OVERTEMP (0x00008000)
|
||||
|
||||
|
||||
/* SHORT Temperature in <20>C x 256 */
|
||||
#define TEMPMON_CORE (TEMPMON_BASE + 0x04)
|
||||
#define TEMPMON_SENSOR0 (TEMPMON_BASE + 0x04)
|
||||
#define TEMPMON_SENSOR1 (TEMPMON_BASE + 0x08)
|
||||
#define TEMPMON_SENSOR2 (TEMPMON_BASE + 0x0C)
|
||||
|
||||
#define TEMPMON_FANCONTROL (TEMPMON_BASE + 0x10)
|
||||
#define TEMPMON_FANPWM (0x00000F00) // PWM speed in 10% steps
|
||||
#define TEMPMON_FANTACHO (0x000000FF) // Rotations in 100/min steps
|
||||
|
||||
/* V1 Temperature Monitor
|
||||
* Temperature Monitor TEMPMON_CONTROL & 0x8000 == 0 : ( 2x LM75A @ 0x90,0x92 )
|
||||
* Temperature Monitor TEMPMON_CONTROL & 0x8000 == 1 :
|
||||
* ( 1x LM75A @ 0x90, 1x ADM1032 @ 0x9A )
|
||||
*/
|
||||
|
||||
#define TEMPMON1_CORE (TEMPMON_SENSOR0) // u16 Temperature in <20>C x 256 (ADM1032 ext)
|
||||
#define TEMPMON1_SENSOR1 (TEMPMON_BASE + 0x08) // SHORT Temperature in <20>C x 256 (LM75A 0x90)
|
||||
#define TEMPMON1_SENSOR2 (TEMPMON_BASE + 0x0C) // SHORT Temperature in <20>C x 256 (LM75A 0x92 or ADM1032 Int)
|
||||
|
||||
// V2 Temperature Monitor 2 ADM1032
|
||||
|
||||
#define TEMPMON2_BOARD (TEMPMON_SENSOR0) // SHORT Temperature in <20>C x 256 (ADM1032 int)
|
||||
#define TEMPMON2_FPGACORE (TEMPMON_SENSOR1) // SHORT Temperature in <20>C x 256 (ADM1032 ext)
|
||||
#define TEMPMON2_QAMCORE (TEMPMON_SENSOR2) // SHORT Temperature in <20>C x 256 (ADM1032 ext)
|
||||
#define TEMPMON2_DACCORE (TEMPMON_SENSOR2) // SHORT Temperature in <20>C x 256 (ADM1032 ext)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* I2C Master Controller */
|
||||
|
||||
#define I2C_BASE (0x80) /* Byte offset */
|
||||
|
||||
#define I2C_COMMAND (0x00)
|
||||
#define I2C_TIMING (0x04)
|
||||
#define I2C_TASKLENGTH (0x08) /* High read, low write */
|
||||
#define I2C_TASKADDRESS (0x0C) /* High read, low write */
|
||||
#define I2C_MONITOR (0x1C)
|
||||
|
||||
|
||||
#define I2C_SPEED_666 (0x02010202)
|
||||
#define I2C_SPEED_400 (0x04030404)
|
||||
#define I2C_SPEED_200 (0x09080909)
|
||||
@@ -173,26 +221,17 @@
|
||||
#define DMA_DIAG_WAITOVERFLOWCOUNTER (0x38)
|
||||
#define DMA_DIAG_WAITCOUNTER (0x3C)
|
||||
|
||||
#define TS_INPUT_BASE (0x200)
|
||||
#define TS_INPUT_CONTROL(i) (TS_INPUT_BASE + (i) * 0x10 + 0x00)
|
||||
#define TS_INPUT_CONTROL2(i) (TS_INPUT_BASE + (i) * 0x10 + 0x04)
|
||||
#define TS_CONTROL(_io) (_io->regs + 0x00)
|
||||
#define TS_CONTROL2(_io) (_io->regs + 0x04)
|
||||
|
||||
#define TS_OUTPUT_BASE (0x280)
|
||||
#define TS_OUTPUT_CONTROL(i) (TS_OUTPUT_BASE + (i) * 0x10 + 0x00)
|
||||
#define TS_OUTPUT_CONTROL2(i) (TS_OUTPUT_BASE + (i) * 0x10 + 0x04)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* DMA Buffer */
|
||||
|
||||
#define DMA_BUFFER_BASE (0x300)
|
||||
|
||||
#define DMA_BUFFER_CONTROL(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x00)
|
||||
#define DMA_BUFFER_ACK(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x04)
|
||||
#define DMA_BUFFER_CURRENT(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x08)
|
||||
#define DMA_BUFFER_SIZE(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x0c)
|
||||
|
||||
#define DMA_BASE_ADDRESS_TABLE (0x2000)
|
||||
#define DMA_BASE_ADDRESS_TABLE_ENTRIES (512)
|
||||
#define DMA_BUFFER_CONTROL(_dma) (_dma->regs + 0x00)
|
||||
#define DMA_BUFFER_ACK(_dma) (_dma->regs + 0x04)
|
||||
#define DMA_BUFFER_CURRENT(_dma) (_dma->regs + 0x08)
|
||||
#define DMA_BUFFER_SIZE(_dma) (_dma->regs + 0x0c)
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -207,7 +246,7 @@
|
||||
#define LNB_CMD_HIGH 4
|
||||
#define LNB_CMD_OFF 5
|
||||
#define LNB_CMD_DISEQC 6
|
||||
#define LNB_CMD_UNI 7
|
||||
#define LNB_CMD_SCIF 7
|
||||
|
||||
#define LNB_BUSY (1ULL << 4)
|
||||
#define LNB_TONE (1ULL << 15)
|
||||
@@ -263,6 +302,8 @@
|
||||
#define CI_BLOCKIO_SEND_BUFFER(i) \
|
||||
(CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE + CI_BLOCKIO_BUFFER_SIZE)
|
||||
|
||||
// V1
|
||||
|
||||
#define VCO1_BASE (0xC0)
|
||||
#define VCO1_CONTROL (VCO1_BASE + 0x00)
|
||||
#define VCO1_DATA (VCO1_BASE + 0x04) /* 24 Bit */
|
||||
@@ -293,12 +334,73 @@
|
||||
/* Muxout from VCO (usually = Lock) */
|
||||
#define VCO3_CONTROL_MUXOUT (0x00000004)
|
||||
|
||||
/* V2 */
|
||||
|
||||
#define MAX2871_BASE (0xC0)
|
||||
#define MAX2871_CONTROL (MAX2871_BASE + 0x00)
|
||||
#define MAX2871_OUTDATA (MAX2871_BASE + 0x04)
|
||||
#define MAX2871_INDATA (MAX2871_BASE + 0x08)
|
||||
#define MAX2871_CONTROL_WRITE (0x00000001) // 1 = Trigger write, resets when done
|
||||
#define MAX2871_CONTROL_CE (0x00000002) // 0 = Put VCO into power down
|
||||
#define MAX2871_CONTROL_MUXOUT (0x00000004) // Muxout from VCO
|
||||
#define MAX2871_CONTROL_LOCK (0x00000008) // Lock from VCO
|
||||
|
||||
#define FSM_BASE (0x200)
|
||||
#define FSM_CONTROL (FSM_BASE + 0x00)
|
||||
|
||||
#define FSM_CONTROL_ENABLE (0x00000100)
|
||||
|
||||
#define FSM_CMD_MASK (0x00000087)
|
||||
#define FSM_CMD_STATUS (0x00000080)
|
||||
#define FSM_CMD_RESET (0x00000080)
|
||||
#define FSM_CMD_POWERDOWN (0x00000081)
|
||||
#define FSM_CMD_SETUP (0x00000082)
|
||||
|
||||
#define FSM_STATUS (FSM_BASE + 0x00)
|
||||
#define FSM_STATUS_READY (0x00010000)
|
||||
#define FSM_STATUS_QAMREADY (0x00020000)
|
||||
|
||||
|
||||
#define FSM_CAPACITY (FSM_BASE + 0x04)
|
||||
#define FSM_CAPACITY_MAX (0x3F000000)
|
||||
#define FSM_CAPACITY_CUR (0x003F0000)
|
||||
#define FSM_CAPACITY_INUSE (0x0000003F)
|
||||
|
||||
#define FSM_GAIN (FSM_BASE + 0x10)
|
||||
#define FSM_GAINMASK (0x000000FF)
|
||||
|
||||
#define FSM_GAIN_N1 (0x000000FE)
|
||||
#define FSM_GAIN_N2 (0x000000A1)
|
||||
#define FSM_GAIN_N4 (0x00000066)
|
||||
#define FSM_GAIN_N8 (0x00000048)
|
||||
#define FSM_GAIN_N16 (0x0000002D)
|
||||
#define FSM_GAIN_N24 (0x00000029)
|
||||
#define FSM_GAIN_N96 (0x00000011)
|
||||
|
||||
|
||||
// Attenuator/VGA
|
||||
|
||||
#define RF_ATTENUATOR (0xD8)
|
||||
#define RF_ATTENUATOR (0xD8)
|
||||
/* 0x00 = 0 dB
|
||||
0x01 = 1 dB
|
||||
...
|
||||
0x1F = 31 dB
|
||||
*/
|
||||
* 0x01 = 1 dB
|
||||
* ...
|
||||
* 0x1F = 31 dB
|
||||
*/
|
||||
|
||||
#define RF_VGA (0xDC)
|
||||
/* Only V2 */
|
||||
/* 8 bit range 0 - 31.75 dB Gain */
|
||||
|
||||
/* VGA Gain for same output level as V1 Modulator */
|
||||
#define RF_VGA_GAIN_N8 (85)
|
||||
#define RF_VGA_GAIN_N16 (117)
|
||||
#define RF_VGA_GAIN_N24 (122)
|
||||
|
||||
#define RF_VGA_GAIN_MAX (200)
|
||||
|
||||
|
||||
/* V1 only */
|
||||
|
||||
#define RF_POWER (0xE0)
|
||||
#define RF_POWER_BASE (0xE0)
|
||||
@@ -311,9 +413,9 @@
|
||||
#define RF_POWER_CONTROL_VALID (0x00000500)
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Output control
|
||||
*/
|
||||
/*
|
||||
* Output control
|
||||
*/
|
||||
|
||||
#define IQOUTPUT_BASE (0x240)
|
||||
#define IQOUTPUT_CONTROL (IQOUTPUT_BASE + 0x00)
|
||||
@@ -343,7 +445,7 @@
|
||||
#define IQOUTPUT_CONTROL_BYPASS_EQUALIZER (0x00000010)
|
||||
|
||||
|
||||
/* Modulator Base */
|
||||
/* Modulator Base V1 */
|
||||
|
||||
#define MODULATOR_BASE (0x200)
|
||||
#define MODULATOR_CONTROL (MODULATOR_BASE)
|
||||
@@ -361,9 +463,11 @@
|
||||
|
||||
/* Modulator Channels */
|
||||
|
||||
#define CHANNEL_BASE (0x400)
|
||||
#define CHANNEL_BASE dev->link[0].info->regmap->channel->base
|
||||
|
||||
#define CHANNEL_CONTROL(i) (CHANNEL_BASE + (i) * 64 + 0x00)
|
||||
#define CHANNEL_SETTINGS(i) (CHANNEL_BASE + (i) * 64 + 0x04)
|
||||
#define CHANNEL_SETTINGS2(i) (CHANNEL_BASE + (i) * 64 + 0x08)
|
||||
#define CHANNEL_RATE_INCR(i) (CHANNEL_BASE + (i) * 64 + 0x0C)
|
||||
#define CHANNEL_PCR_ADJUST_OUTL(i) (CHANNEL_BASE + (i) * 64 + 0x10)
|
||||
#define CHANNEL_PCR_ADJUST_OUTH(i) (CHANNEL_BASE + (i) * 64 + 0x14)
|
||||
@@ -373,6 +477,8 @@
|
||||
#define CHANNEL_PCR_ADJUST_ACCUH(i) (CHANNEL_BASE + (i) * 64 + 0x24)
|
||||
#define CHANNEL_PKT_COUNT_OUT(i) (CHANNEL_BASE + (i) * 64 + 0x28)
|
||||
#define CHANNEL_PKT_COUNT_IN(i) (CHANNEL_BASE + (i) * 64 + 0x2C)
|
||||
#define CHANNEL_KF(i) (CHANNEL_BASE + (i) * 64 + 0x30)
|
||||
#define CHANNEL_LF(i) (CHANNEL_BASE + (i) * 64 + 0x34)
|
||||
|
||||
#define CHANNEL_CONTROL_RESET (0x00000001)
|
||||
#define CHANNEL_CONTROL_ENABLE_DVB (0x00000002)
|
||||
@@ -381,8 +487,17 @@
|
||||
#define CHANNEL_CONTROL_ENABLE_PCRADJUST (0x00000010)
|
||||
#define CHANNEL_CONTROL_FREEZE_STATUS (0x00000100)
|
||||
|
||||
#define CHANNEL_CONTROL_CMD_MASK (0x0000F000)
|
||||
#define CHANNEL_CONTROL_CMD_STATUS (0x00008000)
|
||||
#define CHANNEL_CONTROL_CMD_FREE (0x00008000)
|
||||
#define CHANNEL_CONTROL_CMD_SETUP (0x00009000)
|
||||
#define CHANNEL_CONTROL_CMD_MUTE (0x0000A000)
|
||||
#define CHANNEL_CONTROL_CMD_UNMUTE (0x0000B000)
|
||||
|
||||
#define CHANNEL_CONTROL_RESET_ERROR (0x00010000)
|
||||
#define CHANNEL_CONTROL_BUSY (0x01000000)
|
||||
#define CHANNEL_CONTROL_ACTIVE (0x00400000)
|
||||
#define CHANNEL_CONTROL_BUSY (0x00800000)
|
||||
#define CHANNEL_CONTROL_ERROR_CMD (0x10000000)
|
||||
#define CHANNEL_CONTROL_ERROR_SYNC (0x20000000)
|
||||
#define CHANNEL_CONTROL_ERROR_UNDERRUN (0x40000000)
|
||||
#define CHANNEL_CONTROL_ERROR_FATAL (0x80000000)
|
||||
@@ -394,6 +509,14 @@
|
||||
#define CHANNEL_SETTINGS_QAM128 (0x00000003)
|
||||
#define CHANNEL_SETTINGS_QAM256 (0x00000004)
|
||||
|
||||
#define CHANNEL_SETTINGS2_OUTPUT_MASK (0x0000007F)
|
||||
|
||||
#define KFLF_MAX (0x07FFFFFFUL)
|
||||
#define KF_INIT(Symbolrate) (Symbolrate)
|
||||
#define LF_INIT(Symbolrate) (9000000UL)
|
||||
#define MIN_SYMBOLRATE (1000000)
|
||||
#define MAX_SYMBOLRATE (7100000)
|
||||
|
||||
|
||||
/* OCTONET */
|
||||
|
||||
@@ -433,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 \
|
||||
)
|
||||
|
||||
|
@@ -1,533 +0,0 @@
|
||||
/*
|
||||
* ddbridge.c: Digital Devices PCIe bridge driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*#define DDB_ALT_DMA*/
|
||||
#define DDB_USE_WORK
|
||||
/*#define DDB_TEST_THREADED*/
|
||||
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-regs.h"
|
||||
|
||||
static struct workqueue_struct *ddb_wq;
|
||||
|
||||
static int adapter_alloc;
|
||||
module_param(adapter_alloc, int, 0444);
|
||||
MODULE_PARM_DESC(adapter_alloc,
|
||||
"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all");
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
static int msi = 1;
|
||||
module_param(msi, int, 0444);
|
||||
MODULE_PARM_DESC(msi,
|
||||
" Control MSI interrupts: 0-disable, 1-enable (default)");
|
||||
#endif
|
||||
|
||||
#include "ddbridge-core.c"
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static void ddb_unmap(struct ddb *dev)
|
||||
{
|
||||
if (dev->regs)
|
||||
iounmap(dev->regs);
|
||||
vfree(dev);
|
||||
}
|
||||
|
||||
|
||||
static void __devexit ddb_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev);
|
||||
|
||||
ddb_nsd_detach(dev);
|
||||
ddb_ports_detach(dev);
|
||||
ddb_i2c_release(dev);
|
||||
|
||||
if (dev->link[0].info->ns_num)
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
ddbwritel(dev, 0, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0, MSI1_ENABLE);
|
||||
if (dev->msi == 2)
|
||||
free_irq(dev->pdev->irq + 1, dev);
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
if (dev->msi)
|
||||
pci_disable_msi(dev->pdev);
|
||||
#endif
|
||||
ddb_ports_release(dev);
|
||||
ddb_buffers_free(dev);
|
||||
ddb_device_destroy(dev);
|
||||
|
||||
ddb_unmap(dev);
|
||||
pci_set_drvdata(pdev, 0);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
|
||||
#define __devinit
|
||||
#define __devinitdata
|
||||
#endif
|
||||
|
||||
static int __devinit ddb_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct ddb *dev;
|
||||
int stat = 0;
|
||||
int irq_flag = IRQF_SHARED;
|
||||
|
||||
if (pci_enable_device(pdev) < 0)
|
||||
return -ENODEV;
|
||||
|
||||
dev = vzalloc(sizeof(struct ddb));
|
||||
if (dev == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&dev->mutex);
|
||||
dev->has_dma = 1;
|
||||
dev->pdev = pdev;
|
||||
dev->dev = &pdev->dev;
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
||||
dev->ids.vendor = id->vendor;
|
||||
dev->ids.device = id->device;
|
||||
dev->ids.subvendor = id->subvendor;
|
||||
dev->ids.subdevice = id->subdevice;
|
||||
|
||||
dev->link[0].dev = dev;
|
||||
dev->link[0].info = (struct ddb_info *) id->driver_data;
|
||||
pr_info("DDBridge driver detected: %s\n", dev->link[0].info->name);
|
||||
|
||||
dev->regs_len = pci_resource_len(dev->pdev, 0);
|
||||
dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
|
||||
pci_resource_len(dev->pdev, 0));
|
||||
|
||||
if (!dev->regs) {
|
||||
pr_err("DDBridge: not enough memory for register map\n");
|
||||
stat = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
if (ddbreadl(dev, 0) == 0xffffffff) {
|
||||
pr_err("DDBridge: cannot read registers\n");
|
||||
stat = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dev->ids.hwid = ddbreadl(dev, 0);
|
||||
dev->ids.regmapid = ddbreadl(dev, 4);
|
||||
|
||||
pr_info("DDBridge: HW %08x REGMAP %08x\n",
|
||||
dev->ids.hwid, dev->ids.regmapid);
|
||||
|
||||
if (dev->link[0].info->ns_num) {
|
||||
int i;
|
||||
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
for (i = 0; i < 16; i++)
|
||||
ddbwritel(dev, 0x00, TS_OUTPUT_CONTROL(i));
|
||||
usleep_range(5000, 6000);
|
||||
}
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI2_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI3_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI4_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI5_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI6_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI7_ENABLE);
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
if (msi && pci_msi_enabled()) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
||||
stat = pci_enable_msi_range(dev->pdev, 1, 2);
|
||||
if (stat >= 1) {
|
||||
dev->msi = stat;
|
||||
pr_info("DDBridge: using %d MSI interrupt(s)\n", dev->msi);
|
||||
irq_flag = 0;
|
||||
} else
|
||||
pr_info("DDBridge: MSI not available.\n");
|
||||
|
||||
#else
|
||||
stat = pci_enable_msi_block(dev->pdev, 2);
|
||||
if (stat == 0) {
|
||||
dev->msi = 1;
|
||||
pr_info("DDBridge: using 2 MSI interrupts\n");
|
||||
}
|
||||
if (stat == 1)
|
||||
stat = pci_enable_msi(dev->pdev);
|
||||
if (stat < 0) {
|
||||
pr_info("DDBridge: MSI not available.\n");
|
||||
} else {
|
||||
irq_flag = 0;
|
||||
dev->msi++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (dev->msi == 2) {
|
||||
stat = request_irq(dev->pdev->irq, irq_handler0,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0)
|
||||
goto fail0;
|
||||
stat = request_irq(dev->pdev->irq + 1, irq_handler1,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0) {
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
goto fail0;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef DDB_TEST_THREADED
|
||||
stat = request_threaded_irq(dev->pdev->irq, irq_handler,
|
||||
irq_thread,
|
||||
irq_flag,
|
||||
"ddbridge", (void *) dev);
|
||||
#else
|
||||
stat = request_irq(dev->pdev->irq, irq_handler,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
#endif
|
||||
if (stat < 0)
|
||||
goto fail0;
|
||||
}
|
||||
ddbwritel(dev, 0, DMA_BASE_READ);
|
||||
if (dev->link[0].info->type != DDB_MOD)
|
||||
ddbwritel(dev, 0, DMA_BASE_WRITE);
|
||||
|
||||
if (dev->link[0].info->type == DDB_MOD) {
|
||||
if (ddbreadl(dev, 0x1c) == 4)
|
||||
dev->link[0].info->port_num = 4;
|
||||
}
|
||||
|
||||
/*ddbwritel(dev, 0xffffffff, INTERRUPT_ACK);*/
|
||||
if (dev->msi == 2) {
|
||||
ddbwritel(dev, 0x0fffff00, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x0000000f, MSI1_ENABLE);
|
||||
} else {
|
||||
ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
|
||||
}
|
||||
if (ddb_init(dev) == 0)
|
||||
return 0;
|
||||
|
||||
ddbwritel(dev, 0, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0, MSI1_ENABLE);
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
if (dev->msi == 2)
|
||||
free_irq(dev->pdev->irq + 1, dev);
|
||||
fail0:
|
||||
pr_err("fail0\n");
|
||||
if (dev->msi)
|
||||
pci_disable_msi(dev->pdev);
|
||||
fail:
|
||||
pr_err("fail\n");
|
||||
|
||||
ddb_unmap(dev);
|
||||
pci_set_drvdata(pdev, 0);
|
||||
pci_disable_device(pdev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_regset octopus_i2c = {
|
||||
.base = 0x80,
|
||||
.num = 0x04,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_i2c_buf = {
|
||||
.base = 0x1000,
|
||||
.num = 0x04,
|
||||
.size = 0x200,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
static struct ddb_regmap octopus_map = {
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_net_map = {
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_mod_map = {
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_info ddb_none = {
|
||||
.type = DDB_NONE,
|
||||
.name = "unknown Digital Devices PCIe card, install newer driver",
|
||||
.regmap = &octopus_map,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopusv3 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus V3 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_le = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus LE DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 2,
|
||||
.i2c_mask = 0x03,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_oem = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus OEM",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.led_num = 1,
|
||||
.fan_num = 1,
|
||||
.temp_num = 1,
|
||||
.temp_bus = 0,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_mini = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus Mini",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_v6 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine S2 V6 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x07,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_v6_5 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine S2 V6.5 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_v7 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine S2 V7 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 2,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ctv7 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine CT V7 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 3,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_satixS2v3 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Mystique SaTiX-S2 V3 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x07,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ci = {
|
||||
.type = DDB_OCTOPUS_CI,
|
||||
.name = "Digital Devices Octopus CI",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x03,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_cis = {
|
||||
.type = DDB_OCTOPUS_CI,
|
||||
.name = "Digital Devices Octopus CI single",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x01,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ci_s2_pro = {
|
||||
.type = DDB_OCTOPUS_CI,
|
||||
.name = "Digital Devices Octopus CI S2 Pro",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 3,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_dvbct = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices DVBCT V6.1 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x07,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_info ddb_s2_48 = {
|
||||
.type = DDB_OCTOPUS_MAX,
|
||||
.name = "Digital Devices MAX S8 4/8",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_mod = {
|
||||
.type = DDB_MOD,
|
||||
.name = "Digital Devices DVB-C modulator",
|
||||
.regmap = &octopus_mod_map,
|
||||
.port_num = 10,
|
||||
.temp_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_net = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet network DVB adapter",
|
||||
.regmap = &octopus_net_map,
|
||||
.port_num = 10,
|
||||
.i2c_mask = 0x3ff,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
#define DDVID 0xdd01 /* Digital Devices Vendor ID */
|
||||
|
||||
#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \
|
||||
.vendor = _vend, .device = _dev, \
|
||||
.subvendor = _subvend, .subdevice = _subdev, \
|
||||
.driver_data = (unsigned long)&_driverdata }
|
||||
|
||||
static const struct pci_device_id ddb_id_tbl[] __devinitconst = {
|
||||
DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus),
|
||||
DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini),
|
||||
DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5),
|
||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3),
|
||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7),
|
||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7),
|
||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7),
|
||||
DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48),
|
||||
DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci),
|
||||
DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis),
|
||||
DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci),
|
||||
DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro),
|
||||
DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod),
|
||||
DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod),
|
||||
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_octopus_net),
|
||||
/* in case sub-ids got deleted in flash */
|
||||
DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0005, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
{0}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ddb_id_tbl);
|
||||
|
||||
static struct pci_driver ddb_pci_driver = {
|
||||
.name = "ddbridge",
|
||||
.id_table = ddb_id_tbl,
|
||||
.probe = ddb_probe,
|
||||
.remove = ddb_remove,
|
||||
};
|
||||
|
||||
static __init int module_init_ddbridge(void)
|
||||
{
|
||||
int stat = -1;
|
||||
|
||||
pr_info("Digital Devices PCIE bridge driver "
|
||||
DDBRIDGE_VERSION
|
||||
", Copyright (C) 2010-15 Digital Devices GmbH\n");
|
||||
if (ddb_class_create() < 0)
|
||||
return -1;
|
||||
ddb_wq = create_workqueue("ddbridge");
|
||||
if (ddb_wq == NULL)
|
||||
goto exit1;
|
||||
stat = pci_register_driver(&ddb_pci_driver);
|
||||
if (stat < 0)
|
||||
goto exit2;
|
||||
return stat;
|
||||
exit2:
|
||||
destroy_workqueue(ddb_wq);
|
||||
exit1:
|
||||
ddb_class_destroy();
|
||||
return stat;
|
||||
}
|
||||
|
||||
static __exit void module_exit_ddbridge(void)
|
||||
{
|
||||
pci_unregister_driver(&ddb_pci_driver);
|
||||
destroy_workqueue(ddb_wq);
|
||||
ddb_class_destroy();
|
||||
}
|
||||
|
||||
module_init(module_init_ddbridge);
|
||||
module_exit(module_exit_ddbridge);
|
||||
|
||||
MODULE_DESCRIPTION("Digital Devices PCIe Bridge");
|
||||
MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DDBRIDGE_VERSION);
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ddbridge.h: Digital Devices PCIe bridge driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||
* Ralph Metzler <rmetzler@digitaldevices.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -25,6 +25,9 @@
|
||||
#ifndef _DDBRIDGE_H_
|
||||
#define _DDBRIDGE_H_
|
||||
|
||||
#define DDB_USE_WORK
|
||||
/*#define DDB_TEST_THREADED*/
|
||||
|
||||
#include <linux/version.h>
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
|
||||
@@ -41,7 +44,7 @@
|
||||
#include <linux/poll.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pci.h>
|
||||
//#include <linux/pci_ids.h>
|
||||
/*#include <linux/pci_ids.h>*/
|
||||
#include <linux/timer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/swab.h>
|
||||
@@ -55,7 +58,6 @@
|
||||
#include <linux/completion.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/dma.h>
|
||||
@@ -91,10 +93,12 @@
|
||||
#include "lnbh25.h"
|
||||
#include "mxl5xx.h"
|
||||
|
||||
#define DDB_MAX_I2C 16
|
||||
#define DDB_MAX_PORT 16
|
||||
#define DDB_MAX_INPUT 44
|
||||
#define DDB_MAX_OUTPUT 10
|
||||
#include "ddbridge-regs.h"
|
||||
|
||||
#define DDB_MAX_I2C 32
|
||||
#define DDB_MAX_PORT 32
|
||||
#define DDB_MAX_INPUT 64
|
||||
#define DDB_MAX_OUTPUT 32
|
||||
#define DDB_MAX_LINK 4
|
||||
#define DDB_LINK_SHIFT 28
|
||||
|
||||
@@ -106,25 +110,30 @@ struct ddb_regset {
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct ddb_ports {
|
||||
u32 base;
|
||||
u32 num;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct ddb_regmap {
|
||||
struct ddb_ports *bc;
|
||||
u32 irq_version;
|
||||
u32 irq_base_i2c;
|
||||
u32 irq_base_idma;
|
||||
u32 irq_base_odma;
|
||||
u32 irq_base_gtl;
|
||||
u32 irq_base_rate;
|
||||
|
||||
struct ddb_regset *i2c;
|
||||
struct ddb_regset *i2c_buf;
|
||||
struct ddb_regset *dma;
|
||||
struct ddb_regset *dma_buf;
|
||||
struct ddb_regset *idma;
|
||||
struct ddb_regset *idma_buf;
|
||||
struct ddb_regset *odma;
|
||||
struct ddb_regset *odma_buf;
|
||||
|
||||
struct ddb_regset *input;
|
||||
struct ddb_regset *output;
|
||||
|
||||
struct ddb_regset *channel;
|
||||
struct ddb_regset *ci;
|
||||
struct ddb_regset *pid_filter;
|
||||
struct ddb_regset *ns;
|
||||
//struct ddb_regset *ci;
|
||||
//struct ddb_regset *pid_filter;
|
||||
//struct ddb_regset *ns;
|
||||
struct ddb_regset *gtl;
|
||||
//struct ddb_regset *mdio;
|
||||
};
|
||||
|
||||
struct ddb_ids {
|
||||
@@ -132,7 +141,7 @@ struct ddb_ids {
|
||||
u16 device;
|
||||
u16 subvendor;
|
||||
u16 subdevice;
|
||||
|
||||
|
||||
u32 hwid;
|
||||
u32 regmapid;
|
||||
u32 devid;
|
||||
@@ -140,13 +149,17 @@ struct ddb_ids {
|
||||
};
|
||||
|
||||
struct ddb_info {
|
||||
int type;
|
||||
u32 type;
|
||||
#define DDB_NONE 0
|
||||
#define DDB_OCTOPUS 1
|
||||
#define DDB_OCTOPUS_CI 2
|
||||
#define DDB_MOD 3
|
||||
#define DDB_OCTONET 4
|
||||
#define DDB_OCTOPUS_MAX 5
|
||||
#define DDB_OCTOPUS_MAX_CT 6
|
||||
#define DDB_OCTOPRO 7
|
||||
#define DDB_OCTOPRO_HDIN 8
|
||||
u32 version;
|
||||
char *name;
|
||||
u32 i2c_mask;
|
||||
u8 port_num;
|
||||
@@ -154,18 +167,35 @@ struct ddb_info {
|
||||
u8 fan_num;
|
||||
u8 temp_num;
|
||||
u8 temp_bus;
|
||||
u8 board_control;
|
||||
u32 board_control;
|
||||
u32 board_control_2;
|
||||
u8 ns_num;
|
||||
u8 mdio_num;
|
||||
u8 con_clock;
|
||||
u8 con_clock; /* use a continuous clock */
|
||||
u8 ts_quirks;
|
||||
#define TS_QUIRK_SERIAL 1
|
||||
#define TS_QUIRK_REVERSED 2
|
||||
#define TS_QUIRK_NO_OUTPUT 4
|
||||
#define TS_QUIRK_ALT_OSC 8
|
||||
u32 tempmon_irq;
|
||||
struct ddb_regmap *regmap;
|
||||
};
|
||||
|
||||
/* DMA_SIZE MUST be smaller than 256k and
|
||||
MUST be divisible by 188 and 128 !!! */
|
||||
* MUST be divisible by 188 and 128 !!!
|
||||
*/
|
||||
|
||||
#define DMA_MAX_BUFS 32 /* hardware table limit */
|
||||
|
||||
#ifdef SMALL_DMA_BUFS
|
||||
#define INPUT_DMA_BUFS 32
|
||||
#define INPUT_DMA_SIZE (128*47*5)
|
||||
#define INPUT_DMA_IRQ_DIV 1
|
||||
|
||||
#define OUTPUT_DMA_BUFS 32
|
||||
#define OUTPUT_DMA_SIZE (128*47*5)
|
||||
#define OUTPUT_DMA_IRQ_DIV 1
|
||||
#else
|
||||
#define INPUT_DMA_BUFS 8
|
||||
#define INPUT_DMA_SIZE (128*47*21)
|
||||
#define INPUT_DMA_IRQ_DIV 1
|
||||
@@ -173,20 +203,27 @@ struct ddb_info {
|
||||
#define OUTPUT_DMA_BUFS 8
|
||||
#define OUTPUT_DMA_SIZE (128*47*21)
|
||||
#define OUTPUT_DMA_IRQ_DIV 1
|
||||
#endif
|
||||
#define OUTPUT_DMA_BUFS_SDR 32
|
||||
#define OUTPUT_DMA_SIZE_SDR (256*1024)
|
||||
#define OUTPUT_DMA_IRQ_DIV_SDR 1
|
||||
|
||||
|
||||
struct ddb;
|
||||
struct ddb_port;
|
||||
|
||||
struct ddb_dma {
|
||||
void *io;
|
||||
u32 nr;
|
||||
u32 regs;
|
||||
u32 bufregs;
|
||||
|
||||
dma_addr_t pbuf[DMA_MAX_BUFS];
|
||||
u8 *vbuf[DMA_MAX_BUFS];
|
||||
u32 num;
|
||||
u32 size;
|
||||
u32 div;
|
||||
u32 bufreg;
|
||||
|
||||
u32 bufval;
|
||||
|
||||
#ifdef DDB_USE_WORK
|
||||
struct work_struct work;
|
||||
#else
|
||||
@@ -200,7 +237,7 @@ struct ddb_dma {
|
||||
u32 cbuf;
|
||||
u32 coff;
|
||||
};
|
||||
|
||||
|
||||
struct ddb_dvb {
|
||||
struct dvb_adapter *adap;
|
||||
int adap_registered;
|
||||
@@ -216,14 +253,15 @@ struct ddb_dvb {
|
||||
int users;
|
||||
u32 attached;
|
||||
u8 input;
|
||||
|
||||
|
||||
fe_sec_tone_mode_t tone;
|
||||
fe_sec_voltage_t voltage;
|
||||
|
||||
|
||||
int (*i2c_gate_ctrl)(struct dvb_frontend *, int);
|
||||
int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
|
||||
int (*set_input)(struct dvb_frontend *fe, int input);
|
||||
int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
|
||||
int (*diseqc_send_master_cmd)(struct dvb_frontend *fe,
|
||||
struct dvb_diseqc_master_cmd *cmd);
|
||||
};
|
||||
|
||||
struct ddb_ci {
|
||||
@@ -236,6 +274,7 @@ struct ddb_ci {
|
||||
struct ddb_io {
|
||||
struct ddb_port *port;
|
||||
u32 nr;
|
||||
u32 regs;
|
||||
struct ddb_dma *dma;
|
||||
struct ddb_io *redo;
|
||||
struct ddb_io *redi;
|
||||
@@ -271,6 +310,7 @@ struct ddb_port {
|
||||
#define DDB_PORT_LOOP 3
|
||||
#define DDB_PORT_MOD 4
|
||||
char *name;
|
||||
char *type_name;
|
||||
u32 type;
|
||||
#define DDB_TUNER_NONE 0
|
||||
#define DDB_TUNER_DVBS_ST 1
|
||||
@@ -286,14 +326,16 @@ struct ddb_port {
|
||||
#define DDB_TUNER_MXL5XX 11
|
||||
#define DDB_CI_EXTERNAL_XO2 12
|
||||
#define DDB_CI_EXTERNAL_XO2_B 13
|
||||
#define DDB_TUNER_DVBS_STV0910_PR 14
|
||||
#define DDB_TUNER_DVBC2T2I_SONY_P 15
|
||||
|
||||
#define DDB_TUNER_XO2 16
|
||||
#define DDB_TUNER_DVBS_STV0910 16
|
||||
#define DDB_TUNER_DVBCT2_SONY 17
|
||||
#define DDB_TUNER_ISDBT_SONY 18
|
||||
#define DDB_TUNER_DVBC2T2_SONY 19
|
||||
#define DDB_TUNER_ATSC_ST 20
|
||||
#define DDB_TUNER_DVBC2T2_ST 21
|
||||
#define DDB_TUNER_XO2 32
|
||||
#define DDB_TUNER_DVBS_STV0910 (DDB_TUNER_XO2 + 0)
|
||||
#define DDB_TUNER_DVBCT2_SONY (DDB_TUNER_XO2 + 1)
|
||||
#define DDB_TUNER_ISDBT_SONY (DDB_TUNER_XO2 + 2)
|
||||
#define DDB_TUNER_DVBC2T2_SONY (DDB_TUNER_XO2 + 3)
|
||||
#define DDB_TUNER_ATSC_ST (DDB_TUNER_XO2 + 4)
|
||||
#define DDB_TUNER_DVBC2T2I_SONY (DDB_TUNER_XO2 + 5)
|
||||
|
||||
struct ddb_input *input[2];
|
||||
struct ddb_output *output;
|
||||
@@ -310,8 +352,15 @@ struct mod_base {
|
||||
u32 flat_end;
|
||||
};
|
||||
|
||||
struct mod_state {
|
||||
struct ddb_mod {
|
||||
struct ddb_port *port;
|
||||
//u32 nr;
|
||||
//u32 regs;
|
||||
|
||||
u32 frequency;
|
||||
u32 modulation;
|
||||
u32 symbolrate;
|
||||
|
||||
u64 obitrate;
|
||||
u64 ibitrate;
|
||||
u32 pcr_correction;
|
||||
@@ -367,11 +416,10 @@ struct ddb_ns {
|
||||
struct ddb_lnb {
|
||||
struct mutex lock;
|
||||
u32 tone;
|
||||
fe_sec_voltage_t oldvoltage[4];
|
||||
fe_sec_voltage_t oldvoltage[4];
|
||||
u32 voltage[4];
|
||||
u32 voltages;
|
||||
u32 fmode;
|
||||
u32 setmode;
|
||||
};
|
||||
|
||||
struct ddb_link {
|
||||
@@ -383,19 +431,23 @@ struct ddb_link {
|
||||
struct mutex flash_mutex;
|
||||
struct ddb_lnb lnb;
|
||||
struct tasklet_struct tasklet;
|
||||
struct ddb_ids ids;
|
||||
|
||||
spinlock_t temp_lock;
|
||||
int OverTemperatureError;
|
||||
u8 temp_tab[11];
|
||||
};
|
||||
|
||||
struct ddb {
|
||||
struct pci_dev *pdev;
|
||||
struct platform_device *pfdev;
|
||||
struct device *dev;
|
||||
struct ddb_ids ids;
|
||||
|
||||
|
||||
int msi;
|
||||
struct workqueue_struct *wq;
|
||||
u32 has_dma;
|
||||
u32 has_ns;
|
||||
|
||||
|
||||
struct ddb_link link[DDB_MAX_LINK];
|
||||
unsigned char *regs;
|
||||
u32 regs_len;
|
||||
@@ -406,10 +458,11 @@ struct ddb {
|
||||
struct ddb_input input[DDB_MAX_INPUT];
|
||||
struct ddb_output output[DDB_MAX_OUTPUT];
|
||||
struct dvb_adapter adap[DDB_MAX_INPUT];
|
||||
struct ddb_dma dma[DDB_MAX_INPUT + DDB_MAX_OUTPUT];
|
||||
|
||||
void (*handler[128])(unsigned long);
|
||||
unsigned long handler_data[128];
|
||||
struct ddb_dma idma[DDB_MAX_INPUT];
|
||||
struct ddb_dma odma[DDB_MAX_OUTPUT];
|
||||
|
||||
void (*handler[4][256])(unsigned long);
|
||||
unsigned long handler_data[4][256];
|
||||
|
||||
struct device *ddb_dev;
|
||||
u32 ddb_dev_users;
|
||||
@@ -429,221 +482,10 @@ struct ddb {
|
||||
u8 tsbuf[TS_CAPTURE_LEN];
|
||||
|
||||
struct mod_base mod_base;
|
||||
struct mod_state mod[10];
|
||||
struct ddb_mod mod[24];
|
||||
|
||||
};
|
||||
|
||||
static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr)
|
||||
{
|
||||
writeb(val, (char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static inline u32 ddbreadb(struct ddb *dev, u32 adr)
|
||||
{
|
||||
return readb((char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static inline void ddbwritel0(struct ddb_link *link, u32 val, u32 adr)
|
||||
{
|
||||
writel(val, (char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static inline u32 ddbreadl0(struct ddb_link *link, u32 adr)
|
||||
{
|
||||
return readl((char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline void gtlw(struct ddb_link *link)
|
||||
{
|
||||
u32 count = 0;
|
||||
static u32 max = 0;
|
||||
|
||||
while (1 & ddbreadl0(link, link->regs + 0x10)) {
|
||||
if (++count == 1024) {
|
||||
printk("LTO\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count > max) {
|
||||
max = count;
|
||||
printk("TO=%u\n", max);
|
||||
}
|
||||
if (ddbreadl0(link, link->regs + 0x10) & 0x8000)
|
||||
printk("link error\n");
|
||||
}
|
||||
#else
|
||||
static inline void gtlw(struct ddb_link *link)
|
||||
{
|
||||
while (1 & ddbreadl0(link, link->regs + 0x10));
|
||||
}
|
||||
#endif
|
||||
|
||||
static u32 ddblreadl(struct ddb_link *link, u32 adr)
|
||||
{
|
||||
if (unlikely(link->nr)) {
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
|
||||
ddbwritel0(link, 3, link->regs + 0x10);
|
||||
gtlw(link);
|
||||
val = ddbreadl0(link, link->regs + 0x1c);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return val;
|
||||
}
|
||||
return readl((char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static void ddblwritel(struct ddb_link *link, u32 val, u32 adr)
|
||||
{
|
||||
if (unlikely(link->nr)) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
|
||||
ddbwritel0(link, val, link->regs + 0x18);
|
||||
ddbwritel0(link, 1, link->regs + 0x10);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return;
|
||||
}
|
||||
writel(val, (char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static u32 ddbreadl(struct ddb *dev, u32 adr)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000)) {
|
||||
unsigned long flags;
|
||||
u32 val, l = (adr >> DDB_LINK_SHIFT);
|
||||
struct ddb_link *link = &dev->link[l];
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
|
||||
ddbwritel0(link, 3, link->regs + 0x10);
|
||||
gtlw(link);
|
||||
val = ddbreadl0(link, link->regs + 0x1c);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return val;
|
||||
}
|
||||
return readl((char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static void ddbwritel(struct ddb *dev, u32 val, u32 adr)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000)) {
|
||||
unsigned long flags;
|
||||
u32 l = (adr >> DDB_LINK_SHIFT);
|
||||
struct ddb_link *link = &dev->link[l];
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
|
||||
ddbwritel0(link, val, link->regs + 0x18);
|
||||
ddbwritel0(link, 1, link->regs + 0x10);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return;
|
||||
}
|
||||
writel(val, (char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf,
|
||||
unsigned int count)
|
||||
{
|
||||
u32 val = 0, p = adr;
|
||||
u32 aa = p & 3;
|
||||
|
||||
if (aa) {
|
||||
while (p & 3 && count) {
|
||||
val >>= 8;
|
||||
val |= *buf << 24;
|
||||
p++;
|
||||
buf++;
|
||||
count--;
|
||||
}
|
||||
ddbwritel(dev, val, adr);
|
||||
}
|
||||
while (count >= 4) {
|
||||
val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
||||
ddbwritel(dev, val, p);
|
||||
p += 4;
|
||||
buf += 4;
|
||||
count -= 4;
|
||||
}
|
||||
if (count) {
|
||||
val = buf[0];
|
||||
if (count > 1)
|
||||
val |= buf[1] << 8;
|
||||
if (count > 2)
|
||||
val |= buf[2] << 16;
|
||||
ddbwritel(dev, val, p);
|
||||
}
|
||||
}
|
||||
|
||||
static void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count)
|
||||
{
|
||||
u32 val = 0, p = adr;
|
||||
u32 a = p & 3;
|
||||
|
||||
if (a) {
|
||||
val = ddbreadl(dev, p) >> (8 * a);
|
||||
while (p & 3 && count) {
|
||||
*buf = val & 0xff;
|
||||
val >>= 8;
|
||||
p++;
|
||||
buf++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
while (count >= 4) {
|
||||
val = ddbreadl(dev, p);
|
||||
buf[0] = val & 0xff;
|
||||
buf[1] = (val >> 8) & 0xff;
|
||||
buf[2] = (val >> 16) & 0xff;
|
||||
buf[3] = (val >> 24) & 0xff;
|
||||
p += 4;
|
||||
buf += 4;
|
||||
count -= 4;
|
||||
}
|
||||
if (count) {
|
||||
val = ddbreadl(dev, p);
|
||||
buf[0] = val & 0xff;
|
||||
if (count > 1)
|
||||
buf[1] = (val >> 8) & 0xff;
|
||||
if (count > 2)
|
||||
buf[2] = (val >> 16) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000))
|
||||
return gtlcpyto(dev, adr, src, count);
|
||||
return memcpy_toio((char *) (dev->regs + adr), src, count);
|
||||
}
|
||||
|
||||
static void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000))
|
||||
return gtlcpyfrom(dev, dst, adr, count);
|
||||
return memcpy_fromio(dst, (char *) (dev->regs + adr), count);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
#define ddbcpyto(_dev, _adr, _src, _count) \
|
||||
memcpy_toio((char *) (_dev->regs + (_adr)), (_src), (_count))
|
||||
|
||||
#define ddbcpyfrom(_dev, _dst, _adr, _count) \
|
||||
memcpy_fromio((_dst), (char *) (_dev->regs + (_adr)), (_count))
|
||||
#endif
|
||||
|
||||
#define ddbmemset(_dev, _adr, _val, _count) \
|
||||
memset_io((char *) (_dev->regs + (_adr)), (_val), (_count))
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
@@ -697,15 +539,39 @@ struct DDMOD_FLASH {
|
||||
#define DDMOD_FLASH_MAGIC 0x5F564d5F
|
||||
|
||||
|
||||
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
|
||||
|
||||
#define DDBRIDGE_VERSION "0.9.31"
|
||||
|
||||
/* linked function prototypes */
|
||||
|
||||
struct ddb_info *get_ddb_info(u16 vendor, u16 device, u16 subvendor, u16 subdevice);
|
||||
int netstream_init(struct ddb_input *input);
|
||||
int ddb_dvb_ns_input_start(struct ddb_input *input);
|
||||
int ddb_dvb_ns_input_stop(struct ddb_input *input);
|
||||
|
||||
int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg);
|
||||
int ddbridge_mod_init(struct ddb *dev);
|
||||
void ddbridge_mod_output_stop(struct ddb_output *output);
|
||||
void ddbridge_mod_output_start(struct ddb_output *output);
|
||||
int ddbridge_mod_output_start(struct ddb_output *output);
|
||||
void ddbridge_mod_rate_handler(unsigned long data);
|
||||
|
||||
void ddb_device_destroy(struct ddb *dev);
|
||||
void ddb_nsd_detach(struct ddb *dev);
|
||||
void ddb_ports_detach(struct ddb *dev);
|
||||
void ddb_ports_release(struct ddb *dev);
|
||||
void ddb_buffers_free(struct ddb *dev);
|
||||
void ddb_unmap(struct ddb *dev);
|
||||
irqreturn_t irq_handler0(int irq, void *dev_id);
|
||||
irqreturn_t irq_handler1(int irq, void *dev_id);
|
||||
irqreturn_t irq_handler(int irq, void *dev_id);
|
||||
irqreturn_t irq_handler_v2(int irq, void *dev_id);
|
||||
void ddb_reset_ios(struct ddb *dev);
|
||||
int ddb_init(struct ddb *dev);
|
||||
int ddb_class_create(void);
|
||||
void ddb_class_destroy(void);
|
||||
|
||||
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
|
||||
|
||||
#define DDBRIDGE_VERSION "0.9.19"
|
||||
int ddb_i2c_init(struct ddb *dev);
|
||||
void ddb_i2c_release(struct ddb *dev);
|
||||
|
||||
#endif
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* octonet.c: Digital Devices network tuner driver
|
||||
*
|
||||
* Copyright (C) 2012-15 Digital Devices GmbH
|
||||
* Copyright (C) 2012-17 Digital Devices GmbH
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
*
|
||||
@@ -24,88 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-regs.h"
|
||||
#include <asm-generic/pci-dma-compat.h>
|
||||
|
||||
static int adapter_alloc = 3;
|
||||
module_param(adapter_alloc, int, 0444);
|
||||
MODULE_PARM_DESC(adapter_alloc,
|
||||
"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all");
|
||||
|
||||
#include "ddbridge-core.c"
|
||||
|
||||
static struct ddb_regset octopus_i2c = {
|
||||
.base = 0x80,
|
||||
.num = 0x04,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_i2c_buf = {
|
||||
.base = 0x1000,
|
||||
.num = 0x04,
|
||||
.size = 0x200,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_net_map = {
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_gtl = {
|
||||
.base = 0x180,
|
||||
.num = 0x01,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_net_gtl = {
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
.gtl = &octopus_gtl,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet network DVB adapter",
|
||||
.regmap = &octopus_net_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet_jse = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet network DVB adapter JSE",
|
||||
.regmap = &octopus_net_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.ns_num = 15,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet_gtl = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet GTL",
|
||||
.regmap = &octopus_net_gtl,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x05,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
.con_clock = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet_tbd = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet",
|
||||
.regmap = &octopus_net_map,
|
||||
};
|
||||
|
||||
static void octonet_unmap(struct ddb *dev)
|
||||
{
|
||||
if (dev->regs)
|
||||
iounmap(dev->regs);
|
||||
vfree(dev);
|
||||
}
|
||||
#include "ddbridge-io.h"
|
||||
|
||||
static int __exit octonet_remove(struct platform_device *pdev)
|
||||
{
|
||||
@@ -113,17 +32,18 @@ static int __exit octonet_remove(struct platform_device *pdev)
|
||||
|
||||
dev = platform_get_drvdata(pdev);
|
||||
|
||||
ddb_device_destroy(dev);
|
||||
ddb_nsd_detach(dev);
|
||||
ddb_ports_detach(dev);
|
||||
ddb_i2c_release(dev);
|
||||
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
if (dev->link[0].info->ns_num)
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
ddbwritel(dev, 0, INTERRUPT_ENABLE);
|
||||
free_irq(platform_get_irq(dev->pfdev, 0), dev);
|
||||
|
||||
free_irq(platform_get_irq(dev->pfdev, 0), dev);
|
||||
ddb_ports_release(dev);
|
||||
ddb_device_destroy(dev);
|
||||
octonet_unmap(dev);
|
||||
ddb_unmap(dev);
|
||||
platform_set_drvdata(pdev, 0);
|
||||
return 0;
|
||||
}
|
||||
@@ -133,7 +53,6 @@ static int __init octonet_probe(struct platform_device *pdev)
|
||||
struct ddb *dev;
|
||||
struct resource *regs;
|
||||
int irq;
|
||||
int i;
|
||||
|
||||
dev = vzalloc(sizeof(struct ddb));
|
||||
if (!dev)
|
||||
@@ -156,35 +75,40 @@ static int __init octonet_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev->ids.hwid = ddbreadl(dev, 0);
|
||||
dev->ids.regmapid = ddbreadl(dev, 4);
|
||||
dev->ids.devid = ddbreadl(dev, 8);
|
||||
dev->ids.mac = ddbreadl(dev, 12);
|
||||
dev->link[0].ids.hwid = ddbreadl(dev, 0);
|
||||
dev->link[0].ids.regmapid = ddbreadl(dev, 4);
|
||||
dev->link[0].ids.devid = ddbreadl(dev, 8);
|
||||
dev->link[0].ids.mac = ddbreadl(dev, 12);
|
||||
|
||||
dev->ids.vendor = dev->ids.devid & 0xffff;
|
||||
dev->ids.device = dev->ids.devid >> 16;
|
||||
dev->ids.subvendor = dev->ids.devid & 0xffff;
|
||||
dev->ids.subdevice = dev->ids.devid >> 16;
|
||||
dev->link[0].ids.vendor = dev->link[0].ids.devid & 0xffff;
|
||||
dev->link[0].ids.device = dev->link[0].ids.devid >> 16;
|
||||
dev->link[0].ids.subvendor = dev->link[0].ids.devid & 0xffff;
|
||||
dev->link[0].ids.subdevice = dev->link[0].ids.devid >> 16;
|
||||
|
||||
dev->link[0].dev = dev;
|
||||
if (dev->ids.devid == 0x0300dd01)
|
||||
#if 0
|
||||
if (dev->link[0].ids.devid == 0x0300dd01)
|
||||
dev->link[0].info = &ddb_octonet;
|
||||
else if (dev->ids.devid == 0x0301dd01)
|
||||
else if (dev->link[0].ids.devid == 0x0301dd01)
|
||||
dev->link[0].info = &ddb_octonet_jse;
|
||||
else if (dev->ids.devid == 0x0307dd01)
|
||||
else if (dev->link[0].ids.devid == 0x0307dd01)
|
||||
dev->link[0].info = &ddb_octonet_gtl;
|
||||
else
|
||||
dev->link[0].info = &ddb_octonet_tbd;
|
||||
|
||||
pr_info("HW %08x REGMAP %08x\n", dev->ids.hwid, dev->ids.regmapid);
|
||||
pr_info("MAC %08x DEVID %08x\n", dev->ids.mac, dev->ids.devid);
|
||||
#else
|
||||
dev->link[0].info = get_ddb_info(dev->link[0].ids.vendor,
|
||||
dev->link[0].ids.device,
|
||||
0xdd01, 0xffff);
|
||||
#endif
|
||||
pr_info("DDBridge: HW %08x REGMAP %08x\n",
|
||||
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
|
||||
pr_info("DDBridge: MAC %08x DEVID %08x\n",
|
||||
dev->link[0].ids.mac, dev->link[0].ids.devid);
|
||||
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_STATUS);
|
||||
for (i = 0; i < 16; i++)
|
||||
ddbwritel(dev, 0x00, TS_OUTPUT_CONTROL(i));
|
||||
usleep_range(5000, 6000);
|
||||
ddb_reset_ios(dev);
|
||||
|
||||
irq = platform_get_irq(dev->pfdev, 0);
|
||||
if (irq < 0)
|
||||
@@ -202,7 +126,7 @@ fail:
|
||||
dev_err(dev->dev, "fail\n");
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
ddbwritel(dev, 0, INTERRUPT_ENABLE);
|
||||
octonet_unmap(dev);
|
||||
ddb_unmap(dev);
|
||||
platform_set_drvdata(pdev, 0);
|
||||
return -1;
|
||||
}
|
||||
@@ -216,7 +140,7 @@ static const struct of_device_id octonet_dt_ids[] = {
|
||||
MODULE_DEVICE_TABLE(of, octonet_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct platform_driver octonet_driver = {
|
||||
static struct platform_driver octonet_driver __refdata = {
|
||||
.remove = __exit_p(octonet_remove),
|
||||
.probe = octonet_probe,
|
||||
.driver = {
|
||||
@@ -232,8 +156,8 @@ static __init int init_octonet(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION
|
||||
", Copyright (C) 2010-14 Digital Devices GmbH\n");
|
||||
pr_info("DDBridge: Digital Devices OctopusNet driver " DDBRIDGE_VERSION
|
||||
", Copyright (C) 2010-16 Digital Devices GmbH\n");
|
||||
res = ddb_class_create();
|
||||
if (res)
|
||||
return res;
|
||||
@@ -257,4 +181,4 @@ module_exit(exit_octonet);
|
||||
MODULE_DESCRIPTION("GPL");
|
||||
MODULE_AUTHOR("Marcus and Ralph Metzler, Metzler Brothers Systementwicklung GbR");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("0.6");
|
||||
MODULE_VERSION(DDBRIDGE_VERSION);
|
22
docs/ci
22
docs/ci
@@ -1,3 +1,5 @@
|
||||
- General Information
|
||||
|
||||
The caX device associated with a CI device behaves just like any other
|
||||
caX interface. You usually use it through a library like libdvben50221
|
||||
which is part of the dvb-apps package available at linuxtv.org.
|
||||
@@ -26,6 +28,24 @@ use the new interface.
|
||||
See docs/redirect for more info.
|
||||
|
||||
|
||||
- Clock Speed
|
||||
|
||||
The normal clock speed for the TS output is 72 MHz wich is the standard
|
||||
speed used for CI.
|
||||
|
||||
Packets are sent with an adjustable gap between the packets.
|
||||
The gap size is (gap value * 2) + 4 or 0 if the gap is disabled.
|
||||
So, the standard gap value of 4 leads to a gap of 12 bytes which means
|
||||
that the effective data rate is (72*188)/200 = 67.68 MBits/s.
|
||||
|
||||
Depending on the hardware, the clock speed can be changed with the
|
||||
ci_bitrate module parameter:
|
||||
|
||||
- Octopus CI, Octopus CI S2 Pro : supported
|
||||
|
||||
- old CI single flex modules: supported
|
||||
|
||||
- new dual CI flex module: not yet supported, use the standard 72000 kHz
|
||||
|
||||
|
||||
|
||||
Valid ranges for are from ... to 96000 KHz.
|
||||
|
29
dvb-core/Kconfig
Normal file
29
dvb-core/Kconfig
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# DVB device configuration
|
||||
#
|
||||
|
||||
config DVB_MAX_ADAPTERS
|
||||
int "maximum number of DVB/ATSC adapters"
|
||||
depends on DVB_CORE
|
||||
default 8
|
||||
range 1 255
|
||||
help
|
||||
Maximum number of DVB/ATSC adapters. Increasing this number
|
||||
increases the memory consumption of the DVB subsystem even
|
||||
if a much lower number of DVB/ATSC adapters is present.
|
||||
Only values in the range 4-32 are tested.
|
||||
|
||||
If you are unsure about this, use the default value 8
|
||||
|
||||
config DVB_DYNAMIC_MINORS
|
||||
bool "Dynamic DVB minor allocation"
|
||||
depends on DVB_CORE
|
||||
default n
|
||||
help
|
||||
If you say Y here, the DVB subsystem will use dynamic minor
|
||||
allocation for any device that uses the DVB major number.
|
||||
This means that you can have more than 4 of a single type
|
||||
of device (like demuxes and frontends) per adapter, but udev
|
||||
will be required to manage the device nodes.
|
||||
|
||||
If you are unsure about this, say N here.
|
12
dvb-core/Makefile.kernel
Normal file
12
dvb-core/Makefile.kernel
Normal file
@@ -0,0 +1,12 @@
|
||||
#
|
||||
# Makefile for the kernel DVB device drivers.
|
||||
#
|
||||
|
||||
dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
|
||||
|
||||
dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
|
||||
dvb_ca_en50221.o dvb_frontend.o \
|
||||
$(dvb-net-y) dvb_ringbuffer.o dvb_math.o \
|
||||
dvb_netstream.o
|
||||
|
||||
obj-$(CONFIG_DVB_CORE) += dvb-core.o
|
@@ -35,7 +35,12 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/delay.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>
|
||||
#endif
|
||||
#include <linux/kthread.h>
|
||||
|
||||
#include "dvb_ca_en50221.h"
|
||||
@@ -315,7 +320,7 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
|
||||
/* read the buffer size from the CAM */
|
||||
if ((ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | CMDREG_SR)) != 0)
|
||||
return ret;
|
||||
if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ / 10)) != 0)
|
||||
if ((ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_DA, HZ)) != 0)
|
||||
return ret;
|
||||
if ((ret = dvb_ca_en50221_read_data(ca, slot, buf, 2)) != 2)
|
||||
return -EIO;
|
||||
@@ -763,7 +768,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
|
||||
status = -EAGAIN;
|
||||
goto exit;
|
||||
}
|
||||
#if 0
|
||||
|
||||
/* It may need some time for the CAM to settle down, or there might be a
|
||||
race condition between the CAM, writing HC and our last check for DA.
|
||||
This happens, if the CAM asserts DA, just after checking DA before we
|
||||
@@ -781,7 +786,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
|
||||
status = -EAGAIN;
|
||||
goto exit;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* send the amount of data */
|
||||
if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0)
|
||||
goto exit;
|
||||
|
@@ -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>
|
||||
#endif
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
|
@@ -955,6 +955,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
|
||||
}
|
||||
|
||||
c->stream_id = NO_STREAM_ID_FILTER;
|
||||
c->pls = NO_SCRAMBLING_CODE;
|
||||
|
||||
switch (c->delivery_system) {
|
||||
case SYS_DVBS:
|
||||
@@ -1031,6 +1032,7 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
|
||||
_DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0),
|
||||
_DTV_CMD(DTV_LNA, 1, 0),
|
||||
_DTV_CMD(DTV_INPUT, 1, 0),
|
||||
_DTV_CMD(DTV_PLS, 1, 0),
|
||||
|
||||
/* Get */
|
||||
_DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
|
||||
@@ -1462,6 +1464,10 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
|
||||
tvp->u.buffer.len = 4;
|
||||
break;
|
||||
|
||||
case DTV_PLS:
|
||||
tvp->u.data = c->pls;
|
||||
break;
|
||||
|
||||
/* Fill quality measures */
|
||||
case DTV_STAT_SIGNAL_STRENGTH:
|
||||
tvp->u.st = c->strength;
|
||||
@@ -1901,6 +1907,10 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
|
||||
r = fe->ops.set_input(fe, c->input);
|
||||
break;
|
||||
|
||||
case DTV_PLS:
|
||||
c->pls = tvp->u.data;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@@ -29,7 +29,12 @@
|
||||
#define _DVB_FRONTEND_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>
|
||||
#endif
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
@@ -397,6 +402,7 @@ struct dtv_frontend_properties {
|
||||
|
||||
u32 lna;
|
||||
s32 input;
|
||||
u32 pls;
|
||||
|
||||
/* statistics data */
|
||||
struct dtv_fe_stats strength;
|
||||
|
@@ -1227,7 +1227,9 @@ static int dvb_net_stop(struct net_device *dev)
|
||||
static const struct header_ops dvb_header_ops = {
|
||||
.create = eth_header,
|
||||
.parse = eth_header_parse,
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 2)
|
||||
.rebuild = eth_rebuild_header,
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@@ -31,7 +31,12 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/version.h>
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
|
||||
#include <asm/uaccess.h>
|
||||
#else
|
||||
#include <linux/uaccess.h>
|
||||
#endif
|
||||
|
||||
#include "dvb_ringbuffer.h"
|
||||
|
||||
|
@@ -33,7 +33,7 @@
|
||||
#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
|
||||
#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
|
||||
#else
|
||||
#define DVB_MAX_ADAPTERS 8
|
||||
#define DVB_MAX_ADAPTERS 64
|
||||
#endif
|
||||
|
||||
#define DVB_UNSET (-1)
|
||||
|
838
frontends/Kconfig
Normal file
838
frontends/Kconfig
Normal file
@@ -0,0 +1,838 @@
|
||||
menu "Customise DVB Frontends"
|
||||
visible if !MEDIA_SUBDRV_AUTOSELECT
|
||||
|
||||
comment "Multistandard (satellite) frontends"
|
||||
depends on DVB_CORE
|
||||
|
||||
config DVB_STB0899
|
||||
tristate "STB0899 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S/S2/DSS Multistandard demodulator. Say Y when you want
|
||||
to support this demodulator based frontends
|
||||
|
||||
config DVB_STB6100
|
||||
tristate "STB6100 based tuners"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A Silicon tuner from ST used in conjunction with the STB0899
|
||||
demodulator. Say Y when you want to support this tuner.
|
||||
|
||||
config DVB_STV090x
|
||||
tristate "STV0900/STV0903(A/B) based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
|
||||
Say Y when you want to support these frontends.
|
||||
|
||||
config DVB_STV6110x
|
||||
tristate "STV6110/(A) based tuners"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A Silicon tuner that supports DVB-S and DVB-S2 modes
|
||||
|
||||
config DVB_STV0910
|
||||
tristate "STV0910 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
|
||||
Say Y when you want to support these frontends.
|
||||
|
||||
config DVB_MXL5XX
|
||||
tristate "MXL5XX based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
|
||||
Say Y when you want to support these frontends.
|
||||
|
||||
config DVB_STV6111
|
||||
tristate "STV6111 based tuners"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A Silicon tuner that supports DVB-S and DVB-S2 modes
|
||||
|
||||
config DVB_M88DS3103
|
||||
tristate "Montage M88DS3103"
|
||||
depends on DVB_CORE && I2C && I2C_MUX
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
comment "Multistandard (cable + terrestrial) frontends"
|
||||
depends on DVB_CORE
|
||||
|
||||
config DVB_DRXK
|
||||
tristate "Micronas DRXK based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Micronas DRX-K DVB-C/T demodulator.
|
||||
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
|
||||
config DVB_TDA18271C2DD
|
||||
tristate "NXP TDA18271C2 silicon tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
NXP TDA18271 silicon tuner.
|
||||
|
||||
Say Y when you want to support this tuner.
|
||||
|
||||
config DVB_SI2165
|
||||
tristate "Silicon Labs si2165 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-C/T demodulator.
|
||||
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
comment "DVB-S (satellite) frontends"
|
||||
depends on DVB_CORE
|
||||
|
||||
config DVB_CX24110
|
||||
tristate "Conexant CX24110 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_CX24123
|
||||
tristate "Conexant CX24123 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_MT312
|
||||
tristate "Zarlink VP310/MT312/ZL10313 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_ZL10036
|
||||
tristate "Zarlink ZL10036 silicon tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_ZL10039
|
||||
tristate "Zarlink ZL10039 silicon tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_S5H1420
|
||||
tristate "Samsung S5H1420 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_STV0288
|
||||
tristate "ST STV0288 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_STB6000
|
||||
tristate "ST STB6000 silicon tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
|
||||
|
||||
config DVB_STV0299
|
||||
tristate "ST STV0299 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_STV6110
|
||||
tristate "ST STV6110 silicon tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
|
||||
|
||||
config DVB_STV0900
|
||||
tristate "ST STV0900 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S/S2 demodulator. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TDA8083
|
||||
tristate "Philips TDA8083 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TDA10086
|
||||
tristate "Philips TDA10086 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TDA8261
|
||||
tristate "Philips TDA8261 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_VES1X93
|
||||
tristate "VLSI VES1893 or VES1993 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TUNER_ITD1000
|
||||
tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TUNER_CX24113
|
||||
tristate "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
|
||||
config DVB_TDA826X
|
||||
tristate "Philips TDA826X silicon tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
|
||||
|
||||
config DVB_TUA6100
|
||||
tristate "Infineon TUA6100 PLL"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S PLL chip.
|
||||
|
||||
config DVB_CX24116
|
||||
tristate "Conexant CX24116 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_CX24117
|
||||
tristate "Conexant CX24117 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A Dual DVB-S/S2 tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_SI21XX
|
||||
tristate "Silicon Labs SI21XX based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TS2020
|
||||
tristate "Montage Tehnology TS2020 based tuners"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S/S2 silicon tuner. Say Y when you want to support this tuner.
|
||||
|
||||
config DVB_DS3000
|
||||
tristate "Montage Tehnology DS3000 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_MB86A16
|
||||
tristate "Fujitsu MB86A16 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S/DSS Direct Conversion reveiver.
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TDA10071
|
||||
tristate "NXP TDA10071"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
comment "DVB-T (terrestrial) frontends"
|
||||
depends on DVB_CORE
|
||||
|
||||
config DVB_SP8870
|
||||
tristate "Spase sp8870 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
This driver needs external firmware. Please use the command
|
||||
"<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to
|
||||
download/extract it, and then copy it to /usr/lib/hotplug/firmware
|
||||
or /lib/firmware (depending on configuration of firmware hotplug).
|
||||
|
||||
config DVB_SP887X
|
||||
tristate "Spase sp887x based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
This driver needs external firmware. Please use the command
|
||||
"<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
|
||||
download/extract it, and then copy it to /usr/lib/hotplug/firmware
|
||||
or /lib/firmware (depending on configuration of firmware hotplug).
|
||||
|
||||
config DVB_CX22700
|
||||
tristate "Conexant CX22700 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_CX22702
|
||||
tristate "Conexant cx22702 demodulator (OFDM)"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_S5H1432
|
||||
tristate "Samsung s5h1432 demodulator (OFDM)"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_DRXD
|
||||
tristate "Micronas DRXD driver"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
Note: this driver was based on vendor driver reference code (released
|
||||
under the GPL) as opposed to the existing drx397xd driver, which
|
||||
was written via reverse engineering.
|
||||
|
||||
config DVB_L64781
|
||||
tristate "LSI L64781"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TDA1004X
|
||||
tristate "Philips TDA10045H/TDA10046H based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
This driver needs external firmware. Please use the commands
|
||||
"<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
|
||||
"<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
|
||||
download/extract them, and then copy them to /usr/lib/hotplug/firmware
|
||||
or /lib/firmware (depending on configuration of firmware hotplug).
|
||||
|
||||
config DVB_NXT6000
|
||||
tristate "NxtWave Communications NXT6000 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_MT352
|
||||
tristate "Zarlink MT352 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_ZL10353
|
||||
tristate "Zarlink ZL10353 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_DIB3000MB
|
||||
tristate "DiBcom 3000M-B"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_DIB3000MC
|
||||
tristate "DiBcom 3000P/M-C"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_DIB7000M
|
||||
tristate "DiBcom 7000MA/MB/PA/PB/MC"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_DIB7000P
|
||||
tristate "DiBcom 7000PC"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_DIB9000
|
||||
tristate "DiBcom 9000"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_TDA10048
|
||||
tristate "Philips TDA10048HN based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TDA18212DD
|
||||
tristate "Philips TDA18212 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_AF9013
|
||||
tristate "Afatech AF9013 demodulator"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_EC100
|
||||
tristate "E3C EC100"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_HD29L2
|
||||
tristate "HDIC HD29L2"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_STV0367
|
||||
tristate "ST STV0367 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T/C tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_STV0367DD
|
||||
tristate "ST STV0367dd based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T/C tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_CXD2843
|
||||
tristate "Sony CXD2843"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-T/T2/C/C2 tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_CXD2820R
|
||||
tristate "Sony CXD2820R"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_RTL2830
|
||||
tristate "Realtek RTL2830 DVB-T"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_RTL2832
|
||||
tristate "Realtek RTL2832 DVB-T"
|
||||
depends on DVB_CORE && I2C && I2C_MUX
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_RTL2832_SDR
|
||||
tristate "Realtek RTL2832 SDR"
|
||||
depends on DVB_CORE && I2C && I2C_MUX && VIDEO_V4L2 && MEDIA_SDR_SUPPORT && USB
|
||||
select DVB_RTL2832
|
||||
select VIDEOBUF2_VMALLOC
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this SDR module.
|
||||
|
||||
config DVB_SI2168
|
||||
tristate "Silicon Labs Si2168"
|
||||
depends on DVB_CORE && I2C && I2C_MUX
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
comment "DVB-C (cable) frontends"
|
||||
depends on DVB_CORE
|
||||
|
||||
config DVB_VES1820
|
||||
tristate "VLSI VES1820 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-C tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TDA10021
|
||||
tristate "Philips TDA10021 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-C tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TDA10023
|
||||
tristate "Philips TDA10023 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-C tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_STV0297
|
||||
tristate "ST STV0297 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-C tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
|
||||
depends on DVB_CORE
|
||||
|
||||
config DVB_NXT200X
|
||||
tristate "NxtWave Communications NXT2002/NXT2004 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
This driver needs external firmware. Please use the commands
|
||||
"<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and
|
||||
"<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
|
||||
download/extract them, and then copy them to /usr/lib/hotplug/firmware
|
||||
or /lib/firmware (depending on configuration of firmware hotplug).
|
||||
|
||||
config DVB_OR51211
|
||||
tristate "Oren OR51211 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
This driver needs external firmware. Please use the command
|
||||
"<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
|
||||
download it, and then copy it to /usr/lib/hotplug/firmware
|
||||
or /lib/firmware (depending on configuration of firmware hotplug).
|
||||
|
||||
config DVB_OR51132
|
||||
tristate "Oren OR51132 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
This driver needs external firmware. Please use the commands
|
||||
"<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_vsb" and/or
|
||||
"<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_qam" to
|
||||
download firmwares for 8VSB and QAM64/256, respectively. Copy them to
|
||||
/usr/lib/hotplug/firmware or /lib/firmware (depending on
|
||||
configuration of firmware hotplug).
|
||||
|
||||
config DVB_BCM3510
|
||||
tristate "Broadcom BCM3510"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
|
||||
support this frontend.
|
||||
|
||||
config DVB_LGDT330X
|
||||
tristate "LG Electronics LGDT3302/LGDT3303 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_LGDT3305
|
||||
tristate "LG Electronics LGDT3304 and LGDT3305 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_LG2160
|
||||
tristate "LG Electronics LG216x based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC/MH demodulator module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_S5H1409
|
||||
tristate "Samsung S5H1409 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
config DVB_AU8522
|
||||
depends on I2C
|
||||
tristate
|
||||
|
||||
config DVB_AU8522_DTV
|
||||
tristate "Auvitek AU8522 based DTV demod"
|
||||
depends on DVB_CORE && I2C
|
||||
select DVB_AU8522
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
|
||||
you want to enable DTV demodulation support for this frontend.
|
||||
|
||||
config DVB_AU8522_V4L
|
||||
tristate "Auvitek AU8522 based ATV demod"
|
||||
depends on VIDEO_V4L2 && I2C
|
||||
select DVB_AU8522
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
|
||||
you want to enable ATV demodulation support for this frontend.
|
||||
|
||||
config DVB_S5H1411
|
||||
tristate "Samsung S5H1411 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
|
||||
to support this frontend.
|
||||
|
||||
comment "ISDB-T (terrestrial) frontends"
|
||||
depends on DVB_CORE
|
||||
|
||||
config DVB_S921
|
||||
tristate "Sharp S921 frontend"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_DIB8000
|
||||
tristate "DiBcom 8000MB/MC"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_MB86A20S
|
||||
tristate "Fujitsu mb86a20s"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
comment "Digital terrestrial only tuners/PLL"
|
||||
depends on DVB_CORE
|
||||
|
||||
config DVB_PLL
|
||||
tristate "Generic I2C PLL based tuners"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
This module drives a number of tuners based on PLL chips with a
|
||||
common I2C interface. Say Y when you want to support these tuners.
|
||||
|
||||
config DVB_TUNER_DIB0070
|
||||
tristate "DiBcom DiB0070 silicon base-band tuner"
|
||||
depends on I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A driver for the silicon baseband tuner DiB0070 from DiBcom.
|
||||
This device is only used inside a SiP called together with a
|
||||
demodulator for now.
|
||||
|
||||
config DVB_TUNER_DIB0090
|
||||
tristate "DiBcom DiB0090 silicon base-band tuner"
|
||||
depends on I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A driver for the silicon baseband tuner DiB0090 from DiBcom.
|
||||
This device is only used inside a SiP called together with a
|
||||
demodulator for now.
|
||||
|
||||
comment "SEC control devices for DVB-S"
|
||||
depends on DVB_CORE
|
||||
|
||||
source "drivers/media/dvb-frontends/drx39xyj/Kconfig"
|
||||
|
||||
config DVB_LNBP21
|
||||
tristate "LNBP21/LNBH24 SEC controllers"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An SEC control chips.
|
||||
|
||||
config DVB_LNBH25
|
||||
tristate "LNBH25 SEC controllers"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An SEC control chips.
|
||||
|
||||
config DVB_LNBP22
|
||||
tristate "LNBP22 SEC controllers"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
LNB power supply and control voltage
|
||||
regulator chip with step-up converter
|
||||
and I2C interface.
|
||||
Say Y when you want to support this chip.
|
||||
|
||||
config DVB_ISL6405
|
||||
tristate "ISL6405 SEC controller"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An SEC control chip.
|
||||
|
||||
config DVB_ISL6421
|
||||
tristate "ISL6421 SEC controller"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
An SEC control chip.
|
||||
|
||||
config DVB_ISL6423
|
||||
tristate "ISL6423 SEC controller"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A SEC controller chip from Intersil
|
||||
|
||||
config DVB_A8293
|
||||
tristate "Allegro A8293"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
|
||||
config DVB_LGS8GL5
|
||||
tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DMB-TH tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_LGS8GXX
|
||||
tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator"
|
||||
depends on DVB_CORE && I2C
|
||||
select FW_LOADER
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DMB-TH tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_ATBM8830
|
||||
tristate "AltoBeam ATBM8830/8831 DMB-TH demodulator"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DMB-TH tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TDA665x
|
||||
tristate "TDA665x tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
Support for tuner modules based on Philips TDA6650/TDA6651 chips.
|
||||
Say Y when you want to support this chip.
|
||||
|
||||
Currently supported tuners:
|
||||
* Panasonic ENV57H12D5 (ET-50DT)
|
||||
|
||||
config DVB_IX2505V
|
||||
tristate "Sharp IX2505V silicon tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_M88RS2000
|
||||
tristate "M88RS2000 DVB-S demodulator and tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
help
|
||||
A DVB-S tuner module.
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_AF9033
|
||||
tristate "Afatech AF9033 DVB-T demodulator"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
|
||||
config DVB_CXD2099
|
||||
tristate "cxd2099"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if !MEDIA_SUBDRV_AUTOSELECT
|
||||
|
||||
comment "Tools to develop new frontends"
|
||||
|
||||
config DVB_DUMMY_FE
|
||||
tristate "Dummy frontend driver"
|
||||
default n
|
||||
endmenu
|
123
frontends/Makefile.kernel
Normal file
123
frontends/Makefile.kernel
Normal file
@@ -0,0 +1,123 @@
|
||||
#
|
||||
# Makefile for the kernel DVB frontend device drivers.
|
||||
#
|
||||
|
||||
ccflags-y += -I$(srctree)/drivers/media/dvb-core/
|
||||
ccflags-y += -I$(srctree)/drivers/media/tuners/
|
||||
|
||||
# FIXME: RTL2832 SDR driver uses power management directly from USB IF driver
|
||||
ifdef CONFIG_DVB_RTL2832_SDR
|
||||
ccflags-y += -I$(srctree)/drivers/media/usb/dvb-usb-v2
|
||||
endif
|
||||
|
||||
stb0899-objs := stb0899_drv.o stb0899_algo.o
|
||||
stv0900-objs := stv0900_core.o stv0900_sw.o
|
||||
drxd-objs := drxd_firm.o drxd_hard.o
|
||||
cxd2820r-objs := cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
|
||||
drxk-objs := drxk_hard.o
|
||||
|
||||
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
|
||||
obj-$(CONFIG_DVB_STV0299) += stv0299.o
|
||||
obj-$(CONFIG_DVB_STB0899) += stb0899.o
|
||||
obj-$(CONFIG_DVB_STB6100) += stb6100.o
|
||||
obj-$(CONFIG_DVB_SP8870) += sp8870.o
|
||||
obj-$(CONFIG_DVB_CX22700) += cx22700.o
|
||||
obj-$(CONFIG_DVB_S5H1432) += s5h1432.o
|
||||
obj-$(CONFIG_DVB_CX24110) += cx24110.o
|
||||
obj-$(CONFIG_DVB_TDA8083) += tda8083.o
|
||||
obj-$(CONFIG_DVB_L64781) += l64781.o
|
||||
obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
|
||||
obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
|
||||
obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o
|
||||
obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o
|
||||
obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o
|
||||
obj-$(CONFIG_DVB_DIB9000) += dib9000.o dibx000_common.o
|
||||
obj-$(CONFIG_DVB_MT312) += mt312.o
|
||||
obj-$(CONFIG_DVB_VES1820) += ves1820.o
|
||||
obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
|
||||
obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
|
||||
obj-$(CONFIG_DVB_SP887X) += sp887x.o
|
||||
obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
|
||||
obj-$(CONFIG_DVB_MT352) += mt352.o
|
||||
obj-$(CONFIG_DVB_ZL10036) += zl10036.o
|
||||
obj-$(CONFIG_DVB_ZL10039) += zl10039.o
|
||||
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
|
||||
obj-$(CONFIG_DVB_CX22702) += cx22702.o
|
||||
obj-$(CONFIG_DVB_DRXD) += drxd.o
|
||||
obj-$(CONFIG_DVB_TDA10021) += tda10021.o
|
||||
obj-$(CONFIG_DVB_TDA10023) += tda10023.o
|
||||
obj-$(CONFIG_DVB_STV0297) += stv0297.o
|
||||
obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
|
||||
obj-$(CONFIG_DVB_OR51211) += or51211.o
|
||||
obj-$(CONFIG_DVB_OR51132) += or51132.o
|
||||
obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
|
||||
obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
|
||||
obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
|
||||
obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
|
||||
obj-$(CONFIG_DVB_LG2160) += lg2160.o
|
||||
obj-$(CONFIG_DVB_CX24123) += cx24123.o
|
||||
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
|
||||
obj-$(CONFIG_DVB_LNBP22) += lnbp22.o
|
||||
obj-$(CONFIG_DVB_ISL6405) += isl6405.o
|
||||
obj-$(CONFIG_DVB_ISL6421) += isl6421.o
|
||||
obj-$(CONFIG_DVB_TDA10086) += tda10086.o
|
||||
obj-$(CONFIG_DVB_TDA826X) += tda826x.o
|
||||
obj-$(CONFIG_DVB_TDA8261) += tda8261.o
|
||||
obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
|
||||
obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o
|
||||
obj-$(CONFIG_DVB_TUA6100) += tua6100.o
|
||||
obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
|
||||
obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
|
||||
obj-$(CONFIG_DVB_AU8522) += au8522_common.o
|
||||
obj-$(CONFIG_DVB_AU8522_DTV) += au8522_dig.o
|
||||
obj-$(CONFIG_DVB_AU8522_V4L) += au8522_decoder.o
|
||||
obj-$(CONFIG_DVB_TDA10048) += tda10048.o
|
||||
obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
|
||||
obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
|
||||
obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
|
||||
obj-$(CONFIG_DVB_TDA665x) += tda665x.o
|
||||
obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
|
||||
obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
|
||||
obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
|
||||
obj-$(CONFIG_DVB_AF9013) += af9013.o
|
||||
obj-$(CONFIG_DVB_CX24116) += cx24116.o
|
||||
obj-$(CONFIG_DVB_CX24117) += cx24117.o
|
||||
obj-$(CONFIG_DVB_SI21XX) += si21xx.o
|
||||
obj-$(CONFIG_DVB_SI2168) += si2168.o
|
||||
obj-$(CONFIG_DVB_STV0288) += stv0288.o
|
||||
obj-$(CONFIG_DVB_STB6000) += stb6000.o
|
||||
obj-$(CONFIG_DVB_S921) += s921.o
|
||||
obj-$(CONFIG_DVB_STV6110) += stv6110.o
|
||||
obj-$(CONFIG_DVB_STV0900) += stv0900.o
|
||||
obj-$(CONFIG_DVB_STV090x) += stv090x.o
|
||||
obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
|
||||
obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o
|
||||
obj-$(CONFIG_DVB_ISL6423) += isl6423.o
|
||||
obj-$(CONFIG_DVB_EC100) += ec100.o
|
||||
obj-$(CONFIG_DVB_HD29L2) += hd29l2.o
|
||||
obj-$(CONFIG_DVB_DS3000) += ds3000.o
|
||||
obj-$(CONFIG_DVB_TS2020) += ts2020.o
|
||||
obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
|
||||
obj-$(CONFIG_DVB_DRX39XYJ) += drx39xyj/
|
||||
obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
|
||||
obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
|
||||
obj-$(CONFIG_DVB_STV0367) += stv0367.o
|
||||
obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
|
||||
obj-$(CONFIG_DVB_DRXK) += drxk.o
|
||||
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
|
||||
obj-$(CONFIG_DVB_SI2165) += si2165.o
|
||||
obj-$(CONFIG_DVB_A8293) += a8293.o
|
||||
obj-$(CONFIG_DVB_TDA10071) += tda10071.o
|
||||
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
|
||||
obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
|
||||
obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
|
||||
obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
|
||||
obj-$(CONFIG_DVB_AF9033) += af9033.o
|
||||
obj-$(CONFIG_DVB_STV0367DD) += stv0367dd.o
|
||||
obj-$(CONFIG_DVB_TDA18212DD) += tda18212dd.o
|
||||
obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
|
||||
obj-$(CONFIG_DVB_CXD2843) += cxd2843.o
|
||||
obj-$(CONFIG_DVB_STV6111) += stv6111.o
|
||||
obj-$(CONFIG_DVB_STV0910) += stv0910.o
|
||||
obj-$(CONFIG_DVB_LNBH25) += lnbh25.o
|
||||
obj-$(CONFIG_DVB_MXL5XX) += mxl5xx.o
|
@@ -662,15 +662,19 @@ static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
|
||||
static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
|
||||
int status;
|
||||
|
||||
if (ci->write_busy)
|
||||
return -EAGAIN;
|
||||
mutex_lock(&ci->lock);
|
||||
write_reg(ci, 0x0d, ecount >> 8);
|
||||
write_reg(ci, 0x0e, ecount & 0xff);
|
||||
write_block(ci, 0x11, ebuf, ecount);
|
||||
ci->write_busy = 1;
|
||||
status = write_block(ci, 0x11, ebuf, ecount);
|
||||
if (!status)
|
||||
ci->write_busy = 1;
|
||||
mutex_unlock(&ci->lock);
|
||||
if (status)
|
||||
return status;
|
||||
return ecount;
|
||||
}
|
||||
#endif
|
||||
|
1006
frontends/cxd2843.c
1006
frontends/cxd2843.c
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ struct cxd2843_cfg {
|
||||
u8 adr;
|
||||
u32 ts_clock;
|
||||
u8 parallel;
|
||||
u32 osc;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_CXD2843) || \
|
||||
|
@@ -1,10 +1,10 @@
|
||||
#ifndef _DRXK_H_
|
||||
#define _DRXK_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
extern struct dvb_frontend *drxk_attach(struct i2c_adapter *i2c,
|
||||
u8 adr,
|
||||
struct dvb_frontend **fe_t);
|
||||
#endif
|
||||
#ifndef _DRXK_H_
|
||||
#define _DRXK_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
extern struct dvb_frontend *drxk_attach(struct i2c_adapter *i2c,
|
||||
u8 adr,
|
||||
struct dvb_frontend **fe_t);
|
||||
#endif
|
||||
|
10190
frontends/drxk_hard.c
10190
frontends/drxk_hard.c
File diff suppressed because it is too large
Load Diff
@@ -1,343 +1,343 @@
|
||||
#include "drxk_map.h"
|
||||
|
||||
#define DRXK_VERSION_MAJOR 0
|
||||
#define DRXK_VERSION_MINOR 9
|
||||
#define DRXK_VERSION_PATCH 4300
|
||||
|
||||
#define HI_I2C_DELAY 42
|
||||
#define HI_I2C_BRIDGE_DELAY 350
|
||||
#define DRXK_MAX_RETRIES 100
|
||||
|
||||
#define DRIVER_4400 1
|
||||
|
||||
#define DRXX_JTAGID 0x039210D9
|
||||
#define DRXX_J_JTAGID 0x239310D9
|
||||
#define DRXX_K_JTAGID 0x039210D9
|
||||
|
||||
#define DRX_UNKNOWN 254
|
||||
#define DRX_AUTO 255
|
||||
|
||||
#define DRX_SCU_READY 0
|
||||
#define DRXK_MAX_WAITTIME (200)
|
||||
#define SCU_RESULT_OK 0
|
||||
#define SCU_RESULT_UNKSTD -2
|
||||
#define SCU_RESULT_UNKCMD -1
|
||||
|
||||
#ifndef DRXK_OFDM_TR_SHUTDOWN_TIMEOUT
|
||||
#define DRXK_OFDM_TR_SHUTDOWN_TIMEOUT (200)
|
||||
#endif
|
||||
|
||||
#define DRXK_8VSB_MPEG_BIT_RATE 19392658UL /*bps*/
|
||||
#define DRXK_DVBT_MPEG_BIT_RATE 32000000UL /*bps*/
|
||||
#define DRXK_QAM16_MPEG_BIT_RATE 27000000UL /*bps*/
|
||||
#define DRXK_QAM32_MPEG_BIT_RATE 33000000UL /*bps*/
|
||||
#define DRXK_QAM64_MPEG_BIT_RATE 40000000UL /*bps*/
|
||||
#define DRXK_QAM128_MPEG_BIT_RATE 46000000UL /*bps*/
|
||||
#define DRXK_QAM256_MPEG_BIT_RATE 52000000UL /*bps*/
|
||||
#define DRXK_MAX_MPEG_BIT_RATE 52000000UL /*bps*/
|
||||
|
||||
#define IQM_CF_OUT_ENA_OFDM__M 0x4
|
||||
#define IQM_FS_ADJ_SEL_B_QAM 0x1
|
||||
#define IQM_FS_ADJ_SEL_B_OFF 0x0
|
||||
#define IQM_FS_ADJ_SEL_B_VSB 0x2
|
||||
#define IQM_RC_ADJ_SEL_B_OFF 0x0
|
||||
#define IQM_RC_ADJ_SEL_B_QAM 0x1
|
||||
#define IQM_RC_ADJ_SEL_B_VSB 0x2
|
||||
|
||||
enum OperationMode {
|
||||
OM_NONE,
|
||||
OM_QAM_ITU_A,
|
||||
OM_QAM_ITU_B,
|
||||
OM_QAM_ITU_C,
|
||||
OM_DVBT
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
DRX_POWER_UP = 0,
|
||||
DRX_POWER_MODE_1,
|
||||
DRX_POWER_MODE_2,
|
||||
DRX_POWER_MODE_3,
|
||||
DRX_POWER_MODE_4,
|
||||
DRX_POWER_MODE_5,
|
||||
DRX_POWER_MODE_6,
|
||||
DRX_POWER_MODE_7,
|
||||
DRX_POWER_MODE_8,
|
||||
|
||||
DRX_POWER_MODE_9,
|
||||
DRX_POWER_MODE_10,
|
||||
DRX_POWER_MODE_11,
|
||||
DRX_POWER_MODE_12,
|
||||
DRX_POWER_MODE_13,
|
||||
DRX_POWER_MODE_14,
|
||||
DRX_POWER_MODE_15,
|
||||
DRX_POWER_MODE_16,
|
||||
DRX_POWER_DOWN = 255
|
||||
}DRXPowerMode_t, *pDRXPowerMode_t;
|
||||
|
||||
|
||||
/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */
|
||||
#ifndef DRXK_POWER_DOWN_OFDM
|
||||
#define DRXK_POWER_DOWN_OFDM DRX_POWER_MODE_1
|
||||
#endif
|
||||
|
||||
/** /brief Intermediate power mode for DRXK, power down core (sysclk) */
|
||||
#ifndef DRXK_POWER_DOWN_CORE
|
||||
#define DRXK_POWER_DOWN_CORE DRX_POWER_MODE_9
|
||||
#endif
|
||||
|
||||
/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */
|
||||
#ifndef DRXK_POWER_DOWN_PLL
|
||||
#define DRXK_POWER_DOWN_PLL DRX_POWER_MODE_10
|
||||
#endif
|
||||
|
||||
|
||||
enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF };
|
||||
enum EDrxkState { DRXK_UNINITIALIZED = 0, DRXK_STOPPED, DRXK_DTV_STARTED, DRXK_ATV_STARTED, DRXK_POWERED_DOWN };
|
||||
enum EDrxkCoefArrayIndex {
|
||||
DRXK_COEF_IDX_MN = 0,
|
||||
DRXK_COEF_IDX_FM ,
|
||||
DRXK_COEF_IDX_L ,
|
||||
DRXK_COEF_IDX_LP ,
|
||||
DRXK_COEF_IDX_BG ,
|
||||
DRXK_COEF_IDX_DK ,
|
||||
DRXK_COEF_IDX_I ,
|
||||
DRXK_COEF_IDX_MAX
|
||||
};
|
||||
enum EDrxkSifAttenuation {
|
||||
DRXK_SIF_ATTENUATION_0DB,
|
||||
DRXK_SIF_ATTENUATION_3DB,
|
||||
DRXK_SIF_ATTENUATION_6DB,
|
||||
DRXK_SIF_ATTENUATION_9DB
|
||||
};
|
||||
enum EDrxkConstellation {
|
||||
DRX_CONSTELLATION_BPSK = 0,
|
||||
DRX_CONSTELLATION_QPSK,
|
||||
DRX_CONSTELLATION_PSK8,
|
||||
DRX_CONSTELLATION_QAM16,
|
||||
DRX_CONSTELLATION_QAM32,
|
||||
DRX_CONSTELLATION_QAM64,
|
||||
DRX_CONSTELLATION_QAM128,
|
||||
DRX_CONSTELLATION_QAM256,
|
||||
DRX_CONSTELLATION_QAM512,
|
||||
DRX_CONSTELLATION_QAM1024,
|
||||
DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
|
||||
DRX_CONSTELLATION_AUTO = DRX_AUTO
|
||||
};
|
||||
enum EDrxkInterleaveMode {
|
||||
DRXK_QAM_I12_J17 = 16,
|
||||
DRXK_QAM_I_UNKNOWN = DRX_UNKNOWN
|
||||
};
|
||||
enum {
|
||||
DRXK_SPIN_A1 = 0,
|
||||
DRXK_SPIN_A2,
|
||||
DRXK_SPIN_A3,
|
||||
DRXK_SPIN_UNKNOWN
|
||||
};
|
||||
|
||||
enum DRXKCfgDvbtSqiSpeed {
|
||||
DRXK_DVBT_SQI_SPEED_FAST = 0,
|
||||
DRXK_DVBT_SQI_SPEED_MEDIUM,
|
||||
DRXK_DVBT_SQI_SPEED_SLOW,
|
||||
DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN
|
||||
} ;
|
||||
|
||||
enum DRXFftmode_t {
|
||||
DRX_FFTMODE_2K = 0,
|
||||
DRX_FFTMODE_4K,
|
||||
DRX_FFTMODE_8K,
|
||||
DRX_FFTMODE_UNKNOWN = DRX_UNKNOWN,
|
||||
DRX_FFTMODE_AUTO = DRX_AUTO
|
||||
};
|
||||
|
||||
enum DRXMPEGStrWidth_t {
|
||||
DRX_MPEG_STR_WIDTH_1,
|
||||
DRX_MPEG_STR_WIDTH_8
|
||||
};
|
||||
|
||||
enum DRXQamLockRange_t {
|
||||
DRX_QAM_LOCKRANGE_NORMAL,
|
||||
DRX_QAM_LOCKRANGE_EXTENDED
|
||||
};
|
||||
|
||||
struct DRXKCfgDvbtEchoThres_t {
|
||||
u16 threshold;
|
||||
enum DRXFftmode_t fftMode;
|
||||
} ;
|
||||
|
||||
struct SCfgAgc
|
||||
{
|
||||
enum AGC_CTRL_MODE ctrlMode; /* off, user, auto */
|
||||
u16 outputLevel; /* range dependent on AGC */
|
||||
u16 minOutputLevel; /* range dependent on AGC */
|
||||
u16 maxOutputLevel; /* range dependent on AGC */
|
||||
u16 speed; /* range dependent on AGC */
|
||||
u16 top; /* rf-agc take over point */
|
||||
u16 cutOffCurrent; /* rf-agc is accelerated if output current
|
||||
is below cut-off current */
|
||||
u16 IngainTgtMax;
|
||||
u16 FastClipCtrlDelay;
|
||||
};
|
||||
|
||||
struct SCfgPreSaw
|
||||
{
|
||||
u16 reference; /* pre SAW reference value, range 0 .. 31 */
|
||||
bool usePreSaw; /* TRUE algorithms must use pre SAW sense */
|
||||
};
|
||||
|
||||
struct DRXKOfdmScCmd_t
|
||||
{
|
||||
u16 cmd; /**< Command number */
|
||||
u16 subcmd; /**< Sub-command parameter*/
|
||||
u16 param0; /**< General purpous param */
|
||||
u16 param1; /**< General purpous param */
|
||||
u16 param2; /**< General purpous param */
|
||||
u16 param3; /**< General purpous param */
|
||||
u16 param4; /**< General purpous param */
|
||||
};
|
||||
|
||||
struct drxk_state {
|
||||
struct dvb_frontend c_frontend;
|
||||
struct dvb_frontend t_frontend;
|
||||
#ifndef USE_API3
|
||||
struct dtv_frontend_properties props;
|
||||
#else
|
||||
struct dvb_frontend_parameters param;
|
||||
#endif
|
||||
struct device *dev;
|
||||
|
||||
struct i2c_adapter *i2c;
|
||||
u8 demod_address;
|
||||
void *priv;
|
||||
|
||||
struct mutex mutex;
|
||||
struct mutex ctlock;
|
||||
|
||||
u32 m_Instance; ///< Channel 1,2,3 or 4
|
||||
|
||||
int m_ChunkSize;
|
||||
u8 Chunk[256];
|
||||
|
||||
bool m_hasLNA;
|
||||
bool m_hasDVBT;
|
||||
bool m_hasDVBC;
|
||||
bool m_hasAudio;
|
||||
bool m_hasATV;
|
||||
bool m_hasOOB;
|
||||
bool m_hasSAWSW; /**< TRUE if mat_tx is available */
|
||||
bool m_hasGPIO1; /**< TRUE if mat_rx is available */
|
||||
bool m_hasGPIO2; /**< TRUE if GPIO is available */
|
||||
bool m_hasIRQN; /**< TRUE if IRQN is available */
|
||||
u16 m_oscClockFreq;
|
||||
u16 m_HICfgTimingDiv;
|
||||
u16 m_HICfgBridgeDelay;
|
||||
u16 m_HICfgWakeUpKey;
|
||||
u16 m_HICfgTimeout;
|
||||
u16 m_HICfgCtrl;
|
||||
s32 m_sysClockFreq ; ///< system clock frequency in kHz
|
||||
|
||||
enum EDrxkState m_DrxkState; ///< State of Drxk (init,stopped,started)
|
||||
enum OperationMode m_OperationMode; ///< digital standards
|
||||
struct SCfgAgc m_vsbRfAgcCfg; ///< settings for VSB RF-AGC
|
||||
struct SCfgAgc m_vsbIfAgcCfg; ///< settings for VSB IF-AGC
|
||||
u16 m_vsbPgaCfg; ///< settings for VSB PGA
|
||||
struct SCfgPreSaw m_vsbPreSawCfg; ///< settings for pre SAW sense
|
||||
s32 m_Quality83percent; ///< MER level (*0.1 dB) for 83% quality indication
|
||||
s32 m_Quality93percent; ///< MER level (*0.1 dB) for 93% quality indication
|
||||
bool m_smartAntInverted;
|
||||
bool m_bDebugEnableBridge;
|
||||
bool m_bPDownOpenBridge; ///< only open DRXK bridge before power-down once it has been accessed
|
||||
bool m_bPowerDown; ///< Power down when not used
|
||||
|
||||
u32 m_IqmFsRateOfs; ///< frequency shift as written to DRXK register (28bit fixpoint)
|
||||
|
||||
bool m_enableMPEGOutput; /**< If TRUE, enable MPEG output */
|
||||
bool m_insertRSByte; /**< If TRUE, insert RS byte */
|
||||
bool m_enableParallel; /**< If TRUE, parallel out otherwise serial */
|
||||
bool m_invertDATA; /**< If TRUE, invert DATA signals */
|
||||
bool m_invertERR; /**< If TRUE, invert ERR signal */
|
||||
bool m_invertSTR; /**< If TRUE, invert STR signals */
|
||||
bool m_invertVAL; /**< If TRUE, invert VAL signals */
|
||||
bool m_invertCLK; /**< If TRUE, invert CLK signals */
|
||||
bool m_DVBCStaticCLK;
|
||||
bool m_DVBTStaticCLK; /**< If TRUE, static MPEG clockrate will
|
||||
be used, otherwise clockrate will
|
||||
adapt to the bitrate of the TS */
|
||||
u32 m_DVBTBitrate;
|
||||
u32 m_DVBCBitrate;
|
||||
|
||||
u8 m_TSDataStrength;
|
||||
u8 m_TSClockkStrength;
|
||||
|
||||
enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width**/
|
||||
u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case
|
||||
static clockrate is selected */
|
||||
|
||||
//LARGE_INTEGER m_StartTime; ///< Contains the time of the last demod start
|
||||
s32 m_MpegLockTimeOut; ///< WaitForLockStatus Timeout (counts from start time)
|
||||
s32 m_DemodLockTimeOut; ///< WaitForLockStatus Timeout (counts from start time)
|
||||
|
||||
bool m_disableTEIhandling;
|
||||
|
||||
bool m_RfAgcPol;
|
||||
bool m_IfAgcPol;
|
||||
|
||||
struct SCfgAgc m_atvRfAgcCfg; ///< settings for ATV RF-AGC
|
||||
struct SCfgAgc m_atvIfAgcCfg; ///< settings for ATV IF-AGC
|
||||
struct SCfgPreSaw m_atvPreSawCfg; ///< settings for ATV pre SAW sense
|
||||
bool m_phaseCorrectionBypass;
|
||||
s16 m_atvTopVidPeak;
|
||||
u16 m_atvTopNoiseTh;
|
||||
enum EDrxkSifAttenuation m_sifAttenuation;
|
||||
bool m_enableCVBSOutput;
|
||||
bool m_enableSIFOutput;
|
||||
bool m_bMirrorFreqSpect;
|
||||
enum EDrxkConstellation m_Constellation; ///< Constellation type of the channel
|
||||
u32 m_CurrSymbolRate; ///< Current QAM symbol rate
|
||||
struct SCfgAgc m_qamRfAgcCfg; ///< settings for QAM RF-AGC
|
||||
struct SCfgAgc m_qamIfAgcCfg; ///< settings for QAM IF-AGC
|
||||
u16 m_qamPgaCfg; ///< settings for QAM PGA
|
||||
struct SCfgPreSaw m_qamPreSawCfg; ///< settings for QAM pre SAW sense
|
||||
enum EDrxkInterleaveMode m_qamInterleaveMode; ///< QAM Interleave mode
|
||||
u16 m_fecRsPlen;
|
||||
u16 m_fecRsPrescale;
|
||||
|
||||
enum DRXKCfgDvbtSqiSpeed m_sqiSpeed;
|
||||
|
||||
u16 m_GPIO;
|
||||
u16 m_GPIOCfg;
|
||||
|
||||
struct SCfgAgc m_dvbtRfAgcCfg; ///< settings for QAM RF-AGC
|
||||
struct SCfgAgc m_dvbtIfAgcCfg; ///< settings for QAM IF-AGC
|
||||
struct SCfgPreSaw m_dvbtPreSawCfg; ///< settings for QAM pre SAW sense
|
||||
|
||||
u16 m_agcFastClipCtrlDelay;
|
||||
bool m_adcCompPassed;
|
||||
u16 m_adcCompCoef[64];
|
||||
u16 m_adcState;
|
||||
|
||||
u8 *m_microcode;
|
||||
int m_microcode_length;
|
||||
bool m_DRXK_A1_PATCH_CODE;
|
||||
bool m_DRXK_A1_ROM_CODE;
|
||||
bool m_DRXK_A2_ROM_CODE;
|
||||
bool m_DRXK_A3_ROM_CODE;
|
||||
bool m_DRXK_A2_PATCH_CODE;
|
||||
bool m_DRXK_A3_PATCH_CODE;
|
||||
|
||||
bool m_rfmirror;
|
||||
u8 m_deviceSpin;
|
||||
u32 m_iqmRcRate;
|
||||
|
||||
u16 m_AntennaDVBC;
|
||||
u16 m_AntennaDVBT;
|
||||
u16 m_AntennaSwitchDVBTDVBC;
|
||||
|
||||
DRXPowerMode_t m_currentPowerMode;
|
||||
};
|
||||
|
||||
#define NEVER_LOCK 0
|
||||
#define NOT_LOCKED 1
|
||||
#define DEMOD_LOCK 2
|
||||
#define FEC_LOCK 3
|
||||
#define MPEG_LOCK 4
|
||||
|
||||
#include "drxk_map.h"
|
||||
|
||||
#define DRXK_VERSION_MAJOR 0
|
||||
#define DRXK_VERSION_MINOR 9
|
||||
#define DRXK_VERSION_PATCH 4300
|
||||
|
||||
#define HI_I2C_DELAY 42
|
||||
#define HI_I2C_BRIDGE_DELAY 350
|
||||
#define DRXK_MAX_RETRIES 100
|
||||
|
||||
#define DRIVER_4400 1
|
||||
|
||||
#define DRXX_JTAGID 0x039210D9
|
||||
#define DRXX_J_JTAGID 0x239310D9
|
||||
#define DRXX_K_JTAGID 0x039210D9
|
||||
|
||||
#define DRX_UNKNOWN 254
|
||||
#define DRX_AUTO 255
|
||||
|
||||
#define DRX_SCU_READY 0
|
||||
#define DRXK_MAX_WAITTIME (200)
|
||||
#define SCU_RESULT_OK 0
|
||||
#define SCU_RESULT_UNKSTD -2
|
||||
#define SCU_RESULT_UNKCMD -1
|
||||
|
||||
#ifndef DRXK_OFDM_TR_SHUTDOWN_TIMEOUT
|
||||
#define DRXK_OFDM_TR_SHUTDOWN_TIMEOUT (200)
|
||||
#endif
|
||||
|
||||
#define DRXK_8VSB_MPEG_BIT_RATE 19392658UL /*bps*/
|
||||
#define DRXK_DVBT_MPEG_BIT_RATE 32000000UL /*bps*/
|
||||
#define DRXK_QAM16_MPEG_BIT_RATE 27000000UL /*bps*/
|
||||
#define DRXK_QAM32_MPEG_BIT_RATE 33000000UL /*bps*/
|
||||
#define DRXK_QAM64_MPEG_BIT_RATE 40000000UL /*bps*/
|
||||
#define DRXK_QAM128_MPEG_BIT_RATE 46000000UL /*bps*/
|
||||
#define DRXK_QAM256_MPEG_BIT_RATE 52000000UL /*bps*/
|
||||
#define DRXK_MAX_MPEG_BIT_RATE 52000000UL /*bps*/
|
||||
|
||||
#define IQM_CF_OUT_ENA_OFDM__M 0x4
|
||||
#define IQM_FS_ADJ_SEL_B_QAM 0x1
|
||||
#define IQM_FS_ADJ_SEL_B_OFF 0x0
|
||||
#define IQM_FS_ADJ_SEL_B_VSB 0x2
|
||||
#define IQM_RC_ADJ_SEL_B_OFF 0x0
|
||||
#define IQM_RC_ADJ_SEL_B_QAM 0x1
|
||||
#define IQM_RC_ADJ_SEL_B_VSB 0x2
|
||||
|
||||
enum OperationMode {
|
||||
OM_NONE,
|
||||
OM_QAM_ITU_A,
|
||||
OM_QAM_ITU_B,
|
||||
OM_QAM_ITU_C,
|
||||
OM_DVBT
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
DRX_POWER_UP = 0,
|
||||
DRX_POWER_MODE_1,
|
||||
DRX_POWER_MODE_2,
|
||||
DRX_POWER_MODE_3,
|
||||
DRX_POWER_MODE_4,
|
||||
DRX_POWER_MODE_5,
|
||||
DRX_POWER_MODE_6,
|
||||
DRX_POWER_MODE_7,
|
||||
DRX_POWER_MODE_8,
|
||||
|
||||
DRX_POWER_MODE_9,
|
||||
DRX_POWER_MODE_10,
|
||||
DRX_POWER_MODE_11,
|
||||
DRX_POWER_MODE_12,
|
||||
DRX_POWER_MODE_13,
|
||||
DRX_POWER_MODE_14,
|
||||
DRX_POWER_MODE_15,
|
||||
DRX_POWER_MODE_16,
|
||||
DRX_POWER_DOWN = 255
|
||||
}DRXPowerMode_t, *pDRXPowerMode_t;
|
||||
|
||||
|
||||
/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */
|
||||
#ifndef DRXK_POWER_DOWN_OFDM
|
||||
#define DRXK_POWER_DOWN_OFDM DRX_POWER_MODE_1
|
||||
#endif
|
||||
|
||||
/** /brief Intermediate power mode for DRXK, power down core (sysclk) */
|
||||
#ifndef DRXK_POWER_DOWN_CORE
|
||||
#define DRXK_POWER_DOWN_CORE DRX_POWER_MODE_9
|
||||
#endif
|
||||
|
||||
/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */
|
||||
#ifndef DRXK_POWER_DOWN_PLL
|
||||
#define DRXK_POWER_DOWN_PLL DRX_POWER_MODE_10
|
||||
#endif
|
||||
|
||||
|
||||
enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF };
|
||||
enum EDrxkState { DRXK_UNINITIALIZED = 0, DRXK_STOPPED, DRXK_DTV_STARTED, DRXK_ATV_STARTED, DRXK_POWERED_DOWN };
|
||||
enum EDrxkCoefArrayIndex {
|
||||
DRXK_COEF_IDX_MN = 0,
|
||||
DRXK_COEF_IDX_FM ,
|
||||
DRXK_COEF_IDX_L ,
|
||||
DRXK_COEF_IDX_LP ,
|
||||
DRXK_COEF_IDX_BG ,
|
||||
DRXK_COEF_IDX_DK ,
|
||||
DRXK_COEF_IDX_I ,
|
||||
DRXK_COEF_IDX_MAX
|
||||
};
|
||||
enum EDrxkSifAttenuation {
|
||||
DRXK_SIF_ATTENUATION_0DB,
|
||||
DRXK_SIF_ATTENUATION_3DB,
|
||||
DRXK_SIF_ATTENUATION_6DB,
|
||||
DRXK_SIF_ATTENUATION_9DB
|
||||
};
|
||||
enum EDrxkConstellation {
|
||||
DRX_CONSTELLATION_BPSK = 0,
|
||||
DRX_CONSTELLATION_QPSK,
|
||||
DRX_CONSTELLATION_PSK8,
|
||||
DRX_CONSTELLATION_QAM16,
|
||||
DRX_CONSTELLATION_QAM32,
|
||||
DRX_CONSTELLATION_QAM64,
|
||||
DRX_CONSTELLATION_QAM128,
|
||||
DRX_CONSTELLATION_QAM256,
|
||||
DRX_CONSTELLATION_QAM512,
|
||||
DRX_CONSTELLATION_QAM1024,
|
||||
DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
|
||||
DRX_CONSTELLATION_AUTO = DRX_AUTO
|
||||
};
|
||||
enum EDrxkInterleaveMode {
|
||||
DRXK_QAM_I12_J17 = 16,
|
||||
DRXK_QAM_I_UNKNOWN = DRX_UNKNOWN
|
||||
};
|
||||
enum {
|
||||
DRXK_SPIN_A1 = 0,
|
||||
DRXK_SPIN_A2,
|
||||
DRXK_SPIN_A3,
|
||||
DRXK_SPIN_UNKNOWN
|
||||
};
|
||||
|
||||
enum DRXKCfgDvbtSqiSpeed {
|
||||
DRXK_DVBT_SQI_SPEED_FAST = 0,
|
||||
DRXK_DVBT_SQI_SPEED_MEDIUM,
|
||||
DRXK_DVBT_SQI_SPEED_SLOW,
|
||||
DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN
|
||||
} ;
|
||||
|
||||
enum DRXFftmode_t {
|
||||
DRX_FFTMODE_2K = 0,
|
||||
DRX_FFTMODE_4K,
|
||||
DRX_FFTMODE_8K,
|
||||
DRX_FFTMODE_UNKNOWN = DRX_UNKNOWN,
|
||||
DRX_FFTMODE_AUTO = DRX_AUTO
|
||||
};
|
||||
|
||||
enum DRXMPEGStrWidth_t {
|
||||
DRX_MPEG_STR_WIDTH_1,
|
||||
DRX_MPEG_STR_WIDTH_8
|
||||
};
|
||||
|
||||
enum DRXQamLockRange_t {
|
||||
DRX_QAM_LOCKRANGE_NORMAL,
|
||||
DRX_QAM_LOCKRANGE_EXTENDED
|
||||
};
|
||||
|
||||
struct DRXKCfgDvbtEchoThres_t {
|
||||
u16 threshold;
|
||||
enum DRXFftmode_t fftMode;
|
||||
} ;
|
||||
|
||||
struct SCfgAgc
|
||||
{
|
||||
enum AGC_CTRL_MODE ctrlMode; /* off, user, auto */
|
||||
u16 outputLevel; /* range dependent on AGC */
|
||||
u16 minOutputLevel; /* range dependent on AGC */
|
||||
u16 maxOutputLevel; /* range dependent on AGC */
|
||||
u16 speed; /* range dependent on AGC */
|
||||
u16 top; /* rf-agc take over point */
|
||||
u16 cutOffCurrent; /* rf-agc is accelerated if output current
|
||||
is below cut-off current */
|
||||
u16 IngainTgtMax;
|
||||
u16 FastClipCtrlDelay;
|
||||
};
|
||||
|
||||
struct SCfgPreSaw
|
||||
{
|
||||
u16 reference; /* pre SAW reference value, range 0 .. 31 */
|
||||
bool usePreSaw; /* TRUE algorithms must use pre SAW sense */
|
||||
};
|
||||
|
||||
struct DRXKOfdmScCmd_t
|
||||
{
|
||||
u16 cmd; /**< Command number */
|
||||
u16 subcmd; /**< Sub-command parameter*/
|
||||
u16 param0; /**< General purpous param */
|
||||
u16 param1; /**< General purpous param */
|
||||
u16 param2; /**< General purpous param */
|
||||
u16 param3; /**< General purpous param */
|
||||
u16 param4; /**< General purpous param */
|
||||
};
|
||||
|
||||
struct drxk_state {
|
||||
struct dvb_frontend c_frontend;
|
||||
struct dvb_frontend t_frontend;
|
||||
#ifndef USE_API3
|
||||
struct dtv_frontend_properties props;
|
||||
#else
|
||||
struct dvb_frontend_parameters param;
|
||||
#endif
|
||||
struct device *dev;
|
||||
|
||||
struct i2c_adapter *i2c;
|
||||
u8 demod_address;
|
||||
void *priv;
|
||||
|
||||
struct mutex mutex;
|
||||
struct mutex ctlock;
|
||||
|
||||
u32 m_Instance; ///< Channel 1,2,3 or 4
|
||||
|
||||
int m_ChunkSize;
|
||||
u8 Chunk[256];
|
||||
|
||||
bool m_hasLNA;
|
||||
bool m_hasDVBT;
|
||||
bool m_hasDVBC;
|
||||
bool m_hasAudio;
|
||||
bool m_hasATV;
|
||||
bool m_hasOOB;
|
||||
bool m_hasSAWSW; /**< TRUE if mat_tx is available */
|
||||
bool m_hasGPIO1; /**< TRUE if mat_rx is available */
|
||||
bool m_hasGPIO2; /**< TRUE if GPIO is available */
|
||||
bool m_hasIRQN; /**< TRUE if IRQN is available */
|
||||
u16 m_oscClockFreq;
|
||||
u16 m_HICfgTimingDiv;
|
||||
u16 m_HICfgBridgeDelay;
|
||||
u16 m_HICfgWakeUpKey;
|
||||
u16 m_HICfgTimeout;
|
||||
u16 m_HICfgCtrl;
|
||||
s32 m_sysClockFreq ; ///< system clock frequency in kHz
|
||||
|
||||
enum EDrxkState m_DrxkState; ///< State of Drxk (init,stopped,started)
|
||||
enum OperationMode m_OperationMode; ///< digital standards
|
||||
struct SCfgAgc m_vsbRfAgcCfg; ///< settings for VSB RF-AGC
|
||||
struct SCfgAgc m_vsbIfAgcCfg; ///< settings for VSB IF-AGC
|
||||
u16 m_vsbPgaCfg; ///< settings for VSB PGA
|
||||
struct SCfgPreSaw m_vsbPreSawCfg; ///< settings for pre SAW sense
|
||||
s32 m_Quality83percent; ///< MER level (*0.1 dB) for 83% quality indication
|
||||
s32 m_Quality93percent; ///< MER level (*0.1 dB) for 93% quality indication
|
||||
bool m_smartAntInverted;
|
||||
bool m_bDebugEnableBridge;
|
||||
bool m_bPDownOpenBridge; ///< only open DRXK bridge before power-down once it has been accessed
|
||||
bool m_bPowerDown; ///< Power down when not used
|
||||
|
||||
u32 m_IqmFsRateOfs; ///< frequency shift as written to DRXK register (28bit fixpoint)
|
||||
|
||||
bool m_enableMPEGOutput; /**< If TRUE, enable MPEG output */
|
||||
bool m_insertRSByte; /**< If TRUE, insert RS byte */
|
||||
bool m_enableParallel; /**< If TRUE, parallel out otherwise serial */
|
||||
bool m_invertDATA; /**< If TRUE, invert DATA signals */
|
||||
bool m_invertERR; /**< If TRUE, invert ERR signal */
|
||||
bool m_invertSTR; /**< If TRUE, invert STR signals */
|
||||
bool m_invertVAL; /**< If TRUE, invert VAL signals */
|
||||
bool m_invertCLK; /**< If TRUE, invert CLK signals */
|
||||
bool m_DVBCStaticCLK;
|
||||
bool m_DVBTStaticCLK; /**< If TRUE, static MPEG clockrate will
|
||||
be used, otherwise clockrate will
|
||||
adapt to the bitrate of the TS */
|
||||
u32 m_DVBTBitrate;
|
||||
u32 m_DVBCBitrate;
|
||||
|
||||
u8 m_TSDataStrength;
|
||||
u8 m_TSClockkStrength;
|
||||
|
||||
enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width**/
|
||||
u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case
|
||||
static clockrate is selected */
|
||||
|
||||
//LARGE_INTEGER m_StartTime; ///< Contains the time of the last demod start
|
||||
s32 m_MpegLockTimeOut; ///< WaitForLockStatus Timeout (counts from start time)
|
||||
s32 m_DemodLockTimeOut; ///< WaitForLockStatus Timeout (counts from start time)
|
||||
|
||||
bool m_disableTEIhandling;
|
||||
|
||||
bool m_RfAgcPol;
|
||||
bool m_IfAgcPol;
|
||||
|
||||
struct SCfgAgc m_atvRfAgcCfg; ///< settings for ATV RF-AGC
|
||||
struct SCfgAgc m_atvIfAgcCfg; ///< settings for ATV IF-AGC
|
||||
struct SCfgPreSaw m_atvPreSawCfg; ///< settings for ATV pre SAW sense
|
||||
bool m_phaseCorrectionBypass;
|
||||
s16 m_atvTopVidPeak;
|
||||
u16 m_atvTopNoiseTh;
|
||||
enum EDrxkSifAttenuation m_sifAttenuation;
|
||||
bool m_enableCVBSOutput;
|
||||
bool m_enableSIFOutput;
|
||||
bool m_bMirrorFreqSpect;
|
||||
enum EDrxkConstellation m_Constellation; ///< Constellation type of the channel
|
||||
u32 m_CurrSymbolRate; ///< Current QAM symbol rate
|
||||
struct SCfgAgc m_qamRfAgcCfg; ///< settings for QAM RF-AGC
|
||||
struct SCfgAgc m_qamIfAgcCfg; ///< settings for QAM IF-AGC
|
||||
u16 m_qamPgaCfg; ///< settings for QAM PGA
|
||||
struct SCfgPreSaw m_qamPreSawCfg; ///< settings for QAM pre SAW sense
|
||||
enum EDrxkInterleaveMode m_qamInterleaveMode; ///< QAM Interleave mode
|
||||
u16 m_fecRsPlen;
|
||||
u16 m_fecRsPrescale;
|
||||
|
||||
enum DRXKCfgDvbtSqiSpeed m_sqiSpeed;
|
||||
|
||||
u16 m_GPIO;
|
||||
u16 m_GPIOCfg;
|
||||
|
||||
struct SCfgAgc m_dvbtRfAgcCfg; ///< settings for QAM RF-AGC
|
||||
struct SCfgAgc m_dvbtIfAgcCfg; ///< settings for QAM IF-AGC
|
||||
struct SCfgPreSaw m_dvbtPreSawCfg; ///< settings for QAM pre SAW sense
|
||||
|
||||
u16 m_agcFastClipCtrlDelay;
|
||||
bool m_adcCompPassed;
|
||||
u16 m_adcCompCoef[64];
|
||||
u16 m_adcState;
|
||||
|
||||
u8 *m_microcode;
|
||||
int m_microcode_length;
|
||||
bool m_DRXK_A1_PATCH_CODE;
|
||||
bool m_DRXK_A1_ROM_CODE;
|
||||
bool m_DRXK_A2_ROM_CODE;
|
||||
bool m_DRXK_A3_ROM_CODE;
|
||||
bool m_DRXK_A2_PATCH_CODE;
|
||||
bool m_DRXK_A3_PATCH_CODE;
|
||||
|
||||
bool m_rfmirror;
|
||||
u8 m_deviceSpin;
|
||||
u32 m_iqmRcRate;
|
||||
|
||||
u16 m_AntennaDVBC;
|
||||
u16 m_AntennaDVBT;
|
||||
u16 m_AntennaSwitchDVBTDVBC;
|
||||
|
||||
DRXPowerMode_t m_currentPowerMode;
|
||||
};
|
||||
|
||||
#define NEVER_LOCK 0
|
||||
#define NOT_LOCKED 1
|
||||
#define DEMOD_LOCK 2
|
||||
#define FEC_LOCK 3
|
||||
#define MPEG_LOCK 4
|
||||
|
||||
|
32876
frontends/drxk_map.h
32876
frontends/drxk_map.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -146,7 +146,7 @@ struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe,
|
||||
fe->ops.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage;
|
||||
fe->ops.release_sec = lnbh25_release;
|
||||
|
||||
pr_info("LNB25 on %02x\n", lnbh->adr);
|
||||
pr_info("LNBH25 on %02x\n", lnbh->adr);
|
||||
|
||||
return fe;
|
||||
}
|
||||
|
@@ -193,7 +193,8 @@ static int read_register_unlocked(struct mxl *state, u32 reg, u32 *val)
|
||||
if (stat)
|
||||
pr_err("i2c read error 1\n");
|
||||
if (!stat)
|
||||
stat = i2cread(state, (u8 *) val, MXL_HYDRA_REG_SIZE_IN_BYTES);
|
||||
stat = i2cread(state, (u8 *) val,
|
||||
MXL_HYDRA_REG_SIZE_IN_BYTES);
|
||||
le32_to_cpus(val);
|
||||
if (stat)
|
||||
pr_err("i2c read error 2\n");
|
||||
@@ -218,10 +219,12 @@ static int send_command(struct mxl *state, u32 size, u8 *buf)
|
||||
mutex_unlock(&state->base->i2c_lock);
|
||||
usleep_range(1000, 2000);
|
||||
mutex_lock(&state->base->i2c_lock);
|
||||
read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR, &val);
|
||||
read_register_unlocked(state, DMA_I2C_INTERRUPT_ADDR,
|
||||
&val);
|
||||
}
|
||||
if (!count) {
|
||||
pr_info("mxl5xx: send_command busy\n");
|
||||
mutex_unlock(&state->base->i2c_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
@@ -246,7 +249,8 @@ static int write_register(struct mxl *state, u32 reg, u32 val)
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int write_register_block(struct mxl *state, u32 reg, u32 size, u8 *data)
|
||||
static int write_register_block(struct mxl *state, u32 reg,
|
||||
u32 size, u8 *data)
|
||||
{
|
||||
int stat;
|
||||
u8 *buf = state->base->buf;
|
||||
@@ -307,7 +311,8 @@ static int read_register(struct mxl *state, u32 reg, u32 *val)
|
||||
if (stat)
|
||||
pr_err("i2c read error 1\n");
|
||||
if (!stat)
|
||||
stat = i2cread(state, (u8 *) val, MXL_HYDRA_REG_SIZE_IN_BYTES);
|
||||
stat = i2cread(state, (u8 *) val,
|
||||
MXL_HYDRA_REG_SIZE_IN_BYTES);
|
||||
mutex_unlock(&state->base->i2c_lock);
|
||||
le32_to_cpus(val);
|
||||
if (stat)
|
||||
@@ -419,9 +424,22 @@ static int get_algo(struct dvb_frontend *fe)
|
||||
return DVBFE_ALGO_HW;
|
||||
}
|
||||
|
||||
/*
|
||||
static int cfg_scrambler(struct mxl *state)
|
||||
/* This should maybe go into dvb-core/dvb_math.c */
|
||||
|
||||
static u32 gold2root(u32 gold)
|
||||
{
|
||||
u32 x, g;
|
||||
|
||||
if (gold >= 0x3ffff)
|
||||
gold = 0;
|
||||
for (g = 0, x = 1; g < gold; g++)
|
||||
x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1);
|
||||
return x;
|
||||
}
|
||||
|
||||
static int cfg_scrambler(struct mxl *state, u32 gold)
|
||||
{
|
||||
u32 root;
|
||||
u8 buf[26] = {
|
||||
MXL_HYDRA_PLID_CMD_WRITE, 24,
|
||||
0, MXL_HYDRA_DEMOD_SCRAMBLE_CODE_CMD, 0, 0,
|
||||
@@ -430,11 +448,18 @@ static int cfg_scrambler(struct mxl *state)
|
||||
0, 0, 0, 0, 1, 0, 0, 0,
|
||||
};
|
||||
|
||||
if (gold != NO_SCRAMBLING_CODE)
|
||||
root = gold2root(gold);
|
||||
else
|
||||
root = 1;
|
||||
buf[25] = (root >> 24) & 0xff;
|
||||
buf[24] = (root >> 16) & 0xff;
|
||||
buf[23] = (root >> 8) & 0xff;
|
||||
buf[22] = root & 0xff;
|
||||
|
||||
return send_command(state, sizeof(buf), buf);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
static int CfgDemodAbortTune(struct mxl *state)
|
||||
{
|
||||
MXL_HYDRA_DEMOD_ABORT_TUNE_T abortTuneCmd;
|
||||
@@ -442,8 +467,23 @@ static int CfgDemodAbortTune(struct mxl *state)
|
||||
u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN];
|
||||
|
||||
abortTuneCmd.demodId = state->demod;
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_ABORT_TUNE_CMD, MXL_CMD_WRITE, cmdSize, &abortTuneCmd, cmdBuff);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_ABORT_TUNE_CMD, MXL_CMD_WRITE,
|
||||
cmdSize, &abortTuneCmd, cmdBuff);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
}
|
||||
|
||||
static int reset_fec_counter(struct mxl *state)
|
||||
{
|
||||
MXL_HYDRA_DEMOD_ABORT_TUNE_T abortTuneCmd;
|
||||
u32 demodIndex = (u32) state->demod;
|
||||
u8 cmdSize = sizeof(u32);
|
||||
u8 cmdBuff[MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN];
|
||||
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_DEMOD_RESET_FEC_COUNTER_CMD,
|
||||
MXL_CMD_WRITE, cmdSize, &demodIndex, cmdBuff);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
}
|
||||
|
||||
static int send_master_cmd(struct dvb_frontend *fe,
|
||||
@@ -490,7 +530,7 @@ static int set_parameters(struct dvb_frontend *fe)
|
||||
demodChanCfg.rollOff = MXL_HYDRA_ROLLOFF_AUTO;
|
||||
demodChanCfg.modulationScheme = MXL_HYDRA_MOD_AUTO;
|
||||
demodChanCfg.pilots = MXL_HYDRA_PILOTS_AUTO;
|
||||
//cfg_scrambler(state);
|
||||
cfg_scrambler(state, p->pls);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@@ -504,18 +544,22 @@ static int set_parameters(struct dvb_frontend *fe)
|
||||
demodChanCfg.fecCodeRate = MXL_HYDRA_FEC_AUTO;
|
||||
|
||||
mutex_lock(&state->base->tune_lock);
|
||||
if (time_after(jiffies + msecs_to_jiffies(200), state->base->next_tune))
|
||||
if (time_after(jiffies + msecs_to_jiffies(200),
|
||||
state->base->next_tune))
|
||||
while (time_before(jiffies, state->base->next_tune))
|
||||
msleep(10);
|
||||
state->base->next_tune = jiffies + msecs_to_jiffies(100);
|
||||
state->tuner_in_use = state->tuner;
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_DEMOD_SET_PARAM_CMD, MXL_CMD_WRITE,
|
||||
cmdSize, &demodChanCfg, cmdBuff);
|
||||
stat = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
stat = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
mutex_unlock(&state->base->tune_lock);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int get_stats(struct dvb_frontend *fe);
|
||||
|
||||
static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
{
|
||||
struct mxl *state = fe->demodulator_priv;
|
||||
@@ -532,7 +576,7 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
mutex_unlock(&state->base->status_lock);
|
||||
|
||||
*status = (regData == 1) ? 0x1f : 0;
|
||||
|
||||
get_stats(fe);
|
||||
return stat;
|
||||
}
|
||||
|
||||
@@ -552,21 +596,19 @@ static int tune(struct dvb_frontend *fe, bool re_tune,
|
||||
state->tune_time = jiffies;
|
||||
return 0;
|
||||
}
|
||||
if (*status & FE_HAS_LOCK)
|
||||
return 0;
|
||||
|
||||
r = read_status(fe, status);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (*status & FE_HAS_LOCK)
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
if (p->delivery_system == SYS_DVBS)
|
||||
p->delivery_system = SYS_DVBS2;
|
||||
else
|
||||
p->delivery_system = SYS_DVBS;
|
||||
set_parameters(fe);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -585,7 +627,7 @@ static int sleep(struct dvb_frontend *fe)
|
||||
if (p->tuner_in_use == state->tuner)
|
||||
break;
|
||||
}
|
||||
if (p == &state->base->mxls)
|
||||
if (&p->mxl == &state->base->mxls)
|
||||
enable_tuner(state, state->tuner, 0);
|
||||
mutex_unlock(&state->base->tune_lock);
|
||||
}
|
||||
@@ -597,6 +639,7 @@ static int read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
struct mxl *state = fe->demodulator_priv;
|
||||
int stat;
|
||||
u32 regData = 0;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
|
||||
mutex_lock(&state->base->status_lock);
|
||||
HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
|
||||
@@ -605,23 +648,76 @@ static int read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
®Data);
|
||||
HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
|
||||
mutex_unlock(&state->base->status_lock);
|
||||
*snr = (s16) (regData & 0xFFFF);
|
||||
*snr = (s16) (regData & 0xFFFF); /* 100x dB */
|
||||
p->cnr.len = 1;
|
||||
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->cnr.stat[0].uvalue = 10 * (s64) *snr;
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
struct mxl *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 reg[8], reg2[4], n = 0, d = 0;
|
||||
int stat;
|
||||
|
||||
*ber = 0;
|
||||
|
||||
mutex_lock(&state->base->status_lock);
|
||||
HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
|
||||
stat = read_register_block(state,
|
||||
(HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET +
|
||||
HYDRA_DMD_STATUS_OFFSET(state->demod)),
|
||||
(7 * sizeof(u32)),
|
||||
(u8 *) ®[0]);
|
||||
stat = read_register_block(
|
||||
state,
|
||||
(HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET +
|
||||
HYDRA_DMD_STATUS_OFFSET(state->demod)),
|
||||
(4 * sizeof(u32)),
|
||||
(u8 *) ®2[0]);
|
||||
HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
|
||||
mutex_unlock(&state->base->status_lock);
|
||||
|
||||
|
||||
switch (p->delivery_system) {
|
||||
case SYS_DSS:
|
||||
break;
|
||||
case SYS_DVBS:
|
||||
p->pre_bit_error.len = 1;
|
||||
p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_error.stat[0].uvalue = reg[5];
|
||||
p->pre_bit_count.len = 1;
|
||||
p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_count.stat[0].uvalue = reg[6] * 188 * 8;
|
||||
break;
|
||||
case SYS_DVBS2:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
pr_debug("mxl5xx: ber %08x %08x %08x %08x %08x %08x %08x\n",
|
||||
reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6]);
|
||||
pr_debug("mxl5xx: ber2 %08x %08x %08x %08x\n",
|
||||
reg[0], reg[1], reg[2], reg[3]);
|
||||
//pre_bit_error, pre_bit_count
|
||||
//post_bit_error, post_bit_count;
|
||||
//block_error block_count;
|
||||
//reset_fec_counter(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
{
|
||||
struct mxl *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
int stat;
|
||||
u32 regData = 0;
|
||||
|
||||
#if 0
|
||||
if (!firmware_is_alive(state))
|
||||
pr_info("FW dead!\n");
|
||||
#endif
|
||||
mutex_lock(&state->base->status_lock);
|
||||
HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
|
||||
stat = read_register(state, (HYDRA_DMD_STATUS_INPUT_POWER_ADDR +
|
||||
@@ -629,7 +725,10 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
®Data);
|
||||
HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
|
||||
mutex_unlock(&state->base->status_lock);
|
||||
*strength = (u16) (regData & 0xFFFF);
|
||||
*strength = (u16) (regData & 0xFFFF); /* 10x dBm */
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].uvalue = 10 * (s64) (s16) (regData & 0xFFFF);
|
||||
return stat;
|
||||
}
|
||||
|
||||
@@ -638,17 +737,105 @@ static int read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_stats(struct dvb_frontend *fe)
|
||||
{
|
||||
u16 val;
|
||||
u32 val32;
|
||||
|
||||
read_signal_strength(fe, &val);
|
||||
read_snr(fe, &val);
|
||||
read_ber(fe, &val32);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static fe_code_rate_t conv_fec(MXL_HYDRA_FEC_E fec)
|
||||
{
|
||||
enum fe_code_rate fec2fec[11] = {
|
||||
FEC_NONE, FEC_1_2, FEC_3_5, FEC_2_3,
|
||||
FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7,
|
||||
FEC_7_8, FEC_8_9, FEC_9_10
|
||||
};
|
||||
|
||||
if (fec > MXL_HYDRA_FEC_9_10)
|
||||
return FEC_NONE;
|
||||
return fec2fec[fec];
|
||||
}
|
||||
|
||||
static int get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
//struct mxl *state = fe->demodulator_priv;
|
||||
struct mxl *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 regData[MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE];
|
||||
u32 freq;
|
||||
int stat;
|
||||
|
||||
mutex_lock(&state->base->status_lock);
|
||||
HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
|
||||
stat = read_register_block(state,
|
||||
(HYDRA_DMD_STANDARD_ADDR_OFFSET +
|
||||
HYDRA_DMD_STATUS_OFFSET(state->demod)),
|
||||
(MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE * 4), // 25 * 4 bytes
|
||||
(u8 *) ®Data[0]);
|
||||
// read demod channel parameters
|
||||
stat = read_register_block(state,
|
||||
(HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR +
|
||||
HYDRA_DMD_STATUS_OFFSET(state->demod)),
|
||||
(4), // 4 bytes
|
||||
(u8 *) &freq);
|
||||
HYDRA_DEMOD_STATUS_UNLOCK(state, state->demod);
|
||||
mutex_unlock(&state->base->status_lock);
|
||||
|
||||
pr_debug("mxl5xx: freq=%u delsys=%u srate=%u\n",
|
||||
freq * 1000, regData[DMD_STANDARD_ADDR],
|
||||
regData[DMD_SYMBOL_RATE_ADDR]);
|
||||
p->symbol_rate = regData[DMD_SYMBOL_RATE_ADDR];
|
||||
p->frequency = freq;
|
||||
//p->delivery_system = (MXL_HYDRA_BCAST_STD_E )regData[DMD_STANDARD_ADDR];
|
||||
//p->inversion = (MXL_HYDRA_SPECTRUM_E )regData[DMD_SPECTRUM_INVERSION_ADDR];
|
||||
//freqSearchRangeKHz = (regData[DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR]);
|
||||
|
||||
p->fec_inner = conv_fec(regData[DMD_FEC_CODE_RATE_ADDR]);
|
||||
switch (p->delivery_system) {
|
||||
case SYS_DSS:
|
||||
break;
|
||||
case SYS_DVBS:
|
||||
break;
|
||||
case SYS_DVBS2:
|
||||
switch ((MXL_HYDRA_PILOTS_E )
|
||||
regData[DMD_DVBS2_PILOT_ON_OFF_ADDR]) {
|
||||
case MXL_HYDRA_PILOTS_OFF:
|
||||
p->pilot = PILOT_OFF;
|
||||
break;
|
||||
case MXL_HYDRA_PILOTS_ON:
|
||||
p->pilot = PILOT_ON;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
case SYS_DVBS:
|
||||
switch ((MXL_HYDRA_MODULATION_E)
|
||||
regData[DMD_MODULATION_SCHEME_ADDR]) {
|
||||
case MXL_HYDRA_MOD_QPSK:
|
||||
p->modulation = QPSK;
|
||||
break;
|
||||
case MXL_HYDRA_MOD_8PSK:
|
||||
p->modulation = PSK_8;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch ((MXL_HYDRA_ROLLOFF_E)
|
||||
regData[DMD_SPECTRUM_ROLL_OFF_ADDR]) {
|
||||
case MXL_HYDRA_ROLLOFF_0_20:
|
||||
p->rolloff = ROLLOFF_20;
|
||||
break;
|
||||
case MXL_HYDRA_ROLLOFF_0_35:
|
||||
p->rolloff = ROLLOFF_35;
|
||||
break;
|
||||
case MXL_HYDRA_ROLLOFF_0_25:
|
||||
p->rolloff = ROLLOFF_25;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
@@ -670,8 +857,8 @@ static struct dvb_frontend_ops mxl_ops = {
|
||||
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
|
||||
.info = {
|
||||
.name = "MXL5XX",
|
||||
.frequency_min = 950000,
|
||||
.frequency_max = 2150000,
|
||||
.frequency_min = 300000,
|
||||
.frequency_max = 2350000,
|
||||
.frequency_stepsize = 0,
|
||||
.frequency_tolerance = 0,
|
||||
.symbol_rate_min = 1000000,
|
||||
@@ -749,12 +936,14 @@ static int write_fw_segment(struct mxl *state,
|
||||
u32 origSize = 0;
|
||||
u8 *wBufPtr = NULL;
|
||||
u32 blockSize = ((MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH -
|
||||
(MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4;
|
||||
(MXL_HYDRA_I2C_HDR_SIZE +
|
||||
MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4;
|
||||
u8 wMsgBuffer[MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH -
|
||||
(MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)];
|
||||
|
||||
do {
|
||||
size = origSize = (((u32)(dataCount + blockSize)) > totalSize) ?
|
||||
size = origSize =
|
||||
(((u32)(dataCount + blockSize)) > totalSize) ?
|
||||
(totalSize - dataCount) : blockSize;
|
||||
|
||||
if (origSize & 3)
|
||||
@@ -775,8 +964,8 @@ static int write_fw_segment(struct mxl *state,
|
||||
return status;
|
||||
}
|
||||
|
||||
static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr, u32 mbinBufferSize)
|
||||
|
||||
static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr,
|
||||
u32 mbinBufferSize)
|
||||
{
|
||||
int status;
|
||||
u32 index = 0;
|
||||
@@ -801,26 +990,31 @@ static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr, u32 mbinBu
|
||||
__func__, segmentPtr->header.id);
|
||||
return -EINVAL;
|
||||
}
|
||||
segLength = get_big_endian(24, &(segmentPtr->header.len24[0]));
|
||||
segAddress = get_big_endian(32, &(segmentPtr->header.address[0]));
|
||||
segLength = get_big_endian(24,
|
||||
&(segmentPtr->header.len24[0]));
|
||||
segAddress = get_big_endian(32,
|
||||
&(segmentPtr->header.address[0]));
|
||||
|
||||
if (state->base->type == MXL_HYDRA_DEVICE_568) {
|
||||
if ((((segAddress & 0x90760000) == 0x90760000) ||
|
||||
((segAddress & 0x90740000) == 0x90740000)) &&
|
||||
(xcpuFwFlag == MXL_FALSE)) {
|
||||
SET_REG_FIELD_DATA(PRCM_PRCM_CPU_SOFT_RST_N, 1);
|
||||
SET_REG_FIELD_DATA(PRCM_PRCM_CPU_SOFT_RST_N,
|
||||
1);
|
||||
msleep(200);
|
||||
write_register(state, 0x90720000, 0);
|
||||
msleep(10);
|
||||
xcpuFwFlag = MXL_TRUE;
|
||||
}
|
||||
status = write_fw_segment(state, segAddress,
|
||||
segLength, (u8 *) segmentPtr->data);
|
||||
segLength,
|
||||
(u8 *) segmentPtr->data);
|
||||
} else {
|
||||
if (((segAddress & 0x90760000) != 0x90760000) &&
|
||||
((segAddress & 0x90740000) != 0x90740000))
|
||||
status = write_fw_segment(state, segAddress,
|
||||
segLength, (u8 *) segmentPtr->data);
|
||||
segLength,
|
||||
(u8 *) segmentPtr->data);
|
||||
}
|
||||
if (status)
|
||||
return status;
|
||||
@@ -883,14 +1077,17 @@ static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len)
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Disable clock to Baseband, Wideband, SerDes, Alias ext & Transport modules */
|
||||
status = write_register(state, HYDRA_MODULES_CLK_2_REG, HYDRA_DISABLE_CLK_2);
|
||||
/* Disable clock to Baseband, Wideband, SerDes,
|
||||
Alias ext & Transport modules */
|
||||
status = write_register(state, HYDRA_MODULES_CLK_2_REG,
|
||||
HYDRA_DISABLE_CLK_2);
|
||||
if (status)
|
||||
return status;
|
||||
/* Clear Software & Host interrupt status - (Clear on read) */
|
||||
status = read_register(state, HYDRA_PRCM_ROOT_CLK_REG, ®Data);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = do_firmware_download(state, mbin, mbin_len);
|
||||
if (status)
|
||||
return status;
|
||||
@@ -927,13 +1124,15 @@ static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len)
|
||||
|
||||
pr_info("mxl5xx: Hydra FW alive. Hail!\n");
|
||||
|
||||
/* sometimes register values are wrong shortly after first heart beats */
|
||||
/* sometimes register values are wrong shortly
|
||||
after first heart beats */
|
||||
msleep(50);
|
||||
|
||||
devSkuCfg.skuType = state->base->sku_type;
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_DEV_CFG_SKU_CMD, MXL_CMD_WRITE,
|
||||
cmdSize, &devSkuCfg, cmdBuff);
|
||||
status = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
status = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -963,19 +1162,32 @@ static int cfg_ts_pad_mux(struct mxl *state, MXL_BOOL_E enableSerialTS)
|
||||
case MXL_HYDRA_DEVICE_541S:
|
||||
case MXL_HYDRA_DEVICE_561S:
|
||||
case MXL_HYDRA_DEVICE_581S:
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_14_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_15_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_16_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_17_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_18_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_19_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_20_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_21_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_22_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_23_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_24_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_25_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_26_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_14_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_15_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_16_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_17_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_18_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_19_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_20_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_21_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_22_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_23_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_24_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_25_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_26_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
break;
|
||||
|
||||
case MXL_HYDRA_DEVICE_544:
|
||||
@@ -1159,7 +1371,7 @@ static int enable_tuner(struct mxl *state, u32 tuner, u32 enable)
|
||||
if (!count)
|
||||
return -1;
|
||||
read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val);
|
||||
pr_info("mxl5xx: tuner %u ready = %u\n", tuner , (val >> tuner) & 1);
|
||||
/*pr_info("mxl5xx: tuner %u ready = %u\n", tuner , (val >> tuner) & 1);*/
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -1194,8 +1406,10 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId,
|
||||
{XPT_TS_CLK_PHASE4}, {XPT_TS_CLK_PHASE5},
|
||||
{XPT_TS_CLK_PHASE6}, {XPT_TS_CLK_PHASE7} };
|
||||
MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = {
|
||||
{XPT_LSB_FIRST0}, {XPT_LSB_FIRST1}, {XPT_LSB_FIRST2}, {XPT_LSB_FIRST3},
|
||||
{XPT_LSB_FIRST4}, {XPT_LSB_FIRST5}, {XPT_LSB_FIRST6}, {XPT_LSB_FIRST7} };
|
||||
{XPT_LSB_FIRST0}, {XPT_LSB_FIRST1},
|
||||
{XPT_LSB_FIRST2}, {XPT_LSB_FIRST3},
|
||||
{XPT_LSB_FIRST4}, {XPT_LSB_FIRST5},
|
||||
{XPT_LSB_FIRST6}, {XPT_LSB_FIRST7} };
|
||||
MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = {
|
||||
{XPT_SYNC_FULL_BYTE0}, {XPT_SYNC_FULL_BYTE1},
|
||||
{XPT_SYNC_FULL_BYTE2}, {XPT_SYNC_FULL_BYTE3},
|
||||
@@ -1230,16 +1444,17 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId,
|
||||
MXL_REG_FIELD_T mxl561_xpt_ts_sync[MXL_HYDRA_DEMOD_ID_6] = {
|
||||
{PAD_MUX_DIGIO_25_PINMUX_SEL}, {PAD_MUX_DIGIO_20_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_17_PINMUX_SEL}, {PAD_MUX_DIGIO_11_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_08_PINMUX_SEL}, {PAD_MUX_DIGIO_03_PINMUX_SEL} };
|
||||
{PAD_MUX_DIGIO_08_PINMUX_SEL}, {PAD_MUX_DIGIO_03_PINMUX_SEL}};
|
||||
MXL_REG_FIELD_T mxl561_xpt_ts_valid[MXL_HYDRA_DEMOD_ID_6] = {
|
||||
{PAD_MUX_DIGIO_26_PINMUX_SEL}, {PAD_MUX_DIGIO_19_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_18_PINMUX_SEL}, {PAD_MUX_DIGIO_10_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_09_PINMUX_SEL}, {PAD_MUX_DIGIO_02_PINMUX_SEL} };
|
||||
{PAD_MUX_DIGIO_09_PINMUX_SEL}, {PAD_MUX_DIGIO_02_PINMUX_SEL}};
|
||||
|
||||
demodId = state->base->ts_map[demodId];
|
||||
|
||||
if (MXL_ENABLE == mpegOutParamPtr->enable) {
|
||||
if (mpegOutParamPtr->mpegMode == MXL_HYDRA_MPEG_MODE_PARALLEL) {
|
||||
if (mpegOutParamPtr->mpegMode ==
|
||||
MXL_HYDRA_MPEG_MODE_PARALLEL) {
|
||||
#if 0
|
||||
for (i = MXL_HYDRA_DEMOD_ID_0; i < MXL_HYDRA_DEMOD_MAX; i++) {
|
||||
mxlStatus |= MxLWare_Hydra_UpdateByMnemonic(devId,
|
||||
@@ -1373,11 +1588,12 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId,
|
||||
}
|
||||
|
||||
if (mpegOutParamPtr->mpegMode != MXL_HYDRA_MPEG_MODE_PARALLEL) {
|
||||
status |= update_by_mnemonic(state,
|
||||
xpt_enable_output[demodId].regAddr,
|
||||
xpt_enable_output[demodId].lsbPos,
|
||||
xpt_enable_output[demodId].numOfBits,
|
||||
mpegOutParamPtr->enable);
|
||||
status |=
|
||||
update_by_mnemonic(state,
|
||||
xpt_enable_output[demodId].regAddr,
|
||||
xpt_enable_output[demodId].lsbPos,
|
||||
xpt_enable_output[demodId].numOfBits,
|
||||
mpegOutParamPtr->enable);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -1415,7 +1631,8 @@ static int config_dis(struct mxl *state, u32 id)
|
||||
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_DISEQC_CFG_MSG_CMD,
|
||||
MXL_CMD_WRITE, cmdSize, &diseqcMsg, cmdBuff);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
}
|
||||
|
||||
static int load_fw(struct mxl *state, struct mxl5xx_cfg *cfg)
|
||||
@@ -1442,7 +1659,7 @@ static int load_fw(struct mxl *state, struct mxl5xx_cfg *cfg)
|
||||
|
||||
static int validate_sku(struct mxl *state)
|
||||
{
|
||||
u32 padMuxBond, prcmChipId, prcmSoCId;
|
||||
u32 padMuxBond = 0, prcmChipId = 0, prcmSoCId = 0;
|
||||
int status;
|
||||
u32 type = state->base->type;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,9 @@
|
||||
#include "stv090x.h"
|
||||
#include "stv090x_priv.h"
|
||||
|
||||
#define ERRCTRL1_DVBS1 0x76
|
||||
/* Max transfer size done by I2C transfer functions */
|
||||
#define MAX_XFER_SIZE 64
|
||||
#define ERRCTRL1_DVBS1 0x76
|
||||
#define ERRCTRL1_DVBS2 0x67
|
||||
|
||||
#define STOP_DEMOD 1
|
||||
@@ -728,8 +730,16 @@ static int stv090x_write_regs(struct stv090x_state *state, unsigned int reg, u8
|
||||
{
|
||||
const struct stv090x_config *config = state->config;
|
||||
int ret;
|
||||
u8 buf[2 + count];
|
||||
struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0, .buf = buf, .len = 2 + count };
|
||||
u8 buf[MAX_XFER_SIZE];
|
||||
struct i2c_msg i2c_msg = { .addr = config->address, .flags = 0,
|
||||
.buf = buf, .len = 2 + count };
|
||||
|
||||
if (2 + count > sizeof(buf)) {
|
||||
printk(KERN_WARNING
|
||||
"%s: i2c wr reg=%04x: len=%d is too big!\n",
|
||||
KBUILD_MODNAME, reg, count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf[0] = reg >> 8;
|
||||
buf[1] = reg & 0xff;
|
||||
@@ -2144,7 +2154,7 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
|
||||
|
||||
u32 reg;
|
||||
s32 car_step, steps, cur_step, dir, freq, timeout_lock;
|
||||
int lock = 0;
|
||||
int lock;
|
||||
|
||||
if (state->srate >= 10000000)
|
||||
timeout_lock = timeout_dmd / 3;
|
||||
@@ -2152,100 +2162,97 @@ static int stv090x_get_coldlock(struct stv090x_state *state, s32 timeout_dmd)
|
||||
timeout_lock = timeout_dmd / 2;
|
||||
|
||||
lock = stv090x_get_dmdlock(state, timeout_lock); /* cold start wait */
|
||||
if (!lock) {
|
||||
if (state->srate >= 10000000) {
|
||||
if (stv090x_chk_tmg(state)) {
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
|
||||
goto err;
|
||||
lock = stv090x_get_dmdlock(state, timeout_dmd);
|
||||
} else {
|
||||
lock = 0;
|
||||
}
|
||||
} else {
|
||||
if (state->srate <= 4000000)
|
||||
car_step = 1000;
|
||||
else if (state->srate <= 7000000)
|
||||
car_step = 2000;
|
||||
else if (state->srate <= 10000000)
|
||||
car_step = 3000;
|
||||
else
|
||||
car_step = 5000;
|
||||
if (lock)
|
||||
return lock;
|
||||
|
||||
steps = (state->search_range / 1000) / car_step;
|
||||
steps /= 2;
|
||||
steps = 2 * (steps + 1);
|
||||
if (steps < 0)
|
||||
steps = 2;
|
||||
else if (steps > 12)
|
||||
steps = 12;
|
||||
|
||||
cur_step = 1;
|
||||
dir = 1;
|
||||
|
||||
if (!lock) {
|
||||
freq = state->frequency;
|
||||
state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
|
||||
while ((cur_step <= steps) && (!lock)) {
|
||||
if (dir > 0)
|
||||
freq += cur_step * car_step;
|
||||
else
|
||||
freq -= cur_step * car_step;
|
||||
|
||||
/* Setup tuner */
|
||||
if (stv090x_i2c_gate_ctrl(state, 1) < 0)
|
||||
goto err;
|
||||
|
||||
if (state->config->tuner_set_frequency) {
|
||||
if (state->config->tuner_set_frequency(fe, freq) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (state->config->tuner_set_bandwidth) {
|
||||
if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
|
||||
goto err;
|
||||
|
||||
msleep(50);
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 1) < 0)
|
||||
goto err;
|
||||
|
||||
if (state->config->tuner_get_status) {
|
||||
if (state->config->tuner_get_status(fe, ®) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (reg)
|
||||
dprintk(FE_DEBUG, 1, "Tuner phase locked");
|
||||
else
|
||||
dprintk(FE_DEBUG, 1, "Tuner unlocked");
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
|
||||
goto err;
|
||||
|
||||
STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
|
||||
if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
|
||||
goto err;
|
||||
lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
|
||||
|
||||
dir *= -1;
|
||||
cur_step++;
|
||||
}
|
||||
}
|
||||
if (state->srate >= 10000000) {
|
||||
if (stv090x_chk_tmg(state)) {
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
|
||||
goto err;
|
||||
return stv090x_get_dmdlock(state, timeout_dmd);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (state->srate <= 4000000)
|
||||
car_step = 1000;
|
||||
else if (state->srate <= 7000000)
|
||||
car_step = 2000;
|
||||
else if (state->srate <= 10000000)
|
||||
car_step = 3000;
|
||||
else
|
||||
car_step = 5000;
|
||||
|
||||
steps = (state->search_range / 1000) / car_step;
|
||||
steps /= 2;
|
||||
steps = 2 * (steps + 1);
|
||||
if (steps < 0)
|
||||
steps = 2;
|
||||
else if (steps > 12)
|
||||
steps = 12;
|
||||
|
||||
cur_step = 1;
|
||||
dir = 1;
|
||||
|
||||
freq = state->frequency;
|
||||
state->tuner_bw = stv090x_car_width(state->srate, state->rolloff) + state->srate;
|
||||
while ((cur_step <= steps) && (!lock)) {
|
||||
if (dir > 0)
|
||||
freq += cur_step * car_step;
|
||||
else
|
||||
freq -= cur_step * car_step;
|
||||
|
||||
/* Setup tuner */
|
||||
if (stv090x_i2c_gate_ctrl(state, 1) < 0)
|
||||
goto err;
|
||||
|
||||
if (state->config->tuner_set_frequency) {
|
||||
if (state->config->tuner_set_frequency(fe, freq) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (state->config->tuner_set_bandwidth) {
|
||||
if (state->config->tuner_set_bandwidth(fe, state->tuner_bw) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
|
||||
goto err;
|
||||
|
||||
msleep(50);
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 1) < 0)
|
||||
goto err;
|
||||
|
||||
if (state->config->tuner_get_status) {
|
||||
if (state->config->tuner_get_status(fe, ®) < 0)
|
||||
goto err_gateoff;
|
||||
}
|
||||
|
||||
if (reg)
|
||||
dprintk(FE_DEBUG, 1, "Tuner phase locked");
|
||||
else
|
||||
dprintk(FE_DEBUG, 1, "Tuner unlocked");
|
||||
|
||||
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
|
||||
goto err;
|
||||
|
||||
STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1c);
|
||||
if (STV090x_WRITE_DEMOD(state, CFRINIT1, 0x00) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, CFRINIT0, 0x00) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x1f) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, DMDISTATE, 0x15) < 0)
|
||||
goto err;
|
||||
lock = stv090x_get_dmdlock(state, (timeout_dmd / 3));
|
||||
|
||||
dir *= -1;
|
||||
cur_step++;
|
||||
}
|
||||
return lock;
|
||||
|
||||
err_gateoff:
|
||||
@@ -2661,14 +2668,9 @@ static enum stv090x_signal_state stv090x_get_sig_params(struct stv090x_state *st
|
||||
return STV090x_RANGEOK;
|
||||
else if (abs(offst_freq) <= (stv090x_car_width(state->srate, state->rolloff) / 2000))
|
||||
return STV090x_RANGEOK;
|
||||
else
|
||||
return STV090x_OUTOFRANGE; /* Out of Range */
|
||||
} else {
|
||||
} else
|
||||
if (abs(offst_freq) <= ((state->search_range / 2000) + 500))
|
||||
return STV090x_RANGEOK;
|
||||
else
|
||||
return STV090x_OUTOFRANGE;
|
||||
}
|
||||
|
||||
return STV090x_OUTOFRANGE;
|
||||
|
||||
@@ -2787,6 +2789,12 @@ static u8 stv090x_optimize_carloop(struct stv090x_state *state, enum stv090x_mod
|
||||
aclc = car_loop[i].crl_pilots_off_30;
|
||||
}
|
||||
} else { /* 16APSK and 32APSK */
|
||||
/*
|
||||
* This should never happen in practice, except if
|
||||
* something is really wrong at the car_loop table.
|
||||
*/
|
||||
if (i >= 11)
|
||||
i = 10;
|
||||
if (state->srate <= 3000000)
|
||||
aclc = car_loop_apsk_low[i].crl_pilots_on_2;
|
||||
else if (state->srate <= 7000000)
|
||||
@@ -3435,6 +3443,48 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv090x_set_pls(struct stv090x_state *state, u8 pls_mode, u32 pls_code)
|
||||
{
|
||||
dprintk(FE_DEBUG, 1, "Set PLS code %d (mode %d)", pls_code, pls_mode);
|
||||
if (STV090x_WRITE_DEMOD(state, PLROOT2, (pls_mode << 2) | (pls_code >> 16)) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, PLROOT1, (pls_code >> 8) & 0xff) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code & 0xff) < 0)
|
||||
goto err;
|
||||
return 0;
|
||||
err:
|
||||
dprintk(FE_ERROR, 1, "I/O error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv090x_set_mis(struct stv090x_state *state, u32 mis)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (mis == NO_STREAM_ID_FILTER) {
|
||||
dprintk(FE_DEBUG, 1, "Disable MIS filtering");
|
||||
reg = STV090x_READ_DEMOD(state, PDELCTRL1);
|
||||
STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x00);
|
||||
if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
|
||||
goto err;
|
||||
} else {
|
||||
dprintk(FE_DEBUG, 1, "Enable MIS filtering - %d", mis);
|
||||
reg = STV090x_READ_DEMOD(state, PDELCTRL1);
|
||||
STV090x_SETFIELD_Px(reg, FILTER_EN_FIELD, 0x01);
|
||||
if (STV090x_WRITE_DEMOD(state, PDELCTRL1, reg) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, ISIENTRY, mis & 0xff) < 0)
|
||||
goto err;
|
||||
if (STV090x_WRITE_DEMOD(state, ISIBITENA, 0xff) < 0)
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
err:
|
||||
dprintk(FE_ERROR, 1, "I/O error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef USE_API3
|
||||
static enum dvbfe_search stv090x_search(struct dvb_frontend *fe)
|
||||
#else
|
||||
@@ -3443,14 +3493,27 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *props = &fe->dtv_property_cache;
|
||||
|
||||
u32 pls = 1;
|
||||
|
||||
#ifndef USE_API3
|
||||
if (props->frequency == 0)
|
||||
#else
|
||||
return DVBFE_ALGO_SEARCH_INVALID;
|
||||
#endif
|
||||
|
||||
state->delsys = props->delivery_system;
|
||||
switch (props->delivery_system) {
|
||||
case SYS_DSS:
|
||||
state->delsys = STV090x_DSS;
|
||||
break;
|
||||
case SYS_DVBS:
|
||||
state->delsys = STV090x_DVBS1;
|
||||
break;
|
||||
case SYS_DVBS2:
|
||||
state->delsys = STV090x_DVBS2;
|
||||
break;
|
||||
default:
|
||||
return DVBFE_ALGO_SEARCH_INVALID;
|
||||
}
|
||||
#ifndef USE_API3
|
||||
state->frequency = props->frequency;
|
||||
state->srate = props->symbol_rate;
|
||||
@@ -3469,6 +3532,16 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron
|
||||
state->search_range = 5000000;
|
||||
}
|
||||
|
||||
/* Backwards compatibility to "crazy" API.
|
||||
PRBS X root cannot be 0, so this should always work. */
|
||||
if ((props->stream_id != NO_STREAM_ID_FILTER) &&
|
||||
(props->stream_id & 0xffffff00))
|
||||
pls = props->stream_id >> 8;
|
||||
if (props->pls != NO_SCRAMBLING_CODE)
|
||||
pls = props->pls | 0x40000; /* props->pls is always gold code */
|
||||
stv090x_set_pls(state, (pls >> 18) & 3, pls & 0x3ffff);
|
||||
stv090x_set_mis(state, props->stream_id);
|
||||
|
||||
if (stv090x_algo(state) == STV090x_RANGEOK) {
|
||||
dprintk(FE_DEBUG, 1, "Search success!");
|
||||
return DVBFE_ALGO_SEARCH_SUCCESS;
|
||||
@@ -3480,6 +3553,43 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron
|
||||
return DVBFE_ALGO_SEARCH_ERROR;
|
||||
}
|
||||
|
||||
static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr);
|
||||
static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength);
|
||||
|
||||
static int stv090x_ber_prop(struct dvb_frontend *fe, enum fe_status *status)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
|
||||
u32 reg, h, m, l;
|
||||
u32 n = 0, d = 1;
|
||||
|
||||
if (!(*status & FE_HAS_LOCK)) {
|
||||
n = 1;
|
||||
d = 1;
|
||||
} else {
|
||||
/* Counter 1 */
|
||||
reg = STV090x_READ_DEMOD(state, ERRCNT12);
|
||||
h = STV090x_GETFIELD_Px(reg, ERR_CNT12_FIELD);
|
||||
|
||||
reg = STV090x_READ_DEMOD(state, ERRCNT11);
|
||||
m = STV090x_GETFIELD_Px(reg, ERR_CNT11_FIELD);
|
||||
|
||||
reg = STV090x_READ_DEMOD(state, ERRCNT10);
|
||||
l = STV090x_GETFIELD_Px(reg, ERR_CNT10_FIELD);
|
||||
|
||||
n = ((h << 16) | (m << 8) | l);
|
||||
|
||||
}
|
||||
p->pre_bit_error.len = 1;
|
||||
p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_error.stat[0].uvalue =n;
|
||||
p->pre_bit_count.len = 1;
|
||||
p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_count.stat[0].uvalue = d;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
@@ -3494,15 +3604,17 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
|
||||
|
||||
reg = STV090x_READ_DEMOD(state, DMDSTATE);
|
||||
search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD);
|
||||
|
||||
|
||||
switch (search_state) {
|
||||
case 0: /* searching */
|
||||
case 1: /* first PLH detected */
|
||||
default:
|
||||
dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)");
|
||||
state->rec_mode = 0;
|
||||
break;
|
||||
|
||||
case 2: /* DVB-S2 mode */
|
||||
state->rec_mode = 2;
|
||||
dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2");
|
||||
if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) {
|
||||
reg = STV090x_READ_DEMOD(state, PDELSTATUS1);
|
||||
@@ -3516,6 +3628,7 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
|
||||
break;
|
||||
|
||||
case 3: /* DVB-S1/legacy mode */
|
||||
state->rec_mode = 1;
|
||||
dprintk(FE_DEBUG, 1, "Delivery system: DVB-S");
|
||||
if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) {
|
||||
reg = STV090x_READ_DEMOD(state, VSTATUSVIT);
|
||||
@@ -3529,13 +3642,22 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status)
|
||||
break;
|
||||
}
|
||||
|
||||
{
|
||||
u16 val;
|
||||
u32 ber;
|
||||
|
||||
stv090x_read_cnr(fe, &val);
|
||||
stv090x_read_signal_strength(fe, &val);
|
||||
stv090x_ber_prop(fe, status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv090x_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 reg, h, m, l;
|
||||
enum fe_status status;
|
||||
|
||||
@@ -3555,6 +3677,14 @@ static int stv090x_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
|
||||
*ber = ((h << 16) | (m << 8) | l);
|
||||
}
|
||||
#if 0
|
||||
p->pre_bit_error.len = 1;
|
||||
p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_error.stat[0].uvalue = n;
|
||||
p->pre_bit_count.len = 1;
|
||||
p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_count.stat[0].uvalue = d;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3650,6 +3780,7 @@ static int stv090x_table_lookup(const struct stv090x_tab *tab, int max, int val)
|
||||
static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 reg;
|
||||
s32 agc_0, agc_1, agc;
|
||||
s32 str;
|
||||
@@ -3666,8 +3797,15 @@ static int stv090x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
str = 0;
|
||||
else if (agc < stv090x_rf_tab[ARRAY_SIZE(stv090x_rf_tab) - 1].read)
|
||||
str = -100;
|
||||
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].uvalue = 1000 * (s64) (s32) str;
|
||||
#ifdef DBVALS
|
||||
*strength = str;
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].uvalue = 10 * (s64) str;
|
||||
#else
|
||||
*strength = (str + 100) * 0xFFFF / 100;
|
||||
#endif
|
||||
@@ -3694,13 +3832,13 @@ static int stv090x_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
|
||||
static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 reg_0, reg_1, reg, i;
|
||||
s32 val_0, val_1, val = 0;
|
||||
u8 lock_f;
|
||||
#ifndef DBVALS
|
||||
s32 cnr_db;
|
||||
s32 div;
|
||||
u32 last;
|
||||
#endif
|
||||
|
||||
switch (state->delsys) {
|
||||
case STV090x_DVBS2:
|
||||
@@ -3717,21 +3855,16 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
|
||||
msleep(1);
|
||||
}
|
||||
val /= 16;
|
||||
#ifdef DBVALS
|
||||
*cnr = stv090x_table_lookup(stv090x_s2cn_tab,
|
||||
ARRAY_SIZE(stv090x_s2cn_tab) - 1, val);
|
||||
#else
|
||||
cnr_db = stv090x_table_lookup(stv090x_s2cn_tab,
|
||||
ARRAY_SIZE(stv090x_s2cn_tab) - 1, val);
|
||||
last = ARRAY_SIZE(stv090x_s2cn_tab) - 1;
|
||||
div = stv090x_s2cn_tab[0].read -
|
||||
stv090x_s2cn_tab[last].read;
|
||||
*cnr = 0xFFFF - ((val * 0xFFFF) / div);
|
||||
#endif
|
||||
} else
|
||||
#ifdef DBVALS
|
||||
*cnr = -30;
|
||||
#else
|
||||
} else {
|
||||
cnr_db = -30;
|
||||
*cnr = 0;
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case STV090x_DVBS1:
|
||||
@@ -3749,26 +3882,30 @@ static int stv090x_read_cnr(struct dvb_frontend *fe, u16 *cnr)
|
||||
msleep(1);
|
||||
}
|
||||
val /= 16;
|
||||
#ifdef DBVALS
|
||||
*cnr = stv090x_table_lookup(stv090x_s1cn_tab,
|
||||
ARRAY_SIZE(stv090x_s1cn_tab) - 1, val);
|
||||
#else
|
||||
cnr_db = stv090x_table_lookup(stv090x_s1cn_tab,
|
||||
ARRAY_SIZE(stv090x_s1cn_tab) - 1, val);
|
||||
last = ARRAY_SIZE(stv090x_s1cn_tab) - 1;
|
||||
div = stv090x_s1cn_tab[0].read -
|
||||
stv090x_s1cn_tab[last].read;
|
||||
*cnr = 0xFFFF - ((val * 0xFFFF) / div);
|
||||
#endif
|
||||
} else
|
||||
} else {
|
||||
cnr_db = -30;
|
||||
*cnr = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef DBVALS
|
||||
*cnr = cnr_db;
|
||||
#endif
|
||||
p->cnr.len = 1;
|
||||
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->cnr.stat[0].uvalue = 100 * (s64) cnr_db;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv090x_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
|
||||
static int stv090x_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
u32 reg;
|
||||
@@ -3866,7 +4003,8 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv090x_send_diseqc_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
|
||||
static int stv090x_send_diseqc_burst(struct dvb_frontend *fe,
|
||||
enum fe_sec_mini_cmd burst)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
u32 reg, idle = 0, fifo_full = 1;
|
||||
@@ -3977,12 +4115,12 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
reg = stv090x_read_reg(state, STV090x_TSTTNR1);
|
||||
STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
/* power off DiSEqC 1 */
|
||||
reg = stv090x_read_reg(state, STV090x_TSTTNR2);
|
||||
STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
|
||||
/* check whether path 2 is already sleeping, that is when
|
||||
ADC2 is off */
|
||||
@@ -4001,7 +4139,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
reg = stv090x_read_reg(state, STV090x_STOPCLK2);
|
||||
/* sampling 1 clock */
|
||||
STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
|
||||
@@ -4012,7 +4150,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
break;
|
||||
|
||||
case STV090x_DEMODULATOR_1:
|
||||
@@ -4020,12 +4158,12 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
reg = stv090x_read_reg(state, STV090x_TSTTNR3);
|
||||
STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
/* power off DiSEqC 2 */
|
||||
reg = stv090x_read_reg(state, STV090x_TSTTNR4);
|
||||
STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
|
||||
if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
|
||||
/* check whether path 1 is already sleeping, that is when
|
||||
ADC1 is off */
|
||||
@@ -4044,7 +4182,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
reg = stv090x_read_reg(state, STV090x_STOPCLK2);
|
||||
/* sampling 2 clock */
|
||||
STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
|
||||
@@ -4055,7 +4193,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
if (full_standby)
|
||||
STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
|
||||
if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -4068,7 +4206,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
|
||||
STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
|
||||
goto err;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
mutex_unlock(&state->internal->demod_lock);
|
||||
@@ -4076,8 +4214,10 @@ static int stv090x_sleep(struct dvb_frontend *fe)
|
||||
|
||||
err_gateoff:
|
||||
stv090x_i2c_gate_ctrl(state, 0);
|
||||
err:
|
||||
goto err;
|
||||
err_unlock:
|
||||
mutex_unlock(&state->internal->demod_lock);
|
||||
err:
|
||||
dprintk(FE_ERROR, 1, "I/O error");
|
||||
return -1;
|
||||
}
|
||||
@@ -4338,7 +4478,7 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv090x_set_tspath(struct stv090x_state *state)
|
||||
static int stv0900_set_tspath(struct stv090x_state *state)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
@@ -4588,8 +4728,6 @@ static int stv090x_set_tspath(struct stv090x_state *state)
|
||||
}
|
||||
|
||||
|
||||
printk("TSCFGH resets\n");
|
||||
|
||||
reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
|
||||
@@ -4612,6 +4750,121 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv0903_set_tspath(struct stv090x_state *state)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
if (state->internal->dev_ver >= 0x20) {
|
||||
switch (state->config->ts1_mode) {
|
||||
case STV090x_TSMODE_PARALLEL_PUNCTURED:
|
||||
case STV090x_TSMODE_DVBCI:
|
||||
stv090x_write_reg(state, STV090x_TSGENERAL, 0x00);
|
||||
break;
|
||||
|
||||
case STV090x_TSMODE_SERIAL_PUNCTURED:
|
||||
case STV090x_TSMODE_SERIAL_CONTINUOUS:
|
||||
default:
|
||||
stv090x_write_reg(state, STV090x_TSGENERAL, 0x0c);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (state->config->ts1_mode) {
|
||||
case STV090x_TSMODE_PARALLEL_PUNCTURED:
|
||||
case STV090x_TSMODE_DVBCI:
|
||||
stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x10);
|
||||
break;
|
||||
|
||||
case STV090x_TSMODE_SERIAL_PUNCTURED:
|
||||
case STV090x_TSMODE_SERIAL_CONTINUOUS:
|
||||
default:
|
||||
stv090x_write_reg(state, STV090x_TSGENERAL1X, 0x14);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (state->config->ts1_mode) {
|
||||
case STV090x_TSMODE_PARALLEL_PUNCTURED:
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
case STV090x_TSMODE_DVBCI:
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
case STV090x_TSMODE_SERIAL_PUNCTURED:
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
case STV090x_TSMODE_SERIAL_CONTINUOUS:
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (state->config->ts1_clk > 0) {
|
||||
u32 speed;
|
||||
|
||||
switch (state->config->ts1_mode) {
|
||||
case STV090x_TSMODE_PARALLEL_PUNCTURED:
|
||||
case STV090x_TSMODE_DVBCI:
|
||||
default:
|
||||
speed = state->internal->mclk /
|
||||
(state->config->ts1_clk / 4);
|
||||
if (speed < 0x08)
|
||||
speed = 0x08;
|
||||
if (speed > 0xFF)
|
||||
speed = 0xFF;
|
||||
break;
|
||||
case STV090x_TSMODE_SERIAL_PUNCTURED:
|
||||
case STV090x_TSMODE_SERIAL_CONTINUOUS:
|
||||
speed = state->internal->mclk /
|
||||
(state->config->ts1_clk / 32);
|
||||
if (speed < 0x20)
|
||||
speed = 0x20;
|
||||
if (speed > 0xFF)
|
||||
speed = 0xFF;
|
||||
break;
|
||||
}
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGM);
|
||||
STV090x_SETFIELD_Px(reg, TSFIFO_MANSPEED_FIELD, 3);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGM, reg) < 0)
|
||||
goto err;
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSSPEED, speed) < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
|
||||
STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x01);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
STV090x_SETFIELD_Px(reg, RST_HWARE_FIELD, 0x00);
|
||||
if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
err:
|
||||
dprintk(FE_ERROR, 1, "I/O error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int stv090x_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
@@ -4675,8 +4928,13 @@ static int stv090x_init(struct dvb_frontend *fe)
|
||||
goto err;
|
||||
|
||||
#if 0
|
||||
if (stv090x_set_tspath(state) < 0)
|
||||
goto err;
|
||||
if (state->device == STV0900) {
|
||||
if (stv0900_set_tspath(state) < 0)
|
||||
goto err;
|
||||
} else {
|
||||
if (stv0903_set_tspath(state) < 0)
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
@@ -4717,23 +4975,26 @@ static int stv090x_setup(struct dvb_frontend *fe)
|
||||
/* Stop Demod */
|
||||
if (stv090x_write_reg(state, STV090x_P1_DMDISTATE, 0x5c) < 0)
|
||||
goto err;
|
||||
if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0)
|
||||
goto err;
|
||||
if (state->device == STV0900)
|
||||
if (stv090x_write_reg(state, STV090x_P2_DMDISTATE, 0x5c) < 0)
|
||||
goto err;
|
||||
|
||||
msleep(5);
|
||||
|
||||
/* Set No Tuner Mode */
|
||||
if (stv090x_write_reg(state, STV090x_P1_TNRCFG, 0x6c) < 0)
|
||||
goto err;
|
||||
if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0)
|
||||
goto err;
|
||||
if (state->device == STV0900)
|
||||
if (stv090x_write_reg(state, STV090x_P2_TNRCFG, 0x6c) < 0)
|
||||
goto err;
|
||||
|
||||
/* I2C repeater OFF */
|
||||
STV090x_SETFIELD_Px(reg, ENARPT_LEVEL_FIELD, config->repeater_level);
|
||||
if (stv090x_write_reg(state, STV090x_P1_I2CRPT, reg) < 0)
|
||||
goto err;
|
||||
if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0)
|
||||
goto err;
|
||||
if (state->device == STV0900)
|
||||
if (stv090x_write_reg(state, STV090x_P2_I2CRPT, reg) < 0)
|
||||
goto err;
|
||||
|
||||
if (stv090x_write_reg(state, STV090x_NCOARSE, 0x13) < 0) /* set PLL divider */
|
||||
goto err;
|
||||
@@ -4793,8 +5054,13 @@ static int stv090x_setup(struct dvb_frontend *fe)
|
||||
if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
|
||||
goto err;
|
||||
|
||||
if (stv090x_set_tspath(state) < 0)
|
||||
goto err;
|
||||
if (state->device == STV0900) {
|
||||
if (stv0900_set_tspath(state) < 0)
|
||||
goto err;
|
||||
} else {
|
||||
if (stv0903_set_tspath(state) < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
@@ -4802,8 +5068,8 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
|
||||
u8 xor_value)
|
||||
static int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir,
|
||||
u8 value, u8 xor_value)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
u8 reg = 0;
|
||||
@@ -4814,7 +5080,69 @@ int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
|
||||
|
||||
return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
|
||||
}
|
||||
EXPORT_SYMBOL(stv090x_set_gpio);
|
||||
|
||||
static int stv090x_get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
struct stv090x_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u8 tmp;
|
||||
u32 reg = 0;
|
||||
|
||||
if (state->rec_mode == 2) {
|
||||
u32 mc;
|
||||
enum fe_modulation modcod2mod[0x20] = {
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
PSK_8, PSK_8, PSK_8, PSK_8,
|
||||
PSK_8, PSK_8, APSK_16, APSK_16,
|
||||
APSK_16, APSK_16, APSK_16, APSK_16,
|
||||
APSK_32, APSK_32, APSK_32, APSK_32,
|
||||
APSK_32,
|
||||
};
|
||||
enum fe_code_rate modcod2fec[0x20] = {
|
||||
FEC_NONE, FEC_1_4, FEC_1_3, FEC_2_5,
|
||||
FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4,
|
||||
FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10,
|
||||
FEC_3_5, FEC_2_3, FEC_3_4, FEC_5_6,
|
||||
FEC_8_9, FEC_9_10, FEC_2_3, FEC_3_4,
|
||||
FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10,
|
||||
FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9,
|
||||
FEC_9_10
|
||||
};
|
||||
mc = state->modcod;
|
||||
p->pilot = (state->pilots & 0x01) ? PILOT_ON : PILOT_OFF;
|
||||
p->modulation = modcod2mod[mc];
|
||||
p->fec_inner = modcod2fec[mc];
|
||||
} else if (state->rec_mode == 1) {
|
||||
reg = STV090x_READ_DEMOD(state, VITCURPUN);
|
||||
switch( reg & 0x1F ) {
|
||||
case 0x0d:
|
||||
p->fec_inner = FEC_1_2;
|
||||
break;
|
||||
case 0x12:
|
||||
p->fec_inner = FEC_2_3;
|
||||
break;
|
||||
case 0x15:
|
||||
p->fec_inner = FEC_3_4;
|
||||
break;
|
||||
case 0x18:
|
||||
p->fec_inner = FEC_5_6;
|
||||
break;
|
||||
case 0x1a:
|
||||
p->fec_inner = FEC_7_8;
|
||||
break;
|
||||
default:
|
||||
p->fec_inner = FEC_NONE;
|
||||
break;
|
||||
}
|
||||
p->rolloff = ROLLOFF_35;
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_frontend_ops stv090x_ops = {
|
||||
#ifndef USE_API3
|
||||
@@ -4842,6 +5170,7 @@ static struct dvb_frontend_ops stv090x_ops = {
|
||||
|
||||
.sleep = stv090x_sleep,
|
||||
.get_frontend_algo = stv090x_frontend_algo,
|
||||
.get_frontend = stv090x_get_frontend,
|
||||
|
||||
.diseqc_send_master_cmd = stv090x_send_diseqc_msg,
|
||||
.diseqc_send_burst = stv090x_send_diseqc_burst,
|
||||
@@ -4857,7 +5186,7 @@ static struct dvb_frontend_ops stv090x_ops = {
|
||||
};
|
||||
|
||||
|
||||
struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
|
||||
struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
|
||||
struct i2c_adapter *i2c,
|
||||
enum stv090x_demodulator demod)
|
||||
{
|
||||
@@ -4911,15 +5240,22 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
|
||||
}
|
||||
}
|
||||
|
||||
if (state->internal->dev_ver >= 0x30)
|
||||
state->frontend.ops.info.caps |= FE_CAN_MULTISTREAM;
|
||||
|
||||
/* workaround for stuck DiSEqC output */
|
||||
if (config->diseqc_envelope_mode)
|
||||
stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
|
||||
|
||||
config->set_gpio = stv090x_set_gpio;
|
||||
|
||||
dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
|
||||
state->device == STV0900 ? "STV0900" : "STV0903",
|
||||
demod,
|
||||
state->internal->dev_ver);
|
||||
|
||||
printk("STV0900 version 0x%02x\n", state->internal->dev_ver);
|
||||
|
||||
return &state->frontend;
|
||||
|
||||
err_remove:
|
||||
|
@@ -101,18 +101,18 @@ struct stv090x_config {
|
||||
int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
|
||||
int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
|
||||
void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock);
|
||||
|
||||
/* dir = 0 -> output, dir = 1 -> input/open-drain */
|
||||
int (*set_gpio)(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
|
||||
u8 xor_value);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
|
||||
extern struct dvb_frontend *stv090x_attach(struct stv090x_config *config,
|
||||
struct i2c_adapter *i2c,
|
||||
enum stv090x_demodulator demod);
|
||||
|
||||
/* dir = 0 -> output, dir = 1 -> input/open-drain */
|
||||
extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
|
||||
u8 dir, u8 value, u8 xor_value);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
|
||||
@@ -123,12 +123,6 @@ static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
|
||||
u8 opd, u8 value, u8 xor_value)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_DVB_STV090x */
|
||||
|
||||
#endif /* __STV090x_H */
|
||||
|
@@ -274,6 +274,7 @@ struct stv090x_state {
|
||||
|
||||
s32 DemodTimeout;
|
||||
s32 FecTimeout;
|
||||
u32 rec_mode;
|
||||
};
|
||||
|
||||
#endif /* __STV090x_PRIV_H */
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Driver for the ST STV0910 DVB-S/S2 demodulator.
|
||||
*
|
||||
* Copyright (C) 2014-2015 Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Copyright (C) 2014-2016 Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* developed for Digital Devices GmbH
|
||||
*
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "stv0910_regs.h"
|
||||
|
||||
|
||||
#define EXT_CLOCK 30000000
|
||||
#define TUNING_DELAY 200
|
||||
#define BER_SRC_S 0x20
|
||||
#define BER_SRC_S2 0x20
|
||||
@@ -46,7 +47,6 @@ LIST_HEAD(stvlist);
|
||||
|
||||
enum ReceiveMode { Mode_None, Mode_DVBS, Mode_DVBS2, Mode_Auto };
|
||||
|
||||
|
||||
enum DVBS2_FECType { DVBS2_64K, DVBS2_16K };
|
||||
|
||||
enum DVBS2_ModCod {
|
||||
@@ -103,7 +103,9 @@ struct stv {
|
||||
u16 regoff;
|
||||
u8 i2crpt;
|
||||
u8 tscfgh;
|
||||
u8 tsgeneral;
|
||||
u8 tsspeed;
|
||||
u8 single;
|
||||
unsigned long tune_time;
|
||||
|
||||
s32 SearchRange;
|
||||
@@ -123,9 +125,17 @@ struct stv {
|
||||
u32 Pilots;
|
||||
enum FE_STV0910_RollOff FERollOff;
|
||||
|
||||
int isStandardBroadcast;
|
||||
int isVCM;
|
||||
|
||||
u32 CurScramblingCode;
|
||||
u32 ScramblingCode;
|
||||
|
||||
u32 LastBERNumerator;
|
||||
u32 LastBERDenominator;
|
||||
u8 BERScale;
|
||||
|
||||
u8 VTH[6];
|
||||
};
|
||||
|
||||
struct SInitTable {
|
||||
@@ -133,9 +143,9 @@ struct SInitTable {
|
||||
u8 Data;
|
||||
};
|
||||
|
||||
struct SLookupSNTable {
|
||||
s16 SignalToNoise;
|
||||
u16 RefValue;
|
||||
struct SLookup {
|
||||
s16 Value;
|
||||
u16 RegValue;
|
||||
};
|
||||
|
||||
static inline int i2c_write(struct i2c_adapter *adap, u8 adr,
|
||||
@@ -193,7 +203,20 @@ static int read_regs(struct stv *state, u16 reg, u8 *val, int len)
|
||||
reg, val, len);
|
||||
}
|
||||
|
||||
struct SLookupSNTable S1_SN_Lookup[] = {
|
||||
static int write_shared_reg(struct stv *state, u16 reg, u8 mask, u8 val)
|
||||
{
|
||||
int status;
|
||||
u8 tmp;
|
||||
|
||||
mutex_lock(&state->base->reg_lock);
|
||||
status = read_reg(state, reg, &tmp);
|
||||
if (!status)
|
||||
status = write_reg(state, reg, (tmp & ~mask) | (val & mask));
|
||||
mutex_unlock(&state->base->reg_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
struct SLookup S1_SN_Lookup[] = {
|
||||
{ 0, 9242 }, /*C/N= 0dB*/
|
||||
{ 05, 9105 }, /*C/N=0.5dB*/
|
||||
{ 10, 8950 }, /*C/N=1.0dB*/
|
||||
@@ -250,7 +273,7 @@ struct SLookupSNTable S1_SN_Lookup[] = {
|
||||
{ 510, 425 } /*C/N=51.0dB*/
|
||||
};
|
||||
|
||||
struct SLookupSNTable S2_SN_Lookup[] = {
|
||||
struct SLookup S2_SN_Lookup[] = {
|
||||
{ -30, 13950 }, /*C/N=-2.5dB*/
|
||||
{ -25, 13580 }, /*C/N=-2.5dB*/
|
||||
{ -20, 13150 }, /*C/N=-2.0dB*/
|
||||
@@ -452,24 +475,45 @@ static int GetCurSymbolRate(struct stv *state, u32 *pSymbolRate)
|
||||
|
||||
static int GetSignalParameters(struct stv *state)
|
||||
{
|
||||
u8 tmp;
|
||||
|
||||
if (!state->Started)
|
||||
return -1;
|
||||
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
u8 tmp;
|
||||
u8 rolloff;
|
||||
|
||||
read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp);
|
||||
state->ModCod = (enum FE_STV0910_ModCod) ((tmp & 0x7c) >> 2);
|
||||
state->Pilots = (tmp & 0x01) != 0;
|
||||
state->FECType = (enum DVBS2_FECType) ((tmp & 0x02) >> 1);
|
||||
|
||||
#if 0
|
||||
read_reg(state, RSTV0910_P2_TMGOBS + state->regoff, &rolloff);
|
||||
rolloff = rolloff >> 6;
|
||||
state->FERollOff = (enum FE_STV0910_RollOff) rolloff;
|
||||
|
||||
#endif
|
||||
} else if (state->ReceiveMode == Mode_DVBS) {
|
||||
/* todo */
|
||||
read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp);
|
||||
state->PunctureRate = FEC_NONE;
|
||||
switch (tmp & 0x1F) {
|
||||
case 0x0d:
|
||||
state->PunctureRate = FEC_1_2;
|
||||
break;
|
||||
case 0x12:
|
||||
state->PunctureRate = FEC_2_3;
|
||||
break;
|
||||
case 0x15:
|
||||
state->PunctureRate = FEC_3_4;
|
||||
break;
|
||||
case 0x18:
|
||||
state->PunctureRate = FEC_5_6;
|
||||
break;
|
||||
case 0x1A:
|
||||
state->PunctureRate = FEC_7_8;
|
||||
break;
|
||||
}
|
||||
state->isVCM = 0;
|
||||
state->isStandardBroadcast = 1;
|
||||
state->FERollOff = FE_SAT_35;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -485,18 +529,20 @@ static int TrackingOptimization(struct stv *state)
|
||||
|
||||
switch (state->ReceiveMode) {
|
||||
case Mode_DVBS:
|
||||
tmp |= 0x40; break;
|
||||
tmp |= 0x40;
|
||||
break;
|
||||
case Mode_DVBS2:
|
||||
tmp |= 0x80; break;
|
||||
tmp |= 0x80;
|
||||
break;
|
||||
default:
|
||||
tmp |= 0xC0; break;
|
||||
tmp |= 0xC0;
|
||||
break;
|
||||
}
|
||||
write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, tmp);
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
/* force to PRE BCH Rate */
|
||||
write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff,
|
||||
BER_SRC_S2 | state->BERScale);
|
||||
/*Disable Reed-Solomon */
|
||||
write_shared_reg(state, RSTV0910_TSTTSRS, state->nr ? 0x02 : 0x01, 0x03);
|
||||
|
||||
if (state->FECType == DVBS2_64K) {
|
||||
u8 aclc = get_optim_cloop(state, state->ModCod,
|
||||
@@ -523,40 +569,51 @@ static int TrackingOptimization(struct stv *state)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state->ReceiveMode == Mode_DVBS) {
|
||||
u8 tmp;
|
||||
|
||||
read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp);
|
||||
state->PunctureRate = FEC_NONE;
|
||||
switch (tmp & 0x1F) {
|
||||
case 0x0d:
|
||||
state->PunctureRate = FEC_1_2;
|
||||
break;
|
||||
case 0x12:
|
||||
state->PunctureRate = FEC_2_3;
|
||||
break;
|
||||
case 0x15:
|
||||
state->PunctureRate = FEC_3_4;
|
||||
break;
|
||||
case 0x18:
|
||||
state->PunctureRate = FEC_5_6;
|
||||
break;
|
||||
case 0x1A:
|
||||
state->PunctureRate = FEC_7_8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 TableLookup(struct SLookup *Table,
|
||||
int TableSize, u16 RegValue)
|
||||
{
|
||||
s32 Value;
|
||||
int imin = 0;
|
||||
int imax = TableSize - 1;
|
||||
int i;
|
||||
s32 RegDiff;
|
||||
|
||||
/* Assumes Table[0].RegValue > Table[imax].RegValue */
|
||||
if( RegValue >= Table[0].RegValue )
|
||||
Value = Table[0].Value;
|
||||
else if( RegValue <= Table[imax].RegValue )
|
||||
Value = Table[imax].Value;
|
||||
else
|
||||
{
|
||||
while(imax-imin > 1)
|
||||
{
|
||||
i = (imax + imin) / 2;
|
||||
if( (Table[imin].RegValue >= RegValue) && (RegValue >= Table[i].RegValue) )
|
||||
imax = i;
|
||||
else
|
||||
imin = i;
|
||||
}
|
||||
|
||||
RegDiff = Table[imax].RegValue - Table[imin].RegValue;
|
||||
Value = Table[imin].Value;
|
||||
if( RegDiff != 0 )
|
||||
Value += ((s32)(RegValue - Table[imin].RegValue) *
|
||||
(s32)(Table[imax].Value - Table[imin].Value))/(RegDiff);
|
||||
}
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
static int GetSignalToNoise(struct stv *state, s32 *SignalToNoise)
|
||||
{
|
||||
int i;
|
||||
u8 Data0;
|
||||
u8 Data1;
|
||||
u16 Data;
|
||||
int nLookup;
|
||||
struct SLookupSNTable *Lookup;
|
||||
struct SLookup *Lookup;
|
||||
|
||||
*SignalToNoise = 0;
|
||||
|
||||
@@ -575,25 +632,7 @@ static int GetSignalToNoise(struct stv *state, s32 *SignalToNoise)
|
||||
Lookup = S1_SN_Lookup;
|
||||
}
|
||||
Data = (((u16)Data1) << 8) | (u16) Data0;
|
||||
if (Data > Lookup[0].RefValue) {
|
||||
*SignalToNoise = Lookup[0].SignalToNoise;
|
||||
} else if (Data <= Lookup[nLookup-1].RefValue) {
|
||||
*SignalToNoise = Lookup[nLookup-1].SignalToNoise;
|
||||
} else {
|
||||
for (i = 0; i < nLookup - 1; i += 1) {
|
||||
if (Data <= Lookup[i].RefValue &&
|
||||
Data > Lookup[i+1].RefValue) {
|
||||
*SignalToNoise =
|
||||
(s32)(Lookup[i].SignalToNoise) +
|
||||
((s32)(Data - Lookup[i].RefValue) *
|
||||
(s32)(Lookup[i+1].SignalToNoise -
|
||||
Lookup[i].SignalToNoise)) /
|
||||
((s32)(Lookup[i+1].RefValue) -
|
||||
(s32)(Lookup[i].RefValue));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*SignalToNoise = TableLookup(Lookup, nLookup, Data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -634,6 +673,7 @@ static int GetBitErrorRateS(struct stv *state, u32 *BERNumerator,
|
||||
static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType)
|
||||
{
|
||||
static u32 nBCH[][2] = {
|
||||
{ 0, 0}, /* dummy */
|
||||
{16200, 3240}, /* QPSK_1_4, */
|
||||
{21600, 5400}, /* QPSK_1_3, */
|
||||
{25920, 6480}, /* QPSK_2_5, */
|
||||
@@ -666,15 +706,16 @@ static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType)
|
||||
|
||||
if (ModCod >= DVBS2_QPSK_1_4 &&
|
||||
ModCod <= DVBS2_32APSK_9_10 && FECType <= DVBS2_16K)
|
||||
return nBCH[FECType][ModCod];
|
||||
return nBCH[ModCod][FECType];
|
||||
return 64800;
|
||||
}
|
||||
|
||||
static int GetBitErrorRateS2(struct stv *state, u32 *BERNumerator,
|
||||
static int GetBitErrorRateS2(struct stv *state,
|
||||
u32 *BERNumerator,
|
||||
u32 *BERDenominator)
|
||||
{
|
||||
u8 Regs[3];
|
||||
|
||||
|
||||
int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff,
|
||||
Regs, 3);
|
||||
|
||||
@@ -812,12 +853,118 @@ static int Stop(struct stv *state)
|
||||
}
|
||||
|
||||
|
||||
static int init_search_param(struct stv *state)
|
||||
{
|
||||
u8 tmp;
|
||||
|
||||
read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp);
|
||||
tmp |= 0x20; // Filter_en (no effect if SIS=non-MIS
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, &tmp);
|
||||
tmp &= ~0x02; // frame mode = 0
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, tmp);
|
||||
|
||||
write_reg(state, RSTV0910_P2_UPLCCST0 + state->regoff, 0xe0);
|
||||
write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0x00);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, &tmp);
|
||||
tmp &= ~0x01; // nosync = 0, in case next signal is standard TS
|
||||
write_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSCFGL + state->regoff, &tmp);
|
||||
tmp &= ~0x04; // embindvb = 0
|
||||
write_reg(state, RSTV0910_P2_TSCFGL + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, &tmp);
|
||||
tmp &= ~0x80; // syncbyte = 0
|
||||
write_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, &tmp);
|
||||
tmp &= ~0x08; // token = 0
|
||||
write_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, &tmp);
|
||||
tmp &= ~0x30; // hysteresis threshold = 0
|
||||
write_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, &tmp);
|
||||
tmp = (tmp & ~0x30) | 0x10; // isi obs mode = 1, observe min ISI
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int EnablePunctureRate(struct stv *state, enum fe_code_rate rate)
|
||||
{
|
||||
switch(rate) {
|
||||
case FEC_1_2:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x01);
|
||||
case FEC_2_3:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x02);
|
||||
case FEC_3_4:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x04);
|
||||
case FEC_5_6:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x08);
|
||||
case FEC_7_8:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x20);
|
||||
case FEC_NONE:
|
||||
default:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2f);
|
||||
}
|
||||
}
|
||||
|
||||
static int set_vth_default(struct stv *state)
|
||||
{
|
||||
state->VTH[0] = 0xd7;
|
||||
state->VTH[1] = 0x85;
|
||||
state->VTH[2] = 0x58;
|
||||
state->VTH[3] = 0x3a;
|
||||
state->VTH[4] = 0x34;
|
||||
state->VTH[5] = 0x28;
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 0, state->VTH[0]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 1, state->VTH[1]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 2, state->VTH[2]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 3, state->VTH[3]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 4, state->VTH[4]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 5, state->VTH[5]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_vth(struct stv *state)
|
||||
{
|
||||
static struct SLookup VTHLookupTable[] = {
|
||||
{250, 8780}, /*C/N=1.5dB*/
|
||||
{100, 7405}, /*C/N=4.5dB*/
|
||||
{40, 6330}, /*C/N=6.5dB*/
|
||||
{12, 5224}, /*C/N=8.5dB*/
|
||||
{5, 4236} /*C/N=10.5dB*/
|
||||
};
|
||||
int i;
|
||||
u8 tmp[2];
|
||||
int status = read_regs(state, RSTV0910_P2_NNOSDATAT1 + state->regoff, tmp, 2);
|
||||
u16 RegValue = (tmp[0] << 8) | tmp[1];
|
||||
s32 vth = TableLookup(VTHLookupTable, ARRAY_SIZE(VTHLookupTable), RegValue);
|
||||
|
||||
for (i = 0; i < 6; i += 1)
|
||||
if (state->VTH[i] > vth)
|
||||
state->VTH[i] = vth;
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 0, state->VTH[0]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 1, state->VTH[1]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 2, state->VTH[2]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 3, state->VTH[3]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 4, state->VTH[4]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 5, state->VTH[5]);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
{
|
||||
s32 Freq;
|
||||
u8 regDMDCFGMD;
|
||||
u16 symb;
|
||||
|
||||
u32 ScramblingCode = 1;
|
||||
|
||||
if (p->symbol_rate < 100000 || p->symbol_rate > 70000000)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -828,6 +975,33 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
if (state->Started)
|
||||
write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5C);
|
||||
|
||||
init_search_param(state);
|
||||
|
||||
if (p->stream_id != NO_STREAM_ID_FILTER) {
|
||||
/* Backwards compatibility to "crazy" API.
|
||||
PRBS X root cannot be 0, so this should always work.
|
||||
*/
|
||||
if (p->stream_id & 0xffffff00)
|
||||
ScramblingCode = p->stream_id >> 8;
|
||||
write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff, p->stream_id & 0xff);
|
||||
write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0xff);
|
||||
//pr_info("ID=%08x\n", p->stream_id & 0xff);
|
||||
}
|
||||
|
||||
/* props->pls is always gold code ! */
|
||||
if (p->pls != NO_SCRAMBLING_CODE)
|
||||
ScramblingCode = p->pls | 0x40000;
|
||||
|
||||
if (ScramblingCode != state->CurScramblingCode) {
|
||||
write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff,
|
||||
ScramblingCode & 0xff);
|
||||
write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff,
|
||||
(ScramblingCode >> 8) & 0xff);
|
||||
write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff,
|
||||
(ScramblingCode >> 16) & 0x0f);
|
||||
state->CurScramblingCode = ScramblingCode;
|
||||
}
|
||||
|
||||
if (p->symbol_rate <= 1000000) { /*SR <=1Msps*/
|
||||
state->DemodTimeout = 3000;
|
||||
state->FecTimeout = 2000;
|
||||
@@ -836,7 +1010,7 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
state->FecTimeout = 1300;
|
||||
} else if (p->symbol_rate <= 5000000) { /*2Msps< SR <=5Msps*/
|
||||
state->DemodTimeout = 1000;
|
||||
state->FecTimeout = 650;
|
||||
state->FecTimeout = 650;
|
||||
} else if (p->symbol_rate <= 10000000) { /*5Msps< SR <=10Msps*/
|
||||
state->DemodTimeout = 700;
|
||||
state->FecTimeout = 350;
|
||||
@@ -863,25 +1037,43 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, ®DMDCFGMD);
|
||||
write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff,
|
||||
regDMDCFGMD |= 0xC0);
|
||||
|
||||
write_shared_reg(state, RSTV0910_TSTTSRS, state->nr ? 0x02 : 0x01, 0x00);
|
||||
|
||||
/* Disable DSS */
|
||||
write_reg(state, RSTV0910_P2_FECM + state->regoff, 0x00);
|
||||
write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2F);
|
||||
|
||||
EnablePunctureRate(state, FEC_NONE);
|
||||
|
||||
/* 8PSK 3/5, 8PSK 2/3 Poff tracking optimization WA*/
|
||||
write_reg(state, RSTV0910_P2_ACLC2S2Q + state->regoff, 0x0B);
|
||||
write_reg(state, RSTV0910_P2_ACLC2S28 + state->regoff, 0x0A);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S2Q + state->regoff, 0x84);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S28 + state->regoff, 0x84);
|
||||
write_reg(state, RSTV0910_P2_CARHDR + state->regoff, 0x1C);
|
||||
/* Reset demod */
|
||||
write_reg(state, RSTV0910_P2_CARFREQ + state->regoff, 0x79);
|
||||
|
||||
write_reg(state, RSTV0910_P2_ACLC2S216A + state->regoff, 0x29);
|
||||
write_reg(state, RSTV0910_P2_ACLC2S232A + state->regoff, 0x09);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S216A + state->regoff, 0x84);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S232A + state->regoff, 0x84);
|
||||
|
||||
/* Reset CAR3, bug DVBS2->DVBS1 lock*/
|
||||
/* Note: The bit is only pulsed -> no lock on shared register needed */
|
||||
write_reg(state, RSTV0910_TSTRES0, state->nr ? 0x04 : 0x08);
|
||||
write_reg(state, RSTV0910_TSTRES0, 0);
|
||||
|
||||
set_vth_default(state);
|
||||
|
||||
/* Reset demod */
|
||||
write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F);
|
||||
|
||||
write_reg(state, RSTV0910_P2_CARCFG + state->regoff, 0x46);
|
||||
|
||||
Freq = (state->SearchRange / 2000) + 600;
|
||||
if (p->symbol_rate <= 5000000)
|
||||
Freq -= (600 + 80);
|
||||
Freq = (state->SearchRange / 2000) + 80;
|
||||
else
|
||||
Freq = (state->SearchRange / 2000) + 1600;
|
||||
Freq = (Freq << 16) / (state->base->mclk / 1000);
|
||||
|
||||
write_reg(state, RSTV0910_P2_CFRUP1 + state->regoff,
|
||||
@@ -932,26 +1124,42 @@ static int probe(struct stv *state)
|
||||
|
||||
if (id != 0x51)
|
||||
return -EINVAL;
|
||||
pr_info("stv0910: found STV0910 id=0x%02x\n", id);
|
||||
/* pr_info("stv0910: found STV0910 id=0x%02x\n", id); */
|
||||
|
||||
/* Configure the I2C repeater to off */
|
||||
write_reg(state, RSTV0910_P1_I2CRPT, 0x24);
|
||||
/* Configure the I2C repeater to off */
|
||||
write_reg(state, RSTV0910_P2_I2CRPT, 0x24);
|
||||
/* Set the I2C to oversampling ratio */
|
||||
write_reg(state, RSTV0910_I2CCFG, 0x88);
|
||||
write_reg(state, RSTV0910_I2CCFG, 0x88); /* state->i2ccfg */
|
||||
|
||||
write_reg(state, RSTV0910_OUTCFG, 0x00); /* OUTCFG */
|
||||
write_reg(state, RSTV0910_PADCFG, 0x05); /* RF AGC Pads Dev = 05 */
|
||||
write_reg(state, RSTV0910_PADCFG, 0x05); /* RFAGC Pads Dev = 05 */
|
||||
write_reg(state, RSTV0910_SYNTCTRL, 0x02); /* SYNTCTRL */
|
||||
write_reg(state, RSTV0910_TSGENERAL, 0x00); /* TSGENERAL */
|
||||
write_reg(state, RSTV0910_TSGENERAL, state->tsgeneral); /* TSGENERAL */
|
||||
write_reg(state, RSTV0910_CFGEXT, 0x02); /* CFGEXT */
|
||||
write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */
|
||||
if (state->single)
|
||||
write_reg(state, RSTV0910_GENCFG, 0x14); /* GENCFG */
|
||||
else
|
||||
write_reg(state, RSTV0910_GENCFG, 0x15); /* GENCFG */
|
||||
|
||||
write_reg(state, RSTV0910_P1_TNRCFG2, 0x02); /* IQSWAP = 0 */
|
||||
write_reg(state, RSTV0910_P2_TNRCFG2, 0x82); /* IQSWAP = 1 */
|
||||
|
||||
write_reg(state, RSTV0910_P1_CAR3CFG, 0x02);
|
||||
write_reg(state, RSTV0910_P2_CAR3CFG, 0x02);
|
||||
write_reg(state, RSTV0910_P1_DMDCFG4, 0x04);
|
||||
write_reg(state, RSTV0910_P2_DMDCFG4, 0x04);
|
||||
|
||||
write_reg(state, RSTV0910_TSTRES0, 0x80); /* LDPC Reset */
|
||||
write_reg(state, RSTV0910_TSTRES0, 0x00);
|
||||
|
||||
write_reg(state, RSTV0910_P1_TSPIDFLT1, 0x00);
|
||||
write_reg(state, RSTV0910_P2_TSPIDFLT1, 0x00);
|
||||
|
||||
write_reg(state, RSTV0910_P1_TMGCFG2, 0x80);
|
||||
write_reg(state, RSTV0910_P2_TMGCFG2, 0x80);
|
||||
|
||||
set_mclock(state, 135000000);
|
||||
|
||||
/* TS output */
|
||||
@@ -1038,6 +1246,114 @@ static int set_parameters(struct dvb_frontend *fe)
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int get_frequency_offset(struct stv *state, s32 *off)
|
||||
{
|
||||
u8 cfr0, cfr1, cfr2;
|
||||
s32 derot;
|
||||
|
||||
read_reg(state, RSTV0910_P2_CFR2 + state->regoff, &cfr2);
|
||||
read_reg(state, RSTV0910_P2_CFR1 + state->regoff, &cfr1);
|
||||
read_reg(state, RSTV0910_P2_CFR0 + state->regoff, &cfr0);
|
||||
|
||||
derot = ((u32) cfr2 << 16) | ((u32)cfr1 << 8) | cfr0;
|
||||
if (derot & (1<<23))
|
||||
derot |= 0xFF000000;
|
||||
*off = (s32) (((s64) derot * (s64) state->base->mclk) >> 24);
|
||||
//pr_info("foff = %d\n", *off);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int get_frontend(struct dvb_frontend *fe)
|
||||
{
|
||||
struct stv *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u8 tmp;
|
||||
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
u32 mc;
|
||||
enum fe_modulation modcod2mod[0x20] = {
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
QPSK, QPSK, QPSK, QPSK,
|
||||
PSK_8, PSK_8, PSK_8, PSK_8,
|
||||
PSK_8, PSK_8, APSK_16, APSK_16,
|
||||
APSK_16, APSK_16, APSK_16, APSK_16,
|
||||
APSK_32, APSK_32, APSK_32, APSK_32,
|
||||
APSK_32,
|
||||
};
|
||||
enum fe_code_rate modcod2fec[0x20] = {
|
||||
FEC_NONE, FEC_1_4, FEC_1_3, FEC_2_5,
|
||||
FEC_1_2, FEC_3_5, FEC_2_3, FEC_3_4,
|
||||
FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10,
|
||||
FEC_3_5, FEC_2_3, FEC_3_4, FEC_5_6,
|
||||
FEC_8_9, FEC_9_10, FEC_2_3, FEC_3_4,
|
||||
FEC_4_5, FEC_5_6, FEC_8_9, FEC_9_10,
|
||||
FEC_3_4, FEC_4_5, FEC_5_6, FEC_8_9,
|
||||
FEC_9_10
|
||||
};
|
||||
read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp);
|
||||
mc = ((tmp & 0x7c) >> 2);
|
||||
p->pilot = (tmp & 0x01) ? PILOT_ON : PILOT_OFF;
|
||||
p->modulation = modcod2mod[mc];
|
||||
p->fec_inner = modcod2fec[mc];
|
||||
} else if (state->ReceiveMode == Mode_DVBS) {
|
||||
read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp);
|
||||
switch( tmp & 0x1F ) {
|
||||
case 0x0d:
|
||||
p->fec_inner = FEC_1_2;
|
||||
break;
|
||||
case 0x12:
|
||||
p->fec_inner = FEC_2_3;
|
||||
break;
|
||||
case 0x15:
|
||||
p->fec_inner = FEC_3_4;
|
||||
break;
|
||||
case 0x18:
|
||||
p->fec_inner = FEC_5_6;
|
||||
break;
|
||||
case 0x1a:
|
||||
p->fec_inner = FEC_7_8;
|
||||
break;
|
||||
default:
|
||||
p->fec_inner = FEC_NONE;
|
||||
break;
|
||||
}
|
||||
p->rolloff = ROLLOFF_35;
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ManageMatypeInfo(struct stv *state)
|
||||
{
|
||||
if (!state->Started)
|
||||
return -1;
|
||||
if (state->ReceiveMode == Mode_DVBS2 ) {
|
||||
u8 BBHeader[2];
|
||||
|
||||
read_regs(state, RSTV0910_P2_MATSTR1 + state->regoff,
|
||||
BBHeader, 2);
|
||||
state->FERollOff =
|
||||
(enum FE_STV0910_RollOff) (BBHeader[0] & 0x03);
|
||||
state->isVCM = (BBHeader[0] & 0x10) == 0;
|
||||
state->isStandardBroadcast = (BBHeader[0] & 0xFC) == 0xF0;
|
||||
} else if (state->ReceiveMode == Mode_DVBS) {
|
||||
state->isVCM = 0;
|
||||
state->isStandardBroadcast = 1;
|
||||
state->FERollOff = FE_SAT_35;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int read_snr(struct dvb_frontend *fe, u16 *snr);
|
||||
static int read_signal_strength(struct dvb_frontend *fe, u16 *strength);
|
||||
static int read_ber(struct dvb_frontend *fe, u32 *ber);
|
||||
|
||||
static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
{
|
||||
@@ -1046,26 +1362,55 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
u8 DStatus = 0;
|
||||
enum ReceiveMode CurReceiveMode = Mode_None;
|
||||
u32 FECLock = 0;
|
||||
u16 val;
|
||||
u32 ber;
|
||||
s32 foff;
|
||||
|
||||
*status = 0;
|
||||
get_frequency_offset(state, &foff);
|
||||
|
||||
read_signal_strength(fe, &val);
|
||||
|
||||
read_snr(fe, &val);
|
||||
|
||||
read_ber(fe, &ber);
|
||||
|
||||
read_reg(state, RSTV0910_P2_DMDSTATE + state->regoff, &DmdState);
|
||||
|
||||
if (DmdState & 0x40) {
|
||||
read_reg(state, RSTV0910_P2_DSTATUS + state->regoff, &DStatus);
|
||||
read_reg(state, RSTV0910_P2_DSTATUS + state->regoff,
|
||||
&DStatus);
|
||||
if (DStatus & 0x08)
|
||||
CurReceiveMode = (DmdState & 0x20) ?
|
||||
Mode_DVBS : Mode_DVBS2;
|
||||
}
|
||||
if (CurReceiveMode == Mode_None) {
|
||||
*status = 0;
|
||||
set_vth(state);
|
||||
//if( Time >= m_DemodTimeout ) *pLockStatus = NEVER_LOCK;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*status |= 0x0f;
|
||||
if (state->ReceiveMode == Mode_None) {
|
||||
state->ReceiveMode = CurReceiveMode;
|
||||
state->DemodLockTime = jiffies;
|
||||
state->FirstTimeLock = 0;
|
||||
state->FirstTimeLock = 1;
|
||||
|
||||
GetSignalParameters(state);
|
||||
TrackingOptimization(state);
|
||||
|
||||
#if 0
|
||||
if( CurReceiveMode == Mode_DVBS2 && m_bPilots
|
||||
&& ( m_ModCod == FE_8PSK_23 || m_ModCod == FE_8PSK_35) )
|
||||
{
|
||||
LONG C_N;
|
||||
CHK_ERROR(GetSignalToNoise(&C_N));
|
||||
if( C_N < 80 )
|
||||
{
|
||||
CHK_ERROR(WriteReg(RSTV0910_P2_CARHDR + m_DemodOffset , 0x04));
|
||||
CHK_ERROR(WriteReg(RSTV0910_P2_BCLC2S28 + m_DemodOffset , 0x31));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
write_reg(state, RSTV0910_P2_TSCFGH + state->regoff,
|
||||
state->tscfgh);
|
||||
usleep_range(3000, 4000);
|
||||
@@ -1091,6 +1436,7 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
}
|
||||
|
||||
if (!FECLock)
|
||||
//if( Time >= m_DemodLockTime + m_FecTimeout ) *pLockStatus = NEVER_LOCK;
|
||||
return 0;
|
||||
|
||||
*status |= 0x10;
|
||||
@@ -1099,10 +1445,23 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
u8 tmp;
|
||||
|
||||
state->FirstTimeLock = 0;
|
||||
GetSignalParameters(state);
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
/* FSTV0910_P2_MANUALSX_ROLLOFF,
|
||||
ManageMatypeInfo(state);
|
||||
|
||||
#if 0
|
||||
ULONG Bitrate;
|
||||
CSTV0910::GetBitrate(&Bitrate);
|
||||
BYTE newTSSPEED = (Bitrate > 67000000) ? 0x30 : 0x40;
|
||||
if (newTSSPEED != m_TSSPEED)
|
||||
{
|
||||
KdPrintEx((MSG_INFO "_%d " __FUNCTION__ " TSSPEED = %02X\n", m_Instance, newTSSPEED));
|
||||
CHK_ERROR(WriteReg(RSTV0910_P2_TSSPEED + m_DemodOffset, newTSSPEED));
|
||||
m_TSSPEED = newTSSPEED;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
/* FSTV0910_P2_MANUALSX_ROLLOFF,
|
||||
FSTV0910_P2_MANUALS2_ROLLOFF = 0 */
|
||||
state->DEMOD &= ~0x84;
|
||||
write_reg(state, RSTV0910_P2_DEMOD + state->regoff,
|
||||
@@ -1111,11 +1470,13 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
&tmp);
|
||||
/*reset DVBS2 packet delinator error counter */
|
||||
tmp |= 0x40;
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff,
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 +
|
||||
state->regoff,
|
||||
tmp);
|
||||
/*reset DVBS2 packet delinator error counter */
|
||||
tmp &= ~0x40;
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff,
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 +
|
||||
state->regoff,
|
||||
tmp);
|
||||
|
||||
state->BERScale = 2;
|
||||
@@ -1138,8 +1499,25 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
infinit error count mode )*/
|
||||
write_reg(state, RSTV0910_P2_ERRCTRL2 + state->regoff, 0xc1);
|
||||
|
||||
TrackingOptimization(state);
|
||||
set_vth_default(state);
|
||||
if (state->ReceiveMode == Mode_DVBS)
|
||||
EnablePunctureRate(state, state->PunctureRate);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if( m_isVCM )
|
||||
{
|
||||
// Use highest signaled ModCod for quality
|
||||
BYTE tmp;
|
||||
CHK_ERROR(ReadReg(RSTV0910_P2_DMDMODCOD +
|
||||
m_DemodOffset,&tmp));
|
||||
FE_STV0910_ModCod ModCod =
|
||||
FE_STV0910_ModCod((tmp & 0x7c) >> 2);
|
||||
|
||||
if( ModCod > m_ModCod )
|
||||
m_ModCod = ModCod;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1156,13 +1534,13 @@ static int tune(struct dvb_frontend *fe, bool re_tune,
|
||||
return r;
|
||||
state->tune_time = jiffies;
|
||||
}
|
||||
if (*status & FE_HAS_LOCK)
|
||||
return 0;
|
||||
*delay = HZ;
|
||||
|
||||
r = read_status(fe, status);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
if (*status & FE_HAS_LOCK)
|
||||
return 0;
|
||||
*delay = HZ / 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1258,21 +1636,28 @@ static int sleep(struct dvb_frontend *fe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
{
|
||||
struct stv *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
s32 SNR;
|
||||
|
||||
*snr = 0;
|
||||
if (GetSignalToNoise(state, &SNR))
|
||||
return -EIO;
|
||||
*snr = SNR;
|
||||
p->cnr.len = 1;
|
||||
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->cnr.stat[0].uvalue = 100 * (s64) SNR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
struct stv *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 n, d;
|
||||
|
||||
GetBitErrorRate(state, &n, &d);
|
||||
@@ -1280,18 +1665,98 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
*ber = n / d;
|
||||
else
|
||||
*ber = 0;
|
||||
|
||||
p->pre_bit_error.len = 1;
|
||||
p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_error.stat[0].uvalue = n;
|
||||
p->pre_bit_count.len = 1;
|
||||
p->pre_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_count.stat[0].uvalue = d;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 Log10x100(u32 x)
|
||||
{
|
||||
static u32 LookupTable[100] = {
|
||||
101157945, 103514217, 105925373, 108392691, 110917482,
|
||||
113501082, 116144861, 118850223, 121618600, 124451461,
|
||||
127350308, 130316678, 133352143, 136458314, 139636836,
|
||||
142889396, 146217717, 149623566, 153108746, 156675107,
|
||||
160324539, 164058977, 167880402, 171790839, 175792361,
|
||||
179887092, 184077200, 188364909, 192752491, 197242274,
|
||||
201836636, 206538016, 211348904, 216271852, 221309471,
|
||||
226464431, 231739465, 237137371, 242661010, 248313311,
|
||||
254097271, 260015956, 266072506, 272270131, 278612117,
|
||||
285101827, 291742701, 298538262, 305492111, 312607937,
|
||||
319889511, 327340695, 334965439, 342767787, 350751874,
|
||||
358921935, 367282300, 375837404, 384591782, 393550075,
|
||||
402717034, 412097519, 421696503, 431519077, 441570447,
|
||||
451855944, 462381021, 473151259, 484172368, 495450191,
|
||||
506990708, 518800039, 530884444, 543250331, 555904257,
|
||||
568852931, 582103218, 595662144, 609536897, 623734835,
|
||||
638263486, 653130553, 668343918, 683911647, 699841996,
|
||||
716143410, 732824533, 749894209, 767361489, 785235635,
|
||||
803526122, 822242650, 841395142, 860993752, 881048873,
|
||||
901571138, 922571427, 944060876, 966050879, 988553095,
|
||||
};
|
||||
s32 y;
|
||||
int i;
|
||||
|
||||
if (x == 0)
|
||||
return 0;
|
||||
y = 800;
|
||||
if (x >= 1000000000) {
|
||||
x /= 10;
|
||||
y += 100;
|
||||
}
|
||||
|
||||
while (x < 100000000) {
|
||||
x *= 10;
|
||||
y -= 100;
|
||||
}
|
||||
i = 0;
|
||||
while (i < 100 && x > LookupTable[i])
|
||||
i += 1;
|
||||
y += i;
|
||||
return y;
|
||||
}
|
||||
|
||||
static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
{
|
||||
struct stv *state = fe->demodulator_priv;
|
||||
u8 Agc1, Agc0;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u8 Reg[2];
|
||||
s32 bbgain;
|
||||
s32 Power = 0;
|
||||
int i;
|
||||
|
||||
read_reg(state, RSTV0910_P2_AGCIQIN1 + state->regoff, &Agc1);
|
||||
read_reg(state, RSTV0910_P2_AGCIQIN0 + state->regoff, &Agc0);
|
||||
read_regs(state, RSTV0910_P2_AGCIQIN1 + state->regoff, Reg, 2);
|
||||
*strength = (((u32) Reg[0]) << 8) | Reg[1];
|
||||
|
||||
for (i = 0; i < 5; i += 1) {
|
||||
read_regs(state, RSTV0910_P2_POWERI + state->regoff, Reg, 2);
|
||||
Power += (u32) Reg[0] * (u32) Reg[0] +
|
||||
(u32) Reg[1] * (u32) Reg[1];
|
||||
msleep(3);
|
||||
}
|
||||
Power /= 5;
|
||||
bbgain = (465 - Log10x100(Power)) * 10;
|
||||
|
||||
if (fe->ops.tuner_ops.get_rf_strength)
|
||||
fe->ops.tuner_ops.get_rf_strength(fe, strength);
|
||||
else
|
||||
*strength = 0;
|
||||
|
||||
*strength = ((255 - Agc1) * 3300) / 256;
|
||||
if (bbgain < (s32) *strength)
|
||||
*strength -= bbgain;
|
||||
else
|
||||
*strength = 0;
|
||||
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].uvalue = 10 * (s64) (s16) *strength - 108750;
|
||||
|
||||
/* *strength is in hundredth dBuv, uvalue is in thousandth dBm */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1316,13 +1781,15 @@ static struct dvb_frontend_ops stv0910_ops = {
|
||||
.caps = FE_CAN_INVERSION_AUTO |
|
||||
FE_CAN_FEC_AUTO |
|
||||
FE_CAN_QPSK |
|
||||
FE_CAN_2G_MODULATION
|
||||
FE_CAN_2G_MODULATION |
|
||||
FE_CAN_MULTISTREAM,
|
||||
},
|
||||
.init = init,
|
||||
.sleep = sleep,
|
||||
.release = release,
|
||||
.i2c_gate_ctrl = gate_ctrl,
|
||||
.get_frontend_algo = get_algo,
|
||||
.get_frontend = get_frontend,
|
||||
.tune = tune,
|
||||
.read_status = read_status,
|
||||
.set_tone = set_tone,
|
||||
@@ -1359,14 +1826,17 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c,
|
||||
return NULL;
|
||||
|
||||
state->tscfgh = 0x20 | (cfg->parallel ? 0 : 0x40);
|
||||
state->tsgeneral = (cfg->parallel == 2) ? 0x02 : 0x00;
|
||||
state->i2crpt = 0x0A | ((cfg->rptlvl & 0x07) << 4);
|
||||
state->tsspeed = 0x40;
|
||||
state->tsspeed = 0x28;
|
||||
state->nr = nr;
|
||||
state->regoff = state->nr ? 0 : 0x200;
|
||||
state->SearchRange = 16000000;
|
||||
state->DEMOD = 0x10; /* Inversion : Auto with reset to 0 */
|
||||
state->ReceiveMode = Mode_None;
|
||||
|
||||
state->CurScramblingCode = NO_SCRAMBLING_CODE;
|
||||
state->single = cfg->single ? 1 : 0;
|
||||
|
||||
base = match_base(i2c, cfg->adr);
|
||||
if (base) {
|
||||
base->count++;
|
||||
@@ -1402,5 +1872,5 @@ fail:
|
||||
EXPORT_SYMBOL_GPL(stv0910_attach);
|
||||
|
||||
MODULE_DESCRIPTION("STV0910 driver");
|
||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||
MODULE_AUTHOR("Ralph und Marcus Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@@ -9,6 +9,7 @@ struct stv0910_cfg {
|
||||
u8 adr;
|
||||
u8 parallel;
|
||||
u8 rptlvl;
|
||||
u8 single;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_STV0910) || \
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -50,6 +50,7 @@ struct stv {
|
||||
|
||||
u8 reg[11];
|
||||
u32 ref_freq;
|
||||
u32 Frequency;
|
||||
};
|
||||
|
||||
static int i2c_read(struct i2c_adapter *adap,
|
||||
@@ -87,14 +88,12 @@ static int write_regs(struct stv *state, int reg, int len)
|
||||
return i2c_write(state->i2c, state->adr, d, len + 1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int write_reg(struct stv *state, u8 reg, u8 val)
|
||||
{
|
||||
u8 d[2] = {reg, val};
|
||||
|
||||
return i2c_write(state->i2c, state->adr, d, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int read_reg(struct stv *state, u8 reg, u8 *val)
|
||||
{
|
||||
@@ -106,20 +105,20 @@ static int read_regs(struct stv *state, u8 reg, u8 *val, int len)
|
||||
return i2c_read(state->i2c, state->adr, ®, 1, val, len);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void dump_regs(struct stv *state)
|
||||
{
|
||||
u8 d[11], *c = &state->reg[0];
|
||||
|
||||
read_regs(state, 0, d, 11);
|
||||
#if 0
|
||||
pr_info("stv6111_regs = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7],
|
||||
d[8], d[9], d[10]);
|
||||
pr_info("reg[] = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7],
|
||||
c[8], c[9], c[10]);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static int wait_for_call_done(struct stv *state, u8 mask)
|
||||
{
|
||||
@@ -185,7 +184,9 @@ static int attach_init(struct stv *state)
|
||||
{
|
||||
if (write_regs(state, 0, 11))
|
||||
return -1;
|
||||
#if 0
|
||||
dump_regs(state);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -298,7 +299,11 @@ static int set_lof(struct stv *state, u32 LocalFrequency, u32 CutOffFrequency)
|
||||
}
|
||||
read_reg(state, 0x08, &tmp);
|
||||
|
||||
state->Frequency = Frequency;
|
||||
|
||||
#if 0
|
||||
dump_regs(state);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -306,7 +311,6 @@ static int set_params(struct dvb_frontend *fe)
|
||||
{
|
||||
struct stv *state = fe->tuner_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
int status;
|
||||
u32 freq, symb, cutoff;
|
||||
|
||||
if (p->delivery_system != SYS_DVBS && p->delivery_system != SYS_DVBS2)
|
||||
@@ -321,7 +325,7 @@ static int set_params(struct dvb_frontend *fe)
|
||||
set_lof(state, freq, cutoff);
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
return status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
@@ -330,54 +334,351 @@ static int get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 AGC_Gain[] = {
|
||||
000, /* 0.0 */
|
||||
000, /* 0.1 */
|
||||
1000, /* 0.2 */
|
||||
2000, /* 0.3 */
|
||||
3000, /* 0.4 */
|
||||
4000, /* 0.5 */
|
||||
5000, /* 0.6 */
|
||||
6000, /* 0.7 */
|
||||
7000, /* 0.8 */
|
||||
14000, /* 0.9 */
|
||||
20000, /* 1.0 */
|
||||
27000, /* 1.1 */
|
||||
32000, /* 1.2 */
|
||||
37000, /* 1.3 */
|
||||
42000, /* 1.4 */
|
||||
47000, /* 1.5 */
|
||||
50000, /* 1.6 */
|
||||
53000, /* 1.7 */
|
||||
56000, /* 1.8 */
|
||||
58000, /* 1.9 */
|
||||
60000, /* 2.0 */
|
||||
62000, /* 2.1 */
|
||||
63000, /* 2.2 */
|
||||
64000, /* 2.3 */
|
||||
64500, /* 2.4 */
|
||||
65000, /* 2.5 */
|
||||
65500, /* 2.6 */
|
||||
66000, /* 2.7 */
|
||||
66500, /* 2.8 */
|
||||
67000, /* 2.9 */
|
||||
struct SLookup {
|
||||
s16 Value;
|
||||
u16 RegValue;
|
||||
};
|
||||
|
||||
|
||||
static struct SLookup LNAGain_NF_LookUp[] = {
|
||||
/*Gain *100dB*/ /*Reg*/
|
||||
{ 2572 , 0 },
|
||||
{ 2575 , 1 },
|
||||
{ 2580 , 2 },
|
||||
{ 2588 , 3 },
|
||||
{ 2596 , 4 },
|
||||
{ 2611 , 5 },
|
||||
{ 2633 , 6 },
|
||||
{ 2664 , 7 },
|
||||
{ 2701 , 8 },
|
||||
{ 2753 , 9 },
|
||||
{ 2816 , 10 },
|
||||
{ 2902 , 11 },
|
||||
{ 2995 , 12 },
|
||||
{ 3104 , 13 },
|
||||
{ 3215 , 14 },
|
||||
{ 3337 , 15 },
|
||||
{ 3492 , 16 },
|
||||
{ 3614 , 17 },
|
||||
{ 3731 , 18 },
|
||||
{ 3861 , 19 },
|
||||
{ 3988 , 20 },
|
||||
{ 4124 , 21 },
|
||||
{ 4253 , 22 },
|
||||
{ 4386 , 23 },
|
||||
{ 4505 , 24 },
|
||||
{ 4623 , 25 },
|
||||
{ 4726 , 26 },
|
||||
{ 4821 , 27 },
|
||||
{ 4903 , 28 },
|
||||
{ 4979 , 29 },
|
||||
{ 5045 , 30 },
|
||||
{ 5102 , 31 }
|
||||
};
|
||||
|
||||
static struct SLookup LNAGain_IIP3_LookUp[] = {
|
||||
/*Gain *100dB*/ /*reg*/
|
||||
{ 1548 , 0 },
|
||||
{ 1552 , 1 },
|
||||
{ 1569 , 2 },
|
||||
{ 1565 , 3 },
|
||||
{ 1577 , 4 },
|
||||
{ 1594 , 5 },
|
||||
{ 1627 , 6 },
|
||||
{ 1656 , 7 },
|
||||
{ 1700 , 8 },
|
||||
{ 1748 , 9 },
|
||||
{ 1805 , 10 },
|
||||
{ 1896 , 11 },
|
||||
{ 1995 , 12 },
|
||||
{ 2113 , 13 },
|
||||
{ 2233 , 14 },
|
||||
{ 2366 , 15 },
|
||||
{ 2543 , 16 },
|
||||
{ 2687 , 17 },
|
||||
{ 2842 , 18 },
|
||||
{ 2999 , 19 },
|
||||
{ 3167 , 20 },
|
||||
{ 3342 , 21 },
|
||||
{ 3507 , 22 },
|
||||
{ 3679 , 23 },
|
||||
{ 3827 , 24 },
|
||||
{ 3970 , 25 },
|
||||
{ 4094 , 26 },
|
||||
{ 4210 , 27 },
|
||||
{ 4308 , 28 },
|
||||
{ 4396 , 29 },
|
||||
{ 4468 , 30 },
|
||||
{ 4535 , 31 }
|
||||
};
|
||||
|
||||
static struct SLookup Gain_RFAGC_LookUp[] = {
|
||||
/*Gain *100dB*/ /*reg*/
|
||||
{ 4870 , 0x3000 },
|
||||
{ 4850 , 0x3C00 },
|
||||
{ 4800 , 0x4500 },
|
||||
{ 4750 , 0x4800 },
|
||||
{ 4700 , 0x4B00 },
|
||||
{ 4650 , 0x4D00 },
|
||||
{ 4600 , 0x4F00 },
|
||||
{ 4550 , 0x5100 },
|
||||
{ 4500 , 0x5200 },
|
||||
{ 4420 , 0x5500 },
|
||||
{ 4316 , 0x5800 },
|
||||
{ 4200 , 0x5B00 },
|
||||
{ 4119 , 0x5D00 },
|
||||
{ 3999 , 0x6000 },
|
||||
{ 3950 , 0x6100 },
|
||||
{ 3876 , 0x6300 },
|
||||
{ 3755 , 0x6600 },
|
||||
{ 3641 , 0x6900 },
|
||||
{ 3567 , 0x6B00 },
|
||||
{ 3425 , 0x6F00 },
|
||||
{ 3350 , 0x7100 },
|
||||
{ 3236 , 0x7400 },
|
||||
{ 3118 , 0x7700 },
|
||||
{ 3004 , 0x7A00 },
|
||||
{ 2917 , 0x7C00 },
|
||||
{ 2776 , 0x7F00 },
|
||||
{ 2635 , 0x8200 },
|
||||
{ 2516 , 0x8500 },
|
||||
{ 2406 , 0x8800 },
|
||||
{ 2290 , 0x8B00 },
|
||||
{ 2170 , 0x8E00 },
|
||||
{ 2073 , 0x9100 },
|
||||
{ 1949 , 0x9400 },
|
||||
{ 1836 , 0x9700 },
|
||||
{ 1712 , 0x9A00 },
|
||||
{ 1631 , 0x9C00 },
|
||||
{ 1515 , 0x9F00 },
|
||||
{ 1400 , 0xA200 },
|
||||
{ 1323 , 0xA400 },
|
||||
{ 1203 , 0xA700 },
|
||||
{ 1091 , 0xAA00 },
|
||||
{ 1011 , 0xAC00 },
|
||||
{ 904 , 0xAF00 },
|
||||
{ 787 , 0xB200 },
|
||||
{ 685 , 0xB500 },
|
||||
{ 571 , 0xB800 },
|
||||
{ 464 , 0xBB00 },
|
||||
{ 374 , 0xBE00 },
|
||||
{ 275 , 0xC200 },
|
||||
{ 181 , 0xC600 },
|
||||
{ 102 , 0xCC00 },
|
||||
{ 49 , 0xD900 }
|
||||
};
|
||||
|
||||
|
||||
// This table is 6 dB too low comapred to the others (probably created with a different BB_MAG setting)
|
||||
static struct SLookup Gain_Channel_AGC_NF_LookUp[] = {
|
||||
/*Gain *100dB*/ /*reg*/
|
||||
{ 7082 , 0x3000 },
|
||||
{ 7052 , 0x4000 },
|
||||
{ 7007 , 0x4600 },
|
||||
{ 6954 , 0x4A00 },
|
||||
{ 6909 , 0x4D00 },
|
||||
{ 6833 , 0x5100 },
|
||||
{ 6753 , 0x5400 },
|
||||
{ 6659 , 0x5700 },
|
||||
{ 6561 , 0x5A00 },
|
||||
{ 6472 , 0x5C00 },
|
||||
{ 6366 , 0x5F00 },
|
||||
{ 6259 , 0x6100 },
|
||||
{ 6151 , 0x6400 },
|
||||
{ 6026 , 0x6700 },
|
||||
{ 5920 , 0x6900 },
|
||||
{ 5835 , 0x6B00 },
|
||||
{ 5770 , 0x6C00 },
|
||||
{ 5681 , 0x6E00 },
|
||||
{ 5596 , 0x7000 },
|
||||
{ 5503 , 0x7200 },
|
||||
{ 5429 , 0x7300 },
|
||||
{ 5319 , 0x7500 },
|
||||
{ 5220 , 0x7700 },
|
||||
{ 5111 , 0x7900 },
|
||||
{ 4983 , 0x7B00 },
|
||||
{ 4876 , 0x7D00 },
|
||||
{ 4755 , 0x7F00 },
|
||||
{ 4635 , 0x8100 },
|
||||
{ 4499 , 0x8300 },
|
||||
{ 4405 , 0x8500 },
|
||||
{ 4323 , 0x8600 },
|
||||
{ 4233 , 0x8800 },
|
||||
{ 4156 , 0x8A00 },
|
||||
{ 4038 , 0x8C00 },
|
||||
{ 3935 , 0x8E00 },
|
||||
{ 3823 , 0x9000 },
|
||||
{ 3712 , 0x9200 },
|
||||
{ 3601 , 0x9500 },
|
||||
{ 3511 , 0x9700 },
|
||||
{ 3413 , 0x9900 },
|
||||
{ 3309 , 0x9B00 },
|
||||
{ 3213 , 0x9D00 },
|
||||
{ 3088 , 0x9F00 },
|
||||
{ 2992 , 0xA100 },
|
||||
{ 2878 , 0xA400 },
|
||||
{ 2769 , 0xA700 },
|
||||
{ 2645 , 0xAA00 },
|
||||
{ 2538 , 0xAD00 },
|
||||
{ 2441 , 0xB000 },
|
||||
{ 2350 , 0xB600 },
|
||||
{ 2237 , 0xBA00 },
|
||||
{ 2137 , 0xBF00 },
|
||||
{ 2039 , 0xC500 },
|
||||
{ 1938 , 0xDF00 },
|
||||
{ 1927 , 0xFF00 }
|
||||
};
|
||||
|
||||
|
||||
static struct SLookup Gain_Channel_AGC_IIP3_LookUp[] = {
|
||||
/*Gain *100dB*/ /*reg*/
|
||||
{ 7070 , 0x3000 },
|
||||
{ 7028 , 0x4000 },
|
||||
{ 7019 , 0x4600 },
|
||||
{ 6900 , 0x4A00 },
|
||||
{ 6811 , 0x4D00 },
|
||||
{ 6763 , 0x5100 },
|
||||
{ 6690 , 0x5400 },
|
||||
{ 6644 , 0x5700 },
|
||||
{ 6617 , 0x5A00 },
|
||||
{ 6598 , 0x5C00 },
|
||||
{ 6462 , 0x5F00 },
|
||||
{ 6348 , 0x6100 },
|
||||
{ 6197 , 0x6400 },
|
||||
{ 6154 , 0x6700 },
|
||||
{ 6098 , 0x6900 },
|
||||
{ 5893 , 0x6B00 },
|
||||
{ 5812 , 0x6C00 },
|
||||
{ 5773 , 0x6E00 },
|
||||
{ 5723 , 0x7000 },
|
||||
{ 5661 , 0x7200 },
|
||||
{ 5579 , 0x7300 },
|
||||
{ 5460 , 0x7500 },
|
||||
{ 5308 , 0x7700 },
|
||||
{ 5099 , 0x7900 },
|
||||
{ 4910 , 0x7B00 },
|
||||
{ 4800 , 0x7D00 },
|
||||
{ 4785 , 0x7F00 },
|
||||
{ 4635 , 0x8100 },
|
||||
{ 4466 , 0x8300 },
|
||||
{ 4314 , 0x8500 },
|
||||
{ 4295 , 0x8600 },
|
||||
{ 4144 , 0x8800 },
|
||||
{ 3920 , 0x8A00 },
|
||||
{ 3889 , 0x8C00 },
|
||||
{ 3771 , 0x8E00 },
|
||||
{ 3655 , 0x9000 },
|
||||
{ 3446 , 0x9200 },
|
||||
{ 3298 , 0x9500 },
|
||||
{ 3083 , 0x9700 },
|
||||
{ 3015 , 0x9900 },
|
||||
{ 2833 , 0x9B00 },
|
||||
{ 2746 , 0x9D00 },
|
||||
{ 2632 , 0x9F00 },
|
||||
{ 2598 , 0xA100 },
|
||||
{ 2480 , 0xA400 },
|
||||
{ 2236 , 0xA700 },
|
||||
{ 2171 , 0xAA00 },
|
||||
{ 2060 , 0xAD00 },
|
||||
{ 1999 , 0xB000 },
|
||||
{ 1974 , 0xB600 },
|
||||
{ 1820 , 0xBA00 },
|
||||
{ 1741 , 0xBF00 },
|
||||
{ 1655 , 0xC500 },
|
||||
{ 1444 , 0xDF00 },
|
||||
{ 1325 , 0xFF00 },
|
||||
};
|
||||
|
||||
|
||||
static s32 TableLookup(struct SLookup *Table, int TableSize, u16 RegValue)
|
||||
{
|
||||
s32 Gain;
|
||||
s32 RegDiff;
|
||||
int imin = 0;
|
||||
int imax = TableSize - 1;
|
||||
int i;
|
||||
|
||||
// Assumes Table[0].RegValue < Table[imax].RegValue
|
||||
if( RegValue <= Table[0].RegValue )
|
||||
Gain = Table[0].Value;
|
||||
else if( RegValue >= Table[imax].RegValue )
|
||||
Gain = Table[imax].Value;
|
||||
else {
|
||||
while(imax-imin > 1) {
|
||||
i = (imax + imin) / 2;
|
||||
if ((Table[imin].RegValue <= RegValue) &&
|
||||
(RegValue <= Table[i].RegValue) )
|
||||
imax = i;
|
||||
else
|
||||
imin = i;
|
||||
}
|
||||
RegDiff = Table[imax].RegValue - Table[imin].RegValue;
|
||||
Gain = Table[imin].Value;
|
||||
if (RegDiff != 0)
|
||||
Gain += ((s32) (RegValue - Table[imin].RegValue) *
|
||||
(s32)(Table[imax].Value - Table[imin].Value))/(RegDiff);
|
||||
}
|
||||
return Gain;
|
||||
}
|
||||
|
||||
static int get_rf_strength(struct dvb_frontend *fe, u16 *st)
|
||||
{
|
||||
*st = 0;
|
||||
#if 0
|
||||
struct stv *state = fe->tuner_priv;
|
||||
u16 RFAgc = *st;
|
||||
s32 Gain;
|
||||
u32 Index = RFAgc / 100;
|
||||
if (Index >= (sizeof(AGC_Gain) / sizeof(AGC_Gain[0]) - 1))
|
||||
Gain = AGC_Gain[sizeof(AGC_Gain) / sizeof(AGC_Gain[0]) - 1];
|
||||
else
|
||||
Gain = AGC_Gain[Index] +
|
||||
((AGC_Gain[Index+1] - AGC_Gain[Index]) *
|
||||
(RFAgc % 100)) / 100;
|
||||
*st = Gain;
|
||||
#endif
|
||||
|
||||
if ((state->reg[0x03] & 0x60) == 0 ) {
|
||||
// RF Mode
|
||||
// Read AGC ADC
|
||||
u8 Reg = 0;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
write_reg(state, 0x02, state->reg[0x02] | 0x20);
|
||||
read_reg(state, 2, &Reg);
|
||||
if( Reg & 0x20 )
|
||||
read_reg(state, 2, &Reg);
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 0);
|
||||
|
||||
if((state->reg[0x02] & 0x80) == 0)
|
||||
// NF
|
||||
Gain = TableLookup(LNAGain_NF_LookUp,
|
||||
ARRAY_SIZE(LNAGain_NF_LookUp), Reg & 0x1F);
|
||||
else
|
||||
// IIP3
|
||||
Gain = TableLookup(LNAGain_IIP3_LookUp,
|
||||
ARRAY_SIZE(LNAGain_IIP3_LookUp), Reg & 0x1F);
|
||||
Gain += TableLookup(Gain_RFAGC_LookUp,
|
||||
ARRAY_SIZE(Gain_RFAGC_LookUp), RFAgc);
|
||||
Gain -= 2400;
|
||||
} else {
|
||||
// Channel Mode
|
||||
if( (state->reg[0x02] & 0x80) == 0 ) {
|
||||
// NF
|
||||
Gain = TableLookup(Gain_Channel_AGC_NF_LookUp,
|
||||
ARRAY_SIZE(Gain_Channel_AGC_NF_LookUp), RFAgc);
|
||||
Gain += 600;
|
||||
} else {
|
||||
// IIP3
|
||||
Gain = TableLookup(Gain_Channel_AGC_IIP3_LookUp,
|
||||
ARRAY_SIZE(Gain_Channel_AGC_IIP3_LookUp), RFAgc);
|
||||
}
|
||||
}
|
||||
|
||||
if (state->Frequency > 0)
|
||||
// Tilt correction ( 0.00016 dB/MHz )
|
||||
Gain -= ((((s32)(state->Frequency / 1000) - 1550) * 2) / 12);
|
||||
|
||||
Gain += (s32)( (state->reg[0x01] & 0xC0 ) >> 6 ) * 600 - 1300;// + (BBGain * 10);
|
||||
|
||||
if( Gain < 0 )
|
||||
Gain = 0;
|
||||
else if (Gain > 10000)
|
||||
Gain = 10000;
|
||||
|
||||
*st = 10000 - Gain;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -447,8 +447,8 @@ static int attach_init(struct tda_state *state)
|
||||
if (!state->m_isMaster)
|
||||
state->m_bLTEnable = false;
|
||||
|
||||
pr_info("tda18212dd: ChipID %04x %s\n", state->m_ID,
|
||||
state->m_isMaster ? "master" : "slave");
|
||||
/*pr_info("tda18212dd: ChipID %04x %s\n", state->m_ID,
|
||||
state->m_isMaster ? "master" : "slave");*/
|
||||
|
||||
if (state->m_ID != 18212)
|
||||
return -1;
|
||||
@@ -457,7 +457,7 @@ static int attach_init(struct tda_state *state)
|
||||
if (stat < 0)
|
||||
return stat;
|
||||
|
||||
pr_info("tda18212dd: PowerState %02x\n", PowerState);
|
||||
/*pr_info("tda18212dd: PowerState %02x\n", PowerState);*/
|
||||
|
||||
if (state->m_isMaster) {
|
||||
if (PowerState & 0x02) {
|
||||
@@ -487,6 +487,7 @@ static int attach_init(struct tda_state *state)
|
||||
FinishCalibration(state);
|
||||
Standby(state);
|
||||
|
||||
#if 0
|
||||
{
|
||||
u8 RFCal_Log[12];
|
||||
|
||||
@@ -499,6 +500,7 @@ static int attach_init(struct tda_state *state)
|
||||
RFCal_Log[8], RFCal_Log[9],
|
||||
RFCal_Log[10], RFCal_Log[11]);
|
||||
}
|
||||
#endif
|
||||
return stat;
|
||||
}
|
||||
|
||||
@@ -775,6 +777,10 @@ static int sleep(struct dvb_frontend *fe)
|
||||
struct tda_state *state = fe->tuner_priv;
|
||||
|
||||
Standby(state);
|
||||
write_reg(state, THERMO_2, 0x01);
|
||||
read_reg1(state, THERMO_1);
|
||||
write_reg(state, THERMO_2, 0x00);
|
||||
/* printk("sleep: temp = %u\n", state->Regs[THERMO_1]); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -165,6 +165,8 @@ typedef enum fe_code_rate {
|
||||
FEC_3_5,
|
||||
FEC_9_10,
|
||||
FEC_2_5,
|
||||
FEC_1_4,
|
||||
FEC_1_3,
|
||||
} fe_code_rate_t;
|
||||
|
||||
|
||||
@@ -195,6 +197,7 @@ typedef enum fe_transmit_mode {
|
||||
TRANSMISSION_MODE_32K,
|
||||
TRANSMISSION_MODE_C1,
|
||||
TRANSMISSION_MODE_C3780,
|
||||
TRANSMISSION_MODE_64K,
|
||||
} fe_transmit_mode_t;
|
||||
|
||||
#if defined(__DVB_CORE__) || !defined (__KERNEL__)
|
||||
@@ -376,8 +379,9 @@ struct dvb_frontend_event {
|
||||
#define DTV_STAT_TOTAL_BLOCK_COUNT 69
|
||||
|
||||
#define DTV_INPUT 70
|
||||
#define DTV_PLS 71
|
||||
|
||||
#define DTV_MAX_COMMAND DTV_INPUT
|
||||
#define DTV_MAX_COMMAND DTV_PLS
|
||||
|
||||
typedef enum fe_pilot {
|
||||
PILOT_ON,
|
||||
@@ -452,6 +456,7 @@ enum atscmh_rs_code_mode {
|
||||
};
|
||||
|
||||
#define NO_STREAM_ID_FILTER (~0U)
|
||||
#define NO_SCRAMBLING_CODE (~0U)
|
||||
#define LNA_AUTO (~0U)
|
||||
|
||||
struct dtv_cmds_h {
|
||||
|
@@ -19,4 +19,17 @@ struct dvb_mod_channel_params {
|
||||
#define DVB_MOD_SET _IOW('o', 208, struct dvb_mod_params)
|
||||
#define DVB_MOD_CHANNEL_SET _IOW('o', 209, struct dvb_mod_channel_params)
|
||||
|
||||
#define MODULATOR_UNDEFINED 0
|
||||
#define MODULATOR_START 1
|
||||
#define MODULATOR_STOP 2
|
||||
#define MODULATOR_FREQUENCY 3
|
||||
#define MODULATOR_MODULATION 4
|
||||
#define MODULATOR_SYMBOL_RATE 5 /* Hz */
|
||||
#define MODULATOR_BASE_FREQUENCY 6
|
||||
#define MODULATOR_ATTENUATOR 32
|
||||
#define MODULATOR_INPUT_BITRATE 33 /* Hz */
|
||||
#define MODULATOR_PCR_MODE 34 /* 1=pcr correction enabled */
|
||||
#define MODULATOR_GAIN 35
|
||||
#define MODULATOR_OUTPUT_ARI 64
|
||||
|
||||
#endif /*_UAPI_DVBMOD_H_*/
|
||||
|
@@ -50,6 +50,11 @@ struct dvb_nsd_ts {
|
||||
__u16 section_id;
|
||||
};
|
||||
|
||||
struct dvb_ns_cap {
|
||||
__u8 streams_max;
|
||||
__u8 reserved[127];
|
||||
};
|
||||
|
||||
#define NS_SET_NET _IOW('o', 192, struct dvb_ns_params)
|
||||
#define NS_START _IO('o', 193)
|
||||
#define NS_STOP _IO('o', 194)
|
||||
@@ -66,4 +71,6 @@ struct dvb_nsd_ts {
|
||||
#define NS_INSERT_PACKETS _IOW('o', 203, __u8)
|
||||
#define NS_SET_CI _IOW('o', 204, __u8)
|
||||
|
||||
#define NS_GET_CAP _IOR('o', 204, struct dvb_ns_cap))
|
||||
|
||||
#endif /*_UAPI_DVBNS_H_*/
|
||||
|
@@ -26,6 +26,10 @@
|
||||
|
||||
#include <linux/compiler.h>
|
||||
|
||||
#ifndef __user
|
||||
#define __user
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
// All functions return -2 on "not open"
|
||||
OSD_Close=1, // ()
|
||||
|
@@ -30,6 +30,10 @@
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifndef __user
|
||||
#define __user
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
VIDEO_FORMAT_4_3, /* Select 4:3 format */
|
||||
VIDEO_FORMAT_16_9, /* Select 16:9 format. */
|
||||
|
Reference in New Issue
Block a user