mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2025-03-01 10:35:23 +00:00
Compare commits
103 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
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 |
@@ -1,3 +1,6 @@
|
||||
0.9.24 2016.08.03
|
||||
- suport new V2 modulator cards
|
||||
|
||||
0.9.19c 2015.07.20
|
||||
- MAX S8:
|
||||
do not turn on diseqc and tuners on init
|
||||
|
89
apps/cit.c
89
apps/cit.c
@@ -9,6 +9,9 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <pthread.h>
|
||||
#include <getopt.h>
|
||||
|
||||
uint32_t adapter = 0, device = 0, snum = 256, rnum = 256;
|
||||
|
||||
uint8_t fill[188]={0x47, 0x1f, 0xff, 0x10,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
@@ -68,24 +71,34 @@ void proc_buf(uint8_t *buf, uint32_t *d)
|
||||
} else {
|
||||
if (memcmp(ts+8, buf+8, 180))
|
||||
printf("error\n");
|
||||
if (!(c&0xffff))
|
||||
printf("R %08x\n", c);
|
||||
if (!(c&0xffff)) {
|
||||
printf("R %08x\r", c);
|
||||
fflush(0);
|
||||
}
|
||||
}
|
||||
(*d)++;
|
||||
}
|
||||
|
||||
void *get_ts(void *a)
|
||||
{
|
||||
uint8_t buf[188*1024];
|
||||
uint8_t *buf;
|
||||
int len, off;
|
||||
|
||||
int fdi=open("/dev/dvb/adapter2/ci0", O_RDONLY);
|
||||
int fdi;
|
||||
char fname[80];
|
||||
uint32_t d=0;
|
||||
|
||||
buf = malloc(188*rnum);
|
||||
if (!buf)
|
||||
return NULL;
|
||||
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
|
||||
fdi = open(fname, O_RDONLY);
|
||||
|
||||
while (1) {
|
||||
len=read(fdi, buf, 188*1024);
|
||||
memset(buf, 0, 188*rnum);
|
||||
len=read(fdi, buf, 188*rnum);
|
||||
if (len<0)
|
||||
continue;
|
||||
//printf("read %u\n", len);
|
||||
if (buf[0]!=0x47) {
|
||||
read(fdi, buf, 1);
|
||||
continue;
|
||||
@@ -96,20 +109,23 @@ void *get_ts(void *a)
|
||||
}
|
||||
}
|
||||
|
||||
#define SNUM 233
|
||||
//671
|
||||
void send(void)
|
||||
|
||||
int send(void)
|
||||
{
|
||||
uint8_t buf[188*SNUM], *cts;
|
||||
uint8_t *buf, *cts;
|
||||
int i;
|
||||
uint32_t c=0;
|
||||
int fdo;
|
||||
|
||||
fdo=open("/dev/dvb/adapter2/ci0", O_WRONLY);
|
||||
|
||||
char fname[80];
|
||||
|
||||
buf = malloc(188*snum);
|
||||
if (!buf)
|
||||
return -1;
|
||||
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
|
||||
fdo=open(fname, O_WRONLY);
|
||||
|
||||
while (1) {
|
||||
for (i=0; i<SNUM; i++) {
|
||||
for (i=0; i<snum; i++) {
|
||||
cts=buf+i*188;
|
||||
memcpy(cts, ts, 188);
|
||||
cts[4]=(c>>24);
|
||||
@@ -122,15 +138,54 @@ void send(void)
|
||||
//usleep(100000+0xffff&rand());
|
||||
//usleep(1000);
|
||||
}
|
||||
write(fdo, buf, 188*SNUM);
|
||||
write(fdo, buf, 188*snum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pthread_t th;
|
||||
|
||||
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
int c;
|
||||
static struct option long_options[] = {
|
||||
{"adapter", required_argument, 0, 'a'},
|
||||
{"device", required_argument, 0, 'd'},
|
||||
{"snum", required_argument, 0, 's'},
|
||||
{"rnum", required_argument, 0, 'r'},
|
||||
{"help", no_argument , 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
c = getopt_long(argc, argv,
|
||||
"a:d:h",
|
||||
long_options, &option_index);
|
||||
if (c==-1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'd':
|
||||
device = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'a':
|
||||
adapter = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 's':
|
||||
snum = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'r':
|
||||
rnum = strtoul(optarg, NULL, 10);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
if (optind < argc) {
|
||||
printf("Warning: unused arguments\n");
|
||||
}
|
||||
memset(ts+8, 180, 0x5a);
|
||||
pthread_create(&th, NULL, get_ts, NULL);
|
||||
usleep(10000);
|
||||
|
@@ -17,3 +17,4 @@ octonet: octonet.c
|
||||
|
||||
octokey: octokey.c
|
||||
$(CC) -o octokey octokey.c
|
||||
|
||||
|
@@ -91,6 +91,8 @@ enum {
|
||||
SSTI_SST25VF032B = 3,
|
||||
SSTI_SST25VF064C = 4,
|
||||
SPANSION_S25FL116K = 5,
|
||||
SPANSION_S25FL132K = 6,
|
||||
SPANSION_S25FL164K = 7,
|
||||
};
|
||||
|
||||
static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
|
||||
@@ -393,6 +395,8 @@ static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxle
|
||||
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;
|
||||
@@ -467,6 +471,16 @@ static int flash_detect(struct ddflash *ddf)
|
||||
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) {
|
||||
ddf->flash_type = ATMEL_AT45DB642D;
|
||||
printf("Flash: Atmel AT45DB642D 64 MBit\n");
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843 -DCONFIG_DVB_LNBP21 -DCONFIG_DVB_STV090x -DCONFIG_DVB_STV6110x -DCONFIG_DVB_DRXK -DCONFIG_DVB_STV0910 -DCONFIG_DVB_STV6111 -DCONFIG_DVB_LNBH25 -DCONFIG_DVB_MXL5XX
|
||||
|
||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||
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
|
@@ -1,9 +1,9 @@
|
||||
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
MODDEFS := CONFIG_DVB_DDBRIDGE=m
|
||||
MODDEFS := CONFIG_DVB_DDBRIDGE=m
|
||||
|
||||
all:
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MODDEFS) modules
|
||||
$(MAKE) -C apps
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -118,14 +118,24 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
|
||||
pr_err("DDBridge I2C timeout, card %d, port %d, link %u\n",
|
||||
dev->nr, i2c->nr, i2c->link);
|
||||
#if 1
|
||||
{
|
||||
{
|
||||
u32 istat = ddbreadl(dev, INTERRUPT_STATUS);
|
||||
|
||||
|
||||
dev_err(dev->dev, "DDBridge IRS %08x\n", istat);
|
||||
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);
|
||||
u32 mon = ddbreadl(dev,
|
||||
i2c->regs + I2C_MONITOR);
|
||||
|
||||
dev_err(dev->dev, "I2C cmd=%08x mon=%08x\n",
|
||||
val, mon);
|
||||
@@ -145,7 +155,7 @@ 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;
|
||||
@@ -214,19 +224,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
|
||||
@@ -236,7 +247,9 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
|
||||
adap->class = I2C_CLASS_TV_ANALOG;
|
||||
#endif
|
||||
#endif
|
||||
strcpy(adap->name, "ddbridge");
|
||||
/*strcpy(adap->name, "ddbridge");*/
|
||||
snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x",
|
||||
dev->nr, i2c->link, i);
|
||||
adap->algo = &ddb_i2c_algo;
|
||||
adap->algo_data = (void *)i2c;
|
||||
adap->dev.parent = dev->dev;
|
||||
@@ -246,23 +259,24 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
|
||||
static int ddb_i2c_init(struct ddb *dev)
|
||||
{
|
||||
int stat = 0;
|
||||
u32 i, j, num = 0, l;
|
||||
u32 i, j, num = 0, l, base;
|
||||
struct ddb_i2c *i2c;
|
||||
struct i2c_adapter *adap;
|
||||
struct ddb_regmap *regmap;
|
||||
|
||||
|
||||
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;
|
||||
@@ -275,7 +289,7 @@ static int ddb_i2c_init(struct ddb *dev)
|
||||
adap = &i2c->adap;
|
||||
i2c_del_adapter(adap);
|
||||
}
|
||||
} else
|
||||
} else
|
||||
dev->i2c_num = num;
|
||||
return stat;
|
||||
}
|
||||
|
@@ -28,6 +28,10 @@
|
||||
|
||||
#include <linux/dvb/mod.h>
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
inline s64 ConvertPCR(s64 a)
|
||||
{
|
||||
s32 ext;
|
||||
@@ -72,6 +76,81 @@ inline s64 RoundPCRDown(s64 a)
|
||||
return a & ~(HW_LSB_MASK - 1);
|
||||
}
|
||||
|
||||
// Calculating KF, LF from Symbolrate
|
||||
//
|
||||
// Symbolrate is usually calculated as (M/N) * 10.24 MS/s
|
||||
//
|
||||
// Common Values for M,N
|
||||
// J.83 Annex A,
|
||||
// Euro Docsis 6.952 MS/s : M = 869, N = 1280
|
||||
// 6.900 MS/s : M = 345, N = 512
|
||||
// 6.875 MS/s : M = 1375, N = 2048
|
||||
// 6.111 MS/s : M = 6111, N = 10240
|
||||
// J.83 Annex B **
|
||||
// QAM64 5.056941 : M = 401, N = 812
|
||||
// QAM256 5.360537 : M = 78, N = 149
|
||||
// J.83 Annex C **
|
||||
// 5.309734 : M = 1889, N = 3643
|
||||
//
|
||||
// For the present hardware
|
||||
// KF' = 256 * M
|
||||
// LF' = 225 * N
|
||||
// or
|
||||
// KF' = Symbolrate in Hz
|
||||
// LF' = 9000000
|
||||
//
|
||||
// KF = KF' / gcd(KF',LF')
|
||||
// LF = LF' / gcd(KF',LF')
|
||||
// Note: LF must not be a power of 2.
|
||||
// Maximum value for KF,LF = 13421727 ( 0x7FFFFFF )
|
||||
// ** using these M,N values will result in a small err (<5ppm)
|
||||
// calculating KF,LF directly gives the exact normative result
|
||||
// but with rather large KF,LF values
|
||||
|
||||
static inline u32 gcd(u32 u,u32 v)
|
||||
{
|
||||
int s = 0;
|
||||
while (((u|v)&1) == 0) {
|
||||
s += 1;
|
||||
u >>= 1;
|
||||
v >>= 1;
|
||||
}
|
||||
while ((u&1) == 0)
|
||||
u >>= 1;
|
||||
do {
|
||||
while ( (v&1) == 0 ) v >>= 1;
|
||||
if( u > v ) {
|
||||
u32 t = v;
|
||||
v = u;
|
||||
u = t;
|
||||
}
|
||||
v = v - u;
|
||||
} while(v != 0);
|
||||
return u << s;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static int mod_SendChannelCommand(struct ddb *dev, u32 Channel, u32 Command)
|
||||
{
|
||||
u32 ControlReg = ddbreadl(dev, CHANNEL_CONTROL(Channel));
|
||||
|
||||
ControlReg = (ControlReg & ~CHANNEL_CONTROL_CMD_MASK)|Command;
|
||||
ddbwritel(dev, ControlReg, CHANNEL_CONTROL(Channel));
|
||||
while(1) {
|
||||
ControlReg = ddbreadl(dev, CHANNEL_CONTROL(Channel));
|
||||
if (ControlReg == 0xFFFFFFFF)
|
||||
return -EIO;
|
||||
if((ControlReg & CHANNEL_CONTROL_CMD_STATUS) == 0)
|
||||
break;
|
||||
}
|
||||
if (ControlReg & CHANNEL_CONTROL_ERROR_CMD)
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mod_busy(struct ddb *dev, int chan)
|
||||
{
|
||||
u32 creg;
|
||||
@@ -89,10 +168,12 @@ static int mod_busy(struct ddb *dev, int chan)
|
||||
void ddbridge_mod_output_stop(struct ddb_output *output)
|
||||
{
|
||||
struct ddb *dev = output->port->dev;
|
||||
struct mod_state *mod = &dev->mod[output->nr];
|
||||
struct ddb_mod *mod = &dev->mod[output->nr];
|
||||
|
||||
mod->State = CM_IDLE;
|
||||
mod->Control = 0;
|
||||
if (dev->link[0].info->version == 2)
|
||||
mod_SendChannelCommand(dev, output->nr, CHANNEL_CONTROL_CMD_FREE);
|
||||
ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr));
|
||||
#if 0
|
||||
udelay(10);
|
||||
@@ -108,7 +189,7 @@ static void mod_set_incs(struct ddb_output *output)
|
||||
{
|
||||
s64 pcr;
|
||||
struct ddb *dev = output->port->dev;
|
||||
struct mod_state *mod = &dev->mod[output->nr];
|
||||
struct ddb_mod *mod = &dev->mod[output->nr];
|
||||
|
||||
pcr = ConvertPCR(mod->PCRIncrement);
|
||||
ddbwritel(dev, pcr & 0xffffffff,
|
||||
@@ -137,8 +218,10 @@ static u32 qamtab[6] = { 0x000, 0x600, 0x601, 0x602, 0x903, 0x604 };
|
||||
void ddbridge_mod_output_start(struct ddb_output *output)
|
||||
{
|
||||
struct ddb *dev = output->port->dev;
|
||||
struct mod_state *mod = &dev->mod[output->nr];
|
||||
|
||||
u32 Channel = output->nr;
|
||||
struct ddb_mod *mod = &dev->mod[output->nr];
|
||||
u32 Symbolrate = 6900000;
|
||||
|
||||
/*PCRIncrement = RoundPCR(PCRIncrement);*/
|
||||
/*PCRDecrement = RoundPCR(PCRDecrement);*/
|
||||
|
||||
@@ -164,18 +247,55 @@ void ddbridge_mod_output_start(struct ddb_output *output)
|
||||
udelay(10);
|
||||
ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr));
|
||||
|
||||
/* QAM: 600 601 602 903 604 = 16 32 64 128 256 */
|
||||
/* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */
|
||||
ddbwritel(dev, qamtab[mod->modulation], CHANNEL_SETTINGS(output->nr));
|
||||
pr_info("CHANNEL_BASE = %08x\n", CHANNEL_BASE);
|
||||
pr_info("CHANNEL_CONTROL = %08x\n", CHANNEL_CONTROL(Channel));
|
||||
if (dev->link[0].info->version == 2) {
|
||||
u32 Output = ((dev->mod_base.frequency - 114000000)/8000000 + Channel) % 96;
|
||||
u32 KF = Symbolrate;
|
||||
u32 LF = 9000000UL;
|
||||
u32 d = gcd(KF,LF);
|
||||
u32 checkLF;
|
||||
|
||||
mod->modulation = QAM_256 - 1;
|
||||
ddbwritel(dev, mod->modulation, CHANNEL_SETTINGS(Channel));
|
||||
ddbwritel(dev, Output, CHANNEL_SETTINGS2(Channel));
|
||||
|
||||
KF = KF / d;
|
||||
LF = LF / d;
|
||||
|
||||
while( (KF > KFLF_MAX) || (LF > KFLF_MAX) ) {
|
||||
KF >>= 1;
|
||||
LF >>= 1;
|
||||
}
|
||||
|
||||
checkLF = LF;
|
||||
while ((checkLF & 1) == 0)
|
||||
checkLF >>= 1;
|
||||
if (checkLF <= 1)
|
||||
return -EINVAL;
|
||||
|
||||
pr_info("KF=%u LF=%u Output=%u mod=%u\n", KF, LF, Output, mod->modulation);
|
||||
ddbwritel(dev, KF, CHANNEL_KF(Channel));
|
||||
ddbwritel(dev, LF, CHANNEL_LF(Channel));
|
||||
|
||||
if (mod_SendChannelCommand(dev, Channel, CHANNEL_CONTROL_CMD_SETUP))
|
||||
return -EINVAL;
|
||||
mod->Control = CHANNEL_CONTROL_ENABLE_DVB;
|
||||
} else {
|
||||
/* QAM: 600 601 602 903 604 = 16 32 64 128 256 */
|
||||
/* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */
|
||||
ddbwritel(dev, qamtab[mod->modulation], CHANNEL_SETTINGS(output->nr));
|
||||
mod->Control = (CHANNEL_CONTROL_ENABLE_IQ | CHANNEL_CONTROL_ENABLE_DVB);
|
||||
}
|
||||
mod_set_rateinc(dev, output->nr);
|
||||
mod_set_incs(output);
|
||||
|
||||
mod->Control = (CHANNEL_CONTROL_ENABLE_IQ |
|
||||
CHANNEL_CONTROL_ENABLE_DVB |
|
||||
CHANNEL_CONTROL_ENABLE_SOURCE);
|
||||
mod->Control |= CHANNEL_CONTROL_ENABLE_SOURCE;
|
||||
|
||||
ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr));
|
||||
if (dev->link[0].info->version == 2)
|
||||
if (mod_SendChannelCommand(dev, Channel, CHANNEL_CONTROL_CMD_UNMUTE))
|
||||
return -EINVAL;
|
||||
pr_info("mod_output_start %d.%d\n", dev->nr, output->nr);
|
||||
}
|
||||
|
||||
@@ -183,6 +303,195 @@ void ddbridge_mod_output_start(struct ddb_output *output)
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static int mod_write_max2871(struct ddb *dev, u32 val)
|
||||
{
|
||||
ddbwritel(dev, val, MAX2871_OUTDATA);
|
||||
ddbwritel(dev, MAX2871_CONTROL_CE | MAX2871_CONTROL_WRITE, MAX2871_CONTROL);
|
||||
while(1) {
|
||||
u32 ControlReg = ddbreadl(dev, MAX2871_CONTROL);
|
||||
if (ControlReg == 0xFFFFFFFF)
|
||||
return -EIO;
|
||||
if ((ControlReg & MAX2871_CONTROL_WRITE) == 0)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mod_setup_max2871(struct ddb *dev)
|
||||
{
|
||||
int status = 0;
|
||||
int i;
|
||||
|
||||
ddbwritel(dev, MAX2871_CONTROL_CE, MAX2871_CONTROL);
|
||||
for (i = 0; i < 2; i++) {
|
||||
status = mod_write_max2871(dev, 0x00440005);
|
||||
if (status)
|
||||
break;
|
||||
status = mod_write_max2871(dev, 0x6199003C);
|
||||
if (status)
|
||||
break;
|
||||
status = mod_write_max2871(dev, 0x000000CB);
|
||||
if (status)
|
||||
break;
|
||||
status = mod_write_max2871(dev, 0x510061C2);
|
||||
if (status)
|
||||
break;
|
||||
status = mod_write_max2871(dev, 0x600080A1);
|
||||
if (status)
|
||||
break;
|
||||
status = mod_write_max2871(dev, 0x00730040);
|
||||
if (status)
|
||||
break;
|
||||
msleep(30);
|
||||
} while(0);
|
||||
|
||||
if (status == 0) {
|
||||
u32 ControlReg = ddbreadl(dev, MAX2871_CONTROL);
|
||||
|
||||
if ((ControlReg & MAX2871_CONTROL_LOCK) == 0)
|
||||
status = -EIO;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan, u32 MaxUsedChannels)
|
||||
{
|
||||
int status = 0;
|
||||
u32 Capacity;
|
||||
u32 tmp = ddbreadl(dev, FSM_STATUS);
|
||||
|
||||
if ((tmp & FSM_STATUS_READY) == 0) {
|
||||
status = mod_setup_max2871(dev);
|
||||
if (status)
|
||||
return status;
|
||||
ddbwritel(dev, FSM_CMD_RESET, FSM_CONTROL);
|
||||
msleep(10);
|
||||
|
||||
tmp = ddbreadl(dev, FSM_STATUS);
|
||||
if ((tmp & FSM_STATUS_READY) == 0)
|
||||
return -1;
|
||||
}
|
||||
Capacity = ddbreadl(dev, FSM_CAPACITY);
|
||||
if (((tmp & FSM_STATUS_QAMREADY) != 0) &&
|
||||
((Capacity & FSM_CAPACITY_INUSE) != 0))
|
||||
return -EBUSY;
|
||||
|
||||
ddbwritel(dev, FSM_CMD_SETUP, FSM_CONTROL);
|
||||
msleep(10);
|
||||
tmp = ddbreadl(dev, FSM_STATUS);
|
||||
|
||||
if ((tmp & FSM_STATUS_QAMREADY) == 0)
|
||||
return -1;
|
||||
|
||||
if (MaxUsedChannels == 0)
|
||||
MaxUsedChannels = (Capacity & FSM_CAPACITY_CUR) >> 16;
|
||||
|
||||
pr_info("max used chan = %u\n", MaxUsedChannels);
|
||||
if (MaxUsedChannels <= 1 )
|
||||
ddbwritel(dev, FSM_GAIN_N1, FSM_GAIN);
|
||||
else if (MaxUsedChannels <= 2)
|
||||
ddbwritel(dev, FSM_GAIN_N2, FSM_GAIN);
|
||||
else if (MaxUsedChannels <= 4)
|
||||
ddbwritel(dev, FSM_GAIN_N4, FSM_GAIN);
|
||||
else if (MaxUsedChannels <= 8)
|
||||
ddbwritel(dev, FSM_GAIN_N8, FSM_GAIN);
|
||||
else if (MaxUsedChannels <= 16)
|
||||
ddbwritel(dev, FSM_GAIN_N16, FSM_GAIN);
|
||||
else if (MaxUsedChannels <= 24)
|
||||
ddbwritel(dev, FSM_GAIN_N24, FSM_GAIN);
|
||||
else
|
||||
ddbwritel(dev, FSM_GAIN_N96, FSM_GAIN);
|
||||
|
||||
ddbwritel(dev, FSM_CONTROL_ENABLE, FSM_CONTROL);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int mod_set_vga(struct ddb *dev, u32 Gain)
|
||||
{
|
||||
if( Gain > 255 )
|
||||
return -EINVAL;
|
||||
ddbwritel(dev, Gain, RF_VGA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mod_get_vga(struct ddb *dev, u32 *pGain)
|
||||
{
|
||||
*pGain = ddbreadl(dev, RF_VGA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mod_TemperatureMonitorSetFan(struct ddb *dev)
|
||||
{
|
||||
u32 tqam, pwm;
|
||||
|
||||
if ((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0) {
|
||||
pr_info("Over temperature condition\n");
|
||||
dev->mod_base.OverTemperatureError = 1;
|
||||
}
|
||||
tqam = (ddbreadl(dev, TEMPMON2_QAMCORE) >> 8) & 0xFF;
|
||||
if (tqam & 0x80)
|
||||
tqam = 0;
|
||||
|
||||
pwm = (ddbreadl(dev, TEMPMON_FANCONTROL) >> 8) & 0x0F;
|
||||
if (pwm > 10)
|
||||
pwm = 10;
|
||||
|
||||
if (tqam >= dev->mod_base.temp_tab[pwm]) {
|
||||
while( pwm < 10 && tqam >= dev->mod_base.temp_tab[pwm + 1])
|
||||
pwm += 1;
|
||||
} else {
|
||||
while( pwm > 1 && tqam < dev->mod_base.temp_tab[pwm - 2])
|
||||
pwm -= 1;
|
||||
}
|
||||
ddbwritel(dev, (pwm << 8), TEMPMON_FANCONTROL);
|
||||
}
|
||||
|
||||
|
||||
static void mod_temp_handler(unsigned long data)
|
||||
{
|
||||
struct ddb *dev = (struct ddb *) data;
|
||||
|
||||
pr_info("mod_temp_handler\n");
|
||||
|
||||
spin_lock(&dev->mod_base.temp_lock);
|
||||
mod_TemperatureMonitorSetFan(dev);
|
||||
spin_unlock(&dev->mod_base.temp_lock);
|
||||
}
|
||||
|
||||
static int mod_TemperatureMonitorInit(struct ddb *dev, int FirstTime) {
|
||||
int status = 0;
|
||||
|
||||
spin_lock_irq(&dev->mod_base.temp_lock);
|
||||
if (FirstTime) {
|
||||
static u8 TemperatureTable[11] = {30,35,40,45,50,55,60,65,70,75,80};
|
||||
|
||||
memcpy(dev->mod_base.temp_tab, TemperatureTable, sizeof(TemperatureTable));
|
||||
}
|
||||
dev->handler[0][8] = mod_temp_handler;
|
||||
dev->handler_data[0][8] = (unsigned long) dev;
|
||||
ddbwritel(dev, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN |
|
||||
TEMPMON_CONTROL_INTENABLE),
|
||||
TEMPMON_CONTROL);
|
||||
ddbwritel(dev, (3 << 8), TEMPMON_FANCONTROL);
|
||||
|
||||
dev->mod_base.OverTemperatureError =
|
||||
((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0);
|
||||
if (dev->mod_base.OverTemperatureError) {
|
||||
pr_info("Over temperature condition\n");
|
||||
status = -1;
|
||||
}
|
||||
mod_TemperatureMonitorSetFan(dev);
|
||||
spin_unlock_irq(&dev->mod_base.temp_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static void mod_write_dac_register(struct ddb *dev, u8 Index, u8 Value)
|
||||
{
|
||||
u32 RegValue = 0;
|
||||
@@ -804,7 +1113,7 @@ static int set_base_frequency(struct ddb *dev, u32 freq)
|
||||
return mod_set_down(dev, down, 8, Ext);
|
||||
}
|
||||
|
||||
static int mod_init(struct ddb *dev, u32 Frequency)
|
||||
static int mod_init_1(struct ddb *dev, u32 Frequency)
|
||||
{
|
||||
int stat = 0;
|
||||
u8 *buffer;
|
||||
@@ -906,7 +1215,7 @@ void ddbridge_mod_rate_handler(unsigned long data)
|
||||
struct ddb_output *output = (struct ddb_output *) data;
|
||||
struct ddb_dma *dma = output->dma;
|
||||
struct ddb *dev = output->port->dev;
|
||||
struct mod_state *mod = &dev->mod[output->nr];
|
||||
struct ddb_mod *mod = &dev->mod[output->nr];
|
||||
|
||||
u32 chan = output->nr;
|
||||
u32 OutPacketCount;
|
||||
@@ -965,7 +1274,8 @@ void ddbridge_mod_rate_handler(unsigned long data)
|
||||
InPacketDiff/1000));
|
||||
if (OutPacketDiff)
|
||||
mod->rate_inc =
|
||||
div_u64(mul, OutPacketDiff);
|
||||
div_u64(mul,
|
||||
OutPacketDiff);
|
||||
else
|
||||
mod->rate_inc = 0;
|
||||
mod_set_rateinc(dev, output->nr);
|
||||
@@ -975,7 +1285,8 @@ void ddbridge_mod_rate_handler(unsigned long data)
|
||||
if (InPacketDiff)
|
||||
mod->PCRDecrement =
|
||||
div_u64(mod->PCRIncrement *
|
||||
(u64) OutPacketDiff,
|
||||
(u64)
|
||||
OutPacketDiff,
|
||||
InPacketDiff);
|
||||
else
|
||||
mod->PCRDecrement = 0;
|
||||
@@ -1079,7 +1390,7 @@ void ddbridge_mod_rate_handler(unsigned long data)
|
||||
PCRAdjustExtFrac, PCRCorr, mod->PCRIncrement);
|
||||
}
|
||||
|
||||
int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
||||
static int mod_ioctl_1(struct file *file, unsigned int cmd, void *parg)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
struct ddb_output *output = dvbdev->priv;
|
||||
@@ -1144,7 +1455,114 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static int mod_ioctl_2(struct file *file, unsigned int cmd, void *parg)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
struct ddb_output *output = dvbdev->priv;
|
||||
struct ddb *dev = output->port->dev;
|
||||
|
||||
/* unsigned long arg = (unsigned long) parg; */
|
||||
int ret = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case DVB_MOD_SET:
|
||||
{
|
||||
struct dvb_mod_params *mp = parg;
|
||||
|
||||
pr_info("set base freq\n");
|
||||
dev->mod_base.frequency = mp->base_frequency;
|
||||
pr_info("set attenuator\n");
|
||||
mod_set_attenuator(dev, mp->attenuator);
|
||||
break;
|
||||
}
|
||||
case DVB_MOD_CHANNEL_SET:
|
||||
{
|
||||
struct dvb_mod_channel_params *cp = parg;
|
||||
int res;
|
||||
u32 ri;
|
||||
|
||||
pr_info("set modulation\n");
|
||||
res = mod_set_modulation(dev, output->nr, cp->modulation);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
if (cp->input_bitrate > dev->mod[output->nr].obitrate)
|
||||
return -EINVAL;
|
||||
dev->mod[output->nr].ibitrate = cp->input_bitrate;
|
||||
dev->mod[output->nr].pcr_correction = cp->pcr_correction;
|
||||
|
||||
pr_info("ibitrate %llu\n", dev->mod[output->nr].ibitrate);
|
||||
pr_info("obitrate %llu\n", dev->mod[output->nr].obitrate);
|
||||
if (cp->input_bitrate != 0) {
|
||||
u64 d = dev->mod[output->nr].obitrate -
|
||||
dev->mod[output->nr].ibitrate;
|
||||
|
||||
d = div64_u64(d, dev->mod[output->nr].obitrate >> 24);
|
||||
if (d > 0xfffffe)
|
||||
ri = 0xfffffe;
|
||||
else
|
||||
ri = d;
|
||||
} else
|
||||
ri = 0;
|
||||
dev->mod[output->nr].rate_inc = ri;
|
||||
pr_info("ibr=%llu, obr=%llu, ri=0x%06x\n",
|
||||
dev->mod[output->nr].ibitrate >> 32,
|
||||
dev->mod[output->nr].obitrate >> 32,
|
||||
ri);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int mod_init_2(struct ddb *dev, u32 Frequency)
|
||||
{
|
||||
int status;
|
||||
int streams = dev->link[0].info->port_num;
|
||||
|
||||
dev->mod_base.frequency = Frequency;
|
||||
mod_TemperatureMonitorInit(dev, 1);
|
||||
status = mod_fsm_setup(dev, 0, 0);
|
||||
|
||||
if (streams <= 8)
|
||||
mod_set_vga(dev, RF_VGA_GAIN_N8);
|
||||
else if (streams <= 16)
|
||||
mod_set_vga(dev, RF_VGA_GAIN_N16);
|
||||
else
|
||||
mod_set_vga(dev, RF_VGA_GAIN_N24);
|
||||
|
||||
mod_set_attenuator(dev, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
struct ddb_output *output = dvbdev->priv;
|
||||
struct ddb *dev = output->port->dev;
|
||||
|
||||
if (dev->link[0].info->version <= 0)
|
||||
return mod_ioctl_1(file, cmd, parg);
|
||||
if (dev->link[0].info->version == 2)
|
||||
return mod_ioctl_2(file, cmd, parg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ddbridge_mod_init(struct ddb *dev)
|
||||
{
|
||||
return mod_init(dev, 722000000);
|
||||
spin_lock_init(&dev->mod_base.temp_lock);
|
||||
if (dev->link[0].info->version <= 1)
|
||||
return mod_init_1(dev, 722000000);
|
||||
if (dev->link[0].info->version == 2)
|
||||
return mod_init_2(dev, 114000000);
|
||||
return -1;
|
||||
}
|
||||
|
@@ -197,11 +197,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("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 +446,8 @@ 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);
|
||||
/* 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;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* ddbridge-regs.h: Digital Devices PCIe bridge driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* Copyright (C) 2010-2016 Digital Devices GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -23,12 +23,11 @@
|
||||
|
||||
/* Register Definitions */
|
||||
|
||||
#define CUR_REGISTERMAP_VERSION 0x10003
|
||||
#define CUR_REGISTERMAP_VERSION_CI 0x10000
|
||||
#define CUR_REGISTERMAP_VERSION_MOD 0x10000
|
||||
#define CUR_REGISTERMAP_VERSION_V1 0x00010001
|
||||
#define CUR_REGISTERMAP_VERSION_V2 0x00020000
|
||||
|
||||
#define HARDWARE_VERSION 0x00
|
||||
#define REGISTERMAP_VERSION 0x04
|
||||
#define HARDWARE_VERSION 0x00000000
|
||||
#define REGISTERMAP_VERSION 0x00000004
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* SPI Controller */
|
||||
@@ -76,6 +75,8 @@
|
||||
|
||||
#define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20)
|
||||
#define INTERRUPT_ACK (INTERRUPT_BASE + 0x20)
|
||||
#define INTERRUPT_ACK1 (INTERRUPT_BASE + 0x24)
|
||||
#define INTERRUPT_ACK2 (INTERRUPT_BASE + 0x28)
|
||||
|
||||
#define INTMASK_CLOCKGEN (0x00000001)
|
||||
#define INTMASK_TEMPMON (0x00000002)
|
||||
@@ -105,6 +106,26 @@
|
||||
#define INTMASK_TSOUTPUT4 (0x00080000)
|
||||
|
||||
|
||||
#define INTERRUPT_V2_CONTROL (INTERRUPT_BASE + 0x00)
|
||||
#define INTERRUPT_V2_ENABLE_1 (INTERRUPT_BASE + 0x04)
|
||||
#define INTERRUPT_V2_ENABLE_2 (INTERRUPT_BASE + 0x08)
|
||||
#define INTERRUPT_V2_ENABLE_3 (INTERRUPT_BASE + 0x0c)
|
||||
#define INTERRUPT_V2_ENABLE_4 (INTERRUPT_BASE + 0x10)
|
||||
#define INTERRUPT_V2_ENABLE_5 (INTERRUPT_BASE + 0x14)
|
||||
#define INTERRUPT_V2_ENABLE_6 (INTERRUPT_BASE + 0x18)
|
||||
#define INTERRUPT_V2_ENABLE_7 (INTERRUPT_BASE + 0x1c)
|
||||
|
||||
#define INTERRUPT_V2_STATUS (INTERRUPT_BASE + 0x20)
|
||||
#define INTERRUPT_V2_STATUS_1 (INTERRUPT_BASE + 0x24)
|
||||
#define INTERRUPT_V2_STATUS_2 (INTERRUPT_BASE + 0x28)
|
||||
#define INTERRUPT_V2_STATUS_3 (INTERRUPT_BASE + 0x2c)
|
||||
#define INTERRUPT_V2_STATUS_4 (INTERRUPT_BASE + 0x30)
|
||||
#define INTERRUPT_V2_STATUS_5 (INTERRUPT_BASE + 0x34)
|
||||
#define INTERRUPT_V2_STATUS_6 (INTERRUPT_BASE + 0x38)
|
||||
#define INTERRUPT_V2_STATUS_7 (INTERRUPT_BASE + 0x3c)
|
||||
|
||||
|
||||
|
||||
|
||||
/* Modulator registers */
|
||||
|
||||
@@ -128,23 +149,46 @@
|
||||
/* Temperature Monitor ( 2x LM75A @ 0x90,0x92 I2c ) */
|
||||
#define TEMPMON_BASE (0xA0)
|
||||
#define TEMPMON_CONTROL (TEMPMON_BASE + 0x00)
|
||||
|
||||
#define TEMPMON_CONTROL_SCAN (0x00000001)
|
||||
#define TEMPMON_CONTROL_AUTOSCAN (0x00000002)
|
||||
#define TEMPMON_CONTROL_INTENABLE (0x00000004)
|
||||
#define TEMPMON_CONTROL_OVERTEMP (0x00008000)
|
||||
|
||||
|
||||
/* SHORT Temperature in <20>C x 256 */
|
||||
#define TEMPMON_CORE (TEMPMON_BASE + 0x04)
|
||||
#define TEMPMON_SENSOR0 (TEMPMON_BASE + 0x04)
|
||||
#define TEMPMON_SENSOR1 (TEMPMON_BASE + 0x08)
|
||||
#define TEMPMON_SENSOR2 (TEMPMON_BASE + 0x0C)
|
||||
|
||||
#define TEMPMON_FANCONTROL (TEMPMON_BASE + 0x10)
|
||||
#define TEMPMON_FANPWM (0x00000F00) // PWM speed in 10% steps
|
||||
#define TEMPMON_FANTACHO (0x000000FF) // Rotations in 100/min steps
|
||||
|
||||
// V1 Temperature Monitor
|
||||
// Temperature Monitor TEMPMON_CONTROL & 0x8000 == 0 : ( 2x LM75A @ 0x90,0x92 )
|
||||
// Temperature Monitor TEMPMON_CONTROL & 0x8000 == 1 : ( 1x LM75A @ 0x90, 1x ADM1032 @ 0x9A )
|
||||
|
||||
#define TEMPMON1_CORE (TEMPMON_SENSOR0) // SHORT Temperature in <20>C x 256 (ADM1032 ext)
|
||||
#define TEMPMON1_SENSOR1 (TEMPMON_BASE + 0x08) // SHORT Temperature in <20>C x 256 (LM75A 0x90)
|
||||
#define TEMPMON1_SENSOR2 (TEMPMON_BASE + 0x0C) // SHORT Temperature in <20>C x 256 (LM75A 0x92 or ADM1032 Int)
|
||||
|
||||
// V2 Temperature Monitor 2 ADM1032
|
||||
|
||||
#define TEMPMON2_BOARD (TEMPMON_SENSOR0) // SHORT Temperature in <20>C x 256 (ADM1032 int)
|
||||
#define TEMPMON2_FPGACORE (TEMPMON_SENSOR1) // SHORT Temperature in <20>C x 256 (ADM1032 ext)
|
||||
#define TEMPMON2_QAMCORE (TEMPMON_SENSOR2) // SHORT Temperature in <20>C x 256 (ADM1032 ext)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* I2C Master Controller */
|
||||
|
||||
#define I2C_BASE (0x80) /* Byte offset */
|
||||
|
||||
#define I2C_COMMAND (0x00)
|
||||
#define I2C_TIMING (0x04)
|
||||
#define I2C_TASKLENGTH (0x08) /* High read, low write */
|
||||
#define I2C_TASKADDRESS (0x0C) /* High read, low write */
|
||||
#define I2C_MONITOR (0x1C)
|
||||
|
||||
|
||||
#define I2C_SPEED_666 (0x02010202)
|
||||
#define I2C_SPEED_400 (0x04030404)
|
||||
#define I2C_SPEED_200 (0x09080909)
|
||||
@@ -173,26 +217,17 @@
|
||||
#define DMA_DIAG_WAITOVERFLOWCOUNTER (0x38)
|
||||
#define DMA_DIAG_WAITCOUNTER (0x3C)
|
||||
|
||||
#define TS_INPUT_BASE (0x200)
|
||||
#define TS_INPUT_CONTROL(i) (TS_INPUT_BASE + (i) * 0x10 + 0x00)
|
||||
#define TS_INPUT_CONTROL2(i) (TS_INPUT_BASE + (i) * 0x10 + 0x04)
|
||||
#define TS_CONTROL(_io) (_io->regs + 0x00)
|
||||
#define TS_CONTROL2(_io) (_io->regs + 0x04)
|
||||
|
||||
#define TS_OUTPUT_BASE (0x280)
|
||||
#define TS_OUTPUT_CONTROL(i) (TS_OUTPUT_BASE + (i) * 0x10 + 0x00)
|
||||
#define TS_OUTPUT_CONTROL2(i) (TS_OUTPUT_BASE + (i) * 0x10 + 0x04)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* DMA Buffer */
|
||||
|
||||
#define DMA_BUFFER_BASE (0x300)
|
||||
|
||||
#define DMA_BUFFER_CONTROL(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x00)
|
||||
#define DMA_BUFFER_ACK(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x04)
|
||||
#define DMA_BUFFER_CURRENT(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x08)
|
||||
#define DMA_BUFFER_SIZE(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x0c)
|
||||
|
||||
#define DMA_BASE_ADDRESS_TABLE (0x2000)
|
||||
#define DMA_BASE_ADDRESS_TABLE_ENTRIES (512)
|
||||
#define DMA_BUFFER_CONTROL(_dma) (_dma->regs + 0x00)
|
||||
#define DMA_BUFFER_ACK(_dma) (_dma->regs + 0x04)
|
||||
#define DMA_BUFFER_CURRENT(_dma) (_dma->regs + 0x08)
|
||||
#define DMA_BUFFER_SIZE(_dma) (_dma->regs + 0x0c)
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -263,6 +298,8 @@
|
||||
#define CI_BLOCKIO_SEND_BUFFER(i) \
|
||||
(CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE + CI_BLOCKIO_BUFFER_SIZE)
|
||||
|
||||
// V1
|
||||
|
||||
#define VCO1_BASE (0xC0)
|
||||
#define VCO1_CONTROL (VCO1_BASE + 0x00)
|
||||
#define VCO1_DATA (VCO1_BASE + 0x04) /* 24 Bit */
|
||||
@@ -293,6 +330,53 @@
|
||||
/* Muxout from VCO (usually = Lock) */
|
||||
#define VCO3_CONTROL_MUXOUT (0x00000004)
|
||||
|
||||
// V2
|
||||
|
||||
#define MAX2871_BASE (0xC0)
|
||||
#define MAX2871_CONTROL (MAX2871_BASE + 0x00)
|
||||
#define MAX2871_OUTDATA (MAX2871_BASE + 0x04) // 32 Bit
|
||||
#define MAX2871_INDATA (MAX2871_BASE + 0x08) // 32 Bit
|
||||
#define MAX2871_CONTROL_WRITE (0x00000001) // 1 = Trigger write, resets when done
|
||||
#define MAX2871_CONTROL_CE (0x00000002) // 0 = Put VCO into power down
|
||||
#define MAX2871_CONTROL_MUXOUT (0x00000004) // Muxout from VCO
|
||||
#define MAX2871_CONTROL_LOCK (0x00000008) // Lock from VCO
|
||||
|
||||
#define FSM_BASE (0x200)
|
||||
#define FSM_CONTROL (FSM_BASE + 0x00)
|
||||
|
||||
#define FSM_CONTROL_ENABLE (0x00000100)
|
||||
|
||||
#define FSM_CMD_MASK (0x00000087)
|
||||
#define FSM_CMD_STATUS (0x00000080)
|
||||
#define FSM_CMD_RESET (0x00000080)
|
||||
#define FSM_CMD_POWERDOWN (0x00000081)
|
||||
#define FSM_CMD_SETUP (0x00000082)
|
||||
|
||||
#define FSM_STATUS (FSM_BASE + 0x00)
|
||||
#define FSM_STATUS_READY (0x00010000)
|
||||
#define FSM_STATUS_QAMREADY (0x00020000)
|
||||
|
||||
|
||||
#define FSM_CAPACITY (FSM_BASE + 0x04)
|
||||
#define FSM_CAPACITY_MAX (0x3F000000)
|
||||
#define FSM_CAPACITY_CUR (0x003F0000)
|
||||
#define FSM_CAPACITY_INUSE (0x0000003F)
|
||||
|
||||
#define FSM_GAIN (FSM_BASE + 0x10)
|
||||
#define FSM_GAINMASK (0x000000FF)
|
||||
|
||||
#define FSM_GAIN_N1 (0x000000FE)
|
||||
#define FSM_GAIN_N2 (0x000000A1)
|
||||
#define FSM_GAIN_N4 (0x00000066)
|
||||
#define FSM_GAIN_N8 (0x00000048)
|
||||
#define FSM_GAIN_N16 (0x0000002D)
|
||||
#define FSM_GAIN_N24 (0x00000029)
|
||||
#define FSM_GAIN_N96 (0x00000011)
|
||||
|
||||
|
||||
// Attenuator/VGA
|
||||
|
||||
#define RF_ATTENUATOR (0xD8)
|
||||
#define RF_ATTENUATOR (0xD8)
|
||||
/* 0x00 = 0 dB
|
||||
0x01 = 1 dB
|
||||
@@ -300,6 +384,20 @@
|
||||
0x1F = 31 dB
|
||||
*/
|
||||
|
||||
#define RF_VGA (0xDC)
|
||||
/* Only V2 */
|
||||
/* 8 bit range 0 - 31.75 dB Gain */
|
||||
|
||||
/* VGA Gain for same output level as V1 Modulator */
|
||||
#define RF_VGA_GAIN_N8 (85)
|
||||
#define RF_VGA_GAIN_N16 (117)
|
||||
#define RF_VGA_GAIN_N24 (122)
|
||||
|
||||
#define RF_VGA_GAIN_MAX (200)
|
||||
|
||||
|
||||
/* V1 only */
|
||||
|
||||
#define RF_POWER (0xE0)
|
||||
#define RF_POWER_BASE (0xE0)
|
||||
#define RF_POWER_CONTROL (RF_POWER_BASE + 0x00)
|
||||
@@ -343,7 +441,7 @@
|
||||
#define IQOUTPUT_CONTROL_BYPASS_EQUALIZER (0x00000010)
|
||||
|
||||
|
||||
/* Modulator Base */
|
||||
/* Modulator Base V1 */
|
||||
|
||||
#define MODULATOR_BASE (0x200)
|
||||
#define MODULATOR_CONTROL (MODULATOR_BASE)
|
||||
@@ -361,9 +459,11 @@
|
||||
|
||||
/* Modulator Channels */
|
||||
|
||||
#define CHANNEL_BASE (0x400)
|
||||
#define CHANNEL_BASE dev->link[0].info->regmap->channel->base
|
||||
|
||||
#define CHANNEL_CONTROL(i) (CHANNEL_BASE + (i) * 64 + 0x00)
|
||||
#define CHANNEL_SETTINGS(i) (CHANNEL_BASE + (i) * 64 + 0x04)
|
||||
#define CHANNEL_SETTINGS2(i) (CHANNEL_BASE + (i) * 64 + 0x08)
|
||||
#define CHANNEL_RATE_INCR(i) (CHANNEL_BASE + (i) * 64 + 0x0C)
|
||||
#define CHANNEL_PCR_ADJUST_OUTL(i) (CHANNEL_BASE + (i) * 64 + 0x10)
|
||||
#define CHANNEL_PCR_ADJUST_OUTH(i) (CHANNEL_BASE + (i) * 64 + 0x14)
|
||||
@@ -373,6 +473,8 @@
|
||||
#define CHANNEL_PCR_ADJUST_ACCUH(i) (CHANNEL_BASE + (i) * 64 + 0x24)
|
||||
#define CHANNEL_PKT_COUNT_OUT(i) (CHANNEL_BASE + (i) * 64 + 0x28)
|
||||
#define CHANNEL_PKT_COUNT_IN(i) (CHANNEL_BASE + (i) * 64 + 0x2C)
|
||||
#define CHANNEL_KF(i) (CHANNEL_BASE + (i) * 64 + 0x30)
|
||||
#define CHANNEL_LF(i) (CHANNEL_BASE + (i) * 64 + 0x34)
|
||||
|
||||
#define CHANNEL_CONTROL_RESET (0x00000001)
|
||||
#define CHANNEL_CONTROL_ENABLE_DVB (0x00000002)
|
||||
@@ -381,8 +483,17 @@
|
||||
#define CHANNEL_CONTROL_ENABLE_PCRADJUST (0x00000010)
|
||||
#define CHANNEL_CONTROL_FREEZE_STATUS (0x00000100)
|
||||
|
||||
#define CHANNEL_CONTROL_CMD_MASK (0x0000F000)
|
||||
#define CHANNEL_CONTROL_CMD_STATUS (0x00008000)
|
||||
#define CHANNEL_CONTROL_CMD_FREE (0x00008000)
|
||||
#define CHANNEL_CONTROL_CMD_SETUP (0x00009000)
|
||||
#define CHANNEL_CONTROL_CMD_MUTE (0x0000A000)
|
||||
#define CHANNEL_CONTROL_CMD_UNMUTE (0x0000B000)
|
||||
|
||||
#define CHANNEL_CONTROL_RESET_ERROR (0x00010000)
|
||||
#define CHANNEL_CONTROL_BUSY (0x01000000)
|
||||
#define CHANNEL_CONTROL_ACTIVE (0x00400000)
|
||||
#define CHANNEL_CONTROL_BUSY (0x00800000)
|
||||
#define CHANNEL_CONTROL_ERROR_CMD (0x10000000)
|
||||
#define CHANNEL_CONTROL_ERROR_SYNC (0x20000000)
|
||||
#define CHANNEL_CONTROL_ERROR_UNDERRUN (0x40000000)
|
||||
#define CHANNEL_CONTROL_ERROR_FATAL (0x80000000)
|
||||
@@ -394,6 +505,14 @@
|
||||
#define CHANNEL_SETTINGS_QAM128 (0x00000003)
|
||||
#define CHANNEL_SETTINGS_QAM256 (0x00000004)
|
||||
|
||||
#define CHANNEL_SETTINGS2_OUTPUT_MASK (0x0000007F)
|
||||
|
||||
#define KFLF_MAX (0x07FFFFFFUL)
|
||||
#define KF_INIT(Symbolrate) (Symbolrate)
|
||||
#define LF_INIT(Symbolrate) (9000000UL)
|
||||
#define MIN_SYMBOLRATE (1000000)
|
||||
#define MAX_SYMBOLRATE (7100000)
|
||||
|
||||
|
||||
/* OCTONET */
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/*
|
||||
* ddbridge.c: Digital Devices PCIe bridge driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* 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
|
||||
@@ -24,7 +24,6 @@
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*#define DDB_ALT_DMA*/
|
||||
#define DDB_USE_WORK
|
||||
/*#define DDB_TEST_THREADED*/
|
||||
|
||||
@@ -58,19 +57,26 @@ static void ddb_unmap(struct ddb *dev)
|
||||
vfree(dev);
|
||||
}
|
||||
|
||||
|
||||
static void __devexit ddb_remove(struct pci_dev *pdev)
|
||||
static void __devexit ddb_irq_disable(struct ddb *dev)
|
||||
{
|
||||
struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
@@ -78,12 +84,25 @@ static void __devexit ddb_remove(struct pci_dev *pdev)
|
||||
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_device_destroy(dev);
|
||||
|
||||
ddb_unmap(dev);
|
||||
pci_set_drvdata(pdev, 0);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
@@ -92,16 +111,146 @@ static void __devexit ddb_remove(struct pci_dev *pdev)
|
||||
#define __devinitdata
|
||||
#endif
|
||||
|
||||
static int __devinit ddb_irq_msi(struct ddb *dev, int nr)
|
||||
{
|
||||
int stat;
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
if (msi && pci_msi_enabled()) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
||||
stat = pci_enable_msi_range(dev->pdev, 1, nr);
|
||||
if (stat >= 1) {
|
||||
dev->msi = stat;
|
||||
pr_info("DDBridge: using %d MSI interrupt(s)\n",
|
||||
dev->msi);
|
||||
} else
|
||||
pr_info("DDBridge: MSI not available.\n");
|
||||
|
||||
#else
|
||||
stat = pci_enable_msi_block(dev->pdev, nr);
|
||||
if (stat == 0) {
|
||||
dev->msi = nr;
|
||||
pr_info("DDBridge: using %d MSI interrupts\n", nr);
|
||||
} else if (stat == 1) {
|
||||
stat = pci_enable_msi(dev->pdev);
|
||||
dev->msi = 1;
|
||||
}
|
||||
if (stat < 0)
|
||||
pr_info("DDBridge: MSI not available.\n");
|
||||
#endif
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int __devinit ddb_irq_init2(struct ddb *dev)
|
||||
{
|
||||
int stat;
|
||||
int irq_flag = IRQF_SHARED;
|
||||
|
||||
pr_info("init type 2 IRQ hardware block\n");
|
||||
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_2);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_3);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_4);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_5);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_6);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_7);
|
||||
|
||||
ddb_irq_msi(dev, 1);
|
||||
if (dev->msi)
|
||||
irq_flag = 0;
|
||||
|
||||
stat = request_irq(dev->pdev->irq, irq_handler_v2,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0)
|
||||
return stat;
|
||||
|
||||
ddbwritel(dev, 0x0000ff7f, INTERRUPT_V2_CONTROL);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_1);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_2);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_3);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_4);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_5);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_6);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_7);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int __devinit ddb_irq_init(struct ddb *dev)
|
||||
{
|
||||
int stat;
|
||||
int irq_flag = IRQF_SHARED;
|
||||
|
||||
if (dev->link[0].info->regmap->irq_version == 2)
|
||||
return ddb_irq_init2(dev);
|
||||
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI2_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI3_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI4_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI5_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI6_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI7_ENABLE);
|
||||
|
||||
ddb_irq_msi(dev, 2);
|
||||
|
||||
if (dev->msi)
|
||||
irq_flag = 0;
|
||||
if (dev->msi == 2) {
|
||||
stat = request_irq(dev->pdev->irq, irq_handler0,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0)
|
||||
return stat;
|
||||
stat = request_irq(dev->pdev->irq + 1, irq_handler1,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0) {
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
return stat;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef DDB_TEST_THREADED
|
||||
stat = request_threaded_irq(dev->pdev->irq, irq_handler,
|
||||
irq_thread,
|
||||
irq_flag,
|
||||
"ddbridge", (void *) dev);
|
||||
#else
|
||||
stat = request_irq(dev->pdev->irq, irq_handler,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
#endif
|
||||
if (stat < 0)
|
||||
return stat;
|
||||
}
|
||||
/*ddbwritel(dev, 0xffffffff, INTERRUPT_ACK);*/
|
||||
if (dev->msi == 2) {
|
||||
ddbwritel(dev, 0x0fffff00, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x0000000f, MSI1_ENABLE);
|
||||
} else {
|
||||
ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
static int __devinit ddb_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct ddb *dev;
|
||||
int stat = 0;
|
||||
int irq_flag = IRQF_SHARED;
|
||||
|
||||
if (pci_enable_device(pdev) < 0)
|
||||
return -ENODEV;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
|
||||
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
|
||||
return -ENODEV;
|
||||
|
||||
dev = vzalloc(sizeof(struct ddb));
|
||||
if (dev == NULL)
|
||||
return -ENOMEM;
|
||||
@@ -143,100 +292,26 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
|
||||
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
|
||||
|
||||
if (dev->link[0].info->ns_num) {
|
||||
int i;
|
||||
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
for (i = 0; i < 16; i++)
|
||||
ddbwritel(dev, 0x00, TS_OUTPUT_CONTROL(i));
|
||||
usleep_range(5000, 6000);
|
||||
}
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI2_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI3_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI4_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI5_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI6_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI7_ENABLE);
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
if (msi && pci_msi_enabled()) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
||||
stat = pci_enable_msi_range(dev->pdev, 1, 2);
|
||||
if (stat >= 1) {
|
||||
dev->msi = stat;
|
||||
pr_info("DDBridge: using %d MSI interrupt(s)\n", dev->msi);
|
||||
irq_flag = 0;
|
||||
} else
|
||||
pr_info("DDBridge: MSI not available.\n");
|
||||
|
||||
#else
|
||||
stat = pci_enable_msi_block(dev->pdev, 2);
|
||||
if (stat == 0) {
|
||||
dev->msi = 1;
|
||||
pr_info("DDBridge: using 2 MSI interrupts\n");
|
||||
}
|
||||
if (stat == 1)
|
||||
stat = pci_enable_msi(dev->pdev);
|
||||
if (stat < 0) {
|
||||
pr_info("DDBridge: MSI not available.\n");
|
||||
} else {
|
||||
irq_flag = 0;
|
||||
dev->msi++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (dev->msi == 2) {
|
||||
stat = request_irq(dev->pdev->irq, irq_handler0,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0)
|
||||
goto fail0;
|
||||
stat = request_irq(dev->pdev->irq + 1, irq_handler1,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0) {
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
goto fail0;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef DDB_TEST_THREADED
|
||||
stat = request_threaded_irq(dev->pdev->irq, irq_handler,
|
||||
irq_thread,
|
||||
irq_flag,
|
||||
"ddbridge", (void *) dev);
|
||||
#else
|
||||
stat = request_irq(dev->pdev->irq, irq_handler,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
#endif
|
||||
if (stat < 0)
|
||||
goto fail0;
|
||||
ddb_reset_ios(dev);
|
||||
}
|
||||
ddbwritel(dev, 0, DMA_BASE_READ);
|
||||
if (dev->link[0].info->type != DDB_MOD)
|
||||
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);
|
||||
}
|
||||
stat = ddb_irq_init(dev);
|
||||
if (stat < 0)
|
||||
goto fail0;
|
||||
|
||||
if (ddb_init(dev) == 0)
|
||||
return 0;
|
||||
|
||||
ddbwritel(dev, 0, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0, MSI1_ENABLE);
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
if (dev->msi == 2)
|
||||
free_irq(dev->pdev->irq + 1, dev);
|
||||
|
||||
ddb_irq_disable(dev);
|
||||
fail0:
|
||||
pr_err("fail0\n");
|
||||
if (dev->msi)
|
||||
@@ -245,7 +320,7 @@ fail:
|
||||
pr_err("fail\n");
|
||||
|
||||
ddb_unmap(dev);
|
||||
pci_set_drvdata(pdev, 0);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
pci_disable_device(pdev);
|
||||
return -1;
|
||||
}
|
||||
@@ -254,37 +329,6 @@ fail:
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_regset octopus_i2c = {
|
||||
.base = 0x80,
|
||||
.num = 0x04,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_i2c_buf = {
|
||||
.base = 0x1000,
|
||||
.num = 0x04,
|
||||
.size = 0x200,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
static struct ddb_regmap octopus_map = {
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_net_map = {
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_mod_map = {
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_info ddb_none = {
|
||||
.type = DDB_NONE,
|
||||
.name = "unknown Digital Devices PCIe card, install newer driver",
|
||||
@@ -357,7 +401,9 @@ static struct ddb_info ddb_v7 = {
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 2,
|
||||
.board_control = 2,
|
||||
.board_control_2 = 4,
|
||||
.ts_quirks = TS_QUIRK_REVERSED,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ctv7 = {
|
||||
@@ -366,7 +412,8 @@ static struct ddb_info ddb_ctv7 = {
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 3,
|
||||
.board_control = 3,
|
||||
.board_control_2 = 4,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_satixS2v3 = {
|
||||
@@ -390,7 +437,7 @@ static struct ddb_info ddb_cis = {
|
||||
.name = "Digital Devices Octopus CI single",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x01,
|
||||
.i2c_mask = 0x03,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ci_s2_pro = {
|
||||
@@ -399,7 +446,8 @@ static struct ddb_info ddb_ci_s2_pro = {
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 3,
|
||||
.board_control = 2,
|
||||
.board_control_2 = 4,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_dvbct = {
|
||||
@@ -412,15 +460,6 @@ static struct ddb_info ddb_dvbct = {
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_info ddb_s2_48 = {
|
||||
.type = DDB_OCTOPUS_MAX,
|
||||
.name = "Digital Devices MAX S8 4/8",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_mod = {
|
||||
.type = DDB_MOD,
|
||||
.name = "Digital Devices DVB-C modulator",
|
||||
@@ -429,13 +468,48 @@ static struct ddb_info ddb_mod = {
|
||||
.temp_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_net = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet network DVB adapter",
|
||||
.regmap = &octopus_net_map,
|
||||
static struct ddb_info ddb_mod_fsm_24 = {
|
||||
.type = DDB_MOD,
|
||||
.version = 2,
|
||||
.name = "Digital Devices DVB-C modulator FSM-24",
|
||||
.regmap = &octopus_mod_2_map,
|
||||
.port_num = 24,
|
||||
.temp_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_mod_fsm_16 = {
|
||||
.type = DDB_MOD,
|
||||
.version = 2,
|
||||
.name = "Digital Devices DVB-C modulator FSM-16",
|
||||
.regmap = &octopus_mod_2_map,
|
||||
.port_num = 16,
|
||||
.temp_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_mod_fsm_8 = {
|
||||
.type = DDB_MOD,
|
||||
.name = "Digital Devices DVB-C modulator FSM-8",
|
||||
.version = 2,
|
||||
.regmap = &octopus_mod_2_map,
|
||||
.port_num = 8,
|
||||
.temp_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopro_hdin = {
|
||||
.type = DDB_OCTOPRO_HDIN,
|
||||
.name = "Digital Devices OctopusNet Pro HDIN",
|
||||
.regmap = &octopro_hdin_map,
|
||||
.port_num = 10,
|
||||
.i2c_mask = 0x3ff,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopro = {
|
||||
.type = DDB_OCTOPRO,
|
||||
.name = "Digital Devices OctopusNet Pro",
|
||||
.regmap = &octopro_map,
|
||||
.port_num = 10,
|
||||
.i2c_mask = 0x3ff,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
@@ -467,18 +541,31 @@ static const struct pci_device_id ddb_id_tbl[] __devinitconst = {
|
||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7),
|
||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7),
|
||||
DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48),
|
||||
DDB_ID(DDVID, 0x0008, DDVID, 0x0034, ddb_ct_8),
|
||||
DDB_ID(DDVID, 0x0008, DDVID, 0x0035, ddb_ct_8),
|
||||
DDB_ID(DDVID, 0x0008, DDVID, 0x0036, ddb_ct_8),
|
||||
DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci),
|
||||
DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis),
|
||||
DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci),
|
||||
DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro),
|
||||
DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod),
|
||||
DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod),
|
||||
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_octopus_net),
|
||||
DDB_ID(DDVID, 0x0210, DDVID, 0x0001, ddb_mod_fsm_24),
|
||||
DDB_ID(DDVID, 0x0210, DDVID, 0x0002, ddb_mod_fsm_16),
|
||||
DDB_ID(DDVID, 0x0210, DDVID, 0x0003, ddb_mod_fsm_8),
|
||||
/* testing on OctopusNet Pro */
|
||||
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro_hdin),
|
||||
DDB_ID(DDVID, 0x0321, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0322, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro),
|
||||
DDB_ID(DDVID, 0x0323, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0328, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0329, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro_hdin),
|
||||
/* in case sub-ids got deleted in flash */
|
||||
DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0005, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0008, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
@@ -500,7 +587,7 @@ static __init int module_init_ddbridge(void)
|
||||
|
||||
pr_info("Digital Devices PCIE bridge driver "
|
||||
DDBRIDGE_VERSION
|
||||
", Copyright (C) 2010-15 Digital Devices GmbH\n");
|
||||
", Copyright (C) 2010-16 Digital Devices GmbH\n");
|
||||
if (ddb_class_create() < 0)
|
||||
return -1;
|
||||
ddb_wq = create_workqueue("ddbridge");
|
||||
|
@@ -41,7 +41,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>
|
||||
@@ -91,10 +91,10 @@
|
||||
#include "lnbh25.h"
|
||||
#include "mxl5xx.h"
|
||||
|
||||
#define DDB_MAX_I2C 16
|
||||
#define DDB_MAX_PORT 16
|
||||
#define DDB_MAX_INPUT 44
|
||||
#define DDB_MAX_OUTPUT 10
|
||||
#define DDB_MAX_I2C 32
|
||||
#define DDB_MAX_PORT 32
|
||||
#define DDB_MAX_INPUT 64
|
||||
#define DDB_MAX_OUTPUT 32
|
||||
#define DDB_MAX_LINK 4
|
||||
#define DDB_LINK_SHIFT 28
|
||||
|
||||
@@ -106,25 +106,30 @@ struct ddb_regset {
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct ddb_ports {
|
||||
u32 base;
|
||||
u32 num;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct ddb_regmap {
|
||||
struct ddb_ports *bc;
|
||||
u32 irq_version;
|
||||
u32 irq_base_i2c;
|
||||
u32 irq_base_idma;
|
||||
u32 irq_base_odma;
|
||||
u32 irq_base_gtl;
|
||||
u32 irq_base_rate;
|
||||
|
||||
struct ddb_regset *i2c;
|
||||
struct ddb_regset *i2c_buf;
|
||||
struct ddb_regset *dma;
|
||||
struct ddb_regset *dma_buf;
|
||||
struct ddb_regset *idma;
|
||||
struct ddb_regset *idma_buf;
|
||||
struct ddb_regset *odma;
|
||||
struct ddb_regset *odma_buf;
|
||||
|
||||
struct ddb_regset *input;
|
||||
struct ddb_regset *output;
|
||||
|
||||
struct ddb_regset *channel;
|
||||
struct ddb_regset *ci;
|
||||
struct ddb_regset *pid_filter;
|
||||
struct ddb_regset *ns;
|
||||
//struct ddb_regset *ci;
|
||||
//struct ddb_regset *pid_filter;
|
||||
//struct ddb_regset *ns;
|
||||
struct ddb_regset *gtl;
|
||||
//struct ddb_regset *mdio;
|
||||
};
|
||||
|
||||
struct ddb_ids {
|
||||
@@ -132,7 +137,7 @@ struct ddb_ids {
|
||||
u16 device;
|
||||
u16 subvendor;
|
||||
u16 subdevice;
|
||||
|
||||
|
||||
u32 hwid;
|
||||
u32 regmapid;
|
||||
u32 devid;
|
||||
@@ -140,13 +145,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,10 +163,15 @@ 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
|
||||
struct ddb_regmap *regmap;
|
||||
};
|
||||
|
||||
@@ -166,6 +180,15 @@ struct ddb_info {
|
||||
|
||||
#define DMA_MAX_BUFS 32 /* hardware table limit */
|
||||
|
||||
#ifdef SMALL_DMA_BUFS
|
||||
#define INPUT_DMA_BUFS 32
|
||||
#define INPUT_DMA_SIZE (32*47*21)
|
||||
#define INPUT_DMA_IRQ_DIV 1
|
||||
|
||||
#define OUTPUT_DMA_BUFS 32
|
||||
#define OUTPUT_DMA_SIZE (32*47*21)
|
||||
#define OUTPUT_DMA_IRQ_DIV 1
|
||||
#else
|
||||
#define INPUT_DMA_BUFS 8
|
||||
#define INPUT_DMA_SIZE (128*47*21)
|
||||
#define INPUT_DMA_IRQ_DIV 1
|
||||
@@ -173,20 +196,23 @@ struct ddb_info {
|
||||
#define OUTPUT_DMA_BUFS 8
|
||||
#define OUTPUT_DMA_SIZE (128*47*21)
|
||||
#define OUTPUT_DMA_IRQ_DIV 1
|
||||
#endif
|
||||
|
||||
struct ddb;
|
||||
struct ddb_port;
|
||||
|
||||
struct ddb_dma {
|
||||
void *io;
|
||||
u32 nr;
|
||||
u32 regs;
|
||||
u32 bufregs;
|
||||
|
||||
dma_addr_t pbuf[DMA_MAX_BUFS];
|
||||
u8 *vbuf[DMA_MAX_BUFS];
|
||||
u32 num;
|
||||
u32 size;
|
||||
u32 div;
|
||||
u32 bufreg;
|
||||
|
||||
u32 bufval;
|
||||
|
||||
#ifdef DDB_USE_WORK
|
||||
struct work_struct work;
|
||||
#else
|
||||
@@ -200,7 +226,7 @@ struct ddb_dma {
|
||||
u32 cbuf;
|
||||
u32 coff;
|
||||
};
|
||||
|
||||
|
||||
struct ddb_dvb {
|
||||
struct dvb_adapter *adap;
|
||||
int adap_registered;
|
||||
@@ -216,14 +242,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 +263,7 @@ struct ddb_ci {
|
||||
struct ddb_io {
|
||||
struct ddb_port *port;
|
||||
u32 nr;
|
||||
u32 regs;
|
||||
struct ddb_dma *dma;
|
||||
struct ddb_io *redo;
|
||||
struct ddb_io *redi;
|
||||
@@ -271,6 +299,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 +315,15 @@ 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_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_DVBC2T2_ST (DDB_TUNER_XO2 + 5)
|
||||
|
||||
struct ddb_input *input[2];
|
||||
struct ddb_output *output;
|
||||
@@ -308,10 +338,21 @@ struct mod_base {
|
||||
u32 frequency;
|
||||
u32 flat_start;
|
||||
u32 flat_end;
|
||||
|
||||
spinlock_t temp_lock;
|
||||
int OverTemperatureError;
|
||||
u8 temp_tab[11];
|
||||
};
|
||||
|
||||
struct mod_state {
|
||||
struct ddb_mod {
|
||||
struct ddb_port *port;
|
||||
u32 nr;
|
||||
u32 regs;
|
||||
|
||||
u32 frequency;
|
||||
u32 modulation;
|
||||
u32 symbolrate;
|
||||
|
||||
u64 obitrate;
|
||||
u64 ibitrate;
|
||||
u32 pcr_correction;
|
||||
@@ -367,7 +408,7 @@ 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;
|
||||
@@ -389,12 +430,12 @@ struct ddb {
|
||||
struct pci_dev *pdev;
|
||||
struct platform_device *pfdev;
|
||||
struct device *dev;
|
||||
|
||||
|
||||
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;
|
||||
@@ -405,10 +446,11 @@ struct ddb {
|
||||
struct ddb_input input[DDB_MAX_INPUT];
|
||||
struct ddb_output output[DDB_MAX_OUTPUT];
|
||||
struct dvb_adapter adap[DDB_MAX_INPUT];
|
||||
struct ddb_dma dma[DDB_MAX_INPUT + DDB_MAX_OUTPUT];
|
||||
|
||||
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;
|
||||
@@ -428,7 +470,7 @@ struct ddb {
|
||||
u8 tsbuf[TS_CAPTURE_LEN];
|
||||
|
||||
struct mod_base mod_base;
|
||||
struct mod_state mod[10];
|
||||
struct ddb_mod mod[24];
|
||||
};
|
||||
|
||||
static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr)
|
||||
@@ -454,36 +496,38 @@ static inline u32 ddbreadl0(struct ddb_link *link, u32 adr)
|
||||
#if 0
|
||||
static inline void gtlw(struct ddb_link *link)
|
||||
{
|
||||
u32 count = 0;
|
||||
static u32 max = 0;
|
||||
u32 count = 0;
|
||||
static u32 max;
|
||||
|
||||
while (1 & ddbreadl0(link, link->regs + 0x10)) {
|
||||
if (++count == 1024) {
|
||||
printk("LTO\n");
|
||||
while (1 & ddbreadl0(link, link->regs + 0x10)) {
|
||||
if (++count == 1024) {
|
||||
pr_info("LTO\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count > max) {
|
||||
max = count;
|
||||
printk("TO=%u\n", max);
|
||||
pr_info("TO=%u\n", max);
|
||||
}
|
||||
if (ddbreadl0(link, link->regs + 0x10) & 0x8000)
|
||||
printk("link error\n");
|
||||
pr_err("link error\n");
|
||||
}
|
||||
#else
|
||||
static inline void gtlw(struct ddb_link *link)
|
||||
{
|
||||
while (1 & ddbreadl0(link, link->regs + 0x10));
|
||||
while (1 & ddbreadl0(link, link->regs + 0x10))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static u32 ddblreadl(struct ddb_link *link, u32 adr)
|
||||
{
|
||||
if (unlikely(link->nr)) {
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
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);
|
||||
@@ -499,8 +543,8 @@ static void ddblwritel(struct ddb_link *link, u32 val, u32 adr)
|
||||
{
|
||||
if (unlikely(link->nr)) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
|
||||
ddbwritel0(link, val, link->regs + 0x18);
|
||||
@@ -510,15 +554,16 @@ static void ddblwritel(struct ddb_link *link, u32 val, u32 adr)
|
||||
}
|
||||
writel(val, (char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
#endif
|
||||
|
||||
static u32 ddbreadl(struct ddb *dev, u32 adr)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000)) {
|
||||
unsigned long flags;
|
||||
u32 val, l = (adr >> DDB_LINK_SHIFT);
|
||||
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);
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
|
||||
ddbwritel0(link, 3, link->regs + 0x10);
|
||||
@@ -536,8 +581,8 @@ static void ddbwritel(struct ddb *dev, u32 val, u32 adr)
|
||||
unsigned long flags;
|
||||
u32 l = (adr >> DDB_LINK_SHIFT);
|
||||
struct ddb_link *link = &dev->link[l];
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
|
||||
ddbwritel0(link, val, link->regs + 0x18);
|
||||
@@ -705,6 +750,6 @@ void ddbridge_mod_rate_handler(unsigned long data);
|
||||
|
||||
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
|
||||
|
||||
#define DDBRIDGE_VERSION "0.9.20"
|
||||
#define DDBRIDGE_VERSION "0.9.24"
|
||||
|
||||
#endif
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* octonet.c: Digital Devices network tuner driver
|
||||
*
|
||||
* Copyright (C) 2012-15 Digital Devices GmbH
|
||||
* Copyright (C) 2012-16 Digital Devices GmbH
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
*
|
||||
@@ -25,7 +25,11 @@
|
||||
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-regs.h"
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
|
||||
#include <asm-generic/pci-dma-compat.h>
|
||||
#else
|
||||
#include <linux/pci-dma-compat.h>
|
||||
#endif
|
||||
|
||||
static int adapter_alloc = 3;
|
||||
module_param(adapter_alloc, int, 0444);
|
||||
@@ -34,21 +38,13 @@ MODULE_PARM_DESC(adapter_alloc,
|
||||
|
||||
#include "ddbridge-core.c"
|
||||
|
||||
static struct ddb_regset octopus_i2c = {
|
||||
.base = 0x80,
|
||||
.num = 0x04,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_i2c_buf = {
|
||||
.base = 0x1000,
|
||||
.num = 0x04,
|
||||
.size = 0x200,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_net_map = {
|
||||
.irq_version = 1,
|
||||
.irq_base_i2c = 0,
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
.input = &octopus_input,
|
||||
.output = &octopus_output,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_gtl = {
|
||||
@@ -58,8 +54,13 @@ static struct ddb_regset octopus_gtl = {
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_net_gtl = {
|
||||
.irq_version = 1,
|
||||
.irq_base_i2c = 0,
|
||||
.irq_base_gtl = 10,
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
.input = &octopus_input,
|
||||
.output = &octopus_output,
|
||||
.gtl = &octopus_gtl,
|
||||
};
|
||||
|
||||
@@ -113,16 +114,17 @@ 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);
|
||||
platform_set_drvdata(pdev, 0);
|
||||
return 0;
|
||||
@@ -133,7 +135,6 @@ static int __init octonet_probe(struct platform_device *pdev)
|
||||
struct ddb *dev;
|
||||
struct resource *regs;
|
||||
int irq;
|
||||
int i;
|
||||
|
||||
dev = vzalloc(sizeof(struct ddb));
|
||||
if (!dev)
|
||||
@@ -175,16 +176,16 @@ static int __init octonet_probe(struct platform_device *pdev)
|
||||
dev->link[0].info = &ddb_octonet_gtl;
|
||||
else
|
||||
dev->link[0].info = &ddb_octonet_tbd;
|
||||
|
||||
pr_info("HW %08x REGMAP %08x\n", dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
|
||||
pr_info("MAC %08x DEVID %08x\n", dev->link[0].ids.mac, dev->link[0].ids.devid);
|
||||
|
||||
pr_info("HW %08x REGMAP %08x\n",
|
||||
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
|
||||
pr_info("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)
|
||||
@@ -233,7 +234,7 @@ static __init int init_octonet(void)
|
||||
int res;
|
||||
|
||||
pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION
|
||||
", Copyright (C) 2010-15 Digital Devices GmbH\n");
|
||||
", Copyright (C) 2010-16 Digital Devices GmbH\n");
|
||||
res = ddb_class_create();
|
||||
if (res)
|
||||
return res;
|
||||
|
22
docs/ci
22
docs/ci
@@ -1,3 +1,5 @@
|
||||
- General Information
|
||||
|
||||
The caX device associated with a CI device behaves just like any other
|
||||
caX interface. You usually use it through a library like libdvben50221
|
||||
which is part of the dvb-apps package available at linuxtv.org.
|
||||
@@ -26,6 +28,24 @@ use the new interface.
|
||||
See docs/redirect for more info.
|
||||
|
||||
|
||||
- Clock Speed
|
||||
|
||||
The normal clock speed for the TS output is 72 MHz wich is the standard
|
||||
speed used for CI.
|
||||
|
||||
Packets are sent with an adjustable gap between the packets.
|
||||
The gap size is (gap value * 2) + 4 or 0 if the gap is disabled.
|
||||
So, the standard gap value of 4 leads to a gap of 12 bytes which means
|
||||
that the effective data rate is (72*188)/200 = 67.68 MBits/s.
|
||||
|
||||
Depending on the hardware, the clock speed can be changed with the
|
||||
ci_bitrate module parameter:
|
||||
|
||||
- Octopus CI, Octopus CI S2 Pro : supported
|
||||
|
||||
- old CI single flex modules: supported
|
||||
|
||||
- new dual CI flex module: not yet supported, use the standard 72000 kHz
|
||||
|
||||
|
||||
|
||||
Valid ranges for are from ... to 96000 KHz.
|
||||
|
@@ -955,6 +955,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
|
||||
}
|
||||
|
||||
c->stream_id = NO_STREAM_ID_FILTER;
|
||||
c->pls = NO_SCRAMBLING_CODE;
|
||||
|
||||
switch (c->delivery_system) {
|
||||
case SYS_DVBS:
|
||||
@@ -1031,6 +1032,7 @@ static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
|
||||
_DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0),
|
||||
_DTV_CMD(DTV_LNA, 1, 0),
|
||||
_DTV_CMD(DTV_INPUT, 1, 0),
|
||||
_DTV_CMD(DTV_PLS, 1, 0),
|
||||
|
||||
/* Get */
|
||||
_DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
|
||||
@@ -1462,6 +1464,10 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
|
||||
tvp->u.buffer.len = 4;
|
||||
break;
|
||||
|
||||
case DTV_PLS:
|
||||
tvp->u.data = c->pls;
|
||||
break;
|
||||
|
||||
/* Fill quality measures */
|
||||
case DTV_STAT_SIGNAL_STRENGTH:
|
||||
tvp->u.st = c->strength;
|
||||
@@ -1901,6 +1907,10 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
|
||||
r = fe->ops.set_input(fe, c->input);
|
||||
break;
|
||||
|
||||
case DTV_PLS:
|
||||
c->pls = tvp->u.data;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@@ -397,6 +397,7 @@ struct dtv_frontend_properties {
|
||||
|
||||
u32 lna;
|
||||
s32 input;
|
||||
u32 pls;
|
||||
|
||||
/* statistics data */
|
||||
struct dtv_fe_stats strength;
|
||||
|
@@ -35,8 +35,11 @@
|
||||
#include <asm/div64.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_math.h"
|
||||
#include "cxd2843.h"
|
||||
|
||||
#define Log10x100(x) ((s32)(((((u64) intlog2(x) * 0x1e1a5e2e) >> 47 ) + 1) >> 1))
|
||||
|
||||
#define USE_ALGO 1
|
||||
|
||||
enum demod_type { CXD2843, CXD2837, CXD2838 };
|
||||
@@ -329,7 +332,7 @@ static inline u32 MulDiv32(u32 a, u32 b, u32 c)
|
||||
static int read_tps(struct cxd_state *state, u8 *tps)
|
||||
{
|
||||
if (state->last_status != 0x1f)
|
||||
return 0;
|
||||
return -1;
|
||||
|
||||
freeze_regst(state);
|
||||
readregst_unlocked(state, 0x10, 0x2f, tps, 7);
|
||||
@@ -337,6 +340,63 @@ static int read_tps(struct cxd_state *state, u8 *tps)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read DVBT2 OFDM Info */
|
||||
/* OFDMInfo[0] [5] OFDM_MIXED */
|
||||
/* OFDMInfo[0] [4] OFDM_MISO */
|
||||
/* OFDMInfo[0] [2:0] OFDM_FFTSIZE[2:0] */
|
||||
/* OFDMInfo[1] [6:4] OFDM_GI[2:0] */
|
||||
/* OFDMInfo[1] [2:0] OFDM_PP[2:0] */
|
||||
/* OFDMInfo[2] [4] OFDM_BWT_EXT */
|
||||
/* OFDMInfo[2] [3:0] OFDM_PAPR[3:0] */
|
||||
/* OFDMInfo[3] [3:0] OFDM_NDSYM[11:8] */
|
||||
/* OFDMInfo[4] [7:0] OFDM_NDSYM[7:0] */
|
||||
|
||||
static int read_t2_ofdm_info(struct cxd_state *state, u8 *ofdm)
|
||||
{
|
||||
if (state->last_status != 0x1f)
|
||||
return -1;
|
||||
|
||||
freeze_regst(state);
|
||||
readregst_unlocked(state, 0x20, 0x5c, ofdm, 5);
|
||||
unfreeze_regst(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read DVBT2 QAM,
|
||||
Data PLP
|
||||
0 [7:0] L1POST_PLP_ID[7:0]
|
||||
1 [2:0] L1POST_PLP_TYPE[2:0]
|
||||
2 [4:0] L1POST_PLP_PAYLOAD_TYPE[4:0]
|
||||
3 [0] L1POST_FF_FLAG
|
||||
4 [2:0] L1POST_FIRST_RF_IDX[2:0]
|
||||
5 [7:0] L1POST_FIRST_FRAME_IDX[7:0]
|
||||
6 [7:0] L1POST_PLP_GROUP_ID[7:0]
|
||||
7 [2:0] L1POST_PLP_COD[2:0]
|
||||
8 [2:0] L1POST_PLP_MOD[2:0]
|
||||
9 [0] L1POST_PLP_ROTATION
|
||||
10 [1:0] L1POST_PLP_FEC_TYPE[1:0]
|
||||
11 [1:0] L1POST_PLP_NUM_BLOCKS_MAX[9:8]
|
||||
12 [7:0] L1POST_PLP_NUM_BLOCKS_MAX[7:0]
|
||||
13 [7:0] L1POST_FRAME_INTERVAL[7:0]
|
||||
14 [7:0] L1POST_TIME_IL_LENGTH[7:0]
|
||||
15 [0] L1POST_TIME_IL_TYPE
|
||||
16 [0] L1POST_IN_BAND_FLAG
|
||||
17 [7:0] L1POST_RESERVED_1[15:8]
|
||||
18 [7:0] L1POST_RESERVED_1[7:0]
|
||||
19-37 same for common PLP
|
||||
*/
|
||||
|
||||
static int read_t2_tlp_info(struct cxd_state *state, u8 off, u8 count, u8 *tlp)
|
||||
{
|
||||
if (state->last_status != 0x1f)
|
||||
return -1;
|
||||
|
||||
freeze_regst(state);
|
||||
readregst_unlocked(state, 0x22, 0x54 + off, tlp, count);
|
||||
unfreeze_regst(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Active_to_Sleep(struct cxd_state *state)
|
||||
{
|
||||
if (state->state <= Sleep)
|
||||
@@ -1008,6 +1068,15 @@ static void release(struct dvb_frontend *fe)
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static int sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
struct cxd_state *state = fe->demodulator_priv;
|
||||
|
||||
Stop(state);
|
||||
ShutDown(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Start(struct cxd_state *state, u32 IntermediateFrequency)
|
||||
{
|
||||
enum demod_state newDemodState = Unknown;
|
||||
@@ -1165,7 +1234,7 @@ static int set_parameters(struct dvb_frontend *fe)
|
||||
fe->ops.tuner_ops.set_params(fe);
|
||||
state->bandwidth = fe->dtv_property_cache.bandwidth_hz;
|
||||
state->bw = (fe->dtv_property_cache.bandwidth_hz + 999999) / 1000000;
|
||||
if (fe->dtv_property_cache.stream_id == 0xffffffff) {
|
||||
if (fe->dtv_property_cache.stream_id == NO_STREAM_ID_FILTER) {
|
||||
state->DataSliceID = 0xffffffff;
|
||||
state->plp = 0xffffffff;
|
||||
} else {
|
||||
@@ -1260,11 +1329,40 @@ static int get_tune_settings(struct dvb_frontend *fe,
|
||||
}
|
||||
}
|
||||
|
||||
static int read_snr(struct dvb_frontend *fe, u16 *snr);
|
||||
|
||||
static int get_stats(struct dvb_frontend *fe)
|
||||
{
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u16 val;
|
||||
s64 str;
|
||||
|
||||
if (fe->ops.tuner_ops.get_rf_strength)
|
||||
fe->ops.tuner_ops.get_rf_strength(fe, &val);
|
||||
else
|
||||
val = 0;
|
||||
|
||||
str = 1000 * (s64) (s16) val;
|
||||
str -= 108750;
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].uvalue = str;
|
||||
|
||||
read_snr(fe, &val);
|
||||
p->cnr.len = 1;
|
||||
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->cnr.stat[0].uvalue = 100 * (s64) (s16) val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
{
|
||||
struct cxd_state *state = fe->demodulator_priv;
|
||||
u8 rdata;
|
||||
|
||||
get_stats(fe);
|
||||
|
||||
*status = 0;
|
||||
switch (state->state) {
|
||||
case ActiveC:
|
||||
@@ -1277,6 +1375,12 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
if (rdata & 0x20)
|
||||
*status |= 0x1f;
|
||||
}
|
||||
if (*status == 0x1f && state->FirstTimeLock) {
|
||||
readregst(state, 0x40, 0x19, &rdata, 1);
|
||||
rdata &= 0x07;
|
||||
state->BERScaleMax = ( rdata < 2 ) ? 18 : 19;
|
||||
state->FirstTimeLock = 0;
|
||||
}
|
||||
break;
|
||||
case ActiveT:
|
||||
readregst(state, 0x10, 0x10, &rdata, 1);
|
||||
@@ -1287,6 +1391,16 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
if (rdata & 0x20)
|
||||
*status |= 0x1f;
|
||||
}
|
||||
if (*status == 0x1f && state->FirstTimeLock) {
|
||||
u8 tps[7];
|
||||
|
||||
read_tps(state, tps);
|
||||
state->BERScaleMax =
|
||||
(((tps[0] >> 6) & 0x03) < 2 ) ? 17 : 18;
|
||||
if ((tps[0] & 7) < 2)
|
||||
state->BERScaleMax--;
|
||||
state->FirstTimeLock = 0;
|
||||
}
|
||||
break;
|
||||
case ActiveT2:
|
||||
readregst(state, 0x20, 0x10, &rdata, 1);
|
||||
@@ -1333,6 +1447,12 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
if (rdata & 0x01)
|
||||
*status |= 0x18;
|
||||
}
|
||||
if (*status == 0x1f && state->FirstTimeLock) {
|
||||
/* readregst(state, 0x40, 0x19, &rdata, 1); */
|
||||
/* rdata &= 0x07; */
|
||||
/* state->BERScaleMax = ( rdata < 2 ) ? 18 : 19; */
|
||||
state->FirstTimeLock = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1371,8 +1491,44 @@ static int get_ber_t(struct cxd_state *state, u32 *n, u32 *d)
|
||||
|
||||
static int get_ber_t2(struct cxd_state *state, u32 *n, u32 *d)
|
||||
{
|
||||
u8 BERRegs[4];
|
||||
u8 Scale;
|
||||
u8 FECType;
|
||||
u8 CodeRate;
|
||||
static const u32 nBCHBitsLookup[2][8] = {
|
||||
/* R1_2 R3_5 R2_3 R3_4 R4_5 R5_6 R1_3 R2_5 */
|
||||
{7200, 9720, 10800, 11880, 12600, 13320, 5400, 6480}, /* 16K FEC */
|
||||
{32400, 38880, 43200, 48600, 51840, 54000, 21600, 25920} /* 64k FEC */
|
||||
};
|
||||
|
||||
*n = 0;
|
||||
*d = 1;
|
||||
freeze_regst(state);
|
||||
readregst(state, 0x24, 0x40, BERRegs, 4);
|
||||
readregst(state, 0x22, 0x5e, &FECType, 1);
|
||||
readregst(state, 0x22, 0x5b, &CodeRate, 1);
|
||||
|
||||
FECType &= 0x03;
|
||||
CodeRate &= 0x07;
|
||||
unfreeze_regst(state);
|
||||
if (FECType > 1)
|
||||
return 0;
|
||||
|
||||
|
||||
readregst(state, 0x20, 0x72, &Scale, 1);
|
||||
Scale &= 0x0F;
|
||||
if (BERRegs[0] & 0x01) {
|
||||
state->LastBERNominator = (((u32) BERRegs[1] & 0x3F) << 16) |
|
||||
(((u32) BERRegs[2]) << 8) | BERRegs[3];
|
||||
state->LastBERDenominator = nBCHBitsLookup[FECType][CodeRate] << Scale;
|
||||
if (state->LastBERNominator < 256 &&
|
||||
Scale < state->BERScaleMax) {
|
||||
writebitst(state, 0x20, 0x72, Scale + 1, 0x0F);
|
||||
} else if (state->LastBERNominator > 512 && Scale > 8)
|
||||
writebitst(state, 0x20, 0x72, Scale - 1, 0x0F);
|
||||
}
|
||||
*n = state->LastBERNominator;
|
||||
*d = state->LastBERDenominator;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1421,7 +1577,8 @@ static int get_ber_it(struct cxd_state *state, u32 *n, u32 *d)
|
||||
static int read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
{
|
||||
struct cxd_state *state = fe->demodulator_priv;
|
||||
u32 n, d;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 n = 0, d = 1;
|
||||
int s = 0;
|
||||
|
||||
*ber = 0;
|
||||
@@ -1446,7 +1603,15 @@ static int read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||
}
|
||||
if (s)
|
||||
return s;
|
||||
|
||||
|
||||
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;
|
||||
if (d)
|
||||
*ber = (n * 1000) / d;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1459,57 +1624,63 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 Log10x100(u32 x)
|
||||
{
|
||||
static u32 LookupTable[100] = {
|
||||
101157945, 103514217, 105925373, 108392691, 110917482,
|
||||
113501082, 116144861, 118850223, 121618600, 124451461,
|
||||
127350308, 130316678, 133352143, 136458314, 139636836,
|
||||
142889396, 146217717, 149623566, 153108746, 156675107,
|
||||
160324539, 164058977, 167880402, 171790839, 175792361,
|
||||
179887092, 184077200, 188364909, 192752491, 197242274,
|
||||
201836636, 206538016, 211348904, 216271852, 221309471,
|
||||
226464431, 231739465, 237137371, 242661010, 248313311,
|
||||
254097271, 260015956, 266072506, 272270131, 278612117,
|
||||
285101827, 291742701, 298538262, 305492111, 312607937,
|
||||
319889511, 327340695, 334965439, 342767787, 350751874,
|
||||
358921935, 367282300, 375837404, 384591782, 393550075,
|
||||
402717034, 412097519, 421696503, 431519077, 441570447,
|
||||
451855944, 462381021, 473151259, 484172368, 495450191,
|
||||
506990708, 518800039, 530884444, 543250331, 555904257,
|
||||
568852931, 582103218, 595662144, 609536897, 623734835,
|
||||
638263486, 653130553, 668343918, 683911647, 699841996,
|
||||
716143410, 732824533, 749894209, 767361489, 785235635,
|
||||
803526122, 822242650, 841395142, 860993752, 881048873,
|
||||
901571138, 922571427, 944060876, 966050879, 988553095,
|
||||
};
|
||||
s32 y;
|
||||
int i;
|
||||
|
||||
if (x == 0)
|
||||
return 0;
|
||||
y = 800;
|
||||
if (x >= 1000000000) {
|
||||
x /= 10;
|
||||
y += 100;
|
||||
}
|
||||
|
||||
while (x < 100000000) {
|
||||
x *= 10;
|
||||
y -= 100;
|
||||
}
|
||||
i = 0;
|
||||
while (i < 100 && x > LookupTable[i])
|
||||
i += 1;
|
||||
y += i;
|
||||
return y;
|
||||
}
|
||||
|
||||
#if 0
|
||||
+NTSTATUS CCXD2843ER::GetT2PLPIds(DD_T2_PLPIDS* pT2_PLPIDS)
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
- *pReturned = 0;
|
||||
+
|
||||
if( m_DemodState != ActiveT2 ) return STATUS_NOT_IMPLEMENTED;
|
||||
- if( m_LastLockStatus < TSLock || m_LastLockStatus == Unlock ) return status;
|
||||
+ if( m_LastLockStatus < TSLock ) return status;
|
||||
|
||||
do
|
||||
{
|
||||
+ BYTE tmp;
|
||||
+
|
||||
CHK_ERROR(FreezeRegsT());
|
||||
|
||||
+ CHK_ERROR(ReadRegT(0x20,0x5C,&tmp)); // OFDM Info
|
||||
+
|
||||
+ if( tmp & 0x20 ) pT2_PLPIDS->Flags |= DD_T2_PLPIDS_FEF;
|
||||
+ if( m_T2Profile == T2P_Lite ) pT2_PLPIDS->Flags |= DD_T2_PLPIDS_LITE;
|
||||
+
|
||||
+ CHK_ERROR(ReadRegT(0x22,0x54,&tmp));
|
||||
+ pT2_PLPIDS->PLPID = tmp;
|
||||
+
|
||||
+ CHK_ERROR(ReadRegT(0x22,0x54 + 19 + 13,&tmp)); // Interval
|
||||
+ if( tmp > 0 )
|
||||
+ {
|
||||
+ CHK_ERROR(ReadRegT(0x22,0x54 + 19,&tmp));
|
||||
+ pT2_PLPIDS->CommonPLPID = tmp;
|
||||
+ }
|
||||
+
|
||||
BYTE nPids = 0;
|
||||
CHK_ERROR(ReadRegT(0x22,0x7F,&nPids));
|
||||
|
||||
- pValues[0] = nPids;
|
||||
- if( nPids >= nValues ) nPids = BYTE(nValues-1);
|
||||
+ pT2_PLPIDS->NumPLPS = nPids;
|
||||
+ CHK_ERROR(ReadRegT(0x22,0x80,&pT2_PLPIDS->PLPList[0], nPids > 128 ? 128 : nPids));
|
||||
|
||||
- CHK_ERROR(ReadRegT(0x22,0x80,&pValues[1], nPids > 128 ? 128 : nPids));
|
||||
-
|
||||
if( nPids > 128 )
|
||||
{
|
||||
- CHK_ERROR(ReadRegT(0x23,0x10,&pValues[129], nPids - 128));
|
||||
+ CHK_ERROR(ReadRegT(0x23,0x10,&pT2_PLPIDS->PLPList[128], nPids - 128));
|
||||
}
|
||||
|
||||
- *pReturned = nPids + 1;
|
||||
+
|
||||
}
|
||||
while(0);
|
||||
UnFreezeRegsT();
|
||||
|
||||
static void GetPLPIds(struct cxd_state *state, u32 nValues,
|
||||
u8 *Values, u32 *Returned)
|
||||
{
|
||||
u8 nPids = 0;
|
||||
u8 nPids = 0, tmp;
|
||||
|
||||
*Returned = 0;
|
||||
if (state->state != ActiveT2)
|
||||
@@ -1549,7 +1720,7 @@ static void GetSignalToNoiseIT(struct cxd_state *state, u32 *SignalToNoise)
|
||||
reg = (Data[0] << 8) | Data[1];
|
||||
if (reg > 51441)
|
||||
reg = 51441;
|
||||
|
||||
|
||||
if (state->bw == 8) {
|
||||
if (reg > 1143)
|
||||
reg = 1143;
|
||||
@@ -1645,6 +1816,7 @@ static void GetSignalToNoiseC(struct cxd_state *state, u32 *SignalToNoise)
|
||||
static int read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
{
|
||||
struct cxd_state *state = fe->demodulator_priv;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u32 SNR = 0;
|
||||
|
||||
*snr = 0;
|
||||
@@ -1671,6 +1843,9 @@ static int read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||
break;
|
||||
}
|
||||
*snr = SNR;
|
||||
p->cnr.len = 1;
|
||||
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->cnr.stat[0].uvalue = 10 * (s64) SNR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1731,6 +1906,110 @@ static int get_algo(struct dvb_frontend *fe)
|
||||
return DVBFE_ALGO_HW;
|
||||
}
|
||||
|
||||
static int get_fe_t2(struct cxd_state *state)
|
||||
{
|
||||
struct dvb_frontend *fe = &state->frontend;
|
||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||
u8 ofdm[5], modcod[2];
|
||||
|
||||
freeze_regst(state);
|
||||
readregst_unlocked(state, 0x20, 0x5c, ofdm, 5);
|
||||
readregst_unlocked(state, 0x22, 0x5b, modcod, 2);
|
||||
unfreeze_regst(state);
|
||||
|
||||
switch (modcod[0] & 0x07) {
|
||||
case 0:
|
||||
p->fec_inner = FEC_1_2;
|
||||
break;
|
||||
case 1:
|
||||
p->fec_inner = FEC_3_5;
|
||||
break;
|
||||
case 2:
|
||||
p->fec_inner = FEC_2_3;
|
||||
break;
|
||||
case 3:
|
||||
p->fec_inner = FEC_3_4;
|
||||
break;
|
||||
case 4:
|
||||
p->fec_inner = FEC_4_5;
|
||||
break;
|
||||
case 5:
|
||||
p->fec_inner = FEC_5_6;
|
||||
break;
|
||||
case 6:
|
||||
p->fec_inner = FEC_1_3;
|
||||
break;
|
||||
case 7:
|
||||
p->fec_inner = FEC_2_5;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (modcod[1] & 0x07) {
|
||||
case 0:
|
||||
p->modulation = QPSK;
|
||||
break;
|
||||
case 1:
|
||||
p->modulation = QAM_16;
|
||||
break;
|
||||
case 2:
|
||||
p->modulation = QAM_64;
|
||||
break;
|
||||
case 3:
|
||||
p->modulation = QAM_256;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ofdm[0] & 0x07) {
|
||||
case 0:
|
||||
p->transmission_mode = TRANSMISSION_MODE_2K;
|
||||
break;
|
||||
case 1:
|
||||
p->transmission_mode = TRANSMISSION_MODE_8K;
|
||||
break;
|
||||
case 2:
|
||||
p->transmission_mode = TRANSMISSION_MODE_4K;
|
||||
break;
|
||||
case 3:
|
||||
p->transmission_mode = TRANSMISSION_MODE_1K;
|
||||
break;
|
||||
case 4:
|
||||
p->transmission_mode = TRANSMISSION_MODE_16K;
|
||||
break;
|
||||
case 5:
|
||||
p->transmission_mode = TRANSMISSION_MODE_32K;
|
||||
break;
|
||||
case 6:
|
||||
p->transmission_mode = TRANSMISSION_MODE_64K;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ((ofdm[1] >> 4) & 0x07) {
|
||||
case 0:
|
||||
p->guard_interval = GUARD_INTERVAL_1_32;
|
||||
break;
|
||||
case 1:
|
||||
p->guard_interval = GUARD_INTERVAL_1_16;
|
||||
break;
|
||||
case 2:
|
||||
p->guard_interval = GUARD_INTERVAL_1_8;
|
||||
break;
|
||||
case 3:
|
||||
p->guard_interval = GUARD_INTERVAL_1_4;
|
||||
break;
|
||||
case 4:
|
||||
p->guard_interval = GUARD_INTERVAL_1_128;
|
||||
break;
|
||||
case 5:
|
||||
p->guard_interval = GUARD_INTERVAL_19_128;
|
||||
break;
|
||||
case 6:
|
||||
p->guard_interval = GUARD_INTERVAL_19_256;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_fe_t(struct cxd_state *state)
|
||||
{
|
||||
struct dvb_frontend *fe = &state->frontend;
|
||||
@@ -1842,7 +2121,7 @@ static int get_fe_c(struct cxd_state *state)
|
||||
freeze_regst(state);
|
||||
readregst_unlocked(state, 0x40, 0x19, &qam, 1);
|
||||
unfreeze_regst(state);
|
||||
p->modulation = qam & 0x07;
|
||||
p->modulation = 1 + (qam & 0x07);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1858,6 +2137,7 @@ static int get_frontend(struct dvb_frontend *fe)
|
||||
get_fe_t(state);
|
||||
break;
|
||||
case ActiveT2:
|
||||
get_fe_t2(state);
|
||||
break;
|
||||
case ActiveC:
|
||||
get_fe_c(state);
|
||||
@@ -1889,9 +2169,10 @@ static struct dvb_frontend_ops common_ops_2843 = {
|
||||
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
|
||||
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
|
||||
FE_CAN_RECOVER | FE_CAN_MUTE_TS
|
||||
FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION
|
||||
},
|
||||
.release = release,
|
||||
.sleep = sleep,
|
||||
.i2c_gate_ctrl = gate_ctrl,
|
||||
.set_frontend = set_parameters,
|
||||
|
||||
@@ -1926,9 +2207,10 @@ static struct dvb_frontend_ops common_ops_2837 = {
|
||||
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
|
||||
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
|
||||
FE_CAN_RECOVER | FE_CAN_MUTE_TS
|
||||
FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION
|
||||
},
|
||||
.release = release,
|
||||
.sleep = sleep,
|
||||
.i2c_gate_ctrl = gate_ctrl,
|
||||
.set_frontend = set_parameters,
|
||||
|
||||
@@ -1955,15 +2237,16 @@ static struct dvb_frontend_ops common_ops_2838 = {
|
||||
.frequency_max = 865000000,
|
||||
.symbol_rate_min = 870000,
|
||||
.symbol_rate_max = 11700000,
|
||||
.caps = FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
|
||||
.caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
|
||||
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||
FE_CAN_FEC_4_5 |
|
||||
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
|
||||
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
|
||||
FE_CAN_RECOVER | FE_CAN_MUTE_TS
|
||||
FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION
|
||||
},
|
||||
.release = release,
|
||||
.sleep = sleep,
|
||||
.i2c_gate_ctrl = gate_ctrl,
|
||||
.set_frontend = set_parameters,
|
||||
|
||||
|
@@ -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
@@ -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)
|
||||
@@ -442,8 +447,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,
|
||||
@@ -504,18 +524,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 +556,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;
|
||||
}
|
||||
|
||||
@@ -559,6 +583,7 @@ static int tune(struct dvb_frontend *fe, bool re_tune,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
#if 0
|
||||
if (*status & FE_HAS_LOCK)
|
||||
return 0;
|
||||
|
||||
@@ -567,6 +592,7 @@ static int tune(struct dvb_frontend *fe, bool re_tune,
|
||||
else
|
||||
p->delivery_system = SYS_DVBS;
|
||||
set_parameters(fe);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -597,6 +623,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,20 +632,69 @@ 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;
|
||||
|
||||
@@ -629,7 +705,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 +717,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;
|
||||
@@ -749,12 +916,14 @@ static int write_fw_segment(struct mxl *state,
|
||||
u32 origSize = 0;
|
||||
u8 *wBufPtr = NULL;
|
||||
u32 blockSize = ((MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH -
|
||||
(MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4;
|
||||
(MXL_HYDRA_I2C_HDR_SIZE +
|
||||
MXL_HYDRA_REG_SIZE_IN_BYTES)) / 4) * 4;
|
||||
u8 wMsgBuffer[MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH -
|
||||
(MXL_HYDRA_I2C_HDR_SIZE + MXL_HYDRA_REG_SIZE_IN_BYTES)];
|
||||
|
||||
do {
|
||||
size = origSize = (((u32)(dataCount + blockSize)) > totalSize) ?
|
||||
size = origSize =
|
||||
(((u32)(dataCount + blockSize)) > totalSize) ?
|
||||
(totalSize - dataCount) : blockSize;
|
||||
|
||||
if (origSize & 3)
|
||||
@@ -775,8 +944,8 @@ static int write_fw_segment(struct mxl *state,
|
||||
return status;
|
||||
}
|
||||
|
||||
static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr, u32 mbinBufferSize)
|
||||
|
||||
static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr,
|
||||
u32 mbinBufferSize)
|
||||
{
|
||||
int status;
|
||||
u32 index = 0;
|
||||
@@ -801,26 +970,31 @@ static int do_firmware_download(struct mxl *state, u8 *mbinBufferPtr, u32 mbinBu
|
||||
__func__, segmentPtr->header.id);
|
||||
return -EINVAL;
|
||||
}
|
||||
segLength = get_big_endian(24, &(segmentPtr->header.len24[0]));
|
||||
segAddress = get_big_endian(32, &(segmentPtr->header.address[0]));
|
||||
segLength = get_big_endian(24,
|
||||
&(segmentPtr->header.len24[0]));
|
||||
segAddress = get_big_endian(32,
|
||||
&(segmentPtr->header.address[0]));
|
||||
|
||||
if (state->base->type == MXL_HYDRA_DEVICE_568) {
|
||||
if ((((segAddress & 0x90760000) == 0x90760000) ||
|
||||
((segAddress & 0x90740000) == 0x90740000)) &&
|
||||
(xcpuFwFlag == MXL_FALSE)) {
|
||||
SET_REG_FIELD_DATA(PRCM_PRCM_CPU_SOFT_RST_N, 1);
|
||||
SET_REG_FIELD_DATA(PRCM_PRCM_CPU_SOFT_RST_N,
|
||||
1);
|
||||
msleep(200);
|
||||
write_register(state, 0x90720000, 0);
|
||||
msleep(10);
|
||||
xcpuFwFlag = MXL_TRUE;
|
||||
}
|
||||
status = write_fw_segment(state, segAddress,
|
||||
segLength, (u8 *) segmentPtr->data);
|
||||
segLength,
|
||||
(u8 *) segmentPtr->data);
|
||||
} else {
|
||||
if (((segAddress & 0x90760000) != 0x90760000) &&
|
||||
((segAddress & 0x90740000) != 0x90740000))
|
||||
status = write_fw_segment(state, segAddress,
|
||||
segLength, (u8 *) segmentPtr->data);
|
||||
segLength,
|
||||
(u8 *) segmentPtr->data);
|
||||
}
|
||||
if (status)
|
||||
return status;
|
||||
@@ -883,14 +1057,17 @@ static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len)
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* Disable clock to Baseband, Wideband, SerDes, Alias ext & Transport modules */
|
||||
status = write_register(state, HYDRA_MODULES_CLK_2_REG, HYDRA_DISABLE_CLK_2);
|
||||
/* Disable clock to Baseband, Wideband, SerDes,
|
||||
Alias ext & Transport modules */
|
||||
status = write_register(state, HYDRA_MODULES_CLK_2_REG,
|
||||
HYDRA_DISABLE_CLK_2);
|
||||
if (status)
|
||||
return status;
|
||||
/* Clear Software & Host interrupt status - (Clear on read) */
|
||||
status = read_register(state, HYDRA_PRCM_ROOT_CLK_REG, ®Data);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = do_firmware_download(state, mbin, mbin_len);
|
||||
if (status)
|
||||
return status;
|
||||
@@ -927,13 +1104,15 @@ static int firmware_download(struct mxl *state, u8 *mbin, u32 mbin_len)
|
||||
|
||||
pr_info("mxl5xx: Hydra FW alive. Hail!\n");
|
||||
|
||||
/* sometimes register values are wrong shortly after first heart beats */
|
||||
/* sometimes register values are wrong shortly
|
||||
after first heart beats */
|
||||
msleep(50);
|
||||
|
||||
devSkuCfg.skuType = state->base->sku_type;
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_DEV_CFG_SKU_CMD, MXL_CMD_WRITE,
|
||||
cmdSize, &devSkuCfg, cmdBuff);
|
||||
status = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
status = send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -963,19 +1142,32 @@ static int cfg_ts_pad_mux(struct mxl *state, MXL_BOOL_E enableSerialTS)
|
||||
case MXL_HYDRA_DEVICE_541S:
|
||||
case MXL_HYDRA_DEVICE_561S:
|
||||
case MXL_HYDRA_DEVICE_581S:
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_14_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_15_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_16_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_17_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_18_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_19_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_20_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_21_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_22_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_23_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_24_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_25_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_26_PINMUX_SEL, padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_14_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_15_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_16_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_17_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_18_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_19_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_20_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_21_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_22_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_23_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_24_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_25_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
status |= SET_REG_FIELD_DATA(PAD_MUX_DIGIO_26_PINMUX_SEL,
|
||||
padMuxValue);
|
||||
break;
|
||||
|
||||
case MXL_HYDRA_DEVICE_544:
|
||||
@@ -1159,7 +1351,7 @@ static int enable_tuner(struct mxl *state, u32 tuner, u32 enable)
|
||||
if (!count)
|
||||
return -1;
|
||||
read_register(state, HYDRA_TUNER_ENABLE_COMPLETE, &val);
|
||||
pr_info("mxl5xx: tuner %u ready = %u\n", tuner , (val >> tuner) & 1);
|
||||
/*pr_info("mxl5xx: tuner %u ready = %u\n", tuner , (val >> tuner) & 1);*/
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
@@ -1194,8 +1386,10 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId,
|
||||
{XPT_TS_CLK_PHASE4}, {XPT_TS_CLK_PHASE5},
|
||||
{XPT_TS_CLK_PHASE6}, {XPT_TS_CLK_PHASE7} };
|
||||
MXL_REG_FIELD_T xpt_lsb_first[MXL_HYDRA_DEMOD_MAX] = {
|
||||
{XPT_LSB_FIRST0}, {XPT_LSB_FIRST1}, {XPT_LSB_FIRST2}, {XPT_LSB_FIRST3},
|
||||
{XPT_LSB_FIRST4}, {XPT_LSB_FIRST5}, {XPT_LSB_FIRST6}, {XPT_LSB_FIRST7} };
|
||||
{XPT_LSB_FIRST0}, {XPT_LSB_FIRST1},
|
||||
{XPT_LSB_FIRST2}, {XPT_LSB_FIRST3},
|
||||
{XPT_LSB_FIRST4}, {XPT_LSB_FIRST5},
|
||||
{XPT_LSB_FIRST6}, {XPT_LSB_FIRST7} };
|
||||
MXL_REG_FIELD_T xpt_sync_byte[MXL_HYDRA_DEMOD_MAX] = {
|
||||
{XPT_SYNC_FULL_BYTE0}, {XPT_SYNC_FULL_BYTE1},
|
||||
{XPT_SYNC_FULL_BYTE2}, {XPT_SYNC_FULL_BYTE3},
|
||||
@@ -1230,16 +1424,17 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId,
|
||||
MXL_REG_FIELD_T mxl561_xpt_ts_sync[MXL_HYDRA_DEMOD_ID_6] = {
|
||||
{PAD_MUX_DIGIO_25_PINMUX_SEL}, {PAD_MUX_DIGIO_20_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_17_PINMUX_SEL}, {PAD_MUX_DIGIO_11_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_08_PINMUX_SEL}, {PAD_MUX_DIGIO_03_PINMUX_SEL} };
|
||||
{PAD_MUX_DIGIO_08_PINMUX_SEL}, {PAD_MUX_DIGIO_03_PINMUX_SEL}};
|
||||
MXL_REG_FIELD_T mxl561_xpt_ts_valid[MXL_HYDRA_DEMOD_ID_6] = {
|
||||
{PAD_MUX_DIGIO_26_PINMUX_SEL}, {PAD_MUX_DIGIO_19_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_18_PINMUX_SEL}, {PAD_MUX_DIGIO_10_PINMUX_SEL},
|
||||
{PAD_MUX_DIGIO_09_PINMUX_SEL}, {PAD_MUX_DIGIO_02_PINMUX_SEL} };
|
||||
{PAD_MUX_DIGIO_09_PINMUX_SEL}, {PAD_MUX_DIGIO_02_PINMUX_SEL}};
|
||||
|
||||
demodId = state->base->ts_map[demodId];
|
||||
|
||||
if (MXL_ENABLE == mpegOutParamPtr->enable) {
|
||||
if (mpegOutParamPtr->mpegMode == MXL_HYDRA_MPEG_MODE_PARALLEL) {
|
||||
if (mpegOutParamPtr->mpegMode ==
|
||||
MXL_HYDRA_MPEG_MODE_PARALLEL) {
|
||||
#if 0
|
||||
for (i = MXL_HYDRA_DEMOD_ID_0; i < MXL_HYDRA_DEMOD_MAX; i++) {
|
||||
mxlStatus |= MxLWare_Hydra_UpdateByMnemonic(devId,
|
||||
@@ -1373,11 +1568,12 @@ static int config_ts(struct mxl *state, MXL_HYDRA_DEMOD_ID_E demodId,
|
||||
}
|
||||
|
||||
if (mpegOutParamPtr->mpegMode != MXL_HYDRA_MPEG_MODE_PARALLEL) {
|
||||
status |= update_by_mnemonic(state,
|
||||
xpt_enable_output[demodId].regAddr,
|
||||
xpt_enable_output[demodId].lsbPos,
|
||||
xpt_enable_output[demodId].numOfBits,
|
||||
mpegOutParamPtr->enable);
|
||||
status |=
|
||||
update_by_mnemonic(state,
|
||||
xpt_enable_output[demodId].regAddr,
|
||||
xpt_enable_output[demodId].lsbPos,
|
||||
xpt_enable_output[demodId].numOfBits,
|
||||
mpegOutParamPtr->enable);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@@ -1415,7 +1611,8 @@ static int config_dis(struct mxl *state, u32 id)
|
||||
|
||||
BUILD_HYDRA_CMD(MXL_HYDRA_DISEQC_CFG_MSG_CMD,
|
||||
MXL_CMD_WRITE, cmdSize, &diseqcMsg, cmdBuff);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE, &cmdBuff[0]);
|
||||
return send_command(state, cmdSize + MXL_HYDRA_CMD_HEADER_SIZE,
|
||||
&cmdBuff[0]);
|
||||
}
|
||||
|
||||
static int load_fw(struct mxl *state, struct mxl5xx_cfg *cfg)
|
||||
|
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
File diff suppressed because it is too large
Load Diff
@@ -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,6 +103,7 @@ struct stv {
|
||||
u16 regoff;
|
||||
u8 i2crpt;
|
||||
u8 tscfgh;
|
||||
u8 tsgeneral;
|
||||
u8 tsspeed;
|
||||
unsigned long tune_time;
|
||||
|
||||
@@ -123,9 +124,17 @@ struct stv {
|
||||
u32 Pilots;
|
||||
enum FE_STV0910_RollOff FERollOff;
|
||||
|
||||
int isStandardBroadcast;
|
||||
int isVCM;
|
||||
|
||||
u32 CurScramblingCode;
|
||||
u32 ScramblingCode;
|
||||
|
||||
u32 LastBERNumerator;
|
||||
u32 LastBERDenominator;
|
||||
u8 BERScale;
|
||||
|
||||
u8 VTH[6];
|
||||
};
|
||||
|
||||
struct SInitTable {
|
||||
@@ -133,9 +142,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 +202,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 +272,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 +474,45 @@ static int GetCurSymbolRate(struct stv *state, u32 *pSymbolRate)
|
||||
|
||||
static int GetSignalParameters(struct stv *state)
|
||||
{
|
||||
u8 tmp;
|
||||
|
||||
if (!state->Started)
|
||||
return -1;
|
||||
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
u8 tmp;
|
||||
u8 rolloff;
|
||||
|
||||
read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp);
|
||||
state->ModCod = (enum FE_STV0910_ModCod) ((tmp & 0x7c) >> 2);
|
||||
state->Pilots = (tmp & 0x01) != 0;
|
||||
state->FECType = (enum DVBS2_FECType) ((tmp & 0x02) >> 1);
|
||||
|
||||
#if 0
|
||||
read_reg(state, RSTV0910_P2_TMGOBS + state->regoff, &rolloff);
|
||||
rolloff = rolloff >> 6;
|
||||
state->FERollOff = (enum FE_STV0910_RollOff) rolloff;
|
||||
|
||||
#endif
|
||||
} else if (state->ReceiveMode == Mode_DVBS) {
|
||||
/* todo */
|
||||
read_reg(state, RSTV0910_P2_VITCURPUN + state->regoff, &tmp);
|
||||
state->PunctureRate = FEC_NONE;
|
||||
switch (tmp & 0x1F) {
|
||||
case 0x0d:
|
||||
state->PunctureRate = FEC_1_2;
|
||||
break;
|
||||
case 0x12:
|
||||
state->PunctureRate = FEC_2_3;
|
||||
break;
|
||||
case 0x15:
|
||||
state->PunctureRate = FEC_3_4;
|
||||
break;
|
||||
case 0x18:
|
||||
state->PunctureRate = FEC_5_6;
|
||||
break;
|
||||
case 0x1A:
|
||||
state->PunctureRate = FEC_7_8;
|
||||
break;
|
||||
}
|
||||
state->isVCM = 0;
|
||||
state->isStandardBroadcast = 1;
|
||||
state->FERollOff = FE_SAT_35;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -485,18 +528,20 @@ static int TrackingOptimization(struct stv *state)
|
||||
|
||||
switch (state->ReceiveMode) {
|
||||
case Mode_DVBS:
|
||||
tmp |= 0x40; break;
|
||||
tmp |= 0x40;
|
||||
break;
|
||||
case Mode_DVBS2:
|
||||
tmp |= 0x80; break;
|
||||
tmp |= 0x80;
|
||||
break;
|
||||
default:
|
||||
tmp |= 0xC0; break;
|
||||
tmp |= 0xC0;
|
||||
break;
|
||||
}
|
||||
write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, tmp);
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
/* force to PRE BCH Rate */
|
||||
write_reg(state, RSTV0910_P2_ERRCTRL1 + state->regoff,
|
||||
BER_SRC_S2 | state->BERScale);
|
||||
/*Disable Reed-Solomon */
|
||||
write_shared_reg(state, RSTV0910_TSTTSRS, state->nr ? 0x02 : 0x01, 0x03);
|
||||
|
||||
if (state->FECType == DVBS2_64K) {
|
||||
u8 aclc = get_optim_cloop(state, state->ModCod,
|
||||
@@ -523,40 +568,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 +631,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;
|
||||
}
|
||||
|
||||
@@ -670,11 +708,12 @@ static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType)
|
||||
return 64800;
|
||||
}
|
||||
|
||||
static int GetBitErrorRateS2(struct stv *state, u32 *BERNumerator,
|
||||
static int GetBitErrorRateS2(struct stv *state,
|
||||
u32 *BERNumerator,
|
||||
u32 *BERDenominator)
|
||||
{
|
||||
u8 Regs[3];
|
||||
|
||||
|
||||
int status = read_regs(state, RSTV0910_P2_ERRCNT12 + state->regoff,
|
||||
Regs, 3);
|
||||
|
||||
@@ -812,12 +851,118 @@ static int Stop(struct stv *state)
|
||||
}
|
||||
|
||||
|
||||
static int init_search_param(struct stv *state)
|
||||
{
|
||||
u8 tmp;
|
||||
|
||||
read_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, &tmp);
|
||||
tmp |= 0x20; // Filter_en (no effect if SIS=non-MIS
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL1 + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, &tmp);
|
||||
tmp &= ~0x02; // frame mode = 0
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff, tmp);
|
||||
|
||||
write_reg(state, RSTV0910_P2_UPLCCST0 + state->regoff, 0xe0);
|
||||
write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0x00);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, &tmp);
|
||||
tmp &= ~0x01; // nosync = 0, in case next signal is standard TS
|
||||
write_reg(state, RSTV0910_P2_TSSTATEM + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSCFGL + state->regoff, &tmp);
|
||||
tmp &= ~0x04; // embindvb = 0
|
||||
write_reg(state, RSTV0910_P2_TSCFGL + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, &tmp);
|
||||
tmp &= ~0x80; // syncbyte = 0
|
||||
write_reg(state, RSTV0910_P2_TSINSDELH + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, &tmp);
|
||||
tmp &= ~0x08; // token = 0
|
||||
write_reg(state, RSTV0910_P2_TSINSDELM + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, &tmp);
|
||||
tmp &= ~0x30; // hysteresis threshold = 0
|
||||
write_reg(state, RSTV0910_P2_TSDLYSET2 + state->regoff, tmp);
|
||||
|
||||
read_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, &tmp);
|
||||
tmp = (tmp & ~0x30) | 0x10; // isi obs mode = 1, observe min ISI
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL0 + state->regoff, tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int EnablePunctureRate(struct stv *state, enum fe_code_rate rate)
|
||||
{
|
||||
switch(rate) {
|
||||
case FEC_1_2:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x01);
|
||||
case FEC_2_3:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x02);
|
||||
case FEC_3_4:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x04);
|
||||
case FEC_5_6:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x08);
|
||||
case FEC_7_8:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x20);
|
||||
case FEC_NONE:
|
||||
default:
|
||||
return write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2f);
|
||||
}
|
||||
}
|
||||
|
||||
static int set_vth_default(struct stv *state)
|
||||
{
|
||||
state->VTH[0] = 0xd7;
|
||||
state->VTH[1] = 0x85;
|
||||
state->VTH[2] = 0x58;
|
||||
state->VTH[3] = 0x3a;
|
||||
state->VTH[4] = 0x34;
|
||||
state->VTH[5] = 0x28;
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 0, state->VTH[0]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 1, state->VTH[1]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 2, state->VTH[2]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 3, state->VTH[3]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 4, state->VTH[4]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 5, state->VTH[5]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_vth(struct stv *state)
|
||||
{
|
||||
static struct SLookup VTHLookupTable[] = {
|
||||
{250, 8780}, /*C/N=1.5dB*/
|
||||
{100, 7405}, /*C/N=4.5dB*/
|
||||
{40, 6330}, /*C/N=6.5dB*/
|
||||
{12, 5224}, /*C/N=8.5dB*/
|
||||
{5, 4236} /*C/N=10.5dB*/
|
||||
};
|
||||
int i;
|
||||
u8 tmp[2];
|
||||
int status = read_regs(state, RSTV0910_P2_NNOSDATAT1 + state->regoff, tmp, 2);
|
||||
u16 RegValue = (tmp[0] << 8) | tmp[1];
|
||||
s32 vth = TableLookup(VTHLookupTable, ARRAY_SIZE(VTHLookupTable), RegValue);
|
||||
|
||||
for (i = 0; i < 6; i += 1)
|
||||
if (state->VTH[i] > vth)
|
||||
state->VTH[i] = vth;
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 0, state->VTH[0]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 1, state->VTH[1]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 2, state->VTH[2]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 3, state->VTH[3]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 4, state->VTH[4]);
|
||||
write_reg(state, RSTV0910_P2_VTH12 + state->regoff + 5, state->VTH[5]);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
{
|
||||
s32 Freq;
|
||||
u8 regDMDCFGMD;
|
||||
u16 symb;
|
||||
|
||||
u32 ScramblingCode = 1;
|
||||
|
||||
if (p->symbol_rate < 100000 || p->symbol_rate > 70000000)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -828,6 +973,34 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
if (state->Started)
|
||||
write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x5C);
|
||||
|
||||
init_search_param(state);
|
||||
|
||||
if (p->stream_id != NO_STREAM_ID_FILTER) {
|
||||
/* Backwards compatibility to "crazy" API.
|
||||
PRBS X root cannot be 0, so this should always work.
|
||||
*/
|
||||
if (p->stream_id & 0xffffff00)
|
||||
ScramblingCode = p->stream_id >> 8;
|
||||
write_reg(state, RSTV0910_P2_ISIENTRY + state->regoff, p->stream_id & 0xff);
|
||||
write_reg(state, RSTV0910_P2_ISIBITENA + state->regoff, 0xff);
|
||||
//pr_info("ID=%08x\n", p->stream_id & 0xff);
|
||||
}
|
||||
|
||||
/* props->pls is always gold code ! */
|
||||
if (p->pls != NO_SCRAMBLING_CODE)
|
||||
ScramblingCode = p->pls | 0x40000;
|
||||
|
||||
if (ScramblingCode != state->CurScramblingCode) {
|
||||
write_reg(state, RSTV0910_P2_PLROOT0 + state->regoff,
|
||||
ScramblingCode & 0xff);
|
||||
write_reg(state, RSTV0910_P2_PLROOT1 + state->regoff,
|
||||
(ScramblingCode >> 8) & 0xff);
|
||||
write_reg(state, RSTV0910_P2_PLROOT2 + state->regoff,
|
||||
(ScramblingCode >> 16) & 0x07);
|
||||
state->CurScramblingCode = ScramblingCode;
|
||||
//pr_info("PLS=%08x\n", ScramblingCode);
|
||||
}
|
||||
|
||||
if (p->symbol_rate <= 1000000) { /*SR <=1Msps*/
|
||||
state->DemodTimeout = 3000;
|
||||
state->FecTimeout = 2000;
|
||||
@@ -836,7 +1009,7 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
state->FecTimeout = 1300;
|
||||
} else if (p->symbol_rate <= 5000000) { /*2Msps< SR <=5Msps*/
|
||||
state->DemodTimeout = 1000;
|
||||
state->FecTimeout = 650;
|
||||
state->FecTimeout = 650;
|
||||
} else if (p->symbol_rate <= 10000000) { /*5Msps< SR <=10Msps*/
|
||||
state->DemodTimeout = 700;
|
||||
state->FecTimeout = 350;
|
||||
@@ -863,25 +1036,43 @@ static int Start(struct stv *state, struct dtv_frontend_properties *p)
|
||||
read_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff, ®DMDCFGMD);
|
||||
write_reg(state, RSTV0910_P2_DMDCFGMD + state->regoff,
|
||||
regDMDCFGMD |= 0xC0);
|
||||
|
||||
write_shared_reg(state, RSTV0910_TSTTSRS, state->nr ? 0x02 : 0x01, 0x00);
|
||||
|
||||
/* Disable DSS */
|
||||
write_reg(state, RSTV0910_P2_FECM + state->regoff, 0x00);
|
||||
write_reg(state, RSTV0910_P2_PRVIT + state->regoff, 0x2F);
|
||||
|
||||
EnablePunctureRate(state, FEC_NONE);
|
||||
|
||||
/* 8PSK 3/5, 8PSK 2/3 Poff tracking optimization WA*/
|
||||
write_reg(state, RSTV0910_P2_ACLC2S2Q + state->regoff, 0x0B);
|
||||
write_reg(state, RSTV0910_P2_ACLC2S28 + state->regoff, 0x0A);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S2Q + state->regoff, 0x84);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S28 + state->regoff, 0x84);
|
||||
write_reg(state, RSTV0910_P2_CARHDR + state->regoff, 0x1C);
|
||||
/* Reset demod */
|
||||
write_reg(state, RSTV0910_P2_CARFREQ + state->regoff, 0x79);
|
||||
|
||||
write_reg(state, RSTV0910_P2_ACLC2S216A + state->regoff, 0x29);
|
||||
write_reg(state, RSTV0910_P2_ACLC2S232A + state->regoff, 0x09);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S216A + state->regoff, 0x84);
|
||||
write_reg(state, RSTV0910_P2_BCLC2S232A + state->regoff, 0x84);
|
||||
|
||||
/* Reset CAR3, bug DVBS2->DVBS1 lock*/
|
||||
/* Note: The bit is only pulsed -> no lock on shared register needed */
|
||||
write_reg(state, RSTV0910_TSTRES0, state->nr ? 0x04 : 0x08);
|
||||
write_reg(state, RSTV0910_TSTRES0, 0);
|
||||
|
||||
set_vth_default(state);
|
||||
|
||||
/* Reset demod */
|
||||
write_reg(state, RSTV0910_P2_DMDISTATE + state->regoff, 0x1F);
|
||||
|
||||
write_reg(state, RSTV0910_P2_CARCFG + state->regoff, 0x46);
|
||||
|
||||
Freq = (state->SearchRange / 2000) + 600;
|
||||
if (p->symbol_rate <= 5000000)
|
||||
Freq -= (600 + 80);
|
||||
Freq = (state->SearchRange / 2000) + 80;
|
||||
else
|
||||
Freq = (state->SearchRange / 2000) + 1600;
|
||||
Freq = (Freq << 16) / (state->base->mclk / 1000);
|
||||
|
||||
write_reg(state, RSTV0910_P2_CFRUP1 + state->regoff,
|
||||
@@ -932,26 +1123,36 @@ 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 */
|
||||
|
||||
|
||||
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 +1239,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 +1355,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;
|
||||
|
||||
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) {
|
||||
set_vth(state);
|
||||
//if( Time >= m_DemodTimeout ) *pLockStatus = NEVER_LOCK;
|
||||
*status = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*status |= 0x0f;
|
||||
if (state->ReceiveMode == Mode_None) {
|
||||
state->ReceiveMode = CurReceiveMode;
|
||||
state->DemodLockTime = jiffies;
|
||||
state->FirstTimeLock = 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 +1429,7 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
}
|
||||
|
||||
if (!FECLock)
|
||||
//if( Time >= m_DemodLockTime + m_FecTimeout ) *pLockStatus = NEVER_LOCK;
|
||||
return 0;
|
||||
|
||||
*status |= 0x10;
|
||||
@@ -1099,10 +1438,23 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
u8 tmp;
|
||||
|
||||
state->FirstTimeLock = 0;
|
||||
GetSignalParameters(state);
|
||||
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
/* FSTV0910_P2_MANUALSX_ROLLOFF,
|
||||
ManageMatypeInfo(state);
|
||||
|
||||
#if 0
|
||||
ULONG Bitrate;
|
||||
CSTV0910::GetBitrate(&Bitrate);
|
||||
BYTE newTSSPEED = (Bitrate > 67000000) ? 0x30 : 0x40;
|
||||
if (newTSSPEED != m_TSSPEED)
|
||||
{
|
||||
KdPrintEx((MSG_INFO "_%d " __FUNCTION__ " TSSPEED = %02X\n", m_Instance, newTSSPEED));
|
||||
CHK_ERROR(WriteReg(RSTV0910_P2_TSSPEED + m_DemodOffset, newTSSPEED));
|
||||
m_TSSPEED = newTSSPEED;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (state->ReceiveMode == Mode_DVBS2) {
|
||||
/* FSTV0910_P2_MANUALSX_ROLLOFF,
|
||||
FSTV0910_P2_MANUALS2_ROLLOFF = 0 */
|
||||
state->DEMOD &= ~0x84;
|
||||
write_reg(state, RSTV0910_P2_DEMOD + state->regoff,
|
||||
@@ -1111,11 +1463,13 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
&tmp);
|
||||
/*reset DVBS2 packet delinator error counter */
|
||||
tmp |= 0x40;
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff,
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 +
|
||||
state->regoff,
|
||||
tmp);
|
||||
/*reset DVBS2 packet delinator error counter */
|
||||
tmp &= ~0x40;
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 + state->regoff,
|
||||
write_reg(state, RSTV0910_P2_PDELCTRL2 +
|
||||
state->regoff,
|
||||
tmp);
|
||||
|
||||
state->BERScale = 2;
|
||||
@@ -1138,8 +1492,25 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
|
||||
infinit error count mode )*/
|
||||
write_reg(state, RSTV0910_P2_ERRCTRL2 + state->regoff, 0xc1);
|
||||
|
||||
TrackingOptimization(state);
|
||||
set_vth_default(state);
|
||||
if (state->ReceiveMode == Mode_DVBS)
|
||||
EnablePunctureRate(state, state->PunctureRate);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if( m_isVCM )
|
||||
{
|
||||
// Use highest signaled ModCod for quality
|
||||
BYTE tmp;
|
||||
CHK_ERROR(ReadReg(RSTV0910_P2_DMDMODCOD +
|
||||
m_DemodOffset,&tmp));
|
||||
FE_STV0910_ModCod ModCod =
|
||||
FE_STV0910_ModCod((tmp & 0x7c) >> 2);
|
||||
|
||||
if( ModCod > m_ModCod )
|
||||
m_ModCod = ModCod;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1258,21 +1629,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 +1658,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;
|
||||
}
|
||||
|
||||
@@ -1323,6 +1781,7 @@ static struct dvb_frontend_ops stv0910_ops = {
|
||||
.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,13 +1818,15 @@ 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;
|
||||
|
||||
base = match_base(i2c, cfg->adr);
|
||||
if (base) {
|
||||
@@ -1402,5 +1863,5 @@ fail:
|
||||
EXPORT_SYMBOL_GPL(stv0910_attach);
|
||||
|
||||
MODULE_DESCRIPTION("STV0910 driver");
|
||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||
MODULE_AUTHOR("Ralph und Marcus Metzler, Manfred Voelkel");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -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 {
|
||||
|
@@ -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