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