mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2023-10-10 13:37:43 +02:00
Release 0.9.29
New Hardware, fixes, testet up to kernel 4.11.1
This commit is contained in:
commit
01d35aad26
@ -1,3 +1,7 @@
|
|||||||
|
0.9.29 compiles with most kernels up to 4.11.1
|
||||||
|
|
||||||
|
see git commit messages for newer changes
|
||||||
|
|
||||||
0.9.24 2016.08.03
|
0.9.24 2016.08.03
|
||||||
- suport new V2 modulator cards
|
- suport new V2 modulator cards
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
# DDBridge Driver
|
# DDBridge Driver
|
||||||
|
|
||||||
|
###Patches
|
||||||
|
We can only accept patches which don't break compilation for older kernels (as far back as 2.6.37).
|
||||||
|
|
||||||
###Prepare for Building
|
###Prepare for Building
|
||||||
|
|
||||||
TBD
|
TBD
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
all: cit citin flashprog modt ddtest setmod ddflash setmod2
|
all: cit citin flashprog modt ddtest setmod ddflash setmod2
|
||||||
|
|
||||||
cit: cit.c
|
cit: cit.c
|
||||||
gcc -o cit cit.c -lpthread
|
$(CC) -o cit cit.c -lpthread
|
||||||
|
|
||||||
modt: modt.c
|
modt: modt.c
|
||||||
gcc -o modt modt.c -lpthread
|
$(CC) -o modt modt.c -lpthread
|
||||||
|
|
||||||
setmod: setmod.c
|
setmod: setmod.c
|
||||||
gcc -o setmod setmod.c -I../include/
|
$(CC) -o setmod setmod.c -I../include/
|
||||||
|
|
||||||
setmod2: setmod2.c
|
setmod2: setmod2.c
|
||||||
gcc -o setmod2 setmod2.c -I../include/
|
$(CC) -o setmod2 setmod2.c -I../include/
|
||||||
|
|
||||||
flashprog: flashprog.c
|
flashprog: flashprog.c
|
||||||
gcc -o flashprog flashprog.c
|
$(CC) -o flashprog flashprog.c
|
||||||
|
|
||||||
ddtest: ddtest.c
|
ddtest: ddtest.c
|
||||||
gcc -o ddtest ddtest.c
|
$(CC) -o ddtest ddtest.c
|
||||||
|
|
||||||
ddflash: ddflash.c
|
ddflash: ddflash.c
|
||||||
gcc -o ddflash ddflash.c
|
$(CC) -o ddflash ddflash.c
|
||||||
|
@ -91,6 +91,7 @@ void *get_ts(void *a)
|
|||||||
if (!buf)
|
if (!buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
|
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
|
||||||
|
printf("using %s for reading\n", fname);
|
||||||
fdi = open(fname, O_RDONLY);
|
fdi = open(fname, O_RDONLY);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -122,6 +123,7 @@ int send(void)
|
|||||||
if (!buf)
|
if (!buf)
|
||||||
return -1;
|
return -1;
|
||||||
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
|
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
|
||||||
|
printf("using %s for writing\n", fname);
|
||||||
fdo=open(fname, O_WRONLY);
|
fdo=open(fname, O_WRONLY);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -210,9 +210,13 @@ int main(int argc, char **argv)
|
|||||||
printf("Octopus 35\n");
|
printf("Octopus 35\n");
|
||||||
break;
|
break;
|
||||||
case 0x0003:
|
case 0x0003:
|
||||||
fname="DVBBridgeV1B_DVBBridgeV1B.bit";
|
fname="DVBBridgeV1B_DVBBridgeV1B.fpga";
|
||||||
printf("Octopus\n");
|
printf("Octopus\n");
|
||||||
break;
|
break;
|
||||||
|
case 0x0005:
|
||||||
|
fname="DVBBridgeV2A_DD01_0005_STD.fpga";
|
||||||
|
printf("Octopus Classic\n");
|
||||||
|
break;
|
||||||
case 0x0006:
|
case 0x0006:
|
||||||
fname="DVBBridgeV2A_DD01_0006_STD.fpga";
|
fname="DVBBridgeV2A_DD01_0006_STD.fpga";
|
||||||
printf("CineS2 V7\n");
|
printf("CineS2 V7\n");
|
||||||
@ -249,6 +253,10 @@ int main(int argc, char **argv)
|
|||||||
fname="DVBModulatorV2A_DD01_0210.fpga";
|
fname="DVBModulatorV2A_DD01_0210.fpga";
|
||||||
printf("Modulator V2\n");
|
printf("Modulator V2\n");
|
||||||
break;
|
break;
|
||||||
|
case 0x0220:
|
||||||
|
fname="SDRModulatorV1A_DD01_0220.fpga";
|
||||||
|
printf("SDRModulator\n");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
printf("UNKNOWN\n");
|
printf("UNKNOWN\n");
|
||||||
break;
|
break;
|
||||||
@ -314,6 +322,7 @@ int main(int argc, char **argv)
|
|||||||
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x3C);
|
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x3C);
|
||||||
break;
|
break;
|
||||||
case SPANSION_S25FL116K:
|
case SPANSION_S25FL116K:
|
||||||
|
case SPANSION_S25FL164K:
|
||||||
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C);
|
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -426,7 +426,7 @@ static int flash_detect(struct ddflash *ddf)
|
|||||||
}
|
}
|
||||||
if (ddf->sector_size) {
|
if (ddf->sector_size) {
|
||||||
ddf->buffer = malloc(ddf->sector_size);
|
ddf->buffer = malloc(ddf->sector_size);
|
||||||
printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);
|
//printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);
|
||||||
if (!ddf->buffer)
|
if (!ddf->buffer)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -510,6 +510,11 @@ static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
} else if (!strcasecmp(key, "Version")) {
|
} else if (!strcasecmp(key, "Version")) {
|
||||||
|
if (strchr(val,'.')) {
|
||||||
|
int major = 0, minor = 0;
|
||||||
|
sscanf(val,"%d.%d",&major,&minor);
|
||||||
|
version = (major << 16) + minor;
|
||||||
|
} else
|
||||||
sscanf(val, "%x", &version);
|
sscanf(val, "%x", &version);
|
||||||
} else if (!strcasecmp(key, "Length")) {
|
} else if (!strcasecmp(key, "Length")) {
|
||||||
sscanf(val, "%u", &length);
|
sscanf(val, "%u", &length);
|
||||||
@ -565,8 +570,13 @@ static int update_image(struct ddflash *ddf, char *fn,
|
|||||||
if (res < 0)
|
if (res < 0)
|
||||||
goto out;
|
goto out;
|
||||||
res = flashwrite(ddf, fs, adr, len, fw_off);
|
res = flashwrite(ddf, fs, adr, len, fw_off);
|
||||||
if (res == 0)
|
if (res == 0) {
|
||||||
|
res = flashcmp(ddf, fs, adr, len, fw_off);
|
||||||
|
if (res == -2) {
|
||||||
res = 1;
|
res = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
close(fs);
|
close(fs);
|
||||||
return res;
|
return res;
|
||||||
@ -607,18 +617,40 @@ static int update_flash(struct ddflash *ddf)
|
|||||||
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1)
|
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1)
|
||||||
stat |= 1;
|
stat |= 1;
|
||||||
} else {
|
} else {
|
||||||
if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
if (ddf->id.device == 0x0307) {
|
||||||
stat |= 1;
|
|
||||||
if (res == -1)
|
|
||||||
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
|
||||||
stat |= 1;
|
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||||
stat |= 1;
|
stat |= 1;
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||||
stat |= 1;
|
stat |= 1;
|
||||||
|
} else {
|
||||||
|
if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||||
|
stat |= 1;
|
||||||
|
if (res == -1)
|
||||||
|
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||||
|
stat |= 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#if 1
|
||||||
|
if ( (stat&1) && (ddf->id.hw & 0xffffff) <= 0x010001) {
|
||||||
|
if (ddf->id.device == 0x0307) {
|
||||||
|
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1)
|
||||||
|
stat |= 1;
|
||||||
|
if (res == -1)
|
||||||
|
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1)
|
||||||
|
stat |= 1;
|
||||||
|
} else {
|
||||||
|
if ((res = update_image(ddf, "/config/fpga.img", 0x160000, 0x80000, 1, 0)) == 1)
|
||||||
|
stat |= 1;
|
||||||
|
if (res == -1)
|
||||||
|
if ((res = update_image(ddf, "/boot/fpga.img", 0x160000, 0x80000, 1, 0)) == 1)
|
||||||
|
stat |= 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 0x320:
|
case 0x320:
|
||||||
//fname="/boot/DVBNetV1A_DD01_0300.bit";
|
//fname="/boot/DVBNetV1A_DD01_0300.bit";
|
||||||
|
@ -46,6 +46,10 @@ static int fmode;
|
|||||||
module_param(fmode, int, 0444);
|
module_param(fmode, int, 0444);
|
||||||
MODULE_PARM_DESC(fmode, "frontend emulation mode");
|
MODULE_PARM_DESC(fmode, "frontend emulation mode");
|
||||||
|
|
||||||
|
static int fmode_sat = -1;
|
||||||
|
module_param(fmode_sat, int, 0444);
|
||||||
|
MODULE_PARM_DESC(fmode_sat, "set frontend emulation mode sat");
|
||||||
|
|
||||||
static int old_quattro;
|
static int old_quattro;
|
||||||
module_param(old_quattro, int, 0444);
|
module_param(old_quattro, int, 0444);
|
||||||
MODULE_PARM_DESC(old_quattro, "old quattro LNB input order ");
|
MODULE_PARM_DESC(old_quattro, "old quattro LNB input order ");
|
||||||
@ -122,6 +126,12 @@ static struct ddb_regset octopus_mod_2_channel = {
|
|||||||
.size = 0x40,
|
.size = 0x40,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct ddb_regset octopus_sdr_output = {
|
||||||
|
.base = 0x240,
|
||||||
|
.num = 0x14,
|
||||||
|
.size = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
static struct ddb_regset octopus_input = {
|
static struct ddb_regset octopus_input = {
|
||||||
@ -299,6 +309,16 @@ static struct ddb_regmap octopus_mod_2_map = {
|
|||||||
.channel = &octopus_mod_2_channel,
|
.channel = &octopus_mod_2_channel,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct ddb_regmap octopus_sdr_map = {
|
||||||
|
.irq_version = 2,
|
||||||
|
.irq_base_odma = 64,
|
||||||
|
.irq_base_rate = 32,
|
||||||
|
.output = &octopus_sdr_output,
|
||||||
|
.odma = &octopus_mod_2_odma,
|
||||||
|
.odma_buf = &octopus_mod_2_odma_buf,
|
||||||
|
.channel = &octopus_mod_2_channel,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
@ -391,7 +411,7 @@ static void ddb_set_dma_table(struct ddb_io *io)
|
|||||||
ddbwritel(dev, mem & 0xffffffff, dma->bufregs + i * 8);
|
ddbwritel(dev, mem & 0xffffffff, dma->bufregs + i * 8);
|
||||||
ddbwritel(dev, mem >> 32, dma->bufregs + i * 8 + 4);
|
ddbwritel(dev, mem >> 32, dma->bufregs + i * 8 + 4);
|
||||||
}
|
}
|
||||||
dma->bufval = (dma->div << 16) |
|
dma->bufval = ((dma->div & 0x0f) << 16) |
|
||||||
((dma->num & 0x1f) << 11) |
|
((dma->num & 0x1f) << 11) |
|
||||||
((dma->size >> 7) & 0x7ff);
|
((dma->size >> 7) & 0x7ff);
|
||||||
}
|
}
|
||||||
@ -633,27 +653,27 @@ static void ddb_buffers_free(struct ddb *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Control:
|
* Control:
|
||||||
*
|
*
|
||||||
* Bit 0 - Enable TS
|
* Bit 0 - Enable TS
|
||||||
* 1 - Reset
|
* 1 - Reset
|
||||||
* 2 - clock enable
|
* 2 - clock enable
|
||||||
* 3 - clock phase
|
* 3 - clock phase
|
||||||
* 4 - gap enable
|
* 4 - gap enable
|
||||||
* 5 - send null packets on underrun
|
* 5 - send null packets on underrun
|
||||||
* 6 - enable clock gating
|
* 6 - enable clock gating
|
||||||
* 7 - set error bit on inserted null packets
|
* 7 - set error bit on inserted null packets
|
||||||
* 8-10 - fine adjust clock delay
|
* 8-10 - fine adjust clock delay
|
||||||
* 11- HS (high speed), if NCO mode=0: 0=72MHz 1=96Mhz
|
* 11- HS (high speed), if NCO mode=0: 0=72MHz 1=96Mhz
|
||||||
* 12- enable NCO mode
|
* 12- enable NCO mode
|
||||||
*
|
*
|
||||||
* Control 2:
|
* Control 2:
|
||||||
*
|
*
|
||||||
* Bit 0-6 : gap_size, Gap = (gap_size * 2) + 4
|
* Bit 0-6 : gap_size, Gap = (gap_size * 2) + 4
|
||||||
* 16-31: HS = 0: Speed = 72 * Value / 8192 MBit/s
|
* 16-31: HS = 0: Speed = 72 * Value / 8192 MBit/s
|
||||||
* HS = 1: Speed = 72 * 8 / (Value + 1) MBit/s (only bit 19-16 used)
|
* HS = 1: Speed = 72 * 8 / (Value + 1) MBit/s (only bit 19-16 used)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
|
static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
|
||||||
{
|
{
|
||||||
@ -678,7 +698,8 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
|
|||||||
*con |= 0x800;
|
*con |= 0x800;
|
||||||
else {
|
else {
|
||||||
*con |= 0x1000;
|
*con |= 0x1000;
|
||||||
nco = (bitrate * 8192 + 71999) / 72000;
|
nco = (bitrate *
|
||||||
|
8192 + 71999) / 72000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -687,7 +708,7 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
|
|||||||
if (bitrate <= 64000) {
|
if (bitrate <= 64000) {
|
||||||
max_bitrate = 64000;
|
max_bitrate = 64000;
|
||||||
nco = 8;
|
nco = 8;
|
||||||
} else if( bitrate <= 72000) {
|
} else if (bitrate <= 72000) {
|
||||||
max_bitrate = 72000;
|
max_bitrate = 72000;
|
||||||
nco = 7;
|
nco = 7;
|
||||||
} else {
|
} else {
|
||||||
@ -716,7 +737,6 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
|
|||||||
gap = 127;
|
gap = 127;
|
||||||
}
|
}
|
||||||
*con2 = (nco << 16) | gap;
|
*con2 = (nco << 16) | gap;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddb_output_start(struct ddb_output *output)
|
static void ddb_output_start(struct ddb_output *output)
|
||||||
@ -724,6 +744,7 @@ static void ddb_output_start(struct ddb_output *output)
|
|||||||
struct ddb *dev = output->port->dev;
|
struct ddb *dev = output->port->dev;
|
||||||
u32 con = 0x11c, con2 = 0;
|
u32 con = 0x11c, con2 = 0;
|
||||||
|
|
||||||
|
pr_info("Channel Base = %08x\n", output->regs);
|
||||||
if (output->dma) {
|
if (output->dma) {
|
||||||
spin_lock_irq(&output->dma->lock);
|
spin_lock_irq(&output->dma->lock);
|
||||||
output->dma->cbuf = 0;
|
output->dma->cbuf = 0;
|
||||||
@ -749,7 +770,7 @@ static void ddb_output_start(struct ddb_output *output)
|
|||||||
DMA_BUFFER_SIZE(output->dma));
|
DMA_BUFFER_SIZE(output->dma));
|
||||||
ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma));
|
ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma));
|
||||||
ddbwritel(dev, 1, DMA_BASE_READ);
|
ddbwritel(dev, 1, DMA_BASE_READ);
|
||||||
ddbwritel(dev, 3, DMA_BUFFER_CONTROL(output->dma));
|
ddbwritel(dev, 7, DMA_BUFFER_CONTROL(output->dma));
|
||||||
}
|
}
|
||||||
if (output->port->class != DDB_PORT_MOD)
|
if (output->port->class != DDB_PORT_MOD)
|
||||||
ddbwritel(dev, con | 1, TS_CONTROL(output));
|
ddbwritel(dev, con | 1, TS_CONTROL(output));
|
||||||
@ -790,7 +811,8 @@ static void ddb_input_stop(struct ddb_input *input)
|
|||||||
spin_unlock_irq(&input->dma->lock);
|
spin_unlock_irq(&input->dma->lock);
|
||||||
}
|
}
|
||||||
/*printk("input_stop %u.%u.%u\n",
|
/*printk("input_stop %u.%u.%u\n",
|
||||||
dev->nr, input->port->lnr, input->nr);*/
|
* dev->nr, input->port->lnr, input->nr);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddb_input_start(struct ddb_input *input)
|
static void ddb_input_start(struct ddb_input *input)
|
||||||
@ -955,7 +977,8 @@ static ssize_t ddb_output_write(struct ddb_output *output,
|
|||||||
dma_sync_single_for_device(dev->dev,
|
dma_sync_single_for_device(dev->dev,
|
||||||
output->dma->pbuf[
|
output->dma->pbuf[
|
||||||
output->dma->cbuf],
|
output->dma->cbuf],
|
||||||
output->dma->size, DMA_TO_DEVICE);
|
output->dma->size,
|
||||||
|
DMA_TO_DEVICE);
|
||||||
left -= len;
|
left -= len;
|
||||||
buf += len;
|
buf += len;
|
||||||
output->dma->coff += len;
|
output->dma->coff += len;
|
||||||
@ -1085,8 +1108,10 @@ static size_t ddb_input_read(struct ddb_input *input,
|
|||||||
free = left;
|
free = left;
|
||||||
if (alt_dma)
|
if (alt_dma)
|
||||||
dma_sync_single_for_cpu(dev->dev,
|
dma_sync_single_for_cpu(dev->dev,
|
||||||
input->dma->pbuf[input->dma->cbuf],
|
input->dma->pbuf[
|
||||||
input->dma->size, DMA_FROM_DEVICE);
|
input->dma->cbuf],
|
||||||
|
input->dma->size,
|
||||||
|
DMA_FROM_DEVICE);
|
||||||
ret = copy_to_user(buf, input->dma->vbuf[input->dma->cbuf] +
|
ret = copy_to_user(buf, input->dma->vbuf[input->dma->cbuf] +
|
||||||
input->dma->coff, free);
|
input->dma->coff, free);
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -1635,7 +1660,8 @@ static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
|
|||||||
msleep(20);
|
msleep(20);
|
||||||
}
|
}
|
||||||
if (c == 10)
|
if (c == 10)
|
||||||
pr_info("DDBridge: lnb_command lnb = %08x cmd = %08x\n", lnb, cmd);
|
pr_info("DDBridge: lnb_command lnb = %08x cmd = %08x\n",
|
||||||
|
lnb, cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1664,6 +1690,31 @@ static int max_send_master_cmd(struct dvb_frontend *fe,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lnb_send_diseqc(struct ddb *dev, u32 link, u32 input,
|
||||||
|
struct dvb_diseqc_master_cmd *cmd)
|
||||||
|
{
|
||||||
|
u32 tag = DDB_LINK_TAG(link);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ddbwritel(dev, 0, tag | LNB_BUF_LEVEL(input));
|
||||||
|
for (i = 0; i < cmd->msg_len; i++)
|
||||||
|
ddbwritel(dev, cmd->msg[i], tag | LNB_BUF_WRITE(input));
|
||||||
|
lnb_command(dev, link, input, LNB_CMD_DISEQC);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lnb_set_sat(struct ddb *dev, u32 link,
|
||||||
|
u32 input, u32 sat, u32 band, u32 hor)
|
||||||
|
{
|
||||||
|
struct dvb_diseqc_master_cmd cmd = {
|
||||||
|
.msg = {0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00},
|
||||||
|
.msg_len = 4
|
||||||
|
};
|
||||||
|
cmd.msg[3] = 0xf0 | (((sat << 2) & 0x0c) |
|
||||||
|
(band ? 1 : 0) | (hor ? 2 : 0));
|
||||||
|
return lnb_send_diseqc(dev, link, input, &cmd);
|
||||||
|
}
|
||||||
|
|
||||||
static int lnb_set_tone(struct ddb *dev, u32 link, u32 input,
|
static int lnb_set_tone(struct ddb *dev, u32 link, u32 input,
|
||||||
fe_sec_tone_mode_t tone)
|
fe_sec_tone_mode_t tone)
|
||||||
{
|
{
|
||||||
@ -1916,6 +1967,17 @@ static int lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm)
|
|||||||
pr_info("DDBridge: Set fmode link %u = %u\n", l, fm);
|
pr_info("DDBridge: Set fmode link %u = %u\n", l, fm);
|
||||||
mutex_lock(&link->lnb.lock);
|
mutex_lock(&link->lnb.lock);
|
||||||
if (fm == 2 || fm == 1) {
|
if (fm == 2 || fm == 1) {
|
||||||
|
if (fmode_sat >= 0) {
|
||||||
|
lnb_set_sat(dev, l, 0, fmode_sat, 0, 0);
|
||||||
|
if (old_quattro) {
|
||||||
|
lnb_set_sat(dev, l, 1, fmode_sat, 0, 1);
|
||||||
|
lnb_set_sat(dev, l, 2, fmode_sat, 1, 0);
|
||||||
|
} else {
|
||||||
|
lnb_set_sat(dev, l, 1, fmode_sat, 1, 0);
|
||||||
|
lnb_set_sat(dev, l, 2, fmode_sat, 0, 1);
|
||||||
|
}
|
||||||
|
lnb_set_sat(dev, l, 3, fmode_sat, 1, 1);
|
||||||
|
}
|
||||||
lnb_set_tone(dev, l, 0, SEC_TONE_OFF);
|
lnb_set_tone(dev, l, 0, SEC_TONE_OFF);
|
||||||
if (old_quattro) {
|
if (old_quattro) {
|
||||||
lnb_set_tone(dev, l, 1, SEC_TONE_OFF);
|
lnb_set_tone(dev, l, 1, SEC_TONE_OFF);
|
||||||
@ -1983,46 +2045,6 @@ static int fe_attach_mxl5xx(struct ddb_input *input)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id,
|
|
||||||
int (*start_feed)(struct dvb_demux_feed *),
|
|
||||||
int (*stop_feed)(struct dvb_demux_feed *),
|
|
||||||
void *priv)
|
|
||||||
{
|
|
||||||
dvbdemux->priv = priv;
|
|
||||||
|
|
||||||
dvbdemux->filternum = 256;
|
|
||||||
dvbdemux->feednum = 256;
|
|
||||||
dvbdemux->start_feed = start_feed;
|
|
||||||
dvbdemux->stop_feed = stop_feed;
|
|
||||||
dvbdemux->write_to_decoder = NULL;
|
|
||||||
dvbdemux->dmx.capabilities = (DMX_TS_FILTERING |
|
|
||||||
DMX_SECTION_FILTERING |
|
|
||||||
DMX_MEMORY_BASED_FILTERING);
|
|
||||||
return dvb_dmx_init(dvbdemux);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev,
|
|
||||||
struct dvb_demux *dvbdemux,
|
|
||||||
struct dmx_frontend *hw_frontend,
|
|
||||||
struct dmx_frontend *mem_frontend,
|
|
||||||
struct dvb_adapter *dvb_adapter)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
dmxdev->filternum = 256;
|
|
||||||
dmxdev->demux = &dvbdemux->dmx;
|
|
||||||
dmxdev->capabilities = 0;
|
|
||||||
ret = dvb_dmxdev_init(dmxdev, dvb_adapter);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
hw_frontend->source = DMX_FRONTEND_0;
|
|
||||||
dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend);
|
|
||||||
mem_frontend->source = DMX_MEMORY_FE;
|
|
||||||
dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend);
|
|
||||||
return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
static int start_input(struct ddb_input *input)
|
static int start_input(struct ddb_input *input)
|
||||||
{
|
{
|
||||||
@ -2094,12 +2116,13 @@ static void dvb_input_detach(struct ddb_input *input)
|
|||||||
case 0x20:
|
case 0x20:
|
||||||
dvb_net_release(&dvb->dvbnet);
|
dvb_net_release(&dvb->dvbnet);
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 0x11:
|
case 0x12:
|
||||||
dvbdemux->dmx.close(&dvbdemux->dmx);
|
|
||||||
dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
|
dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
|
||||||
&dvb->hw_frontend);
|
&dvb->hw_frontend);
|
||||||
dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
|
dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
|
||||||
&dvb->mem_frontend);
|
&dvb->mem_frontend);
|
||||||
|
/* fallthrough */
|
||||||
|
case 0x11:
|
||||||
dvb_dmxdev_release(&dvb->dmxdev);
|
dvb_dmxdev_release(&dvb->dmxdev);
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
case 0x10:
|
case 0x10:
|
||||||
@ -2222,21 +2245,33 @@ static int dvb_input_attach(struct ddb_input *input)
|
|||||||
|
|
||||||
dvb->attached = 0x01;
|
dvb->attached = 0x01;
|
||||||
|
|
||||||
ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux",
|
dvbdemux->priv = input;
|
||||||
start_feed,
|
dvbdemux->dmx.capabilities = DMX_TS_FILTERING |
|
||||||
stop_feed, input);
|
DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING;
|
||||||
|
dvbdemux->start_feed = start_feed;
|
||||||
|
dvbdemux->stop_feed = stop_feed;
|
||||||
|
dvbdemux->filternum = dvbdemux->feednum = 256;
|
||||||
|
ret = dvb_dmx_init(dvbdemux);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
dvb->attached = 0x10;
|
dvb->attached = 0x10;
|
||||||
|
|
||||||
ret = my_dvb_dmxdev_ts_card_init(&dvb->dmxdev,
|
dvb->dmxdev.filternum = 256;
|
||||||
&dvb->demux,
|
dvb->dmxdev.demux = &dvbdemux->dmx;
|
||||||
&dvb->hw_frontend,
|
ret = dvb_dmxdev_init(&dvb->dmxdev, adap);
|
||||||
&dvb->mem_frontend, adap);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
dvb->attached = 0x11;
|
dvb->attached = 0x11;
|
||||||
|
|
||||||
|
dvb->mem_frontend.source = DMX_MEMORY_FE;
|
||||||
|
dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->mem_frontend);
|
||||||
|
dvb->hw_frontend.source = DMX_FRONTEND_0;
|
||||||
|
dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->hw_frontend);
|
||||||
|
ret = dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, &dvb->hw_frontend);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
dvb->attached = 0x12;
|
||||||
|
|
||||||
ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux);
|
ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -2331,6 +2366,7 @@ static int dvb_input_attach(struct ddb_input *input)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
dvb->attached = 0x30;
|
dvb->attached = 0x30;
|
||||||
|
|
||||||
if (dvb->fe) {
|
if (dvb->fe) {
|
||||||
if (dvb_register_frontend(adap, dvb->fe) < 0)
|
if (dvb_register_frontend(adap, dvb->fe) < 0)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -2500,7 +2536,8 @@ static int init_xo2_ci(struct ddb_port *port)
|
|||||||
port->nr, data[0]);
|
port->nr, data[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pr_info("DDBridge: Port %d: DuoFlex CI %u.%u\n", port->nr, data[0], data[1]);
|
pr_info("DDBridge: Port %d: DuoFlex CI %u.%u\n",
|
||||||
|
port->nr, data[0], data[1]);
|
||||||
|
|
||||||
i2c_read_reg(i2c, 0x10, 0x08, &val);
|
i2c_read_reg(i2c, 0x10, 0x08, &val);
|
||||||
if (val != 0) {
|
if (val != 0) {
|
||||||
@ -2588,7 +2625,7 @@ static void ddb_port_probe(struct ddb_port *port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (dev->link[l].info->type == DDB_OCTOPRO_HDIN) {
|
if (dev->link[l].info->type == DDB_OCTOPRO_HDIN) {
|
||||||
if( port->nr == 0 ) {
|
if (port->nr == 0) {
|
||||||
dev->link[l].info->type = DDB_OCTOPUS;
|
dev->link[l].info->type = DDB_OCTOPUS;
|
||||||
port->name = "HDIN";
|
port->name = "HDIN";
|
||||||
port->class = DDB_PORT_LOOP;
|
port->class = DDB_PORT_LOOP;
|
||||||
@ -2628,7 +2665,7 @@ static void ddb_port_probe(struct ddb_port *port)
|
|||||||
ddbwritel(dev, I2C_SPEED_400,
|
ddbwritel(dev, I2C_SPEED_400,
|
||||||
port->i2c->regs + I2C_TIMING);
|
port->i2c->regs + I2C_TIMING);
|
||||||
} else {
|
} else {
|
||||||
pr_info(KERN_INFO "DDBridge: Port %d: Uninitialized DuoFlex\n",
|
pr_info("DDBridge: Port %d: Uninitialized DuoFlex\n",
|
||||||
port->nr);
|
port->nr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2673,8 +2710,8 @@ static void ddb_port_probe(struct ddb_port *port)
|
|||||||
break;
|
break;
|
||||||
case 0xc1:
|
case 0xc1:
|
||||||
port->name = "DUAL DVB-C2T2 ISDB-T CXD2854";
|
port->name = "DUAL DVB-C2T2 ISDB-T CXD2854";
|
||||||
port->type = DDB_TUNER_DVBC2T2_SONY_P;
|
port->type = DDB_TUNER_DVBC2T2I_SONY_P;
|
||||||
port->type_name = "DVBC2T2_ISDBT_SONY";
|
port->type_name = "DVBC2T2I_ISDBT_SONY";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
@ -3185,7 +3222,8 @@ static void input_write_dvb(struct ddb_input *input,
|
|||||||
|
|
||||||
dma = dma2 = input->dma;
|
dma = dma2 = input->dma;
|
||||||
/* if there also is an output connected, do not ACK.
|
/* if there also is an output connected, do not ACK.
|
||||||
input_write_output will ACK. */
|
* input_write_output will ACK.
|
||||||
|
*/
|
||||||
if (input->redo) {
|
if (input->redo) {
|
||||||
dma2 = input->redo->dma;
|
dma2 = input->redo->dma;
|
||||||
ack = 0;
|
ack = 0;
|
||||||
@ -3200,7 +3238,7 @@ static void input_write_dvb(struct ddb_input *input,
|
|||||||
dma_sync_single_for_cpu(dev->dev, dma2->pbuf[dma->cbuf],
|
dma_sync_single_for_cpu(dev->dev, dma2->pbuf[dma->cbuf],
|
||||||
dma2->size, DMA_FROM_DEVICE);
|
dma2->size, DMA_FROM_DEVICE);
|
||||||
#if 0
|
#if 0
|
||||||
pr_info("DDBridge: %02x %02x %02x %02x \n",
|
pr_info("DDBridge: %02x %02x %02x %02x\n",
|
||||||
dma2->vbuf[dma->cbuf][0], dma2->vbuf[dma->cbuf][1],
|
dma2->vbuf[dma->cbuf][0], dma2->vbuf[dma->cbuf][1],
|
||||||
dma2->vbuf[dma->cbuf][2], dma2->vbuf[dma->cbuf][3]);
|
dma2->vbuf[dma->cbuf][2], dma2->vbuf[dma->cbuf][3]);
|
||||||
#endif
|
#endif
|
||||||
@ -3257,8 +3295,9 @@ static void input_handler(unsigned long data)
|
|||||||
|
|
||||||
|
|
||||||
/* If there is no input connected, input_tasklet() will
|
/* If there is no input connected, input_tasklet() will
|
||||||
just copy pointers and ACK. So, there is no need to go
|
* just copy pointers and ACK. So, there is no need to go
|
||||||
through the tasklet scheduler. */
|
* through the tasklet scheduler.
|
||||||
|
*/
|
||||||
#ifdef DDB_USE_WORK
|
#ifdef DDB_USE_WORK
|
||||||
if (input->redi)
|
if (input->redi)
|
||||||
queue_work(ddb_wq, &dma->work);
|
queue_work(ddb_wq, &dma->work);
|
||||||
@ -3322,9 +3361,16 @@ static void ddb_dma_init(struct ddb_io *io, int nr, int out)
|
|||||||
if (out) {
|
if (out) {
|
||||||
dma->regs = rm->odma->base + rm->odma->size * nr;
|
dma->regs = rm->odma->base + rm->odma->size * nr;
|
||||||
dma->bufregs = rm->odma_buf->base + rm->odma_buf->size * nr;
|
dma->bufregs = rm->odma_buf->base + rm->odma_buf->size * nr;
|
||||||
|
if (io->port->dev->link[0].info->type == DDB_MOD &&
|
||||||
|
io->port->dev->link[0].info->version == 3) {
|
||||||
|
dma->num = OUTPUT_DMA_BUFS_SDR;
|
||||||
|
dma->size = OUTPUT_DMA_SIZE_SDR;
|
||||||
|
dma->div = OUTPUT_DMA_IRQ_DIV_SDR;
|
||||||
|
} else {
|
||||||
dma->num = OUTPUT_DMA_BUFS;
|
dma->num = OUTPUT_DMA_BUFS;
|
||||||
dma->size = OUTPUT_DMA_SIZE;
|
dma->size = OUTPUT_DMA_SIZE;
|
||||||
dma->div = OUTPUT_DMA_IRQ_DIV;
|
dma->div = OUTPUT_DMA_IRQ_DIV;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef DDB_USE_WORK
|
#ifdef DDB_USE_WORK
|
||||||
INIT_WORK(&dma->work, input_work);
|
INIT_WORK(&dma->work, input_work);
|
||||||
@ -3354,7 +3400,8 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr)
|
|||||||
rm = io_regmap(input, 1);
|
rm = io_regmap(input, 1);
|
||||||
input->regs = DDB_LINK_TAG(port->lnr) |
|
input->regs = DDB_LINK_TAG(port->lnr) |
|
||||||
(rm->input->base + rm->input->size * nr);
|
(rm->input->base + rm->input->size * nr);
|
||||||
pr_debug("DDBridge: init link %u, input %u, regs %08x\n", port->lnr, nr, input->regs);
|
pr_debug("DDBridge: init link %u, input %u, regs %08x\n",
|
||||||
|
port->lnr, nr, input->regs);
|
||||||
if (dev->has_dma) {
|
if (dev->has_dma) {
|
||||||
struct ddb_regmap *rm0 = io_regmap(input, 0);
|
struct ddb_regmap *rm0 = io_regmap(input, 0);
|
||||||
u32 base = rm0->irq_base_idma;
|
u32 base = rm0->irq_base_idma;
|
||||||
@ -3551,19 +3598,19 @@ static void ddb_ports_release(struct ddb *dev)
|
|||||||
dev->handler[0][_nr](dev->handler_data[0][_nr]); } \
|
dev->handler[0][_nr](dev->handler_data[0][_nr]); } \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
||||||
#define IRQ_HANDLE_BYTE(_n) \
|
#define IRQ_HANDLE_BYTE(_n) { \
|
||||||
if (s & (0x000000ff << ((_n) & 0x1f))) { \
|
if (s & (0x000000ff << ((_n) & 0x1f))) { \
|
||||||
IRQ_HANDLE(0 + _n); \
|
IRQ_HANDLE(0 + (_n)); \
|
||||||
IRQ_HANDLE(1 + _n); \
|
IRQ_HANDLE(1 + (_n)); \
|
||||||
IRQ_HANDLE(2 + _n); \
|
IRQ_HANDLE(2 + (_n)); \
|
||||||
IRQ_HANDLE(3 + _n); \
|
IRQ_HANDLE(3 + (_n)); \
|
||||||
IRQ_HANDLE(4 + _n); \
|
IRQ_HANDLE(4 + (_n)); \
|
||||||
IRQ_HANDLE(5 + _n); \
|
IRQ_HANDLE(5 + (_n)); \
|
||||||
IRQ_HANDLE(6 + _n); \
|
IRQ_HANDLE(6 + (_n)); \
|
||||||
IRQ_HANDLE(7 + _n); \
|
IRQ_HANDLE(7 + (_n)); \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void irq_handle_msg(struct ddb *dev, u32 s)
|
static void irq_handle_msg(struct ddb *dev, u32 s)
|
||||||
{
|
{
|
||||||
dev->i2c_irq++;
|
dev->i2c_irq++;
|
||||||
@ -3622,9 +3669,9 @@ static irqreturn_t irq_handler0(int irq, void *dev_id)
|
|||||||
do {
|
do {
|
||||||
if (s & 0x80000000)
|
if (s & 0x80000000)
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
if (!(s & 0xfff00))
|
if (!(s & 0xfffff00))
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
ddbwritel(dev, s & 0xfff00, INTERRUPT_ACK);
|
ddbwritel(dev, s & 0xfffff00, INTERRUPT_ACK);
|
||||||
irq_handle_io(dev, s);
|
irq_handle_io(dev, s);
|
||||||
} while ((s = ddbreadl(dev, INTERRUPT_STATUS)));
|
} while ((s = ddbreadl(dev, INTERRUPT_STATUS)));
|
||||||
|
|
||||||
@ -3685,18 +3732,18 @@ static irqreturn_t irq_handle_v2_n(struct ddb *dev, u32 n)
|
|||||||
ddbwritel(dev, s, reg);
|
ddbwritel(dev, s, reg);
|
||||||
|
|
||||||
if ((s & 0x000000ff)) {
|
if ((s & 0x000000ff)) {
|
||||||
IRQ_HANDLE( 0 + off);
|
IRQ_HANDLE(0 + off);
|
||||||
IRQ_HANDLE( 1 + off);
|
IRQ_HANDLE(1 + off);
|
||||||
IRQ_HANDLE( 2 + off);
|
IRQ_HANDLE(2 + off);
|
||||||
IRQ_HANDLE( 3 + off);
|
IRQ_HANDLE(3 + off);
|
||||||
IRQ_HANDLE( 4 + off);
|
IRQ_HANDLE(4 + off);
|
||||||
IRQ_HANDLE( 5 + off);
|
IRQ_HANDLE(5 + off);
|
||||||
IRQ_HANDLE( 6 + off);
|
IRQ_HANDLE(6 + off);
|
||||||
IRQ_HANDLE( 7 + off);
|
IRQ_HANDLE(7 + off);
|
||||||
}
|
}
|
||||||
if ((s & 0x0000ff00)) {
|
if ((s & 0x0000ff00)) {
|
||||||
IRQ_HANDLE( 8 + off);
|
IRQ_HANDLE(8 + off);
|
||||||
IRQ_HANDLE( 9 + off);
|
IRQ_HANDLE(9 + off);
|
||||||
IRQ_HANDLE(10 + off);
|
IRQ_HANDLE(10 + off);
|
||||||
IRQ_HANDLE(11 + off);
|
IRQ_HANDLE(11 + off);
|
||||||
IRQ_HANDLE(12 + off);
|
IRQ_HANDLE(12 + off);
|
||||||
@ -3826,7 +3873,7 @@ static int nsd_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
ctrl = (input->port->lnr << 16) | ((input->nr & 7) << 8) |
|
ctrl = (input->port->lnr << 16) | ((input->nr & 7) << 8) |
|
||||||
((ts->filter_mask & 3) << 2);
|
((ts->filter_mask & 3) << 2);
|
||||||
/*pr_info("DDBridge: GET_TS %u.%u\n", input->port->lnr, input->nr);*/
|
|
||||||
if (ddbreadl(dev, TS_CAPTURE_CONTROL) & 1) {
|
if (ddbreadl(dev, TS_CAPTURE_CONTROL) & 1) {
|
||||||
pr_info("DDBridge: ts capture busy\n");
|
pr_info("DDBridge: ts capture busy\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
@ -4427,7 +4474,7 @@ static ssize_t fan_store(struct device *device, struct device_attribute *d,
|
|||||||
const char *buf, size_t count)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
struct ddb *dev = dev_get_drvdata(device);
|
struct ddb *dev = dev_get_drvdata(device);
|
||||||
unsigned val;
|
u32 val;
|
||||||
|
|
||||||
if (sscanf(buf, "%u\n", &val) != 1)
|
if (sscanf(buf, "%u\n", &val) != 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -4458,8 +4505,8 @@ static ssize_t temp_show(struct device *device,
|
|||||||
int i;
|
int i;
|
||||||
u8 tmp[2];
|
u8 tmp[2];
|
||||||
|
|
||||||
if (dev->link[0].info->type == DDB_MOD) {
|
if (link->info->type == DDB_MOD) {
|
||||||
if (dev->link[0].info->version == 2) {
|
if (link->info->version >= 2) {
|
||||||
temp = 0xffff & ddbreadl(dev, TEMPMON2_BOARD);
|
temp = 0xffff & ddbreadl(dev, TEMPMON2_BOARD);
|
||||||
temp = (temp * 1000) >> 8;
|
temp = (temp * 1000) >> 8;
|
||||||
|
|
||||||
@ -4488,14 +4535,14 @@ static ssize_t temp_show(struct device *device,
|
|||||||
}
|
}
|
||||||
return sprintf(buf, "%d %d\n", temp, temp2);
|
return sprintf(buf, "%d %d\n", temp, temp2);
|
||||||
}
|
}
|
||||||
if (!dev->link[0].info->temp_num)
|
if (!link->info->temp_num)
|
||||||
return sprintf(buf, "no sensor\n");
|
return sprintf(buf, "no sensor\n");
|
||||||
adap = &dev->i2c[dev->link[0].info->temp_bus].adap;
|
adap = &dev->i2c[link->info->temp_bus].adap;
|
||||||
if (i2c_read_regs(adap, 0x48, 0, tmp, 2) < 0)
|
if (i2c_read_regs(adap, 0x48, 0, tmp, 2) < 0)
|
||||||
return sprintf(buf, "read_error\n");
|
return sprintf(buf, "read_error\n");
|
||||||
temp = (tmp[0] << 3) | (tmp[1] >> 5);
|
temp = (tmp[0] << 3) | (tmp[1] >> 5);
|
||||||
temp *= 125;
|
temp *= 125;
|
||||||
if (dev->link[0].info->temp_num == 2) {
|
if (link->info->temp_num == 2) {
|
||||||
if (i2c_read_regs(adap, 0x49, 0, tmp, 2) < 0)
|
if (i2c_read_regs(adap, 0x49, 0, tmp, 2) < 0)
|
||||||
return sprintf(buf, "read_error\n");
|
return sprintf(buf, "read_error\n");
|
||||||
temp2 = (tmp[0] << 3) | (tmp[1] >> 5);
|
temp2 = (tmp[0] << 3) | (tmp[1] >> 5);
|
||||||
@ -4603,7 +4650,7 @@ static ssize_t led_store(struct device *device,
|
|||||||
{
|
{
|
||||||
struct ddb *dev = dev_get_drvdata(device);
|
struct ddb *dev = dev_get_drvdata(device);
|
||||||
int num = attr->attr.name[3] - 0x30;
|
int num = attr->attr.name[3] - 0x30;
|
||||||
unsigned val;
|
u32 val;
|
||||||
|
|
||||||
if (sscanf(buf, "%u\n", &val) != 1)
|
if (sscanf(buf, "%u\n", &val) != 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -4707,6 +4754,7 @@ static ssize_t redirect_store(struct device *device,
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/* A L P I AAAAAALLPPPPPPII */
|
/* A L P I AAAAAALLPPPPPPII */
|
||||||
/* AAAAAAAA LLLLLLLL PPPPPPII */
|
/* AAAAAAAA LLLLLLLL PPPPPPII */
|
||||||
static ssize_t redirect2_show(struct device *device,
|
static ssize_t redirect2_show(struct device *device,
|
||||||
@ -4730,6 +4778,7 @@ static ssize_t redirect2_store(struct device *device,
|
|||||||
pr_info("DDBridge: redirect: %02x, %02x\n", i, p);
|
pr_info("DDBridge: redirect: %02x, %02x\n", i, p);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static ssize_t gap_show(struct device *device,
|
static ssize_t gap_show(struct device *device,
|
||||||
struct device_attribute *attr, char *buf)
|
struct device_attribute *attr, char *buf)
|
||||||
@ -4978,7 +5027,8 @@ static void ddb_device_attrs_del(struct ddb *dev)
|
|||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
if (dev->link[i].info &&
|
if (dev->link[i].info &&
|
||||||
dev->link[i].info->tempmon_irq)
|
dev->link[i].info->tempmon_irq)
|
||||||
device_remove_file(dev->ddb_dev, &ddb_attrs_fanspeed[i]);
|
device_remove_file(dev->ddb_dev,
|
||||||
|
&ddb_attrs_fanspeed[i]);
|
||||||
for (i = 0; i < dev->link[0].info->temp_num; i++)
|
for (i = 0; i < dev->link[0].info->temp_num; i++)
|
||||||
device_remove_file(dev->ddb_dev, &ddb_attrs_temp[i]);
|
device_remove_file(dev->ddb_dev, &ddb_attrs_temp[i]);
|
||||||
for (i = 0; i < dev->link[0].info->port_num; i++)
|
for (i = 0; i < dev->link[0].info->port_num; i++)
|
||||||
@ -5164,8 +5214,22 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l)
|
|||||||
link->info = &ddb_s2_48;
|
link->info = &ddb_s2_48;
|
||||||
break;
|
break;
|
||||||
case 0x0008dd01:
|
case 0x0008dd01:
|
||||||
|
switch (subid) {
|
||||||
|
case 0x0035dd01:
|
||||||
|
default:
|
||||||
link->info = &ddb_c2t2_8;
|
link->info = &ddb_c2t2_8;
|
||||||
break;
|
break;
|
||||||
|
case 0x0036dd01:
|
||||||
|
link->info = &ddb_isdbt_8;
|
||||||
|
break;
|
||||||
|
case 0x0037dd01:
|
||||||
|
link->info = &ddb_c2t2i_v0_8;
|
||||||
|
break;
|
||||||
|
case 0x0038dd01:
|
||||||
|
link->info = &ddb_c2t2i_8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
pr_info("DDBridge: Detected GT link but found invalid ID %08x. You might have to update (flash) the add-on card first.",
|
pr_info("DDBridge: Detected GT link but found invalid ID %08x. You might have to update (flash) the add-on card first.",
|
||||||
id);
|
id);
|
||||||
@ -5219,7 +5283,8 @@ static void tempmon_setfan(struct ddb_link *link)
|
|||||||
{
|
{
|
||||||
u32 temp, temp2, pwm;
|
u32 temp, temp2, pwm;
|
||||||
|
|
||||||
if ((ddblreadl(link, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0) {
|
if ((ddblreadl(link, TEMPMON_CONTROL) &
|
||||||
|
TEMPMON_CONTROL_OVERTEMP) != 0) {
|
||||||
pr_info("DDBridge: Over temperature condition\n");
|
pr_info("DDBridge: Over temperature condition\n");
|
||||||
link->OverTemperatureError = 1;
|
link->OverTemperatureError = 1;
|
||||||
}
|
}
|
||||||
@ -5237,14 +5302,14 @@ static void tempmon_setfan(struct ddb_link *link)
|
|||||||
pwm = 10;
|
pwm = 10;
|
||||||
|
|
||||||
if (temp >= link->temp_tab[pwm]) {
|
if (temp >= link->temp_tab[pwm]) {
|
||||||
while( pwm < 10 && temp >= link->temp_tab[pwm + 1])
|
while (pwm < 10 && temp >= link->temp_tab[pwm + 1])
|
||||||
pwm += 1;
|
pwm += 1;
|
||||||
} else {
|
} else {
|
||||||
while( pwm > 1 && temp < link->temp_tab[pwm - 2])
|
while (pwm > 1 && temp < link->temp_tab[pwm - 2])
|
||||||
pwm -= 1;
|
pwm -= 1;
|
||||||
}
|
}
|
||||||
ddblwritel(link, (pwm << 8), TEMPMON_FANCONTROL);
|
ddblwritel(link, (pwm << 8), TEMPMON_FANCONTROL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void temp_handler(unsigned long data)
|
static void temp_handler(unsigned long data)
|
||||||
@ -5264,9 +5329,11 @@ static int tempmon_init(struct ddb_link *link, int FirstTime)
|
|||||||
|
|
||||||
spin_lock_irq(&link->temp_lock);
|
spin_lock_irq(&link->temp_lock);
|
||||||
if (FirstTime) {
|
if (FirstTime) {
|
||||||
static u8 TemperatureTable[11] = {30,35,40,45,50,55,60,65,70,75,80};
|
static u8 TemperatureTable[11] = {
|
||||||
|
30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80};
|
||||||
|
|
||||||
memcpy(link->temp_tab, TemperatureTable, sizeof(TemperatureTable));
|
memcpy(link->temp_tab, TemperatureTable,
|
||||||
|
sizeof(TemperatureTable));
|
||||||
}
|
}
|
||||||
dev->handler[l][link->info->tempmon_irq] = temp_handler;
|
dev->handler[l][link->info->tempmon_irq] = temp_handler;
|
||||||
dev->handler_data[l][link->info->tempmon_irq] = (unsigned long) link;
|
dev->handler_data[l][link->info->tempmon_irq] = (unsigned long) link;
|
||||||
@ -5276,7 +5343,8 @@ static int tempmon_init(struct ddb_link *link, int FirstTime)
|
|||||||
ddblwritel(link, (3 << 8), TEMPMON_FANCONTROL);
|
ddblwritel(link, (3 << 8), TEMPMON_FANCONTROL);
|
||||||
|
|
||||||
link->OverTemperatureError =
|
link->OverTemperatureError =
|
||||||
((ddblreadl(link, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0);
|
((ddblreadl(link, TEMPMON_CONTROL) &
|
||||||
|
TEMPMON_CONTROL_OVERTEMP) != 0);
|
||||||
if (link->OverTemperatureError) {
|
if (link->OverTemperatureError) {
|
||||||
pr_info("DDBridge: Over temperature condition\n");
|
pr_info("DDBridge: Over temperature condition\n");
|
||||||
status = -1;
|
status = -1;
|
||||||
@ -5288,18 +5356,16 @@ static int tempmon_init(struct ddb_link *link, int FirstTime)
|
|||||||
|
|
||||||
static int ddb_init_tempmon(struct ddb_link *link)
|
static int ddb_init_tempmon(struct ddb_link *link)
|
||||||
{
|
{
|
||||||
struct ddb *dev = link->dev;
|
|
||||||
struct ddb_info *info = link->info;
|
struct ddb_info *info = link->info;
|
||||||
|
|
||||||
if (!info->tempmon_irq)
|
if (!info->tempmon_irq)
|
||||||
return;
|
return 0;
|
||||||
if (info->type == DDB_OCTOPUS_MAX ||
|
if (info->type == DDB_OCTOPUS_MAX ||
|
||||||
info->type == DDB_OCTOPUS_MAX_CT)
|
info->type == DDB_OCTOPUS_MAX_CT)
|
||||||
if (link->ids.regmapid < 0x00010002)
|
if (link->ids.regmapid < 0x00010002)
|
||||||
return;
|
return 0;
|
||||||
spin_lock_init(&link->temp_lock);
|
spin_lock_init(&link->temp_lock);
|
||||||
printk("init_tempmon\n");
|
return tempmon_init(link, 1);
|
||||||
tempmon_init(link, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@ -5364,12 +5430,8 @@ static int ddb_init(struct ddb *dev)
|
|||||||
pr_info("DDBridge: Could not allocate buffer memory\n");
|
pr_info("DDBridge: Could not allocate buffer memory\n");
|
||||||
goto fail2;
|
goto fail2;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
if (ddb_ports_attach(dev) < 0)
|
if (ddb_ports_attach(dev) < 0)
|
||||||
goto fail3;
|
goto fail3;
|
||||||
#else
|
|
||||||
ddb_ports_attach(dev);
|
|
||||||
#endif
|
|
||||||
ddb_nsd_attach(dev);
|
ddb_nsd_attach(dev);
|
||||||
|
|
||||||
ddb_device_create(dev);
|
ddb_device_create(dev);
|
||||||
@ -5409,9 +5471,11 @@ static void ddb_reset_ios(struct ddb *dev)
|
|||||||
|
|
||||||
if (rm->input)
|
if (rm->input)
|
||||||
for (i = 0; i < rm->input->num; i++)
|
for (i = 0; i < rm->input->num; i++)
|
||||||
ddb_reset_io(dev, rm->input->base + i * rm->input->size);
|
ddb_reset_io(dev,
|
||||||
|
rm->input->base + i * rm->input->size);
|
||||||
if (rm->output)
|
if (rm->output)
|
||||||
for (i = 0; i < rm->output->num; i++)
|
for (i = 0; i < rm->output->num; i++)
|
||||||
ddb_reset_io(dev, rm->output->base + i * rm->output->size);
|
ddb_reset_io(dev,
|
||||||
|
rm->output->base + i * rm->output->size);
|
||||||
usleep_range(5000, 6000);
|
usleep_range(5000, 6000);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ddbridge-i2c.c: Digital Devices bridge i2c driver
|
* ddbridge-i2c.c: Digital Devices bridge i2c driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||||
* Marcus Metzler <mocm@metzlerbros.de>
|
* Marcus Metzler <mocm@metzlerbros.de>
|
||||||
*
|
*
|
||||||
@ -156,38 +156,43 @@ static int ddb_i2c_master_xfer(struct i2c_adapter *adapter,
|
|||||||
struct ddb *dev = i2c->dev;
|
struct ddb *dev = i2c->dev;
|
||||||
u8 addr = 0;
|
u8 addr = 0;
|
||||||
|
|
||||||
if (num != 1 && num != 2)
|
|
||||||
return -EIO;
|
|
||||||
addr = msg[0].addr;
|
addr = msg[0].addr;
|
||||||
if (msg[0].len > i2c->bsize)
|
if (msg[0].len > i2c->bsize)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
if (num == 2 && msg[1].flags & I2C_M_RD &&
|
switch (num) {
|
||||||
!(msg[0].flags & I2C_M_RD)) {
|
case 1:
|
||||||
if (msg[1].len > i2c->bsize)
|
if (msg[0].flags & I2C_M_RD) {
|
||||||
return -EIO;
|
ddbwritel(dev, msg[0].len << 16,
|
||||||
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
|
|
||||||
ddbwritel(dev, msg[0].len | (msg[1].len << 16),
|
|
||||||
i2c->regs + I2C_TASKLENGTH);
|
i2c->regs + I2C_TASKLENGTH);
|
||||||
if (!ddb_i2c_cmd(i2c, addr, 1)) {
|
if (ddb_i2c_cmd(i2c, addr, 3))
|
||||||
ddbcpyfrom(dev, msg[1].buf,
|
break;
|
||||||
i2c->rbuf,
|
|
||||||
msg[1].len);
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
|
|
||||||
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
|
|
||||||
ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH);
|
|
||||||
if (!ddb_i2c_cmd(i2c, addr, 2))
|
|
||||||
return num;
|
|
||||||
}
|
|
||||||
if (num == 1 && (msg[0].flags & I2C_M_RD)) {
|
|
||||||
ddbwritel(dev, msg[0].len << 16, i2c->regs + I2C_TASKLENGTH);
|
|
||||||
if (!ddb_i2c_cmd(i2c, addr, 3)) {
|
|
||||||
ddbcpyfrom(dev, msg[0].buf,
|
ddbcpyfrom(dev, msg[0].buf,
|
||||||
i2c->rbuf, msg[0].len);
|
i2c->rbuf, msg[0].len);
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
|
||||||
|
ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH);
|
||||||
|
if (ddb_i2c_cmd(i2c, addr, 2))
|
||||||
|
break;
|
||||||
|
return num;
|
||||||
|
case 2:
|
||||||
|
if ((msg[0].flags & I2C_M_RD) == I2C_M_RD)
|
||||||
|
break;
|
||||||
|
if ((msg[1].flags & I2C_M_RD) != I2C_M_RD)
|
||||||
|
break;
|
||||||
|
if (msg[1].len > i2c->bsize)
|
||||||
|
break;
|
||||||
|
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
|
||||||
|
ddbwritel(dev, msg[0].len | (msg[1].len << 16),
|
||||||
|
i2c->regs + I2C_TASKLENGTH);
|
||||||
|
if (ddb_i2c_cmd(i2c, addr, 1))
|
||||||
|
break;
|
||||||
|
ddbcpyfrom(dev, msg[1].buf,
|
||||||
|
i2c->rbuf,
|
||||||
|
msg[1].len);
|
||||||
|
return num;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -247,11 +252,10 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
|
|||||||
adap->class = I2C_CLASS_TV_ANALOG;
|
adap->class = I2C_CLASS_TV_ANALOG;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
/*strcpy(adap->name, "ddbridge");*/
|
|
||||||
snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x",
|
snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x",
|
||||||
dev->nr, i2c->link, i);
|
dev->nr, i2c->link, i);
|
||||||
adap->algo = &ddb_i2c_algo;
|
adap->algo = &ddb_i2c_algo;
|
||||||
adap->algo_data = (void *)i2c;
|
adap->algo_data = (void *) i2c;
|
||||||
adap->dev.parent = dev->dev;
|
adap->dev.parent = dev->dev;
|
||||||
return i2c_add_adapter(adap);
|
return i2c_add_adapter(adap);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ddbridge-i2c.h: Digital Devices bridge i2c driver
|
* ddbridge-i2c.h: Digital Devices bridge i2c driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||||
* Marcus Metzler <mocm@metzlerbros.de>
|
* Marcus Metzler <mocm@metzlerbros.de>
|
||||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||||
*
|
*
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ddbridge.c: Digital Devices PCIe bridge driver
|
* ddbridge.c: Digital Devices PCIe bridge driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||||
* Marcus Metzler <mocm@metzlerbros.de>
|
* Marcus Metzler <mocm@metzlerbros.de>
|
||||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||||
*
|
*
|
||||||
@ -76,57 +76,62 @@ inline s64 RoundPCRDown(s64 a)
|
|||||||
return a & ~(HW_LSB_MASK - 1);
|
return a & ~(HW_LSB_MASK - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculating KF, LF from Symbolrate
|
/* Calculating KF, LF from Symbolrate
|
||||||
//
|
*
|
||||||
// Symbolrate is usually calculated as (M/N) * 10.24 MS/s
|
* Symbolrate is usually calculated as (M/N) * 10.24 MS/s
|
||||||
//
|
*
|
||||||
// Common Values for M,N
|
* Common Values for M,N
|
||||||
// J.83 Annex A,
|
* J.83 Annex A,
|
||||||
// Euro Docsis 6.952 MS/s : M = 869, N = 1280
|
* Euro Docsis 6.952 MS/s : M = 869, N = 1280
|
||||||
// 6.900 MS/s : M = 345, N = 512
|
* 6.900 MS/s : M = 345, N = 512
|
||||||
// 6.875 MS/s : M = 1375, N = 2048
|
* 6.875 MS/s : M = 1375, N = 2048
|
||||||
// 6.111 MS/s : M = 6111, N = 10240
|
* 6.111 MS/s : M = 6111, N = 10240
|
||||||
// J.83 Annex B **
|
* J.83 Annex B **
|
||||||
// QAM64 5.056941 : M = 401, N = 812
|
* QAM64 5.056941 : M = 401, N = 812
|
||||||
// QAM256 5.360537 : M = 78, N = 149
|
* QAM256 5.360537 : M = 78, N = 149
|
||||||
// J.83 Annex C **
|
* J.83 Annex C **
|
||||||
// 5.309734 : M = 1889, N = 3643
|
* 5.309734 : M = 1889, N = 3643
|
||||||
//
|
*
|
||||||
// For the present hardware
|
* For the present hardware
|
||||||
// KF' = 256 * M
|
* KF' = 256 * M
|
||||||
// LF' = 225 * N
|
* LF' = 225 * N
|
||||||
// or
|
* or
|
||||||
// KF' = Symbolrate in Hz
|
* KF' = Symbolrate in Hz
|
||||||
// LF' = 9000000
|
* LF' = 9000000
|
||||||
//
|
*
|
||||||
// KF = KF' / gcd(KF',LF')
|
* KF = KF' / gcd(KF',LF')
|
||||||
// LF = LF' / gcd(KF',LF')
|
* LF = LF' / gcd(KF',LF')
|
||||||
// Note: LF must not be a power of 2.
|
* Note: LF must not be a power of 2.
|
||||||
// Maximum value for KF,LF = 13421727 ( 0x7FFFFFF )
|
* Maximum value for KF,LF = 13421727 ( 0x7FFFFFF )
|
||||||
// ** using these M,N values will result in a small err (<5ppm)
|
* ** using these M,N values will result in a small err (<5ppm)
|
||||||
// calculating KF,LF directly gives the exact normative result
|
* calculating KF,LF directly gives the exact normative result
|
||||||
// but with rather large KF,LF values
|
* but with rather large KF,LF values
|
||||||
|
*/
|
||||||
|
|
||||||
static inline u32 gcd(u32 u,u32 v)
|
static inline u32 gcd(u32 u, u32 v)
|
||||||
{
|
{
|
||||||
int s = 0;
|
int s = 0;
|
||||||
while (((u|v)&1) == 0) {
|
|
||||||
|
while (((u | v) & 1) == 0) {
|
||||||
s += 1;
|
s += 1;
|
||||||
u >>= 1;
|
u >>= 1;
|
||||||
v >>= 1;
|
v >>= 1;
|
||||||
}
|
}
|
||||||
while ((u&1) == 0)
|
while ((u & 1) == 0)
|
||||||
u >>= 1;
|
u >>= 1;
|
||||||
do {
|
do {
|
||||||
while ( (v&1) == 0 ) v >>= 1;
|
while ((v & 1) == 0)
|
||||||
if( u > v ) {
|
v >>= 1;
|
||||||
|
if (u > v) {
|
||||||
u32 t = v;
|
u32 t = v;
|
||||||
|
|
||||||
v = u;
|
v = u;
|
||||||
u = t;
|
u = t;
|
||||||
}
|
}
|
||||||
v = v - u;
|
v = v - u;
|
||||||
} while(v != 0);
|
} while (v != 0);
|
||||||
return u << s;
|
|
||||||
|
return (u << s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@ -139,11 +144,11 @@ static int mod_SendChannelCommand(struct ddb *dev, u32 Channel, u32 Command)
|
|||||||
|
|
||||||
ControlReg = (ControlReg & ~CHANNEL_CONTROL_CMD_MASK)|Command;
|
ControlReg = (ControlReg & ~CHANNEL_CONTROL_CMD_MASK)|Command;
|
||||||
ddbwritel(dev, ControlReg, CHANNEL_CONTROL(Channel));
|
ddbwritel(dev, ControlReg, CHANNEL_CONTROL(Channel));
|
||||||
while(1) {
|
while (1) {
|
||||||
ControlReg = ddbreadl(dev, CHANNEL_CONTROL(Channel));
|
ControlReg = ddbreadl(dev, CHANNEL_CONTROL(Channel));
|
||||||
if (ControlReg == 0xFFFFFFFF)
|
if (ControlReg == 0xFFFFFFFF)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
if((ControlReg & CHANNEL_CONTROL_CMD_STATUS) == 0)
|
if ((ControlReg & CHANNEL_CONTROL_CMD_STATUS) == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ControlReg & CHANNEL_CONTROL_ERROR_CMD)
|
if (ControlReg & CHANNEL_CONTROL_ERROR_CMD)
|
||||||
@ -171,10 +176,11 @@ void ddbridge_mod_output_stop(struct ddb_output *output)
|
|||||||
struct ddb_mod *mod = &dev->mod[output->nr];
|
struct ddb_mod *mod = &dev->mod[output->nr];
|
||||||
|
|
||||||
mod->State = CM_IDLE;
|
mod->State = CM_IDLE;
|
||||||
mod->Control = 0;
|
mod->Control &= 0xfffffff0;
|
||||||
if (dev->link[0].info->version == 2)
|
if (dev->link[0].info->version == 2)
|
||||||
mod_SendChannelCommand(dev, output->nr, CHANNEL_CONTROL_CMD_FREE);
|
mod_SendChannelCommand(dev, output->nr,
|
||||||
ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr));
|
CHANNEL_CONTROL_CMD_FREE);
|
||||||
|
ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr));
|
||||||
#if 0
|
#if 0
|
||||||
udelay(10);
|
udelay(10);
|
||||||
ddbwritel(dev, CHANNEL_CONTROL_RESET, CHANNEL_CONTROL(output->nr));
|
ddbwritel(dev, CHANNEL_CONTROL_RESET, CHANNEL_CONTROL(output->nr));
|
||||||
@ -237,7 +243,6 @@ static void mod_calc_rateinc(struct ddb_mod *mod)
|
|||||||
|
|
||||||
static int mod_calc_obitrate(struct ddb_mod *mod)
|
static int mod_calc_obitrate(struct ddb_mod *mod)
|
||||||
{
|
{
|
||||||
struct ddb *dev = mod->port->dev;
|
|
||||||
u64 ofac;
|
u64 ofac;
|
||||||
|
|
||||||
ofac = (((u64) mod->symbolrate) << 32) * 188;
|
ofac = (((u64) mod->symbolrate) << 32) * 188;
|
||||||
@ -249,7 +254,6 @@ static int mod_calc_obitrate(struct ddb_mod *mod)
|
|||||||
static int mod_set_symbolrate(struct ddb_mod *mod, u32 srate)
|
static int mod_set_symbolrate(struct ddb_mod *mod, u32 srate)
|
||||||
{
|
{
|
||||||
struct ddb *dev = mod->port->dev;
|
struct ddb *dev = mod->port->dev;
|
||||||
u64 ofac;
|
|
||||||
|
|
||||||
if (dev->link[0].info->version < 2) {
|
if (dev->link[0].info->version < 2) {
|
||||||
if (srate != 6900000)
|
if (srate != 6900000)
|
||||||
@ -265,16 +269,17 @@ static int mod_set_symbolrate(struct ddb_mod *mod, u32 srate)
|
|||||||
|
|
||||||
static u32 qamtab[6] = { 0x000, 0x600, 0x601, 0x602, 0x903, 0x604 };
|
static u32 qamtab[6] = { 0x000, 0x600, 0x601, 0x602, 0x903, 0x604 };
|
||||||
|
|
||||||
static int mod_set_modulation(struct ddb_mod *mod, enum fe_modulation modulation)
|
static int mod_set_modulation(struct ddb_mod *mod,
|
||||||
|
enum fe_modulation modulation)
|
||||||
{
|
{
|
||||||
struct ddb *dev = mod->port->dev;
|
struct ddb *dev = mod->port->dev;
|
||||||
u64 ofac;
|
|
||||||
|
|
||||||
if (modulation > QAM_256 || modulation < QAM_16)
|
if (modulation > QAM_256 || modulation < QAM_16)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
mod->modulation = modulation;
|
mod->modulation = modulation;
|
||||||
if (dev->link[0].info->version < 2)
|
if (dev->link[0].info->version < 2)
|
||||||
ddbwritel(dev, qamtab[modulation], CHANNEL_SETTINGS(mod->nr));
|
ddbwritel(dev, qamtab[modulation],
|
||||||
|
CHANNEL_SETTINGS(mod->port->nr));
|
||||||
mod_calc_obitrate(mod);
|
mod_calc_obitrate(mod);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -309,9 +314,8 @@ int ddbridge_mod_output_start(struct ddb_output *output)
|
|||||||
struct ddb_mod *mod = &dev->mod[output->nr];
|
struct ddb_mod *mod = &dev->mod[output->nr];
|
||||||
u32 Symbolrate = mod->symbolrate;
|
u32 Symbolrate = mod->symbolrate;
|
||||||
|
|
||||||
|
if (dev->link[0].info->version < 3)
|
||||||
mod_calc_rateinc(mod);
|
mod_calc_rateinc(mod);
|
||||||
/*PCRIncrement = RoundPCR(PCRIncrement);*/
|
|
||||||
/*PCRDecrement = RoundPCR(PCRDecrement);*/
|
|
||||||
|
|
||||||
mod->LastInPacketCount = 0;
|
mod->LastInPacketCount = 0;
|
||||||
mod->LastOutPacketCount = 0;
|
mod->LastOutPacketCount = 0;
|
||||||
@ -329,20 +333,23 @@ int ddbridge_mod_output_start(struct ddb_output *output)
|
|||||||
mod->State = CM_STARTUP;
|
mod->State = CM_STARTUP;
|
||||||
mod->StateCounter = CM_STARTUP_DELAY;
|
mod->StateCounter = CM_STARTUP_DELAY;
|
||||||
|
|
||||||
ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr));
|
if (dev->link[0].info->version == 3)
|
||||||
|
mod->Control = 0xfffffff0 &
|
||||||
|
ddbreadl(dev, CHANNEL_CONTROL(output->nr));
|
||||||
|
else
|
||||||
|
mod->Control = 0;
|
||||||
|
ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr));
|
||||||
udelay(10);
|
udelay(10);
|
||||||
ddbwritel(dev, CHANNEL_CONTROL_RESET, CHANNEL_CONTROL(output->nr));
|
ddbwritel(dev, mod->Control | CHANNEL_CONTROL_RESET,
|
||||||
|
CHANNEL_CONTROL(output->nr));
|
||||||
udelay(10);
|
udelay(10);
|
||||||
ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr));
|
ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr));
|
||||||
|
|
||||||
pr_info("DDBridge: CHANNEL_BASE = %08x\n", CHANNEL_BASE);
|
|
||||||
pr_info("DDBridge: CHANNEL_CONTROL = %08x\n", CHANNEL_CONTROL(Channel));
|
|
||||||
if (dev->link[0].info->version == 2) {
|
if (dev->link[0].info->version == 2) {
|
||||||
//u32 Output = ((dev->mod_base.frequency - 114000000)/8000000 + Channel) % 96;
|
|
||||||
u32 Output = (mod->frequency - 114000000) / 8000000;
|
u32 Output = (mod->frequency - 114000000) / 8000000;
|
||||||
u32 KF = Symbolrate;
|
u32 KF = Symbolrate;
|
||||||
u32 LF = 9000000UL;
|
u32 LF = 9000000UL;
|
||||||
u32 d = gcd(KF,LF);
|
u32 d = gcd(KF, LF);
|
||||||
u32 checkLF;
|
u32 checkLF;
|
||||||
|
|
||||||
ddbwritel(dev, mod->modulation - 1, CHANNEL_SETTINGS(Channel));
|
ddbwritel(dev, mod->modulation - 1, CHANNEL_SETTINGS(Channel));
|
||||||
@ -351,7 +358,7 @@ int ddbridge_mod_output_start(struct ddb_output *output)
|
|||||||
KF = KF / d;
|
KF = KF / d;
|
||||||
LF = LF / d;
|
LF = LF / d;
|
||||||
|
|
||||||
while( (KF > KFLF_MAX) || (LF > KFLF_MAX) ) {
|
while ((KF > KFLF_MAX) || (LF > KFLF_MAX)) {
|
||||||
KF >>= 1;
|
KF >>= 1;
|
||||||
LF >>= 1;
|
LF >>= 1;
|
||||||
}
|
}
|
||||||
@ -362,29 +369,39 @@ int ddbridge_mod_output_start(struct ddb_output *output)
|
|||||||
if (checkLF <= 1)
|
if (checkLF <= 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pr_info("DDBridge: KF=%u LF=%u Output=%u mod=%u\n", KF, LF, Output, mod->modulation);
|
pr_info("DDBridge: KF=%u LF=%u Output=%u mod=%u\n",
|
||||||
|
KF, LF, Output, mod->modulation);
|
||||||
ddbwritel(dev, KF, CHANNEL_KF(Channel));
|
ddbwritel(dev, KF, CHANNEL_KF(Channel));
|
||||||
ddbwritel(dev, LF, CHANNEL_LF(Channel));
|
ddbwritel(dev, LF, CHANNEL_LF(Channel));
|
||||||
|
|
||||||
if (mod_SendChannelCommand(dev, Channel, CHANNEL_CONTROL_CMD_SETUP))
|
if (mod_SendChannelCommand(dev, Channel,
|
||||||
|
CHANNEL_CONTROL_CMD_SETUP))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
mod->Control = CHANNEL_CONTROL_ENABLE_DVB;
|
mod->Control |= CHANNEL_CONTROL_ENABLE_DVB;
|
||||||
} else {
|
} else if (dev->link[0].info->version == 1) {
|
||||||
/* QAM: 600 601 602 903 604 = 16 32 64 128 256 */
|
/* QAM: 600 601 602 903 604 = 16 32 64 128 256 */
|
||||||
/* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */
|
/* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */
|
||||||
ddbwritel(dev, qamtab[mod->modulation], CHANNEL_SETTINGS(output->nr));
|
ddbwritel(dev, qamtab[mod->modulation],
|
||||||
mod->Control = (CHANNEL_CONTROL_ENABLE_IQ | CHANNEL_CONTROL_ENABLE_DVB);
|
CHANNEL_SETTINGS(output->nr));
|
||||||
|
mod->Control |= (CHANNEL_CONTROL_ENABLE_IQ |
|
||||||
|
CHANNEL_CONTROL_ENABLE_DVB);
|
||||||
|
} else if (dev->link[0].info->version == 3) {
|
||||||
|
mod->Control |= (CHANNEL_CONTROL_ENABLE_IQ |
|
||||||
|
CHANNEL_CONTROL_ENABLE_DVB);
|
||||||
}
|
}
|
||||||
|
if (dev->link[0].info->version < 3) {
|
||||||
mod_set_rateinc(dev, output->nr);
|
mod_set_rateinc(dev, output->nr);
|
||||||
mod_set_incs(output);
|
mod_set_incs(output);
|
||||||
|
}
|
||||||
mod->Control |= CHANNEL_CONTROL_ENABLE_SOURCE;
|
mod->Control |= CHANNEL_CONTROL_ENABLE_SOURCE;
|
||||||
|
|
||||||
ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr));
|
ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr));
|
||||||
if (dev->link[0].info->version == 2)
|
if (dev->link[0].info->version == 2)
|
||||||
if (mod_SendChannelCommand(dev, Channel, CHANNEL_CONTROL_CMD_UNMUTE))
|
if (mod_SendChannelCommand(dev, Channel,
|
||||||
|
CHANNEL_CONTROL_CMD_UNMUTE))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
pr_info("DDBridge: mod_output_start %d.%d\n", dev->nr, output->nr);
|
pr_info("DDBridge: mod_output_start %d.%d ctrl=%08x\n",
|
||||||
|
dev->nr, output->nr, mod->Control);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,9 +412,11 @@ int ddbridge_mod_output_start(struct ddb_output *output)
|
|||||||
static int mod_write_max2871(struct ddb *dev, u32 val)
|
static int mod_write_max2871(struct ddb *dev, u32 val)
|
||||||
{
|
{
|
||||||
ddbwritel(dev, val, MAX2871_OUTDATA);
|
ddbwritel(dev, val, MAX2871_OUTDATA);
|
||||||
ddbwritel(dev, MAX2871_CONTROL_CE | MAX2871_CONTROL_WRITE, MAX2871_CONTROL);
|
ddbwritel(dev, MAX2871_CONTROL_CE | MAX2871_CONTROL_WRITE,
|
||||||
while(1) {
|
MAX2871_CONTROL);
|
||||||
|
while (1) {
|
||||||
u32 ControlReg = ddbreadl(dev, MAX2871_CONTROL);
|
u32 ControlReg = ddbreadl(dev, MAX2871_CONTROL);
|
||||||
|
|
||||||
if (ControlReg == 0xFFFFFFFF)
|
if (ControlReg == 0xFFFFFFFF)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
if ((ControlReg & MAX2871_CONTROL_WRITE) == 0)
|
if ((ControlReg & MAX2871_CONTROL_WRITE) == 0)
|
||||||
@ -406,57 +425,61 @@ static int mod_write_max2871(struct ddb *dev, u32 val)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mod_setup_max2871(struct ddb *dev)
|
static u32 max2871_fsm[6] = {
|
||||||
|
0x00730040, 0x600080A1, 0x510061C2, 0x010000CB, 0x6199003C, 0x60440005,
|
||||||
|
};
|
||||||
|
|
||||||
|
static u32 max2871_sdr[6] = {
|
||||||
|
0x007A8098, 0x600080C9, 0x510061C2, 0x010000CB, 0x6199003C, 0x60440005
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mod_setup_max2871(struct ddb *dev, u32 *reg)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
int i;
|
int i, j;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
ddbwritel(dev, MAX2871_CONTROL_CE, MAX2871_CONTROL);
|
ddbwritel(dev, MAX2871_CONTROL_CE, MAX2871_CONTROL);
|
||||||
|
msleep(30);
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
status = mod_write_max2871(dev, 0x00440005);
|
for (j = 5; j >= 0; j--) {
|
||||||
if (status)
|
val = reg[j];
|
||||||
break;
|
|
||||||
status = mod_write_max2871(dev, 0x6199003C);
|
if (j == 4)
|
||||||
if (status)
|
val &= 0xFFFFFEDF;
|
||||||
break;
|
status = mod_write_max2871(dev, reg[j]);
|
||||||
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)
|
if (status)
|
||||||
break;
|
break;
|
||||||
msleep(30);
|
msleep(30);
|
||||||
} while(0);
|
}
|
||||||
|
}
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
u32 ControlReg = ddbreadl(dev, MAX2871_CONTROL);
|
u32 ControlReg;
|
||||||
|
|
||||||
|
if (reg[3] & (1 << 24))
|
||||||
|
msleep(100);
|
||||||
|
ControlReg = ddbreadl(dev, MAX2871_CONTROL);
|
||||||
|
|
||||||
if ((ControlReg & MAX2871_CONTROL_LOCK) == 0)
|
if ((ControlReg & MAX2871_CONTROL_LOCK) == 0)
|
||||||
status = -EIO;
|
status = -EIO;
|
||||||
|
status = mod_write_max2871(dev, reg[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan,
|
||||||
static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan, u32 MaxUsedChannels)
|
u32 MaxUsedChannels)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
u32 Capacity;
|
u32 Capacity;
|
||||||
u32 tmp = ddbreadl(dev, FSM_STATUS);
|
u32 tmp = ddbreadl(dev, FSM_STATUS);
|
||||||
|
|
||||||
if ((tmp & FSM_STATUS_READY) == 0) {
|
if ((tmp & FSM_STATUS_READY) == 0) {
|
||||||
status = mod_setup_max2871(dev);
|
status = mod_setup_max2871(dev, max2871_fsm);
|
||||||
if (status)
|
if (status)
|
||||||
return status;
|
return status;
|
||||||
ddbwritel(dev, FSM_CMD_RESET, FSM_CONTROL);
|
ddbwritel(dev, FSM_CMD_RESET, FSM_CONTROL);
|
||||||
msleep(10);
|
msleep(20);
|
||||||
|
|
||||||
tmp = ddbreadl(dev, FSM_STATUS);
|
tmp = ddbreadl(dev, FSM_STATUS);
|
||||||
if ((tmp & FSM_STATUS_READY) == 0)
|
if ((tmp & FSM_STATUS_READY) == 0)
|
||||||
@ -468,7 +491,7 @@ static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan, u32 MaxUsedChannels
|
|||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
ddbwritel(dev, FSM_CMD_SETUP, FSM_CONTROL);
|
ddbwritel(dev, FSM_CMD_SETUP, FSM_CONTROL);
|
||||||
msleep(10);
|
msleep(20);
|
||||||
tmp = ddbreadl(dev, FSM_STATUS);
|
tmp = ddbreadl(dev, FSM_STATUS);
|
||||||
|
|
||||||
if ((tmp & FSM_STATUS_QAMREADY) == 0)
|
if ((tmp & FSM_STATUS_QAMREADY) == 0)
|
||||||
@ -478,7 +501,7 @@ static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan, u32 MaxUsedChannels
|
|||||||
MaxUsedChannels = (Capacity & FSM_CAPACITY_CUR) >> 16;
|
MaxUsedChannels = (Capacity & FSM_CAPACITY_CUR) >> 16;
|
||||||
|
|
||||||
pr_info("DDBridge: max used chan = %u\n", MaxUsedChannels);
|
pr_info("DDBridge: max used chan = %u\n", MaxUsedChannels);
|
||||||
if (MaxUsedChannels <= 1 )
|
if (MaxUsedChannels <= 1)
|
||||||
ddbwritel(dev, FSM_GAIN_N1, FSM_GAIN);
|
ddbwritel(dev, FSM_GAIN_N1, FSM_GAIN);
|
||||||
else if (MaxUsedChannels <= 2)
|
else if (MaxUsedChannels <= 2)
|
||||||
ddbwritel(dev, FSM_GAIN_N2, FSM_GAIN);
|
ddbwritel(dev, FSM_GAIN_N2, FSM_GAIN);
|
||||||
@ -500,83 +523,12 @@ static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan, u32 MaxUsedChannels
|
|||||||
|
|
||||||
static int mod_set_vga(struct ddb *dev, u32 Gain)
|
static int mod_set_vga(struct ddb *dev, u32 Gain)
|
||||||
{
|
{
|
||||||
if( Gain > 255 )
|
if (Gain > 255)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
ddbwritel(dev, Gain, RF_VGA);
|
ddbwritel(dev, Gain, RF_VGA);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mod_get_vga(struct ddb *dev, u32 *pGain)
|
|
||||||
{
|
|
||||||
*pGain = ddbreadl(dev, RF_VGA);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
static void TemperatureMonitorSetFan(struct ddb *dev)
|
|
||||||
{
|
|
||||||
u32 tqam, pwm;
|
|
||||||
|
|
||||||
if ((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0) {
|
|
||||||
pr_info("DDBridge: Over temperature condition\n");
|
|
||||||
dev->OverTemperatureError = 1;
|
|
||||||
}
|
|
||||||
tqam = (ddbreadl(dev, TEMPMON2_QAMCORE) >> 8) & 0xFF;
|
|
||||||
if (tqam & 0x80)
|
|
||||||
tqam = 0;
|
|
||||||
|
|
||||||
pwm = (ddbreadl(dev, TEMPMON_FANCONTROL) >> 8) & 0x0F;
|
|
||||||
if (pwm > 10)
|
|
||||||
pwm = 10;
|
|
||||||
|
|
||||||
if (tqam >= dev->temp_tab[pwm]) {
|
|
||||||
while( pwm < 10 && tqam >= dev->temp_tab[pwm + 1])
|
|
||||||
pwm += 1;
|
|
||||||
} else {
|
|
||||||
while( pwm > 1 && tqam < dev->temp_tab[pwm - 2])
|
|
||||||
pwm -= 1;
|
|
||||||
}
|
|
||||||
ddbwritel(dev, (pwm << 8), TEMPMON_FANCONTROL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void temp_handler(unsigned long data)
|
|
||||||
{
|
|
||||||
struct ddb *dev = (struct ddb *) data;
|
|
||||||
|
|
||||||
pr_info("DDBridge: temp_handler\n");
|
|
||||||
|
|
||||||
spin_lock(&dev->temp_lock);
|
|
||||||
TemperatureMonitorSetFan(dev);
|
|
||||||
spin_unlock(&dev->temp_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int TemperatureMonitorInit(struct ddb *dev, int FirstTime) {
|
|
||||||
int status = 0;
|
|
||||||
|
|
||||||
spin_lock_irq(&dev->temp_lock);
|
|
||||||
if (FirstTime) {
|
|
||||||
static u8 TemperatureTable[11] = {30,35,40,45,50,55,60,65,70,75,80};
|
|
||||||
|
|
||||||
memcpy(dev->temp_tab, TemperatureTable, sizeof(TemperatureTable));
|
|
||||||
}
|
|
||||||
dev->handler[0][8] = temp_handler;
|
|
||||||
dev->handler_data[0][8] = (unsigned long) dev;
|
|
||||||
ddbwritel(dev, (TEMPMON_CONTROL_OVERTEMP | TEMPMON_CONTROL_AUTOSCAN |
|
|
||||||
TEMPMON_CONTROL_INTENABLE),
|
|
||||||
TEMPMON_CONTROL);
|
|
||||||
ddbwritel(dev, (3 << 8), TEMPMON_FANCONTROL);
|
|
||||||
|
|
||||||
dev->OverTemperatureError =
|
|
||||||
((ddbreadl(dev, TEMPMON_CONTROL) & TEMPMON_CONTROL_OVERTEMP ) != 0);
|
|
||||||
if (dev->OverTemperatureError) {
|
|
||||||
pr_info("DDBridge: Over temperature condition\n");
|
|
||||||
status = -1;
|
|
||||||
}
|
|
||||||
TemperatureMonitorSetFan(dev);
|
|
||||||
spin_unlock_irq(&dev->temp_lock);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@ -741,7 +693,8 @@ static int mod_set_si598(struct ddb *dev, u32 freq)
|
|||||||
((u32)(Data[1] & 0xE0) >> 6)) + 1;
|
((u32)(Data[1] & 0xE0) >> 6)) + 1;
|
||||||
fDCO = fOut * (u64)(HSDiv * N);
|
fDCO = fOut * (u64)(HSDiv * N);
|
||||||
m_fXtal = fDCO << 28;
|
m_fXtal = fDCO << 28;
|
||||||
pr_info("DDBridge: fxtal %016llx rfreq %016llx\n", m_fXtal, RFreq);
|
pr_info("DDBridge: fxtal %016llx rfreq %016llx\n",
|
||||||
|
m_fXtal, RFreq);
|
||||||
|
|
||||||
m_fXtal += RFreq >> 1;
|
m_fXtal += RFreq >> 1;
|
||||||
m_fXtal = div64_u64(m_fXtal, RFreq);
|
m_fXtal = div64_u64(m_fXtal, RFreq);
|
||||||
@ -942,8 +895,8 @@ static int mod_init_dac_input(struct ddb *dev)
|
|||||||
Seek = 1;
|
Seek = 1;
|
||||||
for (Sample = 0; Sample < 32; Sample += 1) {
|
for (Sample = 0; Sample < 32; Sample += 1) {
|
||||||
/* printk(" %2d: %d %2d %2d\n",
|
/* printk(" %2d: %d %2d %2d\n",
|
||||||
Sample, SeekTable[Sample], SetTable[Sample],
|
* Sample, SeekTable[Sample], SetTable[Sample],
|
||||||
HldTable[Sample]);
|
* HldTable[Sample]);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (Sample1 == 0xFF && SeekTable[Sample] == 1 && Seek == 0)
|
if (Sample1 == 0xFF && SeekTable[Sample] == 1 && Seek == 0)
|
||||||
@ -1236,7 +1189,8 @@ static int mod_init_1(struct ddb *dev, u32 Frequency)
|
|||||||
FrequencyCH10 = flash->DataSet[0].FlatStart + 4;
|
FrequencyCH10 = flash->DataSet[0].FlatStart + 4;
|
||||||
DownFrequency = Frequency + 9 * 8 + FrequencyCH10 +
|
DownFrequency = Frequency + 9 * 8 + FrequencyCH10 +
|
||||||
UP1Frequency + UP2Frequency;
|
UP1Frequency + UP2Frequency;
|
||||||
pr_info("DDBridge: CH10 = %d, Down = %d\n", FrequencyCH10, DownFrequency);
|
pr_info("DDBridge: CH10 = %d, Down = %d\n",
|
||||||
|
FrequencyCH10, DownFrequency);
|
||||||
|
|
||||||
if ((FrequencyCH10 + 9 * 8) > (flash->DataSet[0].FlatEnd - 4)) {
|
if ((FrequencyCH10 + 9 * 8) > (flash->DataSet[0].FlatEnd - 4)) {
|
||||||
pr_err("DDBridge: Frequency out of range %d\n", FrequencyCH10);
|
pr_err("DDBridge: Frequency out of range %d\n", FrequencyCH10);
|
||||||
@ -1288,10 +1242,10 @@ fail:
|
|||||||
#define FACTOR (1ULL << 22)
|
#define FACTOR (1ULL << 22)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
double Increment = FACTOR*PACKET_CLOCKS/double(m_OutputBitrate);
|
* double Increment = FACTOR*PACKET_CLOCKS/double(m_OutputBitrate);
|
||||||
double Decrement = FACTOR*PACKET_CLOCKS/double(m_InputBitrate);
|
* double Decrement = FACTOR*PACKET_CLOCKS/double(m_InputBitrate);
|
||||||
27000000 * 1504 * 2^22 / (6900000 * 188 / 204) = 26785190066.1
|
* 27000000 * 1504 * 2^22 / (6900000 * 188 / 204) = 26785190066.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ddbridge_mod_rate_handler(unsigned long data)
|
void ddbridge_mod_rate_handler(unsigned long data)
|
||||||
{
|
{
|
||||||
@ -1473,11 +1427,85 @@ void ddbridge_mod_rate_handler(unsigned long data)
|
|||||||
PCRAdjustExtFrac, PCRCorr, mod->PCRIncrement);
|
PCRAdjustExtFrac, PCRCorr, mod->PCRIncrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mod_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp)
|
static int mod3_set_base_frequency(struct ddb *dev, u32 frequency)
|
||||||
|
{
|
||||||
|
u64 tmp;
|
||||||
|
|
||||||
|
if (frequency % 1000)
|
||||||
|
return -EINVAL;
|
||||||
|
if ((frequency < 114000000) || (frequency > 874000000))
|
||||||
|
return -EINVAL;
|
||||||
|
dev->mod_base.frequency = frequency;
|
||||||
|
tmp = frequency;
|
||||||
|
tmp <<= 33;
|
||||||
|
tmp = div64_s64(tmp, 4915200000);
|
||||||
|
pr_info("set base frequency = %u regs = 0x%08llx\n", frequency, tmp);
|
||||||
|
ddbwritel(dev, (u32) tmp, RFDAC_FCW);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mod3_set_cfcw(struct ddb_mod *mod, u32 f)
|
||||||
{
|
{
|
||||||
struct ddb *dev = mod->port->dev;
|
struct ddb *dev = mod->port->dev;
|
||||||
|
s32 freq = f;
|
||||||
|
s32 dcf = dev->mod_base.frequency;
|
||||||
|
s64 tmp, srdac = 245760000;
|
||||||
|
u32 cfcw;
|
||||||
|
|
||||||
switch(tvp->cmd) {
|
tmp = ((s64) (freq - dcf)) << 32;
|
||||||
|
tmp = div64_s64(tmp, srdac);
|
||||||
|
cfcw = (u32) tmp;
|
||||||
|
pr_info("f=%u cfcw = %08x nr = %u\n", f, cfcw, mod->port->nr);
|
||||||
|
ddbwritel(dev, cfcw, SDR_CHANNEL_CFCW(mod->port->nr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mod3_set_frequency(struct ddb_mod *mod, u32 frequency)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
struct ddb *dev = mod->port->dev;
|
||||||
|
|
||||||
|
if (frequency % 1000)
|
||||||
|
return -EINVAL;
|
||||||
|
if ((frequency < 114000000) || (frequency > 874000000))
|
||||||
|
return -EINVAL;
|
||||||
|
if (frequency > dev->mod_base.frequency)
|
||||||
|
if (frequency - dev->mod_base.frequency > 100000000)
|
||||||
|
return -EINVAL;
|
||||||
|
else
|
||||||
|
if (dev->mod_base.frequency - frequency > 100000000)
|
||||||
|
return -EINVAL;
|
||||||
|
#endif
|
||||||
|
mod3_set_cfcw(mod, frequency);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mod3_set_ari(struct ddb_mod *mod, u32 rate)
|
||||||
|
{
|
||||||
|
ddbwritel(mod->port->dev, rate, SDR_CHANNEL_ARICW(mod->port->nr));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int mod3_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp)
|
||||||
|
{
|
||||||
|
switch (tvp->cmd) {
|
||||||
|
case MODULATOR_OUTPUT_ARI:
|
||||||
|
return mod3_set_ari(mod, tvp->u.data);
|
||||||
|
|
||||||
|
case MODULATOR_FREQUENCY:
|
||||||
|
return mod3_set_frequency(mod, tvp->u.data);
|
||||||
|
|
||||||
|
case MODULATOR_BASE_FREQUENCY:
|
||||||
|
return mod3_set_base_frequency(mod->port->dev, tvp->u.data);
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mod_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp)
|
||||||
|
{
|
||||||
|
if (mod->port->dev->link[0].info->version == 3)
|
||||||
|
return mod3_prop_proc(mod, tvp);
|
||||||
|
switch (tvp->cmd) {
|
||||||
case MODULATOR_SYMBOL_RATE:
|
case MODULATOR_SYMBOL_RATE:
|
||||||
return mod_set_symbolrate(mod, tvp->u.data);
|
return mod_set_symbolrate(mod, tvp->u.data);
|
||||||
|
|
||||||
@ -1492,6 +1520,7 @@ static int mod_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp)
|
|||||||
|
|
||||||
case MODULATOR_INPUT_BITRATE:
|
case MODULATOR_INPUT_BITRATE:
|
||||||
return mod_set_ibitrate(mod, tvp->u.data);
|
return mod_set_ibitrate(mod, tvp->u.data);
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1504,17 +1533,21 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
|||||||
struct ddb_mod *mod = &dev->mod[output->nr];
|
struct ddb_mod *mod = &dev->mod[output->nr];
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (dev->link[0].info->version == 3 && cmd != FE_SET_PROPERTY)
|
||||||
|
return -EINVAL;
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case FE_SET_PROPERTY:
|
case FE_SET_PROPERTY:
|
||||||
{
|
{
|
||||||
struct dtv_properties *tvps = (struct dtv_properties __user *) parg;
|
struct dtv_properties *tvps =
|
||||||
|
(struct dtv_properties __user *) parg;
|
||||||
struct dtv_property *tvp = NULL;
|
struct dtv_property *tvp = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
|
if ((tvps->num == 0) || (tvps->num > DTV_IOCTL_MAX_MSGS))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
tvp = kmalloc(tvps->num * sizeof(struct dtv_property), GFP_KERNEL);
|
tvp = kmalloc(tvps->num * sizeof(struct dtv_property),
|
||||||
|
GFP_KERNEL);
|
||||||
if (!tvp) {
|
if (!tvp) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
@ -1525,11 +1558,12 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
for (i = 0; i < tvps->num; i++) {
|
for (i = 0; i < tvps->num; i++) {
|
||||||
if ((ret = mod_prop_proc(mod, tvp + i)) < 0)
|
ret = mod_prop_proc(mod, tvp + i);
|
||||||
|
if (ret < 0)
|
||||||
goto out;
|
goto out;
|
||||||
(tvp + i)->result = ret;
|
(tvp + i)->result = ret;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
kfree(tvp);
|
kfree(tvp);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1588,13 +1622,18 @@ static int mod_init_2(struct ddb *dev, u32 Frequency)
|
|||||||
dev->mod_base.frequency = Frequency;
|
dev->mod_base.frequency = Frequency;
|
||||||
status = mod_fsm_setup(dev, 0, 0);
|
status = mod_fsm_setup(dev, 0, 0);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
pr_err("FSM setup failed!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < streams; i++) {
|
for (i = 0; i < streams; i++) {
|
||||||
struct ddb_mod *mod = &dev->mod[i];
|
struct ddb_mod *mod = &dev->mod[i];
|
||||||
|
|
||||||
mod->port = &dev->port[i];
|
mod->port = &dev->port[i];
|
||||||
mod_set_modulation(mod, QAM_256);
|
mod_set_modulation(mod, QAM_256);
|
||||||
mod_set_symbolrate(mod, 6900000);
|
mod_set_symbolrate(mod, 6900000);
|
||||||
mod_set_frequency(mod, 114000000 + i * 8000000);
|
mod_set_frequency(mod, dev->mod_base.frequency + i * 8000000);
|
||||||
}
|
}
|
||||||
if (streams <= 8)
|
if (streams <= 8)
|
||||||
mod_set_vga(dev, RF_VGA_GAIN_N8);
|
mod_set_vga(dev, RF_VGA_GAIN_N8);
|
||||||
@ -1607,11 +1646,141 @@ static int mod_init_2(struct ddb *dev, u32 Frequency)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************/
|
||||||
|
|
||||||
|
static u32 vsb13500[64] = {
|
||||||
|
0x0000000E, 0x00010004, 0x00020003, 0x00030009,
|
||||||
|
0x0004FFFA, 0x00050002, 0x0006FFF8, 0x0007FFF0,
|
||||||
|
0x00080000, 0x0009FFEA, 0x000A0001, 0x000B0003,
|
||||||
|
0x000CFFF9, 0x000D0025, 0x000E0004, 0x000F001F,
|
||||||
|
0x00100023, 0x0011FFEE, 0x00120020, 0x0013FFD0,
|
||||||
|
0x0014FFD5, 0x0015FFED, 0x0016FF8B, 0x0017000B,
|
||||||
|
0x0018FFC8, 0x0019FFF1, 0x001A009E, 0x001BFFEF,
|
||||||
|
0x001C013B, 0x001D00CB, 0x001E0031, 0x001F05F6,
|
||||||
|
|
||||||
|
0x0040FFFF, 0x00410004, 0x0042FFF8, 0x0043FFFE,
|
||||||
|
0x0044FFFA, 0x0045FFF3, 0x00460003, 0x0047FFF4,
|
||||||
|
0x00480005, 0x0049000D, 0x004A0000, 0x004B0022,
|
||||||
|
0x004C0005, 0x004D000D, 0x004E0013, 0x004FFFDF,
|
||||||
|
0x00500007, 0x0051FFD4, 0x0052FFD2, 0x0053FFFD,
|
||||||
|
0x0054FFB7, 0x00550021, 0x00560009, 0x00570010,
|
||||||
|
0x00580097, 0x00590003, 0x005A009D, 0x005B004F,
|
||||||
|
0x005CFF89, 0x005D0097, 0x005EFD42, 0x005FFCBE
|
||||||
|
};
|
||||||
|
|
||||||
|
static u32 stage2[16] = {
|
||||||
|
0x0080FFFF, 0x00810000, 0x00820005, 0x00830000,
|
||||||
|
0x0084FFF0, 0x00850000, 0x00860029, 0x00870000,
|
||||||
|
0x0088FFA2, 0x0089FFFF, 0x008A00C9, 0x008B000C,
|
||||||
|
0x008CFE49, 0x008DFF9B, 0x008E04D4, 0x008F07FF
|
||||||
|
};
|
||||||
|
|
||||||
|
static void mod_set_sdr_table(struct ddb_mod *mod, u32 *tab, u32 len)
|
||||||
|
{
|
||||||
|
struct ddb *dev = mod->port->dev;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
ddbwritel(dev, tab[i], SDR_CHANNEL_SETFIR(mod->port->nr));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rfdac_init(struct ddb *dev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
ddbwritel(dev, RFDAC_CMD_POWERDOWN, RFDAC_CONTROL);
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
msleep(20);
|
||||||
|
tmp = ddbreadl(dev, RFDAC_CONTROL);
|
||||||
|
if ((tmp & RFDAC_CMD_STATUS) == 0x00)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (tmp & 0x80)
|
||||||
|
return -1;
|
||||||
|
pr_info("sync %d:%08x\n", i, tmp);
|
||||||
|
ddbwritel(dev, RFDAC_CMD_RESET, RFDAC_CONTROL);
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
msleep(20);
|
||||||
|
tmp = ddbreadl(dev, RFDAC_CONTROL);
|
||||||
|
if ((tmp & RFDAC_CMD_STATUS) == 0x00)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (tmp & 0x80)
|
||||||
|
return -1;
|
||||||
|
pr_info("sync %d:%08x\n", i, tmp);
|
||||||
|
ddbwritel(dev, RFDAC_CMD_SETUP, RFDAC_CONTROL);
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
msleep(20);
|
||||||
|
tmp = ddbreadl(dev, RFDAC_CONTROL);
|
||||||
|
if ((tmp & RFDAC_CMD_STATUS) == 0x00)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (tmp & 0x80)
|
||||||
|
return -1;
|
||||||
|
pr_info("sync %d:%08x\n", i, tmp);
|
||||||
|
ddbwritel(dev, 0x01, JESD204B_BASE);
|
||||||
|
for (i = 0; i < 400; i++) {
|
||||||
|
msleep(20);
|
||||||
|
tmp = ddbreadl(dev, JESD204B_BASE);
|
||||||
|
if ((tmp & 0xc0000000) == 0xc0000000)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pr_info("sync %d:%08x\n", i, tmp);
|
||||||
|
if ((tmp & 0xc0000000) != 0xc0000000)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mod_init_3(struct ddb *dev, u32 Frequency)
|
||||||
|
{
|
||||||
|
int streams = dev->link[0].info->port_num;
|
||||||
|
int i, ret = 0;
|
||||||
|
|
||||||
|
mod_set_vga(dev, 64);
|
||||||
|
ret = mod_setup_max2871(dev, max2871_sdr);
|
||||||
|
if (ret)
|
||||||
|
pr_err("DDBridge: PLL setup failed\n");
|
||||||
|
ret = rfdac_init(dev);
|
||||||
|
if (ret)
|
||||||
|
ret = rfdac_init(dev);
|
||||||
|
if (ret)
|
||||||
|
pr_err("DDBridge: RFDAC setup failed\n");
|
||||||
|
|
||||||
|
for (i = 0; i < streams; i++) {
|
||||||
|
struct ddb_mod *mod = &dev->mod[i];
|
||||||
|
|
||||||
|
mod->port = &dev->port[i];
|
||||||
|
mod_set_sdr_table(mod, vsb13500, 64);
|
||||||
|
mod_set_sdr_table(mod, stage2, 16);
|
||||||
|
}
|
||||||
|
ddbwritel(dev, 0x1800, 0x244);
|
||||||
|
ddbwritel(dev, 0x01, 0x240);
|
||||||
|
|
||||||
|
mod3_set_base_frequency(dev, 602000000);
|
||||||
|
for (i = 0; i < streams; i++) {
|
||||||
|
struct ddb_mod *mod = &dev->mod[i];
|
||||||
|
|
||||||
|
ddbwritel(dev, 0x00, SDR_CHANNEL_CONTROL(i));
|
||||||
|
ddbwritel(dev, 0x06, SDR_CHANNEL_CONFIG(i));
|
||||||
|
ddbwritel(dev, 0x70800000, SDR_CHANNEL_ARICW(i));
|
||||||
|
mod3_set_frequency(mod, Frequency + 7000000 * i);
|
||||||
|
|
||||||
|
ddbwritel(dev, 0x00011f80, SDR_CHANNEL_RGAIN(i));
|
||||||
|
ddbwritel(dev, 0x00001000, SDR_CHANNEL_FM1GAIN(i));
|
||||||
|
ddbwritel(dev, 0x00000800, SDR_CHANNEL_FM2GAIN(i));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int ddbridge_mod_init(struct ddb *dev)
|
int ddbridge_mod_init(struct ddb *dev)
|
||||||
{
|
{
|
||||||
if (dev->link[0].info->version <= 1)
|
if (dev->link[0].info->version <= 1)
|
||||||
return mod_init_1(dev, 722000000);
|
return mod_init_1(dev, 722000000);
|
||||||
if (dev->link[0].info->version == 2)
|
if (dev->link[0].info->version == 2)
|
||||||
return mod_init_2(dev, 114000000);
|
return mod_init_2(dev, 114000000);
|
||||||
|
if (dev->link[0].info->version == 3)
|
||||||
|
return mod_init_3(dev, 503250000);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming
|
* ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2015 Marcus Metzler <mocm@metzlerbros.de>
|
* Copyright (C) 2010-2017Marcus Metzler <mocm@metzlerbros.de>
|
||||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||||
* Digital Devices GmbH
|
* Digital Devices GmbH
|
||||||
*
|
*
|
||||||
@ -87,7 +87,6 @@ static int ns_alloc(struct dvbnss *nss)
|
|||||||
dev->ns[i].fe = input;
|
dev->ns[i].fe = input;
|
||||||
nss->priv = &dev->ns[i];
|
nss->priv = &dev->ns[i];
|
||||||
ret = 0;
|
ret = 0;
|
||||||
/*pr_info("DDBridge: %s i=%d fe=%d\n", __func__, i, input->nr); */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ddbwritel(dev, 0x03, RTP_MASTER_CONTROL);
|
ddbwritel(dev, 0x03, RTP_MASTER_CONTROL);
|
||||||
@ -446,8 +445,6 @@ static int ns_start(struct dvbnss *nss)
|
|||||||
if (dns->fe != input)
|
if (dns->fe != input)
|
||||||
ddb_dvb_ns_input_start(dns->fe);
|
ddb_dvb_ns_input_start(dns->fe);
|
||||||
ddb_dvb_ns_input_start(input);
|
ddb_dvb_ns_input_start(input);
|
||||||
/* printk("ns start ns %u, fe %u link %u\n",
|
|
||||||
dns->nr, dns->fe->nr, dns->fe->port->lnr); */
|
|
||||||
ddbwritel(dev, reg | (dns->fe->nr << 8) | (dns->fe->port->lnr << 16),
|
ddbwritel(dev, reg | (dns->fe->nr << 8) | (dns->fe->port->lnr << 16),
|
||||||
STREAM_CONTROL(dns->nr));
|
STREAM_CONTROL(dns->nr));
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ddbridge-regs.h: Digital Devices PCIe bridge driver
|
* ddbridge-regs.h: Digital Devices PCIe bridge driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2016 Digital Devices GmbH
|
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#define CUR_REGISTERMAP_VERSION_V1 0x00010001
|
#define CUR_REGISTERMAP_VERSION_V1 0x00010001
|
||||||
#define CUR_REGISTERMAP_VERSION_V2 0x00020000
|
#define CUR_REGISTERMAP_VERSION_V2 0x00020000
|
||||||
|
#define CUR_REGISTERMAP_VERSION_022X 0x00020001
|
||||||
|
|
||||||
#define HARDWARE_VERSION 0x00000000
|
#define HARDWARE_VERSION 0x00000000
|
||||||
#define REGISTERMAP_VERSION 0x00000004
|
#define REGISTERMAP_VERSION 0x00000004
|
||||||
@ -57,9 +58,9 @@
|
|||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* Interrupt controller
|
/* Interrupt controller
|
||||||
How many MSI's are available depends on HW (Min 2 max 8)
|
* How many MSI's are available depends on HW (Min 2 max 8)
|
||||||
How many are usable also depends on Host platform
|
* How many are usable also depends on Host platform
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define INTERRUPT_BASE (0x40)
|
#define INTERRUPT_BASE (0x40)
|
||||||
|
|
||||||
@ -166,11 +167,13 @@
|
|||||||
#define TEMPMON_FANPWM (0x00000F00) // PWM speed in 10% steps
|
#define TEMPMON_FANPWM (0x00000F00) // PWM speed in 10% steps
|
||||||
#define TEMPMON_FANTACHO (0x000000FF) // Rotations in 100/min steps
|
#define TEMPMON_FANTACHO (0x000000FF) // Rotations in 100/min steps
|
||||||
|
|
||||||
// V1 Temperature Monitor
|
/* V1 Temperature Monitor
|
||||||
// Temperature Monitor TEMPMON_CONTROL & 0x8000 == 0 : ( 2x LM75A @ 0x90,0x92 )
|
* Temperature Monitor TEMPMON_CONTROL & 0x8000 == 0 : ( 2x LM75A @ 0x90,0x92 )
|
||||||
// Temperature Monitor TEMPMON_CONTROL & 0x8000 == 1 : ( 1x LM75A @ 0x90, 1x ADM1032 @ 0x9A )
|
* Temperature Monitor TEMPMON_CONTROL & 0x8000 == 1 :
|
||||||
|
* ( 1x LM75A @ 0x90, 1x ADM1032 @ 0x9A )
|
||||||
|
*/
|
||||||
|
|
||||||
#define TEMPMON1_CORE (TEMPMON_SENSOR0) // SHORT Temperature in °C x 256 (ADM1032 ext)
|
#define TEMPMON1_CORE (TEMPMON_SENSOR0) // u16 Temperature in °C x 256 (ADM1032 ext)
|
||||||
#define TEMPMON1_SENSOR1 (TEMPMON_BASE + 0x08) // SHORT Temperature in °C x 256 (LM75A 0x90)
|
#define TEMPMON1_SENSOR1 (TEMPMON_BASE + 0x08) // SHORT Temperature in °C x 256 (LM75A 0x90)
|
||||||
#define TEMPMON1_SENSOR2 (TEMPMON_BASE + 0x0C) // SHORT Temperature in °C x 256 (LM75A 0x92 or ADM1032 Int)
|
#define TEMPMON1_SENSOR2 (TEMPMON_BASE + 0x0C) // SHORT Temperature in °C x 256 (LM75A 0x92 or ADM1032 Int)
|
||||||
|
|
||||||
@ -179,6 +182,7 @@
|
|||||||
#define TEMPMON2_BOARD (TEMPMON_SENSOR0) // SHORT Temperature in °C x 256 (ADM1032 int)
|
#define TEMPMON2_BOARD (TEMPMON_SENSOR0) // SHORT Temperature in °C x 256 (ADM1032 int)
|
||||||
#define TEMPMON2_FPGACORE (TEMPMON_SENSOR1) // SHORT Temperature in °C x 256 (ADM1032 ext)
|
#define TEMPMON2_FPGACORE (TEMPMON_SENSOR1) // SHORT Temperature in °C x 256 (ADM1032 ext)
|
||||||
#define TEMPMON2_QAMCORE (TEMPMON_SENSOR2) // SHORT Temperature in °C x 256 (ADM1032 ext)
|
#define TEMPMON2_QAMCORE (TEMPMON_SENSOR2) // SHORT Temperature in °C x 256 (ADM1032 ext)
|
||||||
|
#define TEMPMON2_DACCORE (TEMPMON_SENSOR2) // SHORT Temperature in °C x 256 (ADM1032 ext)
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
/* I2C Master Controller */
|
/* I2C Master Controller */
|
||||||
@ -242,7 +246,7 @@
|
|||||||
#define LNB_CMD_HIGH 4
|
#define LNB_CMD_HIGH 4
|
||||||
#define LNB_CMD_OFF 5
|
#define LNB_CMD_OFF 5
|
||||||
#define LNB_CMD_DISEQC 6
|
#define LNB_CMD_DISEQC 6
|
||||||
#define LNB_CMD_UNI 7
|
#define LNB_CMD_SCIF 7
|
||||||
|
|
||||||
#define LNB_BUSY (1ULL << 4)
|
#define LNB_BUSY (1ULL << 4)
|
||||||
#define LNB_TONE (1ULL << 15)
|
#define LNB_TONE (1ULL << 15)
|
||||||
@ -330,12 +334,12 @@
|
|||||||
/* Muxout from VCO (usually = Lock) */
|
/* Muxout from VCO (usually = Lock) */
|
||||||
#define VCO3_CONTROL_MUXOUT (0x00000004)
|
#define VCO3_CONTROL_MUXOUT (0x00000004)
|
||||||
|
|
||||||
// V2
|
/* V2 */
|
||||||
|
|
||||||
#define MAX2871_BASE (0xC0)
|
#define MAX2871_BASE (0xC0)
|
||||||
#define MAX2871_CONTROL (MAX2871_BASE + 0x00)
|
#define MAX2871_CONTROL (MAX2871_BASE + 0x00)
|
||||||
#define MAX2871_OUTDATA (MAX2871_BASE + 0x04) // 32 Bit
|
#define MAX2871_OUTDATA (MAX2871_BASE + 0x04)
|
||||||
#define MAX2871_INDATA (MAX2871_BASE + 0x08) // 32 Bit
|
#define MAX2871_INDATA (MAX2871_BASE + 0x08)
|
||||||
#define MAX2871_CONTROL_WRITE (0x00000001) // 1 = Trigger write, resets when done
|
#define MAX2871_CONTROL_WRITE (0x00000001) // 1 = Trigger write, resets when done
|
||||||
#define MAX2871_CONTROL_CE (0x00000002) // 0 = Put VCO into power down
|
#define MAX2871_CONTROL_CE (0x00000002) // 0 = Put VCO into power down
|
||||||
#define MAX2871_CONTROL_MUXOUT (0x00000004) // Muxout from VCO
|
#define MAX2871_CONTROL_MUXOUT (0x00000004) // Muxout from VCO
|
||||||
@ -379,10 +383,10 @@
|
|||||||
#define RF_ATTENUATOR (0xD8)
|
#define RF_ATTENUATOR (0xD8)
|
||||||
#define RF_ATTENUATOR (0xD8)
|
#define RF_ATTENUATOR (0xD8)
|
||||||
/* 0x00 = 0 dB
|
/* 0x00 = 0 dB
|
||||||
0x01 = 1 dB
|
* 0x01 = 1 dB
|
||||||
...
|
* ...
|
||||||
0x1F = 31 dB
|
* 0x1F = 31 dB
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define RF_VGA (0xDC)
|
#define RF_VGA (0xDC)
|
||||||
/* Only V2 */
|
/* Only V2 */
|
||||||
@ -409,9 +413,9 @@
|
|||||||
#define RF_POWER_CONTROL_VALID (0x00000500)
|
#define RF_POWER_CONTROL_VALID (0x00000500)
|
||||||
|
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------
|
/*
|
||||||
Output control
|
* Output control
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define IQOUTPUT_BASE (0x240)
|
#define IQOUTPUT_BASE (0x240)
|
||||||
#define IQOUTPUT_CONTROL (IQOUTPUT_BASE + 0x00)
|
#define IQOUTPUT_CONTROL (IQOUTPUT_BASE + 0x00)
|
||||||
@ -552,3 +556,76 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// V2
|
||||||
|
|
||||||
|
// MAX2871 same as DVB Modulator V2
|
||||||
|
|
||||||
|
#define RFDAC_BASE (0x200)
|
||||||
|
#define RFDAC_CONTROL (RFDAC_BASE + 0x00)
|
||||||
|
|
||||||
|
#define RFDAC_CMD_MASK (0x00000087)
|
||||||
|
#define RFDAC_CMD_STATUS (0x00000080)
|
||||||
|
#define RFDAC_CMD_RESET (0x00000080)
|
||||||
|
#define RFDAC_CMD_POWERDOWN (0x00000081)
|
||||||
|
#define RFDAC_CMD_SETUP (0x00000082)
|
||||||
|
|
||||||
|
#define RFDAC_STATUS (RFDAC_BASE + 0x00)
|
||||||
|
#define RFDAC_STATUS_READY (0x00010000)
|
||||||
|
#define RFDAC_STATUS_DACREADY (0x00020000)
|
||||||
|
|
||||||
|
#define RFDAC_FCW (RFDAC_BASE + 0x10)
|
||||||
|
|
||||||
|
//
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
|
||||||
|
#define JESD204B_BASE (0x280)
|
||||||
|
|
||||||
|
// Additional Status Bits
|
||||||
|
|
||||||
|
#define DMA_PCIE_LANES_MASK (0x00070000)
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------
|
||||||
|
// Modulator Channels, partially compatible to DVB Modulator V1
|
||||||
|
|
||||||
|
#define SDR_CHANNEL_BASE (0x800)
|
||||||
|
|
||||||
|
#define SDR_CHANNEL_CONTROL(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x00)
|
||||||
|
#define SDR_CHANNEL_CONFIG(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x04)
|
||||||
|
#define SDR_CHANNEL_CFCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x08)
|
||||||
|
#define SDR_CHANNEL_ARICW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x0C)
|
||||||
|
#define SDR_CHANNEL_RGAIN(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x10)
|
||||||
|
#define SDR_CHANNEL_SETFIR(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x14)
|
||||||
|
|
||||||
|
#define SDR_CHANNEL_FMDCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x20)
|
||||||
|
#define SDR_CHANNEL_FM1FCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x24)
|
||||||
|
#define SDR_CHANNEL_FM2FCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x28)
|
||||||
|
#define SDR_CHANNEL_FM1GAIN(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x2C)
|
||||||
|
#define SDR_CHANNEL_FM2GAIN(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x30)
|
||||||
|
|
||||||
|
// Control and status bits
|
||||||
|
#define SDR_CONTROL_ENABLE_CHANNEL (0x00000004)
|
||||||
|
#define SDR_CONTROL_ENABLE_DMA (0x00000008)
|
||||||
|
#define SDR_STATUS_DMA_UNDERRUN (0x00010000)
|
||||||
|
|
||||||
|
// Config
|
||||||
|
#define SDR_CONFIG_ENABLE_FM1 (0x00000002)
|
||||||
|
#define SDR_CONFIG_ENABLE_FM2 (0x00000004)
|
||||||
|
#define SDR_CONFIG_DISABLE_ARI (0x00000010)
|
||||||
|
#define SDR_CONFIG_DISABLE_VSB (0x00000020)
|
||||||
|
|
||||||
|
// SET FIR
|
||||||
|
#define SDR_FIR_COEFF_MASK (0x00000FFF)
|
||||||
|
#define SDR_FIR_TAP_MASK (0x001F0000)
|
||||||
|
#define SDR_FIR_SELECT_MASK (0x00C00000)
|
||||||
|
#define SDR_VSB_LENGTH_MASK (0x01000000)
|
||||||
|
|
||||||
|
#define SDR_SET_FIR(select, tap, coeff, vsblen) \
|
||||||
|
((((select)<<22)&SDR_FIR_SELECT_MASK)| \
|
||||||
|
(((tap)<<16)&SDR_FIR_TAP_MASK)| \
|
||||||
|
((coeff)&SDR_FIR_COEFF_MASK)| \
|
||||||
|
(((vsblen)<<24)&SDR_VSB_LENGTH_MASK)| \
|
||||||
|
0 \
|
||||||
|
)
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ddbridge.c: Digital Devices PCIe bridge driver
|
* ddbridge.c: Digital Devices PCIe bridge driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||||
* Marcus Metzler <mocm@metzlerbros.de>
|
* Marcus Metzler <mocm@metzlerbros.de>
|
||||||
*
|
*
|
||||||
@ -113,12 +113,16 @@ static void __devexit ddb_remove(struct pci_dev *pdev)
|
|||||||
|
|
||||||
static int __devinit ddb_irq_msi(struct ddb *dev, int nr)
|
static int __devinit ddb_irq_msi(struct ddb *dev, int nr)
|
||||||
{
|
{
|
||||||
int stat;
|
int stat = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_MSI
|
#ifdef CONFIG_PCI_MSI
|
||||||
if (msi && pci_msi_enabled()) {
|
if (msi && pci_msi_enabled()) {
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
|
||||||
|
stat = pci_alloc_irq_vectors(dev->pdev, 1, nr, PCI_IRQ_MSI);
|
||||||
|
#else
|
||||||
stat = pci_enable_msi_range(dev->pdev, 1, nr);
|
stat = pci_enable_msi_range(dev->pdev, 1, nr);
|
||||||
|
#endif
|
||||||
if (stat >= 1) {
|
if (stat >= 1) {
|
||||||
dev->msi = stat;
|
dev->msi = stat;
|
||||||
pr_info("DDBridge: using %d MSI interrupt(s)\n",
|
pr_info("DDBridge: using %d MSI interrupt(s)\n",
|
||||||
@ -267,7 +271,11 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
|
|||||||
dev->link[0].ids.subdevice = id->subdevice;
|
dev->link[0].ids.subdevice = id->subdevice;
|
||||||
|
|
||||||
dev->link[0].dev = dev;
|
dev->link[0].dev = dev;
|
||||||
|
#ifdef NUM_IDS
|
||||||
|
dev->link[0].info = ddb_infos[id->driver_data];
|
||||||
|
#else
|
||||||
dev->link[0].info = (struct ddb_info *) id->driver_data;
|
dev->link[0].info = (struct ddb_info *) id->driver_data;
|
||||||
|
#endif
|
||||||
pr_info("DDBridge: device name: %s\n", dev->link[0].info->name);
|
pr_info("DDBridge: device name: %s\n", dev->link[0].info->name);
|
||||||
|
|
||||||
dev->regs_len = pci_resource_len(dev->pdev, 0);
|
dev->regs_len = pci_resource_len(dev->pdev, 0);
|
||||||
@ -311,7 +319,7 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
|
|||||||
if (ddb_init(dev) == 0)
|
if (ddb_init(dev) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ddb_irq_disable(dev);
|
ddb_irq_exit(dev);
|
||||||
fail0:
|
fail0:
|
||||||
pr_err("DDBridge: fail0\n");
|
pr_err("DDBridge: fail0\n");
|
||||||
if (dev->msi)
|
if (dev->msi)
|
||||||
@ -519,6 +527,16 @@ static struct ddb_info ddb_mod_fsm_8 = {
|
|||||||
.tempmon_irq = 8,
|
.tempmon_irq = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct ddb_info ddb_sdr = {
|
||||||
|
.type = DDB_MOD,
|
||||||
|
.name = "Digital Devices SDR",
|
||||||
|
.version = 3,
|
||||||
|
.regmap = &octopus_sdr_map,
|
||||||
|
.port_num = 16,
|
||||||
|
.temp_num = 1,
|
||||||
|
.tempmon_irq = 8,
|
||||||
|
};
|
||||||
|
|
||||||
static struct ddb_info ddb_octopro_hdin = {
|
static struct ddb_info ddb_octopro_hdin = {
|
||||||
.type = DDB_OCTOPRO_HDIN,
|
.type = DDB_OCTOPRO_HDIN,
|
||||||
.name = "Digital Devices OctopusNet Pro HDIN",
|
.name = "Digital Devices OctopusNet Pro HDIN",
|
||||||
@ -541,72 +559,83 @@ static struct ddb_info ddb_octopro = {
|
|||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
#define DDVID 0xdd01 /* Digital Devices Vendor ID */
|
#define DDB_DEVICE(_device, _subdevice, _driver_data) { \
|
||||||
|
PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, _subdevice), \
|
||||||
|
.driver_data = (kernel_ulong_t) &_driver_data }
|
||||||
|
|
||||||
#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \
|
#define DDB_DEVICE_ANY(_device) { \
|
||||||
.vendor = _vend, .device = _dev, \
|
PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, PCI_ANY_ID), \
|
||||||
.subvendor = _subvend, .subdevice = _subdev, \
|
.driver_data = (kernel_ulong_t) &ddb_none }
|
||||||
.driver_data = (unsigned long)&_driverdata }
|
|
||||||
|
|
||||||
static const struct pci_device_id ddb_id_tbl[] __devinitconst = {
|
static const struct pci_device_id ddb_id_table[] __devinitconst = {
|
||||||
DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus),
|
DDB_DEVICE(0x0002, 0x0001, ddb_octopus),
|
||||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus),
|
DDB_DEVICE(0x0003, 0x0001, ddb_octopus),
|
||||||
DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3),
|
DDB_DEVICE(0x0005, 0x0004, ddb_octopusv3),
|
||||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le),
|
DDB_DEVICE(0x0003, 0x0002, ddb_octopus_le),
|
||||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem),
|
DDB_DEVICE(0x0003, 0x0003, ddb_octopus_oem),
|
||||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini),
|
DDB_DEVICE(0x0003, 0x0010, ddb_octopus_mini),
|
||||||
DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini),
|
DDB_DEVICE(0x0005, 0x0011, ddb_octopus_mini),
|
||||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6),
|
DDB_DEVICE(0x0003, 0x0020, ddb_v6),
|
||||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5),
|
DDB_DEVICE(0x0003, 0x0021, ddb_v6_5),
|
||||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7),
|
DDB_DEVICE(0x0006, 0x0022, ddb_v7),
|
||||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0024, ddb_v7a),
|
DDB_DEVICE(0x0006, 0x0024, ddb_v7a),
|
||||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct),
|
DDB_DEVICE(0x0003, 0x0030, ddb_dvbct),
|
||||||
DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3),
|
DDB_DEVICE(0x0003, 0xdb03, ddb_satixS2v3),
|
||||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7),
|
DDB_DEVICE(0x0006, 0x0031, ddb_ctv7),
|
||||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7),
|
DDB_DEVICE(0x0006, 0x0032, ddb_ctv7),
|
||||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7),
|
DDB_DEVICE(0x0006, 0x0033, ddb_ctv7),
|
||||||
DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48),
|
DDB_DEVICE(0x0007, 0x0023, ddb_s2_48),
|
||||||
DDB_ID(DDVID, 0x0008, DDVID, 0x0034, ddb_ct2_8),
|
DDB_DEVICE(0x0008, 0x0034, ddb_ct2_8),
|
||||||
DDB_ID(DDVID, 0x0008, DDVID, 0x0035, ddb_c2t2_8),
|
DDB_DEVICE(0x0008, 0x0035, ddb_c2t2_8),
|
||||||
DDB_ID(DDVID, 0x0008, DDVID, 0x0036, ddb_isdbt_8),
|
DDB_DEVICE(0x0008, 0x0036, ddb_isdbt_8),
|
||||||
DDB_ID(DDVID, 0x0008, DDVID, 0x0037, ddb_c2t2i_v0_8),
|
DDB_DEVICE(0x0008, 0x0037, ddb_c2t2i_v0_8),
|
||||||
DDB_ID(DDVID, 0x0008, DDVID, 0x0038, ddb_c2t2i_8),
|
DDB_DEVICE(0x0008, 0x0038, ddb_c2t2i_8),
|
||||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0039, ddb_ctv7),
|
DDB_DEVICE(0x0006, 0x0039, ddb_ctv7),
|
||||||
DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci),
|
DDB_DEVICE(0x0011, 0x0040, ddb_ci),
|
||||||
DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis),
|
DDB_DEVICE(0x0011, 0x0041, ddb_cis),
|
||||||
DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci),
|
DDB_DEVICE(0x0012, 0x0042, ddb_ci),
|
||||||
DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro),
|
DDB_DEVICE(0x0013, 0x0043, ddb_ci_s2_pro),
|
||||||
DDB_ID(DDVID, 0x0013, DDVID, 0x0044, ddb_ci_s2_pro_a),
|
DDB_DEVICE(0x0013, 0x0044, ddb_ci_s2_pro_a),
|
||||||
DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod),
|
DDB_DEVICE(0x0201, 0x0001, ddb_mod),
|
||||||
DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod),
|
DDB_DEVICE(0x0201, 0x0002, ddb_mod),
|
||||||
DDB_ID(DDVID, 0x0203, DDVID, 0x0001, ddb_mod),
|
DDB_DEVICE(0x0203, 0x0001, ddb_mod),
|
||||||
DDB_ID(DDVID, 0x0210, DDVID, 0x0001, ddb_mod_fsm_24),
|
DDB_DEVICE(0x0210, 0x0001, ddb_mod_fsm_24),
|
||||||
DDB_ID(DDVID, 0x0210, DDVID, 0x0002, ddb_mod_fsm_16),
|
DDB_DEVICE(0x0210, 0x0002, ddb_mod_fsm_16),
|
||||||
DDB_ID(DDVID, 0x0210, DDVID, 0x0003, ddb_mod_fsm_8),
|
DDB_DEVICE(0x0210, 0x0003, ddb_mod_fsm_8),
|
||||||
|
DDB_DEVICE(0x0220, 0x0001, ddb_sdr),
|
||||||
/* testing on OctopusNet Pro */
|
/* testing on OctopusNet Pro */
|
||||||
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro_hdin),
|
DDB_DEVICE(0x0320, PCI_ANY_ID, ddb_octopro_hdin),
|
||||||
DDB_ID(DDVID, 0x0321, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE(0x0321, PCI_ANY_ID, ddb_none),
|
||||||
DDB_ID(DDVID, 0x0322, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro),
|
DDB_DEVICE(0x0322, PCI_ANY_ID, ddb_octopro),
|
||||||
DDB_ID(DDVID, 0x0323, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE(0x0323, PCI_ANY_ID, ddb_none),
|
||||||
DDB_ID(DDVID, 0x0328, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE(0x0328, PCI_ANY_ID, ddb_none),
|
||||||
DDB_ID(DDVID, 0x0329, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro_hdin),
|
DDB_DEVICE(0x0329, PCI_ANY_ID, ddb_octopro_hdin),
|
||||||
/* in case sub-ids got deleted in flash */
|
/* in case sub-ids got deleted in flash */
|
||||||
DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE_ANY(0x0003),
|
||||||
DDB_ID(DDVID, 0x0005, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE_ANY(0x0005),
|
||||||
DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE_ANY(0x0006),
|
||||||
DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE_ANY(0x0007),
|
||||||
DDB_ID(DDVID, 0x0008, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE_ANY(0x0008),
|
||||||
DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE_ANY(0x0011),
|
||||||
DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE_ANY(0x0012),
|
||||||
DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE_ANY(0x0013),
|
||||||
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
DDB_DEVICE_ANY(0x0201),
|
||||||
|
DDB_DEVICE_ANY(0x0203),
|
||||||
|
DDB_DEVICE_ANY(0x0210),
|
||||||
|
DDB_DEVICE_ANY(0x0220),
|
||||||
|
DDB_DEVICE_ANY(0x0320),
|
||||||
|
DDB_DEVICE_ANY(0x0321),
|
||||||
|
DDB_DEVICE_ANY(0x0322),
|
||||||
|
DDB_DEVICE_ANY(0x0323),
|
||||||
|
DDB_DEVICE_ANY(0x0328),
|
||||||
|
DDB_DEVICE_ANY(0x0329),
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, ddb_id_tbl);
|
MODULE_DEVICE_TABLE(pci, ddb_id_table);
|
||||||
|
|
||||||
static struct pci_driver ddb_pci_driver = {
|
static struct pci_driver ddb_pci_driver = {
|
||||||
.name = "ddbridge",
|
.name = "ddbridge",
|
||||||
.id_table = ddb_id_tbl,
|
.id_table = ddb_id_table,
|
||||||
.probe = ddb_probe,
|
.probe = ddb_probe,
|
||||||
.remove = ddb_remove,
|
.remove = ddb_remove,
|
||||||
};
|
};
|
||||||
@ -617,7 +646,7 @@ static __init int module_init_ddbridge(void)
|
|||||||
|
|
||||||
pr_info("DDBridge: Digital Devices PCIE bridge driver "
|
pr_info("DDBridge: Digital Devices PCIE bridge driver "
|
||||||
DDBRIDGE_VERSION
|
DDBRIDGE_VERSION
|
||||||
", Copyright (C) 2010-16 Digital Devices GmbH\n");
|
", Copyright (C) 2010-17 Digital Devices GmbH\n");
|
||||||
if (ddb_class_create() < 0)
|
if (ddb_class_create() < 0)
|
||||||
return -1;
|
return -1;
|
||||||
ddb_wq = create_workqueue("ddbridge");
|
ddb_wq = create_workqueue("ddbridge");
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ddbridge.h: Digital Devices PCIe bridge driver
|
* ddbridge.h: Digital Devices PCIe bridge driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
* Copyright (C) 2010-2017 Digital Devices GmbH
|
||||||
* Ralph Metzler <rmetzler@digitaldevices.de>
|
* Ralph Metzler <rmetzler@digitaldevices.de>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
@ -55,7 +55,6 @@
|
|||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <asm/dma.h>
|
#include <asm/dma.h>
|
||||||
@ -178,7 +177,8 @@ struct ddb_info {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* DMA_SIZE MUST be smaller than 256k and
|
/* DMA_SIZE MUST be smaller than 256k and
|
||||||
MUST be divisible by 188 and 128 !!! */
|
* MUST be divisible by 188 and 128 !!!
|
||||||
|
*/
|
||||||
|
|
||||||
#define DMA_MAX_BUFS 32 /* hardware table limit */
|
#define DMA_MAX_BUFS 32 /* hardware table limit */
|
||||||
|
|
||||||
@ -199,6 +199,10 @@ struct ddb_info {
|
|||||||
#define OUTPUT_DMA_SIZE (128*47*21)
|
#define OUTPUT_DMA_SIZE (128*47*21)
|
||||||
#define OUTPUT_DMA_IRQ_DIV 1
|
#define OUTPUT_DMA_IRQ_DIV 1
|
||||||
#endif
|
#endif
|
||||||
|
#define OUTPUT_DMA_BUFS_SDR 32
|
||||||
|
#define OUTPUT_DMA_SIZE_SDR (256*1024)
|
||||||
|
#define OUTPUT_DMA_IRQ_DIV_SDR 1
|
||||||
|
|
||||||
|
|
||||||
struct ddb;
|
struct ddb;
|
||||||
struct ddb_port;
|
struct ddb_port;
|
||||||
@ -345,8 +349,8 @@ struct mod_base {
|
|||||||
|
|
||||||
struct ddb_mod {
|
struct ddb_mod {
|
||||||
struct ddb_port *port;
|
struct ddb_port *port;
|
||||||
u32 nr;
|
//u32 nr;
|
||||||
u32 regs;
|
//u32 regs;
|
||||||
|
|
||||||
u32 frequency;
|
u32 frequency;
|
||||||
u32 modulation;
|
u32 modulation;
|
||||||
@ -678,15 +682,6 @@ static void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count)
|
|||||||
return memcpy_fromio(dst, (char *) (dev->regs + adr), count);
|
return memcpy_fromio(dst, (char *) (dev->regs + adr), count);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#define ddbcpyto(_dev, _adr, _src, _count) \
|
|
||||||
memcpy_toio((char *) (_dev->regs + (_adr)), (_src), (_count))
|
|
||||||
|
|
||||||
#define ddbcpyfrom(_dev, _dst, _adr, _count) \
|
|
||||||
memcpy_fromio((_dst), (char *) (_dev->regs + (_adr)), (_count))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ddbmemset(_dev, _adr, _val, _count) \
|
#define ddbmemset(_dev, _adr, _val, _count) \
|
||||||
memset_io((char *) (_dev->regs + (_adr)), (_val), (_count))
|
memset_io((char *) (_dev->regs + (_adr)), (_val), (_count))
|
||||||
|
|
||||||
@ -753,6 +748,6 @@ void ddbridge_mod_rate_handler(unsigned long data);
|
|||||||
|
|
||||||
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
|
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
|
||||||
|
|
||||||
#define DDBRIDGE_VERSION "0.9.28"
|
#define DDBRIDGE_VERSION "0.9.29"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* octonet.c: Digital Devices network tuner driver
|
* octonet.c: Digital Devices network tuner driver
|
||||||
*
|
*
|
||||||
* Copyright (C) 2012-16 Digital Devices GmbH
|
* Copyright (C) 2012-17 Digital Devices GmbH
|
||||||
* Marcus Metzler <mocm@metzlerbros.de>
|
* Marcus Metzler <mocm@metzlerbros.de>
|
||||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||||
*
|
*
|
||||||
|
@ -35,7 +35,12 @@
|
|||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
|
||||||
|
#include <linux/sched/signal.h>
|
||||||
|
#else
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#endif
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
|
|
||||||
#include "dvb_ca_en50221.h"
|
#include "dvb_ca_en50221.h"
|
||||||
|
@ -21,7 +21,12 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
|
||||||
|
#include <linux/sched/signal.h>
|
||||||
|
#else
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#endif
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
|
@ -29,7 +29,12 @@
|
|||||||
#define _DVB_FRONTEND_H_
|
#define _DVB_FRONTEND_H_
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
|
||||||
|
#include <linux/sched/signal.h>
|
||||||
|
#else
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#endif
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
|
#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
|
||||||
#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
|
#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
|
||||||
#else
|
#else
|
||||||
#define DVB_MAX_ADAPTERS 8
|
#define DVB_MAX_ADAPTERS 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DVB_UNSET (-1)
|
#define DVB_UNSET (-1)
|
||||||
|
@ -270,9 +270,10 @@ static int writebitsx(struct cxd_state *cxd, u8 Bank, u8 Address,
|
|||||||
mutex_lock(&cxd->mutex);
|
mutex_lock(&cxd->mutex);
|
||||||
status = readregsx_unlocked(cxd, Bank, Address, &tmp, 1);
|
status = readregsx_unlocked(cxd, Bank, Address, &tmp, 1);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return status;
|
goto out;
|
||||||
tmp = (tmp & ~Mask) | Value;
|
tmp = (tmp & ~Mask) | Value;
|
||||||
status = writeregsx_unlocked(cxd, Bank, Address, &tmp, 1);
|
status = writeregsx_unlocked(cxd, Bank, Address, &tmp, 1);
|
||||||
|
out:
|
||||||
mutex_unlock(&cxd->mutex);
|
mutex_unlock(&cxd->mutex);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@ -286,9 +287,10 @@ static int writebitst(struct cxd_state *cxd, u8 Bank, u8 Address,
|
|||||||
mutex_lock(&cxd->mutex);
|
mutex_lock(&cxd->mutex);
|
||||||
status = readregst_unlocked(cxd, Bank, Address, &Tmp, 1);
|
status = readregst_unlocked(cxd, Bank, Address, &Tmp, 1);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return status;
|
goto out;
|
||||||
Tmp = (Tmp & ~Mask) | Value;
|
Tmp = (Tmp & ~Mask) | Value;
|
||||||
status = writeregst_unlocked(cxd, Bank, Address, &Tmp, 1);
|
status = writeregst_unlocked(cxd, Bank, Address, &Tmp, 1);
|
||||||
|
out:
|
||||||
mutex_unlock(&cxd->mutex);
|
mutex_unlock(&cxd->mutex);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe,
|
|||||||
fe->ops.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage;
|
fe->ops.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage;
|
||||||
fe->ops.release_sec = lnbh25_release;
|
fe->ops.release_sec = lnbh25_release;
|
||||||
|
|
||||||
pr_info("LNB25 on %02x\n", lnbh->adr);
|
pr_info("LNBH25 on %02x\n", lnbh->adr);
|
||||||
|
|
||||||
return fe;
|
return fe;
|
||||||
}
|
}
|
||||||
|
@ -841,8 +841,8 @@ static struct dvb_frontend_ops mxl_ops = {
|
|||||||
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
|
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
|
||||||
.info = {
|
.info = {
|
||||||
.name = "MXL5XX",
|
.name = "MXL5XX",
|
||||||
.frequency_min = 950000,
|
.frequency_min = 300000,
|
||||||
.frequency_max = 2150000,
|
.frequency_max = 2350000,
|
||||||
.frequency_stepsize = 0,
|
.frequency_stepsize = 0,
|
||||||
.frequency_tolerance = 0,
|
.frequency_tolerance = 0,
|
||||||
.symbol_rate_min = 1000000,
|
.symbol_rate_min = 1000000,
|
||||||
|
@ -25,9 +25,10 @@ struct dvb_mod_channel_params {
|
|||||||
#define MODULATOR_FREQUENCY 3
|
#define MODULATOR_FREQUENCY 3
|
||||||
#define MODULATOR_MODULATION 4
|
#define MODULATOR_MODULATION 4
|
||||||
#define MODULATOR_SYMBOL_RATE 5 /* Hz */
|
#define MODULATOR_SYMBOL_RATE 5 /* Hz */
|
||||||
|
#define MODULATOR_BASE_FREQUENCY 6
|
||||||
#define MODULATOR_ATTENUATOR 32
|
#define MODULATOR_ATTENUATOR 32
|
||||||
#define MODULATOR_INPUT_BITRATE 33 /* Hz */
|
#define MODULATOR_INPUT_BITRATE 33 /* Hz */
|
||||||
#define MODULATOR_PCR_MODE 34 /* 1=pcr correction enabled */
|
#define MODULATOR_PCR_MODE 34 /* 1=pcr correction enabled */
|
||||||
|
#define MODULATOR_OUTPUT_ARI 64
|
||||||
|
|
||||||
#endif /*_UAPI_DVBMOD_H_*/
|
#endif /*_UAPI_DVBMOD_H_*/
|
||||||
|
Loading…
Reference in New Issue
Block a user