76 Commits

Author SHA1 Message Date
Ralph Metzler
eb81f006e4 bump version to 0.9.30 2017-07-26 15:16:14 +02:00
Ralph Metzler
af554da865 add ddbridge-hw file with hardware info 2017-07-26 15:15:06 +02:00
Ralph Metzler
d6f56c1807 dkms compatibility
Build against specified kernel version (dkms ... -k VERSION) or against current running (uname -r) if not specified
2017-07-26 02:44:56 +02:00
Ralph Metzler
31f22ef4de also clean .*.o.d files 2017-07-26 02:42:35 +02:00
Ralph Metzler
d4d0a9b84e Improvements for cit
- Added error checking.
- Added help text.
- Added info.

Signed-off-by: Jasmin Jessich <jasmin@anw.at>
2017-07-26 02:35:40 +02:00
Ralph Metzler
24503d35ad remove no longer used module parameter 2017-07-26 02:13:27 +02:00
Ralph Metzler
3556d6464b Move device info into ddbridge-hw.c and use get_ddb_info
in ddbridge.c, ddbridge-core.c and octonet.c to get
ddb_info for specific devices.

This unifies the method for getting the device info for all hardware.
It also no longer relies on driver_data in struct pci_dev_id
which is deprecated to be used as a pointer.
2017-07-24 22:24:47 +02:00
Ralph Metzler
862c7bfc60 check for error during write 2017-07-24 22:24:13 +02:00
Ralph Metzler
fd21584ecc Use ddbridge version macro for octonet version 2017-07-24 01:05:31 +02:00
Ralph Metzler
6814a8fa23 move common functions of ddbridge and octonet to core 2017-07-24 01:03:40 +02:00
Ralph Metzler
49d4bd0da8 fix MSI/non-MSI compilation 2017-07-18 01:25:55 +02:00
Ralph Metzler
6d1cfd4cd2 acivate CAM race condition handler 2017-07-18 00:26:09 +02:00
Ralph Metzler
e68ce2ef62 add __refdata 2017-07-18 00:23:13 +02:00
Ralph Metzler
023ae44411 add missing version include 2017-07-17 23:49:19 +02:00
Ralph Metzler
7222bd58b3 change lock check order 2017-07-11 20:37:38 +02:00
Ralph Metzler
f404b3fb6d add multi-stream capability announcement 2017-07-11 20:36:52 +02:00
Ralph Metzler
de34e2ebbd correct array access 2017-07-11 20:29:20 +02:00
Ralph Metzler
774e92bd44 change to unsigned because of possible wrong range 2017-07-11 20:27:42 +02:00
Ralph Metzler
8c46d9a86a change pointer check order 2017-07-11 20:20:39 +02:00
Ralph Metzler
452771913e fix for 4.12. kernels 2017-07-11 20:17:28 +02:00
Ralph Metzler
3285b6ade0 modulator type 1 has no vga 2017-06-12 14:23:35 +02:00
Ralph Metzler
e6dd33deec write really availalble modulator channels to port_num 2017-06-12 14:21:21 +02:00
Ralph Metzler
93e42deeaa only eval register 0x1c for modulator type 1 2017-06-12 14:21:21 +02:00
Ralph Metzler
e415b6e203 force gap setting if given by attribute 2017-06-12 14:21:21 +02:00
manf
1354b9021f increased fm power 2017-06-02 01:14:15 +02:00
manf
4d17f2f5f0 mod3: atten,gain fixed 2017-06-01 20:13:08 +02:00
Ralph Metzler
5fa08eb288 add gain control 2017-06-01 16:46:44 +02:00
mvoelkel
933779aa24 Readme markup fixed 2017-05-19 16:59:30 +02:00
mvoelkel
01d35aad26 Release 0.9.29
New Hardware, fixes, testet up to kernel 4.11.1
2017-05-19 15:48:35 +02:00
Ralph Metzler
40c32767ec new release 2017-05-17 19:42:25 +02:00
Ralph Metzler
8704ceaf94 change default frequencies for SDR modulator 2017-05-16 21:25:30 +02:00
Ralph Metzler
12b792ef3f remove possible mutex deadlock 2017-05-16 21:24:48 +02:00
Ralph Metzler
3063b8e88b revert struct name change 2017-05-04 16:08:13 +02:00
Ralph Metzler
7d73553b61 start output DMA with stall bit set 2017-05-04 09:09:34 +02:00
Ralph Metzler
5d4259f6f6 remove warning for unused code 2017-04-25 19:00:19 +02:00
Ralph Metzler
04294ab5ef increase to 32 buffers for SDR 2017-04-25 18:59:47 +02:00
Ralph Metzler
4699a19bfb increase default adapter number to 64 2017-04-20 15:55:27 +02:00
Ralph Metzler
f44a9dfcbd coding style fixes 2017-04-16 21:20:52 +02:00
Ralph Metzler
b3b7a0ef2e cleanup old code 2017-04-16 14:55:00 +02:00
Ralph Metzler
8a98bd88cd allow wideband frequencies 2017-04-15 11:06:16 +02:00
Ralph Metzler
bfd1f1979d swapped if/else 2017-04-10 17:32:16 +02:00
Ralph Metzler
8931ae4d9e add frequency and center frequency setting for SDR modulator 2017-04-10 11:55:44 +02:00
Ralph Metzler
4070713556 more 4.11 fixes 2017-04-10 11:52:49 +02:00
Ralph Metzler
bba5fa5683 kernel 4.11 fixes 2017-04-10 11:46:36 +02:00
Ralph Metzler
ae37a1e4e9 change SDR to 16 outputs 2017-04-10 11:45:43 +02:00
Ralph Metzler
2aee51e447 wrong port type for ct2ti card 2017-04-09 13:20:22 +02:00
Ralph Metzler
264f08fbad add sub-ids for MAX A8 cards on GT-Link 2017-04-07 22:22:06 +02:00
Ralph Metzler
6830f4df08 add sat selection for fmode 1 and 2 2017-04-07 22:21:06 +02:00
Ralph Metzler
785d7c5126 change command name from UNI to SCIF 2017-04-07 22:20:40 +02:00
Ralph Metzler
52b81cfd8e typo 2017-04-07 12:50:01 +02:00
Ralph Metzler
263d593bcf simplify device table 2017-04-07 12:28:55 +02:00
Ralph Metzler
f56ec446ae add ARI property 2017-04-07 12:28:27 +02:00
Ralph Metzler
fa36763d43 - add support for setting ARI
- use coorect base frequency
2017-04-07 12:27:35 +02:00
Ralph Metzler
08a6d78da7 print used devices 2017-04-07 12:26:03 +02:00
Ralph Metzler
b3806c61ce typo 2017-04-07 12:22:29 +02:00
Ralph Metzler
eb6652f18f lower gain for 16 output channel image 2017-03-13 13:00:12 +01:00
Ralph Metzler
21c69918d3 add support for higher IRQs in case of multiple MSI interrupts 2017-03-10 12:29:11 +01:00
Ralph Metzler
326e928f66 add ids 2017-03-10 12:28:57 +01:00
Ralph Metzler
0e09153b1f use $(CC) instead of gcc 2017-03-10 12:28:31 +01:00
mvoelkel
adf4e40256 Fixed updating of a preloaded GTL version 2017-02-24 20:11:30 +01:00
mvoelkel
9dcd81fe42 Damn 2017-02-24 16:07:17 +01:00
mvoelkel
a7ce2ef8da Verify flash after writing 2017-02-24 15:27:14 +01:00
mvoelkel
285d7aed49 check for old golden version 2017-02-24 15:01:11 +01:00
Ralph Metzler
9eb5458eeb also update golden image 2017-02-24 12:48:00 +01:00
Ralph Metzler
d51a9db022 increase buffer for SDR
more SDR card init in driver
2017-02-21 17:12:35 +01:00
Ralph Metzler
532afaa97c changes for latest SDR card devel version 2017-02-09 10:12:43 +01:00
Ralph Metzler
1984377f72 remove debug message 2017-02-09 10:12:33 +01:00
Ralph Metzler
4bfdb11762 add id for pro advanced 2017-02-06 13:25:57 +01:00
Ralph Metzler
3a3a48654e support cine s2 v7a 2017-02-01 17:48:59 +01:00
Ralph Metzler
1a80437b98 use correct type u32 for pll init table 2017-01-22 13:43:53 +01:00
Ralph Metzler
28a2aaa653 improved PLL setup for modulator 2017-01-22 02:05:44 +01:00
Ralph Metzler
f6c7586815 fix wrong qam register access for SDR cad 2017-01-19 16:37:50 +01:00
Ralph Metzler
d069dc051f basic support for SDR card 2017-01-09 19:28:26 +01:00
Ralph Metzler
9392ccec22 fix error handling and ID output length 2017-01-09 19:27:27 +01:00
Ralph Metzler
4c276fbc75 add SDR support 2017-01-09 19:26:52 +01:00
Ralph Metzler
7cc9107597 add support for single demod mode for testing high bit rates 2016-12-30 15:03:38 +01:00
28 changed files with 1697 additions and 1232 deletions

View File

@@ -1,3 +1,7 @@
0.9.29 compiles with most kernels up to 4.11.1
see git commit messages for newer changes
0.9.24 2016.08.03 0.9.24 2016.08.03
- suport new V2 modulator cards - suport new V2 modulator cards

View File

@@ -1,4 +1,5 @@
KDIR ?= /lib/modules/$(shell uname -r)/build kernelver ?= $(shell uname -r)
KDIR ?= /lib/modules/$(kernelver)/build
PWD := $(shell pwd) PWD := $(shell pwd)
MODDEFS := CONFIG_DVB_CORE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_CXD2099=m CONFIG_DVB_LNBP21=m CONFIG_DVB_STV090x=m CONFIG_DVB_STV6110x=m CONFIG_DVB_STV0367=m CONFIG_DVB_TDA18212=m CONFIG_DVB_STV0367DD=m CONFIG_DVB_TDA18212DD=m CONFIG_DVB_OCTONET=m CONFIG_DVB_CXD2843=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6111=m CONFIG_DVB_LNBH25=m CONFIG_DVB_MXL5XX=m MODDEFS := CONFIG_DVB_CORE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_CXD2099=m CONFIG_DVB_LNBP21=m CONFIG_DVB_STV090x=m CONFIG_DVB_STV6110x=m CONFIG_DVB_STV0367=m CONFIG_DVB_TDA18212=m CONFIG_DVB_STV0367DD=m CONFIG_DVB_TDA18212DD=m CONFIG_DVB_OCTONET=m CONFIG_DVB_CXD2843=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6111=m CONFIG_DVB_LNBH25=m CONFIG_DVB_MXL5XX=m
@@ -14,6 +15,6 @@ install: all
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
clean: clean:
rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules* rm -rf */.*.o.d */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*

View File

@@ -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

View File

@@ -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

View File

@@ -91,7 +91,12 @@ 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);
if (fdi == -1) {
printf("Failed to open %s for read: %m\n", fname);
return NULL;
}
while (1) { while (1) {
memset(buf, 0, 188*rnum); memset(buf, 0, 188*rnum);
@@ -122,7 +127,12 @@ 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);
if (fdo == -1) {
printf("Failed to open %s to write: %m\n", fname);
exit(2);
}
while (1) { while (1) {
for (i=0; i<snum; i++) { for (i=0; i<snum; i++) {
@@ -178,6 +188,8 @@ int main(int argc, char **argv)
rnum = strtoul(optarg, NULL, 10); rnum = strtoul(optarg, NULL, 10);
break; break;
case 'h': case 'h':
printf("cit -a<adapter> -d<device>\n");
exit(-1);
default: default:
break; break;
@@ -186,6 +198,7 @@ int main(int argc, char **argv)
if (optind < argc) { if (optind < argc) {
printf("Warning: unused arguments\n"); printf("Warning: unused arguments\n");
} }
printf("adapter %d, device: %d\n", adapter, device);
memset(ts+8, 180, 0x5a); memset(ts+8, 180, 0x5a);
pthread_create(&th, NULL, get_ts, NULL); pthread_create(&th, NULL, get_ts, NULL);
usleep(10000); usleep(10000);

View File

@@ -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;
} }

View File

@@ -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";

View File

@@ -26,6 +26,20 @@
DEFINE_MUTEX(redirect_lock); DEFINE_MUTEX(redirect_lock);
static struct workqueue_struct *ddb_wq;
static int adapter_alloc;
module_param(adapter_alloc, int, 0444);
MODULE_PARM_DESC(adapter_alloc,
"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all");
#ifdef CONFIG_PCI_MSI
static int msi = 1;
module_param(msi, int, 0444);
MODULE_PARM_DESC(msi,
" Control MSI interrupts: 0-disable, 1-enable (default)");
#endif
static int ci_bitrate = 70000; static int ci_bitrate = 70000;
module_param(ci_bitrate, int, 0444); module_param(ci_bitrate, int, 0444);
MODULE_PARM_DESC(ci_bitrate, " Bitrate in KHz for output to CI."); MODULE_PARM_DESC(ci_bitrate, " Bitrate in KHz for output to CI.");
@@ -38,14 +52,14 @@ static int vlan;
module_param(vlan, int, 0444); module_param(vlan, int, 0444);
MODULE_PARM_DESC(vlan, "VLAN and QoS IDs enabled"); MODULE_PARM_DESC(vlan, "VLAN and QoS IDs enabled");
static int tt;
module_param(tt, int, 0444);
MODULE_PARM_DESC(tt, "");
static int fmode; 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 ");
@@ -78,300 +92,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#include "ddbridge-mod.c" #include "ddbridge-mod.c"
#include "ddbridge-i2c.c" #include "ddbridge-i2c.c"
#include "ddbridge-ns.c" #include "ddbridge-ns.c"
#include "ddbridge-hw.c"
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static struct ddb_regset octopus_mod_odma = {
.base = 0x300,
.num = 0x0a,
.size = 0x10,
};
static struct ddb_regset octopus_mod_odma_buf = {
.base = 0x2000,
.num = 0x0a,
.size = 0x100,
};
static struct ddb_regset octopus_mod_channel = {
.base = 0x400,
.num = 0x0a,
.size = 0x40,
};
/****************************************************************************/
static struct ddb_regset octopus_mod_2_odma = {
.base = 0x400,
.num = 0x18,
.size = 0x10,
};
static struct ddb_regset octopus_mod_2_odma_buf = {
.base = 0x8000,
.num = 0x18,
.size = 0x100,
};
static struct ddb_regset octopus_mod_2_channel = {
.base = 0x800,
.num = 0x18,
.size = 0x40,
};
/****************************************************************************/
static struct ddb_regset octopus_input = {
.base = 0x200,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_output = {
.base = 0x280,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_idma = {
.base = 0x300,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_idma_buf = {
.base = 0x2000,
.num = 0x08,
.size = 0x100,
};
static struct ddb_regset octopus_odma = {
.base = 0x380,
.num = 0x04,
.size = 0x10,
};
static struct ddb_regset octopus_odma_buf = {
.base = 0x2800,
.num = 0x04,
.size = 0x100,
};
static struct ddb_regset octopus_i2c = {
.base = 0x80,
.num = 0x04,
.size = 0x20,
};
static struct ddb_regset octopus_i2c_buf = {
.base = 0x1000,
.num = 0x04,
.size = 0x200,
};
/****************************************************************************/
static struct ddb_regset octopro_input = {
.base = 0x400,
.num = 0x14,
.size = 0x10,
};
static struct ddb_regset octopro_output = {
.base = 0x600,
.num = 0x0a,
.size = 0x10,
};
static struct ddb_regset octopro_idma = {
.base = 0x800,
.num = 0x40,
.size = 0x10,
};
static struct ddb_regset octopro_idma_buf = {
.base = 0x4000,
.num = 0x40,
.size = 0x100,
};
static struct ddb_regset octopro_odma = {
.base = 0xc00,
.num = 0x20,
.size = 0x10,
};
static struct ddb_regset octopro_odma_buf = {
.base = 0x8000,
.num = 0x20,
.size = 0x100,
};
static struct ddb_regset octopro_i2c = {
.base = 0x200,
.num = 0x0a,
.size = 0x20,
};
static struct ddb_regset octopro_i2c_buf = {
.base = 0x2000,
.num = 0x0a,
.size = 0x200,
};
static struct ddb_regset octopro_gtl = {
.base = 0xe00,
.num = 0x03,
.size = 0x40,
};
/****************************************************************************/
/****************************************************************************/
static struct ddb_regmap octopus_map = {
.irq_version = 1,
.irq_base_i2c = 0,
.irq_base_idma = 8,
.irq_base_odma = 16,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.idma = &octopus_idma,
.idma_buf = &octopus_idma_buf,
.odma = &octopus_odma,
.odma_buf = &octopus_odma_buf,
.input = &octopus_input,
.output = &octopus_output,
};
static struct ddb_regmap octopro_map = {
.irq_version = 2,
.irq_base_i2c = 32,
.irq_base_idma = 64,
.irq_base_odma = 128,
.irq_base_gtl = 8,
.i2c = &octopro_i2c,
.i2c_buf = &octopro_i2c_buf,
.idma = &octopro_idma,
.idma_buf = &octopro_idma_buf,
.odma = &octopro_odma,
.odma_buf = &octopro_odma_buf,
.input = &octopro_input,
.output = &octopro_output,
.gtl = &octopro_gtl,
};
static struct ddb_regmap octopro_hdin_map = {
.irq_version = 2,
.irq_base_i2c = 32,
.irq_base_idma = 64,
.irq_base_odma = 128,
.i2c = &octopro_i2c,
.i2c_buf = &octopro_i2c_buf,
.idma = &octopro_idma,
.idma_buf = &octopro_idma_buf,
.odma = &octopro_odma,
.odma_buf = &octopro_odma_buf,
.input = &octopro_input,
.output = &octopro_output,
};
static struct ddb_regmap octopus_mod_map = {
.irq_version = 1,
.irq_base_odma = 8,
.irq_base_rate = 18,
.output = &octopus_output,
.odma = &octopus_mod_odma,
.odma_buf = &octopus_mod_odma_buf,
.channel = &octopus_mod_channel,
};
static struct ddb_regmap octopus_mod_2_map = {
.irq_version = 2,
.irq_base_odma = 64,
.irq_base_rate = 32,
.output = &octopus_output,
.odma = &octopus_mod_2_odma,
.odma_buf = &octopus_mod_2_odma_buf,
.channel = &octopus_mod_2_channel,
};
/****************************************************************************/
static struct ddb_info ddb_s2_48 = {
.type = DDB_OCTOPUS_MAX,
.name = "Digital Devices MAX S8 4/8",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x01,
.board_control = 1,
.tempmon_irq = 24,
};
static struct ddb_info ddb_ct2_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 CT2",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
static struct ddb_info ddb_c2t2_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 C2T2",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
static struct ddb_info ddb_isdbt_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 ISDBT",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
static struct ddb_info ddb_c2t2i_v0_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 C2T2I V0",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL | TS_QUIRK_ALT_OSC,
.tempmon_irq = 24,
};
static struct ddb_info ddb_c2t2i_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 C2T2I",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
/****************************************************************************/ /****************************************************************************/
/****************************************************************************/ /****************************************************************************/
@@ -391,7 +112,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);
} }
@@ -478,9 +199,9 @@ static int ddb_redirect(u32 i, u32 p)
struct ddb *pdev = ddbs[(p >> 4) & 0x3f]; struct ddb *pdev = ddbs[(p >> 4) & 0x3f];
struct ddb_port *port; struct ddb_port *port;
if (!idev->has_dma || !pdev->has_dma) if (!pdev || !idev)
return -EINVAL; return -EINVAL;
if (!idev || !pdev) if (!pdev->has_dma || !idev->has_dma)
return -EINVAL; return -EINVAL;
port = &pdev->port[p & 0x0f]; port = &pdev->port[p & 0x0f];
@@ -665,6 +386,7 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
if (output->port->gap != 0xffffffff) { if (output->port->gap != 0xffffffff) {
flags |= 1; flags |= 1;
gap = output->port->gap; gap = output->port->gap;
max_bitrate = 0;
} }
if (dev->link[0].info->type == DDB_OCTOPUS_CI && output->port->nr > 1) { if (dev->link[0].info->type == DDB_OCTOPUS_CI && output->port->nr > 1) {
*con = 0x10c; *con = 0x10c;
@@ -678,7 +400,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 {
@@ -716,7 +439,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 +446,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 +472,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 +513,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 +679,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 +810,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 +1362,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 +1392,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 +1669,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 +1747,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 +1818,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 +1947,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 +2068,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 +2238,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) {
@@ -2628,7 +2367,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 +2412,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 +2924,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;
@@ -3257,8 +2997,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 +3063,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 +3102,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 +3300,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 +3371,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)));
@@ -3826,7 +3575,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 +4176,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 +4207,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 +4237,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 +4352,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;
@@ -4672,7 +4421,7 @@ static ssize_t bpsnr_show(struct device *device,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
struct ddb *dev = dev_get_drvdata(device); struct ddb *dev = dev_get_drvdata(device);
char snr[32]; unsigned char snr[32];
if (!dev->i2c_num) if (!dev->i2c_num)
return 0; return 0;
@@ -4707,6 +4456,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 +4480,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 +4729,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++)
@@ -5159,14 +4911,10 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l)
} }
id = ddbreadl(dev, DDB_LINK_TAG(l) | 8); id = ddbreadl(dev, DDB_LINK_TAG(l) | 8);
subid = ddbreadl(dev, DDB_LINK_TAG(l) | 12); subid = ddbreadl(dev, DDB_LINK_TAG(l) | 12);
switch (id) { link->info = get_ddb_info(id & 0xffff, id >> 16,
case 0x0007dd01: subid & 0xffff, subid >> 16);
link->info = &ddb_s2_48; if (link->info->type != DDB_OCTOPUS_MAX_CT &&
break; link->info->type != DDB_OCTOPUS_MAX) {
case 0x0008dd01:
link->info = &ddb_c2t2_8;
break;
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);
return -1; return -1;
@@ -5219,7 +4967,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;
} }
@@ -5264,9 +5013,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 +5027,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 +5040,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 +5114,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 +5155,19 @@ 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);
} }
static void ddb_unmap(struct ddb *dev)
{
if (dev->regs)
iounmap(dev->regs);
vfree(dev);
}

704
ddbridge/ddbridge-hw.c Normal file
View File

@@ -0,0 +1,704 @@
/*
* ddbridge.c: Digital Devices PCIe bridge driver
*
* Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de>
* Marcus Metzler <mocm@metzlerbros.de>
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 only, as published by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*/
#include "ddbridge.h"
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static struct ddb_regset octopus_mod_odma = {
.base = 0x300,
.num = 0x0a,
.size = 0x10,
};
static struct ddb_regset octopus_mod_odma_buf = {
.base = 0x2000,
.num = 0x0a,
.size = 0x100,
};
static struct ddb_regset octopus_mod_channel = {
.base = 0x400,
.num = 0x0a,
.size = 0x40,
};
/****************************************************************************/
static struct ddb_regset octopus_mod_2_odma = {
.base = 0x400,
.num = 0x18,
.size = 0x10,
};
static struct ddb_regset octopus_mod_2_odma_buf = {
.base = 0x8000,
.num = 0x18,
.size = 0x100,
};
static struct ddb_regset octopus_mod_2_channel = {
.base = 0x800,
.num = 0x18,
.size = 0x40,
};
static struct ddb_regset octopus_sdr_output = {
.base = 0x240,
.num = 0x14,
.size = 0x10,
};
/****************************************************************************/
static struct ddb_regset octopus_input = {
.base = 0x200,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_output = {
.base = 0x280,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_idma = {
.base = 0x300,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_idma_buf = {
.base = 0x2000,
.num = 0x08,
.size = 0x100,
};
static struct ddb_regset octopus_odma = {
.base = 0x380,
.num = 0x04,
.size = 0x10,
};
static struct ddb_regset octopus_odma_buf = {
.base = 0x2800,
.num = 0x04,
.size = 0x100,
};
static struct ddb_regset octopus_i2c = {
.base = 0x80,
.num = 0x04,
.size = 0x20,
};
static struct ddb_regset octopus_i2c_buf = {
.base = 0x1000,
.num = 0x04,
.size = 0x200,
};
/****************************************************************************/
static struct ddb_regset octopro_input = {
.base = 0x400,
.num = 0x14,
.size = 0x10,
};
static struct ddb_regset octopro_output = {
.base = 0x600,
.num = 0x0a,
.size = 0x10,
};
static struct ddb_regset octopro_idma = {
.base = 0x800,
.num = 0x40,
.size = 0x10,
};
static struct ddb_regset octopro_idma_buf = {
.base = 0x4000,
.num = 0x40,
.size = 0x100,
};
static struct ddb_regset octopro_odma = {
.base = 0xc00,
.num = 0x20,
.size = 0x10,
};
static struct ddb_regset octopro_odma_buf = {
.base = 0x8000,
.num = 0x20,
.size = 0x100,
};
static struct ddb_regset octopro_i2c = {
.base = 0x200,
.num = 0x0a,
.size = 0x20,
};
static struct ddb_regset octopro_i2c_buf = {
.base = 0x2000,
.num = 0x0a,
.size = 0x200,
};
static struct ddb_regset octopro_gtl = {
.base = 0xe00,
.num = 0x03,
.size = 0x40,
};
/****************************************************************************/
/****************************************************************************/
static struct ddb_regmap octopus_map = {
.irq_version = 1,
.irq_base_i2c = 0,
.irq_base_idma = 8,
.irq_base_odma = 16,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.idma = &octopus_idma,
.idma_buf = &octopus_idma_buf,
.odma = &octopus_odma,
.odma_buf = &octopus_odma_buf,
.input = &octopus_input,
.output = &octopus_output,
};
static struct ddb_regmap octopro_map = {
.irq_version = 2,
.irq_base_i2c = 32,
.irq_base_idma = 64,
.irq_base_odma = 128,
.irq_base_gtl = 8,
.i2c = &octopro_i2c,
.i2c_buf = &octopro_i2c_buf,
.idma = &octopro_idma,
.idma_buf = &octopro_idma_buf,
.odma = &octopro_odma,
.odma_buf = &octopro_odma_buf,
.input = &octopro_input,
.output = &octopro_output,
.gtl = &octopro_gtl,
};
static struct ddb_regmap octopro_hdin_map = {
.irq_version = 2,
.irq_base_i2c = 32,
.irq_base_idma = 64,
.irq_base_odma = 128,
.i2c = &octopro_i2c,
.i2c_buf = &octopro_i2c_buf,
.idma = &octopro_idma,
.idma_buf = &octopro_idma_buf,
.odma = &octopro_odma,
.odma_buf = &octopro_odma_buf,
.input = &octopro_input,
.output = &octopro_output,
};
static struct ddb_regmap octopus_mod_map = {
.irq_version = 1,
.irq_base_odma = 8,
.irq_base_rate = 18,
.output = &octopus_output,
.odma = &octopus_mod_odma,
.odma_buf = &octopus_mod_odma_buf,
.channel = &octopus_mod_channel,
};
static struct ddb_regmap octopus_mod_2_map = {
.irq_version = 2,
.irq_base_odma = 64,
.irq_base_rate = 32,
.output = &octopus_output,
.odma = &octopus_mod_2_odma,
.odma_buf = &octopus_mod_2_odma_buf,
.channel = &octopus_mod_2_channel,
};
static struct ddb_regmap octopus_sdr_map = {
.irq_version = 2,
.irq_base_odma = 64,
.irq_base_rate = 32,
.output = &octopus_sdr_output,
.odma = &octopus_mod_2_odma,
.odma_buf = &octopus_mod_2_odma_buf,
.channel = &octopus_mod_2_channel,
};
/****************************************************************************/
/****************************************************************************/
static struct ddb_info ddb_none = {
.type = DDB_NONE,
.name = "unknown Digital Devices device, install newer driver",
.regmap = &octopus_map,
};
static struct ddb_info ddb_octopus = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static struct ddb_info ddb_octopusv3 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus V3 DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static struct ddb_info ddb_octopus_le = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus LE DVB adapter",
.regmap = &octopus_map,
.port_num = 2,
.i2c_mask = 0x03,
};
static struct ddb_info ddb_octopus_oem = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus OEM",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.led_num = 1,
.fan_num = 1,
.temp_num = 1,
.temp_bus = 0,
};
static struct ddb_info ddb_octopus_mini = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus Mini",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static struct ddb_info ddb_v6 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V6 DVB adapter",
.regmap = &octopus_map,
.port_num = 3,
.i2c_mask = 0x07,
};
static struct ddb_info ddb_v6_5 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V6.5 DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static struct ddb_info ddb_v7a = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V7 Advanced DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 2,
.board_control_2 = 4,
.ts_quirks = TS_QUIRK_REVERSED,
};
static struct ddb_info ddb_v7 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V7 DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 2,
.board_control_2 = 4,
.ts_quirks = TS_QUIRK_REVERSED,
};
static struct ddb_info ddb_ctv7 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine CT V7 DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 3,
.board_control_2 = 4,
};
static struct ddb_info ddb_satixS2v3 = {
.type = DDB_OCTOPUS,
.name = "Mystique SaTiX-S2 V3 DVB adapter",
.regmap = &octopus_map,
.port_num = 3,
.i2c_mask = 0x07,
};
static struct ddb_info ddb_ci = {
.type = DDB_OCTOPUS_CI,
.name = "Digital Devices Octopus CI",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x03,
};
static struct ddb_info ddb_cis = {
.type = DDB_OCTOPUS_CI,
.name = "Digital Devices Octopus CI single",
.regmap = &octopus_map,
.port_num = 3,
.i2c_mask = 0x03,
};
static struct ddb_info ddb_ci_s2_pro = {
.type = DDB_OCTOPUS_CI,
.name = "Digital Devices Octopus CI S2 Pro",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x01,
.board_control = 2,
.board_control_2 = 4,
};
static struct ddb_info ddb_ci_s2_pro_a = {
.type = DDB_OCTOPUS_CI,
.name = "Digital Devices Octopus CI S2 Pro Advanced",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x01,
.board_control = 2,
.board_control_2 = 4,
};
static struct ddb_info ddb_dvbct = {
.type = DDB_OCTOPUS,
.name = "Digital Devices DVBCT V6.1 DVB adapter",
.regmap = &octopus_map,
.port_num = 3,
.i2c_mask = 0x07,
};
/****************************************************************************/
static struct ddb_info ddb_mod = {
.type = DDB_MOD,
.name = "Digital Devices DVB-C modulator",
.regmap = &octopus_mod_map,
.port_num = 10,
.temp_num = 1,
};
static struct ddb_info ddb_mod_fsm_24 = {
.type = DDB_MOD,
.version = 2,
.name = "Digital Devices DVB-C modulator FSM-24",
.regmap = &octopus_mod_2_map,
.port_num = 24,
.temp_num = 1,
.tempmon_irq = 8,
};
static struct ddb_info ddb_mod_fsm_16 = {
.type = DDB_MOD,
.version = 2,
.name = "Digital Devices DVB-C modulator FSM-16",
.regmap = &octopus_mod_2_map,
.port_num = 16,
.temp_num = 1,
.tempmon_irq = 8,
};
static struct ddb_info ddb_mod_fsm_8 = {
.type = DDB_MOD,
.name = "Digital Devices DVB-C modulator FSM-8",
.version = 2,
.regmap = &octopus_mod_2_map,
.port_num = 8,
.temp_num = 1,
.tempmon_irq = 8,
};
static struct ddb_info ddb_sdr = {
.type = DDB_MOD,
.name = "Digital Devices SDR",
.version = 3,
.regmap = &octopus_sdr_map,
.port_num = 16,
.temp_num = 1,
.tempmon_irq = 8,
};
static struct ddb_info ddb_octopro_hdin = {
.type = DDB_OCTOPRO_HDIN,
.name = "Digital Devices OctopusNet Pro HDIN",
.regmap = &octopro_hdin_map,
.port_num = 10,
.i2c_mask = 0x3ff,
.mdio_num = 1,
};
static struct ddb_info ddb_octopro = {
.type = DDB_OCTOPRO,
.name = "Digital Devices OctopusNet Pro",
.regmap = &octopro_map,
.port_num = 10,
.i2c_mask = 0x3ff,
.mdio_num = 1,
};
static struct ddb_info ddb_s2_48 = {
.type = DDB_OCTOPUS_MAX,
.name = "Digital Devices MAX S8 4/8",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x01,
.board_control = 1,
.tempmon_irq = 24,
};
static struct ddb_info ddb_ct2_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 CT2",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
static struct ddb_info ddb_c2t2_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 C2T2",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
static struct ddb_info ddb_isdbt_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 ISDBT",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
static struct ddb_info ddb_c2t2i_v0_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 C2T2I V0",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL | TS_QUIRK_ALT_OSC,
.tempmon_irq = 24,
};
static struct ddb_info ddb_c2t2i_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX A8 C2T2I",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
.tempmon_irq = 24,
};
/****************************************************************************/
/****************************************************************************/
static struct ddb_regmap octopus_net_map = {
.irq_version = 1,
.irq_base_i2c = 0,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.input = &octopus_input,
.output = &octopus_output,
};
static struct ddb_regset octopus_gtl = {
.base = 0x180,
.num = 0x01,
.size = 0x20,
};
static struct ddb_regmap octopus_net_gtl = {
.irq_version = 1,
.irq_base_i2c = 0,
.irq_base_gtl = 10,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.input = &octopus_input,
.output = &octopus_output,
.gtl = &octopus_gtl,
};
static struct ddb_info ddb_octonet = {
.type = DDB_OCTONET,
.name = "Digital Devices OctopusNet network DVB adapter",
.regmap = &octopus_net_map,
.port_num = 4,
.i2c_mask = 0x0f,
.ns_num = 12,
.mdio_num = 1,
};
static struct ddb_info ddb_octonet_jse = {
.type = DDB_OCTONET,
.name = "Digital Devices OctopusNet network DVB adapter JSE",
.regmap = &octopus_net_map,
.port_num = 4,
.i2c_mask = 0x0f,
.ns_num = 15,
.mdio_num = 1,
};
static struct ddb_info ddb_octonet_gtl = {
.type = DDB_OCTONET,
.name = "Digital Devices OctopusNet GTL",
.regmap = &octopus_net_gtl,
.port_num = 4,
.i2c_mask = 0x05,
.ns_num = 12,
.mdio_num = 1,
.con_clock = 1,
};
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
struct ddb_device_id {
u16 vendor;
u16 device;
u16 subvendor;
u16 subdevice;
struct ddb_info *info;
};
#define DDB_DEVID(_device, _subdevice, _info) { \
.vendor = 0xdd01, \
.device = _device, \
.subvendor = 0xdd01, \
.subdevice = _subdevice, \
.info = &_info }
static struct ddb_device_id ddb_device_ids[] = {
/* OctopusNet */
DDB_DEVID(0x0300, 0xffff, ddb_octonet),
DDB_DEVID(0x0301, 0xffff, ddb_octonet_jse),
DDB_DEVID(0x0307, 0xffff, ddb_octonet_gtl),
/* PCIe devices */
DDB_DEVID(0x0002, 0x0001, ddb_octopus),
DDB_DEVID(0x0003, 0x0001, ddb_octopus),
DDB_DEVID(0x0005, 0x0004, ddb_octopusv3),
DDB_DEVID(0x0003, 0x0002, ddb_octopus_le),
DDB_DEVID(0x0003, 0x0003, ddb_octopus_oem),
DDB_DEVID(0x0003, 0x0010, ddb_octopus_mini),
DDB_DEVID(0x0005, 0x0011, ddb_octopus_mini),
DDB_DEVID(0x0003, 0x0020, ddb_v6),
DDB_DEVID(0x0003, 0x0021, ddb_v6_5),
DDB_DEVID(0x0006, 0x0022, ddb_v7),
DDB_DEVID(0x0006, 0x0024, ddb_v7a),
DDB_DEVID(0x0003, 0x0030, ddb_dvbct),
DDB_DEVID(0x0003, 0xdb03, ddb_satixS2v3),
DDB_DEVID(0x0006, 0x0031, ddb_ctv7),
DDB_DEVID(0x0006, 0x0032, ddb_ctv7),
DDB_DEVID(0x0006, 0x0033, ddb_ctv7),
DDB_DEVID(0x0007, 0x0023, ddb_s2_48),
DDB_DEVID(0x0008, 0x0034, ddb_ct2_8),
DDB_DEVID(0x0008, 0x0035, ddb_c2t2_8),
DDB_DEVID(0x0008, 0x0036, ddb_isdbt_8),
DDB_DEVID(0x0008, 0x0037, ddb_c2t2i_v0_8),
DDB_DEVID(0x0008, 0x0038, ddb_c2t2i_8),
DDB_DEVID(0x0006, 0x0039, ddb_ctv7),
DDB_DEVID(0x0011, 0x0040, ddb_ci),
DDB_DEVID(0x0011, 0x0041, ddb_cis),
DDB_DEVID(0x0012, 0x0042, ddb_ci),
DDB_DEVID(0x0013, 0x0043, ddb_ci_s2_pro),
DDB_DEVID(0x0013, 0x0044, ddb_ci_s2_pro_a),
DDB_DEVID(0x0201, 0x0001, ddb_mod),
DDB_DEVID(0x0201, 0x0002, ddb_mod),
DDB_DEVID(0x0203, 0x0001, ddb_mod),
DDB_DEVID(0x0210, 0x0001, ddb_mod_fsm_24),
DDB_DEVID(0x0210, 0x0002, ddb_mod_fsm_16),
DDB_DEVID(0x0210, 0x0003, ddb_mod_fsm_8),
DDB_DEVID(0x0220, 0x0001, ddb_sdr),
/* testing on OctopusNet Pro */
DDB_DEVID(0x0320, 0xffff, ddb_octopro_hdin),
DDB_DEVID(0x0321, 0xffff, ddb_none),
DDB_DEVID(0x0322, 0xffff, ddb_octopro),
DDB_DEVID(0x0323, 0xffff, ddb_none),
DDB_DEVID(0x0328, 0xffff, ddb_none),
DDB_DEVID(0x0329, 0xffff, ddb_octopro_hdin),
};
struct ddb_info *get_ddb_info(u16 vendor, u16 device, u16 subvendor, u16 subdevice)
{
int i;
for (i = 0; i < ARRAY_SIZE(ddb_device_ids); i++) {
struct ddb_device_id *id = &ddb_device_ids[i];
if (vendor == id->vendor &&
device == id->device &&
subvendor == id->subvendor &&
((subdevice == id->subdevice) ||
id->subdevice == 0xffff))
return id->info;
}
return &ddb_none;
}

View File

@@ -1,7 +1,7 @@
/* /*
* ddbridge-i2c.c: Digital Devices bridge i2c driver * ddbridge-i2c.c: Digital Devices bridge i2c driver
* *
* Copyright (C) 2010-2015 Digital Devices GmbH * Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de> * Ralph Metzler <rjkm@metzlerbros.de>
* Marcus Metzler <mocm@metzlerbros.de> * Marcus Metzler <mocm@metzlerbros.de>
* *
@@ -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,7 +252,6 @@ 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;

View File

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

View File

@@ -1,7 +1,7 @@
/* /*
* ddbridge.c: Digital Devices PCIe bridge driver * ddbridge.c: Digital Devices PCIe bridge driver
* *
* Copyright (C) 2010-2015 Digital Devices GmbH * Copyright (C) 2010-2017 Digital Devices GmbH
* Marcus Metzler <mocm@metzlerbros.de> * Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de> * Ralph Metzler <rjkm@metzlerbros.de>
* *
@@ -76,40 +76,42 @@ 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;
@@ -118,15 +120,18 @@ static inline u32 gcd(u32 u,u32 v)
while ((u & 1) == 0) while ((u & 1) == 0)
u >>= 1; u >>= 1;
do { do {
while ( (v&1) == 0 ) v >>= 1; while ((v & 1) == 0)
v >>= 1;
if (u > v) { 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);
} }
/****************************************************************************/ /****************************************************************************/
@@ -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,16 +333,19 @@ 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;
@@ -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,
MAX2871_CONTROL);
while (1) { 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)
@@ -493,7 +516,7 @@ static int mod_fsm_setup(struct ddb *dev, u32 FrequencyPlan, u32 MaxUsedChannels
else else
ddbwritel(dev, FSM_GAIN_N96, FSM_GAIN); ddbwritel(dev, FSM_GAIN_N96, FSM_GAIN);
ddbwritel(dev, FSM_CONTROL_ENABLE, FSM_CONTROL); dev->link[0].info->port_num = MaxUsedChannels;
return status; return status;
} }
@@ -506,77 +529,6 @@ static int mod_set_vga(struct ddb *dev, u32 Gain)
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,9 +1242,9 @@ 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,10 +1427,90 @@ 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;
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);
case MODULATOR_ATTENUATOR:
return mod_set_attenuator(mod->port->dev, tvp->u.data);
case MODULATOR_GAIN:
return mod_set_vga(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) { 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 +1526,11 @@ 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);
case MODULATOR_GAIN:
if (mod->port->dev->link[0].info->version == 2)
return mod_set_vga(mod->port->dev, tvp->u.data);
return -EINVAL;
} }
return 0; return 0;
} }
@@ -1504,17 +1543,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,7 +1568,8 @@ 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;
} }
@@ -1588,30 +1632,158 @@ 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)
mod_set_vga(dev, RF_VGA_GAIN_N8);
else if (streams <= 16)
mod_set_vga(dev, RF_VGA_GAIN_N16);
else
mod_set_vga(dev, RF_VGA_GAIN_N24);
mod_set_attenuator(dev, 0); mod_set_attenuator(dev, 0);
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;
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, 0x00002000, SDR_CHANNEL_FM1GAIN(i));
ddbwritel(dev, 0x00001000, SDR_CHANNEL_FM2GAIN(i));
}
mod_set_attenuator(dev, 0);
mod_set_vga(dev, 64);
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;
} }

View File

@@ -1,7 +1,7 @@
/* /*
* ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming * ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming
* *
* Copyright (C) 2010-2015 Marcus Metzler <mocm@metzlerbros.de> * Copyright (C) 2010-2017Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de> * Ralph Metzler <rjkm@metzlerbros.de>
* Digital Devices GmbH * Digital Devices GmbH
* *
@@ -87,7 +87,6 @@ static int ns_alloc(struct dvbnss *nss)
dev->ns[i].fe = input; dev->ns[i].fe = input;
nss->priv = &dev->ns[i]; nss->priv = &dev->ns[i];
ret = 0; ret = 0;
/*pr_info("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;

View File

@@ -1,7 +1,7 @@
/* /*
* ddbridge-regs.h: Digital Devices PCIe bridge driver * ddbridge-regs.h: Digital Devices PCIe bridge driver
* *
* Copyright (C) 2010-2016 Digital Devices GmbH * Copyright (C) 2010-2017 Digital Devices GmbH
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -25,6 +25,7 @@
#define CUR_REGISTERMAP_VERSION_V1 0x00010001 #define CUR_REGISTERMAP_VERSION_V1 0x00010001
#define CUR_REGISTERMAP_VERSION_V2 0x00020000 #define CUR_REGISTERMAP_VERSION_V2 0x00020000
#define CUR_REGISTERMAP_VERSION_022X 0x00020001
#define HARDWARE_VERSION 0x00000000 #define HARDWARE_VERSION 0x00000000
#define REGISTERMAP_VERSION 0x00000004 #define REGISTERMAP_VERSION 0x00000004
@@ -57,8 +58,8 @@
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* 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 <20>C x 256 (ADM1032 ext) #define TEMPMON1_CORE (TEMPMON_SENSOR0) // u16 Temperature in <20>C x 256 (ADM1032 ext)
#define TEMPMON1_SENSOR1 (TEMPMON_BASE + 0x08) // SHORT Temperature in <20>C x 256 (LM75A 0x90) #define TEMPMON1_SENSOR1 (TEMPMON_BASE + 0x08) // SHORT Temperature in <20>C x 256 (LM75A 0x90)
#define TEMPMON1_SENSOR2 (TEMPMON_BASE + 0x0C) // SHORT Temperature in <20>C x 256 (LM75A 0x92 or ADM1032 Int) #define TEMPMON1_SENSOR2 (TEMPMON_BASE + 0x0C) // SHORT Temperature in <20>C x 256 (LM75A 0x92 or ADM1032 Int)
@@ -179,6 +182,7 @@
#define TEMPMON2_BOARD (TEMPMON_SENSOR0) // SHORT Temperature in <20>C x 256 (ADM1032 int) #define TEMPMON2_BOARD (TEMPMON_SENSOR0) // SHORT Temperature in <20>C x 256 (ADM1032 int)
#define TEMPMON2_FPGACORE (TEMPMON_SENSOR1) // SHORT Temperature in <20>C x 256 (ADM1032 ext) #define TEMPMON2_FPGACORE (TEMPMON_SENSOR1) // SHORT Temperature in <20>C x 256 (ADM1032 ext)
#define TEMPMON2_QAMCORE (TEMPMON_SENSOR2) // SHORT Temperature in <20>C x 256 (ADM1032 ext) #define TEMPMON2_QAMCORE (TEMPMON_SENSOR2) // SHORT Temperature in <20>C x 256 (ADM1032 ext)
#define TEMPMON2_DACCORE (TEMPMON_SENSOR2) // SHORT Temperature in <20>C x 256 (ADM1032 ext)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
/* I2C Master Controller */ /* 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,9 +383,9 @@
#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)
@@ -409,8 +413,8 @@
#define RF_POWER_CONTROL_VALID (0x00000500) #define RF_POWER_CONTROL_VALID (0x00000500)
/* -------------------------------------------------------------------------- /*
Output control * Output control
*/ */
#define IQOUTPUT_BASE (0x240) #define IQOUTPUT_BASE (0x240)
@@ -552,3 +556,76 @@
// V2
// MAX2871 same as DVB Modulator V2
#define RFDAC_BASE (0x200)
#define RFDAC_CONTROL (RFDAC_BASE + 0x00)
#define RFDAC_CMD_MASK (0x00000087)
#define RFDAC_CMD_STATUS (0x00000080)
#define RFDAC_CMD_RESET (0x00000080)
#define RFDAC_CMD_POWERDOWN (0x00000081)
#define RFDAC_CMD_SETUP (0x00000082)
#define RFDAC_STATUS (RFDAC_BASE + 0x00)
#define RFDAC_STATUS_READY (0x00010000)
#define RFDAC_STATUS_DACREADY (0x00020000)
#define RFDAC_FCW (RFDAC_BASE + 0x10)
//
// --------------------------------------------------------------------------
//
#define JESD204B_BASE (0x280)
// Additional Status Bits
#define DMA_PCIE_LANES_MASK (0x00070000)
// --------------------------------------------------------------------------
// Modulator Channels, partially compatible to DVB Modulator V1
#define SDR_CHANNEL_BASE (0x800)
#define SDR_CHANNEL_CONTROL(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x00)
#define SDR_CHANNEL_CONFIG(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x04)
#define SDR_CHANNEL_CFCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x08)
#define SDR_CHANNEL_ARICW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x0C)
#define SDR_CHANNEL_RGAIN(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x10)
#define SDR_CHANNEL_SETFIR(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x14)
#define SDR_CHANNEL_FMDCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x20)
#define SDR_CHANNEL_FM1FCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x24)
#define SDR_CHANNEL_FM2FCW(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x28)
#define SDR_CHANNEL_FM1GAIN(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x2C)
#define SDR_CHANNEL_FM2GAIN(i) ((SDR_CHANNEL_BASE) + (i) * 64 + 0x30)
// Control and status bits
#define SDR_CONTROL_ENABLE_CHANNEL (0x00000004)
#define SDR_CONTROL_ENABLE_DMA (0x00000008)
#define SDR_STATUS_DMA_UNDERRUN (0x00010000)
// Config
#define SDR_CONFIG_ENABLE_FM1 (0x00000002)
#define SDR_CONFIG_ENABLE_FM2 (0x00000004)
#define SDR_CONFIG_DISABLE_ARI (0x00000010)
#define SDR_CONFIG_DISABLE_VSB (0x00000020)
// SET FIR
#define SDR_FIR_COEFF_MASK (0x00000FFF)
#define SDR_FIR_TAP_MASK (0x001F0000)
#define SDR_FIR_SELECT_MASK (0x00C00000)
#define SDR_VSB_LENGTH_MASK (0x01000000)
#define SDR_SET_FIR(select, tap, coeff, vsblen) \
((((select)<<22)&SDR_FIR_SELECT_MASK)| \
(((tap)<<16)&SDR_FIR_TAP_MASK)| \
((coeff)&SDR_FIR_COEFF_MASK)| \
(((vsblen)<<24)&SDR_VSB_LENGTH_MASK)| \
0 \
)

View File

@@ -1,7 +1,7 @@
/* /*
* ddbridge.c: Digital Devices PCIe bridge driver * ddbridge.c: Digital Devices PCIe bridge driver
* *
* Copyright (C) 2010-2015 Digital Devices GmbH * Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de> * Ralph Metzler <rjkm@metzlerbros.de>
* Marcus Metzler <mocm@metzlerbros.de> * Marcus Metzler <mocm@metzlerbros.de>
* *
@@ -29,34 +29,12 @@
#include "ddbridge.h" #include "ddbridge.h"
#include "ddbridge-regs.h" #include "ddbridge-regs.h"
static struct workqueue_struct *ddb_wq;
static int adapter_alloc;
module_param(adapter_alloc, int, 0444);
MODULE_PARM_DESC(adapter_alloc,
"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all");
#ifdef CONFIG_PCI_MSI
static int msi = 1;
module_param(msi, int, 0444);
MODULE_PARM_DESC(msi,
" Control MSI interrupts: 0-disable, 1-enable (default)");
#endif
#include "ddbridge-core.c" #include "ddbridge-core.c"
/****************************************************************************/ /****************************************************************************/
/****************************************************************************/ /****************************************************************************/
/****************************************************************************/ /****************************************************************************/
static void ddb_unmap(struct ddb *dev)
{
if (dev->regs)
iounmap(dev->regs);
vfree(dev);
}
static void __devexit ddb_irq_disable(struct ddb *dev) static void __devexit ddb_irq_disable(struct ddb *dev)
{ {
if (dev->link[0].info->regmap->irq_version == 2) { if (dev->link[0].info->regmap->irq_version == 2) {
@@ -113,12 +91,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",
@@ -139,6 +121,7 @@ static int __devinit ddb_irq_msi(struct ddb *dev, int nr)
pr_info("DDBridge: MSI not available.\n"); pr_info("DDBridge: MSI not available.\n");
#endif #endif
} }
#endif
return stat; return stat;
} }
@@ -210,9 +193,7 @@ static int __devinit ddb_irq_init(struct ddb *dev)
free_irq(dev->pdev->irq, dev); free_irq(dev->pdev->irq, dev);
return stat; return stat;
} }
} else } else {
#endif
{
#ifdef DDB_TEST_THREADED #ifdef DDB_TEST_THREADED
stat = request_threaded_irq(dev->pdev->irq, irq_handler, stat = request_threaded_irq(dev->pdev->irq, irq_handler,
irq_thread, irq_thread,
@@ -264,10 +245,11 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
dev->link[0].ids.vendor = id->vendor; dev->link[0].ids.vendor = id->vendor;
dev->link[0].ids.device = id->device; dev->link[0].ids.device = id->device;
dev->link[0].ids.subvendor = id->subvendor; dev->link[0].ids.subvendor = id->subvendor;
dev->link[0].ids.subdevice = id->subdevice; dev->link[0].ids.subdevice = pdev->subsystem_device;
dev->link[0].dev = dev; dev->link[0].dev = dev;
dev->link[0].info = (struct ddb_info *) id->driver_data; dev->link[0].info = get_ddb_info(id->vendor, id->device,
id->subvendor, pdev->subsystem_device);
pr_info("DDBridge: device name: %s\n", dev->link[0].info->name); 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);
@@ -300,6 +282,7 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
ddbwritel(dev, 0, DMA_BASE_WRITE); ddbwritel(dev, 0, DMA_BASE_WRITE);
if (dev->link[0].info->type == DDB_MOD) { if (dev->link[0].info->type == DDB_MOD) {
if (dev->link[0].info->version == 1)
if (ddbreadl(dev, 0x1c) == 4) if (ddbreadl(dev, 0x1c) == 4)
dev->link[0].info->port_num = 4; dev->link[0].info->port_num = 4;
} }
@@ -311,7 +294,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)
@@ -329,284 +312,35 @@ fail:
/****************************************************************************/ /****************************************************************************/
/****************************************************************************/ /****************************************************************************/
static struct ddb_info ddb_none = { #define DDB_DEVICE_ANY(_device) { PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, PCI_ANY_ID) }
.type = DDB_NONE,
.name = "unknown Digital Devices PCIe card, install newer driver",
.regmap = &octopus_map,
};
static struct ddb_info ddb_octopus = { static const struct pci_device_id ddb_id_table[] __devinitconst = {
.type = DDB_OCTOPUS, DDB_DEVICE_ANY(0x0002),
.name = "Digital Devices Octopus DVB adapter", DDB_DEVICE_ANY(0x0003),
.regmap = &octopus_map, DDB_DEVICE_ANY(0x0005),
.port_num = 4, DDB_DEVICE_ANY(0x0006),
.i2c_mask = 0x0f, DDB_DEVICE_ANY(0x0007),
}; DDB_DEVICE_ANY(0x0008),
DDB_DEVICE_ANY(0x0011),
static struct ddb_info ddb_octopusv3 = { DDB_DEVICE_ANY(0x0012),
.type = DDB_OCTOPUS, DDB_DEVICE_ANY(0x0013),
.name = "Digital Devices Octopus V3 DVB adapter", DDB_DEVICE_ANY(0x0201),
.regmap = &octopus_map, DDB_DEVICE_ANY(0x0203),
.port_num = 4, DDB_DEVICE_ANY(0x0210),
.i2c_mask = 0x0f, DDB_DEVICE_ANY(0x0220),
}; DDB_DEVICE_ANY(0x0320),
DDB_DEVICE_ANY(0x0321),
static struct ddb_info ddb_octopus_le = { DDB_DEVICE_ANY(0x0322),
.type = DDB_OCTOPUS, DDB_DEVICE_ANY(0x0323),
.name = "Digital Devices Octopus LE DVB adapter", DDB_DEVICE_ANY(0x0328),
.regmap = &octopus_map, DDB_DEVICE_ANY(0x0329),
.port_num = 2,
.i2c_mask = 0x03,
};
static struct ddb_info ddb_octopus_oem = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus OEM",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.led_num = 1,
.fan_num = 1,
.temp_num = 1,
.temp_bus = 0,
};
static struct ddb_info ddb_octopus_mini = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus Mini",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static struct ddb_info ddb_v6 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V6 DVB adapter",
.regmap = &octopus_map,
.port_num = 3,
.i2c_mask = 0x07,
};
static struct ddb_info ddb_v6_5 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V6.5 DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static struct ddb_info ddb_v7a = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V7 Advanced DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 2,
.board_control_2 = 4,
.ts_quirks = TS_QUIRK_REVERSED,
};
static struct ddb_info ddb_v7 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V7 DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 2,
.board_control_2 = 4,
.ts_quirks = TS_QUIRK_REVERSED,
};
static struct ddb_info ddb_ctv7 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine CT V7 DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 3,
.board_control_2 = 4,
};
static struct ddb_info ddb_satixS2v3 = {
.type = DDB_OCTOPUS,
.name = "Mystique SaTiX-S2 V3 DVB adapter",
.regmap = &octopus_map,
.port_num = 3,
.i2c_mask = 0x07,
};
static struct ddb_info ddb_ci = {
.type = DDB_OCTOPUS_CI,
.name = "Digital Devices Octopus CI",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x03,
};
static struct ddb_info ddb_cis = {
.type = DDB_OCTOPUS_CI,
.name = "Digital Devices Octopus CI single",
.regmap = &octopus_map,
.port_num = 3,
.i2c_mask = 0x03,
};
static struct ddb_info ddb_ci_s2_pro = {
.type = DDB_OCTOPUS_CI,
.name = "Digital Devices Octopus CI S2 Pro",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x01,
.board_control = 2,
.board_control_2 = 4,
};
static struct ddb_info ddb_ci_s2_pro_a = {
.type = DDB_OCTOPUS_CI,
.name = "Digital Devices Octopus CI S2 Pro Advanced",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x01,
.board_control = 2,
.board_control_2 = 4,
};
static struct ddb_info ddb_dvbct = {
.type = DDB_OCTOPUS,
.name = "Digital Devices DVBCT V6.1 DVB adapter",
.regmap = &octopus_map,
.port_num = 3,
.i2c_mask = 0x07,
};
/****************************************************************************/
static struct ddb_info ddb_mod = {
.type = DDB_MOD,
.name = "Digital Devices DVB-C modulator",
.regmap = &octopus_mod_map,
.port_num = 10,
.temp_num = 1,
};
static struct ddb_info ddb_mod_fsm_24 = {
.type = DDB_MOD,
.version = 2,
.name = "Digital Devices DVB-C modulator FSM-24",
.regmap = &octopus_mod_2_map,
.port_num = 24,
.temp_num = 1,
.tempmon_irq = 8,
};
static struct ddb_info ddb_mod_fsm_16 = {
.type = DDB_MOD,
.version = 2,
.name = "Digital Devices DVB-C modulator FSM-16",
.regmap = &octopus_mod_2_map,
.port_num = 16,
.temp_num = 1,
.tempmon_irq = 8,
};
static struct ddb_info ddb_mod_fsm_8 = {
.type = DDB_MOD,
.name = "Digital Devices DVB-C modulator FSM-8",
.version = 2,
.regmap = &octopus_mod_2_map,
.port_num = 8,
.temp_num = 1,
.tempmon_irq = 8,
};
static struct ddb_info ddb_octopro_hdin = {
.type = DDB_OCTOPRO_HDIN,
.name = "Digital Devices OctopusNet Pro HDIN",
.regmap = &octopro_hdin_map,
.port_num = 10,
.i2c_mask = 0x3ff,
.mdio_num = 1,
};
static struct ddb_info ddb_octopro = {
.type = DDB_OCTOPRO,
.name = "Digital Devices OctopusNet Pro",
.regmap = &octopro_map,
.port_num = 10,
.i2c_mask = 0x3ff,
.mdio_num = 1,
};
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
#define DDVID 0xdd01 /* Digital Devices Vendor ID */
#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \
.vendor = _vend, .device = _dev, \
.subvendor = _subvend, .subdevice = _subdev, \
.driver_data = (unsigned long)&_driverdata }
static const struct pci_device_id ddb_id_tbl[] __devinitconst = {
DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus),
DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus),
DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3),
DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le),
DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem),
DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini),
DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini),
DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6),
DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5),
DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7),
DDB_ID(DDVID, 0x0006, DDVID, 0x0024, ddb_v7a),
DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct),
DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3),
DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7),
DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7),
DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7),
DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48),
DDB_ID(DDVID, 0x0008, DDVID, 0x0034, ddb_ct2_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0035, ddb_c2t2_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0036, ddb_isdbt_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0037, ddb_c2t2i_v0_8),
DDB_ID(DDVID, 0x0008, DDVID, 0x0038, ddb_c2t2i_8),
DDB_ID(DDVID, 0x0006, DDVID, 0x0039, ddb_ctv7),
DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci),
DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis),
DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci),
DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro),
DDB_ID(DDVID, 0x0013, DDVID, 0x0044, ddb_ci_s2_pro_a),
DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod),
DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod),
DDB_ID(DDVID, 0x0203, DDVID, 0x0001, ddb_mod),
DDB_ID(DDVID, 0x0210, DDVID, 0x0001, ddb_mod_fsm_24),
DDB_ID(DDVID, 0x0210, DDVID, 0x0002, ddb_mod_fsm_16),
DDB_ID(DDVID, 0x0210, DDVID, 0x0003, ddb_mod_fsm_8),
/* testing on OctopusNet Pro */
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro_hdin),
DDB_ID(DDVID, 0x0321, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0322, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro),
DDB_ID(DDVID, 0x0323, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0328, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0329, PCI_ANY_ID, PCI_ANY_ID, ddb_octopro_hdin),
/* in case sub-ids got deleted in flash */
DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0005, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0008, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
{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 +351,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");

View File

@@ -1,7 +1,7 @@
/* /*
* ddbridge.h: Digital Devices PCIe bridge driver * ddbridge.h: Digital Devices PCIe bridge driver
* *
* Copyright (C) 2010-2015 Digital Devices GmbH * Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rmetzler@digitaldevices.de> * Ralph Metzler <rmetzler@digitaldevices.de>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@@ -55,7 +55,6 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/sched.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <asm/dma.h> #include <asm/dma.h>
@@ -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,10 @@ 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.30"
/* linked functions */
struct ddb_info *get_ddb_info(u16 vendor, u16 device, u16 subvendor, u16 subdevice);
#endif #endif

View File

@@ -1,7 +1,7 @@
/* /*
* octonet.c: Digital Devices network tuner driver * octonet.c: Digital Devices network tuner driver
* *
* Copyright (C) 2012-16 Digital Devices GmbH * Copyright (C) 2012-17 Digital Devices GmbH
* Marcus Metzler <mocm@metzlerbros.de> * Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de> * Ralph Metzler <rjkm@metzlerbros.de>
* *
@@ -31,83 +31,8 @@
#include <linux/pci-dma-compat.h> #include <linux/pci-dma-compat.h>
#endif #endif
static int adapter_alloc = 3;
module_param(adapter_alloc, int, 0444);
MODULE_PARM_DESC(adapter_alloc,
"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all");
#include "ddbridge-core.c" #include "ddbridge-core.c"
static struct ddb_regmap octopus_net_map = {
.irq_version = 1,
.irq_base_i2c = 0,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.input = &octopus_input,
.output = &octopus_output,
};
static struct ddb_regset octopus_gtl = {
.base = 0x180,
.num = 0x01,
.size = 0x20,
};
static struct ddb_regmap octopus_net_gtl = {
.irq_version = 1,
.irq_base_i2c = 0,
.irq_base_gtl = 10,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.input = &octopus_input,
.output = &octopus_output,
.gtl = &octopus_gtl,
};
static struct ddb_info ddb_octonet = {
.type = DDB_OCTONET,
.name = "Digital Devices OctopusNet network DVB adapter",
.regmap = &octopus_net_map,
.port_num = 4,
.i2c_mask = 0x0f,
.ns_num = 12,
.mdio_num = 1,
};
static struct ddb_info ddb_octonet_jse = {
.type = DDB_OCTONET,
.name = "Digital Devices OctopusNet network DVB adapter JSE",
.regmap = &octopus_net_map,
.port_num = 4,
.i2c_mask = 0x0f,
.ns_num = 15,
.mdio_num = 1,
};
static struct ddb_info ddb_octonet_gtl = {
.type = DDB_OCTONET,
.name = "Digital Devices OctopusNet GTL",
.regmap = &octopus_net_gtl,
.port_num = 4,
.i2c_mask = 0x05,
.ns_num = 12,
.mdio_num = 1,
.con_clock = 1,
};
static struct ddb_info ddb_octonet_tbd = {
.type = DDB_OCTONET,
.name = "Digital Devices OctopusNet",
.regmap = &octopus_net_map,
};
static void octonet_unmap(struct ddb *dev)
{
if (dev->regs)
iounmap(dev->regs);
vfree(dev);
}
static int __exit octonet_remove(struct platform_device *pdev) static int __exit octonet_remove(struct platform_device *pdev)
{ {
struct ddb *dev; struct ddb *dev;
@@ -125,7 +50,7 @@ static int __exit octonet_remove(struct platform_device *pdev)
free_irq(platform_get_irq(dev->pfdev, 0), dev); free_irq(platform_get_irq(dev->pfdev, 0), dev);
ddb_ports_release(dev); ddb_ports_release(dev);
octonet_unmap(dev); ddb_unmap(dev);
platform_set_drvdata(pdev, 0); platform_set_drvdata(pdev, 0);
return 0; return 0;
} }
@@ -168,6 +93,7 @@ static int __init octonet_probe(struct platform_device *pdev)
dev->link[0].ids.subdevice = dev->link[0].ids.devid >> 16; dev->link[0].ids.subdevice = dev->link[0].ids.devid >> 16;
dev->link[0].dev = dev; dev->link[0].dev = dev;
#if 0
if (dev->link[0].ids.devid == 0x0300dd01) if (dev->link[0].ids.devid == 0x0300dd01)
dev->link[0].info = &ddb_octonet; dev->link[0].info = &ddb_octonet;
else if (dev->link[0].ids.devid == 0x0301dd01) else if (dev->link[0].ids.devid == 0x0301dd01)
@@ -176,7 +102,11 @@ static int __init octonet_probe(struct platform_device *pdev)
dev->link[0].info = &ddb_octonet_gtl; dev->link[0].info = &ddb_octonet_gtl;
else else
dev->link[0].info = &ddb_octonet_tbd; dev->link[0].info = &ddb_octonet_tbd;
#else
dev->link[0].info = get_ddb_info(dev->link[0].ids.vendor,
dev->link[0].ids.device,
0xdd01, 0xffff);
#endif
pr_info("DDBridge: HW %08x REGMAP %08x\n", pr_info("DDBridge: HW %08x REGMAP %08x\n",
dev->link[0].ids.hwid, dev->link[0].ids.regmapid); dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
pr_info("DDBridge: MAC %08x DEVID %08x\n", pr_info("DDBridge: MAC %08x DEVID %08x\n",
@@ -203,7 +133,7 @@ fail:
dev_err(dev->dev, "fail\n"); dev_err(dev->dev, "fail\n");
ddbwritel(dev, 0, ETHER_CONTROL); ddbwritel(dev, 0, ETHER_CONTROL);
ddbwritel(dev, 0, INTERRUPT_ENABLE); ddbwritel(dev, 0, INTERRUPT_ENABLE);
octonet_unmap(dev); ddb_unmap(dev);
platform_set_drvdata(pdev, 0); platform_set_drvdata(pdev, 0);
return -1; return -1;
} }
@@ -217,7 +147,7 @@ static const struct of_device_id octonet_dt_ids[] = {
MODULE_DEVICE_TABLE(of, octonet_dt_ids); MODULE_DEVICE_TABLE(of, octonet_dt_ids);
#endif #endif
static struct platform_driver octonet_driver = { static struct platform_driver octonet_driver __refdata = {
.remove = __exit_p(octonet_remove), .remove = __exit_p(octonet_remove),
.probe = octonet_probe, .probe = octonet_probe,
.driver = { .driver = {
@@ -258,4 +188,4 @@ module_exit(exit_octonet);
MODULE_DESCRIPTION("GPL"); MODULE_DESCRIPTION("GPL");
MODULE_AUTHOR("Marcus and Ralph Metzler, Metzler Brothers Systementwicklung GbR"); MODULE_AUTHOR("Marcus and Ralph Metzler, Metzler Brothers Systementwicklung GbR");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_VERSION("0.6"); MODULE_VERSION(DDBRIDGE_VERSION);

View File

@@ -35,7 +35,12 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
#include <linux/sched/signal.h>
#else
#include <linux/sched.h> #include <linux/sched.h>
#endif
#include <linux/kthread.h> #include <linux/kthread.h>
#include "dvb_ca_en50221.h" #include "dvb_ca_en50221.h"
@@ -763,7 +768,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
status = -EAGAIN; status = -EAGAIN;
goto exit; goto exit;
} }
#if 0
/* It may need some time for the CAM to settle down, or there might be a /* It may need some time for the CAM to settle down, or there might be a
race condition between the CAM, writing HC and our last check for DA. race condition between the CAM, writing HC and our last check for DA.
This happens, if the CAM asserts DA, just after checking DA before we This happens, if the CAM asserts DA, just after checking DA before we
@@ -781,7 +786,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * b
status = -EAGAIN; status = -EAGAIN;
goto exit; goto exit;
} }
#endif
/* send the amount of data */ /* send the amount of data */
if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0) if ((status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_SIZE_HIGH, bytes_write >> 8)) != 0)
goto exit; goto exit;

View File

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

View File

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

View File

@@ -31,7 +31,12 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/version.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
#include <asm/uaccess.h> #include <asm/uaccess.h>
#else
#include <linux/uaccess.h>
#endif
#include "dvb_ringbuffer.h" #include "dvb_ringbuffer.h"

View File

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

View File

@@ -662,15 +662,19 @@ static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount) static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
{ {
struct cxd *ci = ca->data; struct cxd *ci = ca->data;
int status;
if (ci->write_busy) if (ci->write_busy)
return -EAGAIN; return -EAGAIN;
mutex_lock(&ci->lock); mutex_lock(&ci->lock);
write_reg(ci, 0x0d, ecount >> 8); write_reg(ci, 0x0d, ecount >> 8);
write_reg(ci, 0x0e, ecount & 0xff); write_reg(ci, 0x0e, ecount & 0xff);
write_block(ci, 0x11, ebuf, ecount); status = write_block(ci, 0x11, ebuf, ecount);
if (!status)
ci->write_busy = 1; ci->write_busy = 1;
mutex_unlock(&ci->lock); mutex_unlock(&ci->lock);
if (status)
return status;
return ecount; return ecount;
} }
#endif #endif

View File

@@ -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;
} }

View File

@@ -146,7 +146,7 @@ struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe,
fe->ops.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage; fe->ops.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage;
fe->ops.release_sec = lnbh25_release; fe->ops.release_sec = lnbh25_release;
pr_info("LNB25 on %02x\n", lnbh->adr); pr_info("LNBH25 on %02x\n", lnbh->adr);
return fe; return fe;
} }

View File

@@ -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,

View File

@@ -673,6 +673,7 @@ static int GetBitErrorRateS(struct stv *state, u32 *BERNumerator,
static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType) static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType)
{ {
static u32 nBCH[][2] = { static u32 nBCH[][2] = {
{ 0, 0}, /* dummy */
{16200, 3240}, /* QPSK_1_4, */ {16200, 3240}, /* QPSK_1_4, */
{21600, 5400}, /* QPSK_1_3, */ {21600, 5400}, /* QPSK_1_3, */
{25920, 6480}, /* QPSK_2_5, */ {25920, 6480}, /* QPSK_2_5, */
@@ -705,7 +706,7 @@ static u32 DVBS2_nBCH(enum DVBS2_ModCod ModCod, enum DVBS2_FECType FECType)
if (ModCod >= DVBS2_QPSK_1_4 && if (ModCod >= DVBS2_QPSK_1_4 &&
ModCod <= DVBS2_32APSK_9_10 && FECType <= DVBS2_16K) ModCod <= DVBS2_32APSK_9_10 && FECType <= DVBS2_16K)
return nBCH[FECType][ModCod]; return nBCH[ModCod][FECType];
return 64800; return 64800;
} }
@@ -1534,13 +1535,13 @@ static int tune(struct dvb_frontend *fe, bool re_tune,
return r; return r;
state->tune_time = jiffies; state->tune_time = jiffies;
} }
if (*status & FE_HAS_LOCK)
return 0;
*delay = HZ;
r = read_status(fe, status); r = read_status(fe, status);
if (r) if (r)
return r; return r;
if (*status & FE_HAS_LOCK)
return 0;
*delay = HZ / 10;
return 0; return 0;
} }
@@ -1781,7 +1782,8 @@ static struct dvb_frontend_ops stv0910_ops = {
.caps = FE_CAN_INVERSION_AUTO | .caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_AUTO | FE_CAN_FEC_AUTO |
FE_CAN_QPSK | FE_CAN_QPSK |
FE_CAN_2G_MODULATION FE_CAN_2G_MODULATION |
FE_CAN_MULTISTREAM,
}, },
.init = init, .init = init,
.sleep = sleep, .sleep = sleep,

View File

@@ -25,9 +25,11 @@ 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_GAIN 35
#define MODULATOR_OUTPUT_ARI 64
#endif /*_UAPI_DVBMOD_H_*/ #endif /*_UAPI_DVBMOD_H_*/