134 Commits

Author SHA1 Message Date
mvoelkel
41897e48c8 bump version to 0.9.32 2017-09-23 12:12:38 +02:00
Ralph Metzler
4765eac57a optimize stat checks and only allow stat checks once a second 2017-09-20 21:00:21 +02:00
Ralph Metzler
7756a09420 add i2c commands 2017-09-20 02:36:58 +02:00
Ralph Metzler
92b64711ec strict checkpatch style adjustments 2017-09-16 15:31:52 +02:00
Ralph Metzler
e817b91860 re-enable port_attach error handling 2017-09-10 23:12:54 +02:00
Ralph Metzler
b814cf09e4 use enums instead of types 2017-09-10 23:11:15 +02:00
Ralph Metzler
0dd0997133 change FSM card channel number detection to use register 0x1c 2017-09-10 22:25:02 +02:00
Ralph Metzler
983949f4dd - initialize modulators before registering devices to prevent races
- check for number of FSM modulator channels before allocating ports
2017-09-09 00:21:11 +02:00
Ralph Metzler
fe5f6b737c convert all device information structs to const and fix related problems 2017-09-08 14:47:14 +02:00
Ralph Metzler
3e67af1b5b remove old commented out buggy codepath 2017-09-07 21:55:56 +02:00
Ralph Metzler
e4acb524a7 return EINVAL if input NULL (e.g. in case of mod devices) 2017-09-06 17:51:30 +02:00
Ralph Metzler
aa2762747f move MaxS8 and special MAX card LNB functions to separate file 2017-08-27 23:54:49 +02:00
Ralph Metzler
117d9a065d correct header line 2017-08-27 22:17:27 +02:00
Ralph Metzler
17b3e1ed26 move ci support to separate file 2017-08-27 22:09:43 +02:00
Ralph Metzler
07f7720145 prefix irq handlers with ddb_ to avoid name collisions 2017-08-27 21:42:02 +02:00
Ralph Metzler
b2ca06e639 strict checkpatch style fixes 2017-08-26 22:04:37 +02:00
Ralph Metzler
2b6babfdc0 coding style fixes according to checkpatch 2017-08-26 10:32:53 +02:00
Ralph Metzler
5074e28e10 change output functions from pr_ to dev_ 2017-08-25 23:30:58 +02:00
Ralph Metzler
df4f23384b lower lowest symbol rate to 100000 2017-08-25 23:30:28 +02:00
Ralph Metzler
838eb620ba write register with mode last 2017-08-25 22:07:43 +02:00
Ralph Metzler
e55dcd2fd2 correct status check order 2017-08-25 22:07:43 +02:00
Ralph Metzler
27601b4769 fix for new kernels 2017-08-25 22:07:43 +02:00
mvoelkel
5751c3fb1a bump version to 0.9.31 2017-08-11 22:57:02 +02:00
Ralph Metzler
5c032058b9 add support for PLS 2017-08-11 16:03:45 +02:00
Ralph Metzler
a44dbc889b correct lock check order 2017-08-11 16:03:03 +02:00
Ralph Metzler
3d5fae7dd8 add some explanation and correct help message 2017-08-08 22:06:36 +02:00
Ralph Metzler
7602ecf3e5 fixed regression for FSM modulators 2017-08-04 17:50:03 +02:00
Ralph Metzler
bf0315bcc0 move io functions to ddbridge-io.[ch] 2017-08-02 20:22:52 +02:00
Ralph Metzler
dcddb3437d compile parts of ddbridge and octonet seperately 2017-08-02 17:40:24 +02:00
Ralph Metzler
665b5ef857 add Kconfigs and Makefiles for OctopusNet kernel 2017-08-02 17:34:53 +02:00
Ralph Metzler
c063cffa63 fix comparison for older cards 2017-08-02 16:47:56 +02:00
Ralph Metzler
640c15f4a7 add "pls" too to convert between gold and root codes for DVB-S2 PLS 2017-08-02 00:10:13 +02:00
Ralph Metzler
d3ca949ec5 wrong bitmask for compatibility mode 2017-07-29 14:47:57 +02:00
Ralph Metzler
fd41904378 fix gap handling
gap attribute of 128 will now disable gap
2017-07-27 21:56:39 +02:00
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
37de742aad add id for pro advanced 2017-02-06 13:28:45 +01:00
Ralph Metzler
4bfdb11762 add id for pro advanced 2017-02-06 13:25:57 +01:00
Ralph Metzler
1e99122d52 support cine s2 v7a 2017-02-06 12:49:16 +01:00
Ralph Metzler
cd5de95023 fix error handling and ID output length 2017-02-06 12:48:54 +01:00
Ralph Metzler
c56f593a4c add support for single demod mode for testing high bit rates 2017-02-06 12:48:48 +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
Ralph Metzler
1f77192d62 mask lower bits for temp 2016-12-14 19:24:58 +01:00
Ralph Metzler
fc4a807b4e add support for new cine and change 24 MHz osciallator handling 2016-12-14 19:11:57 +01:00
Ralph Metzler
b6d5976e14 support for 24MHz crystals 2016-11-07 21:19:53 +01:00
Ralph Metzler
101289c77e move common flash code to flash.c 2016-10-24 15:15:09 +02:00
Ralph Metzler
26eedb3d26 change some pr_info to pr_debug 2016-10-24 15:13:26 +02:00
Ralph Metzler
d1387078f1 add DDBridge to all message lines 2016-10-10 00:19:16 +02:00
Ralph Metzler
6bf258b54c - initialize SKU ids
- add debug code to check if firmware crashed
2016-10-10 00:18:37 +02:00
Ralph Metzler
4435efeab5 - initialize SNR values to 0
- check for 0 in register values so that log function does not throw kernel warnings
2016-10-10 00:16:10 +02:00
Ralph Metzler
633797e05f add setmod2 2016-10-10 00:14:38 +02:00
Ralph Metzler
4ee27ff317 change DMA buf size for small bufs to be multiple of 128 2016-10-10 00:14:03 +02:00
Ralph Metzler
7d7da35fb5 add optional file name for flashread 2016-10-10 00:12:47 +02:00
Ralph Metzler
a3b517391a use device id instead of type 2016-10-10 00:10:39 +02:00
Ralph Metzler
1171b345df change MOD_ to MODULATOR_ because of overlapwith timex.h 2016-09-12 14:41:47 +02:00
Ralph Metzler
7f746f0219 backwards compatibility: set all frequencies of V2 card if base frequency is set 2016-09-12 13:46:10 +02:00
mvoelkel
49a05e75af Set version 0.9.26 2016-09-05 16:16:02 +02:00
Ralph Metzler
c546918e79 set deafult ci bitrate to 70MHz 2016-09-05 14:25:43 +02:00
Ralph Metzler
570a565f37 add test app for new modulator API 2016-09-05 14:25:43 +02:00
Ralph Metzler
85b1447059 add new properties API for modulator 2016-09-05 14:25:43 +02:00
Ralph Metzler
a4c275895d missing init for status 2016-09-05 14:25:43 +02:00
Ralph Metzler
7a8d3f80c4 add modulator properties 2016-09-05 14:25:43 +02:00
50 changed files with 6910 additions and 4990 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
- 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)
MODDEFS := CONFIG_DVB_CORE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_CXD2099=m CONFIG_DVB_LNBP21=m CONFIG_DVB_STV090x=m CONFIG_DVB_STV6110x=m CONFIG_DVB_STV0367=m CONFIG_DVB_TDA18212=m CONFIG_DVB_STV0367DD=m CONFIG_DVB_TDA18212DD=m CONFIG_DVB_OCTONET=m CONFIG_DVB_CXD2843=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6111=m CONFIG_DVB_LNBH25=m CONFIG_DVB_MXL5XX=m
@@ -14,6 +15,6 @@ install: all
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
clean:
rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
rm -rf */.*.o.d */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*

View File

@@ -1,10 +1,13 @@
# DDBridge Driver
###Prepare for Building
### Patches
We can only accept patches which don't break compilation for older kernels (as far back as 2.6.37).
### Prepare for Building
TBD
###Building
### Building
TBD

View File

@@ -1,19 +1,25 @@
all: cit citin flashprog modt ddtest setmod ddflash
all: cit citin flashprog modt ddtest setmod ddflash setmod2 pls
cit: cit.c
gcc -o cit cit.c -lpthread
$(CC) -o cit cit.c -lpthread
modt: modt.c
gcc -o modt modt.c -lpthread
$(CC) -o modt modt.c -lpthread
setmod: setmod.c
gcc -o setmod setmod.c -I../include/
$(CC) -o setmod setmod.c -I../include/
setmod2: setmod2.c
$(CC) -o setmod2 setmod2.c -I../include/
flashprog: flashprog.c
gcc -o flashprog flashprog.c
$(CC) -o flashprog flashprog.c
ddtest: ddtest.c
gcc -o ddtest ddtest.c
$(CC) -o ddtest ddtest.c
ddflash: ddflash.c
gcc -o ddflash ddflash.c
$(CC) -o ddflash ddflash.c
pls: pls.c
$(CC) -o pls pls.c

View File

@@ -91,8 +91,13 @@ void *get_ts(void *a)
if (!buf)
return NULL;
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
printf("using %s for reading\n", fname);
fdi = open(fname, O_RDONLY);
if (fdi == -1) {
printf("Failed to open %s for read: %m\n", fname);
return NULL;
}
while (1) {
memset(buf, 0, 188*rnum);
len=read(fdi, buf, 188*rnum);
@@ -122,7 +127,12 @@ int send(void)
if (!buf)
return -1;
sprintf(fname, "/dev/dvb/adapter%u/ci%u", adapter, device);
printf("using %s for writing\n", fname);
fdo=open(fname, O_WRONLY);
if (fdo == -1) {
printf("Failed to open %s to write: %m\n", fname);
exit(2);
}
while (1) {
for (i=0; i<snum; i++) {
@@ -146,7 +156,7 @@ int send(void)
int main(int argc, char **argv)
{
pthread_t th;
while (1) {
int option_index = 0;
int c;
@@ -178,6 +188,8 @@ int main(int argc, char **argv)
rnum = strtoul(optarg, NULL, 10);
break;
case 'h':
printf("cit -a<adapter> -d<device>\n");
exit(-1);
default:
break;
@@ -186,6 +198,7 @@ int main(int argc, char **argv)
if (optind < argc) {
printf("Warning: unused arguments\n");
}
printf("adapter %d, device: %d\n", adapter, device);
memset(ts+8, 180, 0x5a);
pthread_create(&th, NULL, get_ts, NULL);
usleep(10000);

1
apps/flash.c Symbolic link
View File

@@ -0,0 +1 @@
./octonet/flash.c

View File

@@ -33,379 +33,7 @@
#include <sys/ioctl.h>
#include <linux/types.h>
#define DDB_MAGIC 'd'
static uint32_t linknr = 0;
struct ddb_id {
__u16 vendor;
__u16 device;
__u16 subvendor;
__u16 subdevice;
__u32 hw;
__u32 regmap;
};
struct ddb_flashio {
__u8 *write_buf;
__u32 write_len;
__u8 *read_buf;
__u32 read_len;
__u32 link;
};
#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio)
#define IOCTL_DDB_ID _IOR(DDB_MAGIC, 0x03, struct ddb_id)
int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen)
{
struct ddb_flashio fio = {
.write_buf=wbuf,
.write_len=wlen,
.read_buf=rbuf,
.read_len=rlen,
.link=linknr,
};
return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio);
}
enum {
UNKNOWN_FLASH = 0,
ATMEL_AT45DB642D = 1,
SSTI_SST25VF016B = 2,
SSTI_SST25VF032B = 3,
SSTI_SST25VF064C = 4,
SPANSION_S25FL116K = 5,
};
int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
{
uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,
(addr >> 8) & 0xff, addr & 0xff};
return flashio(ddb, cmd, 4, buf, len);
}
int flashdump(int ddb, uint32_t addr, uint32_t len)
{
int i, j;
uint8_t buf[32];
int bl = sizeof(buf);
for (j=0; j<len; j+=bl, addr+=bl) {
flashread(ddb, buf, addr, bl);
for (i=0; i<bl; i++) {
printf("%02x ", buf[i]);
}
printf("\n");
}
}
int FlashDetect(int dev)
{
uint8_t Cmd = 0x9F;
uint8_t Id[3];
int r = flashio(dev, &Cmd,1,Id,3);
if (r < 0)
return r;
if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x41 )
r = SSTI_SST25VF016B;
else if( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4A )
r = SSTI_SST25VF032B;
else if( Id[0] == 0x1F && Id[1] == 0x28 )
r = ATMEL_AT45DB642D;
else if( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4B )
r = SSTI_SST25VF064C;
else if( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x15 )
r = SPANSION_S25FL116K;
else
r = UNKNOWN_FLASH;
switch(r) {
case UNKNOWN_FLASH:
printf("Unknown Flash Flash ID = %02x %02x %02x\n",Id[0],Id[1],Id[2]);
break;
case ATMEL_AT45DB642D:
printf("Flash: Atmel AT45DB642D 64 MBit\n");
break;
case SSTI_SST25VF016B:
printf("Flash: SSTI SST25VF016B 16 MBit\n");
break;
case SSTI_SST25VF032B:
printf("Flash: SSTI SST25VF032B 32 MBit\n"); break;
case SSTI_SST25VF064C:
printf("Flash: SSTI SST25VF064C 64 MBit\n"); break;
case SPANSION_S25FL116K:
printf("Flash: SPANSION S25FL116K 16 MBit\n"); break;
}
return r;
}
int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize)
{
int err = 0;
int BlockErase = BufferSize >= 8192;
int i;
if (BlockErase) {
for(i = 0; i < BufferSize; i += 8192 ) {
uint8_t Cmd[4];
if( (i & 0xFFFF) == 0 )
printf(" Erase %08x\n",FlashOffset + i);
Cmd[0] = 0x50; // Block Erase
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while( 1 )
{
Cmd[0] = 0xD7; // Read Status register
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x80) == 0x80 ) break;
}
}
}
for(i = 0; i < BufferSize; i += 1024 )
{
uint8_t Cmd[4 + 1024];
if( (i & 0xFFFF) == 0 )
{
printf(" Program %08x\n",FlashOffset + i);
}
Cmd[0] = 0x84; // Buffer 1
Cmd[1] = 0x00;
Cmd[2] = 0x00;
Cmd[3] = 0x00;
memcpy(&Cmd[4],&Buffer[i],1024);
err = flashio(dev,Cmd,4 + 1024,NULL,0);
if( err < 0 ) break;
Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while( 1 )
{
Cmd[0] = 0xD7; // Read Status register
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x80) == 0x80 ) break;
}
if( err < 0 ) break;
}
return err;
}
int FlashWritePageMode(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize, uint8_t LockBits)
{
int err = 0, i, j;
uint8_t Cmd[260];
if( (BufferSize % 4096) != 0 )
return -1; // Must be multiple of sector size
do {
Cmd[0] = 0x50; // EWSR
err = flashio(dev, Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = flashio(dev, Cmd,2,NULL,0);
if( err < 0 ) break;
for(i = 0; i < BufferSize; i += 4096 ) {
if( (i & 0xFFFF) == 0 ) {
printf(" Erase %08x\n",FlashOffset + i);
}
Cmd[0] = 0x06; // WREN
err = flashio(dev, Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x20; // Sector erase ( 4Kb)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev, Cmd,4,NULL,0);
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0x05; // RDRS
err = flashio(dev, Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
for (j = BufferSize - 256; j >= 0; j -= 256 )
{
if( (j & 0xFFFF) == 0 )
{
printf(" Programm %08x\n",FlashOffset + j);
}
Cmd[0] = 0x06; // WREN
err = flashio(dev, Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x02; // PP
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
Cmd[3] = 0x00;
memcpy(&Cmd[4],&Buffer[j],256);
err = flashio(dev, Cmd,260,NULL,0);
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0x05; // RDRS
err = flashio(dev, Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x50; // EWSR
err = flashio(dev, Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = LockBits; // BPx = 0, Lock all blocks
err = flashio(dev, Cmd,2,NULL,0);
} while(0);
return err;
}
int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize)
{
int err = 0;
uint8_t Cmd[6];
int i, j;
// Must be multiple of sector size
if( (BufferSize % 4096) != 0 )
return -1;
do {
Cmd[0] = 0x50; // EWSR
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 )
break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = flashio(dev,Cmd,2,NULL,0);
if( err < 0 )
break;
for(i = 0; i < BufferSize; i += 4096 ) {
if( (i & 0xFFFF) == 0 )
printf(" Erase %08x\n",FlashOffset + i);
Cmd[0] = 0x06; // WREN
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 )
break;
Cmd[0] = 0x20; // Sector erase ( 4Kb)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 )
break;
while(1) {
Cmd[0] = 0x05; // RDRS
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 )
break;
for(j = BufferSize - 4096; j >= 0; j -= 4096 ) {
if( (j & 0xFFFF) == 0 )
printf(" Program %08x\n",FlashOffset + j);
for(i = 0; i < 4096; i += 2 ) {
if( i == 0 ) {
Cmd[0] = 0x06; // WREN
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 )
break;
Cmd[0] = 0xAD; // AAI
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
Cmd[3] = 0x00;
Cmd[4] = Buffer[j+i];
Cmd[5] = Buffer[j+i+1];
err = flashio(dev,Cmd,6,NULL,0);
} else {
Cmd[0] = 0xAD; // AAI
Cmd[1] = Buffer[j+i];
Cmd[2] = Buffer[j+i+1];
err = flashio(dev,Cmd,3,NULL,0);
}
if( err < 0 )
break;
while(1) {
Cmd[0] = 0x05; // RDRS
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x04; // WDIS
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x50; // EWSR
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x1C; // BPx = 0, Lock all blocks
err = flashio(dev,Cmd,2,NULL,0);
} while(0);
return err;
}
#include "flash.h"
void get_id(int ddb, struct ddb_id *ddbid) {
uint8_t id[4];
@@ -450,8 +78,8 @@ int main(int argc, char **argv)
uint32_t FlashOffset = 0x10000;
int ddb;
int i, err;
int SectorSize=0;
int FlashSize=0;
uint32_t SectorSize=0;
uint32_t FlashSize=0;
int Flash;
uint32_t svid=0, jump=0, dump=0;
@@ -459,6 +87,7 @@ int main(int argc, char **argv)
int ddbnum = 0;
int force = 0;
char *fname = NULL;
while (1) {
int option_index = 0;
@@ -470,12 +99,15 @@ int main(int argc, char **argv)
{0, 0, 0, 0}
};
c = getopt_long(argc, argv,
"d:n:s:o:l:dfhj",
"d:n:s:o:l:dfhjb:",
long_options, &option_index);
if (c==-1)
break;
switch (c) {
case 'b':
fname = optarg;
break;
case 'd':
dump = strtoul(optarg, NULL, 16);
break;
@@ -513,32 +145,7 @@ int main(int argc, char **argv)
printf("Could not open device\n");
return -1;
}
Flash=FlashDetect(ddb);
switch(Flash) {
case ATMEL_AT45DB642D:
SectorSize = 1024;
FlashSize = 0x800000;
break;
case SSTI_SST25VF016B:
SectorSize = 4096;
FlashSize = 0x200000;
break;
case SSTI_SST25VF032B:
SectorSize = 4096;
FlashSize = 0x400000;
break;
case SSTI_SST25VF064C:
SectorSize = 4096;
FlashSize = 0x800000;
break;
case SPANSION_S25FL116K:
SectorSize = 4096;
FlashSize = 0x200000;
break;
default:
return 0;
}
Flash = flashdetect(ddb, &SectorSize, &FlashSize);
get_id(ddb, &ddbid);
#if 1
@@ -553,27 +160,6 @@ int main(int argc, char **argv)
return 0;
}
if (ddbid.device == 0x0011)
type = 1;
if (ddbid.device == 0x0201)
type = 2;
if (ddbid.device == 0x02)
type = 3;
if (ddbid.device == 0x03)
type = 0;
if (ddbid.device == 0x07)
type = 4;
if (ddbid.device == 0x320)
type = 5;
if (ddbid.device == 0x13)
type = 6;
if (ddbid.device == 0x12)
type = 7;
if (ddbid.device == 0x08)
type = 8;
if (ddbid.device == 0x210)
type = 9;
if (!SectorSize)
return 0;
@@ -616,52 +202,68 @@ int main(int argc, char **argv)
} else {
int fh, i;
int fsize;
char *fname;
switch (type) {
case 0:
fname="DVBBridgeV1B_DVBBridgeV1B.bit";
printf("Octopus\n");
break;
case 1:
fname="CIBridgeV1B_CIBridgeV1B.bit";
printf("Octopus CI\n");
break;
case 2:
fname="DVBModulatorV1B_DVBModulatorV1B.bit";
printf("Modulator\n");
break;
case 3:
if (!fname)
switch (ddbid.device) {
case 0x0002:
fname="DVBBridgeV1A_DVBBridgeV1A.bit";
printf("Octopus 35\n");
break;
case 4:
case 0x0003:
fname="DVBBridgeV1B_DVBBridgeV1B.fpga";
printf("Octopus\n");
break;
case 0x0005:
fname="DVBBridgeV2A_DD01_0005_STD.fpga";
printf("Octopus Classic\n");
break;
case 0x0006:
fname="DVBBridgeV2A_DD01_0006_STD.fpga";
printf("CineS2 V7\n");
break;
case 0x0007:
fname="DVBBridgeV2A_DD01_0007_MXL.fpga";
printf("Octopus 4/8\n");
break;
case 8:
case 0x0008:
fname="DVBBridgeV2A_DD01_0008_CXD.fpga";
printf("Octopus 4/8\n");
break;
case 6:
fname="DVBBridgeV2B_DD01_0013_PRO.fpga";
printf("Octopus PRO\n");
case 0x0011:
fname="CIBridgeV1B_CIBridgeV1B.fpga";
printf("Octopus CI\n");
break;
case 7:
case 0x0012:
fname="DVBBridgeV2B_DD01_0012_STD.fpga";
printf("Octopus CI\n");
break;
case 9:
case 0x0013:
fname="DVBBridgeV2B_DD01_0013_PRO.fpga";
printf("Octopus PRO\n");
break;
case 0x0201:
fname="DVBModulatorV1B_DVBModulatorV1B.bit";
printf("Modulator\n");
break;
case 0x0203:
fname="DVBModulatorV1B_DD01_0203.fpga";
printf("Modulator Test\n");
break;
case 0x0210:
fname="DVBModulatorV2A_DD01_0210.fpga";
printf("Modulator V2\n");
break;
case 0x0220:
fname="SDRModulatorV1A_DD01_0220.fpga";
printf("SDRModulator\n");
break;
default:
printf("UNKNOWN\n");
break;
}
fh = open(fname, O_RDONLY);
if (fh < 0 ) {
printf("File not found \n");
printf("File %s not found \n", fname);
return 0;
}
printf("Using bitstream %s\n", fname);
@@ -720,6 +322,7 @@ int main(int argc, char **argv)
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x3C);
break;
case SPANSION_S25FL116K:
case SPANSION_S25FL164K:
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C);
break;
}

View File

@@ -58,7 +58,6 @@ static int reboot(uint32_t off)
struct ddflash {
int fd;
struct ddb_id id;
uint32_t type;
uint32_t version;
uint32_t flash_type;
@@ -68,74 +67,9 @@ struct ddflash {
uint32_t bufsize;
uint32_t block_erase;
uint8_t * buffer;
uint8_t *buffer;
};
int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen)
{
struct ddb_flashio fio = {
.write_buf=wbuf,
.write_len=wlen,
.read_buf=rbuf,
.read_len=rlen,
.link=0,
};
return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio);
}
enum {
UNKNOWN_FLASH = 0,
ATMEL_AT45DB642D = 1,
SSTI_SST25VF016B = 2,
SSTI_SST25VF032B = 3,
SSTI_SST25VF064C = 4,
SPANSION_S25FL116K = 5,
SPANSION_S25FL132K = 6,
SPANSION_S25FL164K = 7,
};
static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
{
uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,
(addr >> 8) & 0xff, addr & 0xff};
return flashio(ddb, cmd, 4, buf, len);
}
static int flashdump(struct ddflash *ddf, uint32_t addr, uint32_t len)
{
int i, j;
uint8_t buf[32];
int bl = sizeof(buf);
for (j = 0; j < len; j += bl, addr += bl) {
flashread(ddf->fd, buf, addr, bl);
for (i = 0; i < bl; i++) {
printf("%02x ", buf[i]);
}
printf("\n");
}
}
void dump(const uint8_t *b, int l)
{
int i, j;
for (j = 0; j < l; j += 16, b += 16) {
for (i = 0; i < 16; i++)
if (i + j < l)
printf("%02x ", b[i]);
else
printf(" ");
printf(" | ");
for (i = 0; i < 16; i++)
if (i + j < l)
putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.');
printf("\n");
}
}
int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset,
uint8_t LockBits, uint32_t fw_off)
{
@@ -492,7 +426,7 @@ static int flash_detect(struct ddflash *ddf)
}
if (ddf->sector_size) {
ddf->buffer = malloc(ddf->sector_size);
printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);
//printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);
if (!ddf->buffer)
return -1;
}
@@ -500,172 +434,6 @@ static int flash_detect(struct ddflash *ddf)
}
int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize)
{
int err = 0;
int BlockErase = BufferSize >= 8192;
int i;
if (BlockErase) {
for (i = 0; i < BufferSize; i += 8192 ) {
uint8_t cmd[4];
if ((i & 0xFFFF) == 0 )
printf(" Erase %08x\n",FlashOffset + i);
cmd[0] = 0x50; // Block Erase
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
cmd[3] = 0x00;
err = flashio(dev,cmd,4,NULL,0);
if (err < 0 ) break;
while( 1 )
{
cmd[0] = 0xD7; // Read Status register
err = flashio(dev,cmd,1,&cmd[0],1);
if (err < 0 ) break;
if ((cmd[0] & 0x80) == 0x80 ) break;
}
}
}
for (i = 0; i < BufferSize; i += 1024) {
uint8_t cmd[4 + 1024];
if ((i & 0xFFFF) == 0 )
{
printf(" Program %08x\n",FlashOffset + i);
}
cmd[0] = 0x84; // Buffer 1
cmd[1] = 0x00;
cmd[2] = 0x00;
cmd[3] = 0x00;
memcpy(&cmd[4],&Buffer[i],1024);
err = flashio(dev,cmd,4 + 1024,NULL,0);
if (err < 0 ) break;
cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase)
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
cmd[3] = 0x00;
err = flashio(dev,cmd,4,NULL,0);
if (err < 0 ) break;
while( 1 )
{
cmd[0] = 0xD7; // Read Status register
err = flashio(dev,cmd,1,&cmd[0],1);
if (err < 0 ) break;
if ((cmd[0] & 0x80) == 0x80 ) break;
}
if (err < 0 ) break;
}
return err;
}
int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize)
{
int err = 0;
uint8_t cmd[6];
int i, j;
// Must be multiple of sector size
if ((BufferSize % 4096) != 0 )
return -1;
do {
cmd[0] = 0x50; // EWSR
err = flashio(dev,cmd,1,NULL,0);
if (err < 0 )
break;
cmd[0] = 0x01; // WRSR
cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = flashio(dev,cmd,2,NULL,0);
if (err < 0 )
break;
for (i = 0; i < BufferSize; i += 4096 ) {
if ((i & 0xFFFF) == 0 )
printf(" Erase %08x\n",FlashOffset + i);
cmd[0] = 0x06; // WREN
err = flashio(dev,cmd,1,NULL,0);
if (err < 0 )
break;
cmd[0] = 0x20; // Sector erase ( 4Kb)
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
cmd[3] = 0x00;
err = flashio(dev,cmd,4,NULL,0);
if (err < 0 )
break;
while(1) {
cmd[0] = 0x05; // RDRS
err = flashio(dev,cmd,1,&cmd[0],1);
if (err < 0 ) break;
if ((cmd[0] & 0x01) == 0 ) break;
}
if (err < 0 ) break;
}
if (err < 0 )
break;
for (j = BufferSize - 4096; j >= 0; j -= 4096 ) {
if ((j & 0xFFFF) == 0 )
printf(" Program %08x\n",FlashOffset + j);
for (i = 0; i < 4096; i += 2 ) {
if (i == 0 ) {
cmd[0] = 0x06; // WREN
err = flashio(dev,cmd,1,NULL,0);
if (err < 0 )
break;
cmd[0] = 0xAD; // AAI
cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
cmd[3] = 0x00;
cmd[4] = Buffer[j+i];
cmd[5] = Buffer[j+i+1];
err = flashio(dev,cmd,6,NULL,0);
} else {
cmd[0] = 0xAD; // AAI
cmd[1] = Buffer[j+i];
cmd[2] = Buffer[j+i+1];
err = flashio(dev,cmd,3,NULL,0);
}
if (err < 0 )
break;
while(1) {
cmd[0] = 0x05; // RDRS
err = flashio(dev,cmd,1,&cmd[0],1);
if (err < 0 ) break;
if ((cmd[0] & 0x01) == 0 ) break;
}
if (err < 0 ) break;
}
if (err < 0 ) break;
cmd[0] = 0x04; // WDIS
err = flashio(dev,cmd,1,NULL,0);
if (err < 0 ) break;
}
if (err < 0 ) break;
cmd[0] = 0x50; // EWSR
err = flashio(dev,cmd,1,NULL,0);
if (err < 0 ) break;
cmd[0] = 0x01; // WRSR
cmd[1] = 0x1C; // BPx = 0, Lock all blocks
err = flashio(dev,cmd,2,NULL,0);
} while(0);
return err;
}
static int get_id(struct ddflash *ddf) {
uint8_t id[4];
@@ -677,19 +445,6 @@ static int get_id(struct ddflash *ddf) {
ddf->id.subvendor, ddf->id.subdevice,
ddf->id.hw, ddf->id.regmap);
#endif
if (ddf->id.device == 0x0011)
ddf->type = 1;
if (ddf->id.device == 0x0201)
ddf->type = 2;
if (ddf->id.device == 0x02)
ddf->type = 3;
if (ddf->id.device == 0x03)
ddf->type = 0;
if (ddf->id.device == 0x0300)
ddf->type = 4;
if (ddf->id.device == 0x0320)
ddf->type = 5;
return 0;
}
@@ -755,7 +510,12 @@ static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off)
goto out;
}
} else if (!strcasecmp(key, "Version")) {
sscanf(val, "%x", &version);
if (strchr(val,'.')) {
int major = 0, minor = 0;
sscanf(val,"%d.%d",&major,&minor);
version = (major << 16) + minor;
} else
sscanf(val, "%x", &version);
} else if (!strcasecmp(key, "Length")) {
sscanf(val, "%u", &length);
}
@@ -810,8 +570,13 @@ static int update_image(struct ddflash *ddf, char *fn,
if (res < 0)
goto out;
res = flashwrite(ddf, fs, adr, len, fw_off);
if (res == 0)
res = 1;
if (res == 0) {
res = flashcmp(ddf, fs, adr, len, fw_off);
if (res == -2) {
res = 1;
}
}
out:
close(fs);
return res;
@@ -852,18 +617,40 @@ static int update_flash(struct ddflash *ddf)
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1)
stat |= 1;
} else {
if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
stat |= 1;
if (res == -1)
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
stat |= 1;
if (res == -1)
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
stat |= 1;
if (res == -1)
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
if (ddf->id.device == 0x0307) {
if (res == -1)
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
stat |= 1;
if (res == -1)
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
stat |= 1;
} else {
if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
stat |= 1;
if (res == -1)
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
stat |= 1;
}
}
#if 1
if ( (stat&1) && (ddf->id.hw & 0xffffff) <= 0x010001) {
if (ddf->id.device == 0x0307) {
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1)
stat |= 1;
if (res == -1)
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x160000, 0x80000, 1, 0)) == 1)
stat |= 1;
} else {
if ((res = update_image(ddf, "/config/fpga.img", 0x160000, 0x80000, 1, 0)) == 1)
stat |= 1;
if (res == -1)
if ((res = update_image(ddf, "/boot/fpga.img", 0x160000, 0x80000, 1, 0)) == 1)
stat |= 1;
}
}
#endif
break;
case 0x320:
//fname="/boot/DVBNetV1A_DD01_0300.bit";

View File

@@ -1,3 +1,4 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
@@ -12,8 +13,6 @@
#include "flash.h"
static uint32_t linknr = 0;
typedef int (*COMMAND_FUNCTION)(int dev, int argc, char* argv[], uint32_t Flags);
enum {
@@ -21,17 +20,6 @@ enum {
SILENT_FLAG = 0x00000002,
};
enum {
UNKNOWN_FLASH = 0,
ATMEL_AT45DB642D = 1,
SSTI_SST25VF016B = 2,
SSTI_SST25VF032B = 3,
SSTI_SST25VF064C = 4,
SPANSION_S25FL116K = 5,
SPANSION_S25FL132K = 6,
SPANSION_S25FL164K = 7,
};
struct SCommand
{
char* Name;
@@ -42,94 +30,25 @@ struct SCommand
// --------------------------------------------------------------------------------------------
void Dump(const uint8_t *b, uint32_t start, int l)
{
int i, j;
for (j = 0; j < l; j += 16, b += 16) {
printf("%08x: ", start + j);
for (i = 0; i < 16; i++)
if (i + j < l)
printf("%02x ", b[i]);
else
printf(" ");
printf(" |");
for (i = 0; i < 16; i++)
if (i + j < l)
putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.');
printf("|\n");
}
}
int readreg(int dev, uint32_t RegAddress, uint32_t *pRegValue)
{
struct ddb_reg reg = { .reg = RegAddress };
int ret;
ret = ioctl(dev, IOCTL_DDB_READ_REG, &reg);
if (ret < 0)
return ret;
if (pRegValue)
*pRegValue = reg.val;
return 0;
}
int writereg(int dev, uint32_t RegAddress, uint32_t RegValue)
{
struct ddb_reg reg = { .reg = RegAddress, .val = RegValue};
return ioctl(dev, IOCTL_DDB_WRITE_REG, &reg);
}
int FlashIO(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen)
{
struct ddb_flashio fio = {
.write_buf=wbuf,
.write_len=wlen,
.read_buf=rbuf,
.read_len=rlen,
.link=linknr,
};
return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio);
}
int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
{
int ret;
uint8_t cmd[4];
uint32_t l;
while (len) {
cmd[0] = 3;
cmd[1] = (addr >> 16) & 0xff;
cmd[2] = (addr >> 8) & 0xff;
cmd[3] = addr & 0xff;
if (len > 1024)
l = 1024;
else
l = len;
ret = FlashIO(ddb, cmd, 4, buf, l);
if (ret < 0)
return ret;
addr += l;
buf += l;
len -= l;
}
return 0;
}
int ReadFlash(int ddb, int argc, char *argv[], uint32_t Flags)
{
uint32_t Start;
uint32_t Len;
uint8_t *Buffer;
int fd;
if (argc < 2 )
return -1;
Start = strtoul(argv[0],NULL,16);
Len = strtoul(argv[1],NULL,16);
if (argc == 3) {
fd = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC);
if (fd < 0) {
printf("Could not open file %s\n", argv[2]);
return -1;
}
}
Buffer = malloc(Len);
if (flashread(ddb, Buffer, Start, Len) < 0) {
@@ -138,68 +57,43 @@ int ReadFlash(int ddb, int argc, char *argv[], uint32_t Flags)
return 0;
}
Dump(Buffer,Start,Len);
if (argc == 3) {
write(fd, Buffer, Len);
close(fd);
} else
Dump(Buffer,Start,Len);
free(Buffer);
return 0;
}
int FlashDetect(int dev)
int ReadSave(int ddb, int argc, char *argv[], uint32_t Flags)
{
uint8_t Cmd = 0x9F;
uint8_t Id[3];
int r = FlashIO(dev, &Cmd, 1, Id, 3);
if (r < 0)
return r;
if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x41)
r = SSTI_SST25VF016B;
else if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4A)
r = SSTI_SST25VF032B;
else if ( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4B )
r = SSTI_SST25VF064C;
else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x15 )
r = SPANSION_S25FL116K;
else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x16 )
r = SPANSION_S25FL132K;
else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x17 )
r = SPANSION_S25FL164K;
else if ( Id[0] == 0x1F && Id[1] == 0x28)
r = ATMEL_AT45DB642D;
else
r = UNKNOWN_FLASH;
switch(r) {
case UNKNOWN_FLASH :
printf("Unknown Flash Flash ID = %02x %02x %02x\n",Id[0],Id[1],Id[2]);
break;
case ATMEL_AT45DB642D :
printf("Flash: Atmel AT45DB642D 64 MBit\n");
break;
case SSTI_SST25VF016B :
printf("Flash: SSTI SST25VF016B 16 MBit\n");
break;
case SSTI_SST25VF032B :
printf("Flash: SSTI SST25VF032B 32 MBit\n");
break;
case SSTI_SST25VF064C :
printf("Flash: SSTI SST25VF064C 64 MBit\n");
break;
case SPANSION_S25FL116K :
printf("Flash: SPANSION S25FL116K 16 MBit\n");
break;
case SPANSION_S25FL132K :
printf("Flash: SPANSION S25FL132K 32 MBit\n");
break;
case SPANSION_S25FL164K :
printf("Flash: SPANSION S25FL164K 64 MBit\n");
break;
uint32_t Start;
uint32_t Len;
uint8_t *Buffer;
int fd;
if (argc < 3 )
return -1;
Start = strtoul(argv[0],NULL,16);
Len = strtoul(argv[1],NULL,16);
Buffer = malloc(Len);
if (flashread(ddb, Buffer, Start, Len) < 0) {
printf("flashread error\n");
free(Buffer);
return 0;
}
return r;
free(Buffer);
return 0;
}
int FlashChipEraseAtmel(int dev)
{
int err = 0;
@@ -214,12 +108,12 @@ int FlashChipEraseAtmel(int dev)
Cmd[1] = ( (( i ) >> 16) & 0xFF );
Cmd[2] = ( (( i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = FlashIO(dev,Cmd,4,NULL,0);
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 )
break;
while (1) {
Cmd[0] = 0xD7; // Read Status register
err = FlashIO(dev,Cmd,1,&Cmd[0],1);
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x80) == 0x80 ) break;
}
@@ -237,25 +131,25 @@ int FlashChipEraseSSTI(int dev)
do {
Cmd[0] = 0x50; // EWSR
err = FlashIO(dev,Cmd,1,NULL,0);
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = FlashIO(dev,Cmd,2,NULL,0);
err = flashio(dev,Cmd,2,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x06; // WREN
err = FlashIO(dev,Cmd,1,NULL,0);
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x60; // CHIP Erase
err = FlashIO(dev,Cmd,1,NULL,0);
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
while(1) {
Cmd[0] = 0x05; // RDRS
err = FlashIO(dev,Cmd,1,&Cmd[0],1);
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
@@ -263,12 +157,12 @@ int FlashChipEraseSSTI(int dev)
break;
Cmd[0] = 0x50; // EWSR
err = FlashIO(dev,Cmd,1,NULL,0);
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x1C; // BPx = 0, Lock all blocks
err = FlashIO(dev,Cmd,2,NULL,0);
err = flashio(dev,Cmd,2,NULL,0);
}
while(0);
@@ -278,286 +172,6 @@ int FlashChipEraseSSTI(int dev)
}
int FlashWriteAtmel(int dev,uint32_t FlashOffset,uint8_t * Buffer,int BufferSize)
{
int err = 0, i;
int BlockErase = BufferSize >= 8192;
uint8_t Cmd[4];
if( BlockErase ) {
for(i = 0; i < BufferSize; i += 8192 ) {
if( (i & 0xFFFF) == 0 )
{
printf(" Erase %08x\n",FlashOffset + i);
}
Cmd[0] = 0x50; // Block Erase
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = FlashIO(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while(1) {
Cmd[0] = 0xD7; // Read Status register
err = FlashIO(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x80) == 0x80 ) break;
}
}
}
for(i = 0; i < BufferSize; i += 1024 )
{
if( (i & 0xFFFF) == 0 )
{
printf(" Programm %08x\n",FlashOffset + i);
}
uint8_t Cmd[4 + 1024];
Cmd[0] = 0x84; // Buffer 1
Cmd[1] = 0x00;
Cmd[2] = 0x00;
Cmd[3] = 0x00;
memcpy(&Cmd[4],&Buffer[i],1024);
err = FlashIO(dev,Cmd,4 + 1024,NULL,0);
if( err < 0 ) break;
Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = FlashIO(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0xD7; // Read Status register
err = FlashIO(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x80) == 0x80 ) break;
}
if( err < 0 ) break;
}
return err;
}
// **************************************************************************************
// BUG: Erasing and writing an incomplete image will result in an failure to boot golden image.
// FIX: Write the new image from high to low addresses
int FlashWriteSSTI(int dev,uint32_t FlashOffset,uint8_t * Buffer,int BufferSize)
{
int err = 0, i, j;
uint8_t Cmd[6];
if( (BufferSize % 4096) != 0 ) return -1; // Must be multiple of sector size
do
{
Cmd[0] = 0x50; // EWSR
err = FlashIO(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = FlashIO(dev,Cmd,2,NULL,0);
if( err < 0 ) break;
for (i = 0; i < BufferSize; i += 4096 )
{
if( (i & 0xFFFF) == 0 )
{
printf(" Erase %08x\n",FlashOffset + i);
}
Cmd[0] = 0x06; // WREN
err = FlashIO(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x20; // Sector erase ( 4Kb)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = FlashIO(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0x05; // RDRS
err = FlashIO(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
for (j = BufferSize - 4096; j >= 0; j -= 4096 )
{
if( (j & 0xFFFF) == 0 )
{
printf(" Programm %08x\n",FlashOffset + j);
}
for (i = 0; i < 4096; i += 2 )
{
if( i == 0 )
{
Cmd[0] = 0x06; // WREN
err = FlashIO(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0xAD; // AAI
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
Cmd[3] = 0x00;
Cmd[4] = Buffer[j+i];
Cmd[5] = Buffer[j+i+1];
err = FlashIO(dev,Cmd,6,NULL,0);
}
else
{
Cmd[0] = 0xAD; // AAI
Cmd[1] = Buffer[j+i];
Cmd[2] = Buffer[j+i+1];
err = FlashIO(dev,Cmd,3,NULL,0);
}
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0x05; // RDRS
err = FlashIO(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x04; // WDIS
err = FlashIO(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x50; // EWSR
err = FlashIO(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x1C; // BPx = 0, Lock all blocks
err = FlashIO(dev,Cmd,2,NULL,0);
}
while(0);
return err;
}
int FlashWritePageMode(int dev, uint32_t FlashOffset,
uint8_t *Buffer,int BufferSize,uint8_t LockBits)
{
int err = 0;
uint8_t Cmd[260];
int i, j;
if( (BufferSize % 4096) != 0 ) return -1; // Must be multiple of sector size
do
{
Cmd[0] = 0x50; // EWSR
err = FlashIO(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = FlashIO(dev,Cmd,2,NULL,0);
if( err < 0 ) break;
for(i = 0; i < BufferSize; i += 4096 )
{
if( (i & 0xFFFF) == 0 )
{
printf(" Erase %08x\n",FlashOffset + i);
}
Cmd[0] = 0x06; // WREN
err = FlashIO(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x20; // Sector erase ( 4Kb)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = FlashIO(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0x05; // RDRS
err = FlashIO(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
for(j = BufferSize - 256; j >= 0; j -= 256 )
{
if( (j & 0xFFFF) == 0 )
{
printf(" Programm %08x\n",FlashOffset + j);
}
Cmd[0] = 0x06; // WREN
err = FlashIO(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x02; // PP
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
Cmd[3] = 0x00;
memcpy(&Cmd[4],&Buffer[j],256);
err = FlashIO(dev,Cmd,260,NULL,0);
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0x05; // RDRS
err = FlashIO(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x50; // EWSR
err = FlashIO(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = LockBits; // BPx = 0, Lock all blocks
err = FlashIO(dev,Cmd,2,NULL,0);
}
while(0);
return err;
}
// --------------------------------------------------------------------------------------------
int ReadDeviceMemory(int dev,int argc, char* argv[],uint32_t Flags)
{
@@ -693,7 +307,7 @@ int GetSetRegister(int dev,int argc, char* argv[],uint32_t Flags)
// -----------------------------------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------------------
int FlashIOC(int dev,int argc, char* argv[],uint32_t Flags)
int flashioc(int dev,int argc, char* argv[],uint32_t Flags)
{
uint8_t *Buffer;
uint32_t tmp = 0, i;
@@ -718,7 +332,7 @@ int FlashIOC(int dev,int argc, char* argv[],uint32_t Flags)
Buffer[i] = (uint8_t) tmp;
}
if( FlashIO(dev,Buffer,WriteLen,Buffer,ReadLen) < 0 )
if( flashio(dev,Buffer,WriteLen,Buffer,ReadLen) < 0 )
{
return 0;
}
@@ -1655,7 +1269,7 @@ static int read_sfpd(int dev, uint8_t adr, uint8_t *val)
uint8_t cmd[5] = { 0x5a, 0, 0, adr, 00 };
int r;
r = FlashIO(dev, cmd, 5, val, 1);
r = flashio(dev, cmd, 5, val, 1);
if (r < 0)
return r;
return 0;
@@ -1667,7 +1281,7 @@ static int read_sst_id(int dev, uint8_t *id)
uint8_t buf[9];
int r;
r = FlashIO(dev, cmd, 2, buf, 9);
r = flashio(dev, cmd, 2, buf, 9);
if (r < 0)
return r;
memcpy(id, buf + 1, 8);
@@ -1696,15 +1310,129 @@ int read_id(int dev, int argc, char* argv[], uint32_t Flags)
break;
default:
printf("Unsupported Flash\n");
break;
return -1;
}
printf("ID: ");
for (i = 0; i < 8; i++)
for (i = 0; i < len; i++)
printf("%02x ", Id[i]);
printf("\n");
}
int i2cread(int dev, int argc, char* argv[], uint32_t Flags)
{
uint8_t BusNumber = 0;
uint8_t DeviceAddress = 0;
int i;
uint32_t tmp;
char *p;
uint32_t BufferLength;
uint32_t ReadLen;
uint8_t *Buffer;
int Repeat = (Flags & REPEAT_FLAG) != 0;
int Silent = (Flags & SILENT_FLAG) != 0;
if (argc < 2)
return -1;
tmp = strtoul(argv[0],&p,16);
if (tmp > 255)
return -1;
if (*p == ':') {
BusNumber = (uint8_t) (tmp - 1);
tmp = strtoul(&p[1],NULL,16);
}
if (tmp > 255 || BusNumber > 3)
return -1;
DeviceAddress = (uint8_t) tmp;
BufferLength = (argc-2);
ReadLen = strtoul(argv[argc-1],NULL,0);
if (ReadLen > BufferLength)
BufferLength = ReadLen ;
printf(" BufferLength = %d tmp = %d\n", BufferLength, ReadLen);
Buffer = malloc(BufferLength);
for (i = 1; i < (argc-1); i += 1 ) {
tmp = strtoul(argv[i],NULL,16);
if (tmp > 255) {
free(Buffer);
return -1;
}
Buffer[i-1] = (uint8_t) tmp;
}
do {
int hr = i2c_read(dev, BusNumber, DeviceAddress, Buffer, argc-2, Buffer, ReadLen);
if (hr < 0) {
printf("ioctl error\n");
free(Buffer);
return 0;
}
if (!Silent) {
printf("OK\n");
Dump(&Buffer[0],0,ReadLen);
}
} while (Repeat);
free(Buffer);
return 0;
}
int i2cwrite(int dev, int argc, char* argv[], uint32_t Flags)
{
uint8_t BusNumber = 0;
uint8_t DeviceAddress = 0;
uint32_t tmp;
char *p;
uint8_t *Buffer;
int i;
int Repeat = (Flags & REPEAT_FLAG) != 0;
int Silent = (Flags & SILENT_FLAG) != 0;
if( argc < 1 )
return -1;
tmp = strtoul(argv[0],&p,16);
if( tmp > 255 )
return -1;
if (*p == ':') {
BusNumber = (uint8_t) (tmp - 1);
tmp = strtoul(&p[1],NULL,16);
}
if( tmp > 255 || BusNumber > 3)
return -1;
DeviceAddress = (uint8_t) tmp;
Buffer = malloc(argc - 1);
for (i = 1; i < argc; i += 1) {
tmp = strtoul(argv[i],NULL,16);
if (tmp > 255 ) {
free(Buffer);
return -1;
}
Buffer[i-1] = (uint8_t) tmp;
}
do {
int hr =i2c_write(dev, BusNumber,DeviceAddress,NULL,0,Buffer,argc-1);
if (hr < 0) {
printf("ioctl error\n");
free(Buffer);
return 0;
}
if( !Silent )
printf("OK\n");
} while( Repeat );
free(Buffer);
return 0;
}
struct SCommand CommandTable[] =
{
{ "memread", ReadDeviceMemory, 1, "Read Device Memory : memread <start> <count>" },
@@ -1712,13 +1440,13 @@ struct SCommand CommandTable[] =
{ "memwrite", WriteDeviceMemory, 1, "Write Device Memory : memwrite <start> <values(8)> .." },
{ "register", GetSetRegister, 1, "Get/Set Register : reg <regname>|<[0x]regnum> [[0x]value(32)]" },
{ "flashread", ReadFlash, 1, "Read Flash : flashread <start> <count>" },
{ "flashio", FlashIOC, 1, "Flash IO : flashio <write data>.. <read count>" },
{ "flashread", ReadFlash, 1, "Read Flash : flashread <start> <count> [<Filename>]" },
{ "flashio", flashioc, 1, "Flash IO : flashio <write data>.. <read count>" },
{ "flashprog", FlashProg, 1, "Flash Programming : flashprog <FileName> [<address>]" },
{ "flashprog", FlashProg, 1, "Flash Programming : flashprog -SubVendorID <id>" },
{ "flashprog", FlashProg, 1, "Flash Programming : flashprog -Jump <address>" },
{ "flashverify", FlashVerify, 1, "Flash Verify : flashverify <FileName> [<address>]" },
{ "flasherase", FlashErase, 1, "FlashErase : flasherase" },
//{ "flasherase", FlashErase, 1, "FlashErase : flasherase" },
//{ "flashtest", FlashTest, 1, "FlashTest : flashtest" },
@@ -1729,6 +1457,8 @@ struct SCommand CommandTable[] =
{ "licexport", lic_export, 1, "License Export : licexport" },
{ "licerase", lic_erase, 1, "License Erase : licerase" },
{ "read_id", read_id, 1, "Read Unique ID : read_id" },
{ "i2cread", i2cread, 1, "I2C Read : I2CRead <[BusNumber:]DeviceAddress> [<write data>..] <read count>" },
{ "i2write", i2cwrite, 1, "I2C Write : I2CWrite <[BusNumber:]DeviceAddress> [<write data>..]"},
{ NULL,NULL,0 }
};

614
apps/octonet/flash.c Normal file
View File

@@ -0,0 +1,614 @@
enum {
UNKNOWN_FLASH = 0,
ATMEL_AT45DB642D = 1,
SSTI_SST25VF016B = 2,
SSTI_SST25VF032B = 3,
SSTI_SST25VF064C = 4,
SPANSION_S25FL116K = 5,
SPANSION_S25FL132K = 6,
SPANSION_S25FL164K = 7,
};
static uint32_t linknr = 0;
int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen)
{
struct ddb_flashio fio = {
.write_buf=wbuf,
.write_len=wlen,
.read_buf=rbuf,
.read_len=rlen,
.link=linknr,
};
return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio);
}
int FlashDetect(int dev)
{
uint8_t Cmd = 0x9F;
uint8_t Id[3];
int r = flashio(dev, &Cmd, 1, Id, 3);
if (r < 0)
return r;
if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x41)
r = SSTI_SST25VF016B;
else if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4A)
r = SSTI_SST25VF032B;
else if ( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4B )
r = SSTI_SST25VF064C;
else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x15 )
r = SPANSION_S25FL116K;
else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x16 )
r = SPANSION_S25FL132K;
else if ( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x17 )
r = SPANSION_S25FL164K;
else if ( Id[0] == 0x1F && Id[1] == 0x28)
r = ATMEL_AT45DB642D;
else
r = UNKNOWN_FLASH;
switch(r) {
case UNKNOWN_FLASH :
printf("Unknown Flash Flash ID = %02x %02x %02x\n",Id[0],Id[1],Id[2]);
break;
case ATMEL_AT45DB642D :
printf("Flash: Atmel AT45DB642D 64 MBit\n");
break;
case SSTI_SST25VF016B :
printf("Flash: SSTI SST25VF016B 16 MBit\n");
break;
case SSTI_SST25VF032B :
printf("Flash: SSTI SST25VF032B 32 MBit\n");
break;
case SSTI_SST25VF064C :
printf("Flash: SSTI SST25VF064C 64 MBit\n");
break;
case SPANSION_S25FL116K :
printf("Flash: SPANSION S25FL116K 16 MBit\n");
break;
case SPANSION_S25FL132K :
printf("Flash: SPANSION S25FL132K 32 MBit\n");
break;
case SPANSION_S25FL164K :
printf("Flash: SPANSION S25FL164K 64 MBit\n");
break;
}
return r;
}
static int flashdetect(int fd, uint32_t *sector_size, uint32_t *flash_size)
{
uint8_t cmd = 0x9F;
uint8_t id[3];
int flash_type;
int r = flashio(fd, &cmd, 1, id, 3);
if (r < 0)
return r;
if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x41) {
flash_type = SSTI_SST25VF016B;
printf("Flash: SSTI SST25VF016B 16 MBit\n");
*sector_size = 4096;
*flash_size = 0x200000;
} else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4A) {
flash_type = SSTI_SST25VF032B;
printf("Flash: SSTI SST25VF032B 32 MBit\n");
*sector_size = 4096;
*flash_size = 0x400000;
} else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4B) {
flash_type = SSTI_SST25VF064C;
printf("Flash: SSTI SST25VF064C 64 MBit\n");
*sector_size = 4096;
*flash_size = 0x800000;
} else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x15) {
flash_type = SPANSION_S25FL116K;
printf("Flash: SPANSION S25FL116K 16 MBit\n");
*sector_size = 4096;
*flash_size = 0x200000;
} else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x16) {
flash_type = SPANSION_S25FL132K;
printf("Flash: SPANSION S25FL132K 32 MBit\n");
*sector_size = 4096;
*flash_size = 0x400000;
} else if (id[0] == 0x01 && id[1] == 0x40 && id[2] == 0x17) {
flash_type = SPANSION_S25FL164K;
printf("Flash: SPANSION S25FL164K 64 MBit\n");
*sector_size = 4096;
*flash_size = 0x800000;
} else if (id[0] == 0x1F && id[1] == 0x28) {
flash_type = ATMEL_AT45DB642D;
printf("Flash: Atmel AT45DB642D 64 MBit\n");
*sector_size = 1024;
*flash_size = 0x800000;
} else {
printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]);
return -1;
}
return flash_type;
}
#if 1
int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
{
int ret;
uint8_t cmd[4];
uint32_t l;
while (len) {
cmd[0] = 3;
cmd[1] = (addr >> 16) & 0xff;
cmd[2] = (addr >> 8) & 0xff;
cmd[3] = addr & 0xff;
if (len > 1024)
l = 1024;
else
l = len;
ret = flashio(ddb, cmd, 4, buf, l);
if (ret < 0)
return ret;
addr += l;
buf += l;
len -= l;
}
return 0;
}
#else
static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
{
uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,
(addr >> 8) & 0xff, addr & 0xff};
return flashio(ddb, cmd, 4, buf, len);
}
#endif
int flashdump(int ddb, uint32_t addr, uint32_t len)
{
int i, j;
uint8_t buf[32];
int bl = sizeof(buf);
for (j=0; j<len; j+=bl, addr+=bl) {
flashread(ddb, buf, addr, bl);
for (i=0; i<bl; i++) {
printf("%02x ", buf[i]);
}
printf("\n");
}
}
int readreg(int dev, uint32_t RegAddress, uint32_t *pRegValue)
{
struct ddb_reg reg = { .reg = RegAddress };
int ret;
ret = ioctl(dev, IOCTL_DDB_READ_REG, &reg);
if (ret < 0)
return ret;
if (pRegValue)
*pRegValue = reg.val;
return 0;
}
int writereg(int dev, uint32_t RegAddress, uint32_t RegValue)
{
struct ddb_reg reg = { .reg = RegAddress, .val = RegValue};
return ioctl(dev, IOCTL_DDB_WRITE_REG, &reg);
}
void dump(const uint8_t *b, int l)
{
int i, j;
for (j = 0; j < l; j += 16, b += 16) {
for (i = 0; i < 16; i++)
if (i + j < l)
printf("%02x ", b[i]);
else
printf(" ");
printf(" | ");
for (i = 0; i < 16; i++)
if (i + j < l)
putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.');
printf("\n");
}
}
void Dump(const uint8_t *b, uint32_t start, int l)
{
int i, j;
for (j = 0; j < l; j += 16, b += 16) {
printf("%08x: ", start + j);
for (i = 0; i < 16; i++)
if (i + j < l)
printf("%02x ", b[i]);
else
printf(" ");
printf(" |");
for (i = 0; i < 16; i++)
if (i + j < l)
putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.');
printf("|\n");
}
}
int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize)
{
int err = 0;
int BlockErase = BufferSize >= 8192;
int i;
if (BlockErase) {
for(i = 0; i < BufferSize; i += 8192 ) {
uint8_t Cmd[4];
if( (i & 0xFFFF) == 0 )
printf(" Erase %08x\n",FlashOffset + i);
Cmd[0] = 0x50; // Block Erase
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while( 1 )
{
Cmd[0] = 0xD7; // Read Status register
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x80) == 0x80 ) break;
}
}
}
for(i = 0; i < BufferSize; i += 1024 )
{
uint8_t Cmd[4 + 1024];
if( (i & 0xFFFF) == 0 )
{
printf(" Program %08x\n",FlashOffset + i);
}
Cmd[0] = 0x84; // Buffer 1
Cmd[1] = 0x00;
Cmd[2] = 0x00;
Cmd[3] = 0x00;
memcpy(&Cmd[4],&Buffer[i],1024);
err = flashio(dev,Cmd,4 + 1024,NULL,0);
if( err < 0 ) break;
Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while( 1 )
{
Cmd[0] = 0xD7; // Read Status register
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x80) == 0x80 ) break;
}
if( err < 0 ) break;
}
return err;
}
int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize)
{
int err = 0;
uint8_t cmd[6];
int i, j;
// Must be multiple of sector size
if ((BufferSize % 4096) != 0 )
return -1;
do {
cmd[0] = 0x50; // EWSR
err = flashio(dev,cmd,1,NULL,0);
if (err < 0 )
break;
cmd[0] = 0x01; // WRSR
cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = flashio(dev,cmd,2,NULL,0);
if (err < 0 )
break;
for (i = 0; i < BufferSize; i += 4096 ) {
if ((i & 0xFFFF) == 0 )
printf(" Erase %08x\n",FlashOffset + i);
cmd[0] = 0x06; // WREN
err = flashio(dev,cmd,1,NULL,0);
if (err < 0 )
break;
cmd[0] = 0x20; // Sector erase ( 4Kb)
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
cmd[3] = 0x00;
err = flashio(dev,cmd,4,NULL,0);
if (err < 0 )
break;
while(1) {
cmd[0] = 0x05; // RDRS
err = flashio(dev,cmd,1,&cmd[0],1);
if (err < 0 ) break;
if ((cmd[0] & 0x01) == 0 ) break;
}
if (err < 0 ) break;
}
if (err < 0 )
break;
for (j = BufferSize - 4096; j >= 0; j -= 4096 ) {
if ((j & 0xFFFF) == 0 )
printf(" Program %08x\n",FlashOffset + j);
for (i = 0; i < 4096; i += 2 ) {
if (i == 0 ) {
cmd[0] = 0x06; // WREN
err = flashio(dev,cmd,1,NULL,0);
if (err < 0 )
break;
cmd[0] = 0xAD; // AAI
cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
cmd[3] = 0x00;
cmd[4] = Buffer[j+i];
cmd[5] = Buffer[j+i+1];
err = flashio(dev,cmd,6,NULL,0);
} else {
cmd[0] = 0xAD; // AAI
cmd[1] = Buffer[j+i];
cmd[2] = Buffer[j+i+1];
err = flashio(dev,cmd,3,NULL,0);
}
if (err < 0 )
break;
while(1) {
cmd[0] = 0x05; // RDRS
err = flashio(dev,cmd,1,&cmd[0],1);
if (err < 0 ) break;
if ((cmd[0] & 0x01) == 0 ) break;
}
if (err < 0 ) break;
}
if (err < 0 ) break;
cmd[0] = 0x04; // WDIS
err = flashio(dev,cmd,1,NULL,0);
if (err < 0 ) break;
}
if (err < 0 ) break;
cmd[0] = 0x50; // EWSR
err = flashio(dev,cmd,1,NULL,0);
if (err < 0 ) break;
cmd[0] = 0x01; // WRSR
cmd[1] = 0x1C; // BPx = 0, Lock all blocks
err = flashio(dev,cmd,2,NULL,0);
} while(0);
return err;
}
int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize)
{
int err = 0;
uint8_t Cmd[6];
int i, j;
// Must be multiple of sector size
if( (BufferSize % 4096) != 0 )
return -1;
do {
Cmd[0] = 0x50; // EWSR
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 )
break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = flashio(dev,Cmd,2,NULL,0);
if( err < 0 )
break;
for(i = 0; i < BufferSize; i += 4096 ) {
if( (i & 0xFFFF) == 0 )
printf(" Erase %08x\n",FlashOffset + i);
Cmd[0] = 0x06; // WREN
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 )
break;
Cmd[0] = 0x20; // Sector erase ( 4Kb)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 )
break;
while(1) {
Cmd[0] = 0x05; // RDRS
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 )
break;
for(j = BufferSize - 4096; j >= 0; j -= 4096 ) {
if( (j & 0xFFFF) == 0 )
printf(" Program %08x\n",FlashOffset + j);
for(i = 0; i < 4096; i += 2 ) {
if( i == 0 ) {
Cmd[0] = 0x06; // WREN
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 )
break;
Cmd[0] = 0xAD; // AAI
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
Cmd[3] = 0x00;
Cmd[4] = Buffer[j+i];
Cmd[5] = Buffer[j+i+1];
err = flashio(dev,Cmd,6,NULL,0);
} else {
Cmd[0] = 0xAD; // AAI
Cmd[1] = Buffer[j+i];
Cmd[2] = Buffer[j+i+1];
err = flashio(dev,Cmd,3,NULL,0);
}
if( err < 0 )
break;
while(1) {
Cmd[0] = 0x05; // RDRS
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x04; // WDIS
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x50; // EWSR
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x1C; // BPx = 0, Lock all blocks
err = flashio(dev,Cmd,2,NULL,0);
} while(0);
return err;
}
int FlashWritePageMode(int dev, uint32_t FlashOffset,
uint8_t *Buffer,int BufferSize,uint8_t LockBits)
{
int err = 0;
uint8_t Cmd[260];
int i, j;
if( (BufferSize % 4096) != 0 ) return -1; // Must be multiple of sector size
do
{
Cmd[0] = 0x50; // EWSR
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
err = flashio(dev,Cmd,2,NULL,0);
if( err < 0 ) break;
for(i = 0; i < BufferSize; i += 4096 )
{
if( (i & 0xFFFF) == 0 )
{
printf(" Erase %08x\n",FlashOffset + i);
}
Cmd[0] = 0x06; // WREN
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x20; // Sector erase ( 4Kb)
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
Cmd[3] = 0x00;
err = flashio(dev,Cmd,4,NULL,0);
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0x05; // RDRS
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
for(j = BufferSize - 256; j >= 0; j -= 256 )
{
if( (j & 0xFFFF) == 0 )
{
printf(" Programm %08x\n",FlashOffset + j);
}
Cmd[0] = 0x06; // WREN
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x02; // PP
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
Cmd[3] = 0x00;
memcpy(&Cmd[4],&Buffer[j],256);
err = flashio(dev,Cmd,260,NULL,0);
if( err < 0 ) break;
while(1)
{
Cmd[0] = 0x05; // RDRS
err = flashio(dev,Cmd,1,&Cmd[0],1);
if( err < 0 ) break;
if( (Cmd[0] & 0x01) == 0 ) break;
}
if( err < 0 ) break;
}
if( err < 0 ) break;
Cmd[0] = 0x50; // EWSR
err = flashio(dev,Cmd,1,NULL,0);
if( err < 0 ) break;
Cmd[0] = 0x01; // WRSR
Cmd[1] = LockBits; // BPx = 0, Lock all blocks
err = flashio(dev,Cmd,2,NULL,0);
}
while(0);
return err;
}

View File

@@ -61,3 +61,5 @@ struct ddb_i2c_msg {
#define IOCTL_DDB_WRITE_MDIO _IOR(DDB_MAGIC, 0x09, struct ddb_mdio)
#define IOCTL_DDB_READ_I2C _IOWR(DDB_MAGIC, 0x0a, struct ddb_i2c_msg)
#define IOCTL_DDB_WRITE_I2C _IOR(DDB_MAGIC, 0x0b, struct ddb_i2c_msg)
#include "flash.c"

167
apps/pls.c Normal file
View File

@@ -0,0 +1,167 @@
/*
* pls.c: Convert between Gold and Root Codes for DVB-S2 PLS
*
* Copyright (C) 2017 Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de>
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 only, as published by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <getopt.h>
#include <stdio.h>
#include <stdint.h>
/* According to ETSI EN 302 307 5.5.4 the PLS (Physical Layer
Scrambling) for DVB-S2 consists of a complex randomization
sequence which is ultimately derived from two recursively
defined m-sequences (=MLS or maximum length sequences)
x(i) and y(i) of polynomials over GF(2) with m=18
(thus their length is 2^18 - 1).
These m-sequences with sequence y starting from y(0) and
sequence x starting from x(n) are combined to form a set
of 2^18 - 1 different Gold code sequences.
This starting number n of sequence x selects which
of those 2^18 - 1 Gold code sequences to use.
As a DVB-S2 tuning parameter n is called the scrambling sequence index
(cf. ETSI EN 300 468 table 41) or Gold sequence index,
commonly also just called "Gold code".
The 18 values of the sequence x starting from x(n)
(x(n) ... x(n+17)) are also called the "Root code".
So, Gold and Root codes are not different ways of PLS, they are
just different ways to select the same sequence start point.
The initial values for x(i), i=0..18 are x(0)=1, x(1)=0, .., x(17)=0 .
The polynomial used for the x sequence recursion is 1+x^7+x^18.
If the lower 18 bits of a variable "uint32_t X" contain x(n) ... x(n+17),
then we can simply calculate x(n+1) ... x(n+18) by doing:
X = (((X ^ (X >> 7)) & 1) << 17) | (X >> 1);
So, if X contained the "Root code" corresponding to "Gold code" n,
it will now contain the "Root code" corresponding to "Gold code" (n+1).
Note that X=0 and n=2^18 - 1 do not exist (or rather the lattter is the same
as n = 0) and for n=0 to 2^18 - 2 and X=1 to 2^18 - 1 there is a
one-to-one correspondence (bijection).
Note that PLS has nothing to do with encryption for DRM purposes. It is used
to minimize interference between transponders.
"Combo code":
There is no such thing as a combo code. It is the result of a bug in older
STV090x drivers which resulted in a crazy race condition between a Gold->Root
conversion in the STV and an ongoing I2C write.
Better forget about it and determine the proper Root or Gold code.
*/
static uint32_t gold2root(uint32_t gold)
{
uint32_t x, g;
for (g = 0, x = 1; g < gold; g++)
x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1);
return x;
}
static uint32_t root2gold(uint32_t root)
{
uint32_t x, g;
for (g = 0, x = 1; g < 0x3ffff; g++) {
if (root == x)
return g;
x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1);
}
return 0xffffffff;
}
int main(int argc, char **argv)
{
uint32_t gold = 0xffffffff, root = 0xffffffff;
while (1) {
int option_index = 0;
int c;
static struct option long_options[] = {
{"gold", required_argument, 0, 'g'},
{"root", required_argument, 0, 'r'},
{"help", no_argument , 0, 'h'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv,
"r:g:h",
long_options, &option_index);
if (c==-1)
break;
switch (c) {
case 'g':
gold = strtoul(optarg, NULL, 0);
break;
case 'r':
root = strtoul(optarg, NULL, 0);
break;
case 'h':
printf("pls -g gold_code\n");
printf("or\n");
printf("pls -r root_code\n");
exit(-1);
default:
break;
}
}
if (optind < argc) {
printf("Warning: unused arguments\n");
}
if (gold != 0xffffffff && root != 0xffffffff) {
printf("Only specify root or gold code\n");
exit(-1);
};
if (gold != 0xffffffff) {
if (gold < 0x3ffff) {
root = gold2root(gold);
printf("gold = %llu (0x%05x) root = %llu (0x%05x)\n",
gold, gold, root, root);
} else
printf("Invalid gold code specified.\n");
exit(0);
}
if (root != 0xffffffff) {
if (root > 0 && root < 0x40000)
gold = root2gold(root);
if (gold != 0xffffffff)
printf("gold = %llu (0x%05x) root = %llu (0x%05x)\n",
gold, gold, root, root);
else
printf("Invalid root code specified.\n");
exit(0);
}
printf("Specify either root or gold code with -r or -g.\n");
}

47
apps/setmod2.c Normal file
View File

@@ -0,0 +1,47 @@
#include <errno.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <linux/dvb/mod.h>
static int set_property(int fd, uint32_t cmd, uint32_t data)
{
struct dtv_property p;
struct dtv_properties c;
int ret;
p.cmd = cmd;
c.num = 1;
c.props = &p;
p.u.data = data;
ret = ioctl(fd, FE_SET_PROPERTY, &c);
if (ret < 0) {
fprintf(stderr, "FE_SET_PROPERTY returned %d\n", errno);
return -1;
}
return 0;
}
int main()
{
int fd;
struct dvb_mod_params mp;
struct dvb_mod_channel_params mc;
fd = open("/dev/dvb/adapter0/mod0", O_RDONLY);
set_property(fd, MODULATOR_MODULATION, QAM_256);
set_property(fd, MODULATOR_SYMBOL_RATE, 6900000);
set_property(fd, MODULATOR_FREQUENCY, 114000000);
close(fd);
}

View File

@@ -1,5 +1,8 @@
EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843 -DCONFIG_DVB_LNBP21 -DCONFIG_DVB_STV090x -DCONFIG_DVB_STV6110x -DCONFIG_DVB_DRXK -DCONFIG_DVB_STV0910 -DCONFIG_DVB_STV6111 -DCONFIG_DVB_LNBH25 -DCONFIG_DVB_MXL5XX
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
obj-$(CONFIG_DVB_OCTONET) += octonet.o

46
ddbridge/Kconfig Normal file
View File

@@ -0,0 +1,46 @@
config DVB_DDBRIDGE
tristate "Digital Devices bridge support"
depends on MEDIA_PCI_SUPPORT && DVB_CORE && PCI && I2C
select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT
select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
select DVB_TDA18212DD if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV0367DD if MEDIA_SUBDRV_AUTOSELECT
select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT
select DVB_CXD2843 if MEDIA_SUBDRV_AUTOSELECT
select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT
---help---
Support for cards with the Digital Devices PCI express bridge:
- Octopus PCIe Bridge
- Octopus mini PCIe Bridge
- Octopus LE
- DuoFlex S2 Octopus
- DuoFlex CT Octopus
- cineS2(v6)
Say Y if you own such a card and want to use it.
config DVB_OCTONET
tristate "Digital Devices octonet support"
depends on MEDIA_DIGITAL_TV_SUPPORT && DVB_CORE && I2C
select DVB_LNBP21 if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV6110x if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV090x if MEDIA_SUBDRV_AUTOSELECT
select DVB_DRXK if MEDIA_SUBDRV_AUTOSELECT
select DVB_TDA18271C2DD if MEDIA_SUBDRV_AUTOSELECT
select DVB_TDA18212DD if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV0367DD if MEDIA_SUBDRV_AUTOSELECT
select DVB_CXD2099 if MEDIA_SUBDRV_AUTOSELECT
select DVB_CXD2843 if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV0910 if MEDIA_SUBDRV_AUTOSELECT
select DVB_STV6111 if MEDIA_SUBDRV_AUTOSELECT
select DVB_LNBH25 if MEDIA_SUBDRV_AUTOSELECT
select DVB_MXL5XX if MEDIA_SUBDRV_AUTOSELECT
---help---
Support for OctopusNet
Say Y if you own such a card and want to use it.

View File

@@ -1,19 +1,14 @@
KDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
#
# Makefile for the ddbridge device driver
#
MODDEFS := CONFIG_DVB_DDBRIDGE=m
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-ci.o ddbridge-max.o
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-ci.o ddbridge-max.o
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MODDEFS) modules
$(MAKE) -C apps
dep:
DIR=`pwd`; (cd $(TOPDIR); make SUBDIRS=$$DIR dep)
install: all
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
clean:
rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
obj-$(CONFIG_DVB_OCTONET) += octonet.o
ccflags-y += -Idrivers/media/dvb-core/
ccflags-y += -Idrivers/media/dvb-frontends/
ccflags-y += -Idrivers/media/tuners/

14
ddbridge/Makefile.kernel Normal file
View File

@@ -0,0 +1,14 @@
#
# Makefile for the ddbridge device driver
#
ddbridge-objs = ddbridge-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-modulator.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
obj-$(CONFIG_DVB_OCTONET) += octonet.o
ccflags-y += -Idrivers/media/dvb-core/
ccflags-y += -Idrivers/media/dvb-frontends/
ccflags-y += -Idrivers/media/tuners/

350
ddbridge/ddbridge-ci.c Normal file
View File

@@ -0,0 +1,350 @@
/*
* ddbridge-ci.c: Digital Devices bridge and DuoFlex CI 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, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#include "ddbridge.h"
#include "ddbridge-io.h"
#include "ddbridge-i2c.h"
/* Octopus CI internal CI interface */
static int wait_ci_ready(struct ddb_ci *ci)
{
u32 count = 10;
ndelay(500);
do {
if (ddbreadl(ci->port->dev,
CI_CONTROL(ci->nr)) & CI_READY)
break;
usleep_range(1, 2);
if ((--count) == 0)
return -1;
} while (1);
return 0;
}
static int read_attribute_mem(struct dvb_ca_en50221 *ca,
int slot, int address)
{
struct ddb_ci *ci = ca->data;
u32 val, off = (address >> 1) & (CI_BUFFER_SIZE - 1);
if (address > CI_BUFFER_SIZE)
return -1;
ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address,
CI_DO_READ_ATTRIBUTES(ci->nr));
wait_ci_ready(ci);
val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off);
return val;
}
static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
int address, u8 value)
{
struct ddb_ci *ci = ca->data;
ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
CI_DO_ATTRIBUTE_RW(ci->nr));
wait_ci_ready(ci);
return 0;
}
static int read_cam_control(struct dvb_ca_en50221 *ca,
int slot, u8 address)
{
u32 count = 100;
struct ddb_ci *ci = ca->data;
u32 res;
ddbwritel(ci->port->dev, CI_READ_CMD | address,
CI_DO_IO_RW(ci->nr));
ndelay(500);
do {
res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr));
if (res & CI_READY)
break;
usleep_range(1, 2);
if ((--count) == 0)
return -1;
} while (1);
return 0xff & res;
}
static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
u8 address, u8 value)
{
struct ddb_ci *ci = ca->data;
ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
CI_DO_IO_RW(ci->nr));
wait_ci_ready(ci);
return 0;
}
static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
{
struct ddb_ci *ci = ca->data;
ddbwritel(ci->port->dev, CI_POWER_ON,
CI_CONTROL(ci->nr));
msleep(100);
ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM,
CI_CONTROL(ci->nr));
ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM,
CI_CONTROL(ci->nr));
usleep_range(20, 25);
ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON,
CI_CONTROL(ci->nr));
return 0;
}
static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
{
struct ddb_ci *ci = ca->data;
ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr));
msleep(300);
return 0;
}
static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
{
struct ddb_ci *ci = ca->data;
u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE,
CI_CONTROL(ci->nr));
return 0;
}
static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
{
struct ddb_ci *ci = ca->data;
u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
int stat = 0;
if (val & CI_CAM_DETECT)
stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
if (val & CI_CAM_READY)
stat |= DVB_CA_EN50221_POLL_CAM_READY;
return stat;
}
static struct dvb_ca_en50221 en_templ = {
.read_attribute_mem = read_attribute_mem,
.write_attribute_mem = write_attribute_mem,
.read_cam_control = read_cam_control,
.write_cam_control = write_cam_control,
.slot_reset = slot_reset,
.slot_shutdown = slot_shutdown,
.slot_ts_enable = slot_ts_enable,
.poll_slot_status = poll_slot_status,
};
static void ci_attach(struct ddb_port *port)
{
struct ddb_ci *ci = 0;
ci = kzalloc(sizeof(*ci), GFP_KERNEL);
if (!ci)
return;
memcpy(&ci->en, &en_templ, sizeof(en_templ));
ci->en.data = ci;
port->en = &ci->en;
ci->port = port;
ci->nr = port->nr - 2;
}
/* DuoFlex Dual CI support */
static int write_creg(struct ddb_ci *ci, u8 data, u8 mask)
{
struct i2c_adapter *i2c = &ci->port->i2c->adap;
u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
ci->port->creg = (ci->port->creg & ~mask) | data;
return i2c_write_reg(i2c, adr, 0x02, ci->port->creg);
}
static int read_attribute_mem_xo2(struct dvb_ca_en50221 *ca,
int slot, int address)
{
struct ddb_ci *ci = ca->data;
struct i2c_adapter *i2c = &ci->port->i2c->adap;
u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
int res;
u8 val;
res = i2c_read_reg16(i2c, adr, 0x8000 | address, &val);
return res ? res : val;
}
static int write_attribute_mem_xo2(struct dvb_ca_en50221 *ca, int slot,
int address, u8 value)
{
struct ddb_ci *ci = ca->data;
struct i2c_adapter *i2c = &ci->port->i2c->adap;
u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
return i2c_write_reg16(i2c, adr, 0x8000 | address, value);
}
static int read_cam_control_xo2(struct dvb_ca_en50221 *ca,
int slot, u8 address)
{
struct ddb_ci *ci = ca->data;
struct i2c_adapter *i2c = &ci->port->i2c->adap;
u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
u8 val;
int res;
res = i2c_read_reg(i2c, adr, 0x20 | (address & 3), &val);
return res ? res : val;
}
static int write_cam_control_xo2(struct dvb_ca_en50221 *ca, int slot,
u8 address, u8 value)
{
struct ddb_ci *ci = ca->data;
struct i2c_adapter *i2c = &ci->port->i2c->adap;
u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
return i2c_write_reg(i2c, adr, 0x20 | (address & 3), value);
}
static int slot_reset_xo2(struct dvb_ca_en50221 *ca, int slot)
{
struct ddb_ci *ci = ca->data;
write_creg(ci, 0x01, 0x01);
write_creg(ci, 0x04, 0x04);
msleep(20);
write_creg(ci, 0x02, 0x02);
write_creg(ci, 0x00, 0x04);
write_creg(ci, 0x18, 0x18);
return 0;
}
static int slot_shutdown_xo2(struct dvb_ca_en50221 *ca, int slot)
{
struct ddb_ci *ci = ca->data;
/*i2c_write_reg(i2c, adr, 0x03, 0x60);*/
/*i2c_write_reg(i2c, adr, 0x00, 0xc0);*/
write_creg(ci, 0x10, 0xff);
write_creg(ci, 0x08, 0x08);
return 0;
}
static int slot_ts_enable_xo2(struct dvb_ca_en50221 *ca, int slot)
{
struct ddb_ci *ci = ca->data;
write_creg(ci, 0x00, 0x10);
return 0;
}
static int poll_slot_status_xo2(struct dvb_ca_en50221 *ca, int slot, int open)
{
struct ddb_ci *ci = ca->data;
struct i2c_adapter *i2c = &ci->port->i2c->adap;
u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
u8 val = 0;
int stat = 0;
i2c_read_reg(i2c, adr, 0x01, &val);
if (val & 2)
stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
if (val & 1)
stat |= DVB_CA_EN50221_POLL_CAM_READY;
return stat;
}
static struct dvb_ca_en50221 en_xo2_templ = {
.read_attribute_mem = read_attribute_mem_xo2,
.write_attribute_mem = write_attribute_mem_xo2,
.read_cam_control = read_cam_control_xo2,
.write_cam_control = write_cam_control_xo2,
.slot_reset = slot_reset_xo2,
.slot_shutdown = slot_shutdown_xo2,
.slot_ts_enable = slot_ts_enable_xo2,
.poll_slot_status = poll_slot_status_xo2,
};
static void ci_xo2_attach(struct ddb_port *port)
{
struct ddb_ci *ci = 0;
struct i2c_adapter *i2c;
ci = kzalloc(sizeof(*ci), GFP_KERNEL);
if (!ci)
return;
memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ));
ci->en.data = ci;
port->en = &ci->en;
ci->port = port;
ci->nr = port->nr - 2;
ci->port->creg = 0;
i2c = &ci->port->i2c->adap;
write_creg(ci, 0x10, 0xff);
write_creg(ci, 0x08, 0x08);
}
static struct cxd2099_cfg cxd_cfg = {
.bitrate = 72000,
.adr = 0x40,
.polarity = 1,
.clock_mode = 1,
.max_i2c = 512,
};
int ddb_ci_attach(struct ddb_port *port, u32 bitrate)
{
switch (port->type) {
case DDB_CI_EXTERNAL_SONY:
cxd_cfg.bitrate = bitrate;
port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap);
if (!port->en)
return -ENODEV;
dvb_ca_en50221_init(port->dvb[0].adap,
port->en, 0, 1);
break;
case DDB_CI_EXTERNAL_XO2:
case DDB_CI_EXTERNAL_XO2_B:
ci_xo2_attach(port);
if (!port->en)
return -ENODEV;
dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1);
break;
case DDB_CI_INTERNAL:
ci_attach(port);
if (!port->en)
return -ENODEV;
dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1);
break;
}
return 0;
}

File diff suppressed because it is too large Load Diff

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

@@ -0,0 +1,717 @@
/*
* ddbridge-hw.c: Digital Devices device information tables
*
* 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, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#include "ddbridge.h"
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static const struct ddb_regset octopus_mod_odma = {
.base = 0x300,
.num = 0x0a,
.size = 0x10,
};
static const struct ddb_regset octopus_mod_odma_buf = {
.base = 0x2000,
.num = 0x0a,
.size = 0x100,
};
static const struct ddb_regset octopus_mod_channel = {
.base = 0x400,
.num = 0x0a,
.size = 0x40,
};
/****************************************************************************/
static const struct ddb_regset octopus_mod_2_odma = {
.base = 0x400,
.num = 0x18,
.size = 0x10,
};
static const struct ddb_regset octopus_mod_2_odma_buf = {
.base = 0x8000,
.num = 0x18,
.size = 0x100,
};
static const struct ddb_regset octopus_mod_2_channel = {
.base = 0x800,
.num = 0x18,
.size = 0x40,
};
static const struct ddb_regset octopus_sdr_output = {
.base = 0x240,
.num = 0x14,
.size = 0x10,
};
/****************************************************************************/
static const struct ddb_regset octopus_input = {
.base = 0x200,
.num = 0x08,
.size = 0x10,
};
static const struct ddb_regset octopus_output = {
.base = 0x280,
.num = 0x08,
.size = 0x10,
};
static const struct ddb_regset octopus_idma = {
.base = 0x300,
.num = 0x08,
.size = 0x10,
};
static const struct ddb_regset octopus_idma_buf = {
.base = 0x2000,
.num = 0x08,
.size = 0x100,
};
static const struct ddb_regset octopus_odma = {
.base = 0x380,
.num = 0x04,
.size = 0x10,
};
static const struct ddb_regset octopus_odma_buf = {
.base = 0x2800,
.num = 0x04,
.size = 0x100,
};
static const struct ddb_regset octopus_i2c = {
.base = 0x80,
.num = 0x04,
.size = 0x20,
};
static const struct ddb_regset octopus_i2c_buf = {
.base = 0x1000,
.num = 0x04,
.size = 0x200,
};
/****************************************************************************/
static const struct ddb_regset octopro_input = {
.base = 0x400,
.num = 0x14,
.size = 0x10,
};
static const struct ddb_regset octopro_output = {
.base = 0x600,
.num = 0x0a,
.size = 0x10,
};
static const struct ddb_regset octopro_idma = {
.base = 0x800,
.num = 0x40,
.size = 0x10,
};
static const struct ddb_regset octopro_idma_buf = {
.base = 0x4000,
.num = 0x40,
.size = 0x100,
};
static const struct ddb_regset octopro_odma = {
.base = 0xc00,
.num = 0x20,
.size = 0x10,
};
static const struct ddb_regset octopro_odma_buf = {
.base = 0x8000,
.num = 0x20,
.size = 0x100,
};
static const struct ddb_regset octopro_i2c = {
.base = 0x200,
.num = 0x0a,
.size = 0x20,
};
static const struct ddb_regset octopro_i2c_buf = {
.base = 0x2000,
.num = 0x0a,
.size = 0x200,
};
static const struct ddb_regset octopro_gtl = {
.base = 0xe00,
.num = 0x03,
.size = 0x40,
};
/****************************************************************************/
/****************************************************************************/
static const 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 const 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 const 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 const 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 const 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 const 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 const struct ddb_info ddb_none = {
.type = DDB_NONE,
.name = "unknown Digital Devices device, install newer driver",
.regmap = &octopus_map,
};
static const struct ddb_info ddb_octopus = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static const 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 const 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 const 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 const struct ddb_info ddb_octopus_mini = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus Mini",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static const 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 const 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 const 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 const 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 const 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 const 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 const struct ddb_info ddb_ci = {
.type = DDB_OCTOPUS_CI,
.name = "Digital Devices Octopus CI",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x03,
};
static const 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 const 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 const 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 const 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 const 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 const struct ddb_info ddb_mod_4 = {
.type = DDB_MOD,
.name = "Digital Devices DVB-C modulator",
.regmap = &octopus_mod_map,
.port_num = 4,
.temp_num = 1,
};
static const 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 const 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 const 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 const struct ddb_info ddb_mod_fsm_4 = {
.type = DDB_MOD,
.name = "Digital Devices DVB-C modulator FSM-8",
.version = 2,
.regmap = &octopus_mod_2_map,
.port_num = 4,
.temp_num = 1,
.tempmon_irq = 8,
};
static const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const 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 const struct ddb_regset octopus_gtl = {
.base = 0x180,
.num = 0x01,
.size = 0x20,
};
static const 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 const 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 const 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 const 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;
const struct ddb_info *info;
};
#define DDB_DEVID(_device, _subdevice, _info) { \
.vendor = 0xdd01, \
.device = _device, \
.subvendor = 0xdd01, \
.subdevice = _subdevice, \
.info = &(_info) }
static const 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(0x0201, 0x0004, ddb_mod_4), /* dummy entry ! */
DDB_DEVID(0x0203, 0x0001, ddb_mod),
DDB_DEVID(0x0210, 0x0000, ddb_mod_fsm_4), /* dummy entry ! */
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),
};
const 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++) {
const 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
*
* Copyright (C) 2010-2015 Digital Devices GmbH
* Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de>
* Marcus Metzler <mocm@metzlerbros.de>
*
@@ -17,93 +17,12 @@
*
*
* 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
* along with this program; if not, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
static int i2c_io(struct i2c_adapter *adapter, u8 adr,
u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
{
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
.buf = wbuf, .len = wlen },
{.addr = adr, .flags = I2C_M_RD,
.buf = rbuf, .len = rlen } };
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
}
static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
{
struct i2c_msg msg = {.addr = adr, .flags = 0,
.buf = data, .len = len};
return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1;
}
static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
{
struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD,
.buf = val, .len = 1 } };
return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
}
static int i2c_read_regs(struct i2c_adapter *adapter,
u8 adr, u8 reg, u8 *val, u8 len)
{
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
.buf = &reg, .len = 1 },
{.addr = adr, .flags = I2C_M_RD,
.buf = val, .len = len } };
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
}
static int i2c_read_regs16(struct i2c_adapter *adapter,
u8 adr, u16 reg, u8 *val, u8 len)
{
u8 reg16[2] = { reg >> 8, reg };
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
.buf = reg16, .len = 2 },
{.addr = adr, .flags = I2C_M_RD,
.buf = val, .len = len } };
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
}
static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val)
{
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
.buf = &reg, .len = 1},
{.addr = adr, .flags = I2C_M_RD,
.buf = val, .len = 1 } };
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
}
static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
u16 reg, u8 *val)
{
u8 msg[2] = {reg >> 8, reg & 0xff};
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
.buf = msg, .len = 2},
{.addr = adr, .flags = I2C_M_RD,
.buf = val, .len = 1 } };
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
}
static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr,
u16 reg, u8 val)
{
u8 msg[3] = {reg >> 8, reg & 0xff, val};
return i2c_write(adap, adr, msg, 3);
}
static int i2c_write_reg(struct i2c_adapter *adap, u8 adr,
u8 reg, u8 val)
{
u8 msg[2] = {reg, val};
return i2c_write(adap, adr, msg, 2);
}
#include "ddbridge.h"
#include "ddbridge-io.h"
static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
{
@@ -115,8 +34,8 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
stat = wait_for_completion_timeout(&i2c->completion, HZ);
val = ddbreadl(dev, i2c->regs + I2C_COMMAND);
if (stat == 0) {
pr_err("DDBridge I2C timeout, card %d, port %d, link %u\n",
dev->nr, i2c->nr, i2c->link);
dev_err(dev->dev, "I2C timeout, card %d, port %d, link %u\n",
dev->nr, i2c->nr, i2c->link);
#if 1
{
u32 istat = ddbreadl(dev, INTERRUPT_STATUS);
@@ -152,42 +71,47 @@ static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
static int ddb_i2c_master_xfer(struct i2c_adapter *adapter,
struct i2c_msg msg[], int num)
{
struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter);
struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter);
struct ddb *dev = i2c->dev;
u8 addr = 0;
if (num != 1 && num != 2)
return -EIO;
addr = msg[0].addr;
if (msg[0].len > i2c->bsize)
return -EIO;
if (num == 2 && msg[1].flags & I2C_M_RD &&
!(msg[0].flags & I2C_M_RD)) {
if (msg[1].len > i2c->bsize)
return -EIO;
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
ddbwritel(dev, msg[0].len | (msg[1].len << 16),
i2c->regs + I2C_TASKLENGTH);
if (!ddb_i2c_cmd(i2c, addr, 1)) {
ddbcpyfrom(dev, msg[1].buf,
i2c->rbuf,
msg[1].len);
return num;
}
}
if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH);
if (!ddb_i2c_cmd(i2c, addr, 2))
return num;
}
if (num == 1 && (msg[0].flags & I2C_M_RD)) {
ddbwritel(dev, msg[0].len << 16, i2c->regs + I2C_TASKLENGTH);
if (!ddb_i2c_cmd(i2c, addr, 3)) {
switch (num) {
case 1:
if (msg[0].flags & I2C_M_RD) {
ddbwritel(dev, msg[0].len << 16,
i2c->regs + I2C_TASKLENGTH);
if (ddb_i2c_cmd(i2c, addr, 3))
break;
ddbcpyfrom(dev, msg[0].buf,
i2c->rbuf, msg[0].len);
return num;
}
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH);
if (ddb_i2c_cmd(i2c, addr, 2))
break;
return num;
case 2:
if ((msg[0].flags & I2C_M_RD) == I2C_M_RD)
break;
if ((msg[1].flags & I2C_M_RD) != I2C_M_RD)
break;
if (msg[1].len > i2c->bsize)
break;
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
ddbwritel(dev, msg[0].len | (msg[1].len << 16),
i2c->regs + I2C_TASKLENGTH);
if (ddb_i2c_cmd(i2c, addr, 1))
break;
ddbcpyfrom(dev, msg[1].buf,
i2c->rbuf,
msg[1].len);
return num;
default:
break;
}
return -EIO;
}
@@ -202,7 +126,7 @@ struct i2c_algorithm ddb_i2c_algo = {
.functionality = ddb_i2c_functionality,
};
static void ddb_i2c_release(struct ddb *dev)
void ddb_i2c_release(struct ddb *dev)
{
int i;
struct ddb_i2c *i2c;
@@ -215,13 +139,14 @@ static void ddb_i2c_release(struct ddb *dev)
static void i2c_handler(unsigned long priv)
{
struct ddb_i2c *i2c = (struct ddb_i2c *) priv;
struct ddb_i2c *i2c = (struct ddb_i2c *)priv;
complete(&i2c->completion);
}
static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
struct ddb_regmap *regmap, int link, int i, int num)
const struct ddb_regmap *regmap,
int link, int i, int num)
{
struct i2c_adapter *adap;
@@ -241,13 +166,12 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
adap = &i2c->adap;
i2c_set_adapdata(adap, i2c);
#ifdef I2C_ADAP_CLASS_TV_DIGITAL
adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG;
adap->class = I2C_ADAP_CLASS_TV_DIGITAL | I2C_CLASS_TV_ANALOG;
#else
#ifdef I2C_CLASS_TV_ANALOG
adap->class = I2C_CLASS_TV_ANALOG;
#endif
#endif
/*strcpy(adap->name, "ddbridge");*/
snprintf(adap->name, I2C_NAME_SIZE, "ddbridge_%02x.%x.%x",
dev->nr, i2c->link, i);
adap->algo = &ddb_i2c_algo;
@@ -256,13 +180,13 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
return i2c_add_adapter(adap);
}
static int ddb_i2c_init(struct ddb *dev)
int ddb_i2c_init(struct ddb *dev)
{
int stat = 0;
u32 i, j, num = 0, l, base;
struct ddb_i2c *i2c;
struct i2c_adapter *adap;
struct ddb_regmap *regmap;
const struct ddb_regmap *regmap;
for (l = 0; l < DDB_MAX_LINK; l++) {
if (!dev->link[l].info)
@@ -275,7 +199,7 @@ static int ddb_i2c_init(struct ddb *dev)
if (!(dev->link[l].info->i2c_mask & (1 << i)))
continue;
i2c = &dev->i2c[num];
dev->handler_data[l][i + base] = (unsigned long) i2c;
dev->handler_data[l][i + base] = (unsigned long)i2c;
dev->handler[l][i + base] = i2c_handler;
stat = ddb_i2c_add(dev, i2c, regmap, l, i, num);
if (stat)
@@ -289,8 +213,9 @@ static int ddb_i2c_init(struct ddb *dev)
adap = &i2c->adap;
i2c_del_adapter(adap);
}
} else
} else {
dev->i2c_num = num;
}
return stat;
}

View File

@@ -1,7 +1,7 @@
/*
* ddbridge-i2c.h: Digital Devices bridge i2c driver
*
* Copyright (C) 2010-2015 Digital Devices GmbH
* Copyright (C) 2010-2017 Digital Devices GmbH
* Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de>
*
@@ -17,10 +17,8 @@
*
*
* 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
* along with this program; if not, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#ifndef _DDBRIDGE_I2C_H_

178
ddbridge/ddbridge-io.c Normal file
View File

@@ -0,0 +1,178 @@
/*
* ddbridge-io.c: Digital Devices bridge I/O functions
*
* Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de>
* Marcus Metzler <mocm@metzlerbros.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 only, as published by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#include "ddbridge.h"
#include "ddbridge-io.h"
u32 ddblreadl(struct ddb_link *link, u32 adr)
{
if (unlikely(link->nr)) {
unsigned long flags;
u32 val;
spin_lock_irqsave(&link->lock, flags);
gtlw(link);
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
ddbwritel0(link, 3, link->regs + 0x10);
gtlw(link);
val = ddbreadl0(link, link->regs + 0x1c);
spin_unlock_irqrestore(&link->lock, flags);
return val;
}
return readl((char *)(link->dev->regs + (adr)));
}
void ddblwritel(struct ddb_link *link, u32 val, u32 adr)
{
if (unlikely(link->nr)) {
unsigned long flags;
spin_lock_irqsave(&link->lock, flags);
gtlw(link);
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
ddbwritel0(link, val, link->regs + 0x18);
ddbwritel0(link, 1, link->regs + 0x10);
spin_unlock_irqrestore(&link->lock, flags);
return;
}
writel(val, (char *)(link->dev->regs + (adr)));
}
u32 ddbreadl(struct ddb *dev, u32 adr)
{
if (unlikely(adr & 0xf0000000)) {
unsigned long flags;
u32 val, l = (adr >> DDB_LINK_SHIFT);
struct ddb_link *link = &dev->link[l];
spin_lock_irqsave(&link->lock, flags);
gtlw(link);
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
ddbwritel0(link, 3, link->regs + 0x10);
gtlw(link);
val = ddbreadl0(link, link->regs + 0x1c);
spin_unlock_irqrestore(&link->lock, flags);
return val;
}
return readl((char *)(dev->regs + (adr)));
}
void ddbwritel(struct ddb *dev, u32 val, u32 adr)
{
if (unlikely(adr & 0xf0000000)) {
unsigned long flags;
u32 l = (adr >> DDB_LINK_SHIFT);
struct ddb_link *link = &dev->link[l];
spin_lock_irqsave(&link->lock, flags);
gtlw(link);
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
ddbwritel0(link, val, link->regs + 0x18);
ddbwritel0(link, 1, link->regs + 0x10);
spin_unlock_irqrestore(&link->lock, flags);
return;
}
writel(val, (char *)(dev->regs + (adr)));
}
void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf,
unsigned int count)
{
u32 val = 0, p = adr;
u32 aa = p & 3;
if (aa) {
while (p & 3 && count) {
val >>= 8;
val |= *buf << 24;
p++;
buf++;
count--;
}
ddbwritel(dev, val, adr);
}
while (count >= 4) {
val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
ddbwritel(dev, val, p);
p += 4;
buf += 4;
count -= 4;
}
if (count) {
val = buf[0];
if (count > 1)
val |= buf[1] << 8;
if (count > 2)
val |= buf[2] << 16;
ddbwritel(dev, val, p);
}
}
void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count)
{
u32 val = 0, p = adr;
u32 a = p & 3;
if (a) {
val = ddbreadl(dev, p) >> (8 * a);
while (p & 3 && count) {
*buf = val & 0xff;
val >>= 8;
p++;
buf++;
count--;
}
}
while (count >= 4) {
val = ddbreadl(dev, p);
buf[0] = val & 0xff;
buf[1] = (val >> 8) & 0xff;
buf[2] = (val >> 16) & 0xff;
buf[3] = (val >> 24) & 0xff;
p += 4;
buf += 4;
count -= 4;
}
if (count) {
val = ddbreadl(dev, p);
buf[0] = val & 0xff;
if (count > 1)
buf[1] = (val >> 8) & 0xff;
if (count > 2)
buf[2] = (val >> 16) & 0xff;
}
}
void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count)
{
if (unlikely(adr & 0xf0000000))
return gtlcpyto(dev, adr, src, count);
return memcpy_toio((char *)(dev->regs + adr), src, count);
}
void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count)
{
if (unlikely(adr & 0xf0000000))
return gtlcpyfrom(dev, dst, adr, count);
return memcpy_fromio(dst, (char *)(dev->regs + adr), count);
}

87
ddbridge/ddbridge-io.h Normal file
View File

@@ -0,0 +1,87 @@
/*
* ddbridge-io.h: Digital Devices bridge I/O functions
*
* Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de>
* Marcus Metzler <mocm@metzlerbros.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 only, as published by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#ifndef _DDBRIDGE_IO_H_
#define _DDBRIDGE_IO_H_
u32 ddblreadl(struct ddb_link *link, u32 adr);
void ddblwritel(struct ddb_link *link, u32 val, u32 adr);
u32 ddbreadl(struct ddb *dev, u32 adr);
void ddbwritel(struct ddb *dev, u32 val, u32 adr);
void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf,
unsigned int count);
void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count);
void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count);
void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count);
static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr)
{
writeb(val, (char *)(dev->regs + (adr)));
}
static inline u32 ddbreadb(struct ddb *dev, u32 adr)
{
return readb((char *)(dev->regs + (adr)));
}
static inline void ddbwritel0(struct ddb_link *link, u32 val, u32 adr)
{
writel(val, (char *)(link->dev->regs + (adr)));
}
static inline u32 ddbreadl0(struct ddb_link *link, u32 adr)
{
return readl((char *)(link->dev->regs + (adr)));
}
#if 0
static inline void gtlw(struct ddb_link *link)
{
u32 count = 0;
static u32 max;
while (1 & ddbreadl0(link, link->regs + 0x10)) {
if (++count == 1024) {
pr_info("LTO\n");
break;
}
}
if (count > max) {
max = count;
pr_info("TO=%u\n", max);
}
if (ddbreadl0(link, link->regs + 0x10) & 0x8000)
pr_err("link error\n");
}
#else
static inline void gtlw(struct ddb_link *link)
{
while (1 & ddbreadl0(link, link->regs + 0x10))
;
}
#endif
#define ddbmemset(_dev, _adr, _val, _count) \
memset_io((char *)((_dev)->regs + (_adr)), (_val), (_count))
#endif

408
ddbridge/ddbridge-main.c Normal file
View File

@@ -0,0 +1,408 @@
/*
* 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, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#include "ddbridge.h"
#include "ddbridge-io.h"
#ifdef CONFIG_PCI_MSI
static int msi = 1;
module_param(msi, int, 0444);
MODULE_PARM_DESC(msi,
" Control MSI interrupts: 0-disable, 1-enable (default)");
#endif
extern struct workqueue_struct *ddb_wq;
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static void __devexit ddb_irq_disable(struct ddb *dev)
{
if (dev->link[0].info->regmap->irq_version == 2) {
ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_2);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_3);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_4);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_5);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_6);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_7);
} else {
ddbwritel(dev, 0, INTERRUPT_ENABLE);
ddbwritel(dev, 0, MSI1_ENABLE);
}
}
static void __devexit ddb_irq_exit(struct ddb *dev)
{
ddb_irq_disable(dev);
if (dev->msi == 2)
free_irq(dev->pdev->irq + 1, dev);
free_irq(dev->pdev->irq, dev);
#ifdef CONFIG_PCI_MSI
if (dev->msi)
pci_disable_msi(dev->pdev);
#endif
}
static void __devexit ddb_remove(struct pci_dev *pdev)
{
struct ddb *dev = (struct ddb *)pci_get_drvdata(pdev);
ddb_device_destroy(dev);
ddb_nsd_detach(dev);
ddb_ports_detach(dev);
ddb_i2c_release(dev);
if (dev->link[0].info->ns_num)
ddbwritel(dev, 0, ETHER_CONTROL);
ddb_irq_exit(dev);
ddb_ports_release(dev);
ddb_buffers_free(dev);
ddb_unmap(dev);
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
}
#if (KERNEL_VERSION(3, 8, 0) < LINUX_VERSION_CODE)
#define __devinit
#define __devinitdata
#endif
static int __devinit ddb_irq_msi(struct ddb *dev, int nr)
{
int stat = 0;
#ifdef CONFIG_PCI_MSI
if (msi && pci_msi_enabled()) {
#if (KERNEL_VERSION(3, 15, 0) < LINUX_VERSION_CODE)
#if (KERNEL_VERSION(4, 11, 0) < LINUX_VERSION_CODE)
stat = pci_alloc_irq_vectors(dev->pdev, 1, nr, PCI_IRQ_MSI);
#else
stat = pci_enable_msi_range(dev->pdev, 1, nr);
#endif
if (stat >= 1) {
dev->msi = stat;
dev_info(dev->dev, "using %d MSI interrupt(s)\n",
dev->msi);
} else {
dev_info(dev->dev, "MSI not available.\n");
}
#else
stat = pci_enable_msi_block(dev->pdev, nr);
if (stat == 0) {
dev->msi = nr;
dev_info(dev->dev, "using %d MSI interrupts\n", nr);
} else if (stat == 1) {
stat = pci_enable_msi(dev->pdev);
dev->msi = 1;
}
if (stat < 0)
dev_info(dev->dev, "MSI not available.\n");
#endif
}
#endif
return stat;
}
static int __devinit ddb_irq_init2(struct ddb *dev)
{
int stat;
int irq_flag = IRQF_SHARED;
dev_info(dev->dev, "init type 2 IRQ hardware block\n");
ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_2);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_3);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_4);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_5);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_6);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_7);
ddb_irq_msi(dev, 1);
if (dev->msi)
irq_flag = 0;
stat = request_irq(dev->pdev->irq, ddb_irq_handler_v2,
irq_flag, "ddbridge", (void *)dev);
if (stat < 0)
return stat;
ddbwritel(dev, 0x0000ff7f, INTERRUPT_V2_CONTROL);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_1);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_2);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_3);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_4);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_5);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_6);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_7);
return stat;
}
static int __devinit ddb_irq_init(struct ddb *dev)
{
int stat;
int irq_flag = IRQF_SHARED;
if (dev->link[0].info->regmap->irq_version == 2)
return ddb_irq_init2(dev);
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
ddbwritel(dev, 0x00000000, MSI2_ENABLE);
ddbwritel(dev, 0x00000000, MSI3_ENABLE);
ddbwritel(dev, 0x00000000, MSI4_ENABLE);
ddbwritel(dev, 0x00000000, MSI5_ENABLE);
ddbwritel(dev, 0x00000000, MSI6_ENABLE);
ddbwritel(dev, 0x00000000, MSI7_ENABLE);
ddb_irq_msi(dev, 2);
if (dev->msi)
irq_flag = 0;
if (dev->msi == 2) {
stat = request_irq(dev->pdev->irq, ddb_irq_handler0,
irq_flag, "ddbridge", (void *)dev);
if (stat < 0)
return stat;
stat = request_irq(dev->pdev->irq + 1, ddb_irq_handler1,
irq_flag, "ddbridge", (void *)dev);
if (stat < 0) {
free_irq(dev->pdev->irq, dev);
return stat;
}
} else {
#ifdef DDB_TEST_THREADED
stat = request_threaded_irq(dev->pdev->irq, ddb_irq_handler,
irq_thread,
irq_flag,
"ddbridge", (void *)dev);
#else
stat = request_irq(dev->pdev->irq, ddb_irq_handler,
irq_flag, "ddbridge", (void *)dev);
#endif
if (stat < 0)
return stat;
}
/*ddbwritel(dev, 0xffffffff, INTERRUPT_ACK);*/
if (dev->msi == 2) {
ddbwritel(dev, 0x0fffff00, INTERRUPT_ENABLE);
ddbwritel(dev, 0x0000000f, MSI1_ENABLE);
} else {
ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE);
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
}
return stat;
}
static int __devinit ddb_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct ddb *dev;
int stat = 0;
if (pci_enable_device(pdev) < 0)
return -ENODEV;
pci_set_master(pdev);
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
return -ENODEV;
dev = vzalloc(sizeof(*dev));
if (!dev)
return -ENOMEM;
mutex_init(&dev->mutex);
dev->has_dma = 1;
dev->pdev = pdev;
dev->dev = &pdev->dev;
pci_set_drvdata(pdev, dev);
dev->link[0].ids.vendor = id->vendor;
dev->link[0].ids.device = id->device;
dev->link[0].ids.subvendor = id->subvendor;
dev->link[0].ids.subdevice = pdev->subsystem_device;
dev->link[0].dev = dev;
dev->link[0].info = get_ddb_info(id->vendor, id->device,
id->subvendor, pdev->subsystem_device);
dev_info(dev->dev, "device name: %s\n", dev->link[0].info->name);
dev->regs_len = pci_resource_len(dev->pdev, 0);
dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
pci_resource_len(dev->pdev, 0));
if (!dev->regs) {
dev_err(dev->dev, "not enough memory for register map\n");
stat = -ENOMEM;
goto fail;
}
if (ddbreadl(dev, 0) == 0xffffffff) {
dev_err(dev->dev, "cannot read registers\n");
stat = -ENODEV;
goto fail;
}
dev->link[0].ids.hwid = ddbreadl(dev, 0);
dev->link[0].ids.regmapid = ddbreadl(dev, 4);
dev_info(dev->dev, "HW %08x REGMAP %08x\n",
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
if (dev->link[0].info->ns_num) {
ddbwritel(dev, 0, ETHER_CONTROL);
ddb_reset_ios(dev);
}
ddbwritel(dev, 0, DMA_BASE_READ);
if (dev->link[0].info->type != DDB_MOD)
ddbwritel(dev, 0, DMA_BASE_WRITE);
if (dev->link[0].info->type == DDB_MOD
&& dev->link[0].info->version <= 1) {
if (ddbreadl(dev, 0x1c) == 4)
dev->link[0].info =
get_ddb_info(0xdd01, 0x0201, 0xdd01, 0x0004);
}
if (dev->link[0].info->type == DDB_MOD
&& dev->link[0].info->version == 2) {
u32 lic = ddbreadl(dev, 0x1c) & 7;
switch (lic) {
case 0:
dev->link[0].info =
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0000);
break;
case 1:
dev->link[0].info =
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0003);
break;
case 3:
dev->link[0].info =
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0002);
break;
default:
break;
}
}
stat = ddb_irq_init(dev);
if (stat < 0)
goto fail0;
if (ddb_init(dev) == 0)
return 0;
ddb_irq_exit(dev);
fail0:
dev_err(dev->dev, "fail0\n");
if (dev->msi)
pci_disable_msi(dev->pdev);
fail:
dev_err(dev->dev, "fail\n");
ddb_unmap(dev);
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
return -1;
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
#define DDB_DEVICE_ANY(_device) \
{ PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, PCI_ANY_ID) }
static const struct pci_device_id ddb_id_table[] __devinitconst = {
DDB_DEVICE_ANY(0x0002),
DDB_DEVICE_ANY(0x0003),
DDB_DEVICE_ANY(0x0005),
DDB_DEVICE_ANY(0x0006),
DDB_DEVICE_ANY(0x0007),
DDB_DEVICE_ANY(0x0008),
DDB_DEVICE_ANY(0x0011),
DDB_DEVICE_ANY(0x0012),
DDB_DEVICE_ANY(0x0013),
DDB_DEVICE_ANY(0x0201),
DDB_DEVICE_ANY(0x0203),
DDB_DEVICE_ANY(0x0210),
DDB_DEVICE_ANY(0x0220),
DDB_DEVICE_ANY(0x0320),
DDB_DEVICE_ANY(0x0321),
DDB_DEVICE_ANY(0x0322),
DDB_DEVICE_ANY(0x0323),
DDB_DEVICE_ANY(0x0328),
DDB_DEVICE_ANY(0x0329),
{0}
};
MODULE_DEVICE_TABLE(pci, ddb_id_table);
static struct pci_driver ddb_pci_driver = {
.name = "ddbridge",
.id_table = ddb_id_table,
.probe = ddb_probe,
.remove = ddb_remove,
};
static __init int module_init_ddbridge(void)
{
int stat = -1;
pr_info("Digital Devices PCIE bridge driver "
DDBRIDGE_VERSION
", Copyright (C) 2010-17 Digital Devices GmbH\n");
if (ddb_class_create() < 0)
return -1;
ddb_wq = create_workqueue("ddbridge");
if (!ddb_wq)
goto exit1;
stat = pci_register_driver(&ddb_pci_driver);
if (stat < 0)
goto exit2;
return stat;
exit2:
destroy_workqueue(ddb_wq);
exit1:
ddb_class_destroy();
return stat;
}
static __exit void module_exit_ddbridge(void)
{
pci_unregister_driver(&ddb_pci_driver);
destroy_workqueue(ddb_wq);
ddb_class_destroy();
}
module_init(module_init_ddbridge);
module_exit(module_exit_ddbridge);
MODULE_DESCRIPTION("Digital Devices PCIe Bridge");
MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
MODULE_LICENSE("GPL");
MODULE_VERSION(DDBRIDGE_VERSION);

444
ddbridge/ddbridge-max.c Normal file
View File

@@ -0,0 +1,444 @@
/*
* ddbridge-max.c: Digital Devices MAX card line support functions
*
* Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de>
* Marcus Metzler <mocm@metzlerbros.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 only, as published by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#include "ddbridge.h"
#include "ddbridge-io.h"
#include "ddbridge-i2c.h"
/* MAX LNB interface related module parameters */
static int fmode;
module_param(fmode, int, 0444);
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;
module_param(old_quattro, int, 0444);
MODULE_PARM_DESC(old_quattro, "old quattro LNB input order ");
/* MAX LNB interface related functions */
static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
{
u32 c, v = 0, tag = DDB_LINK_TAG(link);
v = LNB_TONE & (dev->link[link].lnb.tone << (15 - lnb));
ddbwritel(dev, cmd | v, tag | LNB_CONTROL(lnb));
for (c = 0; c < 10; c++) {
v = ddbreadl(dev, tag | LNB_CONTROL(lnb));
if ((v & LNB_BUSY) == 0)
break;
msleep(20);
}
if (c == 10)
dev_info(dev->dev,
"%s lnb = %08x cmd = %08x\n",
__func__, lnb, cmd);
return 0;
}
static int max_send_master_cmd(struct dvb_frontend *fe,
struct dvb_diseqc_master_cmd *cmd)
{
struct ddb_input *input = fe->sec_priv;
struct ddb_port *port = input->port;
struct ddb *dev = port->dev;
struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
u32 tag = DDB_LINK_TAG(port->lnr);
int i;
u32 fmode = dev->link[port->lnr].lnb.fmode;
if (fmode == 2 || fmode == 1)
return 0;
if (dvb->diseqc_send_master_cmd)
dvb->diseqc_send_master_cmd(fe, cmd);
mutex_lock(&dev->link[port->lnr].lnb.lock);
ddbwritel(dev, 0, tag | LNB_BUF_LEVEL(dvb->input));
for (i = 0; i < cmd->msg_len; i++)
ddbwritel(dev, cmd->msg[i], tag | LNB_BUF_WRITE(dvb->input));
lnb_command(dev, port->lnr, dvb->input, LNB_CMD_DISEQC);
mutex_unlock(&dev->link[port->lnr].lnb.lock);
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,
enum fe_sec_tone_mode tone)
{
int s = 0;
u32 mask = (1ULL << input);
switch (tone) {
case SEC_TONE_OFF:
if (!(dev->link[link].lnb.tone & mask))
return 0;
dev->link[link].lnb.tone &= ~(1ULL << input);
break;
case SEC_TONE_ON:
if (dev->link[link].lnb.tone & mask)
return 0;
dev->link[link].lnb.tone |= (1ULL << input);
break;
default:
s = -EINVAL;
break;
}
if (!s)
s = lnb_command(dev, link, input, LNB_CMD_NOP);
return s;
}
static int lnb_set_voltage(struct ddb *dev, u32 link, u32 input,
enum fe_sec_voltage voltage)
{
int s = 0;
if (dev->link[link].lnb.oldvoltage[input] == voltage)
return 0;
switch (voltage) {
case SEC_VOLTAGE_OFF:
if (dev->link[link].lnb.voltage[input])
return 0;
lnb_command(dev, link, input, LNB_CMD_OFF);
break;
case SEC_VOLTAGE_13:
lnb_command(dev, link, input, LNB_CMD_LOW);
break;
case SEC_VOLTAGE_18:
lnb_command(dev, link, input, LNB_CMD_HIGH);
break;
default:
s = -EINVAL;
break;
}
dev->link[link].lnb.oldvoltage[input] = voltage;
return s;
}
static int max_set_input_unlocked(struct dvb_frontend *fe, int in)
{
struct ddb_input *input = fe->sec_priv;
struct ddb_port *port = input->port;
struct ddb *dev = port->dev;
struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
int res = 0;
if (in > 3)
return -EINVAL;
if (dvb->input != in) {
u32 bit = (1ULL << input->nr);
u32 obit = dev->link[port->lnr].lnb.voltage[dvb->input] & bit;
dev->link[port->lnr].lnb.voltage[dvb->input] &= ~bit;
dvb->input = in;
dev->link[port->lnr].lnb.voltage[dvb->input] |= obit;
}
res = dvb->set_input(fe, in);
return res;
}
static int max_set_input(struct dvb_frontend *fe, int in)
{
struct ddb_input *input = fe->sec_priv;
struct ddb_port *port = input->port;
struct ddb *dev = input->port->dev;
int res;
mutex_lock(&dev->link[port->lnr].lnb.lock);
res = max_set_input_unlocked(fe, in);
mutex_unlock(&dev->link[port->lnr].lnb.lock);
return res;
}
static int max_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
{
struct ddb_input *input = fe->sec_priv;
struct ddb_port *port = input->port;
struct ddb *dev = port->dev;
struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
int tuner = 0;
int res = 0;
u32 fmode = dev->link[port->lnr].lnb.fmode;
mutex_lock(&dev->link[port->lnr].lnb.lock);
dvb->tone = tone;
switch (fmode) {
default:
case 0:
case 3:
res = lnb_set_tone(dev, port->lnr, dvb->input, tone);
break;
case 1:
case 2:
if (old_quattro) {
if (dvb->tone == SEC_TONE_ON)
tuner |= 2;
if (dvb->voltage == SEC_VOLTAGE_18)
tuner |= 1;
} else {
if (dvb->tone == SEC_TONE_ON)
tuner |= 1;
if (dvb->voltage == SEC_VOLTAGE_18)
tuner |= 2;
}
res = max_set_input_unlocked(fe, tuner);
break;
}
mutex_unlock(&dev->link[port->lnr].lnb.lock);
return res;
}
static int max_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
{
struct ddb_input *input = fe->sec_priv;
struct ddb_port *port = input->port;
struct ddb *dev = port->dev;
struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
int tuner = 0;
u32 nv, ov = dev->link[port->lnr].lnb.voltages;
int res = 0;
u32 fmode = dev->link[port->lnr].lnb.fmode;
mutex_lock(&dev->link[port->lnr].lnb.lock);
dvb->voltage = voltage;
switch (fmode) {
case 3:
default:
case 0:
if (fmode == 3)
max_set_input_unlocked(fe, 0);
if (voltage == SEC_VOLTAGE_OFF)
dev->link[port->lnr].lnb.voltage[dvb->input] &=
~(1ULL << input->nr);
else
dev->link[port->lnr].lnb.voltage[dvb->input] |=
(1ULL << input->nr);
res = lnb_set_voltage(dev, port->lnr, dvb->input, voltage);
break;
case 1:
case 2:
if (voltage == SEC_VOLTAGE_OFF)
dev->link[port->lnr].lnb.voltages &=
~(1ULL << input->nr);
else
dev->link[port->lnr].lnb.voltages |=
(1ULL << input->nr);
nv = dev->link[port->lnr].lnb.voltages;
if (old_quattro) {
if (dvb->tone == SEC_TONE_ON)
tuner |= 2;
if (dvb->voltage == SEC_VOLTAGE_18)
tuner |= 1;
} else {
if (dvb->tone == SEC_TONE_ON)
tuner |= 1;
if (dvb->voltage == SEC_VOLTAGE_18)
tuner |= 2;
}
res = max_set_input_unlocked(fe, tuner);
if (nv != ov) {
if (nv) {
lnb_set_voltage(dev, port->lnr, 0,
SEC_VOLTAGE_13);
if (fmode == 1) {
lnb_set_voltage(dev, port->lnr, 0,
SEC_VOLTAGE_13);
if (old_quattro) {
lnb_set_voltage(dev,
port->lnr, 1,
SEC_VOLTAGE_18);
lnb_set_voltage(dev, port->lnr,
2,
SEC_VOLTAGE_13);
} else {
lnb_set_voltage(dev, port->lnr,
1,
SEC_VOLTAGE_13);
lnb_set_voltage(dev, port->lnr,
2,
SEC_VOLTAGE_18);
}
lnb_set_voltage(dev, port->lnr, 3,
SEC_VOLTAGE_18);
}
} else {
lnb_set_voltage(dev, port->lnr,
0, SEC_VOLTAGE_OFF);
if (fmode == 1) {
lnb_set_voltage(dev, port->lnr, 1,
SEC_VOLTAGE_OFF);
lnb_set_voltage(dev, port->lnr, 2,
SEC_VOLTAGE_OFF);
lnb_set_voltage(dev, port->lnr, 3,
SEC_VOLTAGE_OFF);
}
}
}
break;
}
mutex_unlock(&dev->link[port->lnr].lnb.lock);
return res;
}
static int max_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
{
return 0;
}
static int max_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst)
{
return 0;
}
static int mxl_fw_read(void *priv, u8 *buf, u32 len)
{
struct ddb_link *link = priv;
struct ddb *dev = link->dev;
dev_info(dev->dev,
"Read mxl_fw from link %u\n", link->nr);
return ddbridge_flashread(dev, link->nr, buf, 0xc0000, len);
}
int ddb_lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm)
{
u32 l = link->nr;
if (link->lnb.fmode == fm)
return 0;
dev_info(dev->dev, "Set fmode link %u = %u\n", l, fm);
mutex_lock(&link->lnb.lock);
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);
if (old_quattro) {
lnb_set_tone(dev, l, 1, SEC_TONE_OFF);
lnb_set_tone(dev, l, 2, SEC_TONE_ON);
} else {
lnb_set_tone(dev, l, 1, SEC_TONE_ON);
lnb_set_tone(dev, l, 2, SEC_TONE_OFF);
}
lnb_set_tone(dev, l, 3, SEC_TONE_ON);
}
link->lnb.fmode = fm;
mutex_unlock(&link->lnb.lock);
return 0;
}
/* MAXS8 related functions */
static struct mxl5xx_cfg mxl5xx = {
.adr = 0x60,
.type = 0x01,
.clk = 27000000,
.ts_clk = 139,
.cap = 12,
.fw_read = mxl_fw_read,
};
int ddb_fe_attach_mxl5xx(struct ddb_input *input)
{
struct ddb *dev = input->port->dev;
struct i2c_adapter *i2c = &input->port->i2c->adap;
struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
struct ddb_port *port = input->port;
struct ddb_link *link = &dev->link[port->lnr];
struct mxl5xx_cfg cfg;
int demod, tuner;
cfg = mxl5xx;
cfg.fw_priv = link;
if (dev->link[0].info->type == DDB_OCTONET)
;/*cfg.ts_clk = 69;*/
demod = input->nr;
tuner = demod & 3;
if (fmode == 3)
tuner = 0;
dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, demod, tuner);
if (!dvb->fe) {
dev_err(dev->dev, "No MXL5XX found!\n");
return -ENODEV;
}
if (input->nr < 4) {
lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT);
lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF);
}
ddb_lnb_init_fmode(dev, link, fmode);
dvb->fe->ops.set_voltage = max_set_voltage;
dvb->fe->ops.enable_high_lnb_voltage = max_enable_high_lnb_voltage;
dvb->fe->ops.set_tone = max_set_tone;
dvb->diseqc_send_master_cmd = dvb->fe->ops.diseqc_send_master_cmd;
dvb->fe->ops.diseqc_send_master_cmd = max_send_master_cmd;
dvb->fe->ops.diseqc_send_burst = max_send_burst;
dvb->fe->sec_priv = input;
dvb->set_input = dvb->fe->ops.set_input;
dvb->fe->ops.set_input = max_set_input;
dvb->input = tuner;
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/*
* ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming
*
* Copyright (C) 2010-2015 Marcus Metzler <mocm@metzlerbros.de>
* Copyright (C) 2010-2017Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de>
* Digital Devices GmbH
*
@@ -17,14 +17,12 @@
*
*
* 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
* along with this program; if not, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
static int ddb_dvb_ns_input_start(struct ddb_input *input);
static int ddb_dvb_ns_input_stop(struct ddb_input *input);
#include "ddbridge.h"
#include "ddbridge-io.h"
static u16 calc_pcs(struct dvb_ns_params *p)
{
@@ -62,7 +60,7 @@ static u16 calc_pcs16(struct dvb_ns_params *p, int ipv)
static void ns_free(struct dvbnss *nss)
{
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
struct ddb_ns *dns = (struct ddb_ns *)nss->priv;
struct dvb_netstream *ns = nss->ns;
struct ddb_input *input = ns->priv;
struct ddb *dev = input->port->dev;
@@ -87,7 +85,6 @@ static int ns_alloc(struct dvbnss *nss)
dev->ns[i].fe = input;
nss->priv = &dev->ns[i];
ret = 0;
/*pr_info("%s i=%d fe=%d\n", __func__, i, input->nr); */
break;
}
ddbwritel(dev, 0x03, RTP_MASTER_CONTROL);
@@ -100,7 +97,7 @@ static int ns_set_pids(struct dvbnss *nss)
struct dvb_netstream *ns = nss->ns;
struct ddb_input *input = ns->priv;
struct ddb *dev = input->port->dev;
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
struct ddb_ns *dns = (struct ddb_ns *)nss->priv;
if (dev->link[0].ids.devid == 0x0301dd01) {
u32 sys = 0;
@@ -118,8 +115,9 @@ static int ns_set_pids(struct dvbnss *nss)
/* disable unused pids */
for (; j < 5; j++)
ddbwritel(dev, 0, PID_FILTER_PID(dns->nr, j));
} else
} else {
ddbcpyto(dev, STREAM_PIDS(dns->nr), nss->pids, 0x400);
}
return 0;
}
@@ -128,7 +126,7 @@ static int ns_set_pid(struct dvbnss *nss, u16 pid)
struct dvb_netstream *ns = nss->ns;
struct ddb_input *input = ns->priv;
struct ddb *dev = input->port->dev;
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
struct ddb_ns *dns = (struct ddb_ns *)nss->priv;
u16 byte = (pid & 0x1fff) >> 3;
u8 bit = 1 << (pid & 7);
u32 off = STREAM_PIDS(dns->nr);
@@ -187,7 +185,7 @@ static int ns_set_ci(struct dvbnss *nss, u8 ci)
struct dvb_netstream *ns = nss->ns;
struct ddb_input *input = ns->priv;
struct ddb *dev = input->port->dev;
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
struct ddb_ns *dns = (struct ddb_ns *)nss->priv;
int ciport;
if (ci == 255) {
@@ -198,8 +196,8 @@ static int ns_set_ci(struct dvbnss *nss, u8 ci)
if (ciport < 0)
return -EINVAL;
pr_info("input %d.%d to ci %d at port %d\n",
input->port->lnr, input->nr, ci, ciport);
dev_info(dev->dev, "DDBridge: input %d.%d to ci %d at port %d\n",
input->port->lnr, input->nr, ci, ciport);
ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1c,
TS_CONTROL(dev->port[ciport].output));
usleep_range(1, 5);
@@ -247,7 +245,7 @@ static int ns_set_rtcp_msg(struct dvbnss *nss, u8 *msg, u32 len)
struct dvb_netstream *ns = nss->ns;
struct ddb_input *input = ns->priv;
struct ddb *dev = input->port->dev;
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
struct ddb_ns *dns = (struct ddb_ns *)nss->priv;
u32 off = STREAM_PACKET_ADR(dns->nr);
u32 coff = 96;
u16 wlen;
@@ -371,7 +369,7 @@ static u32 set_nsbuf(struct dvb_ns_params *p, u8 *buf,
static int ns_set_ts_packets(struct dvbnss *nss, u8 *buf, u32 len)
{
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
struct ddb_ns *dns = (struct ddb_ns *)nss->priv;
struct dvb_netstream *ns = nss->ns;
struct ddb_input *input = ns->priv;
struct ddb *dev = input->port->dev;
@@ -388,7 +386,7 @@ static int ns_set_ts_packets(struct dvbnss *nss, u8 *buf, u32 len)
static int ns_insert_ts_packets(struct dvbnss *nss, u8 count)
{
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
struct ddb_ns *dns = (struct ddb_ns *)nss->priv;
struct dvb_netstream *ns = nss->ns;
struct ddb_input *input = ns->priv;
struct ddb *dev = input->port->dev;
@@ -410,7 +408,7 @@ static int ns_set_net(struct dvbnss *nss)
struct ddb_input *input = ns->priv;
struct ddb *dev = input->port->dev;
struct dvb_ns_params *p = &nss->params;
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
struct ddb_ns *dns = (struct ddb_ns *)nss->priv;
u32 off = STREAM_PACKET_ADR(dns->nr);
u32 coff = 96;
@@ -429,7 +427,7 @@ static int ns_set_net(struct dvbnss *nss)
static int ns_start(struct dvbnss *nss)
{
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
struct ddb_ns *dns = (struct ddb_ns *)nss->priv;
struct dvb_netstream *ns = nss->ns;
struct ddb_input *input = ns->priv;
struct ddb *dev = input->port->dev;
@@ -446,8 +444,6 @@ static int ns_start(struct dvbnss *nss)
if (dns->fe != input)
ddb_dvb_ns_input_start(dns->fe);
ddb_dvb_ns_input_start(input);
/* printk("ns start ns %u, fe %u link %u\n",
dns->nr, dns->fe->nr, dns->fe->port->lnr); */
ddbwritel(dev, reg | (dns->fe->nr << 8) | (dns->fe->port->lnr << 16),
STREAM_CONTROL(dns->nr));
return 0;
@@ -455,7 +451,7 @@ static int ns_start(struct dvbnss *nss)
static int ns_stop(struct dvbnss *nss)
{
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
struct ddb_ns *dns = (struct ddb_ns *)nss->priv;
struct dvb_netstream *ns = nss->ns;
struct ddb_input *input = ns->priv;
struct ddb *dev = input->port->dev;
@@ -467,7 +463,7 @@ static int ns_stop(struct dvbnss *nss)
return 0;
}
static int netstream_init(struct ddb_input *input)
int netstream_init(struct ddb_input *input)
{
struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
struct dvb_adapter *adap = dvb->adap;

View File

@@ -1,7 +1,7 @@
/*
* 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
* modify it under the terms of the GNU General Public License
@@ -15,16 +15,15 @@
*
*
* 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
* along with this program; if not, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
/* Register Definitions */
#define CUR_REGISTERMAP_VERSION_V1 0x00010001
#define CUR_REGISTERMAP_VERSION_V2 0x00020000
#define CUR_REGISTERMAP_VERSION_022X 0x00020001
#define HARDWARE_VERSION 0x00000000
#define REGISTERMAP_VERSION 0x00000004
@@ -57,9 +56,9 @@
/* ------------------------------------------------------------------------- */
/* Interrupt controller
How many MSI's are available depends on HW (Min 2 max 8)
How many are usable also depends on Host platform
*/
* How many MSI's are available depends on HW (Min 2 max 8)
* How many are usable also depends on Host platform
*/
#define INTERRUPT_BASE (0x40)
@@ -105,7 +104,6 @@
#define INTMASK_TSOUTPUT3 (0x00040000)
#define INTMASK_TSOUTPUT4 (0x00080000)
#define INTERRUPT_V2_CONTROL (INTERRUPT_BASE + 0x00)
#define INTERRUPT_V2_ENABLE_1 (INTERRUPT_BASE + 0x04)
#define INTERRUPT_V2_ENABLE_2 (INTERRUPT_BASE + 0x08)
@@ -124,9 +122,6 @@
#define INTERRUPT_V2_STATUS_6 (INTERRUPT_BASE + 0x38)
#define INTERRUPT_V2_STATUS_7 (INTERRUPT_BASE + 0x3c)
/* Modulator registers */
/* Clock Generator ( Sil598 @ 0xAA I2c ) */
@@ -139,8 +134,8 @@
/* DAC ( AD9781/AD9783 SPI ) */
#define DAC_BASE (0x090)
#define DAC_CONTROL (DAC_BASE)
#define DAC_WRITE_DATA (DAC_BASE+4)
#define DAC_READ_DATA (DAC_BASE+8)
#define DAC_WRITE_DATA (DAC_BASE + 4)
#define DAC_READ_DATA (DAC_BASE + 8)
#define DAC_CONTROL_INSTRUCTION_REG (0xFF)
#define DAC_CONTROL_STARTIO (0x100)
@@ -155,30 +150,39 @@
#define TEMPMON_CONTROL_INTENABLE (0x00000004)
#define TEMPMON_CONTROL_OVERTEMP (0x00008000)
/* SHORT Temperature in <20>C x 256 */
/* Temperature in C x 256 */
#define TEMPMON_CORE (TEMPMON_BASE + 0x04)
#define TEMPMON_SENSOR0 (TEMPMON_BASE + 0x04)
#define TEMPMON_SENSOR1 (TEMPMON_BASE + 0x08)
#define TEMPMON_SENSOR2 (TEMPMON_BASE + 0x0C)
#define TEMPMON_FANCONTROL (TEMPMON_BASE + 0x10)
#define TEMPMON_FANPWM (0x00000F00) // PWM speed in 10% steps
#define TEMPMON_FANTACHO (0x000000FF) // Rotations in 100/min steps
#define TEMPMON_FANPWM (0x00000F00) /* PWM speed in 10% steps */
#define TEMPMON_FANTACHO (0x000000FF) /* Rotations in 100/min steps */
// V1 Temperature Monitor
// Temperature Monitor TEMPMON_CONTROL & 0x8000 == 0 : ( 2x LM75A @ 0x90,0x92 )
// Temperature Monitor TEMPMON_CONTROL & 0x8000 == 1 : ( 1x LM75A @ 0x90, 1x ADM1032 @ 0x9A )
/* V1 Temperature Monitor
* Temperature Monitor TEMPMON_CONTROL & 0x8000 == 0 : ( 2x LM75A @ 0x90,0x92 )
* Temperature Monitor TEMPMON_CONTROL & 0x8000 == 1 :
* ( 1x LM75A @ 0x90, 1x ADM1032 @ 0x9A )
*/
#define TEMPMON1_CORE (TEMPMON_SENSOR0) // SHORT Temperature in <EFBFBD>C x 256 (ADM1032 ext)
#define TEMPMON1_SENSOR1 (TEMPMON_BASE + 0x08) // SHORT Temperature in <20>C x 256 (LM75A 0x90)
#define TEMPMON1_SENSOR2 (TEMPMON_BASE + 0x0C) // SHORT Temperature in <EFBFBD>C x 256 (LM75A 0x92 or ADM1032 Int)
/* Temperature in C x 256 (ADM1032 ext) */
#define TEMPMON1_CORE (TEMPMON_SENSOR0)
/* Temperature in C x 256 (LM75A 0x90) */
#define TEMPMON1_SENSOR1 (TEMPMON_BASE + 0x08)
/* Temperature in C x 256 (LM75A 0x92 or ADM1032 Int) */
#define TEMPMON1_SENSOR2 (TEMPMON_BASE + 0x0C)
// V2 Temperature Monitor 2 ADM1032
/* V2 Temperature Monitor 2 ADM1032 */
#define TEMPMON2_BOARD (TEMPMON_SENSOR0) // SHORT Temperature in <EFBFBD>C x 256 (ADM1032 int)
#define TEMPMON2_FPGACORE (TEMPMON_SENSOR1) // SHORT Temperature in <20>C x 256 (ADM1032 ext)
#define TEMPMON2_QAMCORE (TEMPMON_SENSOR2) // SHORT Temperature in <EFBFBD>C x 256 (ADM1032 ext)
/* Temperature in C x 256 (ADM1032 int) */
#define TEMPMON2_BOARD (TEMPMON_SENSOR0)
/* Temperature in C x 256 (ADM1032 ext) */
#define TEMPMON2_FPGACORE (TEMPMON_SENSOR1)
/* Temperature in C x 256 (ADM1032 ext) */
#define TEMPMON2_QAMCORE (TEMPMON_SENSOR2)
/* SHORT Temperature in C x 256 (ADM1032 ext) */
#define TEMPMON2_DACCORE (TEMPMON_SENSOR2)
/* ------------------------------------------------------------------------- */
/* I2C Master Controller */
@@ -197,7 +201,6 @@
#define I2C_SPEED_77 (0x19181919)
#define I2C_SPEED_50 (0x27262727)
/* ------------------------------------------------------------------------- */
/* DMA Controller */
@@ -217,18 +220,16 @@
#define DMA_DIAG_WAITOVERFLOWCOUNTER (0x38)
#define DMA_DIAG_WAITCOUNTER (0x3C)
#define TS_CONTROL(_io) (_io->regs + 0x00)
#define TS_CONTROL2(_io) (_io->regs + 0x04)
#define TS_CONTROL(_io) ((_io)->regs + 0x00)
#define TS_CONTROL2(_io) ((_io)->regs + 0x04)
/* ------------------------------------------------------------------------- */
/* DMA Buffer */
#define DMA_BUFFER_CONTROL(_dma) (_dma->regs + 0x00)
#define DMA_BUFFER_ACK(_dma) (_dma->regs + 0x04)
#define DMA_BUFFER_CURRENT(_dma) (_dma->regs + 0x08)
#define DMA_BUFFER_SIZE(_dma) (_dma->regs + 0x0c)
#define DMA_BUFFER_CONTROL(_dma) ((_dma)->regs + 0x00)
#define DMA_BUFFER_ACK(_dma) ((_dma)->regs + 0x04)
#define DMA_BUFFER_CURRENT(_dma) ((_dma)->regs + 0x08)
#define DMA_BUFFER_SIZE(_dma) ((_dma)->regs + 0x0c)
/* ------------------------------------------------------------------------- */
@@ -242,10 +243,10 @@
#define LNB_CMD_HIGH 4
#define LNB_CMD_OFF 5
#define LNB_CMD_DISEQC 6
#define LNB_CMD_UNI 7
#define LNB_CMD_SCIF 7
#define LNB_BUSY (1ULL << 4)
#define LNB_TONE (1ULL << 15)
#define LNB_BUSY BIT_ULL(4)
#define LNB_TONE BIT_ULL(15)
#define LNB_STATUS(i) (LNB_BASE + (i) * 0x20 + 0x04)
#define LNB_VOLTAGE(i) (LNB_BASE + (i) * 0x20 + 0x08)
@@ -291,14 +292,14 @@
#define CI_BUFFER_BASE (0x3000)
#define CI_BUFFER_SIZE (0x0800)
#define CI_BLOCKIO_BUFFER_SIZE (CI_BUFFER_SIZE/2)
#define CI_BLOCKIO_BUFFER_SIZE (CI_BUFFER_SIZE / 2)
#define CI_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE)
#define CI_BLOCKIO_RECEIVE_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE)
#define CI_BLOCKIO_SEND_BUFFER(i) \
(CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE + CI_BLOCKIO_BUFFER_SIZE)
// V1
/* V1 */
#define VCO1_BASE (0xC0)
#define VCO1_CONTROL (VCO1_BASE + 0x00)
@@ -330,16 +331,20 @@
/* Muxout from VCO (usually = Lock) */
#define VCO3_CONTROL_MUXOUT (0x00000004)
// V2
/* V2 */
#define MAX2871_BASE (0xC0)
#define MAX2871_CONTROL (MAX2871_BASE + 0x00)
#define MAX2871_OUTDATA (MAX2871_BASE + 0x04) // 32 Bit
#define MAX2871_INDATA (MAX2871_BASE + 0x08) // 32 Bit
#define MAX2871_CONTROL_WRITE (0x00000001) // 1 = Trigger write, resets when done
#define MAX2871_CONTROL_CE (0x00000002) // 0 = Put VCO into power down
#define MAX2871_CONTROL_MUXOUT (0x00000004) // Muxout from VCO
#define MAX2871_CONTROL_LOCK (0x00000008) // Lock from VCO
#define MAX2871_OUTDATA (MAX2871_BASE + 0x04)
#define MAX2871_INDATA (MAX2871_BASE + 0x08)
/* 1 = Trigger write, resets when done */
#define MAX2871_CONTROL_WRITE (0x00000001)
/* 0 = Put VCO into power down */
#define MAX2871_CONTROL_CE (0x00000002)
/* Muxout from VCO */
#define MAX2871_CONTROL_MUXOUT (0x00000004)
/* Lock from VCO */
#define MAX2871_CONTROL_LOCK (0x00000008)
#define FSM_BASE (0x200)
#define FSM_CONTROL (FSM_BASE + 0x00)
@@ -356,11 +361,10 @@
#define FSM_STATUS_READY (0x00010000)
#define FSM_STATUS_QAMREADY (0x00020000)
#define FSM_CAPACITY (FSM_BASE + 0x04)
#define FSM_CAPACITY_MAX (0x3F000000)
#define FSM_CAPACITY_CUR (0x003F0000)
#define FSM_CAPACITY_INUSE (0x0000003F)
#define FSM_CAPACITY_MAX (0x3F000000)
#define FSM_CAPACITY_CUR (0x003F0000)
#define FSM_CAPACITY_INUSE (0x0000003F)
#define FSM_GAIN (FSM_BASE + 0x10)
#define FSM_GAINMASK (0x000000FF)
@@ -373,21 +377,20 @@
#define FSM_GAIN_N24 (0x00000029)
#define FSM_GAIN_N96 (0x00000011)
// Attenuator/VGA
/* Attenuator/VGA */
#define RF_ATTENUATOR (0xD8)
#define RF_ATTENUATOR (0xD8)
/* 0x00 = 0 dB
0x01 = 1 dB
...
0x1F = 31 dB
*/
* 0x01 = 1 dB
* ...
* 0x1F = 31 dB
*/
#define RF_VGA (0xDC)
/* Only V2 */
/* 8 bit range 0 - 31.75 dB Gain */
/* VGA Gain for same output level as V1 Modulator */
#define RF_VGA_GAIN_N8 (85)
#define RF_VGA_GAIN_N16 (117)
@@ -395,7 +398,6 @@
#define RF_VGA_GAIN_MAX (200)
/* V1 only */
#define RF_POWER (0xE0)
@@ -408,10 +410,9 @@
#define RF_POWER_CONTROL_VALIDMASK (0x00000700)
#define RF_POWER_CONTROL_VALID (0x00000500)
/* --------------------------------------------------------------------------
Output control
*/
/*
* Output control
*/
#define IQOUTPUT_BASE (0x240)
#define IQOUTPUT_CONTROL (IQOUTPUT_BASE + 0x00)
@@ -440,14 +441,13 @@
#define IQOUTPUT_CONTROL_ENABLE_PEAK (0x00000008)
#define IQOUTPUT_CONTROL_BYPASS_EQUALIZER (0x00000010)
/* Modulator Base V1 */
#define MODULATOR_BASE (0x200)
#define MODULATOR_CONTROL (MODULATOR_BASE)
#define MODULATOR_IQTABLE_END (MODULATOR_BASE+4)
#define MODULATOR_IQTABLE_INDEX (MODULATOR_BASE+8)
#define MODULATOR_IQTABLE_DATA (MODULATOR_BASE+12)
#define MODULATOR_IQTABLE_END (MODULATOR_BASE + 4)
#define MODULATOR_IQTABLE_INDEX (MODULATOR_BASE + 8)
#define MODULATOR_IQTABLE_DATA (MODULATOR_BASE + 12)
#define MODULATOR_IQTABLE_INDEX_CHANNEL_MASK (0x000F0000)
#define MODULATOR_IQTABLE_INDEX_IQ_MASK (0x00008000)
@@ -456,7 +456,6 @@
#define MODULATOR_IQTABLE_INDEX_SEL_Q (MODULATOR_IQTABLE_INDEX_IQ_MASK)
#define MODULATOR_IQTABLE_SIZE (2048)
/* Modulator Channels */
#define CHANNEL_BASE dev->link[0].info->regmap->channel->base
@@ -508,12 +507,11 @@
#define CHANNEL_SETTINGS2_OUTPUT_MASK (0x0000007F)
#define KFLF_MAX (0x07FFFFFFUL)
#define KF_INIT(Symbolrate) (Symbolrate)
#define LF_INIT(Symbolrate) (9000000UL)
#define KF_INIT(_symbol_rate) (_symbol_rate)
#define LF_INIT(_symbol_rate) (9000000UL)
#define MIN_SYMBOLRATE (1000000)
#define MAX_SYMBOLRATE (7100000)
/* OCTONET */
#define ETHER_BASE (0x100)
@@ -550,5 +548,70 @@
#define PID_FILTER_SYSTEM_PIDS(i) (PID_FILTER_BASE + (i) * 0x20)
#define PID_FILTER_PID(i, j) (PID_FILTER_BASE + (i) * 0x20 + (j) * 4)
/* 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,626 +0,0 @@
/*
* ddbridge.c: Digital Devices PCIe bridge driver
*
* Copyright (C) 2010-2015 Digital Devices GmbH
* Ralph Metzler <rjkm@metzlerbros.de>
* Marcus Metzler <mocm@metzlerbros.de>
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 only, as published by the Free Software Foundation.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
*/
#define DDB_USE_WORK
/*#define DDB_TEST_THREADED*/
#include "ddbridge.h"
#include "ddbridge-regs.h"
static struct workqueue_struct *ddb_wq;
static int adapter_alloc;
module_param(adapter_alloc, int, 0444);
MODULE_PARM_DESC(adapter_alloc,
"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all");
#ifdef CONFIG_PCI_MSI
static int msi = 1;
module_param(msi, int, 0444);
MODULE_PARM_DESC(msi,
" Control MSI interrupts: 0-disable, 1-enable (default)");
#endif
#include "ddbridge-core.c"
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static void ddb_unmap(struct ddb *dev)
{
if (dev->regs)
iounmap(dev->regs);
vfree(dev);
}
static void __devexit ddb_irq_disable(struct ddb *dev)
{
if (dev->link[0].info->regmap->irq_version == 2) {
ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_2);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_3);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_4);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_5);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_6);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_7);
} else {
ddbwritel(dev, 0, INTERRUPT_ENABLE);
ddbwritel(dev, 0, MSI1_ENABLE);
}
}
static void __devexit ddb_irq_exit(struct ddb *dev)
{
ddb_irq_disable(dev);
if (dev->msi == 2)
free_irq(dev->pdev->irq + 1, dev);
free_irq(dev->pdev->irq, dev);
#ifdef CONFIG_PCI_MSI
if (dev->msi)
pci_disable_msi(dev->pdev);
#endif
}
static void __devexit ddb_remove(struct pci_dev *pdev)
{
struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev);
ddb_device_destroy(dev);
ddb_nsd_detach(dev);
ddb_ports_detach(dev);
ddb_i2c_release(dev);
if (dev->link[0].info->ns_num)
ddbwritel(dev, 0, ETHER_CONTROL);
ddb_irq_exit(dev);
ddb_ports_release(dev);
ddb_buffers_free(dev);
ddb_unmap(dev);
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
#define __devinit
#define __devinitdata
#endif
static int __devinit ddb_irq_msi(struct ddb *dev, int nr)
{
int stat;
#ifdef CONFIG_PCI_MSI
if (msi && pci_msi_enabled()) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
stat = pci_enable_msi_range(dev->pdev, 1, nr);
if (stat >= 1) {
dev->msi = stat;
pr_info("DDBridge: using %d MSI interrupt(s)\n",
dev->msi);
} else
pr_info("DDBridge: MSI not available.\n");
#else
stat = pci_enable_msi_block(dev->pdev, nr);
if (stat == 0) {
dev->msi = nr;
pr_info("DDBridge: using %d MSI interrupts\n", nr);
} else if (stat == 1) {
stat = pci_enable_msi(dev->pdev);
dev->msi = 1;
}
if (stat < 0)
pr_info("DDBridge: MSI not available.\n");
#endif
}
return stat;
}
static int __devinit ddb_irq_init2(struct ddb *dev)
{
int stat;
int irq_flag = IRQF_SHARED;
pr_info("init type 2 IRQ hardware block\n");
ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_2);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_3);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_4);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_5);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_6);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_7);
ddb_irq_msi(dev, 1);
if (dev->msi)
irq_flag = 0;
stat = request_irq(dev->pdev->irq, irq_handler_v2,
irq_flag, "ddbridge", (void *) dev);
if (stat < 0)
return stat;
ddbwritel(dev, 0x0000ff7f, INTERRUPT_V2_CONTROL);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_1);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_2);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_3);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_4);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_5);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_6);
ddbwritel(dev, 0xffffffff, INTERRUPT_V2_ENABLE_7);
return stat;
}
static int __devinit ddb_irq_init(struct ddb *dev)
{
int stat;
int irq_flag = IRQF_SHARED;
if (dev->link[0].info->regmap->irq_version == 2)
return ddb_irq_init2(dev);
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
ddbwritel(dev, 0x00000000, MSI2_ENABLE);
ddbwritel(dev, 0x00000000, MSI3_ENABLE);
ddbwritel(dev, 0x00000000, MSI4_ENABLE);
ddbwritel(dev, 0x00000000, MSI5_ENABLE);
ddbwritel(dev, 0x00000000, MSI6_ENABLE);
ddbwritel(dev, 0x00000000, MSI7_ENABLE);
ddb_irq_msi(dev, 2);
if (dev->msi)
irq_flag = 0;
if (dev->msi == 2) {
stat = request_irq(dev->pdev->irq, irq_handler0,
irq_flag, "ddbridge", (void *) dev);
if (stat < 0)
return stat;
stat = request_irq(dev->pdev->irq + 1, irq_handler1,
irq_flag, "ddbridge", (void *) dev);
if (stat < 0) {
free_irq(dev->pdev->irq, dev);
return stat;
}
} else
#endif
{
#ifdef DDB_TEST_THREADED
stat = request_threaded_irq(dev->pdev->irq, irq_handler,
irq_thread,
irq_flag,
"ddbridge", (void *) dev);
#else
stat = request_irq(dev->pdev->irq, irq_handler,
irq_flag, "ddbridge", (void *) dev);
#endif
if (stat < 0)
return stat;
}
/*ddbwritel(dev, 0xffffffff, INTERRUPT_ACK);*/
if (dev->msi == 2) {
ddbwritel(dev, 0x0fffff00, INTERRUPT_ENABLE);
ddbwritel(dev, 0x0000000f, MSI1_ENABLE);
} else {
ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE);
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
}
return stat;
}
static int __devinit ddb_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct ddb *dev;
int stat = 0;
if (pci_enable_device(pdev) < 0)
return -ENODEV;
pci_set_master(pdev);
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
return -ENODEV;
dev = vzalloc(sizeof(struct ddb));
if (dev == NULL)
return -ENOMEM;
mutex_init(&dev->mutex);
dev->has_dma = 1;
dev->pdev = pdev;
dev->dev = &pdev->dev;
pci_set_drvdata(pdev, dev);
dev->link[0].ids.vendor = id->vendor;
dev->link[0].ids.device = id->device;
dev->link[0].ids.subvendor = id->subvendor;
dev->link[0].ids.subdevice = id->subdevice;
dev->link[0].dev = dev;
dev->link[0].info = (struct ddb_info *) id->driver_data;
pr_info("DDBridge driver detected: %s\n", dev->link[0].info->name);
dev->regs_len = pci_resource_len(dev->pdev, 0);
dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
pci_resource_len(dev->pdev, 0));
if (!dev->regs) {
pr_err("DDBridge: not enough memory for register map\n");
stat = -ENOMEM;
goto fail;
}
if (ddbreadl(dev, 0) == 0xffffffff) {
pr_err("DDBridge: cannot read registers\n");
stat = -ENODEV;
goto fail;
}
dev->link[0].ids.hwid = ddbreadl(dev, 0);
dev->link[0].ids.regmapid = ddbreadl(dev, 4);
pr_info("DDBridge: HW %08x REGMAP %08x\n",
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
if (dev->link[0].info->ns_num) {
ddbwritel(dev, 0, ETHER_CONTROL);
ddb_reset_ios(dev);
}
ddbwritel(dev, 0, DMA_BASE_READ);
if (dev->link[0].info->type != DDB_MOD)
ddbwritel(dev, 0, DMA_BASE_WRITE);
if (dev->link[0].info->type == DDB_MOD) {
if (ddbreadl(dev, 0x1c) == 4)
dev->link[0].info->port_num = 4;
}
stat = ddb_irq_init(dev);
if (stat < 0)
goto fail0;
if (ddb_init(dev) == 0)
return 0;
ddb_irq_disable(dev);
fail0:
pr_err("fail0\n");
if (dev->msi)
pci_disable_msi(dev->pdev);
fail:
pr_err("fail\n");
ddb_unmap(dev);
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
return -1;
}
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static struct ddb_info ddb_none = {
.type = DDB_NONE,
.name = "unknown Digital Devices PCIe card, install newer driver",
.regmap = &octopus_map,
};
static struct ddb_info ddb_octopus = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static struct ddb_info ddb_octopusv3 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus V3 DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static struct ddb_info ddb_octopus_le = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus LE DVB adapter",
.regmap = &octopus_map,
.port_num = 2,
.i2c_mask = 0x03,
};
static struct ddb_info ddb_octopus_oem = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus OEM",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.led_num = 1,
.fan_num = 1,
.temp_num = 1,
.temp_bus = 0,
};
static struct ddb_info ddb_octopus_mini = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus Mini",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static struct ddb_info ddb_v6 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V6 DVB adapter",
.regmap = &octopus_map,
.port_num = 3,
.i2c_mask = 0x07,
};
static struct ddb_info ddb_v6_5 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V6.5 DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
};
static struct ddb_info ddb_v7 = {
.type = DDB_OCTOPUS,
.name = "Digital Devices Cine S2 V7 DVB adapter",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 2,
.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_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, 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, 0x0011, DDVID, 0x0040, ddb_ci),
DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis),
DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci),
DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro),
DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod),
DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod),
DDB_ID(DDVID, 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}
};
MODULE_DEVICE_TABLE(pci, ddb_id_tbl);
static struct pci_driver ddb_pci_driver = {
.name = "ddbridge",
.id_table = ddb_id_tbl,
.probe = ddb_probe,
.remove = ddb_remove,
};
static __init int module_init_ddbridge(void)
{
int stat = -1;
pr_info("Digital Devices PCIE bridge driver "
DDBRIDGE_VERSION
", Copyright (C) 2010-16 Digital Devices GmbH\n");
if (ddb_class_create() < 0)
return -1;
ddb_wq = create_workqueue("ddbridge");
if (ddb_wq == NULL)
goto exit1;
stat = pci_register_driver(&ddb_pci_driver);
if (stat < 0)
goto exit2;
return stat;
exit2:
destroy_workqueue(ddb_wq);
exit1:
ddb_class_destroy();
return stat;
}
static __exit void module_exit_ddbridge(void)
{
pci_unregister_driver(&ddb_pci_driver);
destroy_workqueue(ddb_wq);
ddb_class_destroy();
}
module_init(module_init_ddbridge);
module_exit(module_exit_ddbridge);
MODULE_DESCRIPTION("Digital Devices PCIe Bridge");
MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
MODULE_LICENSE("GPL");
MODULE_VERSION(DDBRIDGE_VERSION);

View File

@@ -1,7 +1,7 @@
/*
* ddbridge.h: Digital Devices PCIe bridge driver
*
* Copyright (C) 2010-2015 Digital Devices GmbH
* Copyright (C) 2010-2017 Digital Devices GmbH
* Ralph Metzler <rmetzler@digitaldevices.de>
*
* This program is free software; you can redistribute it and/or
@@ -16,18 +16,19 @@
*
*
* 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
* along with this program; if not, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#ifndef _DDBRIDGE_H_
#define _DDBRIDGE_H_
#define DDB_USE_WORK
/*#define DDB_TEST_THREADED*/
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
#if (KERNEL_VERSION(3, 8, 0) < LINUX_VERSION_CODE)
#define __devexit
#define __devinit
#define __devinitconst
@@ -55,7 +56,6 @@
#include <linux/completion.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <asm/dma.h>
@@ -91,6 +91,8 @@
#include "lnbh25.h"
#include "mxl5xx.h"
#include "ddbridge-regs.h"
#define DDB_MAX_I2C 32
#define DDB_MAX_PORT 32
#define DDB_MAX_INPUT 64
@@ -98,7 +100,7 @@
#define DDB_MAX_LINK 4
#define DDB_LINK_SHIFT 28
#define DDB_LINK_TAG(_x) (_x << DDB_LINK_SHIFT)
#define DDB_LINK_TAG(_x) ((_x) << DDB_LINK_SHIFT)
struct ddb_regset {
u32 base;
@@ -114,22 +116,18 @@ struct ddb_regmap {
u32 irq_base_gtl;
u32 irq_base_rate;
struct ddb_regset *i2c;
struct ddb_regset *i2c_buf;
struct ddb_regset *idma;
struct ddb_regset *idma_buf;
struct ddb_regset *odma;
struct ddb_regset *odma_buf;
const struct ddb_regset *i2c;
const struct ddb_regset *i2c_buf;
const struct ddb_regset *idma;
const struct ddb_regset *idma_buf;
const struct ddb_regset *odma;
const struct ddb_regset *odma_buf;
struct ddb_regset *input;
struct ddb_regset *output;
struct ddb_regset *channel;
//struct ddb_regset *ci;
//struct ddb_regset *pid_filter;
//struct ddb_regset *ns;
struct ddb_regset *gtl;
//struct ddb_regset *mdio;
const struct ddb_regset *input;
const struct ddb_regset *output;
const struct ddb_regset *channel;
const struct ddb_regset *gtl;
};
struct ddb_ids {
@@ -172,32 +170,37 @@ struct ddb_info {
#define TS_QUIRK_SERIAL 1
#define TS_QUIRK_REVERSED 2
#define TS_QUIRK_NO_OUTPUT 4
#define TS_QUIRK_ALT_OSC 8
u32 tempmon_irq;
struct ddb_regmap *regmap;
const struct ddb_regmap *regmap;
};
/* DMA_SIZE MUST be smaller than 256k and
MUST be divisible by 188 and 128 !!! */
* MUST be divisible by 188 and 128 !!!
*/
#define DMA_MAX_BUFS 32 /* hardware table limit */
#ifdef SMALL_DMA_BUFS
#define INPUT_DMA_BUFS 32
#define INPUT_DMA_SIZE (32*47*21)
#define INPUT_DMA_SIZE (128 * 47 * 5)
#define INPUT_DMA_IRQ_DIV 1
#define OUTPUT_DMA_BUFS 32
#define OUTPUT_DMA_SIZE (32*47*21)
#define OUTPUT_DMA_SIZE (128 * 47 * 5)
#define OUTPUT_DMA_IRQ_DIV 1
#else
#define INPUT_DMA_BUFS 8
#define INPUT_DMA_SIZE (128*47*21)
#define INPUT_DMA_SIZE (128 * 47 * 21)
#define INPUT_DMA_IRQ_DIV 1
#define OUTPUT_DMA_BUFS 8
#define OUTPUT_DMA_SIZE (128*47*21)
#define OUTPUT_DMA_SIZE (128 * 47 * 21)
#define OUTPUT_DMA_IRQ_DIV 1
#endif
#define OUTPUT_DMA_BUFS_SDR 32
#define OUTPUT_DMA_SIZE_SDR (256 * 1024)
#define OUTPUT_DMA_IRQ_DIV_SDR 1
struct ddb;
struct ddb_port;
@@ -219,7 +222,7 @@ struct ddb_dma {
#else
struct tasklet_struct tasklet;
#endif
spinlock_t lock;
spinlock_t lock; /* DMA lock */
wait_queue_head_t wq;
int running;
u32 stat;
@@ -244,11 +247,12 @@ struct ddb_dvb {
u32 attached;
u8 input;
fe_sec_tone_mode_t tone;
fe_sec_voltage_t voltage;
enum fe_sec_tone_mode tone;
enum fe_sec_voltage voltage;
int (*i2c_gate_ctrl)(struct dvb_frontend *, int);
int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
int (*set_voltage)(struct dvb_frontend *fe,
enum fe_sec_voltage voltage);
int (*set_input)(struct dvb_frontend *fe, int input);
int (*diseqc_send_master_cmd)(struct dvb_frontend *fe,
struct dvb_diseqc_master_cmd *cmd);
@@ -258,7 +262,6 @@ struct ddb_ci {
struct dvb_ca_en50221 en;
struct ddb_port *port;
u32 nr;
struct mutex lock;
};
struct ddb_io {
@@ -292,7 +295,7 @@ struct ddb_port {
u32 regs;
u32 lnr;
struct ddb_i2c *i2c;
struct mutex i2c_gate_lock;
struct mutex i2c_gate_lock; /* I2C access lock */
u32 class;
#define DDB_PORT_NONE 0
#define DDB_PORT_CI 1
@@ -317,6 +320,7 @@ struct ddb_port {
#define DDB_CI_EXTERNAL_XO2 12
#define DDB_CI_EXTERNAL_XO2_B 13
#define DDB_TUNER_DVBS_STV0910_PR 14
#define DDB_TUNER_DVBC2T2I_SONY_P 15
#define DDB_TUNER_XO2 32
#define DDB_TUNER_DVBS_STV0910 (DDB_TUNER_XO2 + 0)
@@ -324,7 +328,7 @@ struct ddb_port {
#define DDB_TUNER_ISDBT_SONY (DDB_TUNER_XO2 + 2)
#define DDB_TUNER_DVBC2T2_SONY (DDB_TUNER_XO2 + 3)
#define DDB_TUNER_ATSC_ST (DDB_TUNER_XO2 + 4)
#define DDB_TUNER_DVBC2T2_ST (DDB_TUNER_XO2 + 5)
#define DDB_TUNER_DVBC2T2I_SONY (DDB_TUNER_XO2 + 5)
struct ddb_input *input[2];
struct ddb_output *output;
@@ -343,13 +347,11 @@ struct mod_base {
struct ddb_mod {
struct ddb_port *port;
u32 nr;
u32 regs;
u32 frequency;
u32 modulation;
u32 symbolrate;
u64 obitrate;
u64 ibitrate;
u32 pcr_correction;
@@ -403,7 +405,7 @@ struct ddb_ns {
};
struct ddb_lnb {
struct mutex lock;
struct mutex lock; /* lock lnb access */
u32 tone;
fe_sec_voltage_t oldvoltage[4];
u32 voltage[4];
@@ -413,17 +415,17 @@ struct ddb_lnb {
struct ddb_link {
struct ddb *dev;
struct ddb_info *info;
const struct ddb_info *info;
u32 nr;
u32 regs;
spinlock_t lock;
struct mutex flash_mutex;
spinlock_t lock; /* lock link access */
struct mutex flash_mutex; /* lock flash access */
struct ddb_lnb lnb;
struct tasklet_struct tasklet;
struct ddb_ids ids;
spinlock_t temp_lock;
int OverTemperatureError;
spinlock_t temp_lock; /* lock temp chip access */
int over_temperature_error;
u8 temp_tab[11];
};
@@ -465,7 +467,7 @@ struct ddb {
int ns_num;
struct ddb_ns ns[DDB_NS_MAX];
int vlan;
struct mutex mutex;
struct mutex mutex; /* lock accces to global ddb array */
struct dvb_device *nsd_dev;
u8 tsbuf[TS_CAPTURE_LEN];
@@ -475,220 +477,6 @@ struct ddb {
};
static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr)
{
writeb(val, (char *) (dev->regs + (adr)));
}
static inline u32 ddbreadb(struct ddb *dev, u32 adr)
{
return readb((char *) (dev->regs + (adr)));
}
static inline void ddbwritel0(struct ddb_link *link, u32 val, u32 adr)
{
writel(val, (char *) (link->dev->regs + (adr)));
}
static inline u32 ddbreadl0(struct ddb_link *link, u32 adr)
{
return readl((char *) (link->dev->regs + (adr)));
}
#if 0
static inline void gtlw(struct ddb_link *link)
{
u32 count = 0;
static u32 max;
while (1 & ddbreadl0(link, link->regs + 0x10)) {
if (++count == 1024) {
pr_info("LTO\n");
break;
}
}
if (count > max) {
max = count;
pr_info("TO=%u\n", max);
}
if (ddbreadl0(link, link->regs + 0x10) & 0x8000)
pr_err("link error\n");
}
#else
static inline void gtlw(struct ddb_link *link)
{
while (1 & ddbreadl0(link, link->regs + 0x10))
;
}
#endif
static u32 ddblreadl(struct ddb_link *link, u32 adr)
{
if (unlikely(link->nr)) {
unsigned long flags;
u32 val;
spin_lock_irqsave(&link->lock, flags);
gtlw(link);
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
ddbwritel0(link, 3, link->regs + 0x10);
gtlw(link);
val = ddbreadl0(link, link->regs + 0x1c);
spin_unlock_irqrestore(&link->lock, flags);
return val;
}
return readl((char *) (link->dev->regs + (adr)));
}
static void ddblwritel(struct ddb_link *link, u32 val, u32 adr)
{
if (unlikely(link->nr)) {
unsigned long flags;
spin_lock_irqsave(&link->lock, flags);
gtlw(link);
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
ddbwritel0(link, val, link->regs + 0x18);
ddbwritel0(link, 1, link->regs + 0x10);
spin_unlock_irqrestore(&link->lock, flags);
return;
}
writel(val, (char *) (link->dev->regs + (adr)));
}
static u32 ddbreadl(struct ddb *dev, u32 adr)
{
if (unlikely(adr & 0xf0000000)) {
unsigned long flags;
u32 val, l = (adr >> DDB_LINK_SHIFT);
struct ddb_link *link = &dev->link[l];
spin_lock_irqsave(&link->lock, flags);
gtlw(link);
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
ddbwritel0(link, 3, link->regs + 0x10);
gtlw(link);
val = ddbreadl0(link, link->regs + 0x1c);
spin_unlock_irqrestore(&link->lock, flags);
return val;
}
return readl((char *) (dev->regs + (adr)));
}
static void ddbwritel(struct ddb *dev, u32 val, u32 adr)
{
if (unlikely(adr & 0xf0000000)) {
unsigned long flags;
u32 l = (adr >> DDB_LINK_SHIFT);
struct ddb_link *link = &dev->link[l];
spin_lock_irqsave(&link->lock, flags);
gtlw(link);
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
ddbwritel0(link, val, link->regs + 0x18);
ddbwritel0(link, 1, link->regs + 0x10);
spin_unlock_irqrestore(&link->lock, flags);
return;
}
writel(val, (char *) (dev->regs + (adr)));
}
static void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf,
unsigned int count)
{
u32 val = 0, p = adr;
u32 aa = p & 3;
if (aa) {
while (p & 3 && count) {
val >>= 8;
val |= *buf << 24;
p++;
buf++;
count--;
}
ddbwritel(dev, val, adr);
}
while (count >= 4) {
val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
ddbwritel(dev, val, p);
p += 4;
buf += 4;
count -= 4;
}
if (count) {
val = buf[0];
if (count > 1)
val |= buf[1] << 8;
if (count > 2)
val |= buf[2] << 16;
ddbwritel(dev, val, p);
}
}
static void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count)
{
u32 val = 0, p = adr;
u32 a = p & 3;
if (a) {
val = ddbreadl(dev, p) >> (8 * a);
while (p & 3 && count) {
*buf = val & 0xff;
val >>= 8;
p++;
buf++;
count--;
}
}
while (count >= 4) {
val = ddbreadl(dev, p);
buf[0] = val & 0xff;
buf[1] = (val >> 8) & 0xff;
buf[2] = (val >> 16) & 0xff;
buf[3] = (val >> 24) & 0xff;
p += 4;
buf += 4;
count -= 4;
}
if (count) {
val = ddbreadl(dev, p);
buf[0] = val & 0xff;
if (count > 1)
buf[1] = (val >> 8) & 0xff;
if (count > 2)
buf[2] = (val >> 16) & 0xff;
}
}
static void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count)
{
if (unlikely(adr & 0xf0000000))
return gtlcpyto(dev, adr, src, count);
return memcpy_toio((char *) (dev->regs + adr), src, count);
}
static void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count)
{
if (unlikely(adr & 0xf0000000))
return gtlcpyfrom(dev, dst, adr, count);
return memcpy_fromio(dst, (char *) (dev->regs + adr), count);
}
#if 0
#define ddbcpyto(_dev, _adr, _src, _count) \
memcpy_toio((char *) (_dev->regs + (_adr)), (_src), (_count))
#define ddbcpyfrom(_dev, _dst, _adr, _count) \
memcpy_fromio((_dst), (char *) (_dev->regs + (_adr)), (_count))
#endif
#define ddbmemset(_dev, _adr, _val, _count) \
memset_io((char *) (_dev->regs + (_adr)), (_val), (_count))
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
@@ -741,6 +529,17 @@ struct DDMOD_FLASH {
#define DDMOD_FLASH_MAGIC 0x5F564d5F
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
#define DDBRIDGE_VERSION "0.9.32"
/* linked function prototypes */
const struct ddb_info *get_ddb_info(u16 vendor, u16 device,
u16 subvendor, u16 subdevice);
int netstream_init(struct ddb_input *input);
int ddb_dvb_ns_input_start(struct ddb_input *input);
int ddb_dvb_ns_input_stop(struct ddb_input *input);
int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg);
int ddbridge_mod_init(struct ddb *dev);
@@ -748,9 +547,27 @@ void ddbridge_mod_output_stop(struct ddb_output *output);
int ddbridge_mod_output_start(struct ddb_output *output);
void ddbridge_mod_rate_handler(unsigned long data);
void ddb_device_destroy(struct ddb *dev);
void ddb_nsd_detach(struct ddb *dev);
void ddb_ports_detach(struct ddb *dev);
void ddb_ports_release(struct ddb *dev);
void ddb_buffers_free(struct ddb *dev);
void ddb_unmap(struct ddb *dev);
irqreturn_t ddb_irq_handler0(int irq, void *dev_id);
irqreturn_t ddb_irq_handler1(int irq, void *dev_id);
irqreturn_t ddb_irq_handler(int irq, void *dev_id);
irqreturn_t ddb_irq_handler_v2(int irq, void *dev_id);
void ddb_reset_ios(struct ddb *dev);
int ddb_init(struct ddb *dev);
int ddb_class_create(void);
void ddb_class_destroy(void);
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
int ddb_i2c_init(struct ddb *dev);
void ddb_i2c_release(struct ddb *dev);
#define DDBRIDGE_VERSION "0.9.25"
int ddb_ci_attach(struct ddb_port *port, u32 bitrate);
int ddb_fe_attach_mxl5xx(struct ddb_input *input);
int ddb_lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm);
#endif

View File

@@ -1,7 +1,7 @@
/*
* 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>
* Ralph Metzler <rjkm@metzlerbros.de>
*
@@ -17,96 +17,12 @@
*
*
* 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
* along with this program; if not, point your browser to
* http://www.gnu.org/copyleft/gpl.html
*/
#include "ddbridge.h"
#include "ddbridge-regs.h"
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
#include <asm-generic/pci-dma-compat.h>
#else
#include <linux/pci-dma-compat.h>
#endif
static int adapter_alloc = 3;
module_param(adapter_alloc, int, 0444);
MODULE_PARM_DESC(adapter_alloc,
"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all");
#include "ddbridge-core.c"
static struct ddb_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);
}
#include "ddbridge-io.h"
static int __exit octonet_remove(struct platform_device *pdev)
{
@@ -125,7 +41,7 @@ static int __exit octonet_remove(struct platform_device *pdev)
free_irq(platform_get_irq(dev->pfdev, 0), dev);
ddb_ports_release(dev);
octonet_unmap(dev);
ddb_unmap(dev);
platform_set_drvdata(pdev, 0);
return 0;
}
@@ -136,7 +52,7 @@ static int __init octonet_probe(struct platform_device *pdev)
struct resource *regs;
int irq;
dev = vzalloc(sizeof(struct ddb));
dev = vzalloc(sizeof(*dev));
if (!dev)
return -ENOMEM;
platform_set_drvdata(pdev, dev);
@@ -149,7 +65,7 @@ static int __init octonet_probe(struct platform_device *pdev)
return -ENXIO;
dev->regs_len = (regs->end - regs->start) + 1;
dev_info(dev->dev, "regs_start=%08x regs_len=%08x\n",
(u32) regs->start, (u32) dev->regs_len);
(u32)regs->start, (u32)dev->regs_len);
dev->regs = ioremap(regs->start, dev->regs_len);
if (!dev->regs) {
@@ -168,19 +84,13 @@ static int __init octonet_probe(struct platform_device *pdev)
dev->link[0].ids.subdevice = dev->link[0].ids.devid >> 16;
dev->link[0].dev = dev;
if (dev->link[0].ids.devid == 0x0300dd01)
dev->link[0].info = &ddb_octonet;
else if (dev->link[0].ids.devid == 0x0301dd01)
dev->link[0].info = &ddb_octonet_jse;
else if (dev->link[0].ids.devid == 0x0307dd01)
dev->link[0].info = &ddb_octonet_gtl;
else
dev->link[0].info = &ddb_octonet_tbd;
pr_info("HW %08x REGMAP %08x\n",
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
pr_info("MAC %08x DEVID %08x\n",
dev->link[0].ids.mac, dev->link[0].ids.devid);
dev->link[0].info = get_ddb_info(dev->link[0].ids.vendor,
dev->link[0].ids.device,
0xdd01, 0xffff);
dev_info(dev->dev, "DDBridge: HW %08x REGMAP %08x\n",
dev->link[0].ids.hwid, dev->link[0].ids.regmapid);
dev_info(dev->dev, "DDBridge: MAC %08x DEVID %08x\n",
dev->link[0].ids.mac, dev->link[0].ids.devid);
ddbwritel(dev, 0, ETHER_CONTROL);
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
@@ -190,9 +100,9 @@ static int __init octonet_probe(struct platform_device *pdev)
irq = platform_get_irq(dev->pfdev, 0);
if (irq < 0)
goto fail;
if (request_irq(irq, irq_handler,
if (request_irq(irq, ddb_irq_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
"octonet-dvb", (void *) dev) < 0)
"octonet-dvb", (void *)dev) < 0)
goto fail;
ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE);
@@ -203,7 +113,7 @@ fail:
dev_err(dev->dev, "fail\n");
ddbwritel(dev, 0, ETHER_CONTROL);
ddbwritel(dev, 0, INTERRUPT_ENABLE);
octonet_unmap(dev);
ddb_unmap(dev);
platform_set_drvdata(pdev, 0);
return -1;
}
@@ -217,7 +127,7 @@ static const struct of_device_id octonet_dt_ids[] = {
MODULE_DEVICE_TABLE(of, octonet_dt_ids);
#endif
static struct platform_driver octonet_driver = {
static struct platform_driver octonet_driver __refdata = {
.remove = __exit_p(octonet_remove),
.probe = octonet_probe,
.driver = {
@@ -233,7 +143,7 @@ static __init int init_octonet(void)
{
int res;
pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION
pr_info("DDBridge: Digital Devices OctopusNet driver " DDBRIDGE_VERSION
", Copyright (C) 2010-16 Digital Devices GmbH\n");
res = ddb_class_create();
if (res)
@@ -258,4 +168,4 @@ module_exit(exit_octonet);
MODULE_DESCRIPTION("GPL");
MODULE_AUTHOR("Marcus and Ralph Metzler, Metzler Brothers Systementwicklung GbR");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.6");
MODULE_VERSION(DDBRIDGE_VERSION);

29
dvb-core/Kconfig Normal file
View File

@@ -0,0 +1,29 @@
#
# DVB device configuration
#
config DVB_MAX_ADAPTERS
int "maximum number of DVB/ATSC adapters"
depends on DVB_CORE
default 8
range 1 255
help
Maximum number of DVB/ATSC adapters. Increasing this number
increases the memory consumption of the DVB subsystem even
if a much lower number of DVB/ATSC adapters is present.
Only values in the range 4-32 are tested.
If you are unsure about this, use the default value 8
config DVB_DYNAMIC_MINORS
bool "Dynamic DVB minor allocation"
depends on DVB_CORE
default n
help
If you say Y here, the DVB subsystem will use dynamic minor
allocation for any device that uses the DVB major number.
This means that you can have more than 4 of a single type
of device (like demuxes and frontends) per adapter, but udev
will be required to manage the device nodes.
If you are unsure about this, say N here.

12
dvb-core/Makefile.kernel Normal file
View File

@@ -0,0 +1,12 @@
#
# Makefile for the kernel DVB device drivers.
#
dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
dvb_ca_en50221.o dvb_frontend.o \
$(dvb-net-y) dvb_ringbuffer.o dvb_math.o \
dvb_netstream.o
obj-$(CONFIG_DVB_CORE) += dvb-core.o

View File

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

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>
#endif
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>

View File

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

View File

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

View File

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

838
frontends/Kconfig Normal file
View File

@@ -0,0 +1,838 @@
menu "Customise DVB Frontends"
visible if !MEDIA_SUBDRV_AUTOSELECT
comment "Multistandard (satellite) frontends"
depends on DVB_CORE
config DVB_STB0899
tristate "STB0899 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/S2/DSS Multistandard demodulator. Say Y when you want
to support this demodulator based frontends
config DVB_STB6100
tristate "STB6100 based tuners"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A Silicon tuner from ST used in conjunction with the STB0899
demodulator. Say Y when you want to support this tuner.
config DVB_STV090x
tristate "STV0900/STV0903(A/B) based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
Say Y when you want to support these frontends.
config DVB_STV6110x
tristate "STV6110/(A) based tuners"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A Silicon tuner that supports DVB-S and DVB-S2 modes
config DVB_STV0910
tristate "STV0910 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
Say Y when you want to support these frontends.
config DVB_MXL5XX
tristate "MXL5XX based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
DVB-S/S2/DSS Multistandard Professional/Broadcast demodulators.
Say Y when you want to support these frontends.
config DVB_STV6111
tristate "STV6111 based tuners"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A Silicon tuner that supports DVB-S and DVB-S2 modes
config DVB_M88DS3103
tristate "Montage M88DS3103"
depends on DVB_CORE && I2C && I2C_MUX
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
comment "Multistandard (cable + terrestrial) frontends"
depends on DVB_CORE
config DVB_DRXK
tristate "Micronas DRXK based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Micronas DRX-K DVB-C/T demodulator.
Say Y when you want to support this frontend.
config DVB_TDA18271C2DD
tristate "NXP TDA18271C2 silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
NXP TDA18271 silicon tuner.
Say Y when you want to support this tuner.
config DVB_SI2165
tristate "Silicon Labs si2165 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C/T demodulator.
Say Y when you want to support this frontend.
comment "DVB-S (satellite) frontends"
depends on DVB_CORE
config DVB_CX24110
tristate "Conexant CX24110 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_CX24123
tristate "Conexant CX24123 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_MT312
tristate "Zarlink VP310/MT312/ZL10313 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_ZL10036
tristate "Zarlink ZL10036 silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_ZL10039
tristate "Zarlink ZL10039 silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_S5H1420
tristate "Samsung S5H1420 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_STV0288
tristate "ST STV0288 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_STB6000
tristate "ST STB6000 silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_STV0299
tristate "ST STV0299 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_STV6110
tristate "ST STV6110 silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_STV0900
tristate "ST STV0900 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/S2 demodulator. Say Y when you want to support this frontend.
config DVB_TDA8083
tristate "Philips TDA8083 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TDA10086
tristate "Philips TDA10086 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TDA8261
tristate "Philips TDA8261 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_VES1X93
tristate "VLSI VES1893 or VES1993 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TUNER_ITD1000
tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TUNER_CX24113
tristate "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TDA826X
tristate "Philips TDA826X silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S silicon tuner module. Say Y when you want to support this tuner.
config DVB_TUA6100
tristate "Infineon TUA6100 PLL"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S PLL chip.
config DVB_CX24116
tristate "Conexant CX24116 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
config DVB_CX24117
tristate "Conexant CX24117 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A Dual DVB-S/S2 tuner module. Say Y when you want to support this frontend.
config DVB_SI21XX
tristate "Silicon Labs SI21XX based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_TS2020
tristate "Montage Tehnology TS2020 based tuners"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/S2 silicon tuner. Say Y when you want to support this tuner.
config DVB_DS3000
tristate "Montage Tehnology DS3000 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
config DVB_MB86A16
tristate "Fujitsu MB86A16 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S/DSS Direct Conversion reveiver.
Say Y when you want to support this frontend.
config DVB_TDA10071
tristate "NXP TDA10071"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
comment "DVB-T (terrestrial) frontends"
depends on DVB_CORE
config DVB_SP8870
tristate "Spase sp8870 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
This driver needs external firmware. Please use the command
"<kerneldir>/Documentation/dvb/get_dvb_firmware sp8870" to
download/extract it, and then copy it to /usr/lib/hotplug/firmware
or /lib/firmware (depending on configuration of firmware hotplug).
config DVB_SP887X
tristate "Spase sp887x based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
This driver needs external firmware. Please use the command
"<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to
download/extract it, and then copy it to /usr/lib/hotplug/firmware
or /lib/firmware (depending on configuration of firmware hotplug).
config DVB_CX22700
tristate "Conexant CX22700 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_CX22702
tristate "Conexant cx22702 demodulator (OFDM)"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_S5H1432
tristate "Samsung s5h1432 demodulator (OFDM)"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_DRXD
tristate "Micronas DRXD driver"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
Note: this driver was based on vendor driver reference code (released
under the GPL) as opposed to the existing drx397xd driver, which
was written via reverse engineering.
config DVB_L64781
tristate "LSI L64781"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_TDA1004X
tristate "Philips TDA10045H/TDA10046H based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
This driver needs external firmware. Please use the commands
"<kerneldir>/Documentation/dvb/get_dvb_firmware tda10045",
"<kerneldir>/Documentation/dvb/get_dvb_firmware tda10046" to
download/extract them, and then copy them to /usr/lib/hotplug/firmware
or /lib/firmware (depending on configuration of firmware hotplug).
config DVB_NXT6000
tristate "NxtWave Communications NXT6000 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_MT352
tristate "Zarlink MT352 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_ZL10353
tristate "Zarlink ZL10353 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_DIB3000MB
tristate "DiBcom 3000M-B"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
config DVB_DIB3000MC
tristate "DiBcom 3000P/M-C"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
config DVB_DIB7000M
tristate "DiBcom 7000MA/MB/PA/PB/MC"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
config DVB_DIB7000P
tristate "DiBcom 7000PC"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
config DVB_DIB9000
tristate "DiBcom 9000"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
config DVB_TDA10048
tristate "Philips TDA10048HN based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_TDA18212DD
tristate "Philips TDA18212 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T tuner module. Say Y when you want to support this frontend.
config DVB_AF9013
tristate "Afatech AF9013 demodulator"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_EC100
tristate "E3C EC100"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_HD29L2
tristate "HDIC HD29L2"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_STV0367
tristate "ST STV0367 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T/C tuner module. Say Y when you want to support this frontend.
config DVB_STV0367DD
tristate "ST STV0367dd based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T/C tuner module. Say Y when you want to support this frontend.
config DVB_CXD2843
tristate "Sony CXD2843"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-T/T2/C/C2 tuner module. Say Y when you want to support this frontend.
config DVB_CXD2820R
tristate "Sony CXD2820R"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_RTL2830
tristate "Realtek RTL2830 DVB-T"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_RTL2832
tristate "Realtek RTL2832 DVB-T"
depends on DVB_CORE && I2C && I2C_MUX
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
config DVB_RTL2832_SDR
tristate "Realtek RTL2832 SDR"
depends on DVB_CORE && I2C && I2C_MUX && VIDEO_V4L2 && MEDIA_SDR_SUPPORT && USB
select DVB_RTL2832
select VIDEOBUF2_VMALLOC
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this SDR module.
config DVB_SI2168
tristate "Silicon Labs Si2168"
depends on DVB_CORE && I2C && I2C_MUX
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Say Y when you want to support this frontend.
comment "DVB-C (cable) frontends"
depends on DVB_CORE
config DVB_VES1820
tristate "VLSI VES1820 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_TDA10021
tristate "Philips TDA10021 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_TDA10023
tristate "Philips TDA10023 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C tuner module. Say Y when you want to support this frontend.
config DVB_STV0297
tristate "ST STV0297 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-C tuner module. Say Y when you want to support this frontend.
comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
depends on DVB_CORE
config DVB_NXT200X
tristate "NxtWave Communications NXT2002/NXT2004 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
This driver needs external firmware. Please use the commands
"<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" and
"<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
download/extract them, and then copy them to /usr/lib/hotplug/firmware
or /lib/firmware (depending on configuration of firmware hotplug).
config DVB_OR51211
tristate "Oren OR51211 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
This driver needs external firmware. Please use the command
"<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
download it, and then copy it to /usr/lib/hotplug/firmware
or /lib/firmware (depending on configuration of firmware hotplug).
config DVB_OR51132
tristate "Oren OR51132 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
This driver needs external firmware. Please use the commands
"<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_vsb" and/or
"<kerneldir>/Documentation/dvb/get_dvb_firmware or51132_qam" to
download firmwares for 8VSB and QAM64/256, respectively. Copy them to
/usr/lib/hotplug/firmware or /lib/firmware (depending on
configuration of firmware hotplug).
config DVB_BCM3510
tristate "Broadcom BCM3510"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
support this frontend.
config DVB_LGDT330X
tristate "LG Electronics LGDT3302/LGDT3303 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
config DVB_LGDT3305
tristate "LG Electronics LGDT3304 and LGDT3305 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
config DVB_LG2160
tristate "LG Electronics LG216x based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC/MH demodulator module. Say Y when you want
to support this frontend.
config DVB_S5H1409
tristate "Samsung S5H1409 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
config DVB_AU8522
depends on I2C
tristate
config DVB_AU8522_DTV
tristate "Auvitek AU8522 based DTV demod"
depends on DVB_CORE && I2C
select DVB_AU8522
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
you want to enable DTV demodulation support for this frontend.
config DVB_AU8522_V4L
tristate "Auvitek AU8522 based ATV demod"
depends on VIDEO_V4L2 && I2C
select DVB_AU8522
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when
you want to enable ATV demodulation support for this frontend.
config DVB_S5H1411
tristate "Samsung S5H1411 based"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
comment "ISDB-T (terrestrial) frontends"
depends on DVB_CORE
config DVB_S921
tristate "Sharp S921 frontend"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
Say Y when you want to support this frontend.
config DVB_DIB8000
tristate "DiBcom 8000MB/MC"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend.
config DVB_MB86A20S
tristate "Fujitsu mb86a20s"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for Fujitsu mb86a20s ISDB-T/ISDB-Tsb demodulator.
Say Y when you want to support this frontend.
comment "Digital terrestrial only tuners/PLL"
depends on DVB_CORE
config DVB_PLL
tristate "Generic I2C PLL based tuners"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
This module drives a number of tuners based on PLL chips with a
common I2C interface. Say Y when you want to support these tuners.
config DVB_TUNER_DIB0070
tristate "DiBcom DiB0070 silicon base-band tuner"
depends on I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon baseband tuner DiB0070 from DiBcom.
This device is only used inside a SiP called together with a
demodulator for now.
config DVB_TUNER_DIB0090
tristate "DiBcom DiB0090 silicon base-band tuner"
depends on I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A driver for the silicon baseband tuner DiB0090 from DiBcom.
This device is only used inside a SiP called together with a
demodulator for now.
comment "SEC control devices for DVB-S"
depends on DVB_CORE
source "drivers/media/dvb-frontends/drx39xyj/Kconfig"
config DVB_LNBP21
tristate "LNBP21/LNBH24 SEC controllers"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An SEC control chips.
config DVB_LNBH25
tristate "LNBH25 SEC controllers"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An SEC control chips.
config DVB_LNBP22
tristate "LNBP22 SEC controllers"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
LNB power supply and control voltage
regulator chip with step-up converter
and I2C interface.
Say Y when you want to support this chip.
config DVB_ISL6405
tristate "ISL6405 SEC controller"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An SEC control chip.
config DVB_ISL6421
tristate "ISL6421 SEC controller"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
An SEC control chip.
config DVB_ISL6423
tristate "ISL6423 SEC controller"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A SEC controller chip from Intersil
config DVB_A8293
tristate "Allegro A8293"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
config DVB_LGS8GL5
tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DMB-TH tuner module. Say Y when you want to support this frontend.
config DVB_LGS8GXX
tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator"
depends on DVB_CORE && I2C
select FW_LOADER
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DMB-TH tuner module. Say Y when you want to support this frontend.
config DVB_ATBM8830
tristate "AltoBeam ATBM8830/8831 DMB-TH demodulator"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DMB-TH tuner module. Say Y when you want to support this frontend.
config DVB_TDA665x
tristate "TDA665x tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
Support for tuner modules based on Philips TDA6650/TDA6651 chips.
Say Y when you want to support this chip.
Currently supported tuners:
* Panasonic ENV57H12D5 (ET-50DT)
config DVB_IX2505V
tristate "Sharp IX2505V silicon tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module. Say Y when you want to support this frontend.
config DVB_M88RS2000
tristate "M88RS2000 DVB-S demodulator and tuner"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
help
A DVB-S tuner module.
Say Y when you want to support this frontend.
config DVB_AF9033
tristate "Afatech AF9033 DVB-T demodulator"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
config DVB_CXD2099
tristate "cxd2099"
depends on DVB_CORE && I2C
default m if !MEDIA_SUBDRV_AUTOSELECT
comment "Tools to develop new frontends"
config DVB_DUMMY_FE
tristate "Dummy frontend driver"
default n
endmenu

123
frontends/Makefile.kernel Normal file
View File

@@ -0,0 +1,123 @@
#
# Makefile for the kernel DVB frontend device drivers.
#
ccflags-y += -I$(srctree)/drivers/media/dvb-core/
ccflags-y += -I$(srctree)/drivers/media/tuners/
# FIXME: RTL2832 SDR driver uses power management directly from USB IF driver
ifdef CONFIG_DVB_RTL2832_SDR
ccflags-y += -I$(srctree)/drivers/media/usb/dvb-usb-v2
endif
stb0899-objs := stb0899_drv.o stb0899_algo.o
stv0900-objs := stv0900_core.o stv0900_sw.o
drxd-objs := drxd_firm.o drxd_hard.o
cxd2820r-objs := cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
drxk-objs := drxk_hard.o
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
obj-$(CONFIG_DVB_STV0299) += stv0299.o
obj-$(CONFIG_DVB_STB0899) += stb0899.o
obj-$(CONFIG_DVB_STB6100) += stb6100.o
obj-$(CONFIG_DVB_SP8870) += sp8870.o
obj-$(CONFIG_DVB_CX22700) += cx22700.o
obj-$(CONFIG_DVB_S5H1432) += s5h1432.o
obj-$(CONFIG_DVB_CX24110) += cx24110.o
obj-$(CONFIG_DVB_TDA8083) += tda8083.o
obj-$(CONFIG_DVB_L64781) += l64781.o
obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o
obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o
obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o
obj-$(CONFIG_DVB_DIB9000) += dib9000.o dibx000_common.o
obj-$(CONFIG_DVB_MT312) += mt312.o
obj-$(CONFIG_DVB_VES1820) += ves1820.o
obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o
obj-$(CONFIG_DVB_SP887X) += sp887x.o
obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
obj-$(CONFIG_DVB_MT352) += mt352.o
obj-$(CONFIG_DVB_ZL10036) += zl10036.o
obj-$(CONFIG_DVB_ZL10039) += zl10039.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
obj-$(CONFIG_DVB_DRXD) += drxd.o
obj-$(CONFIG_DVB_TDA10021) += tda10021.o
obj-$(CONFIG_DVB_TDA10023) += tda10023.o
obj-$(CONFIG_DVB_STV0297) += stv0297.o
obj-$(CONFIG_DVB_NXT200X) += nxt200x.o
obj-$(CONFIG_DVB_OR51211) += or51211.o
obj-$(CONFIG_DVB_OR51132) += or51132.o
obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
obj-$(CONFIG_DVB_LG2160) += lg2160.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_LNBP22) += lnbp22.o
obj-$(CONFIG_DVB_ISL6405) += isl6405.o
obj-$(CONFIG_DVB_ISL6421) += isl6421.o
obj-$(CONFIG_DVB_TDA10086) += tda10086.o
obj-$(CONFIG_DVB_TDA826X) += tda826x.o
obj-$(CONFIG_DVB_TDA8261) += tda8261.o
obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o
obj-$(CONFIG_DVB_TUA6100) += tua6100.o
obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
obj-$(CONFIG_DVB_AU8522) += au8522_common.o
obj-$(CONFIG_DVB_AU8522_DTV) += au8522_dig.o
obj-$(CONFIG_DVB_AU8522_V4L) += au8522_decoder.o
obj-$(CONFIG_DVB_TDA10048) += tda10048.o
obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
obj-$(CONFIG_DVB_TDA665x) += tda665x.o
obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
obj-$(CONFIG_DVB_AF9013) += af9013.o
obj-$(CONFIG_DVB_CX24116) += cx24116.o
obj-$(CONFIG_DVB_CX24117) += cx24117.o
obj-$(CONFIG_DVB_SI21XX) += si21xx.o
obj-$(CONFIG_DVB_SI2168) += si2168.o
obj-$(CONFIG_DVB_STV0288) += stv0288.o
obj-$(CONFIG_DVB_STB6000) += stb6000.o
obj-$(CONFIG_DVB_S921) += s921.o
obj-$(CONFIG_DVB_STV6110) += stv6110.o
obj-$(CONFIG_DVB_STV0900) += stv0900.o
obj-$(CONFIG_DVB_STV090x) += stv090x.o
obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
obj-$(CONFIG_DVB_M88DS3103) += m88ds3103.o
obj-$(CONFIG_DVB_ISL6423) += isl6423.o
obj-$(CONFIG_DVB_EC100) += ec100.o
obj-$(CONFIG_DVB_HD29L2) += hd29l2.o
obj-$(CONFIG_DVB_DS3000) += ds3000.o
obj-$(CONFIG_DVB_TS2020) += ts2020.o
obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
obj-$(CONFIG_DVB_DRX39XYJ) += drx39xyj/
obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
obj-$(CONFIG_DVB_STV0367) += stv0367.o
obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
obj-$(CONFIG_DVB_DRXK) += drxk.o
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
obj-$(CONFIG_DVB_SI2165) += si2165.o
obj-$(CONFIG_DVB_A8293) += a8293.o
obj-$(CONFIG_DVB_TDA10071) += tda10071.o
obj-$(CONFIG_DVB_RTL2830) += rtl2830.o
obj-$(CONFIG_DVB_RTL2832) += rtl2832.o
obj-$(CONFIG_DVB_RTL2832_SDR) += rtl2832_sdr.o
obj-$(CONFIG_DVB_M88RS2000) += m88rs2000.o
obj-$(CONFIG_DVB_AF9033) += af9033.o
obj-$(CONFIG_DVB_STV0367DD) += stv0367dd.o
obj-$(CONFIG_DVB_TDA18212DD) += tda18212dd.o
obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
obj-$(CONFIG_DVB_CXD2843) += cxd2843.o
obj-$(CONFIG_DVB_STV6111) += stv6111.o
obj-$(CONFIG_DVB_STV0910) += stv0910.o
obj-$(CONFIG_DVB_LNBH25) += lnbh25.o
obj-$(CONFIG_DVB_MXL5XX) += mxl5xx.o

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)
{
struct cxd *ci = ca->data;
int status;
if (ci->write_busy)
return -EAGAIN;
mutex_lock(&ci->lock);
write_reg(ci, 0x0d, ecount >> 8);
write_reg(ci, 0x0e, ecount & 0xff);
write_block(ci, 0x11, ebuf, ecount);
ci->write_busy = 1;
status = write_block(ci, 0x11, ebuf, ecount);
if (!status)
ci->write_busy = 1;
mutex_unlock(&ci->lock);
if (status)
return status;
return ecount;
}
#endif

View File

@@ -96,7 +96,7 @@ static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
struct i2c_msg msg = {
.addr = adr, .flags = 0, .buf = data, .len = len};
if (i2c_transfer(adap, &msg, 1) != 1) {
pr_err("cxd2843: i2c_write error\n");
pr_err("cxd2843: i2c_write error adr %02x data %02x\n", adr, data[0]);
return -1;
}
return 0;
@@ -270,9 +270,10 @@ static int writebitsx(struct cxd_state *cxd, u8 Bank, u8 Address,
mutex_lock(&cxd->mutex);
status = readregsx_unlocked(cxd, Bank, Address, &tmp, 1);
if (status < 0)
return status;
goto out;
tmp = (tmp & ~Mask) | Value;
status = writeregsx_unlocked(cxd, Bank, Address, &tmp, 1);
out:
mutex_unlock(&cxd->mutex);
return status;
}
@@ -286,9 +287,10 @@ static int writebitst(struct cxd_state *cxd, u8 Bank, u8 Address,
mutex_lock(&cxd->mutex);
status = readregst_unlocked(cxd, Bank, Address, &Tmp, 1);
if (status < 0)
return status;
goto out;
Tmp = (Tmp & ~Mask) | Value;
status = writeregst_unlocked(cxd, Bank, Address, &Tmp, 1);
out:
mutex_unlock(&cxd->mutex);
return status;
}
@@ -508,8 +510,12 @@ static void ActiveC2_to_Sleep(struct cxd_state *state)
writebitst(state, 0x2B, 0x2B, 0x00, 0x1F);
{
u8 data[2] = { 0x75, 0x75 };
u8 data24[2] = { 0x89, 0x89 };
writeregst(state, 0x2D, 0x24, data, sizeof(data));
if (state->is24MHz)
writeregst(state, 0x2D, 0x24, data24, sizeof(data24));
else
writeregst(state, 0x2D, 0x24, data, sizeof(data));
}
writeregx(state, 0x00, 0x18, 0x01); /* Disable ADC 4 */
@@ -554,62 +560,115 @@ static int ConfigureTS(struct cxd_state *state,
return status;
}
#if 0
static int set_tr(struct cxd_state *state, u32 bw, u32 osc24)
{
u64 tr = 7 *(osc24 ? 0x1800000000 : 0x1480000000);
div64_32(tr, bw);
printk("TR %016llx\n", tr);
return 0;
}
#endif
static void BandSettingT(struct cxd_state *state, u32 iffreq)
{
u8 IF_data[3] = { (iffreq >> 16) & 0xff,
(iffreq >> 8) & 0xff, iffreq & 0xff};
u8 data[] = { 0x01, 0x14 };
writeregst(state, 0x13, 0x9c, data, sizeof(data));
switch (state->bw) {
default:
case 8:
{
u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 };
u8 CL_data[] = { 0x01, 0xE0 };
u8 NF_data[] = { 0x01, 0x02 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
if (state->is24MHz) {
u8 TR_data[] = { 0x15, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x00, 0x07);
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
if (state->is24MHz) {
u8 CL_data[] = { 0x15, 0x28 };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
} else {
u8 CL_data[] = { 0x01, 0xE0 };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
}
writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data));
break;
}
case 7:
{
u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 };
u8 CL_data[] = { 0x12, 0xF8 };
u8 NF_data[] = { 0x00, 0x03 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
if (state->is24MHz) {
u8 TR_data[] = { 0x18, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x02, 0x07);
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
if (state->is24MHz) {
u8 CL_data[] = { 0x1f, 0xf8 };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
} else {
u8 CL_data[] = { 0x12, 0xF8 };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
}
writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data));
break;
}
case 6:
{
u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA };
u8 CL_data[] = { 0x1F, 0xDC };
u8 NF_data[] = { 0x00, 0x03 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
if (state->is24MHz) {
u8 TR_data[] = { 0x1c, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x04, 0x07);
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
if (state->is24MHz) {
u8 CL_data[] = { 0x25, 0x4c };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
} else {
u8 CL_data[] = { 0x1F, 0xDC };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
}
writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data));
break;
}
case 5:
{
static u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 };
static u8 CL_data[] = { 0x26, 0x3C };
static u8 NF_data[] = { 0x00, 0x03 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
if (state->is24MHz) {
u8 TR_data[] = { 0x21, 0x99, 0x99, 0x99, 0x99 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
} else {
static u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x06, 0x07);
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
if (state->is24MHz) {
static u8 CL_data[] = { 0x2c, 0xc2 };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
} else {
static u8 CL_data[] = { 0x26, 0x3C };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
}
writeregst(state, 0x17, 0x38, NF_data, sizeof(NF_data));
break;
}
@@ -626,7 +685,7 @@ static void Sleep_to_ActiveT(struct cxd_state *state, u32 iffreq)
writeregt(state, 0x00, 0x30, 0x00); /* Enable ADC Clock */
writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */
{
u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */
u8 data[2] = { 0x09, 0x54 }; /* 20.5/24 MHz */
/*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */
writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */
@@ -634,7 +693,7 @@ static void Sleep_to_ActiveT(struct cxd_state *state, u32 iffreq)
writeregx(state, 0x00, 0x18, 0x00); /* Enable ADC 4 */
writebitst(state, 0x10, 0xD2, 0x0C, 0x1F); /* IF AGC Gain */
writeregt(state, 0x11, 0x6A, 0x48); /* BB AGC Target Level */
writeregt(state, 0x11, 0x6A, 0x50); /* BB AGC Target Level */
writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */
@@ -645,6 +704,13 @@ static void Sleep_to_ActiveT(struct cxd_state *state, u32 iffreq)
writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */
writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/
if (state->is24MHz) {
u8 data[3] = { 0xdc, 0x6c, 0x00 };
writeregt(state, 0x10, 0xbf, 0x60);
writeregst(state, 0x18, 0x24, data, 3);
}
BandSettingT(state, iffreq);
writebitst(state, 0x10, 0x60, 0x11, 0x1f); /* BER scaling */
@@ -662,10 +728,16 @@ static void BandSettingT2(struct cxd_state *state, u32 iffreq)
default:
case 8:
{
u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 };
/* Timing recovery */
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
if (state->is24MHz) {
u8 TR_data[] = { 0x15, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
/* Add EQ Optimisation for tuner here */
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
/* System Bandwidth */
@@ -674,36 +746,60 @@ static void BandSettingT2(struct cxd_state *state, u32 iffreq)
break;
case 7:
{
u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 };
if (state->is24MHz) {
u8 TR_data[] = { 0x18, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x14, 0x80, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x02, 0x07);
}
break;
case 6:
{
u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA };
if (state->is24MHz) {
u8 TR_data[] = { 0x1c, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x04, 0x07);
}
break;
case 5:
{
u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 };
if (state->is24MHz) {
u8 TR_data[] = { 0x21, 0x99, 0x99, 0x99, 0x99 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x1C, 0xB3, 0x33, 0x33, 0x33 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x06, 0x07);
}
break;
case 2: /* 1.7 MHz */
{
u8 TR_data[] = { 0x58, 0xE2, 0xAF, 0xE0, 0xBC };
if (state->is24MHz) {
u8 TR_data[] = { 0x68, 0x0f, 0xa2, 0x32, 0xd0 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x58, 0xE2, 0xAF, 0xE0, 0xBC };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x03, 0x07);
}
@@ -724,7 +820,7 @@ static void Sleep_to_ActiveT2(struct cxd_state *state, u32 iffreq)
writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */
{
u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */
u8 data[2] = { 0x09, 0x54 }; /* 20.5/24 MHz */
/*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */
writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */
@@ -737,6 +833,7 @@ static void Sleep_to_ActiveT2(struct cxd_state *state, u32 iffreq)
writeregt(state, 0x20, 0x8B, 0x3C); /* SNR Good count */
writebitst(state, 0x2B, 0x76, 0x20, 0x70); /* Noise Gain ACQ */
writebitst(state, 0x23, 0xe6, 0x00, 0x03);
writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */
writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/
@@ -745,7 +842,34 @@ static void Sleep_to_ActiveT2(struct cxd_state *state, u32 iffreq)
writeregt(state, 0x13, 0x86, 0x34);
writebitst(state, 0x13, 0x9E, 0x09, 0x0F);
writeregt(state, 0x13, 0x9F, 0xD8);
writebitst(state, 0x23, 0x11, 0x20, 0x3F);
if (state->is24MHz ) {
static u8 data1[] = { 0xEB, 0x03, 0x3B };
static u8 data2[] = { 0x5E, 0x5E, 0x47 };
static u8 data3[] = { 0x3F, 0xFF };
static u8 data4[] = { 0x0B, 0x72 };
static u8 data5[] = { 0x93, 0xF3, 0x00 };
static u8 data6[] = { 0x05, 0xB8, 0xD8 };
static u8 data7[] = { 0x89, 0x89 };
static u8 data8[] = { 0x24, 0x95 };
writeregst(state, 0x11, 0x33, data1, sizeof(data1));
writeregst(state, 0x20, 0x95, data2, sizeof(data2));
writeregt(state, 0x20, 0x99, 0x18);
writeregst(state, 0x20, 0xD9, data3, sizeof(data3));
writeregst(state, 0x24, 0x34, data4, sizeof(data4));
writeregst(state, 0x24, 0xD2, data5, sizeof(data5));
writeregst(state, 0x24, 0xDD, data6, sizeof(data6));
writeregt(state, 0x24, 0xE0, 0x00);
writeregt(state, 0x25, 0xED, 0x60);
writeregt(state, 0x27, 0xFA, 0x34);
writeregt(state, 0x2B, 0x4B, 0x2F);
writeregt(state, 0x2B, 0x9E, 0x0E);
writeregst(state, 0x2D, 0x24, data7, sizeof(data7));
writeregst(state, 0x5E, 0x8C, data8, sizeof(data8));
}
BandSettingT2(state, iffreq);
writebitst(state, 0x20, 0x72, 0x08, 0x0f); /* BER scaling */
@@ -777,7 +901,7 @@ static void Sleep_to_ActiveC(struct cxd_state *state, u32 iffreq)
writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */
{
u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */
u8 data[2] = { 0x09, 0x54 }; /* 20.5/24 MHz */
/*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */
writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */
@@ -793,6 +917,18 @@ static void Sleep_to_ActiveC(struct cxd_state *state, u32 iffreq)
writebitst(state, 0x00, 0xCE, 0x01, 0x01); /* TSIF ONOPARITY */
writebitst(state, 0x00, 0xCF, 0x01, 0x01);/*TSIF ONOPARITY_MANUAL_ON*/
if (state->is24MHz) {
u8 data1[2] = { 0x29, 0x09 };
u8 data2[4] = { 0x08, 0x38, 0x83, 0x0E };
u8 data3[3] = { 0xDC, 0x6C, 0x00 };
u8 data4[2] = { 0x77, 0x00 };
writeregst(state,0x40,0x54,data1,2);
writeregst(state,0x40,0x8b,data2,4);
writeregt(state,0x40,0xBF,0x60);
writeregst(state,0x48,0x24,data3,2);
writeregst(state,0x49,0x11,data4,2);
}
BandSettingC(state, iffreq);
writebitst(state, 0x40, 0x60, 0x11, 0x1f); /* BER scaling */
@@ -810,28 +946,57 @@ static void BandSettingC2(struct cxd_state *state, u32 iffreq)
default:
case 8:
{
u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 };
u8 data[2] = { 0x11, 0x9E };
if (state->is24MHz) {
u8 TR_data[] = { 0x15, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x11, 0xF0, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writebitst(state, 0x27, 0x7a, 0x00, 0x0f);
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x00, 0x07);
writeregst(state, 0x50, 0xEC, data, sizeof(data));
writeregt(state, 0x50, 0xEF, 0x11);
writeregt(state, 0x50, 0xF1, 0x9E);
if (state->is24MHz) {
u8 data[2] = { 0x14, 0xa0 };
writeregst(state, 0x50, 0xEC, data, sizeof(data));
writeregt(state, 0x50, 0xEF, 0x14);
writeregt(state, 0x50, 0xF1, 0xa0);
} else {
u8 data[2] = { 0x11, 0x9E };
writeregst(state, 0x50, 0xEC, data, sizeof(data));
writeregt(state, 0x50, 0xEF, 0x11);
writeregt(state, 0x50, 0xF1, 0x9E);
}
}
break;
case 6:
{
u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA };
u8 data[2] = { 0x17, 0x70 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
if (state->is24MHz) {
u8 TR_data[] = { 0x1c, 0x00, 0x00, 0x00, 0x00 };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x17, 0xEA, 0xAA, 0xAA, 0xAA };
writeregst(state, 0x20, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x04, 0x07);
writeregst(state, 0x50, 0xEC, data, sizeof(data));
writeregt(state, 0x50, 0xEF, 0x17);
writeregt(state, 0x50, 0xF1, 0x70);
if (state->is24MHz) {
u8 data[2] = { 0x1b, 0x70 };
writeregst(state, 0x50, 0xEC, data, sizeof(data));
writeregt(state, 0x50, 0xEF, 0x1b);
writeregt(state, 0x50, 0xF1, 0x70);
} else {
u8 data[2] = { 0x17, 0x70 };
writeregst(state, 0x50, 0xEC, data, sizeof(data));
writeregt(state, 0x50, 0xEF, 0x17);
writeregt(state, 0x50, 0xF1, 0x70);
}
}
break;
}
@@ -849,7 +1014,7 @@ static void Sleep_to_ActiveC2(struct cxd_state *state, u32 iffreq)
writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */
{
u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz */
u8 data[2] = { 0x09, 0x54 }; /* 20.5/24 MHz */
/*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */
writeregst(state, 0x00, 0x43, data, sizeof(data));
@@ -891,7 +1056,23 @@ static void Sleep_to_ActiveC2(struct cxd_state *state, u32 iffreq)
writeregst(state, 0x2D, 0x24, data, sizeof(data));
}
if (state->is24MHz) {
u8 data1[3] = { 0xEB, 0x03, 0x3B };
u8 data2[2] = { 0x3F, 0xFF };
u8 data3[2] = { 0x0B, 0x72 };
u8 data4[3] = { 0x93, 0xF3, 0x00 };
u8 data5[4] = { 0x05, 0xB8, 0xD8, 0x00 };
u8 data6[9] = { 0x18, 0x1E, 0x71, 0x5D, 0xA9, 0x5D, 0xA9, 0x46, 0x3F };
writeregst(state,0x11,0x33,data1,sizeof(data1));
writeregst(state,0x20,0xD9,data2,sizeof(data2));
writeregst(state,0x24,0x34,data3,sizeof(data3));
writeregst(state,0x24,0xD2,data4,sizeof(data4));
writeregst(state,0x24,0xDD,data5,sizeof(data5));
writeregt(state,0x25,0xED,0x60);
writeregst(state,0x5E,0xDB,data6,sizeof(data6));
}
BandSettingC2(state, iffreq);
writeregt(state, 0x00, 0x80, 0x28); /* Disable HiZ Setting 1 */
@@ -908,34 +1089,51 @@ static void BandSettingIT(struct cxd_state *state, u32 iffreq)
default:
case 8:
{
u8 TR_data[] = { 0x0F, 0x22, 0x80, 0x00, 0x00 }; /* 20.5/41 */
u8 CL_data[] = { 0x15, 0xA8 };
/*u8 TR_data[] = { 0x11, 0xB8, 0x00, 0x00, 0x00 }; */ /* 24 */
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
if (state->is24MHz) {
u8 TR_data[] = { 0x11, 0xb8, 0x00, 0x00, 0x00 }; /* 24 */
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x0F, 0x22, 0x80, 0x00, 0x00 }; /* 20.5/41 */
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
}
/* Add EQ Optimisation for tuner here */
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x00, 0x07); /* System Bandwidth */
/*u8 CL_data[] = { 0x13, 0xFC }; */
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
if (state->is24MHz) {
u8 CL_data[] = { 0x13, 0xfc };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
} else {
u8 CL_data[] = { 0x15, 0xA8 };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
}
writebitst(state, 0x12, 0x71, 0x03, 0x07);
writeregt(state, 0x15, 0xbe, 0x03);
}
break;
case 7:
{
u8 TR_data[] = { 0x11, 0x4c, 0x00, 0x00, 0x00 };
u8 CL_data[] = { 0x1B, 0x5D };
/*u8 TR_data[] = { 0x14, 0x40, 0x00, 0x00, 0x00 }; */
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
if (state->is24MHz) {
u8 TR_data[] = { 0x14, 0x40, 0x00, 0x00, 0x00 }; /* 24 */
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x11, 0x4c, 0x00, 0x00, 0x00 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x02, 0x07);
/*static u8 CL_data[] = { 0x1A, 0xFA };*/
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
if (state->is24MHz) {
u8 CL_data[] = { 0x1a, 0xfa };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
} else {
u8 CL_data[] = { 0x1B, 0x5D };
writeregst(state, 0x10, 0xD9, CL_data, sizeof(CL_data));
}
writebitst(state, 0x12, 0x71, 0x03, 0x07);
writeregt(state, 0x15, 0xbe, 0x02);
@@ -943,22 +1141,30 @@ static void BandSettingIT(struct cxd_state *state, u32 iffreq)
break;
case 6:
{
u8 TR_data[] = { 0x14, 0x2E, 0x00, 0x00, 0x00 };
/*u8 TR_data[] = { 0x17, 0xA0, 0x00, 0x00, 0x00 }; */
/*u8 CL_data[] = { 0x1F, 0x79 }; */
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
if (state->is24MHz) {
u8 TR_data[] = { 0x17, 0xa0, 0x00, 0x00, 0x00 }; /* 24 */
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
} else {
u8 TR_data[] = { 0x14, 0x2E, 0x00, 0x00, 0x00 };
writeregst(state, 0x10, 0x9F, TR_data, sizeof(TR_data));
}
writeregst(state, 0x10, 0xB6, IF_data, sizeof(IF_data));
writebitst(state, 0x10, 0xD7, 0x04, 0x07);
if (state->is2k14) {
u8 CL_data[] = { 0x1a, 0xe2 };
writeregst(state, 0x10, 0xDd9, CL_data, sizeof(CL_data));
} else {
u8 CL_data[] = { 0x1F, 0xec };
if (state->is24MHz) {
u8 CL_data[] = { 0x1f, 0x79 };
writeregst(state, 0x10, 0xd9, CL_data, sizeof(CL_data));
} else {
if (state->is2k14) {
u8 CL_data[] = { 0x1a, 0xe2 };
writeregst(state, 0x10, 0xd9, CL_data, sizeof(CL_data));
} else {
u8 CL_data[] = { 0x1F, 0xec };
writeregst(state, 0x10, 0xd9, CL_data, sizeof(CL_data));
}
}
writebitst(state, 0x12, 0x71, 0x07, 0x07);
writeregt(state, 0x15, 0xbe, 0x02);
@@ -969,12 +1175,6 @@ static void BandSettingIT(struct cxd_state *state, u32 iffreq)
static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq)
{
u8 data2[3] = { 0xB9, 0xBA, 0x63 }; /* 20.5/41 MHz */
/*u8 data2[3] = { 0xB7,0x1B,0x00 }; */ /* 24 MHz */
u8 TSIF_data[2] = { 0x61, 0x60 } ; /* 20.5/41 MHz */
/*u8 TSIF_data[2] = { 0x60,0x00 } ; */ /* 24 MHz */
ConfigureTS(state, ActiveIT);
/* writeregx(state, 0x00,0x17,0x01); */ /* 2838 has only one Mode */
@@ -989,7 +1189,7 @@ static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq)
writeregt(state, 0x00, 0x41, 0x1A); /* Enable ADC1 */
{
u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz, 24 MHz */
u8 data[2] = { 0x09, 0x54 }; /* 20.5 MHz/24 MHz */
/*u8 data[2] = { 0x0A, 0xD4 }; */ /* 41 MHz */
writeregst(state, 0x00, 0x43, data, 2); /* Enable ADC 2+3 */
@@ -998,6 +1198,9 @@ static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq)
if (state->is2k14) {
writebitst(state, 0x10, 0xd2, 0x0c, 0x1f);
writeregt(state, 0x11, 0x6a, 0x50);
writebitst(state, 0x10, 0xA5, 0x00, 0x01); /* ASCOT Off */
writebitst(state, 0x18, 0x30, 0x01, 0x01);
@@ -1018,16 +1221,19 @@ static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq)
writebitst(state, 0x1e, 0x73, 0x68, 0xff);
writebitst(state, 0x63, 0x81, 0x00, 0x01);
}
//if( m_is24MHz )
//{
// static BYTE TSIF_data[2] = { 0x60,0x00 } ; // 24 MHz
// CHK_ERROR(WriteRegT(0x10,0xBF,TSIF_data,sizeof(TSIF_data)));
// static BYTE data[3] = { 0xB7,0x1B,0x00 }; // 24 MHz
// CHK_ERROR(WriteRegT(0x60,0xA8,data,sizeof(data)));
//}
//else
writeregst(state, 0x10, 0xBF, TSIF_data, sizeof(TSIF_data));
writeregst(state, 0x60, 0xa8, data2, sizeof(data2));
if (state->is24MHz) {
static u8 TSIF_data[2] = { 0x60,0x00 } ; // 24 MHz
static u8 data[3] = { 0xB7,0x1B,0x00 }; // 24 MHz
writeregst(state, 0x10, 0xBF, TSIF_data, sizeof(TSIF_data));
writeregst(state, 0x60, 0xA8, data, sizeof(data));
} else {
u8 TSIF_data[2] = { 0x61, 0x60 } ; /* 20.5/41 MHz */
u8 data[3] = { 0xB9, 0xBA, 0x63 }; /* 20.5/41 MHz */
writeregst(state, 0x10, 0xBF, TSIF_data, sizeof(TSIF_data));
writeregst(state, 0x60, 0xa8, data, sizeof(data));
}
if (!state->is2k14) {
writeregt(state, 0x10, 0xE2, 0xCE); /* OREG_PNC_DISABLE */
@@ -1042,11 +1248,11 @@ static void Sleep_to_ActiveIT(struct cxd_state *state, u32 iffreq)
static void T2_SetParameters(struct cxd_state *state)
{
u8 Profile = 0x01; /* Profile Base */
u8 notT2time = 12; /* early unlock detection time */
u8 notT2time = state->is24MHz ? 24 : 12; /* early unlock detection time */
if (state->T2Profile == T2P_Lite) {
Profile = 0x05;
notT2time = 40;
notT2time = state->is24MHz ? 46 : 40;
}
if (state->plp != 0xffffffff) {
@@ -1182,7 +1388,7 @@ static int Start(struct cxd_state *state, u32 IntermediateFrequency)
if (state->state < Sleep)
return -EINVAL;
iffreq = MulDiv32(IntermediateFrequency, 16777216, 41000000);
iffreq = MulDiv32(IntermediateFrequency, 16777216, state->is24MHz ? 48000000 : 41000000);
switch (state->omode) {
case OM_DVBT:
@@ -1368,9 +1574,16 @@ static void init(struct cxd_state *state)
writeregx(state, 0x00, 0x10, 0x01);
writeregsx(state, 0x00, 0x13, data, 2);
writeregx(state, 0x00, 0x15, 0x00);
usleep_range(3000, 4000);
writeregsx(state, 0x00, 0x13, data, 0);
if (state->is24MHz)
writeregx(state, 0x00, 0x12, 0x00);
writeregx(state, 0x00, 0x14, state->is24MHz ? 0x03 : 0x00);
writeregx(state, 0x00, 0x10, 0x00);
usleep_range(2000, 3000);
@@ -1382,6 +1595,12 @@ static void init(struct cxd_state *state)
if (state->type == CXD2838)
writeregt(state, 0x60, 0x5A, 0x00);
if (state->type == CXD2854) {
writeregt(state, 0x00, 0x63, 0x16);
writeregt(state, 0x00, 0x65, 0x27);
writeregt(state, 0x00, 0x69, 0x06);
}
writebitst(state, 0x10, 0xCB, 0x00, 0x40);
writeregt(state, 0x10, 0xCD, state->IF_FS);
@@ -1416,6 +1635,8 @@ static void init_state(struct cxd_state *state, struct cxd2843_cfg *cfg)
cfg->ts_clock : 1; /* 1 = fastest (82 MBit/s), 5 = slowest */
/* IF Fullscale 0x50 = 1.4V, 0x39 = 1V, 0x28 = 0.7V */
state->IF_FS = 0x50;
state->is24MHz = (cfg->osc == 24000000) ? 1 : 0;
printk("is24Mhz = %u\n", state->is24MHz);
}
static int get_tune_settings(struct dvb_frontend *fe,
@@ -1738,7 +1959,7 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
do
{
+ BYTE tmp;
+ u8 tmp;
+
CHK_ERROR(FreezeRegsT());
@@ -1757,11 +1978,11 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+ pT2_PLPIDS->CommonPLPID = tmp;
+ }
+
BYTE nPids = 0;
u8 nPids = 0;
CHK_ERROR(ReadRegT(0x22,0x7F,&nPids));
- pValues[0] = nPids;
- if( nPids >= nValues ) nPids = BYTE(nValues-1);
- if( nPids >= nValues ) nPids = nValues - 1;
+ pT2_PLPIDS->NumPLPS = nPids;
+ CHK_ERROR(ReadRegT(0x22,0x80,&pT2_PLPIDS->PLPList[0], nPids > 128 ? 128 : nPids));
@@ -1815,11 +2036,14 @@ static void GetSignalToNoiseIT(struct cxd_state *state, u32 *SignalToNoise)
u8 Data[2];
u32 reg;
*SignalToNoise = 0;
freeze_regst(state);
readregst_unlocked(state, 0x60, 0x28, Data, sizeof(Data));
unfreeze_regst(state);
reg = (Data[0] << 8) | Data[1];
if (reg == 0)
return;
if (reg > 51441)
reg = 51441;
@@ -1837,11 +2061,14 @@ static void GetSignalToNoiseC2(struct cxd_state *state, u32 *SignalToNoise)
u8 Data[2];
u32 reg;
*SignalToNoise = 0;
freeze_regst(state);
readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data));
unfreeze_regst(state);
reg = (Data[0] << 8) | Data[1];
if (reg == 0)
return;
if (reg > 51441)
reg = 51441;
@@ -1854,11 +2081,14 @@ static void GetSignalToNoiseT2(struct cxd_state *state, u32 *SignalToNoise)
u8 Data[2];
u32 reg;
*SignalToNoise = 0;
freeze_regst(state);
readregst_unlocked(state, 0x20, 0x28, Data, sizeof(Data));
unfreeze_regst(state);
reg = (Data[0] << 8) | Data[1];
if (reg == 0)
return;
if (reg > 10876)
reg = 10876;
@@ -1870,11 +2100,14 @@ static void GetSignalToNoiseT(struct cxd_state *state, u32 *SignalToNoise)
u8 Data[2];
u32 reg;
*SignalToNoise = 0;
freeze_regst(state);
readregst_unlocked(state, 0x10, 0x28, Data, sizeof(Data));
unfreeze_regst(state);
reg = (Data[0] << 8) | Data[1];
if (reg == 0)
return;
if (reg > 4996)
reg = 4996;
@@ -1888,7 +2121,6 @@ static void GetSignalToNoiseC(struct cxd_state *state, u32 *SignalToNoise)
u32 reg;
*SignalToNoise = 0;
freeze_regst(state);
readregst_unlocked(state, 0x40, 0x19, &Constellation, 1);
readregst_unlocked(state, 0x40, 0x4C, Data, sizeof(Data));
@@ -1971,12 +2203,13 @@ static int tune(struct dvb_frontend *fe, bool re_tune,
state->tune_time = jiffies;
}
if (*status & FE_HAS_LOCK)
return 0;
/* *delay = 50; */
r = read_status(fe, status);
if (r)
return r;
if (*status & FE_HAS_LOCK) {
*delay = HZ;
return 0;
}
return 0;
}
@@ -2404,13 +2637,12 @@ static int probe(struct cxd_state *state)
int status;
status = readregst(state, 0x00, 0xFD, &ChipID, 1);
if (status)
status = readregsx(state, 0x00, 0xFD, &ChipID, 1);
if (status)
return status;
/*printk("ChipID = %02X\n", ChipID);*/
printk("ChipID = %02X\n", ChipID);
switch (ChipID) {
case 0xa4:
state->type = CXD2843;
@@ -2445,6 +2677,7 @@ struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c,
{
struct cxd_state *state = NULL;
pr_info("attach\n");
state = kzalloc(sizeof(struct cxd_state), GFP_KERNEL);
if (!state)
return NULL;

View File

@@ -8,6 +8,7 @@ struct cxd2843_cfg {
u8 adr;
u32 ts_clock;
u8 parallel;
u32 osc;
};
#if defined(CONFIG_DVB_CXD2843) || \

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.release_sec = lnbh25_release;
pr_info("LNB25 on %02x\n", lnbh->adr);
pr_info("LNBH25 on %02x\n", lnbh->adr);
return fe;
}

View File

@@ -424,9 +424,22 @@ static int get_algo(struct dvb_frontend *fe)
return DVBFE_ALGO_HW;
}
/*
static int cfg_scrambler(struct mxl *state)
/* This should maybe go into dvb-core/dvb_math.c */
static u32 gold2root(u32 gold)
{
u32 x, g;
if (gold >= 0x3ffff)
gold = 0;
for (g = 0, x = 1; g < gold; g++)
x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1);
return x;
}
static int cfg_scrambler(struct mxl *state, u32 gold)
{
u32 root;
u8 buf[26] = {
MXL_HYDRA_PLID_CMD_WRITE, 24,
0, MXL_HYDRA_DEMOD_SCRAMBLE_CODE_CMD, 0, 0,
@@ -435,11 +448,18 @@ static int cfg_scrambler(struct mxl *state)
0, 0, 0, 0, 1, 0, 0, 0,
};
if (gold != NO_SCRAMBLING_CODE)
root = gold2root(gold);
else
root = 1;
buf[25] = (root >> 24) & 0xff;
buf[24] = (root >> 16) & 0xff;
buf[23] = (root >> 8) & 0xff;
buf[22] = root & 0xff;
return send_command(state, sizeof(buf), buf);
}
*/
static int CfgDemodAbortTune(struct mxl *state)
{
MXL_HYDRA_DEMOD_ABORT_TUNE_T abortTuneCmd;
@@ -510,7 +530,7 @@ static int set_parameters(struct dvb_frontend *fe)
demodChanCfg.rollOff = MXL_HYDRA_ROLLOFF_AUTO;
demodChanCfg.modulationScheme = MXL_HYDRA_MOD_AUTO;
demodChanCfg.pilots = MXL_HYDRA_PILOTS_AUTO;
//cfg_scrambler(state);
cfg_scrambler(state, p->pls);
break;
default:
return -EINVAL;
@@ -576,17 +596,13 @@ static int tune(struct dvb_frontend *fe, bool re_tune,
state->tune_time = jiffies;
return 0;
}
if (*status & FE_HAS_LOCK)
return 0;
r = read_status(fe, status);
if (r)
return r;
#if 0
if (*status & FE_HAS_LOCK)
return 0;
#if 0
if (p->delivery_system == SYS_DVBS)
p->delivery_system = SYS_DVBS2;
else
@@ -698,6 +714,10 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
int stat;
u32 regData = 0;
#if 0
if (!firmware_is_alive(state))
pr_info("FW dead!\n");
#endif
mutex_lock(&state->base->status_lock);
HYDRA_DEMOD_STATUS_LOCK(state, state->demod);
stat = read_register(state, (HYDRA_DMD_STATUS_INPUT_POWER_ADDR +
@@ -837,8 +857,8 @@ static struct dvb_frontend_ops mxl_ops = {
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
.info = {
.name = "MXL5XX",
.frequency_min = 950000,
.frequency_max = 2150000,
.frequency_min = 300000,
.frequency_max = 2350000,
.frequency_stepsize = 0,
.frequency_tolerance = 0,
.symbol_rate_min = 1000000,
@@ -1639,7 +1659,7 @@ static int load_fw(struct mxl *state, struct mxl5xx_cfg *cfg)
static int validate_sku(struct mxl *state)
{
u32 padMuxBond, prcmChipId, prcmSoCId;
u32 padMuxBond = 0, prcmChipId = 0, prcmSoCId = 0;
int status;
u32 type = state->base->type;

View File

@@ -3446,11 +3446,11 @@ err:
static int stv090x_set_pls(struct stv090x_state *state, u8 pls_mode, u32 pls_code)
{
dprintk(FE_DEBUG, 1, "Set PLS code %d (mode %d)", pls_code, pls_mode);
if (STV090x_WRITE_DEMOD(state, PLROOT2, (pls_mode << 2) | (pls_code >> 16)) < 0)
if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code & 0xff) < 0)
goto err;
if (STV090x_WRITE_DEMOD(state, PLROOT1, (pls_code >> 8) & 0xff) < 0)
goto err;
if (STV090x_WRITE_DEMOD(state, PLROOT0, pls_code & 0xff) < 0)
if (STV090x_WRITE_DEMOD(state, PLROOT2, (pls_mode << 2) | (pls_code >> 16)) < 0)
goto err;
return 0;
err:
@@ -4927,15 +4927,6 @@ static int stv090x_init(struct dvb_frontend *fe)
if (stv090x_i2c_gate_ctrl(state, 0) < 0)
goto err;
#if 0
if (state->device == STV0900) {
if (stv0900_set_tspath(state) < 0)
goto err;
} else {
if (stv0903_set_tspath(state) < 0)
goto err;
}
#endif
return 0;
err_gateoff:

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,7 @@ struct stv0910_cfg {
u8 adr;
u8 parallel;
u8 rptlvl;
u8 single;
};
#if defined(CONFIG_DVB_STV0910) || \

View File

@@ -19,4 +19,17 @@ struct dvb_mod_channel_params {
#define DVB_MOD_SET _IOW('o', 208, struct dvb_mod_params)
#define DVB_MOD_CHANNEL_SET _IOW('o', 209, struct dvb_mod_channel_params)
#define MODULATOR_UNDEFINED 0
#define MODULATOR_START 1
#define MODULATOR_STOP 2
#define MODULATOR_FREQUENCY 3
#define MODULATOR_MODULATION 4
#define MODULATOR_SYMBOL_RATE 5 /* Hz */
#define MODULATOR_BASE_FREQUENCY 6
#define MODULATOR_ATTENUATOR 32
#define MODULATOR_INPUT_BITRATE 33 /* Hz */
#define MODULATOR_PCR_MODE 34 /* 1=pcr correction enabled */
#define MODULATOR_GAIN 35
#define MODULATOR_OUTPUT_ARI 64
#endif /*_UAPI_DVBMOD_H_*/