mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2025-03-01 10:35:23 +00:00
Compare commits
302 Commits
0.9.38pre3
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
710f9c6fbc | ||
|
849d9ec10f | ||
|
a79f57a675 | ||
|
0690bf6882 | ||
|
f5fcda81dc | ||
|
0b54436695 | ||
|
a986a98b96 | ||
|
345c3b8e0d | ||
|
b172e83a4b | ||
|
5fef324ea0 | ||
|
63f693946c | ||
|
17b741b01d | ||
|
8e4379ef3e | ||
|
1022b26d7f | ||
|
59cbab6383 | ||
|
0fcd9563f1 | ||
|
cf64ad4b0e | ||
|
1c88e05931 | ||
|
11b8c21cb5 | ||
|
3cc98a4995 | ||
|
0c328cd989 | ||
|
ffbef1488e | ||
|
8badef38a7 | ||
|
5d47dbec26 | ||
|
0368446256 | ||
|
07d5675b06 | ||
|
ea8e877dca | ||
|
9ec5f40324 | ||
|
50e230b48d | ||
|
4197d9a59e | ||
|
62b0b57c5d | ||
|
fe63f1d0b8 | ||
|
dc384c70af | ||
|
4e0bf8b182 | ||
|
e7390e1cd8 | ||
|
d54905cc14 | ||
|
7779445112 | ||
|
3ba2128c4e | ||
|
8f2bf94b43 | ||
|
a927449610 | ||
|
3295328aa9 | ||
|
2b53b34350 | ||
|
a6f022941f | ||
|
da1594d424 | ||
|
32afa3e920 | ||
![]() |
f8726493b1 | ||
![]() |
525472b9f1 | ||
![]() |
7423903c67 | ||
![]() |
690289c338 | ||
![]() |
09021aec73 | ||
![]() |
a1c604f212 | ||
![]() |
1124f00b34 | ||
![]() |
70a119c0db | ||
![]() |
123291b26e | ||
![]() |
85f8f5d2bd | ||
![]() |
4d0c806262 | ||
![]() |
9e6e34b857 | ||
![]() |
327cc09d34 | ||
![]() |
adaeb94a54 | ||
![]() |
570864a576 | ||
![]() |
c681e4f24a | ||
![]() |
0628769620 | ||
![]() |
934c619bcb | ||
![]() |
847b8611bd | ||
![]() |
be74b9630f | ||
![]() |
3d17ab8de5 | ||
![]() |
b76aa3c0c2 | ||
![]() |
ca9613d911 | ||
![]() |
0daf0f79ae | ||
|
3884037c93 | ||
![]() |
f23789e90c | ||
![]() |
0c603bc421 | ||
![]() |
f23648f938 | ||
![]() |
d8f3d40352 | ||
![]() |
de5051a85a | ||
![]() |
d63916cba1 | ||
![]() |
3ef783c393 | ||
![]() |
cf7f19b8bc | ||
![]() |
0ad8eff8af | ||
![]() |
a0d4605ad8 | ||
![]() |
948234d787 | ||
![]() |
05718a5965 | ||
![]() |
aedb0a1b64 | ||
![]() |
76697f420f | ||
![]() |
6c7a754004 | ||
![]() |
bf85718376 | ||
![]() |
5f8c0cb75a | ||
![]() |
accad41c2c | ||
![]() |
72181bd0ad | ||
![]() |
100aa25176 | ||
![]() |
73317671a3 | ||
![]() |
f77d50e526 | ||
|
25c730789d | ||
|
775ddf72ef | ||
|
7b23c917d3 | ||
|
d91b2b7813 | ||
|
58c608ab30 | ||
|
8dc2fd062f | ||
|
33ed0ec27c | ||
|
1ca4a8cea5 | ||
|
bb1408a98a | ||
|
9af63d41f7 | ||
![]() |
95d23821b7 | ||
![]() |
059bfbb76e | ||
![]() |
454bb63993 | ||
![]() |
5b83e68887 | ||
![]() |
da4938e3aa | ||
![]() |
3439fd7725 | ||
![]() |
fc043cc914 | ||
![]() |
818b9cb58d | ||
![]() |
0bafbf534f | ||
![]() |
e5072debc0 | ||
![]() |
2f49ece88c | ||
![]() |
52b40198eb | ||
![]() |
98f98fea0e | ||
![]() |
ccfdc2b984 | ||
![]() |
9c920141ca | ||
![]() |
6c2bbbe5b8 | ||
![]() |
3eaae81e6a | ||
![]() |
aae6233b14 | ||
![]() |
c8f3c122af | ||
![]() |
7258b32045 | ||
![]() |
c2a2a27500 | ||
![]() |
847aa3c044 | ||
![]() |
48d9945769 | ||
![]() |
307ce85223 | ||
![]() |
23b2e6d6a0 | ||
![]() |
647e8d77c3 | ||
![]() |
4943ea294a | ||
![]() |
7118ecd9f5 | ||
![]() |
02ded87d78 | ||
![]() |
9698b87204 | ||
![]() |
4d087a3b8c | ||
![]() |
a233c8a6f8 | ||
![]() |
e55ef2f0fb | ||
![]() |
a2f011f62d | ||
![]() |
7250608d53 | ||
![]() |
5e5ff60b21 | ||
![]() |
060eac06b8 | ||
![]() |
dfde99c01e | ||
![]() |
73f270d850 | ||
![]() |
781177ea44 | ||
![]() |
330f2c1821 | ||
![]() |
3fc610f546 | ||
![]() |
c522f28d68 | ||
![]() |
0fa14cca02 | ||
![]() |
ed14095a2f | ||
![]() |
456886f4fb | ||
![]() |
abbb9e324a | ||
![]() |
e18b425f41 | ||
![]() |
88e65b4db6 | ||
![]() |
4d583fd5f4 | ||
![]() |
f27b64b186 | ||
![]() |
7478bcffb9 | ||
![]() |
0d9b5ca619 | ||
![]() |
e9399971f8 | ||
![]() |
626aa6d7be | ||
![]() |
5bfa228d71 | ||
![]() |
42df1e88d4 | ||
![]() |
57101c22b7 | ||
![]() |
37e423d19b | ||
![]() |
17914cb451 | ||
![]() |
25009b3afd | ||
![]() |
2c75179530 | ||
![]() |
58535dd4e3 | ||
![]() |
b51b7c0598 | ||
![]() |
e9ed73b929 | ||
![]() |
c0e174505a | ||
![]() |
87478ec63a | ||
![]() |
4f9cb2810e | ||
![]() |
5988565066 | ||
|
6e4f8dc86b | ||
|
5d876b2615 | ||
|
2968f85c91 | ||
|
a443c3e8de | ||
|
c008e44bf6 | ||
|
7e9650c841 | ||
|
a6565abde3 | ||
|
ee7c48e6ff | ||
|
6ce49ed990 | ||
|
0b36a69c44 | ||
|
e64ceb90fb | ||
|
efbf312d98 | ||
|
0c3c1f5753 | ||
|
4bf1f48926 | ||
|
979cb7a237 | ||
|
7ce5232cd7 | ||
|
3f296bef62 | ||
|
ad01e9f508 | ||
|
e312df576c | ||
|
4b5cd433f9 | ||
|
6c068c0cc3 | ||
|
1488f326d0 | ||
|
c86cb59638 | ||
|
c78905d4a2 | ||
|
31589952a8 | ||
|
7eb5c6e658 | ||
|
172c6c93ba | ||
|
f125fd503c | ||
|
0dd4f106ab | ||
|
60426304db | ||
|
00b0036b33 | ||
|
177e71d62a | ||
|
83a6dc3a1d | ||
|
cc03d96de2 | ||
|
6336bd3689 | ||
|
be79cec76e | ||
|
24801ab41a | ||
|
390f67c03b | ||
|
fa4e3331d8 | ||
|
29cc552a6b | ||
|
42a0b65235 | ||
|
b8abf46d06 | ||
|
ce06e50881 | ||
|
22ffb0ecac | ||
|
92f2132d79 | ||
|
727fba48be | ||
|
09e8a15d78 | ||
|
45c9f076bd | ||
|
5c2757d581 | ||
|
817a464f4a | ||
|
d627e6995f | ||
|
ab4b0c8306 | ||
|
c8c1ee1835 | ||
|
002f39787a | ||
|
871821d6a0 | ||
|
2a88d220e4 | ||
|
e0539d5074 | ||
|
457cb550bb | ||
|
d0793274d2 | ||
|
ffe8764c01 | ||
|
fb4f263aa3 | ||
|
0892a225d2 | ||
|
431dd4f5ee | ||
|
e9ccab3578 | ||
|
cdc5395996 | ||
|
a5f3b75d0a | ||
|
69fcf5d649 | ||
|
d5d63ea2ef | ||
|
4b69ae5399 | ||
|
1cf0526b24 | ||
|
73e8b9943e | ||
|
4b09ad7e42 | ||
|
c39b234fd6 | ||
|
c2f86b6438 | ||
|
6a3ef9873d | ||
|
98b466a2d3 | ||
|
78d30ff6ff | ||
|
d849abd626 | ||
|
9517d698dc | ||
|
75821a6e3c | ||
|
2194f8e03a | ||
|
d9a846d199 | ||
|
31a781c2e3 | ||
|
9b458a72de | ||
|
e0fd8a0f35 | ||
|
1b49bfb8f1 | ||
|
4ce76407e2 | ||
|
a6c53f5ece | ||
|
86579d353e | ||
|
63df691561 | ||
|
4aa7a68e21 | ||
|
b6d2a37ac2 | ||
|
90e6d4806b | ||
|
d995849fdb | ||
|
b5bb500106 | ||
|
24b7f979c4 | ||
|
be19cdb31d | ||
|
56afb2acc1 | ||
|
08b3218e5a | ||
|
e17abdbbb9 | ||
|
811bea8010 | ||
|
e89a868ad5 | ||
|
f02b135bdb | ||
|
8bda007f05 | ||
|
ec655e1438 | ||
|
b606a7b2b2 | ||
|
81793729e6 | ||
|
3757c4671e | ||
|
719ac4d231 | ||
|
a3c6b5acc1 | ||
|
8986494cd3 | ||
|
eeb013e0fa | ||
|
7f40a54b39 | ||
|
1518ba54a4 | ||
|
a97787c3b6 | ||
|
d676919e72 | ||
|
fbc39f71f4 | ||
|
19eea5d42d | ||
|
b23187a049 | ||
|
0165538f13 | ||
|
0b9d3ffa6b | ||
|
61fd25836f | ||
|
d4aa1c634e | ||
|
5bb0a95b02 | ||
|
0a5fb7d6b9 | ||
|
fd21dbbd5e | ||
|
f7fcc1511d | ||
|
37ae102d57 | ||
|
66b1cf3623 | ||
|
7f002f1356 | ||
|
418bd83b40 |
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,7 +1,3 @@
|
|||||||
#
|
|
||||||
# Normal rules
|
|
||||||
#
|
|
||||||
|
|
||||||
.*
|
.*
|
||||||
*.o
|
*.o
|
||||||
*.o.*
|
*.o.*
|
||||||
@ -11,5 +7,9 @@
|
|||||||
*.so
|
*.so
|
||||||
*.so.dbg
|
*.so.dbg
|
||||||
*.orig
|
*.orig
|
||||||
|
*.mod.c
|
||||||
|
*.ko
|
||||||
*~
|
*~
|
||||||
\#*#
|
\#*#
|
||||||
|
Module.symvers
|
||||||
|
modules.order
|
||||||
|
6
Kbuild
6
Kbuild
@ -2,6 +2,12 @@
|
|||||||
# Makefile for the kernel multimedia device drivers.
|
# Makefile for the kernel multimedia device drivers.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
ifeq ($(KERNEL_DVB_CORE),y)
|
||||||
|
obj-y := ddbridge/ \
|
||||||
|
frontends/
|
||||||
|
|
||||||
|
else
|
||||||
obj-y := dvb-core/ \
|
obj-y := dvb-core/ \
|
||||||
ddbridge/ \
|
ddbridge/ \
|
||||||
frontends/
|
frontends/
|
||||||
|
endif
|
16
Makefile
16
Makefile
@ -1,13 +1,18 @@
|
|||||||
kernelver ?= $(shell uname -r)
|
kernelver ?= $(shell uname -r)
|
||||||
|
MDIR ?=
|
||||||
KDIR ?= /lib/modules/$(kernelver)/build
|
KDIR ?= /lib/modules/$(kernelver)/build
|
||||||
PWD := $(shell pwd)
|
PWD := $(shell pwd)
|
||||||
|
|
||||||
MODDEFS := CONFIG_DVB_CORE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_CXD2099=m CONFIG_DVB_LNBP21=m CONFIG_DVB_STV090x=m CONFIG_DVB_STV6110x=m CONFIG_DVB_STV0367=m CONFIG_DVB_TDA18212=m CONFIG_DVB_STV0367DD=m CONFIG_DVB_TDA18212DD=m CONFIG_DVB_OCTONET=m CONFIG_DVB_CXD2843=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6111=m CONFIG_DVB_LNBH25=m CONFIG_DVB_MXL5XX=m CONFIG_DVB_NET=y DDDVB=y
|
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 DDDVB=y
|
||||||
|
|
||||||
KBUILD_EXTMOD = $(PWD)
|
KBUILD_EXTMOD = $(PWD)
|
||||||
|
|
||||||
DDDVB_INC = "-I$(KBUILD_EXTMOD)/include -I$(KBUILD_EXTMOD)/include/linux -I$(KBUILD_EXTMOD)/frontends"
|
ifeq ($(KERNEL_DVB_CORE),y)
|
||||||
|
DDDVB_INC = "--include=$(KBUILD_EXTMOD)/include/dd_compat.h -I$(KBUILD_EXTMOD)/frontends -I$(KBUILD_EXTMOD) -DKERNEL_DVB_CORE=y"
|
||||||
|
else
|
||||||
|
MODDEFS += CONFIG_DVB_NET=y
|
||||||
|
DDDVB_INC = "--include=$(KBUILD_EXTMOD)/include/dd_compat.h -I$(KBUILD_EXTMOD)/frontends -I$(KBUILD_EXTMOD)/include -I$(KBUILD_EXTMOD)/include/linux"
|
||||||
|
endif
|
||||||
|
|
||||||
all:
|
all:
|
||||||
$(MAKE) -C $(KDIR) KBUILD_EXTMOD=$(PWD) $(MODDEFS) modules NOSTDINC_FLAGS=$(DDDVB_INC)
|
$(MAKE) -C $(KDIR) KBUILD_EXTMOD=$(PWD) $(MODDEFS) modules NOSTDINC_FLAGS=$(DDDVB_INC)
|
||||||
@ -26,10 +31,11 @@ dep:
|
|||||||
DIR=`pwd`; (cd $(TOPDIR); make KBUILD_EXTMOD=$$DIR dep)
|
DIR=`pwd`; (cd $(TOPDIR); make KBUILD_EXTMOD=$$DIR dep)
|
||||||
|
|
||||||
install: all
|
install: all
|
||||||
$(MAKE) -C $(KDIR) KBUILD_EXTMOD=$(PWD) modules_install
|
$(MAKE) -C $(KDIR) KBUILD_EXTMOD=$(PWD) INSTALL_MOD_PATH=$(MDIR) modules_install
|
||||||
depmod -a
|
depmod $(kernelver)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf */.*.o.d */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
|
rm -rf */.*.o.d */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
|
||||||
|
$(MAKE) -C apps clean
|
||||||
|
|
||||||
|
|
||||||
|
27
README.md
27
README.md
@ -1,5 +1,7 @@
|
|||||||
# DDBridge Driver
|
# DDBridge Driver
|
||||||
|
|
||||||
|
Device driver for all Digital Devices DVB demodulator and modulator cards.
|
||||||
|
|
||||||
### Patches
|
### Patches
|
||||||
We can only accept patches which don't break compilation for older kernels (as far back as 2.6.37).
|
We can only accept patches which don't break compilation for older kernels (as far back as 2.6.37).
|
||||||
|
|
||||||
@ -9,12 +11,23 @@ incompatiblities to this driver package.
|
|||||||
For installation instructions see:
|
For installation instructions see:
|
||||||
|
|
||||||
http://support.digital-devices.eu/index.php?article=152
|
http://support.digital-devices.eu/index.php?article=152
|
||||||
### Prepare for Building
|
|
||||||
|
|
||||||
TBD
|
|
||||||
|
|
||||||
### Building
|
|
||||||
|
|
||||||
TBD
|
|
||||||
|
|
||||||
|
|
||||||
|
To compile against the dvb-core of a current kernel compile with KERNEL_DVB_CORE=y:
|
||||||
|
|
||||||
|
make KERNEL_DVB_CORE=y install
|
||||||
|
|
||||||
|
This will only work with current mainline kernels.
|
||||||
|
|
||||||
|
Some features will also not work correctly with the mainline kernel dvb-core:
|
||||||
|
|
||||||
|
- some devices will have fewer delivery systems enumerated
|
||||||
|
if one you need is missing you will have to fix it yourself
|
||||||
|
|
||||||
|
- the DTV_INPUT property will not work
|
||||||
|
|
||||||
|
- local bugfixes in dvb-core will be missing
|
||||||
|
|
||||||
|
- Some device names will be different because they do not exist in the kernel
|
||||||
|
|
||||||
|
Also, do not forget to delete old dvb-core modules from e.g. /lib/modules/x.y.z-amd64/updates/ !
|
||||||
|
@ -1,26 +1,34 @@
|
|||||||
all: cit citin flashprog modt ddtest setmod ddflash setmod2 pls setmod3 modconfig ddinfo
|
TARGETS = cit ddtest setmod1 setmod2 modconfig ddinfo getiq modtest ddlicense
|
||||||
|
|
||||||
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
CFLAGS = -g -Wall -Wno-unused -Wno-format
|
||||||
|
FFMPEG := $(shell command -v ffmpeg 2> /dev/null)
|
||||||
|
|
||||||
|
modtest: modtest.c
|
||||||
|
$(CC) -o modtest modtest.c -I../include/ -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
|
||||||
|
|
||||||
|
test.ts:
|
||||||
|
ifndef FFMPEG
|
||||||
|
$(error "ffmpeg is not available please install to create test.ts")
|
||||||
|
endif
|
||||||
|
ffmpeg -f lavfi -i testsrc=duration=10:size=1280x720:rate=30 \
|
||||||
|
-f lavfi -i sine=f=440:b=4 -shortest -metadata \
|
||||||
|
service_provider="DD" -metadata service_name="Test" test.ts
|
||||||
|
|
||||||
cit: cit.c
|
cit: cit.c
|
||||||
$(CC) -o cit cit.c -lpthread
|
$(CC) -o cit cit.c -lpthread
|
||||||
|
|
||||||
modt: modt.c
|
|
||||||
$(CC) -o modt modt.c -lpthread
|
|
||||||
|
|
||||||
setmod: setmod.c
|
|
||||||
$(CC) -o setmod setmod.c -I../include/
|
|
||||||
|
|
||||||
setmod2: setmod2.c
|
|
||||||
$(CC) -o setmod2 setmod2.c -I../include/
|
|
||||||
|
|
||||||
setmod3: setmod3.c
|
|
||||||
$(CC) -o setmod3 setmod3.c -I../include/
|
|
||||||
|
|
||||||
modconfig: modconfig.c
|
|
||||||
$(CC) -o modconfig modconfig.c -I../include/
|
|
||||||
|
|
||||||
%: %.c
|
%: %.c
|
||||||
$(CC) $(CFLAGS) -I../ddbridge -I../include/ $< -o $@
|
$(CC) $(CFLAGS) -I../ddbridge -I../include/ $< -o $@
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $(CFLAGS) -I../ddbridge -o $@ $<
|
$(CC) $(CFLAGS) -I../ddbridge -o $@ $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm test.ts -f
|
||||||
|
for f in $(TARGETS) *.o *~ ; do \
|
||||||
|
if [ -e "$$f" ]; then \
|
||||||
|
rm "$$f" || exit 1; \
|
||||||
|
fi \
|
||||||
|
done
|
||||||
|
44
apps/cit.c
44
apps/cit.c
@ -10,8 +10,9 @@
|
|||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <linux/dvb/ca.h>
|
||||||
|
|
||||||
uint32_t adapter = 0, device = 0, snum = 256, rnum = 256;
|
uint32_t adapter = 0, device = 0, snum = 256, rnum = 256, do_reset = 0;
|
||||||
|
|
||||||
uint8_t fill[188]={0x47, 0x1f, 0xff, 0x10,
|
uint8_t fill[188]={0x47, 0x1f, 0xff, 0x10,
|
||||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||||
@ -83,6 +84,8 @@ void proc_buf(uint8_t *buf, uint32_t *d)
|
|||||||
c=(buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|buf[7];
|
c=(buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|buf[7];
|
||||||
if (c!=*d) {
|
if (c!=*d) {
|
||||||
printf("CONT ERROR: got %08x expected %08x\n", c, *d);
|
printf("CONT ERROR: got %08x expected %08x\n", c, *d);
|
||||||
|
//if (!*d && (c+100) > 100)
|
||||||
|
// return;
|
||||||
*d=c;
|
*d=c;
|
||||||
} else {
|
} else {
|
||||||
if (memcmp(ts+8, buf+8, 180))
|
if (memcmp(ts+8, buf+8, 180))
|
||||||
@ -169,6 +172,34 @@ int send(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
char fname[80];
|
||||||
|
int fd, i;
|
||||||
|
|
||||||
|
sprintf(fname, "/dev/dvb/adapter%u/ca%u", adapter, device);
|
||||||
|
fd=open(fname, O_WRONLY);
|
||||||
|
if (fd < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ioctl(fd, CA_RESET);
|
||||||
|
|
||||||
|
for (i=0; i<24; i++) {
|
||||||
|
ca_slot_info_t info;
|
||||||
|
|
||||||
|
usleep(500000);
|
||||||
|
info.num = 0;
|
||||||
|
if (ioctl(fd, CA_GET_SLOT_INFO, &info))
|
||||||
|
return;
|
||||||
|
if (info.flags & CA_CI_MODULE_READY)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i==24)
|
||||||
|
dprintf(2, "RESET failed\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
pthread_t th;
|
pthread_t th;
|
||||||
@ -181,11 +212,12 @@ int main(int argc, char **argv)
|
|||||||
{"device", required_argument, 0, 'd'},
|
{"device", required_argument, 0, 'd'},
|
||||||
{"snum", required_argument, 0, 's'},
|
{"snum", required_argument, 0, 's'},
|
||||||
{"rnum", required_argument, 0, 'r'},
|
{"rnum", required_argument, 0, 'r'},
|
||||||
|
{"reset", no_argument, 0, 'R'},
|
||||||
{"help", no_argument , 0, 'h'},
|
{"help", no_argument , 0, 'h'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
c = getopt_long(argc, argv,
|
c = getopt_long(argc, argv,
|
||||||
"a:d:h",
|
"a:d:hs:R",
|
||||||
long_options, &option_index);
|
long_options, &option_index);
|
||||||
if (c==-1)
|
if (c==-1)
|
||||||
break;
|
break;
|
||||||
@ -203,6 +235,9 @@ int main(int argc, char **argv)
|
|||||||
case 'r':
|
case 'r':
|
||||||
rnum = strtoul(optarg, NULL, 10);
|
rnum = strtoul(optarg, NULL, 10);
|
||||||
break;
|
break;
|
||||||
|
case 'R':
|
||||||
|
do_reset = 1;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
printf("cit -a<adapter> -d<device>\n");
|
printf("cit -a<adapter> -d<device>\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
@ -214,6 +249,11 @@ int main(int argc, char **argv)
|
|||||||
if (optind < argc) {
|
if (optind < argc) {
|
||||||
printf("Warning: unused arguments\n");
|
printf("Warning: unused arguments\n");
|
||||||
}
|
}
|
||||||
|
if (do_reset) {
|
||||||
|
reset();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
printf("adapter %d, device: %d\n", adapter, device);
|
printf("adapter %d, device: %d\n", adapter, device);
|
||||||
memset(ts+8, 180, 0x5a);
|
memset(ts+8, 180, 0x5a);
|
||||||
pthread_create(&th, NULL, get_ts, NULL);
|
pthread_create(&th, NULL, get_ts, NULL);
|
||||||
|
60
apps/citin.c
60
apps/citin.c
@ -1,60 +0,0 @@
|
|||||||
#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 <linux/dvb/dmx.h>
|
|
||||||
#include <linux/dvb/frontend.h>
|
|
||||||
|
|
||||||
void proc_ts(int i, uint8_t *buf)
|
|
||||||
{
|
|
||||||
uint16_t pid=0x1fff&((buf[1]<<8)|buf[2]);
|
|
||||||
|
|
||||||
if (buf[3]&0xc0) /* only descrambled packets */
|
|
||||||
return;
|
|
||||||
/* only ORF */
|
|
||||||
if (pid==160 || pid==161 || pid==1001||pid==13001 || pid==0)
|
|
||||||
write(1, buf, 188);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TSBUFSIZE (100*188)
|
|
||||||
|
|
||||||
void citest()
|
|
||||||
{
|
|
||||||
uint8_t *buf;
|
|
||||||
uint8_t id;
|
|
||||||
int i, nts;
|
|
||||||
int len;
|
|
||||||
int ts=open("/dev/dvb/adapter4/ci0", O_RDONLY);
|
|
||||||
buf=(uint8_t *)malloc(TSBUFSIZE);
|
|
||||||
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
len=read(ts, buf, TSBUFSIZE);
|
|
||||||
if (len<0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (buf[0]!=0x47) {
|
|
||||||
read(ts, buf, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (len%188) { /* should not happen */
|
|
||||||
printf("blah\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
nts=len/188;
|
|
||||||
for (i=0; i<nts; i++)
|
|
||||||
proc_ts(i, buf+i*188);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
citest();
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
|||||||
#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 <linux/dvb/dmx.h>
|
|
||||||
#include <linux/dvb/frontend.h>
|
|
||||||
#include <linux/dvb/video.h>
|
|
||||||
|
|
||||||
#define TSBUFSIZE (100*188)
|
|
||||||
|
|
||||||
void citest()
|
|
||||||
{
|
|
||||||
uint8_t *buf;
|
|
||||||
uint8_t id;
|
|
||||||
int i, nts;
|
|
||||||
int len;
|
|
||||||
int ts0=open("/dev/dvb/adapter0/dvr0", O_RDONLY);
|
|
||||||
int ts1=open("/dev/dvb/adapter4/sec0", O_WRONLY);
|
|
||||||
int demux0=open("/dev/dvb/adapter0/demux0", O_RDWR);
|
|
||||||
|
|
||||||
struct dmx_pes_filter_params pesFilterParams;
|
|
||||||
|
|
||||||
pesFilterParams.input = DMX_IN_FRONTEND;
|
|
||||||
pesFilterParams.output = DMX_OUT_TS_TAP;
|
|
||||||
pesFilterParams.pes_type = DMX_PES_OTHER;
|
|
||||||
pesFilterParams.flags = DMX_IMMEDIATE_START;
|
|
||||||
|
|
||||||
pesFilterParams.pid = 8192;
|
|
||||||
if (ioctl(demux0, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
|
|
||||||
printf("Could not set PES filter\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
buf=(uint8_t *)malloc(TSBUFSIZE);
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
len=read(ts0, buf, TSBUFSIZE);
|
|
||||||
if (len<=0)
|
|
||||||
break;
|
|
||||||
if (buf[0]!=0x47)
|
|
||||||
printf("oops\n");
|
|
||||||
write(ts1, buf, len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
citest();
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
octonet/ddflash.c
|
|
142
apps/ddinfo.c
142
apps/ddinfo.c
@ -30,6 +30,30 @@ char *Rolloff[8] = {
|
|||||||
"rsvd",
|
"rsvd",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void dump(uint8_t *b, int l)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (j = 0; j < l; j += 16, b += 16) {
|
||||||
|
printf("%04x: ", j);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
if (i + j < l)
|
||||||
|
printf("%02x ", b[i]);
|
||||||
|
else
|
||||||
|
printf(" ");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ldump(uint8_t *b, int l)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < l; i++)
|
||||||
|
printf("%02X", b[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
void print_temp(struct mci_result *res)
|
void print_temp(struct mci_result *res)
|
||||||
{
|
{
|
||||||
printf("Die temperature = %u\n", res->sx8_bist.temperature);
|
printf("Die temperature = %u\n", res->sx8_bist.temperature);
|
||||||
@ -55,6 +79,9 @@ int temp_info(int dev, uint32_t link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
print_temp(&msg.res);
|
print_temp(&msg.res);
|
||||||
|
printf("BIST info dump: ");
|
||||||
|
dump((uint8_t *) &msg.res, 16);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +248,31 @@ char* PunctureRates[32] = {
|
|||||||
/* 0x07 */ "rsvd 7.0",
|
/* 0x07 */ "rsvd 7.0",
|
||||||
};
|
};
|
||||||
|
|
||||||
void print_info(struct mci_result *res, uint8_t demod)
|
int mci_bb(int dev, uint32_t link, uint8_t demod)
|
||||||
|
{
|
||||||
|
struct ddb_mci_msg msg = {
|
||||||
|
.link = link,
|
||||||
|
.cmd.command = MCI_CMD_GET_BBHEADER,
|
||||||
|
.cmd.demod = demod,
|
||||||
|
.cmd.get_bb_header.select = 0,
|
||||||
|
};
|
||||||
|
struct mci_result *res = &msg.res;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("Error: %d %d\n", ret, errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (res->bb_header.valid) {
|
||||||
|
printf("MATYPE1: %02x\n", res->bb_header.matype_1);
|
||||||
|
printf("MATYPE2: %02x\n", res->bb_header.matype_2);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_info(int dev, uint32_t link, uint8_t demod, struct mci_result *res)
|
||||||
{
|
{
|
||||||
if (res->status == MCI_DEMOD_STOPPED) {
|
if (res->status == MCI_DEMOD_STOPPED) {
|
||||||
printf("\nDemod %u: stopped\n", demod);
|
printf("\nDemod %u: stopped\n", demod);
|
||||||
@ -231,8 +282,9 @@ void print_info(struct mci_result *res, uint8_t demod)
|
|||||||
printf("\nDemod %u:\n", demod);
|
printf("\nDemod %u:\n", demod);
|
||||||
if (res->status == MCI_DEMOD_LOCKED) {
|
if (res->status == MCI_DEMOD_LOCKED) {
|
||||||
switch (res->mode) {
|
switch (res->mode) {
|
||||||
case M4_MODE_DVBSX:
|
case 0:
|
||||||
if (res->dvbs2_signal_info.standard == 2) {
|
case MX_MODE_DVBSX:
|
||||||
|
if (res->dvbs2_signal_info.standard != 1) {
|
||||||
int short_frame = 0, pilots = 0;
|
int short_frame = 0, pilots = 0;
|
||||||
char *modcod = "unknown";
|
char *modcod = "unknown";
|
||||||
uint8_t pls = res->dvbs2_signal_info.pls_code;
|
uint8_t pls = res->dvbs2_signal_info.pls_code;
|
||||||
@ -254,19 +306,22 @@ void print_info(struct mci_result *res, uint8_t demod)
|
|||||||
short_frame = pls & 2;
|
short_frame = pls & 2;
|
||||||
modcod = S2ModCods[pls / 4];
|
modcod = S2ModCods[pls / 4];
|
||||||
}
|
}
|
||||||
|
printf("ModCod: %s\n", modcod);
|
||||||
|
mci_bb(dev, link, demod);
|
||||||
printf("Roll-Off: %s\n", Rolloff[res->dvbs2_signal_info.roll_off & 7]);
|
printf("Roll-Off: %s\n", Rolloff[res->dvbs2_signal_info.roll_off & 7]);
|
||||||
printf("Pilots: %s\n", pilots ? "On" : "Off");
|
printf("Pilots: %s\n", pilots ? "On" : "Off");
|
||||||
printf("Frame: %s\n", short_frame ? "Short" : "Long");
|
printf("Frame: %s\n", short_frame ? "Short" : "Normal");
|
||||||
} else {
|
} else {
|
||||||
printf("Demod Locked: DVB-S\n");
|
printf("Demod Locked: DVB-S\n");
|
||||||
printf("PR: %s\n",
|
printf("PR: %s\n",
|
||||||
PunctureRates[res->dvbs2_signal_info.pls_code & 0x07]);
|
PunctureRates[res->dvbs2_signal_info.pls_code & 0x07]);
|
||||||
}
|
}
|
||||||
printf("Inversion: %s\n", (res->dvbs2_signal_info.roll_off & 0x80) ? "on": "off");
|
printf("Inversion: %s\n", (res->dvbs2_signal_info.roll_off & 0x80) ? "on": "off");
|
||||||
case M4_MODE_DVBT:
|
break;
|
||||||
|
case MX_MODE_DVBT:
|
||||||
printf("Locked DVB-T\n");
|
printf("Locked DVB-T\n");
|
||||||
break;
|
break;
|
||||||
case M4_MODE_DVBT2:
|
case MX_MODE_DVBT2:
|
||||||
printf("Locked DVB-T2\n");
|
printf("Locked DVB-T2\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -298,17 +353,18 @@ int readreg(int dev, uint32_t reg, uint32_t link, uint32_t *val)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mci_firmware(int dev, uint32_t link)
|
void mci_firmware(int dev, uint32_t link, uint32_t base)
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
uint32_t u[4];
|
uint32_t u[4];
|
||||||
char s[16];
|
char s[16];
|
||||||
} version;
|
} version;
|
||||||
|
|
||||||
readreg(dev, MIC_INTERFACE_VER , link, &version.u[0]);
|
base += 0xf0;
|
||||||
readreg(dev, MIC_INTERFACE_VER + 4, link, &version.u[1]);
|
readreg(dev, base , link, &version.u[0]);
|
||||||
readreg(dev, MIC_INTERFACE_VER + 8, link, &version.u[2]);
|
readreg(dev, base + 4, link, &version.u[1]);
|
||||||
readreg(dev, MIC_INTERFACE_VER + 12, link, &version.u[3]);
|
readreg(dev, base + 8, link, &version.u[2]);
|
||||||
|
readreg(dev, base + 12, link, &version.u[3]);
|
||||||
|
|
||||||
printf("MCI firmware: %s.%d\n", &version.s, version.s[15]);
|
printf("MCI firmware: %s.%d\n", &version.s, version.s[15]);
|
||||||
}
|
}
|
||||||
@ -322,7 +378,6 @@ int mci_info(int dev, uint32_t link, uint8_t demod)
|
|||||||
.cmd.demod = demod
|
.cmd.demod = demod
|
||||||
};
|
};
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
|
||||||
|
|
||||||
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
|
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
@ -330,7 +385,36 @@ int mci_info(int dev, uint32_t link, uint8_t demod)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_info(&msg.res, demod);
|
print_info(dev, link, demod, &msg.res);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_license(int dev, struct mci_result *res)
|
||||||
|
{
|
||||||
|
if (res->license.serial_number[0] == 0xff)
|
||||||
|
res->license.serial_number[0] = 0;
|
||||||
|
printf("SERNBR:%s\n", (char *) &res->license.serial_number);
|
||||||
|
printf("ID:");
|
||||||
|
ldump(res->license.ID, 8);
|
||||||
|
printf("LK:");
|
||||||
|
ldump(res->license.LK, 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mci_license(int dev)
|
||||||
|
{
|
||||||
|
struct ddb_mci_msg msg = {
|
||||||
|
.link = 0,
|
||||||
|
.cmd.command = CMD_GET_SERIALNUMBER,
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("Error: %d %d\n", ret, errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_license(dev, &msg.res);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,6 +454,8 @@ static int get_id(int fd, int link, struct ddb_id *id)
|
|||||||
static char *id2name(uint16_t id)
|
static char *id2name(uint16_t id)
|
||||||
{
|
{
|
||||||
switch (id) {
|
switch (id) {
|
||||||
|
case 0x210:
|
||||||
|
return "FSM";
|
||||||
case 0x222:
|
case 0x222:
|
||||||
return "MOD";
|
return "MOD";
|
||||||
case 0x0009:
|
case 0x0009:
|
||||||
@ -378,6 +464,8 @@ static char *id2name(uint16_t id)
|
|||||||
return "MAX SX8 Basic";
|
return "MAX SX8 Basic";
|
||||||
case 0x000a:
|
case 0x000a:
|
||||||
return "MAX M4";
|
return "MAX M4";
|
||||||
|
case 0x0014:
|
||||||
|
return "MAX CI M2";
|
||||||
default:
|
default:
|
||||||
return " ";
|
return " ";
|
||||||
}
|
}
|
||||||
@ -387,7 +475,7 @@ static int card_info(int ddbnum, int demod)
|
|||||||
{
|
{
|
||||||
char ddbname[80];
|
char ddbname[80];
|
||||||
struct ddb_id ddbid;
|
struct ddb_id ddbid;
|
||||||
int ddb, ret, link, links = 1, i;
|
int ddb, ret, link, links = 1, i, num=8;
|
||||||
struct ddb_id id;
|
struct ddb_id id;
|
||||||
|
|
||||||
sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum);
|
sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum);
|
||||||
@ -420,24 +508,30 @@ static int card_info(int ddbnum, int demod)
|
|||||||
id.hw, id.regmap, (id.hw & 0xff0000) >> 16, (id.hw & 0xffff));
|
id.hw, id.regmap, (id.hw & 0xff0000) >> 16, (id.hw & 0xffff));
|
||||||
switch (id.device) {
|
switch (id.device) {
|
||||||
case 0x0009:
|
case 0x0009:
|
||||||
mci_firmware(ddb, link);
|
case 0x000b:
|
||||||
if (demod >= 0)
|
|
||||||
mci_info(ddb, link, demod);
|
|
||||||
else {
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
mci_info(ddb, link, i);
|
|
||||||
}
|
|
||||||
temp_info(ddb, link);
|
temp_info(ddb, link);
|
||||||
break;
|
|
||||||
case 0x000a:
|
case 0x000a:
|
||||||
mci_firmware(ddb, link);
|
case 0x0014:
|
||||||
|
if (id.device == 0x000a)
|
||||||
|
num = 4;
|
||||||
|
if (id.device == 0x0014)
|
||||||
|
num = 2;
|
||||||
|
mci_firmware(ddb, link, 0x600);
|
||||||
if (demod >= 0)
|
if (demod >= 0)
|
||||||
mci_info(ddb, link, demod);
|
mci_info(ddb, link, demod);
|
||||||
else {
|
else {
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < num; i++)
|
||||||
mci_info(ddb, link, i);
|
mci_info(ddb, link, i);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0x0210:
|
||||||
|
if (!(id.hw & 0x01000000))
|
||||||
|
break;
|
||||||
|
mci_firmware(ddb, link, 0x300);
|
||||||
|
printf("VEN:DD01\n");
|
||||||
|
printf("DEV:0210\n");
|
||||||
|
mci_license(ddb);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
255
apps/ddlicense.c
Normal file
255
apps/ddlicense.c
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
typedef uint8_t u8;
|
||||||
|
typedef uint16_t u16;
|
||||||
|
typedef int16_t s16;
|
||||||
|
typedef uint32_t u32;
|
||||||
|
typedef uint64_t u64;
|
||||||
|
|
||||||
|
#include "../ddbridge/ddbridge-mci.h"
|
||||||
|
#include "../ddbridge/ddbridge-ioctl.h"
|
||||||
|
|
||||||
|
static void dump(const uint8_t *b, int l)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (j = 0; j < l; j += 16, b += 16) {
|
||||||
|
printf("%04x: ", j);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
if (i + j < l)
|
||||||
|
printf("%02x ", b[i]);
|
||||||
|
else
|
||||||
|
printf(" ");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ldump(FILE *f, uint8_t *b, int l)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < l; i++)
|
||||||
|
fprintf(f, "%02X", b[i]);
|
||||||
|
fprintf(f, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mci_get_license(int dev, uint8_t *ID, uint8_t *LK, uint8_t *SN)
|
||||||
|
{
|
||||||
|
struct ddb_mci_msg msg = {
|
||||||
|
.link = 0,
|
||||||
|
.cmd.command = CMD_GET_SERIALNUMBER,
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
|
||||||
|
if (ret < 0) {
|
||||||
|
dprintf(2, "Error: %d\n", ret, errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (msg.res.status != 0x00) {
|
||||||
|
dprintf(2, "MCI error: %02x, check firmware and license file.\n", msg.res.status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy(ID, msg.res.license.ID, 8);
|
||||||
|
memcpy(LK, msg.res.license.LK, 24);
|
||||||
|
memcpy(SN, msg.res.license.serial_number, 24);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mci_set_license(int dev, uint8_t *ID, uint8_t *LK)
|
||||||
|
{
|
||||||
|
struct ddb_mci_msg msg = {
|
||||||
|
.link = 0,
|
||||||
|
.cmd.command = CMD_IMPORT_LICENSE,
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
memcpy(msg.cmd.license.ID, ID, 8);
|
||||||
|
memcpy(msg.cmd.license.LK, LK, 24);
|
||||||
|
|
||||||
|
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("Error: %d %d\n", ret, errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (msg.res.status != 0x00) {
|
||||||
|
dprintf(2, "MCI error: %02x, check firmware and license file.\n", msg.res.status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int GetHex(char* s, uint32_t nBytes, uint8_t *Buffer)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if( strlen(s) < (nBytes * 2) )
|
||||||
|
return -1;
|
||||||
|
for (i = 0; i < nBytes; i += 1) {
|
||||||
|
char d0, d1;
|
||||||
|
d0 = s[i*2];
|
||||||
|
if( !isxdigit(d0) ) return -1;
|
||||||
|
d1 = s[i*2+1];
|
||||||
|
if( !isxdigit(d1) ) return -1;
|
||||||
|
d0 = toupper(d0);
|
||||||
|
d1 = toupper(d1);
|
||||||
|
Buffer[i] =(uint8_t) ((d0 > '9' ? d0 - 'A' + 10 : d0 - '0') << 4) | ((d1 > '9' ? d1 - 'A' + 10 : d1 - '0'));
|
||||||
|
}
|
||||||
|
return (nBytes * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_id_lk(char *fn, uint8_t *ID, uint8_t *LK)
|
||||||
|
{
|
||||||
|
FILE *fin = fopen(fn, "r");
|
||||||
|
|
||||||
|
if (!fin) {
|
||||||
|
printf("License file not found\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memset(ID, 0, 8);
|
||||||
|
memset(LK, 0xff, 24);
|
||||||
|
while (1) {
|
||||||
|
char s[128];
|
||||||
|
if (fgets(s, sizeof(s), fin) == NULL)
|
||||||
|
break;
|
||||||
|
if (strncmp(s,"ID:",3) == 0) {
|
||||||
|
if (GetHex(&s[3], 8, ID) < 0 )
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (strncmp(s,"LK:",3) == 0) {
|
||||||
|
if (GetHex(&s[3],24, LK) < 0 )
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//dump(ID, 8);
|
||||||
|
//dump(LK, 24);
|
||||||
|
fclose(fin);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_license(int ddb, struct ddb_id *id, char *ename)
|
||||||
|
{
|
||||||
|
uint8_t ID[8], LK[24], SN[17];
|
||||||
|
int stat;
|
||||||
|
FILE *f = fopen(ename, "w+");
|
||||||
|
|
||||||
|
if (!f) {
|
||||||
|
dprintf(2, "Could not write to output file.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
stat = mci_get_license(ddb, ID, LK, SN);
|
||||||
|
if (stat < 0) {
|
||||||
|
dprintf(2, "Could not read license.\n");
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
if (SN[0] == 0xff)
|
||||||
|
SN[0] = 0;
|
||||||
|
fprintf(f, "VEN:%04X\n", id->vendor);
|
||||||
|
fprintf(f, "DEV:%04X\n", id->device);
|
||||||
|
fprintf(f, "SERNBR:%s\n", (char *) SN);
|
||||||
|
fprintf(f, "ID:");
|
||||||
|
ldump(f, ID, 8);
|
||||||
|
fprintf(f, "LK:");
|
||||||
|
ldump(f, LK, 24);
|
||||||
|
fclose(f);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_license(int ddb, char *iname)
|
||||||
|
{
|
||||||
|
uint8_t ID[8], LK[24];
|
||||||
|
int stat=0;
|
||||||
|
|
||||||
|
stat = get_id_lk(iname, ID, LK);
|
||||||
|
if (stat < 0)
|
||||||
|
return stat;
|
||||||
|
return mci_set_license(ddb, ID, LK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_set_license(int ddbnum, char *ename, char *iname)
|
||||||
|
{
|
||||||
|
int ddb, stat = 0;
|
||||||
|
char ddbname[80];
|
||||||
|
struct ddb_id id;
|
||||||
|
|
||||||
|
sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum);
|
||||||
|
ddb = open(ddbname, O_RDWR);
|
||||||
|
if (ddb < 0) {
|
||||||
|
dprintf(2, "Error opening device %s\n", ddbname);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
if (ioctl(ddb, IOCTL_DDB_ID, &id) < 0) {
|
||||||
|
dprintf(2, "Unsupported device %s.\n", ddbname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (id.device != 0x210) {
|
||||||
|
dprintf(2, "Unsupported device %s with ID %04x.\n", ddbname, id.device);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ename)
|
||||||
|
stat = get_license(ddb, &id, ename);
|
||||||
|
if (iname)
|
||||||
|
stat = set_license(ddb, iname);
|
||||||
|
close(ddb);
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char*argv[])
|
||||||
|
{
|
||||||
|
int fd = -1, all = 1, i, ret = 0;
|
||||||
|
char fn[128];
|
||||||
|
int32_t device = 0;
|
||||||
|
char *iname = 0, *ename = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int cur_optind = optind ? optind : 1;
|
||||||
|
int option_index = 0;
|
||||||
|
int c;
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"device", required_argument, 0, 'd'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
c = getopt_long(argc, argv, "ad:i:e:",
|
||||||
|
long_options, &option_index);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
switch (c) {
|
||||||
|
case 'd':
|
||||||
|
device = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
all = 1;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
iname = optarg;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
ename = optarg;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind < argc) {
|
||||||
|
printf("too many arguments\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!ename && !iname) {
|
||||||
|
dprintf(2, "Neither export nor import file name provided.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
get_set_license(device, ename, iname);
|
||||||
|
return 0;
|
||||||
|
}
|
289
apps/flashprog.c
289
apps/flashprog.c
@ -1,289 +0,0 @@
|
|||||||
/*
|
|
||||||
/* flashprog - Programmer for flash on Digital Devices Octopus
|
|
||||||
*
|
|
||||||
* Copyright (C) 2010-2011 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
|
|
||||||
* 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 <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "flash.h"
|
|
||||||
#include "flash.c"
|
|
||||||
|
|
||||||
void get_ddid(int ddb, struct ddb_id *ddbid) {
|
|
||||||
uint8_t id[4];
|
|
||||||
|
|
||||||
if (ioctl(ddb, IOCTL_DDB_ID, ddbid)>=0)
|
|
||||||
return;
|
|
||||||
memset(ddbid, 0, sizeof(*ddbid));
|
|
||||||
flashread(ddb, linknr, id, 0, 4);
|
|
||||||
printf("%02x %02x %02x %02x\n",
|
|
||||||
id[0], id[1], id[2], id[3]);
|
|
||||||
ddbid->subvendor=(id[0] << 8) | id[1];
|
|
||||||
ddbid->subdevice=(id[2] << 8) | id[3];
|
|
||||||
}
|
|
||||||
|
|
||||||
int sure()
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
|
|
||||||
printf("\n\nWARNING! Flashing a new FPGA image might make your card unusable!\n");
|
|
||||||
printf("\n\nWARNUNG! Das Flashen eines neuen FPGA-Images kann Ihre Karte unbrauchbar machen.\n");
|
|
||||||
printf("\n\nAre you sure? y/n?");
|
|
||||||
printf("\n\nSind Sie sicher? y/n?");
|
|
||||||
fflush(0);
|
|
||||||
c = getchar();
|
|
||||||
if (c!='y') {
|
|
||||||
printf("\nFlashing aborted.\n\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
printf("\nStarting to flash\n\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
char ddbname[80];
|
|
||||||
char *flashname;
|
|
||||||
int type = 0;
|
|
||||||
struct ddb_id ddbid;
|
|
||||||
uint8_t *buffer;
|
|
||||||
int BufferSize = 0;
|
|
||||||
int BlockErase = 0;
|
|
||||||
uint32_t FlashOffset = 0x10000;
|
|
||||||
int ddb;
|
|
||||||
int i, err;
|
|
||||||
uint32_t SectorSize=0;
|
|
||||||
uint32_t FlashSize=0;
|
|
||||||
int Flash;
|
|
||||||
|
|
||||||
uint32_t svid=0, jump=0, dump=0;
|
|
||||||
int bin;
|
|
||||||
|
|
||||||
int ddbnum = 0;
|
|
||||||
int force = 0;
|
|
||||||
char *fname = NULL;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
int option_index = 0;
|
|
||||||
int c;
|
|
||||||
static struct option long_options[] = {
|
|
||||||
{"svid", required_argument, NULL, 's'},
|
|
||||||
{"help", no_argument , NULL, 'h'},
|
|
||||||
{"force", no_argument , NULL, 'f'},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
c = getopt_long(argc, argv,
|
|
||||||
"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;
|
|
||||||
case 's':
|
|
||||||
svid = strtoul(optarg, NULL, 16);
|
|
||||||
break;
|
|
||||||
case 'o':
|
|
||||||
FlashOffset = strtoul(optarg, NULL, 16);
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
ddbnum = strtol(optarg, NULL, 0);
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
linknr = strtol(optarg, NULL, 0);
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
force = 1;
|
|
||||||
break;
|
|
||||||
case 'j':
|
|
||||||
jump = 1;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (optind<argc) {
|
|
||||||
printf("Warning: unused arguments\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum);
|
|
||||||
ddb=open(ddbname, O_RDWR);
|
|
||||||
if (ddb < 0) {
|
|
||||||
printf("Could not open device\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
Flash = flashdetect(ddb, &SectorSize, &FlashSize, &flashname);
|
|
||||||
|
|
||||||
get_ddid(ddb, &ddbid);
|
|
||||||
#if 0
|
|
||||||
printf("%04x %04x %04x %04x %08x %08x\n",
|
|
||||||
ddbid.vendor, ddbid.device,
|
|
||||||
ddbid.subvendor, ddbid.subdevice,
|
|
||||||
ddbid.hw, ddbid.regmap);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (dump) {
|
|
||||||
flashdump(ddb, linknr, dump, 128);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SectorSize)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (jump) {
|
|
||||||
uint32_t Jump = 0x200000;
|
|
||||||
|
|
||||||
BufferSize = SectorSize;
|
|
||||||
FlashOffset = FlashSize - SectorSize;
|
|
||||||
buffer = malloc(BufferSize);
|
|
||||||
if (!buffer) {
|
|
||||||
printf("out of memory\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memset(buffer, 0xFF, BufferSize);
|
|
||||||
memset(&buffer[BufferSize - 256 + 0x10], 0x00, 16);
|
|
||||||
|
|
||||||
buffer[BufferSize - 256 + 0x10] = 0xbd;
|
|
||||||
buffer[BufferSize - 256 + 0x11] = 0xb3;
|
|
||||||
buffer[BufferSize - 256 + 0x12] = 0xc4;
|
|
||||||
buffer[BufferSize - 256 + 0x1a] = 0xfe;
|
|
||||||
buffer[BufferSize - 256 + 0x1e] = 0x03;
|
|
||||||
buffer[BufferSize - 256 + 0x1f] = ( ( Jump >> 16 ) & 0xFF );
|
|
||||||
buffer[BufferSize - 256 + 0x20] = ( ( Jump >> 8 ) & 0xFF );
|
|
||||||
buffer[BufferSize - 256 + 0x21] = ( ( Jump ) & 0xFF );
|
|
||||||
} else if (svid) {
|
|
||||||
BufferSize = SectorSize;
|
|
||||||
FlashOffset = 0;
|
|
||||||
|
|
||||||
buffer = malloc(BufferSize);
|
|
||||||
if (!buffer) {
|
|
||||||
printf("out of memory\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
memset(buffer,0xFF,BufferSize);
|
|
||||||
|
|
||||||
buffer[0] = ((svid >> 24 ) & 0xFF);
|
|
||||||
buffer[1] = ((svid >> 16 ) & 0xFF);
|
|
||||||
buffer[2] = ((svid >> 8 ) & 0xFF);
|
|
||||||
buffer[3] = ((svid ) & 0xFF);
|
|
||||||
} else {
|
|
||||||
int fh, i;
|
|
||||||
int fsize;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
if (!fname)
|
|
||||||
fname = devid2fname(ddbid.device, &name);
|
|
||||||
if (name)
|
|
||||||
printf("Card: %s\n", name);
|
|
||||||
|
|
||||||
fh = open(fname, O_RDONLY);
|
|
||||||
if (fh < 0 ) {
|
|
||||||
printf("File %s not found \n", fname);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
printf("Using bitstream %s\n", fname);
|
|
||||||
|
|
||||||
fsize = lseek(fh,0,SEEK_END);
|
|
||||||
if( fsize > FlashSize/2 - 0x10000 || fsize < SectorSize )
|
|
||||||
{
|
|
||||||
close(fh);
|
|
||||||
printf("Invalid File Size \n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( Flash == ATMEL_AT45DB642D ) {
|
|
||||||
BlockErase = fsize >= 8192;
|
|
||||||
if( BlockErase )
|
|
||||||
BufferSize = (fsize + 8191) & ~8191;
|
|
||||||
else
|
|
||||||
BufferSize = (fsize + 1023) & ~1023;
|
|
||||||
} else {
|
|
||||||
BufferSize = (fsize + SectorSize - 1 ) & ~(SectorSize - 1);
|
|
||||||
}
|
|
||||||
printf(" Size %08x, target %08x\n", BufferSize, FlashOffset);
|
|
||||||
|
|
||||||
buffer = malloc(BufferSize);
|
|
||||||
|
|
||||||
if( buffer == NULL ) {
|
|
||||||
close(fh);
|
|
||||||
printf("out of memory\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(buffer, 0xFF, BufferSize);
|
|
||||||
lseek(fh, 0, SEEK_SET);
|
|
||||||
read(fh, buffer, fsize);
|
|
||||||
close(fh);
|
|
||||||
|
|
||||||
if (BufferSize >= 0x10000) {
|
|
||||||
for(i = 0; i < 0x200; i += 1 ) {
|
|
||||||
if ( *(uint16_t *) (&buffer[i]) == 0xFFFF )
|
|
||||||
break;
|
|
||||||
buffer[i] = 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!force && sure()<0)
|
|
||||||
return 0;
|
|
||||||
switch(Flash) {
|
|
||||||
case ATMEL_AT45DB642D:
|
|
||||||
err = FlashWriteAtmel(ddb,FlashOffset,buffer,BufferSize);
|
|
||||||
break;
|
|
||||||
case SSTI_SST25VF016B:
|
|
||||||
case SSTI_SST25VF032B:
|
|
||||||
err = FlashWriteSSTI_B(ddb,FlashOffset,buffer,BufferSize);
|
|
||||||
break;
|
|
||||||
case SSTI_SST25VF064C:
|
|
||||||
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x3C);
|
|
||||||
break;
|
|
||||||
case SPANSION_S25FL116K:
|
|
||||||
case SPANSION_S25FL164K:
|
|
||||||
case WINBOND_W25Q16JV:
|
|
||||||
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err < 0)
|
|
||||||
printf("Programming Error\n");
|
|
||||||
else
|
|
||||||
printf("Programming Done\n");
|
|
||||||
|
|
||||||
free(buffer);
|
|
||||||
return 0;
|
|
||||||
}
|
|
100
apps/getiq.c
Normal file
100
apps/getiq.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
typedef uint8_t u8;
|
||||||
|
typedef uint16_t u16;
|
||||||
|
typedef int16_t s16;
|
||||||
|
typedef uint32_t u32;
|
||||||
|
typedef uint64_t u64;
|
||||||
|
|
||||||
|
#include "../ddbridge/ddbridge-mci.h"
|
||||||
|
#include "../ddbridge/ddbridge-ioctl.h"
|
||||||
|
|
||||||
|
void print_iq(struct mci_result *res, int fd)
|
||||||
|
{
|
||||||
|
dprintf(fd, "%d,%d\n", res->iq_symbol.i, res->iq_symbol.q);
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_iq(int dev, uint32_t link, uint8_t demod, int fd)
|
||||||
|
{
|
||||||
|
struct ddb_mci_msg msg = {
|
||||||
|
.link = link,
|
||||||
|
.cmd.command = MCI_CMD_GET_IQSYMBOL,
|
||||||
|
.cmd.demod = demod,
|
||||||
|
.cmd.get_iq_symbol.tap = 0,
|
||||||
|
.cmd.get_iq_symbol.point = 0,
|
||||||
|
};
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("Error: %d %d\n", ret, errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (msg.res.status & 0x80) {
|
||||||
|
printf("MCI errror %02x\n", msg.res.status);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_iq(&msg.res, fd);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define SIZE_OF_ARRAY(a) (sizeof(a)/sizeof(a[0]))
|
||||||
|
|
||||||
|
int main(int argc, char*argv[])
|
||||||
|
{
|
||||||
|
char ddbname[80];
|
||||||
|
int fd = -1, all = 1, i, ret = 0, ddb;
|
||||||
|
char fn[128];
|
||||||
|
int32_t device = -1, demod = -1;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int cur_optind = optind ? optind : 1;
|
||||||
|
int option_index = 0;
|
||||||
|
int c;
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"device", required_argument, 0, 'd'},
|
||||||
|
{"demod", required_argument, 0, 'n'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
c = getopt_long(argc, argv, "ad:n:",
|
||||||
|
long_options, &option_index);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
switch (c) {
|
||||||
|
case 'd':
|
||||||
|
device = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
demod = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'a':
|
||||||
|
all = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind < argc) {
|
||||||
|
printf("too many arguments\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
sprintf(ddbname, "/dev/ddbridge/card%d", device);
|
||||||
|
ddb = open(ddbname, O_RDWR);
|
||||||
|
if (ddb < 0)
|
||||||
|
return -3;
|
||||||
|
for (i = 0; i < 20000; i++)
|
||||||
|
get_iq(ddb, 0, demod, 1);
|
||||||
|
}
|
270
apps/modconfig.c
270
apps/modconfig.c
@ -24,12 +24,31 @@ struct mconf {
|
|||||||
int set_output;
|
int set_output;
|
||||||
int set_channels;
|
int set_channels;
|
||||||
int fd;
|
int fd;
|
||||||
|
int chanset;
|
||||||
|
|
||||||
struct mci_command channels;
|
struct mci_command channels;
|
||||||
struct mci_command stream;
|
struct mci_command stream;
|
||||||
struct mci_command output;
|
struct mci_command output;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void dump(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 strim(char *s)
|
void strim(char *s)
|
||||||
{
|
{
|
||||||
int l = strlen(s);
|
int l = strlen(s);
|
||||||
@ -39,13 +58,15 @@ void strim(char *s)
|
|||||||
s[l] = 0;
|
s[l] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse(char *fname, char *sec, void *priv, void (*cb)(void *, char *, char *))
|
int parse(char *fname, char *sec, void *priv, void (*cb)(void *, char *, char *))
|
||||||
{
|
{
|
||||||
char line[256], csec[80], par[80], val[80], *p;
|
char line[256], csec[80], par[80], val[80], *p;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
if ((f = fopen(fname, "r")) == NULL)
|
if ((f = fopen(fname, "r")) == NULL) {
|
||||||
return;
|
dprintf(2, "Could not open %s\n", fname);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
while ((p = fgets(line, sizeof(line), f))) {
|
while ((p = fgets(line, sizeof(line), f))) {
|
||||||
if (*p == '\r' || *p == '\n' || *p == '#')
|
if (*p == '\r' || *p == '\n' || *p == '#')
|
||||||
continue;
|
continue;
|
||||||
@ -75,6 +96,7 @@ void parse(char *fname, char *sec, void *priv, void (*cb)(void *, char *, char *
|
|||||||
if (!strcmp(sec, csec) && cb)
|
if (!strcmp(sec, csec) && cb)
|
||||||
cb(priv, NULL, NULL);
|
cb(priv, NULL, NULL);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct param_table_entry {
|
struct param_table_entry {
|
||||||
@ -83,89 +105,169 @@ struct param_table_entry {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct param_table_entry mod_standard_table[] = {
|
struct param_table_entry mod_standard_table[] = {
|
||||||
{ .name = "GENERIC", .value = MOD_STANDARD_GENERIC },
|
|
||||||
{ .name = "DVBT_8", .value = MOD_STANDARD_DVBT_8 },
|
|
||||||
{ .name = "DVBT_7", .value = MOD_STANDARD_DVBT_7 },
|
|
||||||
{ .name = "DVBT_6", .value = MOD_STANDARD_DVBT_6 },
|
|
||||||
{ .name = "DVBT_5", .value = MOD_STANDARD_DVBT_5 },
|
|
||||||
{ .name = "DVBT2_8", .value = MOD_STANDARD_DVBT_8 },
|
|
||||||
{ .name = "DVBT2_7", .value = MOD_STANDARD_DVBT_7 },
|
|
||||||
{ .name = "DVBT2_6", .value = MOD_STANDARD_DVBT_6 },
|
|
||||||
{ .name = "DVBT2_5", .value = MOD_STANDARD_DVBT_5 },
|
|
||||||
{ .name = "0", .value = MOD_STANDARD_GENERIC },
|
{ .name = "0", .value = MOD_STANDARD_GENERIC },
|
||||||
|
{ .name = "GENERIC", .value = MOD_STANDARD_GENERIC },
|
||||||
|
|
||||||
{ .name = "1", .value = MOD_STANDARD_DVBT_8 },
|
{ .name = "1", .value = MOD_STANDARD_DVBT_8 },
|
||||||
|
{ .name = "DVBT_8", .value = MOD_STANDARD_DVBT_8 },
|
||||||
|
{ .name = "DVBT2_8", .value = MOD_STANDARD_DVBT_8 },
|
||||||
|
|
||||||
{ .name = "2", .value = MOD_STANDARD_DVBT_7 },
|
{ .name = "2", .value = MOD_STANDARD_DVBT_7 },
|
||||||
|
{ .name = "DVBT_7", .value = MOD_STANDARD_DVBT_7 },
|
||||||
|
{ .name = "DVBT2_7", .value = MOD_STANDARD_DVBT_7 },
|
||||||
|
|
||||||
{ .name = "3", .value = MOD_STANDARD_DVBT_6 },
|
{ .name = "3", .value = MOD_STANDARD_DVBT_6 },
|
||||||
|
{ .name = "DVBT_6", .value = MOD_STANDARD_DVBT_6 },
|
||||||
|
{ .name = "DVBT2_6", .value = MOD_STANDARD_DVBT_6 },
|
||||||
|
|
||||||
{ .name = "4", .value = MOD_STANDARD_DVBT_5 },
|
{ .name = "4", .value = MOD_STANDARD_DVBT_5 },
|
||||||
|
{ .name = "DVBT_5", .value = MOD_STANDARD_DVBT_5 },
|
||||||
|
{ .name = "DVBT2_5", .value = MOD_STANDARD_DVBT_5 },
|
||||||
|
|
||||||
|
{ .name = "8", .value = MOD_STANDARD_DVBC_8 },
|
||||||
|
{ .name = "DVBC_8", .value = MOD_STANDARD_DVBC_8 },
|
||||||
|
|
||||||
|
{ .name = "9", .value = MOD_STANDARD_DVBC_7 },
|
||||||
|
{ .name = "DVBC_7", .value = MOD_STANDARD_DVBC_7 },
|
||||||
|
|
||||||
|
{ .name = "10", .value = MOD_STANDARD_DVBC_6 },
|
||||||
|
{ .name = "DVBC_6", .value = MOD_STANDARD_DVBC_6 },
|
||||||
|
|
||||||
|
{ .name = "11", .value = MOD_STANDARD_J83B_QAM64 },
|
||||||
|
{ .name = "J83B_QAM64", .value = MOD_STANDARD_J83B_QAM64 },
|
||||||
|
|
||||||
|
{ .name = "12", .value = MOD_STANDARD_J83B_QAM256 },
|
||||||
|
{ .name = "J83B_QAM256", .value = MOD_STANDARD_J83B_QAM256 },
|
||||||
|
|
||||||
|
{ .name = "13", .value = MOD_STANDARD_ISDBC_QAM64 },
|
||||||
|
{ .name = "ISDBC_QAM64", .value = MOD_STANDARD_ISDBC_QAM64 },
|
||||||
|
{ .name = "J83C_QAM64", .value = MOD_STANDARD_ISDBC_QAM64 },
|
||||||
|
|
||||||
|
{ .name = "14", .value = MOD_STANDARD_ISDBC_QAM256 },
|
||||||
|
{ .name = "ISDBC_QAM256", .value = MOD_STANDARD_ISDBC_QAM256 },
|
||||||
|
{ .name = "J83C_QAM256", .value = MOD_STANDARD_ISDBC_QAM256 },
|
||||||
|
|
||||||
{ .name = NULL, .value = 0 }
|
{ .name = NULL, .value = 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct param_table_entry stream_format_table[] = {
|
struct param_table_entry stream_format_table[] = {
|
||||||
{ .name = "default", .value = MOD_FORMAT_DEFAULT },
|
|
||||||
{ .name = "IQ16", .value = MOD_FORMAT_IQ16 },
|
|
||||||
{ .name = "IQ8", .value = MOD_FORMAT_IQ8 },
|
|
||||||
{ .name = "IDX8", .value = MOD_FORMAT_IDX8 },
|
|
||||||
{ .name = "TS", .value = MOD_FORMAT_TS },
|
|
||||||
{ .name = "0", .value = MOD_FORMAT_DEFAULT },
|
{ .name = "0", .value = MOD_FORMAT_DEFAULT },
|
||||||
|
{ .name = "default", .value = MOD_FORMAT_DEFAULT },
|
||||||
|
|
||||||
{ .name = "1", .value = MOD_FORMAT_IQ16 },
|
{ .name = "1", .value = MOD_FORMAT_IQ16 },
|
||||||
|
{ .name = "IQ16", .value = MOD_FORMAT_IQ16 },
|
||||||
|
|
||||||
{ .name = "2", .value = MOD_FORMAT_IQ8 },
|
{ .name = "2", .value = MOD_FORMAT_IQ8 },
|
||||||
|
{ .name = "IQ8", .value = MOD_FORMAT_IQ8 },
|
||||||
|
|
||||||
{ .name = "3", .value = MOD_FORMAT_IDX8 },
|
{ .name = "3", .value = MOD_FORMAT_IDX8 },
|
||||||
|
{ .name = "IDX8", .value = MOD_FORMAT_IDX8 },
|
||||||
|
|
||||||
{ .name = "4", .value = MOD_FORMAT_TS },
|
{ .name = "4", .value = MOD_FORMAT_TS },
|
||||||
|
{ .name = "TS", .value = MOD_FORMAT_TS },
|
||||||
|
|
||||||
{ .name = NULL, .value = 0 }
|
{ .name = NULL, .value = 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct param_table_entry guard_interval_table[] = {
|
struct param_table_entry guard_interval_table[] = {
|
||||||
{ .name = "1/32", .value = MOD_DVBT_GI_1_32 },
|
|
||||||
{ .name = "1/16", .value = MOD_DVBT_GI_1_16 },
|
|
||||||
{ .name = "1/8", .value = MOD_DVBT_GI_1_8 },
|
|
||||||
{ .name = "1/4", .value = MOD_DVBT_GI_1_4 },
|
|
||||||
{ .name = "0", .value = MOD_DVBT_GI_1_32 },
|
{ .name = "0", .value = MOD_DVBT_GI_1_32 },
|
||||||
|
{ .name = "1/32", .value = MOD_DVBT_GI_1_32 },
|
||||||
|
|
||||||
{ .name = "1", .value = MOD_DVBT_GI_1_16 },
|
{ .name = "1", .value = MOD_DVBT_GI_1_16 },
|
||||||
|
{ .name = "1/16", .value = MOD_DVBT_GI_1_16 },
|
||||||
|
|
||||||
{ .name = "2", .value = MOD_DVBT_GI_1_8 },
|
{ .name = "2", .value = MOD_DVBT_GI_1_8 },
|
||||||
|
{ .name = "1/8", .value = MOD_DVBT_GI_1_8 },
|
||||||
|
|
||||||
{ .name = "3", .value = MOD_DVBT_GI_1_4 },
|
{ .name = "3", .value = MOD_DVBT_GI_1_4 },
|
||||||
|
{ .name = "1/4", .value = MOD_DVBT_GI_1_4 },
|
||||||
{ .name = NULL, .value = 0 }
|
{ .name = NULL, .value = 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct param_table_entry puncture_rate_table[] = {
|
struct param_table_entry puncture_rate_table[] = {
|
||||||
{ .name = "1/2", .value = MOD_DVBT_PR_1_2 },
|
|
||||||
{ .name = "2/3", .value = MOD_DVBT_PR_2_3 },
|
|
||||||
{ .name = "3/4", .value = MOD_DVBT_PR_3_4 },
|
|
||||||
{ .name = "5/6", .value = MOD_DVBT_PR_5_6 },
|
|
||||||
{ .name = "7/8", .value = MOD_DVBT_PR_7_8 },
|
|
||||||
{ .name = "1", .value = MOD_DVBT_PR_1_2 },
|
{ .name = "1", .value = MOD_DVBT_PR_1_2 },
|
||||||
|
{ .name = "1/2", .value = MOD_DVBT_PR_1_2 },
|
||||||
|
|
||||||
{ .name = "2", .value = MOD_DVBT_PR_2_3 },
|
{ .name = "2", .value = MOD_DVBT_PR_2_3 },
|
||||||
|
{ .name = "2/3", .value = MOD_DVBT_PR_2_3 },
|
||||||
|
|
||||||
{ .name = "3", .value = MOD_DVBT_PR_3_4 },
|
{ .name = "3", .value = MOD_DVBT_PR_3_4 },
|
||||||
|
{ .name = "3/4", .value = MOD_DVBT_PR_3_4 },
|
||||||
|
|
||||||
{ .name = "5", .value = MOD_DVBT_PR_5_6 },
|
{ .name = "5", .value = MOD_DVBT_PR_5_6 },
|
||||||
|
{ .name = "5/6", .value = MOD_DVBT_PR_5_6 },
|
||||||
|
|
||||||
{ .name = "7", .value = MOD_DVBT_PR_7_8 },
|
{ .name = "7", .value = MOD_DVBT_PR_7_8 },
|
||||||
|
{ .name = "7/8", .value = MOD_DVBT_PR_7_8 },
|
||||||
|
|
||||||
{ .name = NULL, .value = 0 }
|
{ .name = NULL, .value = 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct param_table_entry dvbt_constellation_table[] = {
|
struct param_table_entry dvbt_constellation_table[] = {
|
||||||
{ .name = "0", .value = MOD_DVBT_QPSK },
|
{ .name = "0", .value = MOD_DVBT_QPSK },
|
||||||
{ .name = "qpsk", .value = MOD_DVBT_QPSK },
|
{ .name = "qpsk", .value = MOD_DVBT_QPSK },
|
||||||
|
|
||||||
{ .name = "1", .value = MOD_DVBT_16QAM },
|
{ .name = "1", .value = MOD_DVBT_16QAM },
|
||||||
{ .name = "16qam", .value = MOD_DVBT_16QAM },
|
{ .name = "16qam", .value = MOD_DVBT_16QAM },
|
||||||
{ .name = "qam16", .value = MOD_DVBT_16QAM },
|
{ .name = "qam16", .value = MOD_DVBT_16QAM },
|
||||||
|
|
||||||
{ .name = "2", .value = MOD_DVBT_64QAM },
|
{ .name = "2", .value = MOD_DVBT_64QAM },
|
||||||
{ .name = "64qam", .value = MOD_DVBT_64QAM },
|
{ .name = "64qam", .value = MOD_DVBT_64QAM },
|
||||||
{ .name = "qam64", .value = MOD_DVBT_64QAM },
|
{ .name = "qam64", .value = MOD_DVBT_64QAM },
|
||||||
|
|
||||||
{ .name = NULL, .value = 0 }
|
{ .name = NULL, .value = 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
int parse_param(char *val,struct param_table_entry *table, int *value) {
|
struct param_table_entry qam_modulation_table[] = {
|
||||||
|
{ .name = "0", .value = MOD_QAM_DVBC_16 },
|
||||||
|
{ .name = "qam_dvbc_16", .value = MOD_QAM_DVBC_16 },
|
||||||
|
|
||||||
|
{ .name = "1", .value = MOD_QAM_DVBC_32 },
|
||||||
|
{ .name = "qam_dvbc_32", .value = MOD_QAM_DVBC_32 },
|
||||||
|
|
||||||
|
{ .name = "2", .value = MOD_QAM_DVBC_64 },
|
||||||
|
{ .name = "qam_dvbc_64", .value = MOD_QAM_DVBC_64 },
|
||||||
|
|
||||||
|
{ .name = "3", .value = MOD_QAM_DVBC_128 },
|
||||||
|
{ .name = "qam_dvbc_128", .value = MOD_QAM_DVBC_128 },
|
||||||
|
|
||||||
|
{ .name = "4", .value = MOD_QAM_DVBC_256 },
|
||||||
|
{ .name = "qam_dvbc_256", .value = MOD_QAM_DVBC_256 },
|
||||||
|
|
||||||
|
{ .name = "5", .value = MOD_QAM_J83B_64 },
|
||||||
|
{ .name = "qam_j83b_64", .value = MOD_QAM_J83B_64 },
|
||||||
|
|
||||||
|
{ .name = "6", .value = MOD_QAM_DVBC_256 },
|
||||||
|
{ .name = "qam_j83b_256", .value = MOD_QAM_J83B_256 },
|
||||||
|
|
||||||
|
{ .name = "7", .value = MOD_QAM_GENERIC },
|
||||||
|
{ .name = "qam_generic", .value = MOD_QAM_GENERIC },
|
||||||
|
|
||||||
|
{ .name = "8", .value = MOD_QAM_ISDBC_64 },
|
||||||
|
{ .name = "qam_isdbc_64", .value = MOD_QAM_ISDBC_64 },
|
||||||
|
|
||||||
|
{ .name = "9", .value = MOD_QAM_ISDBC_256 },
|
||||||
|
{ .name = "qam_isdbc_256", .value = MOD_QAM_ISDBC_256 },
|
||||||
|
|
||||||
|
{ .name = NULL, .value = 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int parse_param(char *val, struct param_table_entry *table, int *value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
*value = 0;
|
*value = 0;
|
||||||
if (table) {
|
if (table) {
|
||||||
while (table->name) {
|
while (table->name) {
|
||||||
if( !strcasecmp(val,table->name)) {
|
if( !strcasecmp(val,table->name)) {
|
||||||
*value = table->value;
|
*value = table->value;
|
||||||
|
printf("%s=%u\n", val, *value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
table++;
|
table++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
printf("unknown value %s\n", val);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,11 +277,13 @@ int mci_cmd(int dev, struct mci_command *cmd)
|
|||||||
struct ddb_mci_msg msg;
|
struct ddb_mci_msg msg;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
|
||||||
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.link = 0;
|
msg.link = 0;
|
||||||
memcpy(&msg.cmd, cmd, sizeof(msg.cmd));
|
memcpy(&msg.cmd, cmd, sizeof(msg.cmd));
|
||||||
|
dump((uint8_t *) &msg.cmd, sizeof(msg.cmd));
|
||||||
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
|
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dprintf(2, "mci_cmd error %d\n", errno);
|
dprintf(2, "mci_cmd error %d (%s)\n", errno, strerror(errno));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
status = msg.res.status;
|
status = msg.res.status;
|
||||||
@ -201,7 +305,7 @@ struct mci_command msg_channels = {
|
|||||||
.mod_channel = 0,
|
.mod_channel = 0,
|
||||||
.mod_stream = 0,
|
.mod_stream = 0,
|
||||||
.mod_setup_channels[0] = {
|
.mod_setup_channels[0] = {
|
||||||
.flags = MOD_SETUP_FLAG_FIRST|MOD_SETUP_FLAG_LAST|MOD_SETUP_FLAG_VALID,
|
.flags = 0,
|
||||||
.standard = MOD_STANDARD_DVBT_8,
|
.standard = MOD_STANDARD_DVBT_8,
|
||||||
.num_channels = 25,
|
.num_channels = 25,
|
||||||
.frequency = 474000000,
|
.frequency = 474000000,
|
||||||
@ -210,12 +314,10 @@ struct mci_command msg_channels = {
|
|||||||
|
|
||||||
struct mci_command msg_stream = {
|
struct mci_command msg_stream = {
|
||||||
.mod_command = MOD_SETUP_STREAM,
|
.mod_command = MOD_SETUP_STREAM,
|
||||||
.mod_channel = 1,
|
.mod_channel = 0,
|
||||||
.mod_stream = 0,
|
.mod_stream = 0,
|
||||||
.mod_setup_stream = {
|
.mod_setup_stream = {
|
||||||
.standard = MOD_STANDARD_DVBT_8,
|
.standard = MOD_STANDARD_DVBC_8,
|
||||||
.fft_size = 1,
|
|
||||||
.guard_interval = 0,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -252,7 +354,7 @@ void output_cb(void *priv, char *par, char *val)
|
|||||||
mc->output.mod_setup_output.channel_power = (int16_t) (strtod(val, NULL) * 100.0);
|
mc->output.mod_setup_output.channel_power = (int16_t) (strtod(val, NULL) * 100.0);
|
||||||
} else if (!strcasecmp(par, "channels")) {
|
} else if (!strcasecmp(par, "channels")) {
|
||||||
mc->output.mod_setup_output.num_channels = strtol(val, NULL, 10);
|
mc->output.mod_setup_output.num_channels = strtol(val, NULL, 10);
|
||||||
}else if (!strcasecmp(par, "unit")) {
|
} else if (!strcasecmp(par, "unit")) {
|
||||||
if (!strcasecmp(val, "DBUV")) {
|
if (!strcasecmp(val, "DBUV")) {
|
||||||
mc->output.mod_setup_output.unit = MOD_UNIT_DBUV;
|
mc->output.mod_setup_output.unit = MOD_UNIT_DBUV;
|
||||||
} else if (!strcasecmp(val, "DBM")) {
|
} else if (!strcasecmp(val, "DBM")) {
|
||||||
@ -273,21 +375,29 @@ void channels_cb(void *priv, char *par, char *val)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!strcasecmp(par, "frequency")) {
|
if (!strcasecmp(par, "frequency")) {
|
||||||
mc->channels.mod_setup_channels[0].frequency = (uint32_t) (strtod(val, NULL) * 1000000.0);
|
mc->chanset++;
|
||||||
printf("frequency = %u\n", mc->channels.mod_setup_channels[0].frequency);
|
if (mc->chanset > 3)
|
||||||
} else if (!strcasecmp(par, "channels")) {
|
return;
|
||||||
mc->channels.mod_setup_channels[0].num_channels = strtol(val, NULL, 10);
|
mc->channels.mod_setup_channels[mc->chanset].frequency = (uint32_t) (strtod(val, NULL) * 1000000.0);
|
||||||
|
printf("frequency %u = %u\n", mc->chanset + 1, mc->channels.mod_setup_channels[mc->chanset].frequency);
|
||||||
|
} else
|
||||||
|
if (mc->chanset>=0 && mc->chanset < 4) {
|
||||||
|
if (!strcasecmp(par, "channels")) {
|
||||||
|
mc->channels.mod_setup_channels[mc->chanset].num_channels = strtol(val, NULL, 10);
|
||||||
|
printf("channels = %u\n", mc->channels.mod_setup_channels[mc->chanset].num_channels);
|
||||||
} else if (!strcasecmp(par, "standard")) {
|
} else if (!strcasecmp(par, "standard")) {
|
||||||
if (!parse_param(val,mod_standard_table,&value))
|
if (!parse_param(val,mod_standard_table, &value))
|
||||||
mc->stream.mod_setup_channels[0].standard = value;
|
mc->channels.mod_setup_channels[mc->chanset].standard = value;
|
||||||
|
printf("standard = %u\n", value);
|
||||||
} else if (!strcasecmp(par, "offset")) {
|
} else if (!strcasecmp(par, "offset")) {
|
||||||
mc->channels.mod_setup_channels[0].offset = (uint32_t) (strtod(val, NULL) * 1000000.0);
|
mc->channels.mod_setup_channels[mc->chanset].offset = (uint32_t) (strtod(val, NULL) * 1000000.0);
|
||||||
} else if (!strcasecmp(par, "bandwidth")) {
|
} else if (!strcasecmp(par, "bandwidth")) {
|
||||||
mc->channels.mod_setup_channels[0].bandwidth = (uint32_t) (strtod(val, NULL) * 1000000.0);
|
mc->channels.mod_setup_channels[mc->chanset].bandwidth = (uint32_t) (strtod(val, NULL) * 1000000.0);
|
||||||
mc->channels.mod_setup_channels[0].offset =
|
mc->channels.mod_setup_channels[mc->chanset].offset =
|
||||||
mc->channels.mod_setup_channels[0].bandwidth / 2;
|
mc->channels.mod_setup_channels[mc->chanset].bandwidth / 2;
|
||||||
} else
|
} else
|
||||||
printf("invalid channels parameter: %s\n", par);
|
printf("invalid channels parameter: %s\n", par);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void streams_cb(void *priv, char *par, char *val)
|
void streams_cb(void *priv, char *par, char *val)
|
||||||
@ -299,18 +409,23 @@ void streams_cb(void *priv, char *par, char *val)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!strcasecmp(par, "fft_size")) {
|
if (!strcasecmp(par, "fft_size")) {
|
||||||
mc->stream.mod_setup_stream.fft_size = strtol(val, NULL, 10);
|
mc->stream.mod_setup_stream.ofdm.fft_size = strtol(val, NULL, 10);
|
||||||
} else if (!strcasecmp(par, "guard_interval")) {
|
} else if (!strcasecmp(par, "guard_interval")) {
|
||||||
if (!parse_param(val,guard_interval_table,&value))
|
if (!parse_param(val, guard_interval_table, &value))
|
||||||
mc->stream.mod_setup_stream.guard_interval = value;
|
mc->stream.mod_setup_stream.ofdm.guard_interval = value;
|
||||||
} else if (!strcasecmp(par, "puncture_rate")) {
|
} else if (!strcasecmp(par, "puncture_rate")) {
|
||||||
if (!parse_param(val,puncture_rate_table,&value))
|
if (!parse_param(val, puncture_rate_table, &value))
|
||||||
mc->stream.mod_setup_stream.puncture_rate = value;
|
mc->stream.mod_setup_stream.ofdm.puncture_rate = value;
|
||||||
} else if (!strcasecmp(par, "constellation")) {
|
} else if (!strcasecmp(par, "constellation")) {
|
||||||
if (!parse_param(val,dvbt_constellation_table,&value))
|
if (!parse_param(val,dvbt_constellation_table,&value))
|
||||||
mc->stream.mod_setup_stream.constellation = value;
|
mc->stream.mod_setup_stream.ofdm.constellation = value;
|
||||||
} else if (!strcasecmp(par, "cell_identifier")) {
|
} else if (!strcasecmp(par, "cell_identifier")) {
|
||||||
mc->stream.mod_setup_stream.cell_identifier = strtol(val, NULL, 0);
|
mc->stream.mod_setup_stream.ofdm.cell_identifier = strtol(val, NULL, 0);
|
||||||
|
} else if (!strcasecmp(par, "modulation")) {
|
||||||
|
if (!parse_param(val, qam_modulation_table, &value))
|
||||||
|
mc->stream.mod_setup_stream.qam.modulation = value;
|
||||||
|
} else if (!strcasecmp(par, "rolloff")) {
|
||||||
|
mc->stream.mod_setup_stream.qam.rolloff = strtol(val, NULL, 0);
|
||||||
} else if (!strcasecmp(par, "standard")) {
|
} else if (!strcasecmp(par, "standard")) {
|
||||||
if (!parse_param(val,mod_standard_table,&value))
|
if (!parse_param(val,mod_standard_table,&value))
|
||||||
mc->stream.mod_setup_stream.standard = value;
|
mc->stream.mod_setup_stream.standard = value;
|
||||||
@ -324,17 +439,48 @@ void streams_cb(void *priv, char *par, char *val)
|
|||||||
} else if (!strcasecmp(par, "stream")) {
|
} else if (!strcasecmp(par, "stream")) {
|
||||||
mc->stream.mod_stream = strtol(val, NULL, 10);
|
mc->stream.mod_stream = strtol(val, NULL, 10);
|
||||||
printf("set stream %u to channel %u\n", mc->stream.mod_stream, mc->stream.mod_channel);
|
printf("set stream %u to channel %u\n", mc->stream.mod_stream, mc->stream.mod_channel);
|
||||||
|
printf("%u %u %u %u %u %u %u %u\n",
|
||||||
|
mc->stream.mod_command,
|
||||||
|
mc->stream.mod_channel,
|
||||||
|
mc->stream.mod_stream,
|
||||||
|
mc->stream.mod_setup_stream.standard,
|
||||||
|
mc->stream.mod_setup_stream.symbol_rate,
|
||||||
|
mc->stream.mod_setup_stream.stream_format,
|
||||||
|
mc->stream.mod_setup_stream.qam.modulation,
|
||||||
|
mc->stream.mod_setup_stream.qam.rolloff);
|
||||||
mci_cmd(mc->fd, &mc->stream);
|
mci_cmd(mc->fd, &mc->stream);
|
||||||
} else
|
} else
|
||||||
printf("invalid streams parameter: %s = %s\n", par, val);
|
printf("invalid streams parameter: %s = %s\n", par, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mci_lic(int dev)
|
||||||
|
{
|
||||||
|
struct ddb_mci_msg msg = {
|
||||||
|
.cmd.command = CMD_EXPORT_LICENSE,
|
||||||
|
.cmd.get_bb_header.select = 0,
|
||||||
|
};
|
||||||
|
struct mci_result *res = &msg.res;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("Error: %d %d\n", ret, errno);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (res->bb_header.valid) {
|
||||||
|
printf("MATYPE1: %02x\n", res->bb_header.matype_1);
|
||||||
|
printf("MATYPE2: %02x\n", res->bb_header.matype_2);
|
||||||
|
}
|
||||||
|
//dump((const uint8_t *)&res->license, sizeof(res->license));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char*argv[])
|
int main(int argc, char*argv[])
|
||||||
{
|
{
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
char fn[128];
|
char fn[128];
|
||||||
uint32_t device = 0;
|
uint32_t device = 0;
|
||||||
uint32_t frequency = 0;
|
|
||||||
char *configname = "modulator.conf";
|
char *configname = "modulator.conf";
|
||||||
struct mconf mc;
|
struct mconf mc;
|
||||||
|
|
||||||
@ -342,6 +488,7 @@ int main(int argc, char*argv[])
|
|||||||
mc.channels = msg_channels;
|
mc.channels = msg_channels;
|
||||||
mc.stream = msg_stream;
|
mc.stream = msg_stream;
|
||||||
mc.output = msg_output;
|
mc.output = msg_output;
|
||||||
|
mc.chanset = -1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int cur_optind = optind ? optind : 1;
|
int cur_optind = optind ? optind : 1;
|
||||||
@ -375,18 +522,29 @@ int main(int argc, char*argv[])
|
|||||||
printf("too many arguments\n");
|
printf("too many arguments\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
snprintf(fn, 127, "/dev/ddbridge/card%u", device);
|
//snprintf(fn, 127, "/dev/ddbridge/card%u", device);
|
||||||
|
snprintf(fn, 127, "/dev/dvb/adapter%u/mod0", device);
|
||||||
fd = open(fn, O_RDWR);
|
fd = open(fn, O_RDWR);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
dprintf(2, "Could not open %s\n", fn);
|
dprintf(2, "Could not open %s\n", fn);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
//mci_lic(fd);
|
||||||
mc.fd = fd;
|
mc.fd = fd;
|
||||||
parse(configname, "channels", (void *) &mc, channels_cb);
|
if (parse(configname, "channels", (void *) &mc, channels_cb))
|
||||||
if (mc.set_channels)
|
exit(-1);
|
||||||
|
if (mc.set_channels) {
|
||||||
|
for (int i = 0; i <= mc.chanset; i++)
|
||||||
|
mc.channels.mod_setup_channels[i].flags = MOD_SETUP_FLAG_VALID;
|
||||||
|
mc.channels.mod_setup_channels[0].flags |= MOD_SETUP_FLAG_FIRST;
|
||||||
|
mc.channels.mod_setup_channels[mc.chanset].flags |= MOD_SETUP_FLAG_LAST;
|
||||||
|
printf("setting channels, %u groups.\n", mc.chanset + 1);
|
||||||
mci_cmd(fd, &mc.channels);
|
mci_cmd(fd, &mc.channels);
|
||||||
|
}
|
||||||
parse(configname, "streams", (void *) &mc, streams_cb);
|
parse(configname, "streams", (void *) &mc, streams_cb);
|
||||||
parse(configname, "output", (void *) &mc, output_cb);
|
parse(configname, "output", (void *) &mc, output_cb);
|
||||||
if (mc.set_output)
|
if (mc.set_output) {
|
||||||
|
printf("setting output.\n");
|
||||||
mci_cmd(fd, &mc.output);
|
mci_cmd(fd, &mc.output);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
36
apps/modt.c
36
apps/modt.c
@ -1,36 +0,0 @@
|
|||||||
#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>
|
|
||||||
|
|
||||||
|
|
||||||
#define SNUM 1000
|
|
||||||
//671
|
|
||||||
void send(void)
|
|
||||||
{
|
|
||||||
uint8_t buf[188*SNUM], *cts;
|
|
||||||
int i;
|
|
||||||
uint32_t c=0;
|
|
||||||
int fdo;
|
|
||||||
|
|
||||||
fdo=open("/dev/dvb/adapter0/mod0", O_WRONLY);
|
|
||||||
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
read(0, buf, sizeof(buf));
|
|
||||||
write(fdo, buf, 188*SNUM);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
send();
|
|
||||||
}
|
|
1277
apps/modtest.c
Normal file
1277
apps/modtest.c
Normal file
File diff suppressed because it is too large
Load Diff
63
apps/modulator-c.conf
Normal file
63
apps/modulator-c.conf
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
[output]
|
||||||
|
# connector = OFF, SMA or F
|
||||||
|
connector = F
|
||||||
|
# number of total channels to be used at the same time
|
||||||
|
# use lower number to have fewer channels but stronger signal per channel
|
||||||
|
channels = 16
|
||||||
|
# unit of power in DBUV or DBM
|
||||||
|
unit = DBUV
|
||||||
|
# power output in units of above unit
|
||||||
|
power = 70.0
|
||||||
|
|
||||||
|
# define channels:
|
||||||
|
# channels are frequency slots to which a stream (mod0, mod1 ...) can be assigned
|
||||||
|
[channels]
|
||||||
|
# frequency of channel 0, following channels are spaced according to set standard
|
||||||
|
# frequency parameter has to come first!
|
||||||
|
frequency = 474.0
|
||||||
|
# numbers of channels to allocate, starting from frequency below
|
||||||
|
# this defines 16 channels at 474, 474+8, 474+16, etc. Mhz
|
||||||
|
channels = 16
|
||||||
|
# standard: 0 = generic, 1 = DVB-T 8MHz, 2 = DVB-T 7 MHz, 3 = DVB-T 6 MHz
|
||||||
|
standard = DVBC_8
|
||||||
|
|
||||||
|
frequency = 640.0
|
||||||
|
channels = 8
|
||||||
|
standard = DVBC_8
|
||||||
|
|
||||||
|
|
||||||
|
[streams]
|
||||||
|
# number of streams depends on the card hardware
|
||||||
|
# streams correspond to devices mod0, mod1, ...
|
||||||
|
# channels are defined above in channels section
|
||||||
|
|
||||||
|
standard = DVBC_8
|
||||||
|
stream_format = TS
|
||||||
|
symbol_rate = 6.9
|
||||||
|
modulation = qam_dvbc_256
|
||||||
|
|
||||||
|
channel = 0
|
||||||
|
stream = 0
|
||||||
|
|
||||||
|
channel = 1
|
||||||
|
stream = 1
|
||||||
|
|
||||||
|
channel = 2
|
||||||
|
stream = 2
|
||||||
|
|
||||||
|
channel = 3
|
||||||
|
stream = 3
|
||||||
|
|
||||||
|
channel = 4
|
||||||
|
stream = 4
|
||||||
|
|
||||||
|
channel = 5
|
||||||
|
stream = 5
|
||||||
|
|
||||||
|
channel = 6
|
||||||
|
stream = 6
|
||||||
|
|
||||||
|
#symbol_rate = 6.5
|
||||||
|
#modulation = qam_dvbc_64
|
||||||
|
channel = 7
|
||||||
|
stream = 7
|
@ -7,24 +7,24 @@ channels = 16
|
|||||||
# unit of power in DBUV or DBM
|
# unit of power in DBUV or DBM
|
||||||
unit = DBUV
|
unit = DBUV
|
||||||
# power output in units of above unit
|
# power output in units of above unit
|
||||||
power = 50.0
|
power = 90.0
|
||||||
|
|
||||||
|
|
||||||
# define channels:
|
# define channels:
|
||||||
# channels are frequency slots to which a stream (mod0, mod1 ...) can be assigned
|
# channels are frequency slots to which a stream (mod0, mod1 ...) can be assigned
|
||||||
|
|
||||||
[channels]
|
[channels]
|
||||||
|
frequency = 474.0
|
||||||
# standard: 0 = generic, 1 = DVB-T 8MHz, 2 = DVB-T 7 MHz, 3 = DVB-T 6 MHz
|
# standard: 0 = generic, 1 = DVB-T 8MHz, 2 = DVB-T 7 MHz, 3 = DVB-T 6 MHz
|
||||||
standard = 1
|
standard = DVBT_8
|
||||||
|
|
||||||
# numbers of channels to allocate, starting from frequency below
|
# numbers of channels to allocate, starting from frequency below
|
||||||
# this defines 25 channels at 474, 474+8, 474+16, etc. Mhz
|
# this defines 25 channels at 474, 474+8, 474+16, etc. Mhz
|
||||||
channels = 25
|
channels = 25
|
||||||
# frequency of channel 0, following channels are spaced according to set standard
|
# frequency of channel 0, following channels are spaced according to set standard
|
||||||
frequency = 474.0
|
|
||||||
|
|
||||||
|
|
||||||
[streams]
|
[streams]
|
||||||
|
stream_format = TS
|
||||||
|
standard = DVBT_8
|
||||||
# number of streams depends on the card hardware
|
# number of streams depends on the card hardware
|
||||||
# streams correspond to devices mod0, mod1, ...
|
# streams correspond to devices mod0, mod1, ...
|
||||||
# channels are defined above in channels section
|
# channels are defined above in channels section
|
||||||
@ -33,6 +33,9 @@ frequency = 474.0
|
|||||||
guard_interval = 0
|
guard_interval = 0
|
||||||
# 0 = 2K, 1 = 8K (2K not yet supported)
|
# 0 = 2K, 1 = 8K (2K not yet supported)
|
||||||
fft_size = 1
|
fft_size = 1
|
||||||
|
puncture_rate = 7/8
|
||||||
|
constellation = qam64
|
||||||
|
cell_identifier = 0
|
||||||
|
|
||||||
# all following streams will be set according to the last set other parameters
|
# all following streams will be set according to the last set other parameters
|
||||||
|
|
@ -405,6 +405,9 @@ int FlashProg(int dev,int argc, char* argv[],uint32_t Flags)
|
|||||||
case SPANSION_S25FL132K: SectorSize = 4096; FlashSize = 0x400000; break;
|
case SPANSION_S25FL132K: SectorSize = 4096; FlashSize = 0x400000; break;
|
||||||
case SPANSION_S25FL164K: SectorSize = 4096; FlashSize = 0x800000; break;
|
case SPANSION_S25FL164K: SectorSize = 4096; FlashSize = 0x800000; break;
|
||||||
case WINBOND_W25Q16JV: SectorSize = 4096; FlashSize = 0x200000; break;
|
case WINBOND_W25Q16JV: SectorSize = 4096; FlashSize = 0x200000; break;
|
||||||
|
case WINBOND_W25Q32JV: SectorSize = 4096; FlashSize = 0x400000; break;
|
||||||
|
case WINBOND_W25Q64JV: SectorSize = 4096; FlashSize = 0x800000; break;
|
||||||
|
case WINBOND_W25Q128JV: SectorSize = 4096; FlashSize = 0x1000000; break;
|
||||||
}
|
}
|
||||||
if (SectorSize == 0)
|
if (SectorSize == 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -575,6 +578,9 @@ int FlashProg(int dev,int argc, char* argv[],uint32_t Flags)
|
|||||||
case SPANSION_S25FL132K:
|
case SPANSION_S25FL132K:
|
||||||
case SPANSION_S25FL164K:
|
case SPANSION_S25FL164K:
|
||||||
case WINBOND_W25Q16JV:
|
case WINBOND_W25Q16JV:
|
||||||
|
case WINBOND_W25Q32JV:
|
||||||
|
case WINBOND_W25Q64JV:
|
||||||
|
case WINBOND_W25Q128JV:
|
||||||
err = FlashWritePageMode(dev,FlashOffset,Buffer,BufferSize,0x1C); break;
|
err = FlashWritePageMode(dev,FlashOffset,Buffer,BufferSize,0x1C); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1331,6 +1337,9 @@ int read_id(int dev, int argc, char* argv[], uint32_t Flags)
|
|||||||
|
|
||||||
switch(Flash) {
|
switch(Flash) {
|
||||||
case WINBOND_W25Q16JV:
|
case WINBOND_W25Q16JV:
|
||||||
|
case WINBOND_W25Q32JV:
|
||||||
|
case WINBOND_W25Q64JV:
|
||||||
|
case WINBOND_W25Q128JV:
|
||||||
read_winbd(dev, Id);
|
read_winbd(dev, Id);
|
||||||
len = 8;
|
len = 8;
|
||||||
break;
|
break;
|
||||||
@ -1353,7 +1362,7 @@ int read_id(int dev, int argc, char* argv[], uint32_t Flags)
|
|||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
printf("%02x ", Id[i]);
|
printf("%02x ", Id[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i2cread(int dev, int argc, char* argv[], uint32_t Flags)
|
int i2cread(int dev, int argc, char* argv[], uint32_t Flags)
|
||||||
|
@ -36,6 +36,7 @@ static int update_flash(struct ddflash *ddf)
|
|||||||
char *fname, *default_fname;
|
char *fname, *default_fname;
|
||||||
int res, stat = 0;
|
int res, stat = 0;
|
||||||
char *name = 0, *dname;
|
char *name = 0, *dname;
|
||||||
|
uint32_t imgadr = 0x10000;
|
||||||
|
|
||||||
switch (ddf->id.device) {
|
switch (ddf->id.device) {
|
||||||
case 0x300:
|
case 0x300:
|
||||||
@ -109,6 +110,14 @@ static int update_flash(struct ddflash *ddf)
|
|||||||
return stat;
|
return stat;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
{
|
||||||
|
uint32_t val;
|
||||||
|
if (!readreg(ddf->fd, (ddf->link << 28) | 0x10, &val)) {
|
||||||
|
//printf("reg0x10=%08x\n", val);
|
||||||
|
if ((val >> 24) == 5)
|
||||||
|
imgadr = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
fname = ddf->fname;
|
fname = ddf->fname;
|
||||||
default_fname = devid2fname(ddf->id.device, &name);
|
default_fname = devid2fname(ddf->id.device, &name);
|
||||||
if (!fname)
|
if (!fname)
|
||||||
@ -119,7 +128,8 @@ static int update_flash(struct ddflash *ddf)
|
|||||||
printf("Flash: %s\n", ddf->flash_name);
|
printf("Flash: %s\n", ddf->flash_name);
|
||||||
printf("Version: %08x\n", ddf->id.hw);
|
printf("Version: %08x\n", ddf->id.hw);
|
||||||
printf("REGMAP : %08x\n", ddf->id.regmap);
|
printf("REGMAP : %08x\n", ddf->id.regmap);
|
||||||
if ((res = update_image(ddf, fname, 0x10000, ddf->size / 2, 1, 0)) == 1)
|
printf("Address: %08x\n", imgadr);
|
||||||
|
if ((res = update_image(ddf, fname, imgadr, ddf->size / 2, 1, 0)) == 1)
|
||||||
stat |= 1;
|
stat |= 1;
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ static int flashread(int ddb, int link, uint8_t *buf, uint32_t addr, uint32_t le
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int flashdump(int ddb, int link, uint32_t addr, uint32_t len)
|
void flashdump(int ddb, int link, uint32_t addr, uint32_t len)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
uint8_t buf[32];
|
uint8_t buf[32];
|
||||||
@ -630,13 +630,14 @@ int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset,
|
|||||||
uint8_t cmd[260];
|
uint8_t cmd[260];
|
||||||
int i, j;
|
int i, j;
|
||||||
uint32_t flen, blen;
|
uint32_t flen, blen;
|
||||||
int blockerase = be && ((FlashOffset & 0xFFFF) == 0 ) && (flen >= 0x10000);
|
int blockerase;
|
||||||
|
|
||||||
blen = flen = lseek(dev, 0, SEEK_END) - fw_off;
|
blen = flen = lseek(dev, 0, SEEK_END) - fw_off;
|
||||||
if (blen % 0xff)
|
if (blen % 0xff)
|
||||||
blen = (blen + 0xff) & 0xffffff00;
|
blen = (blen + 0xff) & 0xffffff00;
|
||||||
//printf("blen = %u, flen = %u\n", blen, flen);
|
//printf("blen = %u, flen = %u\n", blen, flen);
|
||||||
setbuf(stdout, NULL);
|
setbuf(stdout, NULL);
|
||||||
|
blockerase = be && ((FlashOffset & 0xFFFF) == 0 ) && (flen >= 0x10000);
|
||||||
|
|
||||||
cmd[0] = 0x50; // EWSR
|
cmd[0] = 0x50; // EWSR
|
||||||
err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0);
|
err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0);
|
||||||
@ -927,7 +928,10 @@ static const struct devids ids[] = {
|
|||||||
DEV(0x0011, "Octopus CI", "DVBBridgeV2B_DD01_0011.fpga"),
|
DEV(0x0011, "Octopus CI", "DVBBridgeV2B_DD01_0011.fpga"),
|
||||||
DEV(0x0012, "Octopus CI", "DVBBridgeV2B_DD01_0012_STD.fpga"),
|
DEV(0x0012, "Octopus CI", "DVBBridgeV2B_DD01_0012_STD.fpga"),
|
||||||
DEV(0x0013, "Octopus PRO", "DVBBridgeV2B_DD01_0013_PRO.fpga"),
|
DEV(0x0013, "Octopus PRO", "DVBBridgeV2B_DD01_0013_PRO.fpga"),
|
||||||
|
DEV(0x0014, "Octopus CI M2", "DVBBridgeV3A_DD01_0014_CIM2.fpga"),
|
||||||
DEV(0x0020, "Octopus GT Mini", "DVBBridgeV2C_DD01_0020.fpga"),
|
DEV(0x0020, "Octopus GT Mini", "DVBBridgeV2C_DD01_0020.fpga"),
|
||||||
|
DEV(0x0022, "Octopus MAXM8", "DVBBridgeV3A_DD01_0022_M8.fpga"),
|
||||||
|
DEV(0x0024, "Octopus MAXM8A", "DVBBridgeV3A_DD01_0024_M8A.fpga"),
|
||||||
DEV(0x0201, "Modulator", "DVBModulatorV1B_DVBModulatorV1B.bit"),
|
DEV(0x0201, "Modulator", "DVBModulatorV1B_DVBModulatorV1B.bit"),
|
||||||
DEV(0x0203, "Modulator Test", "DVBModulatorV1B_DD01_0203.fpga"),
|
DEV(0x0203, "Modulator Test", "DVBModulatorV1B_DD01_0203.fpga"),
|
||||||
DEV(0x0210, "Modulator V2", "DVBModulatorV2A_DD01_0210.fpga"),
|
DEV(0x0210, "Modulator V2", "DVBModulatorV2A_DD01_0210.fpga"),
|
||||||
@ -1075,12 +1079,12 @@ static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off)
|
|||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
for (p = 0; p < fsize && buf[p]; p++) {
|
for (p = 0; p < fsize && buf[p]; p++) {
|
||||||
char *key = &buf[p], *val = NULL;
|
char *key = (char *) &buf[p], *val = NULL;
|
||||||
|
|
||||||
for (; p < fsize && buf[p] != 0x0a; p++) {
|
for (; p < fsize && buf[p] != 0x0a; p++) {
|
||||||
if (buf[p] == ':') {
|
if (buf[p] == ':') {
|
||||||
buf[p] = 0;
|
buf[p] = 0;
|
||||||
val = &buf[p + 1];
|
val = (char *) &buf[p + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (val == NULL || p == fsize)
|
if (val == NULL || p == fsize)
|
||||||
|
167
apps/pls.c
167
apps/pls.c
@ -1,167 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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");
|
|
||||||
}
|
|
128
apps/setmod2.c
128
apps/setmod2.c
@ -10,6 +10,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
#include <linux/dvb/mod.h>
|
#include <linux/dvb/mod.h>
|
||||||
|
|
||||||
@ -31,17 +32,134 @@ static int set_property(int fd, uint32_t cmd, uint32_t data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
static int get_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;
|
||||||
|
ret = ioctl(fd, FE_GET_PROPERTY, &c);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "FE_GET_PROPERTY returned %d\n", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*data = p.u.data;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char*argv[])
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct dvb_mod_params mp;
|
struct dvb_mod_params mp;
|
||||||
struct dvb_mod_channel_params mc;
|
struct dvb_mod_channel_params mc;
|
||||||
|
uint32_t data;
|
||||||
|
int32_t adapter = 0, channel = 0, gain = -1, att=-1, mod=-1;
|
||||||
|
int32_t base = -1, freq = -1, rate = -1, srate = -1;
|
||||||
|
char mod_name[128];
|
||||||
|
|
||||||
fd = open("/dev/dvb/adapter0/mod0", O_RDONLY);
|
while (1) {
|
||||||
|
int cur_optind = optind ? optind : 1;
|
||||||
|
int option_index = 0;
|
||||||
|
int c;
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"adapter", required_argument, 0, 'a'},
|
||||||
|
{"channel", required_argument, 0, 'c'},
|
||||||
|
{"att", required_argument, 0, 't'},
|
||||||
|
{"gain", required_argument, 0, 'g'},
|
||||||
|
{"base", required_argument, 0, 'b'},
|
||||||
|
{"frequency", required_argument, 0, 'f'},
|
||||||
|
{"rate", required_argument, 0, 'r'},
|
||||||
|
{"modulation", required_argument, 0, 'm'},
|
||||||
|
{"symbolrate", required_argument, 0, 's'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
c = getopt_long(argc, argv,
|
||||||
|
"a:c:g:b:f:r:t:m:s:",
|
||||||
|
long_options, &option_index);
|
||||||
|
if (c==-1)
|
||||||
|
break;
|
||||||
|
|
||||||
set_property(fd, MODULATOR_MODULATION, QAM_256);
|
switch (c) {
|
||||||
set_property(fd, MODULATOR_SYMBOL_RATE, 6900000);
|
case 'a':
|
||||||
set_property(fd, MODULATOR_FREQUENCY, 114000000);
|
adapter = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
channel = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
gain = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
att = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
base = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
freq = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
mod = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
srate = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
if (!strcmp(optarg, "DVBT_8"))
|
||||||
|
rate = SYS_DVBT_8;
|
||||||
|
else if (!strcmp(optarg, "DVBT_7"))
|
||||||
|
rate = SYS_DVBT_7;
|
||||||
|
else if (!strcmp(optarg, "DVBT_6"))
|
||||||
|
rate = SYS_DVBT_6;
|
||||||
|
else if (!strcmp(optarg, "ISDBT_6"))
|
||||||
|
rate = SYS_ISDBT_6;
|
||||||
|
else rate = strtoul(optarg, NULL, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind < argc) {
|
||||||
|
printf("too many arguments\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(mod_name, 127, "/dev/dvb/adapter%d/mod%d", adapter, channel);
|
||||||
|
fd = open(mod_name, O_RDONLY);
|
||||||
|
|
||||||
|
if (fd < 0) {
|
||||||
|
printf("Could not open modulator device.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* gain 0-255 */
|
||||||
|
//get_property(fd, MODULATOR_GAIN, &data);
|
||||||
|
//printf("Modulator gain = %u\n", data);
|
||||||
|
//set_property(fd, MODULATOR_GAIN, 100);
|
||||||
|
|
||||||
|
//get_property(fd, MODULATOR_ATTENUATOR, &data);
|
||||||
|
//printf("Modulator attenuator = %u\n", data);
|
||||||
|
|
||||||
|
if (att >= 0)
|
||||||
|
set_property(fd, MODULATOR_ATTENUATOR, att);
|
||||||
|
if (gain >= 0)
|
||||||
|
set_property(fd, MODULATOR_GAIN, gain);
|
||||||
|
if (base > 0)
|
||||||
|
set_property(fd, MODULATOR_BASE_FREQUENCY, base);
|
||||||
|
if (freq > 0)
|
||||||
|
set_property(fd, MODULATOR_FREQUENCY, freq);
|
||||||
|
if (rate > 0)
|
||||||
|
set_property(fd, MODULATOR_OUTPUT_RATE, rate);
|
||||||
|
if (mod >= 0)
|
||||||
|
set_property(fd, MODULATOR_MODULATION, mod);
|
||||||
|
if (srate > 0)
|
||||||
|
set_property(fd, MODULATOR_SYMBOL_RATE, srate);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
149
apps/setmod3.c
149
apps/setmod3.c
@ -1,149 +0,0 @@
|
|||||||
#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 <getopt.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_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;
|
|
||||||
ret = ioctl(fd, FE_GET_PROPERTY, &c);
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "FE_GET_PROPERTY returned %d\n", ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*data = p.u.data;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char*argv[])
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
struct dvb_mod_params mp;
|
|
||||||
struct dvb_mod_channel_params mc;
|
|
||||||
uint32_t data;
|
|
||||||
int32_t adapter = 0, channel = 0, gain = -1;
|
|
||||||
int32_t base = -1, freq = -1, rate = -1;
|
|
||||||
char mod_name[128];
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
int cur_optind = optind ? optind : 1;
|
|
||||||
int option_index = 0;
|
|
||||||
int c;
|
|
||||||
static struct option long_options[] = {
|
|
||||||
{"adapter", required_argument, 0, 'a'},
|
|
||||||
{"channel", required_argument, 0, 'c'},
|
|
||||||
{"gain", required_argument, 0, 'g'},
|
|
||||||
{"base", required_argument, 0, 'b'},
|
|
||||||
{"frequency", required_argument, 0, 'f'},
|
|
||||||
{"rate", required_argument, 0, 'r'},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
c = getopt_long(argc, argv,
|
|
||||||
"a:c:g:b:f:r:",
|
|
||||||
long_options, &option_index);
|
|
||||||
if (c==-1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'a':
|
|
||||||
adapter = strtoul(optarg, NULL, 0);
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
channel = strtoul(optarg, NULL, 0);
|
|
||||||
break;
|
|
||||||
case 'g':
|
|
||||||
gain = strtoul(optarg, NULL, 0);
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
base = strtoul(optarg, NULL, 0);
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
freq = strtoul(optarg, NULL, 0);
|
|
||||||
break;
|
|
||||||
case 'r':
|
|
||||||
if (!strcmp(optarg, "DVBT_8"))
|
|
||||||
rate = SYS_DVBT_8;
|
|
||||||
else if (!strcmp(optarg, "DVBT_7"))
|
|
||||||
rate = SYS_DVBT_7;
|
|
||||||
else if (!strcmp(optarg, "DVBT_6"))
|
|
||||||
rate = SYS_DVBT_6;
|
|
||||||
else if (!strcmp(optarg, "ISDBT_6"))
|
|
||||||
rate = SYS_ISDBT_6;
|
|
||||||
else rate = strtoul(optarg, NULL, 0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (optind < argc) {
|
|
||||||
printf("too many arguments\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(mod_name, 127, "/dev/dvb/adapter%d/mod%d", adapter, channel);
|
|
||||||
fd = open(mod_name, O_RDONLY);
|
|
||||||
|
|
||||||
if (fd < 0) {
|
|
||||||
printf("Could not open modulator device.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* gain 0-255 */
|
|
||||||
//get_property(fd, MODULATOR_GAIN, &data);
|
|
||||||
//printf("Modulator gain = %u\n", data);
|
|
||||||
//set_property(fd, MODULATOR_GAIN, 100);
|
|
||||||
|
|
||||||
//get_property(fd, MODULATOR_ATTENUATOR, &data);
|
|
||||||
//printf("Modulator attenuator = %u\n", data);
|
|
||||||
|
|
||||||
if (gain > 0)
|
|
||||||
set_property(fd, MODULATOR_GAIN, gain);
|
|
||||||
if (base > 0)
|
|
||||||
set_property(fd, MODULATOR_BASE_FREQUENCY, base);
|
|
||||||
if (freq > 0)
|
|
||||||
set_property(fd, MODULATOR_FREQUENCY, freq);
|
|
||||||
if (rate > 0)
|
|
||||||
set_property(fd, MODULATOR_OUTPUT_RATE, rate);
|
|
||||||
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
105
apps/tscheck.c
105
apps/tscheck.c
@ -1,105 +0,0 @@
|
|||||||
#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 <linux/dvb/dmx.h>
|
|
||||||
#include <linux/dvb/frontend.h>
|
|
||||||
#include <linux/dvb/video.h>
|
|
||||||
|
|
||||||
char line_start[16] = "";
|
|
||||||
char line_end[16] = "\r";
|
|
||||||
|
|
||||||
|
|
||||||
uint32_t cc_errors = 0;
|
|
||||||
uint32_t packets = 0;
|
|
||||||
uint32_t payload_packets = 0;
|
|
||||||
uint32_t packet_errors = 0;
|
|
||||||
|
|
||||||
uint8_t cc[8192] = { 0 };
|
|
||||||
|
|
||||||
void proc_ts(int i, uint8_t *buf)
|
|
||||||
{
|
|
||||||
uint16_t pid= 0x1fff& ((buf[1] << 8) | buf[2]);
|
|
||||||
uint8_t ccin = buf[3] & 0x1f;
|
|
||||||
|
|
||||||
if( buf[0] == 0x47 && (buf[1] & 0x80) == 0) {
|
|
||||||
if( pid != 8191 ) {
|
|
||||||
if (ccin & 0x10) {
|
|
||||||
if( cc[pid] != 0 ) {
|
|
||||||
// TODO: 1 repetition allowed
|
|
||||||
if ((((cc[pid] + 1) & 0x0F) != (ccin & 0x0F)) ) {
|
|
||||||
cc_errors += 1;
|
|
||||||
printf("%04x: %u != %u\n", pid, (cc[pid] + 1) & 0x0F, ccin & 0x0F);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cc[pid] = ccin;
|
|
||||||
}
|
|
||||||
payload_packets += 1;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
packet_errors += 1;
|
|
||||||
|
|
||||||
if( (packets & 0x3FFF ) == 0) {
|
|
||||||
printf("%s Packets: %12u non null %12u, errors: %12u, CC errors: %12u%s",
|
|
||||||
line_start, packets, payload_packets, packet_errors, cc_errors, line_end);
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
packets += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define TSBUFSIZE (100*188)
|
|
||||||
|
|
||||||
void citest(char* n)
|
|
||||||
{
|
|
||||||
uint8_t *buf;
|
|
||||||
uint8_t id;
|
|
||||||
int i, nts;
|
|
||||||
int len;
|
|
||||||
int ts=open(n, O_RDONLY);
|
|
||||||
buf=(uint8_t *)malloc(TSBUFSIZE);
|
|
||||||
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
len=read(ts, buf, TSBUFSIZE);
|
|
||||||
if (len<0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (buf[0]!=0x47) {
|
|
||||||
read(ts, buf, 1);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (len%188) { /* should not happen */
|
|
||||||
printf("blah\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
nts=len/188;
|
|
||||||
for (i=0; i<nts; i++)
|
|
||||||
proc_ts(i, buf+i*188);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
if( argc < 2 )
|
|
||||||
{
|
|
||||||
printf("tscheck <file>|<device> [<display line>]\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
if( argc > 2 )
|
|
||||||
{
|
|
||||||
int line = atoi(argv[2]);
|
|
||||||
if( line >= 0 && line < 64 )
|
|
||||||
{
|
|
||||||
snprintf(line_start,sizeof(line_start)-1,"\0337\033[%d;0H",line);
|
|
||||||
strncpy(line_end,"\0338",sizeof(line_end)-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
citest(argv[1]);
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +1,14 @@
|
|||||||
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 -DCONFIG_DVB_CXD2099 -DCONFIG_DVB_NET
|
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 -DCONFIG_DVB_CXD2099 -DCONFIG_DVB_NET -DCONFIG_DVB_TDA18271C2DD
|
||||||
|
|
||||||
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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.o
|
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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.o
|
||||||
|
|
||||||
#mci-objs = ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o ddbridge-io.o
|
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||||
|
|
||||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o #mci.o
|
ifneq ($(KERNEL_DVB_CORE),y)
|
||||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||||
|
endif
|
||||||
|
|
||||||
#EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -Idrivers/media/dvb-frontends
|
#EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -Idrivers/media/dvb-frontends
|
||||||
#EXTRA_CFLAGS += -Idrivers/media/common/tuners
|
#EXTRA_CFLAGS += -Idrivers/media/common/tuners
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
#
|
#
|
||||||
# Makefile for the ddbridge device driver
|
# Makefile for the ddbridge device driver
|
||||||
#
|
#
|
||||||
#NOSTDINC_FLAGS += -I$(KBUILD_EXTMOD)/include -I$(KBUILD_EXTMOD)/include/linux -I$(KBUILD_EXTMOD)/dvb-frontends -I$(KBUILD_EXTMOD)/tuners
|
|
||||||
|
|
||||||
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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.o
|
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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.o
|
||||||
|
|
||||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||||
|
|
||||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||||
|
|
||||||
#ccflags-y += -Idrivers/media/include/linux/
|
ccflags-y += -Idrivers/media/dvb-frontends/
|
||||||
#ccflags-y += -Idrivers/media/dvb-frontends/
|
ccflags-y += -Idrivers/media/tuners/
|
||||||
#ccflags-y += -Idrivers/media/tuners/
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.o
|
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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.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 ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.o
|
octonet-objs = octonet-main.o ddbridge-hw.o ddbridge-i2c.o ddbridge-ns.o ddbridge-core.o ddbridge-io.o ddbridge-ci.o ddbridge-max.o ddbridge-mci.o ddbridge-sx8.o ddbridge-m4.o dvb_netstream.o
|
||||||
|
|
||||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||||
@ -11,4 +11,5 @@ obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
|||||||
ccflags-y += -Idrivers/media/dvb-core/
|
ccflags-y += -Idrivers/media/dvb-core/
|
||||||
ccflags-y += -Idrivers/media/dvb-frontends/
|
ccflags-y += -Idrivers/media/dvb-frontends/
|
||||||
ccflags-y += -Idrivers/media/tuners/
|
ccflags-y += -Idrivers/media/tuners/
|
||||||
|
ccflags-y += --include=dd_compat.h
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ static int wait_ci_ready(struct ddb_ci *ci)
|
|||||||
ndelay(500);
|
ndelay(500);
|
||||||
do {
|
do {
|
||||||
if (ddbreadl(ci->port->dev,
|
if (ddbreadl(ci->port->dev,
|
||||||
CI_CONTROL(ci->nr)) & CI_READY)
|
CI_CONTROL(ci)) & CI_READY)
|
||||||
break;
|
break;
|
||||||
usleep_range(1, 2);
|
usleep_range(1, 2);
|
||||||
if ((--count) == 0)
|
if ((--count) == 0)
|
||||||
@ -45,14 +45,15 @@ static int read_attribute_mem(struct dvb_ca_en50221 *ca,
|
|||||||
int slot, int address)
|
int slot, int address)
|
||||||
{
|
{
|
||||||
struct ddb_ci *ci = ca->data;
|
struct ddb_ci *ci = ca->data;
|
||||||
u32 val, off = (address >> 1) & (CI_BUFFER_SIZE - 1);
|
u32 off = (address >> 1) & (CI_BUFFER_SIZE - 1);
|
||||||
|
u8 val;
|
||||||
|
|
||||||
if (address > CI_BUFFER_SIZE)
|
if (address > CI_BUFFER_SIZE)
|
||||||
return -1;
|
return -1;
|
||||||
ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address,
|
ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address,
|
||||||
CI_DO_READ_ATTRIBUTES(ci->nr));
|
CI_DO_READ_ATTRIBUTES(ci));
|
||||||
wait_ci_ready(ci);
|
wait_ci_ready(ci);
|
||||||
val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off);
|
ddbcpyfrom(ci->port->dev, &val, CI_BUFFER(ci->nr) + off, 1);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
|
|||||||
struct ddb_ci *ci = ca->data;
|
struct ddb_ci *ci = ca->data;
|
||||||
|
|
||||||
ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
|
ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
|
||||||
CI_DO_ATTRIBUTE_RW(ci->nr));
|
CI_DO_ATTRIBUTE_RW(ci));
|
||||||
wait_ci_ready(ci);
|
wait_ci_ready(ci);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -75,10 +76,10 @@ static int read_cam_control(struct dvb_ca_en50221 *ca,
|
|||||||
u32 res;
|
u32 res;
|
||||||
|
|
||||||
ddbwritel(ci->port->dev, CI_READ_CMD | address,
|
ddbwritel(ci->port->dev, CI_READ_CMD | address,
|
||||||
CI_DO_IO_RW(ci->nr));
|
CI_DO_IO_RW(ci));
|
||||||
ndelay(500);
|
ndelay(500);
|
||||||
do {
|
do {
|
||||||
res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr));
|
res = ddbreadl(ci->port->dev, CI_READDATA(ci));
|
||||||
if (res & CI_READY)
|
if (res & CI_READY)
|
||||||
break;
|
break;
|
||||||
usleep_range(1, 2);
|
usleep_range(1, 2);
|
||||||
@ -94,7 +95,7 @@ static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
|
|||||||
struct ddb_ci *ci = ca->data;
|
struct ddb_ci *ci = ca->data;
|
||||||
|
|
||||||
ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
|
ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
|
||||||
CI_DO_IO_RW(ci->nr));
|
CI_DO_IO_RW(ci));
|
||||||
wait_ci_ready(ci);
|
wait_ci_ready(ci);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -104,15 +105,15 @@ static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
|
|||||||
struct ddb_ci *ci = ca->data;
|
struct ddb_ci *ci = ca->data;
|
||||||
|
|
||||||
ddbwritel(ci->port->dev, CI_POWER_ON,
|
ddbwritel(ci->port->dev, CI_POWER_ON,
|
||||||
CI_CONTROL(ci->nr));
|
CI_CONTROL(ci));
|
||||||
msleep(100);
|
msleep(300);
|
||||||
ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM,
|
ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM,
|
||||||
CI_CONTROL(ci->nr));
|
CI_CONTROL(ci));
|
||||||
ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM,
|
ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM,
|
||||||
CI_CONTROL(ci->nr));
|
CI_CONTROL(ci));
|
||||||
usleep_range(20, 25);
|
msleep(20);
|
||||||
ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON,
|
ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON,
|
||||||
CI_CONTROL(ci->nr));
|
CI_CONTROL(ci));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
|
|||||||
{
|
{
|
||||||
struct ddb_ci *ci = ca->data;
|
struct ddb_ci *ci = ca->data;
|
||||||
|
|
||||||
ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr));
|
ddbwritel(ci->port->dev, 0, CI_CONTROL(ci));
|
||||||
msleep(300);
|
msleep(300);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -128,17 +129,17 @@ static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
|
|||||||
static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
|
static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
|
||||||
{
|
{
|
||||||
struct ddb_ci *ci = ca->data;
|
struct ddb_ci *ci = ca->data;
|
||||||
u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
|
u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci));
|
||||||
|
|
||||||
ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE,
|
ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE,
|
||||||
CI_CONTROL(ci->nr));
|
CI_CONTROL(ci));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
|
static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
|
||||||
{
|
{
|
||||||
struct ddb_ci *ci = ca->data;
|
struct ddb_ci *ci = ca->data;
|
||||||
u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
|
u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci));
|
||||||
int stat = 0;
|
int stat = 0;
|
||||||
|
|
||||||
if (val & CI_CAM_DETECT)
|
if (val & CI_CAM_DETECT)
|
||||||
@ -162,6 +163,8 @@ static struct dvb_ca_en50221 en_templ = {
|
|||||||
static void ci_attach(struct ddb_port *port)
|
static void ci_attach(struct ddb_port *port)
|
||||||
{
|
{
|
||||||
struct ddb_ci *ci;
|
struct ddb_ci *ci;
|
||||||
|
const struct ddb_info *info = port->dev->link[port->lnr].info;
|
||||||
|
u32 off = info->ci_base ? info->ci_base : 0x400;
|
||||||
|
|
||||||
ci = kzalloc(sizeof(*ci), GFP_KERNEL);
|
ci = kzalloc(sizeof(*ci), GFP_KERNEL);
|
||||||
if (!ci)
|
if (!ci)
|
||||||
@ -171,6 +174,7 @@ static void ci_attach(struct ddb_port *port)
|
|||||||
port->en = &ci->en;
|
port->en = &ci->en;
|
||||||
ci->port = port;
|
ci->port = port;
|
||||||
ci->nr = port->nr - 2;
|
ci->nr = port->nr - 2;
|
||||||
|
ci->regs = DDB_LINK_TAG(port->lnr) | (off + 32 * ci->nr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DuoFlex Dual CI support */
|
/* DuoFlex Dual CI support */
|
||||||
@ -234,9 +238,11 @@ static int slot_reset_xo2(struct dvb_ca_en50221 *ca, int slot)
|
|||||||
{
|
{
|
||||||
struct ddb_ci *ci = ca->data;
|
struct ddb_ci *ci = ca->data;
|
||||||
|
|
||||||
|
write_creg(ci, 0x00, 0x01);
|
||||||
|
msleep(300);
|
||||||
write_creg(ci, 0x01, 0x01);
|
write_creg(ci, 0x01, 0x01);
|
||||||
write_creg(ci, 0x04, 0x04);
|
write_creg(ci, 0x04, 0x04);
|
||||||
msleep(20);
|
msleep(300);
|
||||||
write_creg(ci, 0x02, 0x02);
|
write_creg(ci, 0x02, 0x02);
|
||||||
write_creg(ci, 0x00, 0x04);
|
write_creg(ci, 0x00, 0x04);
|
||||||
write_creg(ci, 0x18, 0x18);
|
write_creg(ci, 0x18, 0x18);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -246,7 +246,6 @@ static const struct ddb_regmap octopus_map = {
|
|||||||
.odma = &octopus_odma,
|
.odma = &octopus_odma,
|
||||||
.odma_buf = &octopus_odma_buf,
|
.odma_buf = &octopus_odma_buf,
|
||||||
.input = &octopus_input,
|
.input = &octopus_input,
|
||||||
|
|
||||||
.output = &octopus_output,
|
.output = &octopus_output,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -315,10 +314,14 @@ static const struct ddb_regmap octopus_mod_2_map = {
|
|||||||
.irq_version = 2,
|
.irq_version = 2,
|
||||||
.irq_base_odma = 64,
|
.irq_base_odma = 64,
|
||||||
.irq_base_rate = 32,
|
.irq_base_rate = 32,
|
||||||
|
.irq_base_mci = 10,
|
||||||
.output = &octopus_output,
|
.output = &octopus_output,
|
||||||
.odma = &octopus_mod_2_odma,
|
.odma = &octopus_mod_2_odma,
|
||||||
.odma_buf = &octopus_mod_2_odma_buf,
|
.odma_buf = &octopus_mod_2_odma_buf,
|
||||||
.channel = &octopus_mod_2_channel,
|
.channel = &octopus_mod_2_channel,
|
||||||
|
|
||||||
|
.mci = &sdr_mci,
|
||||||
|
.mci_buf = &sdr_mci_buf,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_regmap octopus_sdr_map = {
|
static const struct ddb_regmap octopus_sdr_map = {
|
||||||
@ -459,23 +462,25 @@ static const struct ddb_info ddb_satixs2v3 = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_ci = {
|
static const struct ddb_info ddb_ci = {
|
||||||
.type = DDB_OCTOPUS_CI,
|
.type = DDB_OCTOPUS,
|
||||||
.name = "Digital Devices Octopus CI",
|
.name = "Digital Devices Octopus CI",
|
||||||
.regmap = &octopus_map,
|
.regmap = &octopus_map,
|
||||||
.port_num = 4,
|
.port_num = 4,
|
||||||
.i2c_mask = 0x03,
|
.i2c_mask = 0x03,
|
||||||
|
.ci_mask = 0x0c,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_cis = {
|
static const struct ddb_info ddb_cis = {
|
||||||
.type = DDB_OCTOPUS_CI,
|
.type = DDB_OCTOPUS,
|
||||||
.name = "Digital Devices Octopus CI single",
|
.name = "Digital Devices Octopus CI single",
|
||||||
.regmap = &octopus_map,
|
.regmap = &octopus_map,
|
||||||
.port_num = 3,
|
.port_num = 3,
|
||||||
.i2c_mask = 0x03,
|
.i2c_mask = 0x03,
|
||||||
|
.ci_mask = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_ci_s2_pro = {
|
static const struct ddb_info ddb_ci_s2_pro = {
|
||||||
.type = DDB_OCTOPUS_CI,
|
.type = DDB_OCTOPUS,
|
||||||
.name = "Digital Devices Octopus CI S2 Pro",
|
.name = "Digital Devices Octopus CI S2 Pro",
|
||||||
.regmap = &octopus_map,
|
.regmap = &octopus_map,
|
||||||
.port_num = 4,
|
.port_num = 4,
|
||||||
@ -483,10 +488,11 @@ static const struct ddb_info ddb_ci_s2_pro = {
|
|||||||
.board_control = 2,
|
.board_control = 2,
|
||||||
.board_control_2 = 4,
|
.board_control_2 = 4,
|
||||||
.hw_min = 0x010007,
|
.hw_min = 0x010007,
|
||||||
|
.ci_mask = 0x0c,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_ci_s2_pro_a = {
|
static const struct ddb_info ddb_ci_s2_pro_a = {
|
||||||
.type = DDB_OCTOPUS_CI,
|
.type = DDB_OCTOPUS,
|
||||||
.name = "Digital Devices Octopus CI S2 Pro Advanced",
|
.name = "Digital Devices Octopus CI S2 Pro Advanced",
|
||||||
.regmap = &octopus_map,
|
.regmap = &octopus_map,
|
||||||
.port_num = 4,
|
.port_num = 4,
|
||||||
@ -494,6 +500,7 @@ static const struct ddb_info ddb_ci_s2_pro_a = {
|
|||||||
.board_control = 2,
|
.board_control = 2,
|
||||||
.board_control_2 = 4,
|
.board_control_2 = 4,
|
||||||
.hw_min = 0x010007,
|
.hw_min = 0x010007,
|
||||||
|
.ci_mask = 0x0c,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_dvbct = {
|
static const struct ddb_info ddb_dvbct = {
|
||||||
@ -566,6 +573,17 @@ static const struct ddb_info ddb_mod_fsm_4 = {
|
|||||||
.lostlock_irq = 9,
|
.lostlock_irq = 9,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct ddb_info ddb_mod_fsm = {
|
||||||
|
.type = DDB_MOD,
|
||||||
|
.name = "Digital Devices DVB-C FSM",
|
||||||
|
.version = 2,
|
||||||
|
.regmap = &octopus_mod_2_map,
|
||||||
|
.port_num = 0,
|
||||||
|
.temp_num = 1,
|
||||||
|
.tempmon_irq = 8,
|
||||||
|
.lostlock_irq = 9,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_sdr_atv = {
|
static const struct ddb_info ddb_sdr_atv = {
|
||||||
.type = DDB_MOD,
|
.type = DDB_MOD,
|
||||||
.name = "Digital Devices SDR ATV",
|
.name = "Digital Devices SDR ATV",
|
||||||
@ -601,27 +619,19 @@ static const struct ddb_info ddb_sdr_dvbt = {
|
|||||||
.name = "Digital Devices DVBT",
|
.name = "Digital Devices DVBT",
|
||||||
.version = 18,
|
.version = 18,
|
||||||
.regmap = &octopus_sdr_map,
|
.regmap = &octopus_sdr_map,
|
||||||
.port_num = 16,
|
.port_num = 14,
|
||||||
.temp_num = 1,
|
.temp_num = 1,
|
||||||
.tempmon_irq = 8,
|
.tempmon_irq = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_octopro_hdin = {
|
static const struct ddb_info ddb_sdr_dvbt_16 = {
|
||||||
.type = DDB_OCTOPRO_HDIN,
|
.type = DDB_MOD,
|
||||||
.name = "Digital Devices OctopusNet Pro HDIN",
|
.name = "Digital Devices DVBT",
|
||||||
.regmap = &octopro_hdin_map,
|
.version = 18,
|
||||||
.port_num = 10,
|
.regmap = &octopus_sdr_map,
|
||||||
.i2c_mask = 0x3ff,
|
.port_num = 16,
|
||||||
.mdio_base = 0x10020,
|
.temp_num = 1,
|
||||||
};
|
.tempmon_irq = 8,
|
||||||
|
|
||||||
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_base = 0x10020,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_s2_48 = {
|
static const struct ddb_info ddb_s2_48 = {
|
||||||
@ -632,6 +642,7 @@ static const struct ddb_info ddb_s2_48 = {
|
|||||||
.i2c_mask = 0x01,
|
.i2c_mask = 0x01,
|
||||||
.board_control = 1,
|
.board_control = 1,
|
||||||
.tempmon_irq = 24,
|
.tempmon_irq = 24,
|
||||||
|
.lnb_base = 0x400,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_ct2_8 = {
|
static const struct ddb_info ddb_ct2_8 = {
|
||||||
@ -704,8 +715,9 @@ static const struct ddb_info ddb_s2x_48 = {
|
|||||||
.i2c_mask = 0x00,
|
.i2c_mask = 0x00,
|
||||||
.tempmon_irq = 24,
|
.tempmon_irq = 24,
|
||||||
.mci_ports = 4,
|
.mci_ports = 4,
|
||||||
.mci_type = 0,
|
.mci_type = DDB_TUNER_MCI_SX8,
|
||||||
.temp_num = 1,
|
.temp_num = 1,
|
||||||
|
.lnb_base = 0x400,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_s2x_48_b = {
|
static const struct ddb_info ddb_s2x_48_b = {
|
||||||
@ -716,8 +728,9 @@ static const struct ddb_info ddb_s2x_48_b = {
|
|||||||
.i2c_mask = 0x00,
|
.i2c_mask = 0x00,
|
||||||
.tempmon_irq = 24,
|
.tempmon_irq = 24,
|
||||||
.mci_ports = 4,
|
.mci_ports = 4,
|
||||||
.mci_type = 0,
|
.mci_type = DDB_TUNER_MCI_SX8,
|
||||||
.temp_num = 1,
|
.temp_num = 1,
|
||||||
|
.lnb_base = 0x400,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct ddb_info ddb_m4 = {
|
static const struct ddb_info ddb_m4 = {
|
||||||
@ -728,8 +741,72 @@ static const struct ddb_info ddb_m4 = {
|
|||||||
.i2c_mask = 0x00,
|
.i2c_mask = 0x00,
|
||||||
.tempmon_irq = 24,
|
.tempmon_irq = 24,
|
||||||
.mci_ports = 2,
|
.mci_ports = 2,
|
||||||
.mci_type = 1,
|
.mci_type = DDB_TUNER_MCI_M4,
|
||||||
.temp_num = 1,
|
.temp_num = 1,
|
||||||
|
.lnb_base = 0x400,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ddb_info ddb_m8 = {
|
||||||
|
.type = DDB_OCTOPUS_MCI,
|
||||||
|
.name = "Digital Devices MAX M8",
|
||||||
|
.regmap = &octopus_mci_map,
|
||||||
|
.port_num = 4,
|
||||||
|
.i2c_mask = 0x00,
|
||||||
|
.tempmon_irq = 24,
|
||||||
|
.mci_ports = 4,
|
||||||
|
.mci_type = DDB_TUNER_MCI_M8,
|
||||||
|
.temp_num = 1,
|
||||||
|
.lnb_base = 0x400,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ddb_info ddb_m8a = {
|
||||||
|
.type = DDB_OCTOPUS_MCI,
|
||||||
|
.name = "Digital Devices MAX M8A",
|
||||||
|
.regmap = &octopus_mci_map,
|
||||||
|
.port_num = 4,
|
||||||
|
.tempmon_irq = 24,
|
||||||
|
.mci_ports = 4,
|
||||||
|
.mci_type = DDB_TUNER_MCI_M8A,
|
||||||
|
.temp_num = 1,
|
||||||
|
.lnb_base = 0x400,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ddb_info ddb_m8e = {
|
||||||
|
.type = DDB_OCTOPUS_MCI,
|
||||||
|
.name = "Digital Devices MAX M8E",
|
||||||
|
.regmap = &octopus_mci_map,
|
||||||
|
.port_num = 4,
|
||||||
|
.tempmon_irq = 24,
|
||||||
|
.mci_ports = 4,
|
||||||
|
.mci_type = DDB_TUNER_MCI_M8E,
|
||||||
|
.temp_num = 1,
|
||||||
|
.lnb_base = 0x400,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ddb_info ddb_ci_m2 = {
|
||||||
|
.type = DDB_OCTOPUS_MCI,
|
||||||
|
.name = "Digital Devices Octopus CI M2",
|
||||||
|
.regmap = &octopus_mci_map,
|
||||||
|
.port_num = 4,
|
||||||
|
.tempmon_irq = 24,
|
||||||
|
.mci_ports = 1,
|
||||||
|
.mci_type = DDB_TUNER_MCI_M2,
|
||||||
|
.temp_num = 1,
|
||||||
|
.ci_mask = 0x0c,
|
||||||
|
.ci_base = 0x400,
|
||||||
|
.lnb_base = 0x480,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct ddb_info ddb_m2 = {
|
||||||
|
.type = DDB_OCTOPUS_MCI,
|
||||||
|
.name = "Digital Devices Octopus M2",
|
||||||
|
.regmap = &octopus_mci_map,
|
||||||
|
.port_num = 4,
|
||||||
|
.tempmon_irq = 24,
|
||||||
|
.mci_ports = 1,
|
||||||
|
.mci_type = DDB_TUNER_MCI_M2,
|
||||||
|
.temp_num = 1,
|
||||||
|
.lnb_base = 0x480,
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@ -862,13 +939,19 @@ static const struct ddb_device_id ddb_device_ids[] = {
|
|||||||
DDB_DEVID(0x0012, 0x0042, ddb_ci),
|
DDB_DEVID(0x0012, 0x0042, ddb_ci),
|
||||||
DDB_DEVID(0x0013, 0x0043, ddb_ci_s2_pro),
|
DDB_DEVID(0x0013, 0x0043, ddb_ci_s2_pro),
|
||||||
DDB_DEVID(0x0013, 0x0044, ddb_ci_s2_pro_a),
|
DDB_DEVID(0x0013, 0x0044, ddb_ci_s2_pro_a),
|
||||||
|
DDB_DEVID(0x0014, 0x0045, ddb_ci_m2),
|
||||||
DDB_DEVID(0x0020, 0x0012, ddb_gtl_mini),
|
DDB_DEVID(0x0020, 0x0012, ddb_gtl_mini),
|
||||||
|
DDB_DEVID(0x0022, 0x0052, ddb_m8),
|
||||||
|
DDB_DEVID(0x0024, 0x0053, ddb_m8a),
|
||||||
|
DDB_DEVID(0x0025, 0x0054, ddb_m2),
|
||||||
|
DDB_DEVID(0x0026, 0x0055, ddb_m8e),
|
||||||
|
|
||||||
/* Modulators */
|
/* Modulators */
|
||||||
DDB_DEVID(0x0201, 0x0001, ddb_mod),
|
DDB_DEVID(0x0201, 0x0001, ddb_mod),
|
||||||
DDB_DEVID(0x0201, 0x0002, ddb_mod),
|
DDB_DEVID(0x0201, 0x0002, ddb_mod),
|
||||||
DDB_DEVID(0x0201, 0x0004, ddb_mod_4), /* dummy entry ! */
|
DDB_DEVID(0x0201, 0x0004, ddb_mod_4), /* dummy entry ! */
|
||||||
DDB_DEVID(0x0203, 0x0001, ddb_mod),
|
DDB_DEVID(0x0203, 0x0001, ddb_mod),
|
||||||
|
DDB_DEVID(0x0210, 0x0004, ddb_mod_fsm), /* dummy entry ! */
|
||||||
DDB_DEVID(0x0210, 0x0000, ddb_mod_fsm_4), /* dummy entry ! */
|
DDB_DEVID(0x0210, 0x0000, ddb_mod_fsm_4), /* dummy entry ! */
|
||||||
DDB_DEVID(0x0210, 0x0001, ddb_mod_fsm_24),
|
DDB_DEVID(0x0210, 0x0001, ddb_mod_fsm_24),
|
||||||
DDB_DEVID(0x0210, 0x0002, ddb_mod_fsm_16),
|
DDB_DEVID(0x0210, 0x0002, ddb_mod_fsm_16),
|
||||||
@ -876,16 +959,8 @@ static const struct ddb_device_id ddb_device_ids[] = {
|
|||||||
DDB_DEVID(0x0220, 0x0001, ddb_sdr_atv),
|
DDB_DEVID(0x0220, 0x0001, ddb_sdr_atv),
|
||||||
DDB_DEVID(0x0221, 0x0001, ddb_sdr_iq),
|
DDB_DEVID(0x0221, 0x0001, ddb_sdr_iq),
|
||||||
DDB_DEVID(0x0222, 0x0001, ddb_sdr_dvbt),
|
DDB_DEVID(0x0222, 0x0001, ddb_sdr_dvbt),
|
||||||
|
DDB_DEVID(0x0222, 0x0002, ddb_sdr_dvbt_16), /* dummy entry ! */
|
||||||
DDB_DEVID(0x0223, 0x0001, ddb_sdr_iq2),
|
DDB_DEVID(0x0223, 0x0001, ddb_sdr_iq2),
|
||||||
DDB_DEVID(0xffff, 0xffff, ddb_sdr_iq2),
|
|
||||||
|
|
||||||
/* 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),
|
|
||||||
|
|
||||||
DDB_DEVID(0xffff, 0xffff, ddb_none),
|
DDB_DEVID(0xffff, 0xffff, ddb_none),
|
||||||
};
|
};
|
||||||
|
@ -72,11 +72,12 @@ static int search_s2(struct dvb_frontend *fe)
|
|||||||
cmd.dvbs2_search.retry = 0;
|
cmd.dvbs2_search.retry = 0;
|
||||||
cmd.dvbs2_search.frequency = p->frequency * 1000;
|
cmd.dvbs2_search.frequency = p->frequency * 1000;
|
||||||
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
|
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
|
||||||
cmd.dvbs2_search.scrambling_sequence_index = 0; //p->scrambling_sequence_index;
|
cmd.dvbs2_search.scrambling_sequence_index =
|
||||||
|
p->scrambling_sequence_index;
|
||||||
if (p->stream_id != NO_STREAM_ID_FILTER)
|
if (p->stream_id != NO_STREAM_ID_FILTER)
|
||||||
cmd.dvbs2_search.input_stream_id = p->stream_id;
|
cmd.dvbs2_search.input_stream_id = p->stream_id;
|
||||||
cmd.tuner = state->mci.nr;
|
cmd.tuner = state->mci.tuner;
|
||||||
cmd.demod = state->mci.tuner;
|
cmd.demod = state->mci.demod;
|
||||||
cmd.output = state->mci.nr;
|
cmd.output = state->mci.nr;
|
||||||
|
|
||||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||||
@ -404,7 +405,7 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status)
|
|||||||
ddb_mci_get_strength(fe);
|
ddb_mci_get_strength(fe);
|
||||||
if (res.status == MCI_DEMOD_WAIT_SIGNAL)
|
if (res.status == MCI_DEMOD_WAIT_SIGNAL)
|
||||||
*status = 0x01;
|
*status = 0x01;
|
||||||
else if (res.status == M4_DEMOD_WAIT_TS)
|
else if (res.status == MX_DEMOD_WAIT_TS)
|
||||||
*status = 0x03;
|
*status = 0x03;
|
||||||
else if (res.status == MCI_DEMOD_TIMEOUT)
|
else if (res.status == MCI_DEMOD_TIMEOUT)
|
||||||
*status = FE_TIMEDOUT;
|
*status = FE_TIMEDOUT;
|
||||||
@ -456,6 +457,9 @@ static void release(struct dvb_frontend *fe)
|
|||||||
kfree(mci_base);
|
kfree(mci_base);
|
||||||
}
|
}
|
||||||
kfree(state);
|
kfree(state);
|
||||||
|
#ifdef CONFIG_MEDIA_ATTACH
|
||||||
|
__module_get(THIS_MODULE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum dvbfe_algo get_algo(struct dvb_frontend *fe)
|
static enum dvbfe_algo get_algo(struct dvb_frontend *fe)
|
||||||
@ -473,9 +477,11 @@ static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties
|
|||||||
|
|
||||||
static struct dvb_frontend_ops m4_ops = {
|
static struct dvb_frontend_ops m4_ops = {
|
||||||
.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_C,
|
.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_C,
|
||||||
SYS_ISDBC, SYS_DVBC2,
|
SYS_DVBC2, SYS_DVBT, SYS_DVBT2, SYS_DVBS, SYS_DVBS2,
|
||||||
SYS_DVBT, SYS_DVBT2, SYS_ISDBT,
|
#ifndef KERNEL_DVB_CORE
|
||||||
SYS_DVBS, SYS_DVBS2, SYS_ISDBS, },
|
SYS_ISDBC, SYS_ISDBS, SYS_ISDBT,
|
||||||
|
#endif
|
||||||
|
},
|
||||||
.info = {
|
.info = {
|
||||||
.name = "M4",
|
.name = "M4",
|
||||||
.frequency_min_hz = 47125000, /* DVB-T: 47125000 */
|
.frequency_min_hz = 47125000, /* DVB-T: 47125000 */
|
||||||
@ -516,7 +522,7 @@ static int base_init(struct mci_base *mci_base)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mci_cfg ddb_max_m4_cfg = {
|
static struct mci_cfg ddb_max_m4_cfg = {
|
||||||
.type = 0,
|
.type = 0,
|
||||||
.fe_ops = &m4_ops,
|
.fe_ops = &m4_ops,
|
||||||
.base_size = sizeof(struct m4_base),
|
.base_size = sizeof(struct m4_base),
|
||||||
@ -524,3 +530,137 @@ struct mci_cfg ddb_max_m4_cfg = {
|
|||||||
.init = init,
|
.init = init,
|
||||||
.base_init = base_init,
|
.base_init = base_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct dvb_frontend_ops m_ops = {
|
||||||
|
.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_C,
|
||||||
|
SYS_DVBT, SYS_DVBT2, SYS_DVBS, SYS_DVBS2,
|
||||||
|
#ifndef KERNEL_DVB_CORE
|
||||||
|
SYS_ISDBC, SYS_ISDBS, SYS_ISDBT,
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
.info = {
|
||||||
|
.name = "M_AS",
|
||||||
|
.frequency_min_hz = 47125000, /* DVB-T: 47125000 */
|
||||||
|
.frequency_max_hz = 2150000000, /* DVB-C: 862000000 */
|
||||||
|
.symbol_rate_min = 100000,
|
||||||
|
.symbol_rate_max = 100000000,
|
||||||
|
.frequency_stepsize_hz = 0,
|
||||||
|
.frequency_tolerance_hz = 0,
|
||||||
|
.caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
|
||||||
|
FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 |
|
||||||
|
FE_CAN_QAM_AUTO |
|
||||||
|
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||||
|
FE_CAN_FEC_4_5 |
|
||||||
|
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
|
||||||
|
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||||
|
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
|
||||||
|
FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION
|
||||||
|
},
|
||||||
|
.release = release,
|
||||||
|
.get_frontend_algo = get_algo,
|
||||||
|
.get_frontend = get_frontend,
|
||||||
|
.read_status = read_status,
|
||||||
|
.tune = tune,
|
||||||
|
.sleep = sleep,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mci_cfg ddb_max_m_cfg = {
|
||||||
|
.type = 0,
|
||||||
|
.fe_ops = &m_ops,
|
||||||
|
.base_size = sizeof(struct m4_base),
|
||||||
|
.state_size = sizeof(struct m4),
|
||||||
|
.init = init,
|
||||||
|
.base_init = base_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dvb_frontend_ops m_s_ops = {
|
||||||
|
.delsys = { SYS_DVBS, SYS_DVBS2, SYS_ISDBS },
|
||||||
|
.info = {
|
||||||
|
.name = "M_S",
|
||||||
|
.frequency_min_hz = 47125000, /* DVB-T: 47125000 */
|
||||||
|
.frequency_max_hz = 2150000000, /* DVB-C: 862000000 */
|
||||||
|
.symbol_rate_min = 100000,
|
||||||
|
.symbol_rate_max = 100000000,
|
||||||
|
.frequency_stepsize_hz = 0,
|
||||||
|
.frequency_tolerance_hz = 0,
|
||||||
|
.caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
|
||||||
|
FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 |
|
||||||
|
FE_CAN_QAM_AUTO |
|
||||||
|
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||||
|
FE_CAN_FEC_4_5 |
|
||||||
|
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
|
||||||
|
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||||
|
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
|
||||||
|
FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION
|
||||||
|
},
|
||||||
|
.release = release,
|
||||||
|
.get_frontend_algo = get_algo,
|
||||||
|
.get_frontend = get_frontend,
|
||||||
|
.read_status = read_status,
|
||||||
|
.tune = tune,
|
||||||
|
.sleep = sleep,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mci_cfg ddb_max_m_s_cfg = {
|
||||||
|
.type = 0,
|
||||||
|
.fe_ops = &m_s_ops,
|
||||||
|
.base_size = sizeof(struct m4_base),
|
||||||
|
.state_size = sizeof(struct m4),
|
||||||
|
.init = init,
|
||||||
|
.base_init = base_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct dvb_frontend_ops m_a_ops = {
|
||||||
|
.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBC_ANNEX_B, SYS_DVBC_ANNEX_C,
|
||||||
|
SYS_ISDBC,
|
||||||
|
SYS_DVBT, SYS_DVBT2, SYS_ISDBT,
|
||||||
|
},
|
||||||
|
.info = {
|
||||||
|
.name = "M_A",
|
||||||
|
.frequency_min_hz = 47125000, /* DVB-T: 47125000 */
|
||||||
|
.frequency_max_hz = 2150000000, /* DVB-C: 862000000 */
|
||||||
|
.symbol_rate_min = 100000,
|
||||||
|
.symbol_rate_max = 100000000,
|
||||||
|
.frequency_stepsize_hz = 0,
|
||||||
|
.frequency_tolerance_hz = 0,
|
||||||
|
.caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
|
||||||
|
FE_CAN_QAM_64 | FE_CAN_QAM_128 | FE_CAN_QAM_256 |
|
||||||
|
FE_CAN_QAM_AUTO |
|
||||||
|
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
|
||||||
|
FE_CAN_FEC_4_5 |
|
||||||
|
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
|
||||||
|
FE_CAN_TRANSMISSION_MODE_AUTO |
|
||||||
|
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
|
||||||
|
FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION
|
||||||
|
},
|
||||||
|
.release = release,
|
||||||
|
.get_frontend_algo = get_algo,
|
||||||
|
.get_frontend = get_frontend,
|
||||||
|
.read_status = read_status,
|
||||||
|
.tune = tune,
|
||||||
|
.sleep = sleep,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mci_cfg ddb_max_m_a_cfg = {
|
||||||
|
.type = 0,
|
||||||
|
.fe_ops = &m_a_ops,
|
||||||
|
.base_size = sizeof(struct m4_base),
|
||||||
|
.state_size = sizeof(struct m4),
|
||||||
|
.init = init,
|
||||||
|
.base_init = base_init,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mci_cfg *ddb_max_cfgs [] = {
|
||||||
|
&ddb_max_m4_cfg,
|
||||||
|
&ddb_max_m_a_cfg,
|
||||||
|
&ddb_max_m_s_cfg,
|
||||||
|
&ddb_max_m_cfg,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dvb_frontend *ddb_mx_attach(struct ddb_input *input, int nr, int tuner, int type)
|
||||||
|
{
|
||||||
|
return ddb_mci_attach(input, ddb_max_cfgs[type & 3], nr, tuner);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT_SYMBOL(ddb_mx_attach);
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ int pci_irq_vector(struct pci_dev *dev, unsigned int nr)
|
|||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
static void __devexit ddb_irq_disable(struct ddb *dev)
|
static void ddb_irq_disable(struct ddb *dev)
|
||||||
{
|
{
|
||||||
if (dev->link[0].info->regmap->irq_version == 2) {
|
if (dev->link[0].info->regmap->irq_version == 2) {
|
||||||
ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
|
ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
|
||||||
@ -114,7 +114,7 @@ static void __devexit ddb_msi_exit(struct ddb *dev)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __devexit ddb_irq_exit(struct ddb *dev)
|
static void ddb_irq_exit(struct ddb *dev)
|
||||||
{
|
{
|
||||||
ddb_irq_disable(dev);
|
ddb_irq_disable(dev);
|
||||||
if (dev->msi == 2)
|
if (dev->msi == 2)
|
||||||
@ -255,17 +255,9 @@ static int __devinit ddb_irq_init(struct ddb *dev)
|
|||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#ifdef DDB_TEST_THREADED
|
|
||||||
stat = request_threaded_irq(pci_irq_vector(dev->pdev, 0),
|
|
||||||
dev->pdev->irq, ddb_irq_handler,
|
|
||||||
irq_thread,
|
|
||||||
irq_flag,
|
|
||||||
"ddbridge", (void *)dev);
|
|
||||||
#else
|
|
||||||
stat = request_irq(pci_irq_vector(dev->pdev, 0),
|
stat = request_irq(pci_irq_vector(dev->pdev, 0),
|
||||||
ddb_irq_handler,
|
ddb_irq_handler,
|
||||||
irq_flag, "ddbridge", (void *)dev);
|
irq_flag, "ddbridge", (void *)dev);
|
||||||
#endif
|
|
||||||
if (stat < 0)
|
if (stat < 0)
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
@ -291,11 +283,17 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
|
|||||||
|
|
||||||
pci_set_master(pdev);
|
pci_set_master(pdev);
|
||||||
|
|
||||||
|
#if (KERNEL_VERSION(5, 18, 0) <= LINUX_VERSION_CODE)
|
||||||
|
if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)))
|
||||||
|
if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)))
|
||||||
|
#else
|
||||||
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
||||||
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
|
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
|
||||||
} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
|
} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
|
||||||
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
|
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
|
||||||
} else return -ENODEV;
|
} else
|
||||||
|
#endif
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
dev = vzalloc(sizeof(*dev));
|
dev = vzalloc(sizeof(*dev));
|
||||||
if (!dev)
|
if (!dev)
|
||||||
@ -317,7 +315,6 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
|
|||||||
dev->link[0].dev = dev;
|
dev->link[0].dev = dev;
|
||||||
dev->link[0].info = get_ddb_info(id->vendor, id->device,
|
dev->link[0].info = get_ddb_info(id->vendor, id->device,
|
||||||
id->subvendor, pdev->subsystem_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_len = pci_resource_len(dev->pdev, 0);
|
||||||
dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
|
dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
|
||||||
@ -337,10 +334,6 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
|
|||||||
dev->link[0].ids.hwid = ddbreadl(dev, 0);
|
dev->link[0].ids.hwid = ddbreadl(dev, 0);
|
||||||
dev->link[0].ids.regmapid = ddbreadl(dev, 4);
|
dev->link[0].ids.regmapid = ddbreadl(dev, 4);
|
||||||
|
|
||||||
dev_info(dev->dev, "HW %08x REGMAP %08x FW %u.%u\n",
|
|
||||||
dev->link[0].ids.hwid, dev->link[0].ids.regmapid,
|
|
||||||
(dev->link[0].ids.hwid & 0xff0000) >> 16,
|
|
||||||
dev->link[0].ids.hwid & 0xffff);
|
|
||||||
if ((dev->link[0].ids.hwid & 0xffffff) <
|
if ((dev->link[0].ids.hwid & 0xffffff) <
|
||||||
dev->link[0].info->hw_min) {
|
dev->link[0].info->hw_min) {
|
||||||
u32 min = dev->link[0].info->hw_min;
|
u32 min = dev->link[0].info->hw_min;
|
||||||
@ -357,33 +350,27 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
|
|||||||
if (dev->link[0].info->type != DDB_MOD)
|
if (dev->link[0].info->type != DDB_MOD)
|
||||||
ddbwritel(dev, 0, DMA_BASE_WRITE);
|
ddbwritel(dev, 0, DMA_BASE_WRITE);
|
||||||
|
|
||||||
if (dev->link[0].info->type == DDB_MOD
|
if (dev->link[0].info->type == DDB_MOD &&
|
||||||
&& dev->link[0].info->version <= 1) {
|
dev->link[0].info->version <= 1) {
|
||||||
if (ddbreadl(dev, 0x1c) == 4)
|
if (ddbreadl(dev, 0x1c) == 4)
|
||||||
dev->link[0].info =
|
dev->link[0].info =
|
||||||
get_ddb_info(0xdd01, 0x0201, 0xdd01, 0x0004);
|
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) {
|
if (dev->link[0].info->type == DDB_MOD &&
|
||||||
case 0:
|
dev->link[0].info->version == 2) {
|
||||||
dev->link[0].info =
|
if (dev->link[0].ids.revision == 1)
|
||||||
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0000);
|
dev->link[0].info = get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0004);
|
||||||
break;
|
else if ((ddbreadl(dev, 0x1c) & 7) != 7)
|
||||||
case 1:
|
dev->link[0].info = get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0004);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev_info(dev->dev, "%s\n", dev->link[0].info->name);
|
||||||
|
dev_info(dev->dev, "HW %08x REGMAP %08x FW %u.%u\n",
|
||||||
|
dev->link[0].ids.hwid, dev->link[0].ids.regmapid,
|
||||||
|
(dev->link[0].ids.hwid & 0xff0000) >> 16,
|
||||||
|
dev->link[0].ids.hwid & 0xffff);
|
||||||
|
|
||||||
stat = ddb_irq_init(dev);
|
stat = ddb_irq_init(dev);
|
||||||
if (stat < 0)
|
if (stat < 0)
|
||||||
goto fail0;
|
goto fail0;
|
||||||
@ -401,13 +388,19 @@ fail:
|
|||||||
ddb_unmap(dev);
|
ddb_unmap(dev);
|
||||||
pci_set_drvdata(pdev, NULL);
|
pci_set_drvdata(pdev, NULL);
|
||||||
pci_disable_device(pdev);
|
pci_disable_device(pdev);
|
||||||
return -1;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef PCI_DEVICE_SUB
|
||||||
|
#define PCI_DEVICE_SUB(vend, dev, subvend, subdev) \
|
||||||
|
.vendor = (vend), .device = (dev), \
|
||||||
|
.subvendor = (subvend), .subdevice = (subdev)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DDB_DEVICE_ANY(_device) \
|
#define DDB_DEVICE_ANY(_device) \
|
||||||
{ PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, PCI_ANY_ID) }
|
{ PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, PCI_ANY_ID) }
|
||||||
|
|
||||||
@ -424,7 +417,12 @@ static const struct pci_device_id ddb_id_table[] __devinitconst = {
|
|||||||
DDB_DEVICE_ANY(0x0011),
|
DDB_DEVICE_ANY(0x0011),
|
||||||
DDB_DEVICE_ANY(0x0012),
|
DDB_DEVICE_ANY(0x0012),
|
||||||
DDB_DEVICE_ANY(0x0013),
|
DDB_DEVICE_ANY(0x0013),
|
||||||
|
DDB_DEVICE_ANY(0x0014),
|
||||||
DDB_DEVICE_ANY(0x0020),
|
DDB_DEVICE_ANY(0x0020),
|
||||||
|
DDB_DEVICE_ANY(0x0022),
|
||||||
|
DDB_DEVICE_ANY(0x0024),
|
||||||
|
DDB_DEVICE_ANY(0x0025),
|
||||||
|
DDB_DEVICE_ANY(0x0026),
|
||||||
DDB_DEVICE_ANY(0x0201),
|
DDB_DEVICE_ANY(0x0201),
|
||||||
DDB_DEVICE_ANY(0x0203),
|
DDB_DEVICE_ANY(0x0203),
|
||||||
DDB_DEVICE_ANY(0x0210),
|
DDB_DEVICE_ANY(0x0210),
|
||||||
@ -432,17 +430,10 @@ static const struct pci_device_id ddb_id_table[] __devinitconst = {
|
|||||||
DDB_DEVICE_ANY(0x0221),
|
DDB_DEVICE_ANY(0x0221),
|
||||||
DDB_DEVICE_ANY(0x0222),
|
DDB_DEVICE_ANY(0x0222),
|
||||||
DDB_DEVICE_ANY(0x0223),
|
DDB_DEVICE_ANY(0x0223),
|
||||||
DDB_DEVICE_ANY(0x0320),
|
|
||||||
DDB_DEVICE_ANY(0x0321),
|
|
||||||
DDB_DEVICE_ANY(0x0322),
|
|
||||||
DDB_DEVICE_ANY(0x0323),
|
|
||||||
DDB_DEVICE_ANY(0x0328),
|
|
||||||
DDB_DEVICE_ANY(0x0329),
|
|
||||||
{0}
|
{0}
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(pci, ddb_id_table);
|
MODULE_DEVICE_TABLE(pci, ddb_id_table);
|
||||||
|
|
||||||
|
|
||||||
static pci_ers_result_t ddb_pci_slot_reset(struct pci_dev *dev)
|
static pci_ers_result_t ddb_pci_slot_reset(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
pr_info("pci_slot_reset\n");
|
pr_info("pci_slot_reset\n");
|
||||||
@ -482,7 +473,6 @@ static const struct pci_error_handlers ddb_error = {
|
|||||||
.resume = ddb_pci_resume,
|
.resume = ddb_pci_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct pci_driver ddb_pci_driver = {
|
static struct pci_driver ddb_pci_driver = {
|
||||||
.name = "ddbridge",
|
.name = "ddbridge",
|
||||||
.id_table = ddb_id_table,
|
.id_table = ddb_id_table,
|
||||||
|
@ -28,6 +28,10 @@
|
|||||||
|
|
||||||
/* MAX LNB interface related module parameters */
|
/* MAX LNB interface related module parameters */
|
||||||
|
|
||||||
|
static int delmode;
|
||||||
|
module_param(delmode, int, 0444);
|
||||||
|
MODULE_PARM_DESC(delmode, "frontend delivery system mode");
|
||||||
|
|
||||||
static int fmode;
|
static int fmode;
|
||||||
module_param(fmode, int, 0444);
|
module_param(fmode, int, 0444);
|
||||||
MODULE_PARM_DESC(fmode, "frontend emulation mode");
|
MODULE_PARM_DESC(fmode, "frontend emulation mode");
|
||||||
@ -44,31 +48,36 @@ static int no_voltage;
|
|||||||
module_param(no_voltage, int, 0444);
|
module_param(no_voltage, int, 0444);
|
||||||
MODULE_PARM_DESC(no_voltage, "Do not enable voltage on LNBH (will also disable 22KHz tone).");
|
MODULE_PARM_DESC(no_voltage, "Do not enable voltage on LNBH (will also disable 22KHz tone).");
|
||||||
|
|
||||||
|
static u8 input_diseqc_sequence[6] = { 0x00 };
|
||||||
|
static int input_diseqc_sequence_length = 1;
|
||||||
|
module_param_array(input_diseqc_sequence, byte, &input_diseqc_sequence_length, 0444);
|
||||||
|
MODULE_PARM_DESC(input_diseqc_sequence, "DiSEqC sequence to select input. Last byte & 15 selects input.");
|
||||||
|
|
||||||
/* MAX LNB interface related functions */
|
/* MAX LNB interface related functions */
|
||||||
|
|
||||||
static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
|
static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
|
||||||
{
|
{
|
||||||
u32 c, v = 0, tag = DDB_LINK_TAG(link);
|
u32 c, v = 0, tag = DDB_LINK_TAG(link);
|
||||||
|
u32 base = dev->link[link].info->lnb_base;
|
||||||
|
|
||||||
v = LNB_TONE & (dev->link[link].lnb.tone << (15 - lnb));
|
v = LNB_TONE & (dev->link[link].lnb.tone << (15 - lnb));
|
||||||
ddbwritel(dev, cmd | v, tag | LNB_CONTROL(lnb));
|
ddbwritel(dev, cmd | v, tag | base | LNB_CONTROL(lnb));
|
||||||
for (c = 0; c < 10; c++) {
|
for (c = 0; c < 10; c++) {
|
||||||
v = ddbreadl(dev, tag | LNB_CONTROL(lnb));
|
v = ddbreadl(dev, tag | base | LNB_CONTROL(lnb));
|
||||||
if ((v & LNB_BUSY) == 0)
|
if ((v & LNB_BUSY) == 0)
|
||||||
break;
|
break;
|
||||||
msleep(20);
|
msleep(20);
|
||||||
}
|
}
|
||||||
if (c == 10)
|
if (c == 10)
|
||||||
dev_info(dev->dev,
|
dev_info(dev->dev,
|
||||||
"%s lnb = %08x cmd = %08x\n",
|
"%s lnb = %08x cmd = %08x timed out\n",
|
||||||
__func__, lnb, cmd);
|
__func__, lnb, cmd | v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int max_set_input(struct dvb_frontend *fe, int in);
|
static int max_set_input(struct dvb_frontend *fe, int in);
|
||||||
|
|
||||||
static int max_emulate_switch(struct dvb_frontend *fe,
|
static int max_emulate_switch(struct dvb_frontend *fe, u8 *cmd, u32 len)
|
||||||
u8 *cmd, u32 len)
|
|
||||||
{
|
{
|
||||||
int input;
|
int input;
|
||||||
|
|
||||||
@ -91,6 +100,7 @@ static int max_send_master_cmd(struct dvb_frontend *fe,
|
|||||||
struct ddb *dev = port->dev;
|
struct ddb *dev = port->dev;
|
||||||
struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
|
struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
|
||||||
u32 tag = DDB_LINK_TAG(port->lnr);
|
u32 tag = DDB_LINK_TAG(port->lnr);
|
||||||
|
u32 base = dev->link[port->lnr].info->lnb_base;
|
||||||
int i;
|
int i;
|
||||||
u32 fmode = dev->link[port->lnr].lnb.fmode;
|
u32 fmode = dev->link[port->lnr].lnb.fmode;
|
||||||
|
|
||||||
@ -101,13 +111,18 @@ static int max_send_master_cmd(struct dvb_frontend *fe,
|
|||||||
if (!max_emulate_switch(fe, cmd->msg, cmd->msg_len))
|
if (!max_emulate_switch(fe, cmd->msg, cmd->msg_len))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (cmd->msg_len &&
|
||||||
|
cmd->msg_len == input_diseqc_sequence_length &&
|
||||||
|
!memcmp(cmd->msg, input_diseqc_sequence, cmd->msg_len - 1))
|
||||||
|
return max_set_input(fe, cmd->msg[cmd->msg_len - 1] & 0x0f);
|
||||||
|
|
||||||
if (dvb->diseqc_send_master_cmd)
|
if (dvb->diseqc_send_master_cmd)
|
||||||
dvb->diseqc_send_master_cmd(fe, cmd);
|
dvb->diseqc_send_master_cmd(fe, cmd);
|
||||||
|
|
||||||
mutex_lock(&dev->link[port->lnr].lnb.lock);
|
mutex_lock(&dev->link[port->lnr].lnb.lock);
|
||||||
ddbwritel(dev, 0, tag | LNB_BUF_LEVEL(dvb->input));
|
ddbwritel(dev, 0, tag | base | LNB_BUF_LEVEL(dvb->input));
|
||||||
for (i = 0; i < cmd->msg_len; i++)
|
for (i = 0; i < cmd->msg_len; i++)
|
||||||
ddbwritel(dev, cmd->msg[i], tag | LNB_BUF_WRITE(dvb->input));
|
ddbwritel(dev, cmd->msg[i], tag | base | LNB_BUF_WRITE(dvb->input));
|
||||||
lnb_command(dev, port->lnr, dvb->input, LNB_CMD_DISEQC);
|
lnb_command(dev, port->lnr, dvb->input, LNB_CMD_DISEQC);
|
||||||
mutex_unlock(&dev->link[port->lnr].lnb.lock);
|
mutex_unlock(&dev->link[port->lnr].lnb.lock);
|
||||||
return 0;
|
return 0;
|
||||||
@ -117,11 +132,12 @@ static int lnb_send_diseqc(struct ddb *dev, u32 link, u32 input,
|
|||||||
struct dvb_diseqc_master_cmd *cmd)
|
struct dvb_diseqc_master_cmd *cmd)
|
||||||
{
|
{
|
||||||
u32 tag = DDB_LINK_TAG(link);
|
u32 tag = DDB_LINK_TAG(link);
|
||||||
|
u32 base = dev->link[link].info->lnb_base;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ddbwritel(dev, 0, tag | LNB_BUF_LEVEL(input));
|
ddbwritel(dev, 0, tag | base | LNB_BUF_LEVEL(input));
|
||||||
for (i = 0; i < cmd->msg_len; i++)
|
for (i = 0; i < cmd->msg_len; i++)
|
||||||
ddbwritel(dev, cmd->msg[i], tag | LNB_BUF_WRITE(input));
|
ddbwritel(dev, cmd->msg[i], tag | base | LNB_BUF_WRITE(input));
|
||||||
lnb_command(dev, link, input, LNB_CMD_DISEQC);
|
lnb_command(dev, link, input, LNB_CMD_DISEQC);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -369,6 +385,7 @@ static int max_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
|
|||||||
struct ddb_port *port = input->port;
|
struct ddb_port *port = input->port;
|
||||||
struct ddb *dev = port->dev;
|
struct ddb *dev = port->dev;
|
||||||
u32 tag = DDB_LINK_TAG(port->lnr);
|
u32 tag = DDB_LINK_TAG(port->lnr);
|
||||||
|
u32 base = dev->link[port->lnr].info->lnb_base;
|
||||||
struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
|
struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
|
||||||
u32 fmode = dev->link[port->lnr].lnb.fmode;
|
u32 fmode = dev->link[port->lnr].lnb.fmode;
|
||||||
|
|
||||||
@ -377,14 +394,14 @@ static int max_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
|
|||||||
default:
|
default:
|
||||||
case 0:
|
case 0:
|
||||||
case 3:
|
case 3:
|
||||||
ddbwritel(dev, arg ? 0x34 : 0x01, tag | LNB_CONTROL(dvb->input));
|
ddbwritel(dev, arg ? 0x34 : 0x01, tag | base | LNB_CONTROL(dvb->input));
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
ddbwritel(dev, arg ? 0x34 : 0x01, tag | LNB_CONTROL(0));
|
ddbwritel(dev, arg ? 0x34 : 0x01, tag | base | LNB_CONTROL(0));
|
||||||
ddbwritel(dev, arg ? 0x34 : 0x01, tag | LNB_CONTROL(1));
|
ddbwritel(dev, arg ? 0x34 : 0x01, tag | base | LNB_CONTROL(1));
|
||||||
ddbwritel(dev, arg ? 0x34 : 0x01, tag | LNB_CONTROL(2));
|
ddbwritel(dev, arg ? 0x34 : 0x01, tag | base | LNB_CONTROL(2));
|
||||||
ddbwritel(dev, arg ? 0x34 : 0x01, tag | LNB_CONTROL(3));
|
ddbwritel(dev, arg ? 0x34 : 0x01, tag | base | LNB_CONTROL(3));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mutex_unlock(&dev->link[port->lnr].lnb.lock);
|
mutex_unlock(&dev->link[port->lnr].lnb.lock);
|
||||||
@ -465,14 +482,20 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input)
|
|||||||
|
|
||||||
cfg = mxl5xx;
|
cfg = mxl5xx;
|
||||||
cfg.fw_priv = link;
|
cfg.fw_priv = link;
|
||||||
if (dev->link[0].info->type == DDB_OCTONET)
|
if (dev->link[0].info->type == DDB_OCTONET) {
|
||||||
;/*cfg.ts_clk = 69;*/
|
;/*cfg.ts_clk = 69;*/
|
||||||
|
}
|
||||||
|
|
||||||
demod = input->nr;
|
demod = input->nr;
|
||||||
tuner = demod & 3;
|
tuner = demod & 3;
|
||||||
if (fmode >= 3)
|
if (fmode >= 3)
|
||||||
tuner = 0;
|
tuner = 0;
|
||||||
dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, demod, tuner);
|
#ifdef CONFIG_MEDIA_ATTACH
|
||||||
|
dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg,
|
||||||
|
demod, tuner, &dvb->set_input);
|
||||||
|
#else
|
||||||
|
dvb->fe = mxl5xx_attach(i2c, &cfg, demod, tuner, &dvb->set_input);
|
||||||
|
#endif
|
||||||
if (!dvb->fe) {
|
if (!dvb->fe) {
|
||||||
dev_err(dev->dev, "No MXL5XX found!\n");
|
dev_err(dev->dev, "No MXL5XX found!\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
@ -490,13 +513,18 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input)
|
|||||||
dvb->fe->ops.diseqc_send_master_cmd = max_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->ops.diseqc_send_burst = max_send_burst;
|
||||||
dvb->fe->sec_priv = input;
|
dvb->fe->sec_priv = input;
|
||||||
dvb->set_input = dvb->fe->ops.set_input;
|
#ifndef KERNEL_DVB_CORE
|
||||||
dvb->fe->ops.set_input = max_set_input;
|
dvb->fe->ops.set_input = max_set_input;
|
||||||
|
#endif
|
||||||
dvb->input = tuner;
|
dvb->input = tuner;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* MAX MCI related functions */
|
/* MAX MCI related functions */
|
||||||
|
struct dvb_frontend *ddb_sx8_attach(struct ddb_input *input, int nr, int tuner,
|
||||||
|
int (**fn_set_input)(struct dvb_frontend *fe, int input));
|
||||||
|
struct dvb_frontend *ddb_mx_attach(struct ddb_input *input, int nr, int tuner, int type);
|
||||||
|
|
||||||
|
|
||||||
int ddb_fe_attach_mci(struct ddb_input *input, u32 type)
|
int ddb_fe_attach_mci(struct ddb_input *input, u32 type)
|
||||||
{
|
{
|
||||||
@ -505,30 +533,67 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type)
|
|||||||
struct ddb_port *port = input->port;
|
struct ddb_port *port = input->port;
|
||||||
struct ddb_link *link = &dev->link[port->lnr];
|
struct ddb_link *link = &dev->link[port->lnr];
|
||||||
int demod, tuner;
|
int demod, tuner;
|
||||||
struct mci_cfg cfg;
|
|
||||||
int fm = fmode;
|
int fm = fmode;
|
||||||
|
|
||||||
demod = input->nr;
|
demod = input->nr;
|
||||||
tuner = demod & 3;
|
tuner = demod & 3;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case DDB_TUNER_MCI_SX8:
|
case DDB_TUNER_MCI_SX8:
|
||||||
cfg = ddb_max_sx8_cfg;
|
|
||||||
if (fm >= 3)
|
if (fm >= 3)
|
||||||
tuner = 0;
|
tuner = 0;
|
||||||
|
dvb->fe = ddb_sx8_attach(input, demod, tuner, &dvb->set_input);
|
||||||
|
dvb->input = tuner;
|
||||||
break;
|
break;
|
||||||
case DDB_TUNER_MCI_M4:
|
case DDB_TUNER_MCI_M4:
|
||||||
fm = 0;
|
fm = 0;
|
||||||
cfg = ddb_max_m4_cfg;
|
dvb->fe = ddb_mx_attach(input, demod, tuner, 0);
|
||||||
|
dvb->input = tuner;
|
||||||
break;
|
break;
|
||||||
|
case DDB_TUNER_MCI_M8:
|
||||||
|
fm = 3;
|
||||||
|
if (!demod)
|
||||||
|
ddb_mci_cmd_link_simple(link, MCI_CMD_SET_INPUT_CONFIG,
|
||||||
|
0xff, (delmode & 0x10) | 3);
|
||||||
|
dvb->fe = ddb_mx_attach(input, demod, tuner, 3);
|
||||||
|
dvb->input = 0;
|
||||||
|
break;
|
||||||
|
case DDB_TUNER_MCI_M8A:
|
||||||
|
case DDB_TUNER_MCI_M8E:
|
||||||
|
fm = 3;
|
||||||
|
dvb->fe = ddb_mx_attach(input, demod, tuner, 3);
|
||||||
|
dvb->input = 0;
|
||||||
|
break;
|
||||||
|
case DDB_TUNER_MCI_M2:
|
||||||
|
{
|
||||||
|
u32 mode, mmode;
|
||||||
|
|
||||||
|
// delmode: 0 - sat,sat 1-cable,cable/sat
|
||||||
|
switch (delmode & 1) {
|
||||||
|
case 0:
|
||||||
|
mode = 2;
|
||||||
|
mmode = 2; /* M_S */
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mode = 1;
|
||||||
|
mmode = demod ? 3 : 1; /* demod 1=M/0=M_A */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!demod)
|
||||||
|
ddb_mci_cmd_link_simple(link, MCI_CMD_SET_INPUT_CONFIG,
|
||||||
|
0xff, mode | (delmode & 0x10));
|
||||||
|
dvb->fe = ddb_mx_attach(input, demod, tuner, mmode);
|
||||||
|
dvb->input = tuner;
|
||||||
|
fm = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
dvb->fe = ddb_mci_attach(input, &cfg, demod, tuner);
|
|
||||||
if (!dvb->fe) {
|
if (!dvb->fe) {
|
||||||
dev_err(dev->dev, "No MCI card found!\n");
|
dev_err(dev->dev, "No MCI card found!\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
if (input->nr < 4) {
|
if (!input->nr || (input->nr < 4 && type != DDB_TUNER_MCI_M8)) {
|
||||||
lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT);
|
lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT);
|
||||||
lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF);
|
lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF);
|
||||||
}
|
}
|
||||||
@ -541,14 +606,10 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type)
|
|||||||
dvb->fe->ops.diseqc_send_master_cmd = max_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->ops.diseqc_send_burst = max_send_burst;
|
||||||
dvb->fe->sec_priv = input;
|
dvb->fe->sec_priv = input;
|
||||||
switch (type) {
|
if (type == DDB_TUNER_MCI_SX8) {
|
||||||
case DDB_TUNER_MCI_M4:
|
#ifndef KERNEL_DVB_CORE
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dvb->set_input = dvb->fe->ops.set_input;
|
|
||||||
dvb->fe->ops.set_input = max_set_input;
|
dvb->fe->ops.set_input = max_set_input;
|
||||||
break;
|
#endif
|
||||||
}
|
}
|
||||||
dvb->input = tuner;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -134,6 +134,8 @@ int ddb_mci_cmd_link(struct ddb_link *link,
|
|||||||
struct mci_result res;
|
struct mci_result res;
|
||||||
int stat;
|
int stat;
|
||||||
|
|
||||||
|
if (!link->mci_ok)
|
||||||
|
return -EFAULT;
|
||||||
if (!result)
|
if (!result)
|
||||||
result = &res;
|
result = &res;
|
||||||
mutex_lock(&link->mci_lock);
|
mutex_lock(&link->mci_lock);
|
||||||
@ -150,6 +152,17 @@ int ddb_mci_cmd_link(struct ddb_link *link,
|
|||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ddb_mci_cmd_link_simple(struct ddb_link *link, u8 command, u8 demod, u8 value)
|
||||||
|
{
|
||||||
|
struct mci_command cmd;
|
||||||
|
|
||||||
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
|
cmd.command = command;
|
||||||
|
cmd.demod = demod;
|
||||||
|
cmd.params8[0] = value;
|
||||||
|
return ddb_mci_cmd_link(link, &cmd, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static void mci_handler(void *priv)
|
static void mci_handler(void *priv)
|
||||||
{
|
{
|
||||||
struct ddb_link *link = (struct ddb_link *) priv;
|
struct ddb_link *link = (struct ddb_link *) priv;
|
||||||
@ -197,7 +210,7 @@ int ddb_mci_cmd(struct mci *state,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ddb_mci_cmd_raw(struct mci *state,
|
static int ddb_mci_cmd_raw(struct mci *state,
|
||||||
struct mci_command *command, u32 command_len,
|
struct mci_command *command, u32 command_len,
|
||||||
struct mci_result *result, u32 result_len)
|
struct mci_result *result, u32 result_len)
|
||||||
{
|
{
|
||||||
@ -221,21 +234,6 @@ int ddb_mci_get_status(struct mci *mci, struct mci_result *res)
|
|||||||
return ddb_mci_cmd_raw(mci, &cmd, 1, res, 1);
|
return ddb_mci_cmd_raw(mci, &cmd, 1, res, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ddb_mci_print_info(struct mci *mci)
|
|
||||||
{
|
|
||||||
struct ddb_link *link = mci->base->link;
|
|
||||||
const struct ddb_regmap *regmap = link->info->regmap;
|
|
||||||
struct mci_command cmd;
|
|
||||||
struct mci_result res;
|
|
||||||
|
|
||||||
cmd.command = 0x0f;
|
|
||||||
if (ddb_mci_cmd_raw(mci, &cmd, 1, &res, 1) < 0)
|
|
||||||
return;
|
|
||||||
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 16, 1,
|
|
||||||
link->dev->regs + regmap->mci_buf->base + MCI_COMMAND_SIZE,
|
|
||||||
16, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ddb_mci_get_snr(struct dvb_frontend *fe)
|
int ddb_mci_get_snr(struct dvb_frontend *fe)
|
||||||
{
|
{
|
||||||
struct mci *mci = fe->demodulator_priv;
|
struct mci *mci = fe->demodulator_priv;
|
||||||
@ -300,7 +298,7 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
|
|||||||
};
|
};
|
||||||
const enum fe_code_rate dvbs_fec_lut[8] = {
|
const enum fe_code_rate dvbs_fec_lut[8] = {
|
||||||
FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6,
|
FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6,
|
||||||
FEC_NONE, FEC_7_8, FEC_NONE, FEC_NONE,
|
FEC_7_8, FEC_7_8, FEC_NONE, FEC_NONE,
|
||||||
};
|
};
|
||||||
const enum fe_rolloff ro_lut[8] = {
|
const enum fe_rolloff ro_lut[8] = {
|
||||||
ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_10,
|
ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_10,
|
||||||
@ -309,8 +307,9 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
|
|||||||
|
|
||||||
p->frequency =
|
p->frequency =
|
||||||
mci->signal_info.dvbs2_signal_info.frequency;
|
mci->signal_info.dvbs2_signal_info.frequency;
|
||||||
|
p->symbol_rate =
|
||||||
|
mci->signal_info.dvbs2_signal_info.symbol_rate;
|
||||||
switch (p->delivery_system) {
|
switch (p->delivery_system) {
|
||||||
default:
|
|
||||||
case SYS_DVBS:
|
case SYS_DVBS:
|
||||||
case SYS_DVBS2:
|
case SYS_DVBS2:
|
||||||
{
|
{
|
||||||
@ -353,6 +352,8 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SYS_DVBC_ANNEX_A:
|
case SYS_DVBC_ANNEX_A:
|
||||||
|
p->modulation =
|
||||||
|
mci->signal_info.dvbc_signal_info.constellation + 1;
|
||||||
break;
|
break;
|
||||||
case SYS_DVBT:
|
case SYS_DVBT:
|
||||||
break;
|
break;
|
||||||
@ -362,6 +363,8 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
|
|||||||
break;
|
break;
|
||||||
case SYS_ISDBT:
|
case SYS_ISDBT:
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
/* post is correct, we cannot provide both pre and post at the same time */
|
/* post is correct, we cannot provide both pre and post at the same time */
|
||||||
/* set pre and post the same for now */
|
/* set pre and post the same for now */
|
||||||
|
@ -96,11 +96,13 @@
|
|||||||
#define SX8_DEMOD_IQ_MODE (1)
|
#define SX8_DEMOD_IQ_MODE (1)
|
||||||
#define SX8_DEMOD_WAIT_MATYPE (3)
|
#define SX8_DEMOD_WAIT_MATYPE (3)
|
||||||
|
|
||||||
#define M4_DEMOD_WAIT_TS (6)
|
#define MX_DEMOD_WAIT_TS (6)
|
||||||
#define M4_DEMOD_C2SCAN (16)
|
#define MX_DEMOD_C2SCAN (16)
|
||||||
|
|
||||||
#define MCI_STATUS_OK (0x00)
|
#define MCI_STATUS_OK (0x00)
|
||||||
#define MCI_STATUS_UNSUPPORTED (0x80)
|
#define MCI_STATUS_UNSUPPORTED (0x80)
|
||||||
|
#define MCI_STATUS_BUSY (0xFA)
|
||||||
|
#define MCI_STATUS_HARDWARE_ERROR (0xFB)
|
||||||
#define MCI_STATUS_INVALID_PARAMETER (0xFC)
|
#define MCI_STATUS_INVALID_PARAMETER (0xFC)
|
||||||
#define MCI_STATUS_RETRY (0xFD)
|
#define MCI_STATUS_RETRY (0xFD)
|
||||||
#define MCI_STATUS_NOT_READY (0xFE)
|
#define MCI_STATUS_NOT_READY (0xFE)
|
||||||
@ -111,6 +113,8 @@
|
|||||||
#define MCI_CMD_GETSIGNALINFO (0x03)
|
#define MCI_CMD_GETSIGNALINFO (0x03)
|
||||||
//#define MCI_CMD_RFPOWER (0x04)
|
//#define MCI_CMD_RFPOWER (0x04)
|
||||||
|
|
||||||
|
#define MCI_CMD_SET_INPUT_CONFIG (0x05)
|
||||||
|
|
||||||
#define MCI_CMD_SEARCH_DVBS (0x10)
|
#define MCI_CMD_SEARCH_DVBS (0x10)
|
||||||
#define MCI_CMD_SEARCH_ISDBS (0x11)
|
#define MCI_CMD_SEARCH_ISDBS (0x11)
|
||||||
|
|
||||||
@ -123,6 +127,9 @@
|
|||||||
#define MCI_CMD_SEARCH_ISDBC (0x25)
|
#define MCI_CMD_SEARCH_ISDBC (0x25)
|
||||||
#define MCI_CMD_SEARCH_J83B (0x26)
|
#define MCI_CMD_SEARCH_J83B (0x26)
|
||||||
|
|
||||||
|
#define MCI_CMD_SEARCH_ATSC (0x27)
|
||||||
|
#define MCI_CMD_SEARCH_ATSC3 (0x28)
|
||||||
|
|
||||||
#define MCI_CMD_GET_IQSYMBOL (0x30)
|
#define MCI_CMD_GET_IQSYMBOL (0x30)
|
||||||
|
|
||||||
#define MCI_BANDWIDTH_UNKNOWN (0)
|
#define MCI_BANDWIDTH_UNKNOWN (0)
|
||||||
@ -140,42 +147,45 @@
|
|||||||
#define SX8_CMD_ENABLE_IQOUTPUT (0x44)
|
#define SX8_CMD_ENABLE_IQOUTPUT (0x44)
|
||||||
#define SX8_CMD_DISABLE_IQOUTPUT (0x45)
|
#define SX8_CMD_DISABLE_IQOUTPUT (0x45)
|
||||||
|
|
||||||
#define M4_CMD_GET_L1INFO (0x50)
|
#define MX_CMD_GET_L1INFO (0x50)
|
||||||
#define M4_CMD_GET_IDS (0x51)
|
#define MX_CMD_GET_IDS (0x51)
|
||||||
#define M4_CMD_GET_DVBT_TPS (0x52)
|
#define MX_CMD_GET_DVBT_TPS (0x52)
|
||||||
#define MCI_CMD_GET_BBHEADER (0x53)
|
#define MCI_CMD_GET_BBHEADER (0x53)
|
||||||
#define M4_CMD_GET_ISDBT_TMCC (0x54)
|
#define MX_CMD_GET_ISDBT_TMCC (0x54)
|
||||||
#define M4_CMD_GET_ISDBS_TMCC (0x55)
|
#define MX_CMD_GET_ISDBS_TMCC (0x55)
|
||||||
#define M4_CMD_GET_ISDBC_TSMF (0x56)
|
#define MX_CMD_GET_ISDBC_TSMF (0x56)
|
||||||
|
|
||||||
#define M4_CMD_GET_BBHEADER (MCI_CMD_GET_BBHEADER)
|
#define MX_CMD_GET_BBHEADER (MCI_CMD_GET_BBHEADER)
|
||||||
|
|
||||||
#define M4_L1INFO_SEL_PRE (0)
|
#define MX_L1INFO_SEL_PRE (0)
|
||||||
#define M4_L1INFO_SEL_DSINFO (1)
|
#define MX_L1INFO_SEL_DSINFO (1)
|
||||||
#define M4_L1INFO_SEL_PLPINFO (2)
|
#define MX_L1INFO_SEL_PLPINFO (2)
|
||||||
#define M4_L1INFO_SEL_PLPINFO_C (3)
|
#define MX_L1INFO_SEL_PLPINFO_C (3)
|
||||||
#define M4_L1INFO_SEL_SETID (0x80)
|
#define MX_L1INFO_SEL_SETID (0x80)
|
||||||
|
|
||||||
#define MCI_BANDWIDTH_EXTENSION (0x80) // currently used only for J83B in Japan
|
#define MCI_BANDWIDTH_EXTENSION (0x80) // currently used only for J83B in Japan
|
||||||
|
|
||||||
#define M4_MODE_DVBSX (2)
|
#define MX_MODE_DVBSX (2)
|
||||||
#define M4_MODE_DVBC (3)
|
#define MX_MODE_DVBC (3)
|
||||||
#define M4_MODE_DVBT (4)
|
#define MX_MODE_DVBT (4)
|
||||||
#define M4_MODE_DVBT2 (5)
|
#define MX_MODE_DVBT2 (5)
|
||||||
#define M4_MODE_DVBC2 (6)
|
#define MX_MODE_DVBC2 (6)
|
||||||
#define M4_MODE_J83B (7)
|
#define MX_MODE_J83B (7)
|
||||||
#define M4_MODE_ISDBT (8)
|
#define MX_MODE_ISDBT (8)
|
||||||
#define M4_MODE_ISDBC (9)
|
#define MX_MODE_ISDBC (9)
|
||||||
#define M4_MODE_ISDBS (10)
|
#define MX_MODE_ISDBS (10)
|
||||||
|
#define MX_MODE_ISDBS3 (11)
|
||||||
|
#define MX_MODE_ATSC (12)
|
||||||
|
#define MX_MODE_ATSC3 (13)
|
||||||
|
|
||||||
#define M4_DVBC_CONSTELLATION_16QAM (0)
|
#define MX_DVBC_CONSTELLATION_16QAM (0)
|
||||||
#define M4_DVBC_CONSTELLATION_32QAM (1)
|
#define MX_DVBC_CONSTELLATION_32QAM (1)
|
||||||
#define M4_DVBC_CONSTELLATION_64QAM (2) // also valid for J83B and ISDB-C
|
#define MX_DVBC_CONSTELLATION_64QAM (2) // also valid for J83B and ISDB-C
|
||||||
#define M4_DVBC_CONSTELLATION_128QAM (3)
|
#define MX_DVBC_CONSTELLATION_128QAM (3)
|
||||||
#define M4_DVBC_CONSTELLATION_256QAM (4) // also valid for J83B and ISDB-C
|
#define MX_DVBC_CONSTELLATION_256QAM (4) // also valid for J83B and ISDB-C
|
||||||
|
|
||||||
#define M4_SIGNALINFO_FLAG_CHANGE (0x01)
|
#define MX_SIGNALINFO_FLAG_CHANGE (0x01)
|
||||||
#define M4_SIGNALINFO_FLAG_EWS (0x02)
|
#define MX_SIGNALINFO_FLAG_EWS (0x02)
|
||||||
|
|
||||||
#define SX8_ROLLOFF_35 0
|
#define SX8_ROLLOFF_35 0
|
||||||
#define SX8_ROLLOFF_25 1
|
#define SX8_ROLLOFF_25 1
|
||||||
@ -203,6 +213,23 @@
|
|||||||
#define MOD_STANDARD_DVBT_6 (0x03)
|
#define MOD_STANDARD_DVBT_6 (0x03)
|
||||||
#define MOD_STANDARD_DVBT_5 (0x04)
|
#define MOD_STANDARD_DVBT_5 (0x04)
|
||||||
|
|
||||||
|
#define MOD_STANDARD_DVBC_8 (0x08)
|
||||||
|
#define MOD_STANDARD_DVBC_7 (0x09)
|
||||||
|
#define MOD_STANDARD_DVBC_6 (0x0A)
|
||||||
|
|
||||||
|
#define MOD_STANDARD_J83A_8 (MOD_STANDARD_DVBC_8)
|
||||||
|
#define MOD_STANDARD_J83A_7 (MOD_STANDARD_DVBC_7)
|
||||||
|
#define MOD_STANDARD_J83A_6 (MOD_STANDARD_DVBC_6)
|
||||||
|
|
||||||
|
#define MOD_STANDARD_J83B_QAM64 (0x0B)
|
||||||
|
#define MOD_STANDARD_J83B_QAM256 (0x0C)
|
||||||
|
|
||||||
|
#define MOD_STANDARD_ISDBC_QAM64 (0x0D)
|
||||||
|
#define MOD_STANDARD_ISDBC_QAM256 (0x0E)
|
||||||
|
|
||||||
|
#define MOD_STANDARD_J83C_QAM64 (MOD_STANDARD_ISDBC_QAM64 )
|
||||||
|
#define MOD_STANDARD_J83C_QAM256 (MOD_STANDARD_ISDBC_QAM256)
|
||||||
|
|
||||||
#define MOD_CONNECTOR_OFF (0x00)
|
#define MOD_CONNECTOR_OFF (0x00)
|
||||||
#define MOD_CONNECTOR_F (0x01)
|
#define MOD_CONNECTOR_F (0x01)
|
||||||
#define MOD_CONNECTOR_SMA (0x02)
|
#define MOD_CONNECTOR_SMA (0x02)
|
||||||
@ -232,6 +259,26 @@
|
|||||||
#define MOD_DVBT_16QAM (0x01)
|
#define MOD_DVBT_16QAM (0x01)
|
||||||
#define MOD_DVBT_64QAM (0x02)
|
#define MOD_DVBT_64QAM (0x02)
|
||||||
|
|
||||||
|
#define MOD_QAM_DVBC_16 (0x00)
|
||||||
|
#define MOD_QAM_DVBC_32 (0x01)
|
||||||
|
#define MOD_QAM_DVBC_64 (0x02)
|
||||||
|
#define MOD_QAM_DVBC_128 (0x03)
|
||||||
|
#define MOD_QAM_DVBC_256 (0x04)
|
||||||
|
|
||||||
|
#define MOD_QAM_J83B_64 (0x05)
|
||||||
|
#define MOD_QAM_J83B_256 (0x06)
|
||||||
|
|
||||||
|
#define MOD_QAM_GENERIC (0x07)
|
||||||
|
|
||||||
|
#define MOD_QAM_ISDBC_64 (0x08)
|
||||||
|
#define MOD_QAM_ISDBC_256 (0x09)
|
||||||
|
|
||||||
|
#define CMD_GET_SERIALNUMBER (0xF0)
|
||||||
|
#define CMD_EXPORT_LICENSE (0xF0)
|
||||||
|
#define CMD_IMPORT_LICENSE (0xF1)
|
||||||
|
#define CMD_POWER_DOWN (0xF2)
|
||||||
|
#define CMD_POWER_UP (0xF3)
|
||||||
|
|
||||||
struct mod_setup_channels {
|
struct mod_setup_channels {
|
||||||
u8 flags;
|
u8 flags;
|
||||||
u8 standard;
|
u8 standard;
|
||||||
@ -242,17 +289,29 @@ struct mod_setup_channels {
|
|||||||
u32 bandwidth; /* used only when Standard == 0 */
|
u32 bandwidth; /* used only when Standard == 0 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mod_ofdm_parameter {
|
||||||
|
u8 fft_size; /* 0 = 2K, 1 = 8K (2K not yet supported) */
|
||||||
|
u8 guard_interval; /* 0 = 1/32, 1 = 1/16, 2 = 1/8, 3 = 1/4 (DVB-T Encoding) */
|
||||||
|
u8 puncture_rate; /* 0 = 1/2, 1 = 2/3, 2 = 3/4, 3 = 5/6, 4 = 7/8 (DVB-T Encoding) */
|
||||||
|
u8 constellation; /* MOD_DVBT_QPSK, MOD_DVBT_16QAM, MOD_DVBT_64QAM */
|
||||||
|
u8 rsvd2[2]; /* Reserved for DVB-T hierarchical */
|
||||||
|
u16 cell_identifier;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mod_qam_parameter {
|
||||||
|
u8 modulation;
|
||||||
|
u8 rolloff; /* Legal values: 12,13,15,18 */
|
||||||
|
};
|
||||||
|
|
||||||
struct mod_setup_stream {
|
struct mod_setup_stream {
|
||||||
u8 standard;
|
u8 standard;
|
||||||
u8 stream_format;
|
u8 stream_format;
|
||||||
u8 rsvd1[2];
|
u8 rsvd1[2];
|
||||||
u32 symbol_rate; /* only used when Standard doesn't define a fixed symbol rate */
|
u32 symbol_rate; /* only used when Standard doesn't define a fixed symbol rate */
|
||||||
u8 fft_size; /* 0 = 2K, 1 = 8K (2K yet supported) */
|
union {
|
||||||
u8 guard_interval; /* 0 = 1/32, 1 = 1/16, 2 = 1/8, 3 = 1/4 (DVB-T Encoding) */
|
struct mod_ofdm_parameter ofdm;
|
||||||
u8 puncture_rate; /* 0 = 1/2, 1 = 2/3, 2 = 3/4, 3 = 5/6, 4 = 7/8 (DVB-T Encoding) */
|
struct mod_qam_parameter qam;
|
||||||
u8 constellation;
|
};
|
||||||
u8 rsvd2[2]; /* Reserved for DVB-T hierarchical */
|
|
||||||
u16 cell_identifier;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mod_setup_output {
|
struct mod_setup_output {
|
||||||
@ -283,6 +342,7 @@ struct mci_command {
|
|||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
u32 params[31];
|
u32 params[31];
|
||||||
|
u8 params8[31*4];
|
||||||
struct {
|
struct {
|
||||||
u8 flags; /* Bit 0: DVB-S Enabled, 1: DVB-S2 Enabled,
|
u8 flags; /* Bit 0: DVB-S Enabled, 1: DVB-S2 Enabled,
|
||||||
5: ChannelBonding, 6: FrequencyRange, 7: InputStreamID */
|
5: ChannelBonding, 6: FrequencyRange, 7: InputStreamID */
|
||||||
@ -431,6 +491,20 @@ struct mci_command {
|
|||||||
struct mod_setup_channels mod_setup_channels[4];
|
struct mod_setup_channels mod_setup_channels[4];
|
||||||
struct mod_setup_stream mod_setup_stream;
|
struct mod_setup_stream mod_setup_stream;
|
||||||
struct mod_setup_output mod_setup_output;
|
struct mod_setup_output mod_setup_output;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u8 Cmd;
|
||||||
|
u8 Offset;
|
||||||
|
u8 Length;
|
||||||
|
u8 Rsvd1;
|
||||||
|
u32 Rsvd2[2];
|
||||||
|
u8 Data[96];
|
||||||
|
} sx8_packet_filter;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u8 ID[8];
|
||||||
|
u8 LK[24];
|
||||||
|
} license;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -456,7 +530,7 @@ struct mci_result {
|
|||||||
s16 channel_power; /* channel power in dBm x 100 */
|
s16 channel_power; /* channel power in dBm x 100 */
|
||||||
s16 rsvd2;
|
s16 rsvd2;
|
||||||
s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */
|
s16 signal_to_noise; /* SNR in dB x 100, Note: negativ values are valid in DVB-S2 */
|
||||||
s16 rsvd3;
|
u16 signal_loss_counter;/* Counts signal losses and automatic retunes */
|
||||||
u32 rsvd4;
|
u32 rsvd4;
|
||||||
u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */
|
u32 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */
|
||||||
u32 ber_denominator;
|
u32 ber_denominator;
|
||||||
@ -614,8 +688,8 @@ struct mci_result {
|
|||||||
|
|
||||||
struct {
|
struct {
|
||||||
u8 tps_info[7];
|
u8 tps_info[7];
|
||||||
// uint16_t tps_cell_id;
|
// u16 tps_cell_id;
|
||||||
} DVBT_TPSInfo;
|
} dvbt_tps_info;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct {
|
struct {
|
||||||
@ -644,7 +718,7 @@ struct mci_result {
|
|||||||
u8 CurrentRFIndex;
|
u8 CurrentRFIndex;
|
||||||
u8 T2Version_PostScrambled_BaseLite_Rsvd[2]; // 4,1,1,4 bit
|
u8 T2Version_PostScrambled_BaseLite_Rsvd[2]; // 4,1,1,4 bit
|
||||||
u8 CRC32[4];
|
u8 CRC32[4];
|
||||||
} DVBT2_L1Pre;
|
} dvbt2_l1_pre;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u8 SubSlicesPerFrame[2];
|
u8 SubSlicesPerFrame[2];
|
||||||
@ -656,8 +730,8 @@ struct mci_result {
|
|||||||
u8 FEFType;
|
u8 FEFType;
|
||||||
u8 FEFLength[3];
|
u8 FEFLength[3];
|
||||||
u8 FEFInterval;
|
u8 FEFInterval;
|
||||||
} DVBT2_L1Post;
|
} dvbt2_l1_post;
|
||||||
} DVBT2_L1Info;
|
} dvbt2_l1_info;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u8 PLPID;
|
u8 PLPID;
|
||||||
@ -677,7 +751,7 @@ struct mci_result {
|
|||||||
u8 TimeILType;
|
u8 TimeILType;
|
||||||
u8 InBandAFlag;
|
u8 InBandAFlag;
|
||||||
u8 InBandBFlag_Rsvd1_Mode_StaticFlag_StaticPaddingFlag[2]; // 1,11,2,1,1
|
u8 InBandBFlag_Rsvd1_Mode_StaticFlag_StaticPaddingFlag[2]; // 1,11,2,1,1
|
||||||
} DVBT2_PLPInfo;
|
} dvbt2_plp_info;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u8 NetworkID[2];
|
u8 NetworkID[2];
|
||||||
@ -735,18 +809,18 @@ struct mci_result {
|
|||||||
} DVBC2_PLPInfo;
|
} DVBC2_PLPInfo;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u8 Valid;
|
u8 valid;
|
||||||
u8 MATYPE_1;
|
u8 matype_1;
|
||||||
u8 MATYPE_2;
|
u8 matype_2;
|
||||||
u8 UPL[2];
|
u8 upl[2];
|
||||||
u8 DFL[2];
|
u8 dfl[2];
|
||||||
u8 SYNC;
|
u8 sync;
|
||||||
u8 SYNCD[2];
|
u8 syncd[2];
|
||||||
u8 rsvd;
|
u8 rsvd;
|
||||||
u8 ISSY[3];
|
u8 issy[3];
|
||||||
u8 min_input_stream_id;
|
u8 min_input_stream_id;
|
||||||
u8 max_input_stream_id;
|
u8 max_input_stream_id;
|
||||||
} BBHeader;
|
} bb_header;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u8 Mode; // FFT Mode 1,2,3
|
u8 Mode; // FFT Mode 1,2,3
|
||||||
@ -770,11 +844,41 @@ struct mci_result {
|
|||||||
} ISDBS_TMCCInfo;
|
} ISDBS_TMCCInfo;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint8_t cut;
|
u8 cut;
|
||||||
uint8_t avs_code;
|
u8 avs_code;
|
||||||
uint8_t temperature;
|
u8 temperature;
|
||||||
uint8_t rsvd[13];
|
u8 rsvd[13];
|
||||||
} sx8_bist;
|
} sx8_bist;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u8 status;
|
||||||
|
u8 offset;
|
||||||
|
u8 length;
|
||||||
|
u8 rsvd2;
|
||||||
|
u32 rsvd3[2];
|
||||||
|
u8 data[96];
|
||||||
|
} SX8_packet_filter_status;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u8 version; /* 0 = none, 1 = SX8 */
|
||||||
|
u8 flags; /* Bit 0: 1 = Tuner Valid, Bit 1: 1 = Output Valid */
|
||||||
|
u8 tuner;
|
||||||
|
u8 output;
|
||||||
|
} extended_status;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u8 reserved;
|
||||||
|
u8 serial_number[17];
|
||||||
|
} serial_number;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u8 flags;
|
||||||
|
u8 serial_number[17];
|
||||||
|
u16 code;
|
||||||
|
u8 ID[8];
|
||||||
|
u8 LK[24];
|
||||||
|
} license;
|
||||||
|
|
||||||
};
|
};
|
||||||
u32 version[3];
|
u32 version[3];
|
||||||
u8 version_rsvd;
|
u8 version_rsvd;
|
||||||
@ -889,6 +993,7 @@ struct mci_cfg {
|
|||||||
|
|
||||||
int ddb_mci_cmd(struct mci *state, struct mci_command *command, struct mci_result *result);
|
int ddb_mci_cmd(struct mci *state, struct mci_command *command, struct mci_result *result);
|
||||||
int ddb_mci_cmd_link(struct ddb_link *link, struct mci_command *command, struct mci_result *result);
|
int ddb_mci_cmd_link(struct ddb_link *link, struct mci_command *command, struct mci_result *result);
|
||||||
|
int ddb_mci_cmd_link_simple(struct ddb_link *link, u8 command, u8 demod, u8 value);
|
||||||
int ddb_mci_get_status(struct mci *mci, struct mci_result *res);
|
int ddb_mci_get_status(struct mci *mci, struct mci_result *res);
|
||||||
int ddb_mci_get_snr(struct dvb_frontend *fe);
|
int ddb_mci_get_snr(struct dvb_frontend *fe);
|
||||||
int ddb_mci_get_info(struct mci *mci);
|
int ddb_mci_get_info(struct mci *mci);
|
||||||
@ -897,8 +1002,6 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p);
|
|||||||
int mci_init(struct ddb_link *link);
|
int mci_init(struct ddb_link *link);
|
||||||
int mci_cmd_val(struct ddb_link *link, u32 cmd, u32 val);
|
int mci_cmd_val(struct ddb_link *link, u32 cmd, u32 val);
|
||||||
|
|
||||||
extern struct mci_cfg ddb_max_sx8_cfg;
|
|
||||||
extern struct mci_cfg ddb_max_m4_cfg;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,8 +23,13 @@
|
|||||||
|
|
||||||
#include "ddbridge.h"
|
#include "ddbridge.h"
|
||||||
#include "ddbridge-io.h"
|
#include "ddbridge-io.h"
|
||||||
|
#include "ddbridge-ioctl.h"
|
||||||
|
|
||||||
|
#ifdef KERNEL_DVB_CORE
|
||||||
|
#include "../include/linux/dvb/mod.h"
|
||||||
|
#else
|
||||||
#include <linux/dvb/mod.h>
|
#include <linux/dvb/mod.h>
|
||||||
|
#endif
|
||||||
#include <linux/gcd.h>
|
#include <linux/gcd.h>
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
@ -164,11 +169,6 @@ static void mod_calc_rateinc(struct ddb_mod *mod)
|
|||||||
{
|
{
|
||||||
u32 ri;
|
u32 ri;
|
||||||
|
|
||||||
dev_info(mod->port->dev->dev,
|
|
||||||
"ibitrate %llu\n", mod->ibitrate);
|
|
||||||
dev_info(mod->port->dev->dev,
|
|
||||||
"obitrate %llu\n", mod->obitrate);
|
|
||||||
|
|
||||||
if (mod->ibitrate != 0) {
|
if (mod->ibitrate != 0) {
|
||||||
u64 d = mod->obitrate - mod->ibitrate;
|
u64 d = mod->obitrate - mod->ibitrate;
|
||||||
|
|
||||||
@ -195,6 +195,48 @@ static int mod_calc_obitrate(struct ddb_mod *mod)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mod_set_stream(struct ddb_output *output)
|
||||||
|
{
|
||||||
|
struct ddb *dev = output->port->dev;
|
||||||
|
u32 stream = output->nr;
|
||||||
|
struct ddb_mod *mod = &dev->mod[output->nr];
|
||||||
|
struct ddb_link *link = &dev->link[0];
|
||||||
|
struct mci_result res;
|
||||||
|
u32 channel;
|
||||||
|
struct mci_command cmd = {
|
||||||
|
.mod_command = MOD_SETUP_STREAM,
|
||||||
|
.mod_channel = stream,
|
||||||
|
.mod_stream = stream,
|
||||||
|
.mod_setup_stream = {
|
||||||
|
.standard = MOD_STANDARD_DVBC_8,
|
||||||
|
.symbol_rate = mod->symbolrate,
|
||||||
|
.qam = {
|
||||||
|
.modulation = mod->modulation - 1,
|
||||||
|
.rolloff = 13,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (dev->link[0].info->version != 2)
|
||||||
|
return 0;
|
||||||
|
if (dev->link[0].ids.revision != 1)
|
||||||
|
return 0;
|
||||||
|
if ((dev->link[0].ids.hwid & 0xffffff) < 9065)
|
||||||
|
return 0;
|
||||||
|
if (!mod->frequency && !mod->symbolrate && !mod->modulation)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (mod->frequency)
|
||||||
|
channel = (mod->frequency - 114000000) / 8000000;
|
||||||
|
if (!mod->symbolrate)
|
||||||
|
mod->symbolrate = 6900000;
|
||||||
|
if (!mod->modulation)
|
||||||
|
mod->modulation = 5;
|
||||||
|
cmd.mod_channel = channel;
|
||||||
|
cmd.mod_setup_stream.symbol_rate = mod->symbolrate;
|
||||||
|
cmd.mod_setup_stream.qam.modulation = mod->modulation - 1;
|
||||||
|
return ddb_mci_cmd_link(link, &cmd, &res);
|
||||||
|
}
|
||||||
|
|
||||||
static int mod_set_symbolrate(struct ddb_mod *mod, u32 srate)
|
static int mod_set_symbolrate(struct ddb_mod *mod, u32 srate)
|
||||||
{
|
{
|
||||||
struct ddb *dev = mod->port->dev;
|
struct ddb *dev = mod->port->dev;
|
||||||
@ -210,6 +252,7 @@ static int mod_set_symbolrate(struct ddb_mod *mod, u32 srate)
|
|||||||
}
|
}
|
||||||
mod->symbolrate = srate;
|
mod->symbolrate = srate;
|
||||||
mod_calc_obitrate(mod);
|
mod_calc_obitrate(mod);
|
||||||
|
mod_set_stream(mod->port->output);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +270,7 @@ static int mod_set_modulation(struct ddb_mod *mod,
|
|||||||
ddbwritel(dev, qamtab[modulation],
|
ddbwritel(dev, qamtab[modulation],
|
||||||
CHANNEL_SETTINGS(mod->port->nr));
|
CHANNEL_SETTINGS(mod->port->nr));
|
||||||
mod_calc_obitrate(mod);
|
mod_calc_obitrate(mod);
|
||||||
|
mod_set_stream(mod->port->output);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,6 +285,7 @@ static int mod_set_frequency(struct ddb_mod *mod, u32 frequency)
|
|||||||
if ((freq < 114) || (freq > 874))
|
if ((freq < 114) || (freq > 874))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
mod->frequency = frequency;
|
mod->frequency = frequency;
|
||||||
|
mod_set_stream(mod->port->output);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,14 +367,27 @@ int ddbridge_mod_output_start(struct ddb_output *output)
|
|||||||
CHANNEL_CONTROL(output->nr));
|
CHANNEL_CONTROL(output->nr));
|
||||||
udelay(10);
|
udelay(10);
|
||||||
ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr));
|
ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr));
|
||||||
|
switch (dev->link[0].info->version) {
|
||||||
if (dev->link[0].info->version == 2) {
|
case 2:
|
||||||
|
{
|
||||||
u32 Output = (mod->frequency - 114000000) / 8000000;
|
u32 Output = (mod->frequency - 114000000) / 8000000;
|
||||||
u32 KF = Symbolrate;
|
u32 KF = Symbolrate;
|
||||||
u32 LF = 9000000UL;
|
u32 LF = 9000000UL;
|
||||||
u32 d = gcd(KF, LF);
|
u32 d = gcd(KF, LF);
|
||||||
u32 checkLF;
|
u32 checkLF;
|
||||||
|
|
||||||
|
if ((dev->link[0].ids.revision == 1)) {
|
||||||
|
if ((dev->link[0].info->version == 2)) {
|
||||||
|
if ((dev->link[0].ids.hwid & 0xffffff) >= 9065) {
|
||||||
|
mod->Control |= CHANNEL_CONTROL_ENABLE_DVB;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mod->Control |= CHANNEL_CONTROL_ENABLE_DVB;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ddbwritel(dev, mod->modulation - 1, CHANNEL_SETTINGS(Channel));
|
ddbwritel(dev, mod->modulation - 1, CHANNEL_SETTINGS(Channel));
|
||||||
ddbwritel(dev, Output, CHANNEL_SETTINGS2(Channel));
|
ddbwritel(dev, Output, CHANNEL_SETTINGS2(Channel));
|
||||||
|
|
||||||
@ -356,16 +414,21 @@ int ddbridge_mod_output_start(struct ddb_output *output)
|
|||||||
CHANNEL_CONTROL_CMD_SETUP))
|
CHANNEL_CONTROL_CMD_SETUP))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
mod->Control |= CHANNEL_CONTROL_ENABLE_DVB;
|
mod->Control |= CHANNEL_CONTROL_ENABLE_DVB;
|
||||||
} else if (dev->link[0].info->version <= 1) {
|
break;
|
||||||
|
}
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
/* QAM: 600 601 602 903 604 = 16 32 64 128 256 */
|
/* QAM: 600 601 602 903 604 = 16 32 64 128 256 */
|
||||||
/* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */
|
/* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */
|
||||||
ddbwritel(dev, qamtab[mod->modulation],
|
ddbwritel(dev, qamtab[mod->modulation],
|
||||||
CHANNEL_SETTINGS(output->nr));
|
CHANNEL_SETTINGS(output->nr));
|
||||||
mod->Control |= (CHANNEL_CONTROL_ENABLE_IQ |
|
mod->Control |= (CHANNEL_CONTROL_ENABLE_IQ |
|
||||||
CHANNEL_CONTROL_ENABLE_DVB);
|
CHANNEL_CONTROL_ENABLE_DVB);
|
||||||
} else if (dev->link[0].info->version >= 16) {
|
break;
|
||||||
|
default:
|
||||||
mod->Control |= (CHANNEL_CONTROL_ENABLE_IQ |
|
mod->Control |= (CHANNEL_CONTROL_ENABLE_IQ |
|
||||||
CHANNEL_CONTROL_ENABLE_DVB);
|
CHANNEL_CONTROL_ENABLE_DVB);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (dev->link[0].info->version < 16) {
|
if (dev->link[0].info->version < 16) {
|
||||||
mod_set_rateinc(dev, output->nr);
|
mod_set_rateinc(dev, output->nr);
|
||||||
@ -389,18 +452,20 @@ int ddbridge_mod_output_start(struct ddb_output *output)
|
|||||||
|
|
||||||
static int mod_write_max2871(struct ddb *dev, u32 val)
|
static int mod_write_max2871(struct ddb *dev, u32 val)
|
||||||
{
|
{
|
||||||
|
u32 retry = 100;
|
||||||
ddbwritel(dev, val, MAX2871_OUTDATA);
|
ddbwritel(dev, val, MAX2871_OUTDATA);
|
||||||
ddbwritel(dev, MAX2871_CONTROL_CE | MAX2871_CONTROL_WRITE,
|
ddbwritel(dev, MAX2871_CONTROL_CE | MAX2871_CONTROL_WRITE,
|
||||||
MAX2871_CONTROL);
|
MAX2871_CONTROL);
|
||||||
while (1) {
|
while (--retry) {
|
||||||
u32 ControlReg = ddbreadl(dev, MAX2871_CONTROL);
|
u32 ControlReg = ddbreadl(dev, MAX2871_CONTROL);
|
||||||
|
|
||||||
if (ControlReg == 0xFFFFFFFF)
|
if (ControlReg == 0xFFFFFFFF)
|
||||||
return -EIO;
|
|
||||||
if ((ControlReg & MAX2871_CONTROL_WRITE) == 0)
|
|
||||||
break;
|
break;
|
||||||
}
|
if ((ControlReg & MAX2871_CONTROL_WRITE) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
udelay(10);
|
||||||
|
}
|
||||||
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 max2871_fsm[6] = {
|
static u32 max2871_fsm[6] = {
|
||||||
@ -511,10 +576,37 @@ static int mod_fsm_setup(struct ddb *dev, u32 MaxUsedChannels)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mod_set_power(struct ddb *dev)
|
||||||
|
{
|
||||||
|
struct ddb_link *link = &dev->link[0];
|
||||||
|
struct mod_base *base = &dev->mod_base;
|
||||||
|
struct mci_result res;
|
||||||
|
struct mci_command cmd = {
|
||||||
|
.mod_command = MOD_SETUP_OUTPUT,
|
||||||
|
.mod_channel = 0,
|
||||||
|
.mod_stream = 0,
|
||||||
|
.mod_setup_output = {
|
||||||
|
.connector = MOD_CONNECTOR_F,
|
||||||
|
.num_channels = dev->link[0].info->port_num,
|
||||||
|
.unit = MOD_UNIT_DBUV,
|
||||||
|
.channel_power = 9000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (!link->mci_ok)
|
||||||
|
return -EFAULT;
|
||||||
|
cmd.mod_setup_output.channel_power =
|
||||||
|
8232 - base->attenuation * 1000 + base->gain * 12;
|
||||||
|
return ddb_mci_cmd_link(link, &cmd, &res);
|
||||||
|
}
|
||||||
|
|
||||||
static int mod_set_vga(struct ddb *dev, u32 gain)
|
static int mod_set_vga(struct ddb *dev, u32 gain)
|
||||||
{
|
{
|
||||||
if (gain > 255)
|
if (gain > 255)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (dev->link[0].ids.revision == 1) {
|
||||||
|
dev->mod_base.gain = gain;
|
||||||
|
return mod_set_power(dev);
|
||||||
|
}
|
||||||
ddbwritel(dev, gain, RF_VGA);
|
ddbwritel(dev, gain, RF_VGA);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -622,6 +714,10 @@ static int mod_set_attenuator(struct ddb *dev, u32 Value)
|
|||||||
{
|
{
|
||||||
if (Value > 31)
|
if (Value > 31)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
if (dev->link[0].ids.revision == 1) {
|
||||||
|
dev->mod_base.attenuation = Value;
|
||||||
|
return mod_set_power(dev);
|
||||||
|
} else
|
||||||
ddbwritel(dev, Value, RF_ATTENUATOR);
|
ddbwritel(dev, Value, RF_ATTENUATOR);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1653,7 +1749,11 @@ static int mod_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp)
|
|||||||
return mod_set_attenuator(mod->port->dev, tvp->u.data);
|
return mod_set_attenuator(mod->port->dev, tvp->u.data);
|
||||||
|
|
||||||
case MODULATOR_INPUT_BITRATE:
|
case MODULATOR_INPUT_BITRATE:
|
||||||
|
#ifdef KERNEL_DVB_CORE
|
||||||
|
return mod_set_ibitrate(mod, *(u64 *) &tvp->u.buffer.data[0]);
|
||||||
|
#else
|
||||||
return mod_set_ibitrate(mod, tvp->u.data64);
|
return mod_set_ibitrate(mod, tvp->u.data64);
|
||||||
|
#endif
|
||||||
|
|
||||||
case MODULATOR_GAIN:
|
case MODULATOR_GAIN:
|
||||||
if (mod->port->dev->link[0].info->version == 2)
|
if (mod->port->dev->link[0].info->version == 2)
|
||||||
@ -1709,10 +1809,16 @@ static int mod_prop_get(struct ddb_mod *mod, struct dtv_property *tvp)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case MODULATOR_GAIN:
|
case MODULATOR_GAIN:
|
||||||
|
if (dev->link[0].ids.revision == 1)
|
||||||
|
tvp->u.data = dev->mod_base.gain;
|
||||||
|
else
|
||||||
tvp->u.data = 0xff & ddbreadl(dev, RF_VGA);
|
tvp->u.data = 0xff & ddbreadl(dev, RF_VGA);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case MODULATOR_ATTENUATOR:
|
case MODULATOR_ATTENUATOR:
|
||||||
|
if (dev->link[0].ids.revision == 1)
|
||||||
|
tvp->u.data = dev->mod_base.attenuation;
|
||||||
|
else
|
||||||
tvp->u.data = 0x1f & ddbreadl(dev, RF_ATTENUATOR);
|
tvp->u.data = 0x1f & ddbreadl(dev, RF_ATTENUATOR);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1752,7 +1858,8 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
|||||||
(struct dtv_properties __user *) parg;
|
(struct dtv_properties __user *) parg;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
|
|
||||||
if (dev->link[0].info->version >= 16 && cmd != FE_SET_PROPERTY)
|
if (dev->link[0].info->version >= 16 &&
|
||||||
|
(cmd != FE_SET_PROPERTY && cmd != IOCTL_DDB_MCI_CMD))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
mutex_lock(&dev->ioctl_mutex);
|
mutex_lock(&dev->ioctl_mutex);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
@ -1844,6 +1951,28 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
|||||||
mod->pcr_correction = cp->pcr_correction;
|
mod->pcr_correction = cp->pcr_correction;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IOCTL_DDB_MCI_CMD:
|
||||||
|
{
|
||||||
|
struct ddb_mci_msg *msg =
|
||||||
|
(struct ddb_mci_msg __user *) parg;
|
||||||
|
struct ddb_link *link;
|
||||||
|
|
||||||
|
if (dev->link[0].ids.revision != 1) {
|
||||||
|
ret = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (msg->link > 3) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
link = &dev->link[msg->link];
|
||||||
|
if (!link->mci_ok) {
|
||||||
|
ret = -EFAULT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret = ddb_mci_cmd_link(link, &msg->cmd, &msg->res);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
break;
|
break;
|
||||||
@ -1852,6 +1981,22 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mod_init_2_1(struct ddb *dev, u32 Frequency)
|
||||||
|
{
|
||||||
|
int i, streams = dev->link[0].info->port_num;
|
||||||
|
|
||||||
|
dev->mod_base.frequency = Frequency;
|
||||||
|
dev->mod_base.gain = 64;
|
||||||
|
dev->mod_base.attenuation = 0;
|
||||||
|
mod_set_power(dev);
|
||||||
|
|
||||||
|
for (i = 0; i < streams; i++) {
|
||||||
|
struct ddb_mod *mod = &dev->mod[i];
|
||||||
|
mod->port = &dev->port[i];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mod_init_2(struct ddb *dev, u32 Frequency)
|
static int mod_init_2(struct ddb *dev, u32 Frequency)
|
||||||
{
|
{
|
||||||
int i, status, streams = dev->link[0].info->port_num;
|
int i, status, streams = dev->link[0].info->port_num;
|
||||||
@ -1863,8 +2008,6 @@ static int mod_init_2(struct ddb *dev, u32 Frequency)
|
|||||||
dev_err(dev->dev, "FSM setup failed!\n");
|
dev_err(dev->dev, "FSM setup failed!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (dev->link[0].ids.revision == 1)
|
|
||||||
return 0;
|
|
||||||
for (i = 0; i < streams; i++) {
|
for (i = 0; i < streams; i++) {
|
||||||
struct ddb_mod *mod = &dev->mod[i];
|
struct ddb_mod *mod = &dev->mod[i];
|
||||||
|
|
||||||
@ -2014,7 +2157,6 @@ static int mod_init_3(struct ddb *dev, u32 Frequency)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int mod_init_sdr_iq(struct ddb *dev)
|
static int mod_init_sdr_iq(struct ddb *dev)
|
||||||
{
|
{
|
||||||
int streams = dev->link[0].info->port_num;
|
int streams = dev->link[0].info->port_num;
|
||||||
@ -2031,55 +2173,53 @@ static int mod_init_sdr_iq(struct ddb *dev)
|
|||||||
|
|
||||||
ddbwritel(dev, 0x01, 0x240);
|
ddbwritel(dev, 0x01, 0x240);
|
||||||
|
|
||||||
if (dev->link[0].ids.revision == 1)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
//mod3_set_base_frequency(dev, 602000000);
|
//mod3_set_base_frequency(dev, 602000000);
|
||||||
dev->mod_base.frequency = 570000000;
|
dev->mod_base.frequency = 570000000;
|
||||||
for (i = 0; i < streams; i++) {
|
for (i = 0; i < streams; i++) {
|
||||||
struct ddb_mod *mod = &dev->mod[i];
|
struct ddb_mod *mod = &dev->mod[i];
|
||||||
|
|
||||||
mod->port = &dev->port[i];
|
mod->port = &dev->port[i];
|
||||||
|
if (dev->link[0].ids.revision != 1)
|
||||||
ddbwritel(dev, 0x00, SDR_CHANNEL_CONTROL(i));
|
ddbwritel(dev, 0x00, SDR_CHANNEL_CONTROL(i));
|
||||||
}
|
}
|
||||||
|
if (dev->link[0].ids.revision == 1)
|
||||||
|
return ret;
|
||||||
mod_set_sdr_attenuator(dev, 0);
|
mod_set_sdr_attenuator(dev, 0);
|
||||||
udelay(10);
|
udelay(10);
|
||||||
mod_set_sdr_gain(dev, 120);
|
mod_set_sdr_gain(dev, 120);
|
||||||
|
ddb_mci_cmd_link_simple(&dev->link[0], 0xc0, 0x00, 90);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int mod_init_dvbt(struct ddb *dev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
dev->mod_base.frequency = 570000000;
|
||||||
|
for (i = 0; i < dev->link[0].info->port_num; i++)
|
||||||
|
dev->mod[i].port = &dev->port[i];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int ddbridge_mod_init(struct ddb *dev)
|
int ddbridge_mod_init(struct ddb *dev)
|
||||||
{
|
{
|
||||||
dev_info(dev->dev, "Revision: %u\n", dev->link[0].ids.revision);
|
dev_info(dev->dev, "Revision: %u\n", dev->link[0].ids.revision);
|
||||||
|
switch (dev->link[0].info->version) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
return mod_init_1(dev, 722000000);
|
||||||
|
case 2: /* FSM */
|
||||||
if (dev->link[0].ids.revision == 1) {
|
if (dev->link[0].ids.revision == 1) {
|
||||||
switch (dev->link[0].info->version) {
|
if ((dev->link[0].ids.hwid & 0xffffff) >= 9065)
|
||||||
case 0:
|
return mod_init_2_1(dev, 114000000);
|
||||||
case 1:
|
|
||||||
return mod_init_1(dev, 722000000);
|
|
||||||
case 2: /* FSM */
|
|
||||||
return mod_init_2(dev, 114000000);
|
|
||||||
case 16: /* PAL */
|
|
||||||
return mod_init_3(dev, 503250000);
|
|
||||||
case 17: /* raw IQ */
|
|
||||||
case 18: /* IQ+FFT */
|
|
||||||
return mod_init_sdr_iq(dev);
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
switch (dev->link[0].info->version) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
return mod_init_1(dev, 722000000);
|
|
||||||
case 2: /* FSM */
|
|
||||||
return mod_init_2(dev, 114000000);
|
return mod_init_2(dev, 114000000);
|
||||||
case 16: /* PAL */
|
case 16: /* PAL */
|
||||||
return mod_init_3(dev, 503250000);
|
return mod_init_3(dev, 503250000);
|
||||||
case 17: /* raw IQ */
|
case 17: /* raw IQ */
|
||||||
return mod_init_sdr_iq(dev);
|
return mod_init_sdr_iq(dev);
|
||||||
case 18: /* IQ+FFT */
|
case 18: /* IQ+FFT (DVB-T) */
|
||||||
return mod_init_sdr_iq(dev);
|
return mod_init_dvbt(dev);
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -248,8 +248,7 @@
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define LNB_BASE (0x400)
|
#define LNB_CONTROL(i) ((i) * 0x20 + 0x00)
|
||||||
#define LNB_CONTROL(i) (LNB_BASE + (i) * 0x20 + 0x00)
|
|
||||||
#define LNB_CMD (7ULL << 0)
|
#define LNB_CMD (7ULL << 0)
|
||||||
#define LNB_CMD_NOP 0
|
#define LNB_CMD_NOP 0
|
||||||
#define LNB_CMD_INIT 1
|
#define LNB_CMD_INIT 1
|
||||||
@ -260,32 +259,31 @@
|
|||||||
#define LNB_CMD_DISEQC 6
|
#define LNB_CMD_DISEQC 6
|
||||||
#define LNB_CMD_SCIF 7
|
#define LNB_CMD_SCIF 7
|
||||||
|
|
||||||
#define LNB_BUSY BIT_ULL(4)
|
#define LNB_BUSY (1ULL << 4)
|
||||||
#define LNB_TONE BIT_ULL(15)
|
#define LNB_TONE (1ULL << 15)
|
||||||
|
|
||||||
#define LNB_INTERRUPT_BASE 4
|
#define LNB_INTERRUPT_BASE 4
|
||||||
|
|
||||||
#define LNB_STATUS(i) (LNB_BASE + (i) * 0x20 + 0x04)
|
#define LNB_STATUS(i) ((i) * 0x20 + 0x04)
|
||||||
#define LNB_VOLTAGE(i) (LNB_BASE + (i) * 0x20 + 0x08)
|
#define LNB_VOLTAGE(i) ((i) * 0x20 + 0x08)
|
||||||
#define LNB_CONFIG(i) (LNB_BASE + (i) * 0x20 + 0x0c)
|
#define LNB_CONFIG(i) ((i) * 0x20 + 0x0c)
|
||||||
#define LNB_BUF_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10)
|
#define LNB_BUF_LEVEL(i) ((i) * 0x20 + 0x10)
|
||||||
#define LNB_BUF_WRITE(i) (LNB_BASE + (i) * 0x20 + 0x14)
|
#define LNB_BUF_WRITE(i) ((i) * 0x20 + 0x14)
|
||||||
|
|
||||||
#define LNB_SETTING(i) (LNB_BASE + (i) * 0x20 + 0x0c)
|
#define LNB_SETTING(i) ((i) * 0x20 + 0x0c)
|
||||||
#define LNB_FIFO_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10)
|
#define LNB_FIFO_LEVEL(i) ((i) * 0x20 + 0x10)
|
||||||
#define LNB_RESET_FIFO(i) (LNB_BASE + (i) * 0x20 + 0x10)
|
#define LNB_RESET_FIFO(i) ((i) * 0x20 + 0x10)
|
||||||
#define LNB_WRITE_FIFO(i) (LNB_BASE + (i) * 0x20 + 0x14)
|
#define LNB_WRITE_FIFO(i) ((i) * 0x20 + 0x14)
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
/* CI Interface (only CI-Bridge) */
|
/* CI Interface (only CI-Bridge) */
|
||||||
|
|
||||||
#define CI_BASE (0x400)
|
#define CI_CONTROL(_ci) ((_ci)->regs + 0x00)
|
||||||
#define CI_CONTROL(i) (CI_BASE + (i) * 32 + 0x00)
|
|
||||||
|
|
||||||
#define CI_DO_ATTRIBUTE_RW(i) (CI_BASE + (i) * 32 + 0x04)
|
#define CI_DO_ATTRIBUTE_RW(_ci) ((_ci)->regs + 0x04)
|
||||||
#define CI_DO_IO_RW(i) (CI_BASE + (i) * 32 + 0x08)
|
#define CI_DO_IO_RW(_ci) ((_ci)->regs + 0x08)
|
||||||
#define CI_READDATA(i) (CI_BASE + (i) * 32 + 0x0c)
|
#define CI_READDATA(_ci) ((_ci)->regs + 0x0c)
|
||||||
#define CI_DO_READ_ATTRIBUTES(i) (CI_BASE + (i) * 32 + 0x10)
|
#define CI_DO_READ_ATTRIBUTES(_ci) ((_ci)->regs + 0x10)
|
||||||
|
|
||||||
#define CI_RESET_CAM (0x00000001)
|
#define CI_RESET_CAM (0x00000001)
|
||||||
#define CI_POWER_ON (0x00000002)
|
#define CI_POWER_ON (0x00000002)
|
||||||
@ -296,6 +294,7 @@
|
|||||||
|
|
||||||
#define CI_CAM_READY (0x00010000)
|
#define CI_CAM_READY (0x00010000)
|
||||||
#define CI_CAM_DETECT (0x00020000)
|
#define CI_CAM_DETECT (0x00020000)
|
||||||
|
#define CI_POWER_ERROR (0x00100000)
|
||||||
#define CI_READY (0x80000000)
|
#define CI_READY (0x80000000)
|
||||||
#define CI_BLOCKIO_ACTIVE (0x40000000)
|
#define CI_BLOCKIO_ACTIVE (0x40000000)
|
||||||
#define CI_BLOCKIO_RCVDATA (0x20000000)
|
#define CI_BLOCKIO_RCVDATA (0x20000000)
|
||||||
@ -305,8 +304,8 @@
|
|||||||
#define CI_READ_CMD (0x40000000)
|
#define CI_READ_CMD (0x40000000)
|
||||||
#define CI_WRITE_CMD (0x80000000)
|
#define CI_WRITE_CMD (0x80000000)
|
||||||
|
|
||||||
#define CI_BLOCKIO_SEND(i) (CI_BASE + (i) * 32 + 0x14)
|
#define CI_BLOCKIO_SEND(_ci) ((_ci)->regs + 0x14)
|
||||||
#define CI_BLOCKIO_RECEIVE(i) (CI_BASE + (i) * 32 + 0x18)
|
#define CI_BLOCKIO_RECEIVE(_ci) ((_ci)->regs + 0x18)
|
||||||
|
|
||||||
#define CI_BLOCKIO_SEND_COMMAND (0x80000000)
|
#define CI_BLOCKIO_SEND_COMMAND (0x80000000)
|
||||||
#define CI_BLOCKIO_SEND_COMPLETE_ACK (0x40000000)
|
#define CI_BLOCKIO_SEND_COMPLETE_ACK (0x40000000)
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include "ddbridge.h"
|
#include "ddbridge.h"
|
||||||
#include "ddbridge-io.h"
|
#include "ddbridge-io.h"
|
||||||
#include "ddbridge-i2c.h"
|
|
||||||
#include "ddbridge-mci.h"
|
#include "ddbridge-mci.h"
|
||||||
|
|
||||||
static int default_mod = 3;
|
static int default_mod = 3;
|
||||||
@ -34,6 +33,14 @@ static int direct_mode;
|
|||||||
module_param(direct_mode, int, 0444);
|
module_param(direct_mode, int, 0444);
|
||||||
MODULE_PARM_DESC(direct_mode, "Ignore LDPC limits and assign high speed demods according to needed symbolrate.");
|
MODULE_PARM_DESC(direct_mode, "Ignore LDPC limits and assign high speed demods according to needed symbolrate.");
|
||||||
|
|
||||||
|
static u32 sx8_tuner_flags;
|
||||||
|
module_param(sx8_tuner_flags, int, 0664);
|
||||||
|
MODULE_PARM_DESC(sx8_tuner_flags, "Change SX8 tuner flags.");
|
||||||
|
|
||||||
|
static u32 sx8_tuner_gain;
|
||||||
|
module_param(sx8_tuner_gain, int, 0664);
|
||||||
|
MODULE_PARM_DESC(sx8_tuner_gain, "Change SX8 tuner gain.");
|
||||||
|
|
||||||
static const u32 MCLK = (1550000000 / 12);
|
static const u32 MCLK = (1550000000 / 12);
|
||||||
|
|
||||||
/* Add 2MBit/s overhead allowance (minimum factor is 90/32400 for QPSK w/o Pilots) */
|
/* Add 2MBit/s overhead allowance (minimum factor is 90/32400 for QPSK w/o Pilots) */
|
||||||
@ -110,6 +117,9 @@ static void release(struct dvb_frontend *fe)
|
|||||||
kfree(mci_base);
|
kfree(mci_base);
|
||||||
}
|
}
|
||||||
kfree(state);
|
kfree(state);
|
||||||
|
#ifdef CONFIG_MEDIA_ATTACH
|
||||||
|
__module_get(THIS_MODULE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ddb_mci_tsconfig(struct mci *state, u32 config)
|
static int ddb_mci_tsconfig(struct mci *state, u32 config)
|
||||||
@ -142,6 +152,7 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status)
|
|||||||
if (stat)
|
if (stat)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
if (res.status == MCI_DEMOD_LOCKED || res.status == SX8_DEMOD_IQ_MODE) {
|
if (res.status == MCI_DEMOD_LOCKED || res.status == SX8_DEMOD_IQ_MODE) {
|
||||||
|
//if (res.status == MCI_DEMOD_LOCKED || sx8_base->iq_mode) {
|
||||||
*status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI |
|
*status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI |
|
||||||
FE_HAS_CARRIER | FE_HAS_SIGNAL;
|
FE_HAS_CARRIER | FE_HAS_SIGNAL;
|
||||||
if (res.status == MCI_DEMOD_LOCKED) {
|
if (res.status == MCI_DEMOD_LOCKED) {
|
||||||
@ -161,8 +172,12 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status)
|
|||||||
}
|
}
|
||||||
} else if (res.status == MCI_DEMOD_TIMEOUT)
|
} else if (res.status == MCI_DEMOD_TIMEOUT)
|
||||||
*status = FE_TIMEDOUT;
|
*status = FE_TIMEDOUT;
|
||||||
else if (res.status >= SX8_DEMOD_WAIT_MATYPE)
|
else if (res.status >= SX8_DEMOD_WAIT_MATYPE) {
|
||||||
*status = FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
|
*status = FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
|
||||||
|
if (sx8_base->iq_mode)
|
||||||
|
*status |= FE_HAS_LOCK;
|
||||||
|
}
|
||||||
|
|
||||||
unlock:
|
unlock:
|
||||||
mutex_unlock(&state->lock);
|
mutex_unlock(&state->lock);
|
||||||
return stat;
|
return stat;
|
||||||
@ -252,6 +267,11 @@ static int stop(struct dvb_frontend *fe)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const u8 ro_lut[8] = {
|
||||||
|
8 | SX8_ROLLOFF_35, 8 | SX8_ROLLOFF_20, 8 | SX8_ROLLOFF_25, 0,
|
||||||
|
8 | SX8_ROLLOFF_15, 8 | SX8_ROLLOFF_10, 8 | SX8_ROLLOFF_05, 0,
|
||||||
|
};
|
||||||
|
|
||||||
static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
|
static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
|
||||||
{
|
{
|
||||||
struct sx8 *state = fe->demodulator_priv;
|
struct sx8 *state = fe->demodulator_priv;
|
||||||
@ -266,10 +286,6 @@ static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
|
|||||||
u32 bits_per_symbol = 0;
|
u32 bits_per_symbol = 0;
|
||||||
int i = -1, stat = 0;
|
int i = -1, stat = 0;
|
||||||
struct ddb_link *link = state->mci.base->link;
|
struct ddb_link *link = state->mci.base->link;
|
||||||
const u8 ro_lut[8] = {
|
|
||||||
8 | SX8_ROLLOFF_35, 8 | SX8_ROLLOFF_20, 8 | SX8_ROLLOFF_25, 0,
|
|
||||||
8 | SX8_ROLLOFF_15, 8 | SX8_ROLLOFF_10, 8 | SX8_ROLLOFF_05, 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (link->ids.device == 0x000b) {
|
if (link->ids.device == 0x000b) {
|
||||||
/* Mask out higher modulations and MIS for Basic
|
/* Mask out higher modulations and MIS for Basic
|
||||||
@ -345,7 +361,7 @@ static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
|
|||||||
state->mci.demod = i;
|
state->mci.demod = i;
|
||||||
|
|
||||||
if (!sx8_base->tuner_use_count[input])
|
if (!sx8_base->tuner_use_count[input])
|
||||||
mci_set_tuner(fe, input, 1, 0, 0);
|
mci_set_tuner(fe, input, 1, sx8_tuner_flags, sx8_tuner_gain);
|
||||||
sx8_base->tuner_use_count[input]++;
|
sx8_base->tuner_use_count[input]++;
|
||||||
sx8_base->iq_mode = (ts_config > 1);
|
sx8_base->iq_mode = (ts_config > 1);
|
||||||
unlock:
|
unlock:
|
||||||
@ -374,6 +390,8 @@ unlock:
|
|||||||
cmd.dvbs2_search.s2_modulation_mask = modmask;
|
cmd.dvbs2_search.s2_modulation_mask = modmask;
|
||||||
cmd.dvbs2_search.rsvd1 = ro_lut[p->rolloff & 7];
|
cmd.dvbs2_search.rsvd1 = ro_lut[p->rolloff & 7];
|
||||||
cmd.dvbs2_search.retry = 2;
|
cmd.dvbs2_search.retry = 2;
|
||||||
|
if (sx8_base->iq_mode)
|
||||||
|
cmd.dvbs2_search.retry = 255;
|
||||||
cmd.dvbs2_search.frequency = p->frequency * 1000;
|
cmd.dvbs2_search.frequency = p->frequency * 1000;
|
||||||
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
|
cmd.dvbs2_search.symbol_rate = p->symbol_rate;
|
||||||
cmd.dvbs2_search.scrambling_sequence_index =
|
cmd.dvbs2_search.scrambling_sequence_index =
|
||||||
@ -396,7 +414,7 @@ unlock:
|
|||||||
|
|
||||||
|
|
||||||
static int start_iq(struct dvb_frontend *fe, u32 flags,
|
static int start_iq(struct dvb_frontend *fe, u32 flags,
|
||||||
u32 roll_off, u32 ts_config)
|
u32 ts_config)
|
||||||
{
|
{
|
||||||
struct sx8 *state = fe->demodulator_priv;
|
struct sx8 *state = fe->demodulator_priv;
|
||||||
struct mci_base *mci_base = state->mci.base;
|
struct mci_base *mci_base = state->mci.base;
|
||||||
@ -423,6 +441,7 @@ static int start_iq(struct dvb_frontend *fe, u32 flags,
|
|||||||
state->mci.demod = 0;
|
state->mci.demod = 0;
|
||||||
sx8_base->tuner_use_count[input]++;
|
sx8_base->tuner_use_count[input]++;
|
||||||
sx8_base->iq_mode = 2;
|
sx8_base->iq_mode = 2;
|
||||||
|
mci_set_tuner(fe, input, 1, flags & 0xff, 0x40);
|
||||||
} else {
|
} else {
|
||||||
if ((state->iq_started & 0x07) != state->mci.nr) {
|
if ((state->iq_started & 0x07) != state->mci.nr) {
|
||||||
stat = -EBUSY;
|
stat = -EBUSY;
|
||||||
@ -433,11 +452,11 @@ unlock:
|
|||||||
mutex_unlock(&mci_base->tuner_lock);
|
mutex_unlock(&mci_base->tuner_lock);
|
||||||
if (stat)
|
if (stat)
|
||||||
return stat;
|
return stat;
|
||||||
mci_set_tuner(fe, input, 1, flags & 0xff, 0);
|
|
||||||
memset(&cmd, 0, sizeof(cmd));
|
memset(&cmd, 0, sizeof(cmd));
|
||||||
cmd.command = SX8_CMD_START_IQ;
|
cmd.command = SX8_CMD_START_IQ;
|
||||||
cmd.sx8_start_iq.flags = (flags >> 16) & 0xff;
|
cmd.sx8_start_iq.flags = (flags >> 16) & 0xff;
|
||||||
cmd.sx8_start_iq.roll_off = roll_off;
|
cmd.sx8_start_iq.roll_off = 5;
|
||||||
|
//cmd.sx8_start_iq.roll_off = ro_lut[p->rolloff & 7];
|
||||||
cmd.sx8_start_iq.frequency = p->frequency * 1000;
|
cmd.sx8_start_iq.frequency = p->frequency * 1000;
|
||||||
cmd.sx8_start_iq.symbol_rate = p->symbol_rate;
|
cmd.sx8_start_iq.symbol_rate = p->symbol_rate;
|
||||||
cmd.sx8_start_iq.gain = (flags >> 8) & 0xff;
|
cmd.sx8_start_iq.gain = (flags >> 8) & 0xff;
|
||||||
@ -482,18 +501,21 @@ static int set_parameters(struct dvb_frontend *fe)
|
|||||||
stop_iq(fe);
|
stop_iq(fe);
|
||||||
switch (p->modulation) {
|
switch (p->modulation) {
|
||||||
case APSK_256:
|
case APSK_256:
|
||||||
|
case APSK_256_L:
|
||||||
mask = 0x7f;
|
mask = 0x7f;
|
||||||
break;
|
break;
|
||||||
case APSK_128:
|
case APSK_128:
|
||||||
mask = 0x3f;
|
mask = 0x3f;
|
||||||
break;
|
break;
|
||||||
case APSK_64:
|
case APSK_64:
|
||||||
|
case APSK_64_L:
|
||||||
mask = 0x1f;
|
mask = 0x1f;
|
||||||
break;
|
break;
|
||||||
case APSK_32:
|
case APSK_32:
|
||||||
mask = 0x0f;
|
mask = 0x0f;
|
||||||
break;
|
break;
|
||||||
case APSK_16:
|
case APSK_16:
|
||||||
|
case APSK_16_L:
|
||||||
mask = 0x07;
|
mask = 0x07;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -502,7 +524,7 @@ static int set_parameters(struct dvb_frontend *fe)
|
|||||||
}
|
}
|
||||||
stat = start(fe, 3, mask, ts_config);
|
stat = start(fe, 3, mask, ts_config);
|
||||||
} else {
|
} else {
|
||||||
stat = start_iq(fe, isi & 0xffffff, 4, ts_config);
|
stat = start_iq(fe, isi & 0xffffff, ts_config);
|
||||||
}
|
}
|
||||||
mutex_unlock(&state->lock);
|
mutex_unlock(&state->lock);
|
||||||
return stat;
|
return stat;
|
||||||
@ -537,7 +559,9 @@ static enum dvbfe_algo get_algo(struct dvb_frontend *fe)
|
|||||||
static int set_input(struct dvb_frontend *fe, int input)
|
static int set_input(struct dvb_frontend *fe, int input)
|
||||||
{
|
{
|
||||||
struct sx8 *state = fe->demodulator_priv;
|
struct sx8 *state = fe->demodulator_priv;
|
||||||
|
#ifndef KERNEL_DVB_CORE
|
||||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (input >= SX8_TUNER_NUM)
|
if (input >= SX8_TUNER_NUM)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -546,7 +570,10 @@ static int set_input(struct dvb_frontend *fe, int input)
|
|||||||
mutex_lock(&state->lock);
|
mutex_lock(&state->lock);
|
||||||
stop_iq(fe);
|
stop_iq(fe);
|
||||||
stop(fe);
|
stop(fe);
|
||||||
state->mci.tuner = p->input = input;
|
state->mci.tuner = input;
|
||||||
|
#ifndef KERNEL_DVB_CORE
|
||||||
|
p->input = input;
|
||||||
|
#endif
|
||||||
mutex_unlock(&state->lock);
|
mutex_unlock(&state->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -572,7 +599,6 @@ static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties
|
|||||||
|
|
||||||
static struct dvb_frontend_ops sx8_ops = {
|
static struct dvb_frontend_ops sx8_ops = {
|
||||||
.delsys = { SYS_DVBS, SYS_DVBS2 },
|
.delsys = { SYS_DVBS, SYS_DVBS2 },
|
||||||
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
|
|
||||||
.info = {
|
.info = {
|
||||||
.name = "DVB-S/S2X",
|
.name = "DVB-S/S2X",
|
||||||
.frequency_min_hz = 950000000,
|
.frequency_min_hz = 950000000,
|
||||||
@ -592,7 +618,10 @@ static struct dvb_frontend_ops sx8_ops = {
|
|||||||
.tune = tune,
|
.tune = tune,
|
||||||
.release = release,
|
.release = release,
|
||||||
.read_status = read_status,
|
.read_status = read_status,
|
||||||
|
#ifndef KERNEL_DVB_CORE
|
||||||
|
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
|
||||||
.set_input = set_input,
|
.set_input = set_input,
|
||||||
|
#endif
|
||||||
.set_lna = set_lna,
|
.set_lna = set_lna,
|
||||||
.sleep = sleep,
|
.sleep = sleep,
|
||||||
};
|
};
|
||||||
@ -602,8 +631,10 @@ static int init(struct mci *mci)
|
|||||||
struct sx8 *state = (struct sx8 *) mci;
|
struct sx8 *state = (struct sx8 *) mci;
|
||||||
|
|
||||||
state->mci.demod = SX8_DEMOD_NONE;
|
state->mci.demod = SX8_DEMOD_NONE;
|
||||||
|
#ifndef KERNEL_DVB_CORE
|
||||||
mci->fe.ops.xbar[1] = mci->nr;
|
mci->fe.ops.xbar[1] = mci->nr;
|
||||||
mci->fe.dtv_property_cache.input = mci->tuner;
|
mci->fe.dtv_property_cache.input = mci->tuner;
|
||||||
|
#endif
|
||||||
mutex_init(&state->lock);
|
mutex_init(&state->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -615,7 +646,7 @@ static int base_init(struct mci_base *mci_base)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mci_cfg ddb_max_sx8_cfg = {
|
static struct mci_cfg ddb_max_sx8_cfg = {
|
||||||
.type = 0,
|
.type = 0,
|
||||||
.fe_ops = &sx8_ops,
|
.fe_ops = &sx8_ops,
|
||||||
.base_size = sizeof(struct sx8_base),
|
.base_size = sizeof(struct sx8_base),
|
||||||
@ -623,3 +654,10 @@ struct mci_cfg ddb_max_sx8_cfg = {
|
|||||||
.init = init,
|
.init = init,
|
||||||
.base_init = base_init,
|
.base_init = base_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct dvb_frontend *ddb_sx8_attach(struct ddb_input *input, int nr, int tuner,
|
||||||
|
int (**fn_set_input)(struct dvb_frontend *fe, int input))
|
||||||
|
{
|
||||||
|
*fn_set_input = set_input;
|
||||||
|
return ddb_mci_attach(input, &ddb_max_sx8_cfg, nr, tuner);
|
||||||
|
}
|
||||||
|
@ -23,9 +23,6 @@
|
|||||||
#ifndef _DDBRIDGE_H_
|
#ifndef _DDBRIDGE_H_
|
||||||
#define _DDBRIDGE_H_
|
#define _DDBRIDGE_H_
|
||||||
|
|
||||||
/* #define DDB_USE_WORK */
|
|
||||||
/*#define DDB_TEST_THREADED*/
|
|
||||||
|
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
|
||||||
#if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE)
|
#if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE)
|
||||||
@ -150,13 +147,10 @@ struct ddb_info {
|
|||||||
u32 type;
|
u32 type;
|
||||||
#define DDB_NONE 0
|
#define DDB_NONE 0
|
||||||
#define DDB_OCTOPUS 1
|
#define DDB_OCTOPUS 1
|
||||||
#define DDB_OCTOPUS_CI 2
|
|
||||||
#define DDB_MOD 3
|
#define DDB_MOD 3
|
||||||
#define DDB_OCTONET 4
|
#define DDB_OCTONET 4
|
||||||
#define DDB_OCTOPUS_MAX 5
|
#define DDB_OCTOPUS_MAX 5
|
||||||
#define DDB_OCTOPUS_MAX_CT 6
|
#define DDB_OCTOPUS_MAX_CT 6
|
||||||
#define DDB_OCTOPRO 7
|
|
||||||
#define DDB_OCTOPRO_HDIN 8
|
|
||||||
#define DDB_OCTOPUS_MCI 9
|
#define DDB_OCTOPUS_MCI 9
|
||||||
u32 version;
|
u32 version;
|
||||||
char *name;
|
char *name;
|
||||||
@ -178,11 +172,14 @@ struct ddb_info {
|
|||||||
#define TS_QUIRK_ALT_OSC 8
|
#define TS_QUIRK_ALT_OSC 8
|
||||||
u8 mci_ports;
|
u8 mci_ports;
|
||||||
u8 mci_type;
|
u8 mci_type;
|
||||||
|
u8 ci_mask;
|
||||||
|
|
||||||
u32 tempmon_irq;
|
u32 tempmon_irq;
|
||||||
u32 lostlock_irq;
|
u32 lostlock_irq;
|
||||||
u32 mdio_base;
|
u32 mdio_base;
|
||||||
u32 hw_min;
|
u32 hw_min;
|
||||||
|
u32 ci_base;
|
||||||
|
u32 lnb_base;
|
||||||
const struct ddb_regmap *regmap;
|
const struct ddb_regmap *regmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -205,11 +202,8 @@ struct ddb_dma {
|
|||||||
u32 div;
|
u32 div;
|
||||||
u32 bufval;
|
u32 bufval;
|
||||||
|
|
||||||
#ifdef DDB_USE_WORK
|
|
||||||
struct work_struct work;
|
struct work_struct work;
|
||||||
#else
|
|
||||||
struct tasklet_struct tasklet;
|
struct tasklet_struct tasklet;
|
||||||
#endif
|
|
||||||
spinlock_t lock; /* DMA lock */
|
spinlock_t lock; /* DMA lock */
|
||||||
wait_queue_head_t wq;
|
wait_queue_head_t wq;
|
||||||
int running;
|
int running;
|
||||||
@ -254,6 +248,7 @@ struct ddb_ci {
|
|||||||
struct dvb_ca_en50221 en;
|
struct dvb_ca_en50221 en;
|
||||||
struct ddb_port *port;
|
struct ddb_port *port;
|
||||||
u32 nr;
|
u32 nr;
|
||||||
|
u32 regs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ddb_io {
|
struct ddb_io {
|
||||||
@ -327,6 +322,10 @@ struct ddb_port {
|
|||||||
#define DDB_TUNER_MCI 48
|
#define DDB_TUNER_MCI 48
|
||||||
#define DDB_TUNER_MCI_SX8 (DDB_TUNER_MCI + 0)
|
#define DDB_TUNER_MCI_SX8 (DDB_TUNER_MCI + 0)
|
||||||
#define DDB_TUNER_MCI_M4 (DDB_TUNER_MCI + 1)
|
#define DDB_TUNER_MCI_M4 (DDB_TUNER_MCI + 1)
|
||||||
|
#define DDB_TUNER_MCI_M8 (DDB_TUNER_MCI + 2)
|
||||||
|
#define DDB_TUNER_MCI_M8A (DDB_TUNER_MCI + 3)
|
||||||
|
#define DDB_TUNER_MCI_M2 (DDB_TUNER_MCI + 4)
|
||||||
|
#define DDB_TUNER_MCI_M8E (DDB_TUNER_MCI + 5)
|
||||||
|
|
||||||
struct ddb_input *input[2];
|
struct ddb_input *input[2];
|
||||||
struct ddb_output *output;
|
struct ddb_output *output;
|
||||||
@ -341,6 +340,8 @@ struct mod_base {
|
|||||||
u32 frequency;
|
u32 frequency;
|
||||||
u32 flat_start;
|
u32 flat_start;
|
||||||
u32 flat_end;
|
u32 flat_end;
|
||||||
|
u32 attenuation;
|
||||||
|
u32 gain;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ddb_mod {
|
struct ddb_mod {
|
||||||
@ -424,7 +425,6 @@ struct ddb_link {
|
|||||||
spinlock_t lock; /* lock link access */
|
spinlock_t lock; /* lock link access */
|
||||||
struct mutex flash_mutex; /* lock flash access */
|
struct mutex flash_mutex; /* lock flash access */
|
||||||
struct ddb_lnb lnb;
|
struct ddb_lnb lnb;
|
||||||
struct tasklet_struct tasklet;
|
|
||||||
struct ddb_ids ids;
|
struct ddb_ids ids;
|
||||||
|
|
||||||
spinlock_t temp_lock; /* lock temp chip access */
|
spinlock_t temp_lock; /* lock temp chip access */
|
||||||
@ -537,7 +537,7 @@ struct DDMOD_FLASH {
|
|||||||
|
|
||||||
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
|
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
|
||||||
|
|
||||||
#define DDBRIDGE_VERSION "0.9.38"
|
#define DDBRIDGE_VERSION "0.9.41"
|
||||||
|
|
||||||
/* linked function prototypes */
|
/* linked function prototypes */
|
||||||
|
|
||||||
@ -581,5 +581,10 @@ struct ddb_irq *ddb_irq_set(struct ddb *dev, u32 link, u32 nr,
|
|||||||
void (*handler)(void *), void *data);
|
void (*handler)(void *), void *data);
|
||||||
|
|
||||||
struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, struct mci_cfg *cfg, int nr, int tuner);
|
struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, struct mci_cfg *cfg, int nr, int tuner);
|
||||||
|
struct dvb_frontend *ddb_sx8_attach(struct ddb_input *input, int nr, int tuner,
|
||||||
|
int (**fn_set_input)(struct dvb_frontend *fe, int input));
|
||||||
|
struct dvb_frontend *ddb_mx_attach(struct ddb_input *input, int nr, int tuner, int type);
|
||||||
|
|
||||||
|
int ddb_dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
|
||||||
|
int (*func)(struct file *file, unsigned int cmd, void *arg));
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
#include <linux/net.h>
|
#include <linux/net.h>
|
||||||
#include "dvb_netstream.h"
|
#include "dvb_netstream.h"
|
||||||
|
|
||||||
|
int ddb_dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
|
||||||
|
int (*func)(struct file *file, unsigned int cmd, void *arg));
|
||||||
|
|
||||||
static ssize_t ns_write(struct file *file, const char *buf,
|
static ssize_t ns_write(struct file *file, const char *buf,
|
||||||
size_t count, loff_t *ppos)
|
size_t count, loff_t *ppos)
|
||||||
{
|
{
|
||||||
@ -211,7 +214,7 @@ static int do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
|||||||
static long ns_ioctl(struct file *file,
|
static long ns_ioctl(struct file *file,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
return dvb_usercopy(file, cmd, arg, do_ioctl);
|
return ddb_dvb_usercopy(file, cmd, arg, do_ioctl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct file_operations ns_fops = {
|
static const struct file_operations ns_fops = {
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
#include <linux/socket.h>
|
#include <linux/socket.h>
|
||||||
#include <linux/in.h>
|
#include <linux/in.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <linux/dvb/ns.h>
|
#include "ns.h"
|
||||||
|
|
||||||
#include <media/dvbdev.h>
|
#include <media/dvbdev.h>
|
||||||
|
|
||||||
|
76
ddbridge/ns.h
Normal file
76
ddbridge/ns.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#ifndef _UAPI_DVBNS_H_
|
||||||
|
#define _UAPI_DVBNS_H_
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
struct dvb_ns_params {
|
||||||
|
__u8 smac[6];
|
||||||
|
__u8 dmac[6];
|
||||||
|
__u8 sip[16];
|
||||||
|
__u8 dip[16];
|
||||||
|
__u16 sport;
|
||||||
|
__u16 dport;
|
||||||
|
__u16 sport2;
|
||||||
|
__u16 dport2;
|
||||||
|
__u8 ssrc[8];
|
||||||
|
__u8 flags;
|
||||||
|
__u8 qos;
|
||||||
|
__u16 vlan;
|
||||||
|
__u8 ttl;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DVB_NS_IPV6 0x01
|
||||||
|
#define DVB_NS_RTP 0x02
|
||||||
|
#define DVB_NS_RTCP 0x04
|
||||||
|
#define DVB_NS_RTP_TO 0x08
|
||||||
|
#define DVB_NS_VLAN 0x10
|
||||||
|
|
||||||
|
struct dvb_ns_rtcp {
|
||||||
|
__u8 *msg;
|
||||||
|
__u16 len;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dvb_ns_packet {
|
||||||
|
__u8 *buf;
|
||||||
|
__u8 count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dvb_nsd_ts {
|
||||||
|
__u16 pid;
|
||||||
|
__u16 num;
|
||||||
|
__u16 input;
|
||||||
|
__u16 timeout;
|
||||||
|
__u16 len;
|
||||||
|
__u8 *ts;
|
||||||
|
__u8 mode;
|
||||||
|
__u8 table;
|
||||||
|
|
||||||
|
__u8 filter_mask;
|
||||||
|
__u8 section;
|
||||||
|
__u16 section_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dvb_ns_cap {
|
||||||
|
__u8 streams_max;
|
||||||
|
__u8 reserved[127];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NS_SET_NET _IOW('o', 192, struct dvb_ns_params)
|
||||||
|
#define NS_START _IO('o', 193)
|
||||||
|
#define NS_STOP _IO('o', 194)
|
||||||
|
#define NS_SET_PID _IOW('o', 195, __u16)
|
||||||
|
#define NS_SET_PIDS _IOW('o', 196, __u8 *)
|
||||||
|
#define NS_SET_RTCP_MSG _IOW('o', 197, struct dvb_ns_rtcp)
|
||||||
|
|
||||||
|
#define NSD_START_GET_TS _IOWR('o', 198, struct dvb_nsd_ts)
|
||||||
|
#define NSD_STOP_GET_TS _IOWR('o', 199, struct dvb_nsd_ts)
|
||||||
|
#define NSD_CANCEL_GET_TS _IO('o', 200)
|
||||||
|
#define NSD_POLL_GET_TS _IOWR('o', 201, struct dvb_nsd_ts)
|
||||||
|
|
||||||
|
#define NS_SET_PACKETS _IOW('o', 202, struct dvb_ns_packet)
|
||||||
|
#define NS_INSERT_PACKETS _IOW('o', 203, __u8)
|
||||||
|
#define NS_SET_CI _IOW('o', 204, __u8)
|
||||||
|
|
||||||
|
#define NS_GET_CAP _IOR('o', 204, struct dvb_ns_cap))
|
||||||
|
|
||||||
|
#endif /*_UAPI_DVBNS_H_*/
|
@ -24,7 +24,11 @@
|
|||||||
#include "ddbridge.h"
|
#include "ddbridge.h"
|
||||||
#include "ddbridge-io.h"
|
#include "ddbridge-io.h"
|
||||||
|
|
||||||
|
#if (KERNEL_VERSION(6, 11, 0) > LINUX_VERSION_CODE)
|
||||||
static int __exit octonet_remove(struct platform_device *pdev)
|
static int __exit octonet_remove(struct platform_device *pdev)
|
||||||
|
#else
|
||||||
|
static void __exit octonet_remove(struct platform_device *pdev)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct ddb *dev;
|
struct ddb *dev;
|
||||||
|
|
||||||
@ -43,7 +47,9 @@ static int __exit octonet_remove(struct platform_device *pdev)
|
|||||||
ddb_ports_release(dev);
|
ddb_ports_release(dev);
|
||||||
ddb_unmap(dev);
|
ddb_unmap(dev);
|
||||||
platform_set_drvdata(pdev, 0);
|
platform_set_drvdata(pdev, 0);
|
||||||
|
#if (KERNEL_VERSION(6, 11, 0) > LINUX_VERSION_CODE)
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init octonet_probe(struct platform_device *pdev)
|
static int __init octonet_probe(struct platform_device *pdev)
|
||||||
|
@ -7,7 +7,21 @@ API:
|
|||||||
Currently DTV_STREAM_ID is misused.
|
Currently DTV_STREAM_ID is misused.
|
||||||
|
|
||||||
0x10000000 - symbols (locked and tracked) at symbol rate
|
0x10000000 - symbols (locked and tracked) at symbol rate
|
||||||
0x20000000 - samples at ADC rate (1550/24=64.583... MHz)
|
0x20000000 - samples at symbol rate
|
||||||
0x30000000 - samples at symbol rate
|
(fixed at ADC rate (1550/24=64.583... MHz) if 0x00010000 is set)
|
||||||
|
Max. sample rate is 64.583333 MHz.
|
||||||
|
|
||||||
Max. sample rate is 64.583333 MHz.
|
0x00xx0000 - flags
|
||||||
|
Bit 0 : 0 = VTM/SDR, 1 = SCAN,
|
||||||
|
Bit 1: 1 = Disable channel AGC,
|
||||||
|
Bit 2: 1 = Set Gain.
|
||||||
|
|
||||||
|
0x0000xx00 - xx=gain
|
||||||
|
|
||||||
|
0x000000xx - xx=flags
|
||||||
|
Bit 0:1 Preamp Mode; 0 = Preamp AGC, 1 == Minimum (~ -17dB) ,
|
||||||
|
2 = Medium, 3 = Maximum gain {~ 15dB}
|
||||||
|
Bit 2: Bypass Input LNA (6 dB less gain) (Note this is after Preamp)
|
||||||
|
Bit 4: Set RF Gain
|
||||||
|
Bit 5: Freeze RF Gain (Turn AGC off at current gain, only when already enabled)
|
||||||
|
Bit 7: Optimize RF Gain and freeze for FFT
|
||||||
|
@ -83,6 +83,7 @@ limit depends on # of channels active.
|
|||||||
|
|
||||||
|
|
||||||
MODULATOR_INPUT_BITRATE:
|
MODULATOR_INPUT_BITRATE:
|
||||||
|
THIS FEATURE ONLY WORKS FOR DVB-C MODULATORS
|
||||||
|
|
||||||
The modulator will ALWAY insert null packets if it
|
The modulator will ALWAY insert null packets if it
|
||||||
does not get enough data.
|
does not get enough data.
|
||||||
@ -94,6 +95,21 @@ So, this property should be set last.
|
|||||||
|
|
||||||
unit - 2^-32 Hz
|
unit - 2^-32 Hz
|
||||||
|
|
||||||
|
FOR DVB-T MODULATORS THIS FEATURE DOES NOT WORK
|
||||||
|
|
||||||
|
You should write a steady stream of transport packets with the
|
||||||
|
rate given by the modulation. The easiest way to keep a steady rate
|
||||||
|
is to write as much as the device will receive until it blocks. In that
|
||||||
|
way you ensure that the device will not get an underrun of data and
|
||||||
|
you can use the acceptance rate as a guide for you input rate.
|
||||||
|
All you should do is to correct the PCR of your transport stream according
|
||||||
|
to the calculated packet rate and use a buffer that assures that you are
|
||||||
|
always ready to write as sson as the modulator device allows it.
|
||||||
|
E.g you have a circular output buffer that you fill to say 50% and than start
|
||||||
|
writing into the device in a seperate thread. You feed the output buffer
|
||||||
|
with you input TS and see that it does not underrun, you may need to insert
|
||||||
|
empty packets to do that. The output thread should always have enough data
|
||||||
|
to write to the device as soon as it no longer blocks.
|
||||||
|
|
||||||
|
|
||||||
Debugging features:
|
Debugging features:
|
||||||
|
181
docs/modulator_mci_api
Normal file
181
docs/modulator_mci_api
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
MCI API for modulators:
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
The API is not meant to be used directly but via the app/modconfig command.
|
||||||
|
Example config files for DVB-T and DVB-C are in apps/modulator.conf and
|
||||||
|
apps/modulator-c.conf, respectively.
|
||||||
|
|
||||||
|
stream - refers to one modulator slot which take a TS and modulates it
|
||||||
|
e.g. the FSM16 has 16 streams
|
||||||
|
|
||||||
|
channel - an actual frequency the stream is sent on
|
||||||
|
the FSM cards in default config have 96 channels at 114 MHz + X * 8 MHz (X=0-95)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MCI commands can be sent to modulators with the IOCTL_DDB_MCI_CMD:
|
||||||
|
|
||||||
|
#define IOCTL_DDB_MCI_CMD _IOWR(DDB_MAGIC, 0x0c, struct ddb_mci_msg)
|
||||||
|
|
||||||
|
with
|
||||||
|
|
||||||
|
struct ddb_mci_msg {
|
||||||
|
__u32 link;
|
||||||
|
struct mci_command cmd;
|
||||||
|
struct mci_result res;
|
||||||
|
};
|
||||||
|
|
||||||
|
link is always 0 for modulators.
|
||||||
|
|
||||||
|
mci_command with the entries relevant to modulators looks like this:
|
||||||
|
|
||||||
|
struct mci_command {
|
||||||
|
union {
|
||||||
|
u32 command_word;
|
||||||
|
struct {
|
||||||
|
u8 command;
|
||||||
|
u8 tuner;
|
||||||
|
u8 demod;
|
||||||
|
u8 output;
|
||||||
|
};
|
||||||
|
struct {
|
||||||
|
u8 mod_command;
|
||||||
|
u8 mod_channel;
|
||||||
|
u8 mod_stream;
|
||||||
|
u8 mod_rsvd1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
...
|
||||||
|
struct mod_setup_channels mod_setup_channels[4];
|
||||||
|
struct mod_setup_stream mod_setup_stream;
|
||||||
|
struct mod_setup_output mod_setup_output;
|
||||||
|
...
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mci_result like this:
|
||||||
|
|
||||||
|
struct mci_result {
|
||||||
|
union {
|
||||||
|
u32 status_word;
|
||||||
|
struct {
|
||||||
|
u8 status;
|
||||||
|
u8 mode;
|
||||||
|
u16 time;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
...
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mci_command.command can be one of:
|
||||||
|
|
||||||
|
#define MOD_SETUP_CHANNELS (0x60)
|
||||||
|
#define MOD_SETUP_OUTPUT (0x61)
|
||||||
|
#define MOD_SETUP_STREAM (0x62)
|
||||||
|
|
||||||
|
which use the following corresponding structs in mci_command:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MOD_SETUP_CHANNELS:
|
||||||
|
|
||||||
|
mod_command = MOD_SETUP_CHANNELS
|
||||||
|
mod_channel and mod_stream are not used
|
||||||
|
|
||||||
|
|
||||||
|
struct mod_setup_channels {
|
||||||
|
u8 flags;
|
||||||
|
u8 standard;
|
||||||
|
u8 num_channels;
|
||||||
|
u8 rsvd;
|
||||||
|
u32 frequency;
|
||||||
|
u32 offset; /* used only when Standard == 0 */
|
||||||
|
u32 bandwidth; /* used only when Standard == 0 */
|
||||||
|
};
|
||||||
|
|
||||||
|
You can set up to 4 regions of channels.
|
||||||
|
|
||||||
|
flags:
|
||||||
|
#define MOD_SETUP_FLAG_FIRST (0x01)
|
||||||
|
#define MOD_SETUP_FLAG_LAST (0x02)
|
||||||
|
#define MOD_SETUP_FLAG_VALID (0x80)
|
||||||
|
|
||||||
|
Set first/last if this is the first and/or last region you define.
|
||||||
|
Set valid if you actually want to set it.
|
||||||
|
|
||||||
|
|
||||||
|
standard:
|
||||||
|
|
||||||
|
see MOD_STANDARD_* defines in ddbridge-mci.h
|
||||||
|
for FSM cards only MOD_STANDARD_DVBC_6/7/8 are relevant
|
||||||
|
|
||||||
|
|
||||||
|
num_channels:
|
||||||
|
|
||||||
|
number of channels in this channel region
|
||||||
|
|
||||||
|
|
||||||
|
frequency:
|
||||||
|
|
||||||
|
start frquency of this region
|
||||||
|
frequency offset between channels depends on standard (e.g. 8MHz for DVBC_8)
|
||||||
|
|
||||||
|
|
||||||
|
offset/bandwidth: set offsets between channels and bandwidth by hand (not for FSM cards)
|
||||||
|
|
||||||
|
|
||||||
|
NOTE: After changing the channel setup you have to set the streams you want to use at least once
|
||||||
|
before you use them. Otherwise, they will not have the new channel frequency.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MOD_SETUP_OUTPUT:
|
||||||
|
|
||||||
|
set mod_command to MOD_SETUP_OUTPUT
|
||||||
|
mod_channel and mod_stream are not used
|
||||||
|
|
||||||
|
|
||||||
|
struct mod_setup_output {
|
||||||
|
u8 connector; /* 0 = OFF, 1 = F, 2 = SMA */
|
||||||
|
u8 num_channels; /* max active channels, determines max power for each channel. */
|
||||||
|
u8 unit; /* 0 = dBµV, 1 = dBm, */
|
||||||
|
u8 rsvd;
|
||||||
|
s16 channel_power;
|
||||||
|
};
|
||||||
|
|
||||||
|
connector: use the F- or SMA-connector (the FSM cards only has F)
|
||||||
|
|
||||||
|
num_channels: how many channels will have actually have a stream using it (has to be less or equal to card stream capability)
|
||||||
|
This influences internal multipliers. Setting it lower improves signal quality.
|
||||||
|
|
||||||
|
|
||||||
|
unit: determines unit of channel_power (0 = dBµV, 1 = dBm)
|
||||||
|
|
||||||
|
channel_power: set channel power of output to X dBµV or dBm.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
MOD_SETUP_STREAM:
|
||||||
|
|
||||||
|
|
||||||
|
mod_command = MOD_SETUP_STREAM
|
||||||
|
mod_stream = stream you want to configure
|
||||||
|
mod_channel = channel the stream is to be sent on
|
||||||
|
|
||||||
|
|
||||||
|
struct mod_setup_stream {
|
||||||
|
u8 standard;
|
||||||
|
u8 stream_format;
|
||||||
|
u8 rsvd1[2];
|
||||||
|
u32 symbol_rate; /* only used when Standard doesn't define a fixed symbol rate */
|
||||||
|
union {
|
||||||
|
struct mod_ofdm_parameter ofdm;
|
||||||
|
struct mod_qam_parameter qam;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -28,3 +28,7 @@ devices in any way.
|
|||||||
adapter_alloc=3 is rcommended when using redirect
|
adapter_alloc=3 is rcommended when using redirect
|
||||||
The ci device will then show up in the same adapter directory and most
|
The ci device will then show up in the same adapter directory and most
|
||||||
software will then assume it belongs to the frontend in the same directory.
|
software will then assume it belongs to the frontend in the same directory.
|
||||||
|
|
||||||
|
|
||||||
|
Redirect between cards in different IOMMU groups will not work!
|
||||||
|
Disable IOMMU if you have this problem.
|
@ -6,7 +6,7 @@
|
|||||||
config DVB_MMAP
|
config DVB_MMAP
|
||||||
bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
|
bool "Enable DVB memory-mapped API (EXPERIMENTAL)"
|
||||||
depends on DVB_CORE
|
depends on DVB_CORE
|
||||||
depends on VIDEO_V4L2=y || VIDEO_V4L2=DVB_CORE
|
depends on VIDEO_DEV=y || VIDEO_DEV=DVB_CORE
|
||||||
select VIDEOBUF2_VMALLOC
|
select VIDEOBUF2_VMALLOC
|
||||||
help
|
help
|
||||||
This option enables DVB experimental memory-mapped API, which
|
This option enables DVB experimental memory-mapped API, which
|
||||||
|
@ -13,4 +13,3 @@ dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \
|
|||||||
obj-$(CONFIG_DVB_CORE) += dvb-core.o
|
obj-$(CONFIG_DVB_CORE) += dvb-core.o
|
||||||
|
|
||||||
EXTRA_CFLAGS += -DCONFIG_DVB_DYNAMIC_MINORS -DCONFIG_DVB_NET
|
EXTRA_CFLAGS += -DCONFIG_DVB_DYNAMIC_MINORS -DCONFIG_DVB_NET
|
||||||
#NOSTDINC_FLAGS += -I$(KBUILD_EXTMOD)/include -I$(KBUILD_EXTMOD)/include/linux
|
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
|
|
||||||
dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
|
dvb-net-$(CONFIG_DVB_NET) := dvb_net.o
|
||||||
|
|
||||||
dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
|
dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \
|
||||||
dvb_ca_en50221.o dvb_frontend.o \
|
dvb_ca_en50221.o dvb_frontend.o \
|
||||||
$(dvb-net-y) dvb_ringbuffer.o dvb_math.o
|
$(dvb-net-y) dvb_ringbuffer.o dvb_math.o
|
||||||
|
|
||||||
obj-$(CONFIG_DVB_CORE) += dvb-core.o
|
obj-$(CONFIG_DVB_CORE) += dvb-core.o
|
||||||
|
|
||||||
ccflags-y += -Idrivers/media/dvb-core/
|
ccflags-y += -Idrivers/media/dvb-core/
|
||||||
|
ccflags-y += --include=dd_compat.h
|
||||||
|
@ -1,19 +1,9 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
/*
|
/*
|
||||||
* dmxdev.c - DVB demultiplexer device
|
* dmxdev.c - DVB demultiplexer device
|
||||||
*
|
*
|
||||||
* Copyright (C) 2000 Ralph Metzler & Marcus Metzler
|
* Copyright (C) 2000 Ralph Metzler & Marcus Metzler
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) "dmxdev: " fmt
|
#define pr_fmt(fmt) "dmxdev: " fmt
|
||||||
@ -415,6 +405,7 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
|
static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
|
||||||
const u8 *buffer2, size_t buffer2_len,
|
const u8 *buffer2, size_t buffer2_len,
|
||||||
struct dmx_section_filter *filter,
|
struct dmx_section_filter *filter,
|
||||||
@ -480,6 +471,9 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
|
|||||||
{
|
{
|
||||||
struct dmxdev_filter *dmxdevfilter = feed->priv;
|
struct dmxdev_filter *dmxdevfilter = feed->priv;
|
||||||
struct dvb_ringbuffer *buffer;
|
struct dvb_ringbuffer *buffer;
|
||||||
|
#ifdef CONFIG_DVB_MMAP
|
||||||
|
struct dvb_vb2_ctx *ctx;
|
||||||
|
#endif
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
spin_lock(&dmxdevfilter->dev->lock);
|
spin_lock(&dmxdevfilter->dev->lock);
|
||||||
@ -766,7 +760,7 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter)
|
|||||||
ret = dmxdev->demux->allocate_section_feed(dmxdev->demux,
|
ret = dmxdev->demux->allocate_section_feed(dmxdev->demux,
|
||||||
secfeed,
|
secfeed,
|
||||||
dvb_dmxdev_section_callback);
|
dvb_dmxdev_section_callback);
|
||||||
if (ret < 0) {
|
if (!*secfeed) {
|
||||||
pr_err("DVB (%s): could not alloc feed\n",
|
pr_err("DVB (%s): could not alloc feed\n",
|
||||||
__func__);
|
__func__);
|
||||||
return ret;
|
return ret;
|
||||||
@ -846,6 +840,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
|
|||||||
if (mutex_lock_interruptible(&dmxdev->mutex))
|
if (mutex_lock_interruptible(&dmxdev->mutex))
|
||||||
return -ERESTARTSYS;
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
|
if (dmxdev->exit) {
|
||||||
|
mutex_unlock(&dmxdev->mutex);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < dmxdev->filternum; i++)
|
for (i = 0; i < dmxdev->filternum; i++)
|
||||||
if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
|
if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
|
||||||
break;
|
break;
|
||||||
@ -1482,7 +1481,7 @@ static const struct dvb_device dvbdev_dvr = {
|
|||||||
|
|
||||||
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
|
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
|
||||||
{
|
{
|
||||||
int i;
|
int i, ret;
|
||||||
|
|
||||||
if (dmxdev->demux->open(dmxdev->demux) < 0)
|
if (dmxdev->demux->open(dmxdev->demux) < 0)
|
||||||
return -EUSERS;
|
return -EUSERS;
|
||||||
@ -1505,21 +1504,36 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
|
|||||||
DMXDEV_STATE_FREE);
|
DMXDEV_STATE_FREE);
|
||||||
}
|
}
|
||||||
|
|
||||||
dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
|
ret = dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev,
|
||||||
DVB_DEVICE_DEMUX, dmxdev->filternum);
|
DVB_DEVICE_DEMUX, dmxdev->filternum);
|
||||||
dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
|
if (ret < 0)
|
||||||
|
goto err_register_dvbdev;
|
||||||
|
|
||||||
|
ret = dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr,
|
||||||
dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
|
dmxdev, DVB_DEVICE_DVR, dmxdev->filternum);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err_register_dvr_dvbdev;
|
||||||
|
|
||||||
dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
|
dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_register_dvr_dvbdev:
|
||||||
|
dvb_unregister_device(dmxdev->dvbdev);
|
||||||
|
err_register_dvbdev:
|
||||||
|
vfree(dmxdev->filter);
|
||||||
|
dmxdev->filter = NULL;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL(dvb_dmxdev_init);
|
EXPORT_SYMBOL(dvb_dmxdev_init);
|
||||||
|
|
||||||
void dvb_dmxdev_release(struct dmxdev *dmxdev)
|
void dvb_dmxdev_release(struct dmxdev *dmxdev)
|
||||||
{
|
{
|
||||||
|
mutex_lock(&dmxdev->mutex);
|
||||||
dmxdev->exit = 1;
|
dmxdev->exit = 1;
|
||||||
|
mutex_unlock(&dmxdev->mutex);
|
||||||
|
|
||||||
if (dmxdev->dvbdev->users > 1) {
|
if (dmxdev->dvbdev->users > 1) {
|
||||||
wait_event(dmxdev->dvbdev->wait_queue,
|
wait_event(dmxdev->dvbdev->wait_queue,
|
||||||
dmxdev->dvbdev->users == 1);
|
dmxdev->dvbdev->users == 1);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* dvb_ca.c: generic DVB functions for EN50221 CAM interfaces
|
* dvb_ca.c: generic DVB functions for EN50221 CAM interfaces
|
||||||
*
|
*
|
||||||
@ -158,13 +158,19 @@ struct dvb_ca_private {
|
|||||||
|
|
||||||
/* mutex serializing ioctls */
|
/* mutex serializing ioctls */
|
||||||
struct mutex ioctl_mutex;
|
struct mutex ioctl_mutex;
|
||||||
|
|
||||||
|
/* A mutex used when a device is disconnected */
|
||||||
|
struct mutex remove_mutex;
|
||||||
|
|
||||||
|
/* Whether the device is disconnected */
|
||||||
|
int exit;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dvb_ca_private_free(struct dvb_ca_private *ca)
|
static void dvb_ca_private_free(struct dvb_ca_private *ca)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
dvb_free_device(ca->dvbdev);
|
dvb_device_put(ca->dvbdev);
|
||||||
for (i = 0; i < ca->slot_count; i++)
|
for (i = 0; i < ca->slot_count; i++)
|
||||||
vfree(ca->slot_info[i].rx_buffer.data);
|
vfree(ca->slot_info[i].rx_buffer.data);
|
||||||
|
|
||||||
@ -194,10 +200,10 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca);
|
|||||||
static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
|
static int dvb_ca_en50221_read_data(struct dvb_ca_private *ca, int slot,
|
||||||
u8 *ebuf, int ecount);
|
u8 *ebuf, int ecount);
|
||||||
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
|
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
|
||||||
u8 *ebuf, int ecount);
|
u8 *ebuf, int ecount, int size_write_flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely find needle in haystack.
|
* findstr - Safely find needle in haystack.
|
||||||
*
|
*
|
||||||
* @haystack: Buffer to look in.
|
* @haystack: Buffer to look in.
|
||||||
* @hlen: Number of bytes in haystack.
|
* @hlen: Number of bytes in haystack.
|
||||||
@ -377,7 +383,7 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot)
|
|||||||
ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10);
|
ret = dvb_ca_en50221_wait_if_status(ca, slot, STATUSREG_FR, HZ / 10);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
ret = dvb_ca_en50221_write_data(ca, slot, buf, 2);
|
ret = dvb_ca_en50221_write_data(ca, slot, buf, 2, CMDREG_SW);
|
||||||
if (ret != 2)
|
if (ret != 2)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
|
ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
|
||||||
@ -785,18 +791,19 @@ exit:
|
|||||||
* @buf: The data in this buffer is treated as a complete link-level packet to
|
* @buf: The data in this buffer is treated as a complete link-level packet to
|
||||||
* be written.
|
* be written.
|
||||||
* @bytes_write: Size of ebuf.
|
* @bytes_write: Size of ebuf.
|
||||||
|
* @size_write_flag: A flag on Command Register which says whether the link size
|
||||||
|
* information will be writen or not.
|
||||||
*
|
*
|
||||||
* return: Number of bytes written, or < 0 on error.
|
* return: Number of bytes written, or < 0 on error.
|
||||||
*/
|
*/
|
||||||
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
|
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
|
||||||
u8 *buf, int bytes_write)
|
u8 *buf, int bytes_write, int size_write_flag)
|
||||||
{
|
{
|
||||||
struct dvb_ca_slot *sl = &ca->slot_info[slot];
|
struct dvb_ca_slot *sl = &ca->slot_info[slot];
|
||||||
int status;
|
int status;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dprintk("%s\n", __func__);
|
dprintk("%s\n", __func__);
|
||||||
|
|
||||||
/* sanity check */
|
/* sanity check */
|
||||||
if (bytes_write > sl->link_buf_size)
|
if (bytes_write > sl->link_buf_size)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -824,7 +831,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
|
|||||||
|
|
||||||
/* OK, set HC bit */
|
/* OK, set HC bit */
|
||||||
status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
|
status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
|
||||||
IRQEN | CMDREG_HC);
|
IRQEN | CMDREG_HC | size_write_flag);
|
||||||
if (status)
|
if (status)
|
||||||
goto exit;
|
goto exit;
|
||||||
|
|
||||||
@ -1013,7 +1020,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
|
|||||||
/* EN50221 thread functions */
|
/* EN50221 thread functions */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wake up the DVB CA thread
|
* dvb_ca_en50221_thread_wakeup - Wake up the DVB CA thread
|
||||||
*
|
*
|
||||||
* @ca: CA instance.
|
* @ca: CA instance.
|
||||||
*/
|
*/
|
||||||
@ -1027,7 +1034,7 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the delay used by the thread.
|
* dvb_ca_en50221_thread_update_delay - Update the delay used by the thread.
|
||||||
*
|
*
|
||||||
* @ca: CA instance.
|
* @ca: CA instance.
|
||||||
*/
|
*/
|
||||||
@ -1085,7 +1092,7 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Poll if the CAM is gone.
|
* dvb_ca_en50221_poll_cam_gone - Poll if the CAM is gone.
|
||||||
*
|
*
|
||||||
* @ca: CA instance.
|
* @ca: CA instance.
|
||||||
* @slot: Slot to process.
|
* @slot: Slot to process.
|
||||||
@ -1116,7 +1123,8 @@ static int dvb_ca_en50221_poll_cam_gone(struct dvb_ca_private *ca, int slot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread state machine for one CA slot to perform the data transfer.
|
* dvb_ca_en50221_thread_state_machine - Thread state machine for one CA slot
|
||||||
|
* to perform the data transfer.
|
||||||
*
|
*
|
||||||
* @ca: CA instance.
|
* @ca: CA instance.
|
||||||
* @slot: Slot to process.
|
* @slot: Slot to process.
|
||||||
@ -1347,13 +1355,14 @@ static int dvb_ca_en50221_thread(void *data)
|
|||||||
/* EN50221 IO interface functions */
|
/* EN50221 IO interface functions */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Real ioctl implementation.
|
* dvb_ca_en50221_io_do_ioctl - Real ioctl implementation.
|
||||||
* NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
|
|
||||||
*
|
*
|
||||||
* @file: File concerned.
|
* @file: File concerned.
|
||||||
* @cmd: IOCTL command.
|
* @cmd: IOCTL command.
|
||||||
* @parg: Associated argument.
|
* @parg: Associated argument.
|
||||||
*
|
*
|
||||||
|
* NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
|
||||||
|
*
|
||||||
* return: 0 on success, <0 on error.
|
* return: 0 on success, <0 on error.
|
||||||
*/
|
*/
|
||||||
static int dvb_ca_en50221_io_do_ioctl(struct file *file,
|
static int dvb_ca_en50221_io_do_ioctl(struct file *file,
|
||||||
@ -1407,6 +1416,9 @@ static int dvb_ca_en50221_io_do_ioctl(struct file *file,
|
|||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
|
||||||
|
slot = array_index_nospec(slot, ca->slot_count);
|
||||||
|
#endif
|
||||||
|
|
||||||
info->type = CA_CI_LINK;
|
info->type = CA_CI_LINK;
|
||||||
info->flags = 0;
|
info->flags = 0;
|
||||||
@ -1431,7 +1443,7 @@ out_unlock:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper for ioctl implementation.
|
* dvb_ca_en50221_io_ioctl - Wrapper for ioctl implementation.
|
||||||
*
|
*
|
||||||
* @file: File concerned.
|
* @file: File concerned.
|
||||||
* @cmd: IOCTL command.
|
* @cmd: IOCTL command.
|
||||||
@ -1446,7 +1458,7 @@ static long dvb_ca_en50221_io_ioctl(struct file *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of write() syscall.
|
* dvb_ca_en50221_io_write - Implementation of write() syscall.
|
||||||
*
|
*
|
||||||
* @file: File structure.
|
* @file: File structure.
|
||||||
* @buf: Source buffer.
|
* @buf: Source buffer.
|
||||||
@ -1486,6 +1498,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
|
|||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
buf += 2;
|
buf += 2;
|
||||||
count -= 2;
|
count -= 2;
|
||||||
|
|
||||||
if (slot >= ca->slot_count)
|
if (slot >= ca->slot_count)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
|
||||||
@ -1529,7 +1542,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
|
|||||||
|
|
||||||
mutex_lock(&sl->slot_lock);
|
mutex_lock(&sl->slot_lock);
|
||||||
status = dvb_ca_en50221_write_data(ca, slot, fragbuf,
|
status = dvb_ca_en50221_write_data(ca, slot, fragbuf,
|
||||||
fraglen + 2);
|
fraglen + 2, 0);
|
||||||
mutex_unlock(&sl->slot_lock);
|
mutex_unlock(&sl->slot_lock);
|
||||||
if (status == (fraglen + 2)) {
|
if (status == (fraglen + 2)) {
|
||||||
written = 1;
|
written = 1;
|
||||||
@ -1603,7 +1616,7 @@ nextslot:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of read() syscall.
|
* dvb_ca_en50221_io_read - Implementation of read() syscall.
|
||||||
*
|
*
|
||||||
* @file: File structure.
|
* @file: File structure.
|
||||||
* @buf: Destination buffer.
|
* @buf: Destination buffer.
|
||||||
@ -1714,7 +1727,7 @@ exit:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of file open syscall.
|
* dvb_ca_en50221_io_open - Implementation of file open syscall.
|
||||||
*
|
*
|
||||||
* @inode: Inode concerned.
|
* @inode: Inode concerned.
|
||||||
* @file: File concerned.
|
* @file: File concerned.
|
||||||
@ -1730,12 +1743,22 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
|
|||||||
|
|
||||||
dprintk("%s\n", __func__);
|
dprintk("%s\n", __func__);
|
||||||
|
|
||||||
if (!try_module_get(ca->pub->owner))
|
mutex_lock(&ca->remove_mutex);
|
||||||
|
|
||||||
|
if (ca->exit) {
|
||||||
|
mutex_unlock(&ca->remove_mutex);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!try_module_get(ca->pub->owner)) {
|
||||||
|
mutex_unlock(&ca->remove_mutex);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
err = dvb_generic_open(inode, file);
|
err = dvb_generic_open(inode, file);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
module_put(ca->pub->owner);
|
module_put(ca->pub->owner);
|
||||||
|
mutex_unlock(&ca->remove_mutex);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1760,11 +1783,12 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
|
|||||||
|
|
||||||
dvb_ca_private_get(ca);
|
dvb_ca_private_get(ca);
|
||||||
|
|
||||||
|
mutex_unlock(&ca->remove_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of file close syscall.
|
* dvb_ca_en50221_io_release - Implementation of file close syscall.
|
||||||
*
|
*
|
||||||
* @inode: Inode concerned.
|
* @inode: Inode concerned.
|
||||||
* @file: File concerned.
|
* @file: File concerned.
|
||||||
@ -1779,6 +1803,8 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
|
|||||||
|
|
||||||
dprintk("%s\n", __func__);
|
dprintk("%s\n", __func__);
|
||||||
|
|
||||||
|
mutex_lock(&ca->remove_mutex);
|
||||||
|
|
||||||
/* mark the CA device as closed */
|
/* mark the CA device as closed */
|
||||||
ca->open = 0;
|
ca->open = 0;
|
||||||
dvb_ca_en50221_thread_update_delay(ca);
|
dvb_ca_en50221_thread_update_delay(ca);
|
||||||
@ -1789,11 +1815,18 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
|
|||||||
|
|
||||||
dvb_ca_private_put(ca);
|
dvb_ca_private_put(ca);
|
||||||
|
|
||||||
|
if (dvbdev->users == 1 && ca->exit == 1) {
|
||||||
|
mutex_unlock(&ca->remove_mutex);
|
||||||
|
wake_up(&dvbdev->wait_queue);
|
||||||
|
} else {
|
||||||
|
mutex_unlock(&ca->remove_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of poll() syscall.
|
* dvb_ca_en50221_io_poll - Implementation of poll() syscall.
|
||||||
*
|
*
|
||||||
* @file: File concerned.
|
* @file: File concerned.
|
||||||
* @wait: poll wait table.
|
* @wait: poll wait table.
|
||||||
@ -1855,7 +1888,7 @@ static const struct dvb_device dvbdev_ca = {
|
|||||||
/* Initialisation/shutdown functions */
|
/* Initialisation/shutdown functions */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise a new DVB CA EN50221 interface device.
|
* dvb_ca_en50221_init - Initialise a new DVB CA EN50221 interface device.
|
||||||
*
|
*
|
||||||
* @dvb_adapter: DVB adapter to attach the new CA device to.
|
* @dvb_adapter: DVB adapter to attach the new CA device to.
|
||||||
* @pubca: The dvb_ca instance.
|
* @pubca: The dvb_ca instance.
|
||||||
@ -1916,6 +1949,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mutex_init(&ca->ioctl_mutex);
|
mutex_init(&ca->ioctl_mutex);
|
||||||
|
mutex_init(&ca->remove_mutex);
|
||||||
|
|
||||||
if (signal_pending(current)) {
|
if (signal_pending(current)) {
|
||||||
ret = -EINTR;
|
ret = -EINTR;
|
||||||
@ -1947,7 +1981,7 @@ exit:
|
|||||||
EXPORT_SYMBOL(dvb_ca_en50221_init);
|
EXPORT_SYMBOL(dvb_ca_en50221_init);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release a DVB CA EN50221 interface device.
|
* dvb_ca_en50221_release - Release a DVB CA EN50221 interface device.
|
||||||
*
|
*
|
||||||
* @pubca: The associated dvb_ca instance.
|
* @pubca: The associated dvb_ca instance.
|
||||||
*/
|
*/
|
||||||
@ -1958,6 +1992,14 @@ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca)
|
|||||||
|
|
||||||
dprintk("%s\n", __func__);
|
dprintk("%s\n", __func__);
|
||||||
|
|
||||||
|
mutex_lock(&ca->remove_mutex);
|
||||||
|
ca->exit = 1;
|
||||||
|
mutex_unlock(&ca->remove_mutex);
|
||||||
|
|
||||||
|
if (ca->dvbdev->users < 1)
|
||||||
|
wait_event(ca->dvbdev->wait_queue,
|
||||||
|
ca->dvbdev->users == 1);
|
||||||
|
|
||||||
/* shutdown the thread if there was one */
|
/* shutdown the thread if there was one */
|
||||||
kthread_stop(ca->thread);
|
kthread_stop(ca->thread);
|
||||||
|
|
||||||
|
@ -1,20 +1,10 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
/*
|
/*
|
||||||
* dvb_demux.c - DVB kernel demux API
|
* dvb_demux.c - DVB kernel demux API
|
||||||
*
|
*
|
||||||
* Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de>
|
* Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de>
|
||||||
* & Marcus Metzler <marcus@convergence.de>
|
* & Marcus Metzler <marcus@convergence.de>
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) "dvb_demux: " fmt
|
#define pr_fmt(fmt) "dvb_demux: " fmt
|
||||||
@ -138,12 +128,12 @@ static inline int dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed,
|
|||||||
|
|
||||||
cc = buf[3] & 0x0f;
|
cc = buf[3] & 0x0f;
|
||||||
ccok = ((feed->cc + 1) & 0x0f) == cc;
|
ccok = ((feed->cc + 1) & 0x0f) == cc;
|
||||||
feed->cc = cc;
|
|
||||||
if (!ccok) {
|
if (!ccok) {
|
||||||
set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
|
set_buf_flags(feed, DMX_BUFFER_FLAG_DISCONTINUITY_DETECTED);
|
||||||
dprintk_sect_loss("missed packet: %d instead of %d!\n",
|
dprintk_sect_loss("missed packet: %d instead of %d!\n",
|
||||||
cc, (feed->cc + 1) & 0x0f);
|
cc, (feed->cc + 1) & 0x0f);
|
||||||
}
|
}
|
||||||
|
feed->cc = cc;
|
||||||
|
|
||||||
if (buf[1] & 0x40) // PUSI ?
|
if (buf[1] & 0x40) // PUSI ?
|
||||||
feed->peslen = 0xfffa;
|
feed->peslen = 0xfffa;
|
||||||
@ -256,7 +246,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
|
|||||||
{
|
{
|
||||||
struct dvb_demux *demux = feed->demux;
|
struct dvb_demux *demux = feed->demux;
|
||||||
struct dmx_section_feed *sec = &feed->feed.sec;
|
struct dmx_section_feed *sec = &feed->feed.sec;
|
||||||
u16 limit, seclen, n;
|
u16 limit, seclen;
|
||||||
|
|
||||||
if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
|
if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
|
||||||
return 0;
|
return 0;
|
||||||
@ -285,7 +275,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
|
|||||||
/* to be sure always set secbuf */
|
/* to be sure always set secbuf */
|
||||||
sec->secbuf = sec->secbuf_base + sec->secbufp;
|
sec->secbuf = sec->secbuf_base + sec->secbufp;
|
||||||
|
|
||||||
for (n = 0; sec->secbufp + 2 < limit; n++) {
|
while (sec->secbufp + 2 < limit) {
|
||||||
seclen = section_length(sec->secbuf);
|
seclen = section_length(sec->secbuf);
|
||||||
if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
|
if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
|
||||||
|| seclen + sec->secbufp > limit)
|
|| seclen + sec->secbufp > limit)
|
||||||
@ -323,7 +313,6 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
|
|||||||
|
|
||||||
cc = buf[3] & 0x0f;
|
cc = buf[3] & 0x0f;
|
||||||
ccok = ((feed->cc + 1) & 0x0f) == cc;
|
ccok = ((feed->cc + 1) & 0x0f) == cc;
|
||||||
feed->cc = cc;
|
|
||||||
|
|
||||||
if (buf[3] & 0x20) {
|
if (buf[3] & 0x20) {
|
||||||
/* adaption field present, check for discontinuity_indicator */
|
/* adaption field present, check for discontinuity_indicator */
|
||||||
@ -359,6 +348,7 @@ static int dvb_dmx_swfilter_section_packet(struct dvb_demux_feed *feed,
|
|||||||
feed->pusi_seen = false;
|
feed->pusi_seen = false;
|
||||||
dvb_dmx_swfilter_section_new(feed);
|
dvb_dmx_swfilter_section_new(feed);
|
||||||
}
|
}
|
||||||
|
feed->cc = cc;
|
||||||
|
|
||||||
if (buf[1] & 0x40) {
|
if (buf[1] & 0x40) {
|
||||||
/* PUSI=1 (is set), section boundary is here */
|
/* PUSI=1 (is set), section boundary is here */
|
||||||
|
@ -1,603 +0,0 @@
|
|||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/string.h>
|
|
||||||
#include "dvb_filter.h"
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static unsigned int bitrates[3][16] =
|
|
||||||
{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
|
|
||||||
{0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
|
|
||||||
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static u32 freq[4] = {480, 441, 320, 0};
|
|
||||||
|
|
||||||
static unsigned int ac3_bitrates[32] =
|
|
||||||
{32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
|
|
||||||
0,0,0,0,0,0,0,0,0,0,0,0,0};
|
|
||||||
|
|
||||||
static u32 ac3_frames[3][32] =
|
|
||||||
{{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
|
|
||||||
1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
|
|
||||||
1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
||||||
{96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
|
|
||||||
1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv,
|
|
||||||
void (*pes_write)(u8 *buf, int count, void *data),
|
|
||||||
void *priv)
|
|
||||||
{
|
|
||||||
dvb_filter_ipack_init(pa, IPACKS, pes_write);
|
|
||||||
dvb_filter_ipack_init(pv, IPACKS, pes_write);
|
|
||||||
pa->pid = pida;
|
|
||||||
pv->pid = pidv;
|
|
||||||
pa->data = priv;
|
|
||||||
pv->data = priv;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188)
|
|
||||||
{
|
|
||||||
u8 off = 0;
|
|
||||||
|
|
||||||
if (!buf || !p ){
|
|
||||||
printk("NULL POINTER IDIOT\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (buf[1]&PAY_START) {
|
|
||||||
if (p->plength == MMAX_PLENGTH-6 && p->found>6){
|
|
||||||
p->plength = p->found-6;
|
|
||||||
p->found = 0;
|
|
||||||
send_ipack(p);
|
|
||||||
dvb_filter_ipack_reset(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (buf[3] & ADAPT_FIELD) { // adaptation field?
|
|
||||||
off = buf[4] + 1;
|
|
||||||
if (off+4 > 187) return;
|
|
||||||
}
|
|
||||||
dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* needs 5 byte input, returns picture coding type*/
|
|
||||||
static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr)
|
|
||||||
{
|
|
||||||
u8 pct;
|
|
||||||
|
|
||||||
if (pr) printk( "Pic header: ");
|
|
||||||
pic->temporal_reference[field] = (( headr[0] << 2 ) |
|
|
||||||
(headr[1] & 0x03) )& 0x03ff;
|
|
||||||
if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]);
|
|
||||||
|
|
||||||
pct = ( headr[1] >> 2 ) & 0x07;
|
|
||||||
pic->picture_coding_type[field] = pct;
|
|
||||||
if (pr) {
|
|
||||||
switch(pct){
|
|
||||||
case I_FRAME:
|
|
||||||
printk( " I-FRAME");
|
|
||||||
break;
|
|
||||||
case B_FRAME:
|
|
||||||
printk( " B-FRAME");
|
|
||||||
break;
|
|
||||||
case P_FRAME:
|
|
||||||
printk( " P-FRAME");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) |
|
|
||||||
( (headr[3] & 0x1F) << 11) ) & 0xffff;
|
|
||||||
|
|
||||||
if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay);
|
|
||||||
|
|
||||||
pic->picture_header_parameter = ( headr[3] & 0xe0 ) |
|
|
||||||
((headr[4] & 0x80) >> 3);
|
|
||||||
|
|
||||||
if ( pct == B_FRAME ){
|
|
||||||
pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f;
|
|
||||||
}
|
|
||||||
if (pr) printk( " pic head param: 0x%x",
|
|
||||||
pic->picture_header_parameter);
|
|
||||||
|
|
||||||
return pct;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* needs 4 byte input */
|
|
||||||
static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr)
|
|
||||||
{
|
|
||||||
if (pr) printk("GOP header: ");
|
|
||||||
|
|
||||||
pic->time_code = (( headr[0] << 17 ) | ( headr[1] << 9) |
|
|
||||||
( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff;
|
|
||||||
|
|
||||||
if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F,
|
|
||||||
((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F),
|
|
||||||
((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F));
|
|
||||||
|
|
||||||
if ( ( headr[3] & 0x40 ) != 0 ){
|
|
||||||
pic->closed_gop = 1;
|
|
||||||
} else {
|
|
||||||
pic->closed_gop = 0;
|
|
||||||
}
|
|
||||||
if (pr) printk("closed: %d", pic->closed_gop);
|
|
||||||
|
|
||||||
if ( ( headr[3] & 0x20 ) != 0 ){
|
|
||||||
pic->broken_link = 1;
|
|
||||||
} else {
|
|
||||||
pic->broken_link = 0;
|
|
||||||
}
|
|
||||||
if (pr) printk(" broken: %d\n", pic->broken_link);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* needs 8 byte input */
|
|
||||||
static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr)
|
|
||||||
{
|
|
||||||
int sw;
|
|
||||||
int form = -1;
|
|
||||||
|
|
||||||
if (pr) printk("Reading sequence header\n");
|
|
||||||
|
|
||||||
vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
|
|
||||||
vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]);
|
|
||||||
|
|
||||||
sw = (int)((headr[3]&0xF0) >> 4) ;
|
|
||||||
|
|
||||||
switch( sw ){
|
|
||||||
case 1:
|
|
||||||
if (pr)
|
|
||||||
printk("Videostream: ASPECT: 1:1");
|
|
||||||
vi->aspect_ratio = 100;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (pr)
|
|
||||||
printk("Videostream: ASPECT: 4:3");
|
|
||||||
vi->aspect_ratio = 133;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (pr)
|
|
||||||
printk("Videostream: ASPECT: 16:9");
|
|
||||||
vi->aspect_ratio = 177;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if (pr)
|
|
||||||
printk("Videostream: ASPECT: 2.21:1");
|
|
||||||
vi->aspect_ratio = 221;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5 ... 15:
|
|
||||||
if (pr)
|
|
||||||
printk("Videostream: ASPECT: reserved");
|
|
||||||
vi->aspect_ratio = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
vi->aspect_ratio = 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pr)
|
|
||||||
printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size);
|
|
||||||
|
|
||||||
sw = (int)(headr[3]&0x0F);
|
|
||||||
|
|
||||||
switch ( sw ) {
|
|
||||||
case 1:
|
|
||||||
if (pr)
|
|
||||||
printk(" FRate: 23.976 fps");
|
|
||||||
vi->framerate = 23976;
|
|
||||||
form = -1;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (pr)
|
|
||||||
printk(" FRate: 24 fps");
|
|
||||||
vi->framerate = 24000;
|
|
||||||
form = -1;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (pr)
|
|
||||||
printk(" FRate: 25 fps");
|
|
||||||
vi->framerate = 25000;
|
|
||||||
form = VIDEO_MODE_PAL;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
if (pr)
|
|
||||||
printk(" FRate: 29.97 fps");
|
|
||||||
vi->framerate = 29970;
|
|
||||||
form = VIDEO_MODE_NTSC;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
if (pr)
|
|
||||||
printk(" FRate: 30 fps");
|
|
||||||
vi->framerate = 30000;
|
|
||||||
form = VIDEO_MODE_NTSC;
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
if (pr)
|
|
||||||
printk(" FRate: 50 fps");
|
|
||||||
vi->framerate = 50000;
|
|
||||||
form = VIDEO_MODE_PAL;
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
if (pr)
|
|
||||||
printk(" FRate: 60 fps");
|
|
||||||
vi->framerate = 60000;
|
|
||||||
form = VIDEO_MODE_NTSC;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03);
|
|
||||||
|
|
||||||
vi->vbv_buffer_size
|
|
||||||
= (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5);
|
|
||||||
|
|
||||||
if (pr){
|
|
||||||
printk(" BRate: %d Mbit/s",4*(vi->bit_rate)/10000);
|
|
||||||
printk(" vbvbuffer %d",16*1024*(vi->vbv_buffer_size));
|
|
||||||
printk("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
vi->video_format = form;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr)
|
|
||||||
{
|
|
||||||
u8 *headr;
|
|
||||||
int found = 0;
|
|
||||||
int c = 0;
|
|
||||||
|
|
||||||
while (found < 4 && c+4 < count){
|
|
||||||
u8 *b;
|
|
||||||
|
|
||||||
b = mbuf+c;
|
|
||||||
if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
|
|
||||||
&& b[3] == 0xb3) found = 4;
|
|
||||||
else {
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! found) return -1;
|
|
||||||
c += 4;
|
|
||||||
if (c+12 >= count) return -1;
|
|
||||||
headr = mbuf+c;
|
|
||||||
if (read_sequence_header(headr, vi, pr) < 0) return -1;
|
|
||||||
vi->off = c-4;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
|
|
||||||
{
|
|
||||||
u8 *headr;
|
|
||||||
int found = 0;
|
|
||||||
int c = 0;
|
|
||||||
int fr = 0;
|
|
||||||
|
|
||||||
while (found < 2 && c < count){
|
|
||||||
u8 b[2];
|
|
||||||
memcpy( b, mbuf+c, 2);
|
|
||||||
|
|
||||||
if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
|
|
||||||
found = 2;
|
|
||||||
else {
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) return -1;
|
|
||||||
|
|
||||||
if (c+3 >= count) return -1;
|
|
||||||
headr = mbuf+c;
|
|
||||||
|
|
||||||
ai->layer = (headr[1] & 0x06) >> 1;
|
|
||||||
|
|
||||||
if (pr)
|
|
||||||
printk("Audiostream: Layer: %d", 4-ai->layer);
|
|
||||||
|
|
||||||
|
|
||||||
ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;
|
|
||||||
|
|
||||||
if (pr){
|
|
||||||
if (ai->bit_rate == 0)
|
|
||||||
printk(" Bit rate: free");
|
|
||||||
else if (ai->bit_rate == 0xf)
|
|
||||||
printk(" BRate: reserved");
|
|
||||||
else
|
|
||||||
printk(" BRate: %d kb/s", ai->bit_rate/1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
fr = (headr[2] & 0x0c ) >> 2;
|
|
||||||
ai->frequency = freq[fr]*100;
|
|
||||||
if (pr){
|
|
||||||
if (ai->frequency == 3)
|
|
||||||
printk(" Freq: reserved\n");
|
|
||||||
else
|
|
||||||
printk(" Freq: %d kHz\n",ai->frequency);
|
|
||||||
|
|
||||||
}
|
|
||||||
ai->off = c;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
|
|
||||||
{
|
|
||||||
u8 *headr;
|
|
||||||
int found = 0;
|
|
||||||
int c = 0;
|
|
||||||
u8 frame = 0;
|
|
||||||
int fr = 0;
|
|
||||||
|
|
||||||
while ( !found && c < count){
|
|
||||||
u8 *b = mbuf+c;
|
|
||||||
|
|
||||||
if ( b[0] == 0x0b && b[1] == 0x77 )
|
|
||||||
found = 1;
|
|
||||||
else {
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found) return -1;
|
|
||||||
if (pr)
|
|
||||||
printk("Audiostream: AC3");
|
|
||||||
|
|
||||||
ai->off = c;
|
|
||||||
if (c+5 >= count) return -1;
|
|
||||||
|
|
||||||
ai->layer = 0; // 0 for AC3
|
|
||||||
headr = mbuf+c+2;
|
|
||||||
|
|
||||||
frame = (headr[2]&0x3f);
|
|
||||||
ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
|
|
||||||
|
|
||||||
if (pr)
|
|
||||||
printk(" BRate: %d kb/s", (int) ai->bit_rate/1000);
|
|
||||||
|
|
||||||
ai->frequency = (headr[2] & 0xc0 ) >> 6;
|
|
||||||
fr = (headr[2] & 0xc0 ) >> 6;
|
|
||||||
ai->frequency = freq[fr]*100;
|
|
||||||
if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency);
|
|
||||||
|
|
||||||
|
|
||||||
ai->framesize = ac3_frames[fr][frame >> 1];
|
|
||||||
if ((frame & 1) && (fr == 1)) ai->framesize++;
|
|
||||||
ai->framesize = ai->framesize << 1;
|
|
||||||
if (pr) printk (" Framesize %d\n",(int) ai->framesize);
|
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dvb_filter_get_ac3info);
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static u8 *skip_pes_header(u8 **bufp)
|
|
||||||
{
|
|
||||||
u8 *inbuf = *bufp;
|
|
||||||
u8 *buf = inbuf;
|
|
||||||
u8 *pts = NULL;
|
|
||||||
int skip = 0;
|
|
||||||
|
|
||||||
static const int mpeg1_skip_table[16] = {
|
|
||||||
1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff,
|
|
||||||
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
|
|
||||||
if (buf[7] & PTS_ONLY)
|
|
||||||
pts = buf+9;
|
|
||||||
else pts = NULL;
|
|
||||||
buf = inbuf + 9 + inbuf[8];
|
|
||||||
} else { /* mpeg1 */
|
|
||||||
for (buf = inbuf + 6; *buf == 0xff; buf++)
|
|
||||||
if (buf == inbuf + 6 + 16) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((*buf & 0xc0) == 0x40)
|
|
||||||
buf += 2;
|
|
||||||
skip = mpeg1_skip_table [*buf >> 4];
|
|
||||||
if (skip == 5 || skip == 10) pts = buf;
|
|
||||||
else pts = NULL;
|
|
||||||
|
|
||||||
buf += mpeg1_skip_table [*buf >> 4];
|
|
||||||
}
|
|
||||||
|
|
||||||
*bufp = buf;
|
|
||||||
return pts;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void initialize_quant_matrix( u32 *matrix )
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
matrix[0] = 0x08101013;
|
|
||||||
matrix[1] = 0x10131616;
|
|
||||||
matrix[2] = 0x16161616;
|
|
||||||
matrix[3] = 0x1a181a1b;
|
|
||||||
matrix[4] = 0x1b1b1a1a;
|
|
||||||
matrix[5] = 0x1a1a1b1b;
|
|
||||||
matrix[6] = 0x1b1d1d1d;
|
|
||||||
matrix[7] = 0x2222221d;
|
|
||||||
matrix[8] = 0x1d1d1b1b;
|
|
||||||
matrix[9] = 0x1d1d2020;
|
|
||||||
matrix[10] = 0x22222526;
|
|
||||||
matrix[11] = 0x25232322;
|
|
||||||
matrix[12] = 0x23262628;
|
|
||||||
matrix[13] = 0x28283030;
|
|
||||||
matrix[14] = 0x2e2e3838;
|
|
||||||
matrix[15] = 0x3a454553;
|
|
||||||
|
|
||||||
for ( i = 16 ; i < 32 ; i++ )
|
|
||||||
matrix[i] = 0x10101010;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void initialize_mpg_picture(struct mpg_picture *pic)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* set MPEG1 */
|
|
||||||
pic->mpeg1_flag = 1;
|
|
||||||
pic->profile_and_level = 0x4A ; /* MP@LL */
|
|
||||||
pic->progressive_sequence = 1;
|
|
||||||
pic->low_delay = 0;
|
|
||||||
|
|
||||||
pic->sequence_display_extension_flag = 0;
|
|
||||||
for ( i = 0 ; i < 4 ; i++ ){
|
|
||||||
pic->frame_centre_horizontal_offset[i] = 0;
|
|
||||||
pic->frame_centre_vertical_offset[i] = 0;
|
|
||||||
}
|
|
||||||
pic->last_frame_centre_horizontal_offset = 0;
|
|
||||||
pic->last_frame_centre_vertical_offset = 0;
|
|
||||||
|
|
||||||
pic->picture_display_extension_flag[0] = 0;
|
|
||||||
pic->picture_display_extension_flag[1] = 0;
|
|
||||||
pic->sequence_header_flag = 0;
|
|
||||||
pic->gop_flag = 0;
|
|
||||||
pic->sequence_end_flag = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic )
|
|
||||||
{
|
|
||||||
int16_t last_h_offset;
|
|
||||||
int16_t last_v_offset;
|
|
||||||
|
|
||||||
int16_t *p_h_offset;
|
|
||||||
int16_t *p_v_offset;
|
|
||||||
|
|
||||||
if ( pic->mpeg1_flag ){
|
|
||||||
pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE;
|
|
||||||
pic->top_field_first = 0;
|
|
||||||
pic->repeat_first_field = 0;
|
|
||||||
pic->progressive_frame = 1;
|
|
||||||
pic->picture_coding_parameter = 0x000010;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset flag */
|
|
||||||
pic->picture_display_extension_flag[field_type] = 0;
|
|
||||||
|
|
||||||
last_h_offset = pic->last_frame_centre_horizontal_offset;
|
|
||||||
last_v_offset = pic->last_frame_centre_vertical_offset;
|
|
||||||
if ( field_type == FIRST_FIELD ){
|
|
||||||
p_h_offset = pic->frame_centre_horizontal_offset;
|
|
||||||
p_v_offset = pic->frame_centre_vertical_offset;
|
|
||||||
*p_h_offset = last_h_offset;
|
|
||||||
*(p_h_offset + 1) = last_h_offset;
|
|
||||||
*(p_h_offset + 2) = last_h_offset;
|
|
||||||
*p_v_offset = last_v_offset;
|
|
||||||
*(p_v_offset + 1) = last_v_offset;
|
|
||||||
*(p_v_offset + 2) = last_v_offset;
|
|
||||||
} else {
|
|
||||||
pic->frame_centre_horizontal_offset[3] = last_h_offset;
|
|
||||||
pic->frame_centre_vertical_offset[3] = last_v_offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type)
|
|
||||||
{
|
|
||||||
pic->picture_header = 0;
|
|
||||||
pic->sequence_header_data
|
|
||||||
= ( INIT_HORIZONTAL_SIZE << 20 )
|
|
||||||
| ( INIT_VERTICAL_SIZE << 8 )
|
|
||||||
| ( INIT_ASPECT_RATIO << 4 )
|
|
||||||
| ( INIT_FRAME_RATE );
|
|
||||||
pic->mpeg1_flag = 0;
|
|
||||||
pic->vinfo.horizontal_size
|
|
||||||
= INIT_DISP_HORIZONTAL_SIZE;
|
|
||||||
pic->vinfo.vertical_size
|
|
||||||
= INIT_DISP_VERTICAL_SIZE;
|
|
||||||
pic->picture_display_extension_flag[field_type]
|
|
||||||
= 0;
|
|
||||||
pic->pts_flag[field_type] = 0;
|
|
||||||
|
|
||||||
pic->sequence_gop_header = 0;
|
|
||||||
pic->picture_header = 0;
|
|
||||||
pic->sequence_header_flag = 0;
|
|
||||||
pic->gop_flag = 0;
|
|
||||||
pic->sequence_end_flag = 0;
|
|
||||||
pic->sequence_display_extension_flag = 0;
|
|
||||||
pic->last_frame_centre_horizontal_offset = 0;
|
|
||||||
pic->last_frame_centre_vertical_offset = 0;
|
|
||||||
pic->channel = chan;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
|
|
||||||
dvb_filter_pes2ts_cb_t *cb, void *priv)
|
|
||||||
{
|
|
||||||
unsigned char *buf=p2ts->buf;
|
|
||||||
|
|
||||||
buf[0]=0x47;
|
|
||||||
buf[1]=(pid>>8);
|
|
||||||
buf[2]=pid&0xff;
|
|
||||||
p2ts->cc=0;
|
|
||||||
p2ts->cb=cb;
|
|
||||||
p2ts->priv=priv;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dvb_filter_pes2ts_init);
|
|
||||||
|
|
||||||
int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
|
|
||||||
int len, int payload_start)
|
|
||||||
{
|
|
||||||
unsigned char *buf=p2ts->buf;
|
|
||||||
int ret=0, rest;
|
|
||||||
|
|
||||||
//len=6+((pes[4]<<8)|pes[5]);
|
|
||||||
|
|
||||||
if (payload_start)
|
|
||||||
buf[1]|=0x40;
|
|
||||||
else
|
|
||||||
buf[1]&=~0x40;
|
|
||||||
while (len>=184) {
|
|
||||||
buf[3]=0x10|((p2ts->cc++)&0x0f);
|
|
||||||
memcpy(buf+4, pes, 184);
|
|
||||||
if ((ret=p2ts->cb(p2ts->priv, buf)))
|
|
||||||
return ret;
|
|
||||||
len-=184; pes+=184;
|
|
||||||
buf[1]&=~0x40;
|
|
||||||
}
|
|
||||||
if (!len)
|
|
||||||
return 0;
|
|
||||||
buf[3]=0x30|((p2ts->cc++)&0x0f);
|
|
||||||
rest=183-len;
|
|
||||||
if (rest) {
|
|
||||||
buf[5]=0x00;
|
|
||||||
if (rest-1)
|
|
||||||
memset(buf+6, 0xff, rest-1);
|
|
||||||
}
|
|
||||||
buf[4]=rest;
|
|
||||||
memcpy(buf+5+rest, pes, len);
|
|
||||||
return p2ts->cb(p2ts->priv, buf);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(dvb_filter_pes2ts);
|
|
@ -20,6 +20,7 @@
|
|||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
|
||||||
#include <linux/sched/signal.h>
|
#include <linux/sched/signal.h>
|
||||||
|
#include <linux/nospec.h>
|
||||||
#else
|
#else
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#endif
|
#endif
|
||||||
@ -140,7 +141,7 @@ static void __dvb_frontend_free(struct dvb_frontend *fe)
|
|||||||
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||||
|
|
||||||
if (fepriv)
|
if (fepriv)
|
||||||
dvb_free_device(fepriv->dvbdev);
|
dvb_device_put(fepriv->dvbdev);
|
||||||
|
|
||||||
dvb_frontend_invoke_release(fe, fe->ops.release);
|
dvb_frontend_invoke_release(fe, fe->ops.release);
|
||||||
|
|
||||||
@ -298,14 +299,28 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (events->eventw == events->eventr) {
|
if (events->eventw == events->eventr) {
|
||||||
int ret;
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
|
||||||
|
struct wait_queue_entry wait;
|
||||||
|
#endif
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (flags & O_NONBLOCK)
|
if (flags & O_NONBLOCK)
|
||||||
return -EWOULDBLOCK;
|
return -EWOULDBLOCK;
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
|
||||||
ret = wait_event_interruptible(events->wait_queue,
|
ret = wait_event_interruptible(events->wait_queue,
|
||||||
dvb_frontend_test_event(fepriv, events));
|
dvb_frontend_test_event(fepriv, events));
|
||||||
|
#else
|
||||||
|
init_waitqueue_entry(&wait, current);
|
||||||
|
add_wait_queue(&events->wait_queue, &wait);
|
||||||
|
while (!dvb_frontend_test_event(fepriv, events)) {
|
||||||
|
wait_woken(&wait, TASK_INTERRUPTIBLE, 0);
|
||||||
|
if (signal_pending(current)) {
|
||||||
|
ret = -ERESTARTSYS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove_wait_queue(&events->wait_queue, &wait);
|
||||||
|
#endif
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -487,6 +502,11 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
|
|||||||
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp;
|
struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp;
|
||||||
|
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
|
||||||
|
if (fepriv->max_drift)
|
||||||
|
dev_warn_once(fe->dvb->device,
|
||||||
|
"Frontend requested software zigzag, but didn't set the frequency step size\n");
|
||||||
|
#endif
|
||||||
/* if we've got no parameters, just keep idling */
|
/* if we've got no parameters, just keep idling */
|
||||||
if (fepriv->state & FESTATE_IDLE) {
|
if (fepriv->state & FESTATE_IDLE) {
|
||||||
fepriv->delay = 3 * HZ;
|
fepriv->delay = 3 * HZ;
|
||||||
@ -919,6 +939,7 @@ static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe,
|
|||||||
|
|
||||||
/* If the standard is for satellite, convert frequencies to kHz */
|
/* If the standard is for satellite, convert frequencies to kHz */
|
||||||
switch (c->delivery_system) {
|
switch (c->delivery_system) {
|
||||||
|
case SYS_DSS:
|
||||||
case SYS_DVBS:
|
case SYS_DVBS:
|
||||||
case SYS_DVBS2:
|
case SYS_DVBS2:
|
||||||
case SYS_TURBO:
|
case SYS_TURBO:
|
||||||
@ -944,6 +965,7 @@ static u32 dvb_frontend_get_stepsize(struct dvb_frontend *fe)
|
|||||||
u32 step = max(fe_step, tuner_step);
|
u32 step = max(fe_step, tuner_step);
|
||||||
|
|
||||||
switch (c->delivery_system) {
|
switch (c->delivery_system) {
|
||||||
|
case SYS_DSS:
|
||||||
case SYS_DVBS:
|
case SYS_DVBS:
|
||||||
case SYS_DVBS2:
|
case SYS_DVBS2:
|
||||||
case SYS_TURBO:
|
case SYS_TURBO:
|
||||||
@ -975,6 +997,7 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
|
|||||||
|
|
||||||
/* range check: symbol rate */
|
/* range check: symbol rate */
|
||||||
switch (c->delivery_system) {
|
switch (c->delivery_system) {
|
||||||
|
case SYS_DSS:
|
||||||
case SYS_DVBS:
|
case SYS_DVBS:
|
||||||
case SYS_DVBS2:
|
case SYS_DVBS2:
|
||||||
case SYS_TURBO:
|
case SYS_TURBO:
|
||||||
@ -990,6 +1013,7 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
|
|||||||
fe->ops.info.symbol_rate_max);
|
fe->ops.info.symbol_rate_max);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1041,6 +1065,10 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
|
|||||||
c->input = NO_INPUT;
|
c->input = NO_INPUT;
|
||||||
|
|
||||||
switch (c->delivery_system) {
|
switch (c->delivery_system) {
|
||||||
|
case SYS_DSS:
|
||||||
|
c->modulation = QPSK;
|
||||||
|
c->rolloff = ROLLOFF_20;
|
||||||
|
break;
|
||||||
case SYS_DVBS:
|
case SYS_DVBS:
|
||||||
case SYS_DVBS2:
|
case SYS_DVBS2:
|
||||||
case SYS_TURBO:
|
case SYS_TURBO:
|
||||||
@ -1065,108 +1093,100 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define _DTV_CMD(n, s, b) \
|
#define _DTV_CMD(n) \
|
||||||
[n] = { \
|
[n] = #n
|
||||||
.name = #n, \
|
|
||||||
.cmd = n, \
|
|
||||||
.set = s,\
|
|
||||||
.buffer = b \
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dtv_cmds_h {
|
static char *dtv_cmds[DTV_MAX_COMMAND + 1] = {
|
||||||
char *name; /* A display name for debugging purposes */
|
_DTV_CMD(DTV_TUNE),
|
||||||
|
_DTV_CMD(DTV_CLEAR),
|
||||||
__u32 cmd; /* A unique ID */
|
|
||||||
|
|
||||||
/* Flags */
|
|
||||||
__u32 set:1; /* Either a set or get property */
|
|
||||||
__u32 buffer:1; /* Does this property use the buffer? */
|
|
||||||
__u32 reserved:30; /* Align */
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = {
|
|
||||||
_DTV_CMD(DTV_TUNE, 1, 0),
|
|
||||||
_DTV_CMD(DTV_CLEAR, 1, 0),
|
|
||||||
|
|
||||||
/* Set */
|
/* Set */
|
||||||
_DTV_CMD(DTV_FREQUENCY, 1, 0),
|
_DTV_CMD(DTV_FREQUENCY),
|
||||||
_DTV_CMD(DTV_BANDWIDTH_HZ, 1, 0),
|
_DTV_CMD(DTV_BANDWIDTH_HZ),
|
||||||
_DTV_CMD(DTV_MODULATION, 1, 0),
|
_DTV_CMD(DTV_MODULATION),
|
||||||
_DTV_CMD(DTV_INVERSION, 1, 0),
|
_DTV_CMD(DTV_INVERSION),
|
||||||
_DTV_CMD(DTV_DISEQC_MASTER, 1, 1),
|
_DTV_CMD(DTV_DISEQC_MASTER),
|
||||||
_DTV_CMD(DTV_SYMBOL_RATE, 1, 0),
|
_DTV_CMD(DTV_SYMBOL_RATE),
|
||||||
_DTV_CMD(DTV_INNER_FEC, 1, 0),
|
_DTV_CMD(DTV_INNER_FEC),
|
||||||
_DTV_CMD(DTV_VOLTAGE, 1, 0),
|
_DTV_CMD(DTV_VOLTAGE),
|
||||||
_DTV_CMD(DTV_TONE, 1, 0),
|
_DTV_CMD(DTV_TONE),
|
||||||
_DTV_CMD(DTV_PILOT, 1, 0),
|
_DTV_CMD(DTV_PILOT),
|
||||||
_DTV_CMD(DTV_ROLLOFF, 1, 0),
|
_DTV_CMD(DTV_ROLLOFF),
|
||||||
_DTV_CMD(DTV_DELIVERY_SYSTEM, 1, 0),
|
_DTV_CMD(DTV_DELIVERY_SYSTEM),
|
||||||
_DTV_CMD(DTV_HIERARCHY, 1, 0),
|
_DTV_CMD(DTV_HIERARCHY),
|
||||||
_DTV_CMD(DTV_CODE_RATE_HP, 1, 0),
|
_DTV_CMD(DTV_CODE_RATE_HP),
|
||||||
_DTV_CMD(DTV_CODE_RATE_LP, 1, 0),
|
_DTV_CMD(DTV_CODE_RATE_LP),
|
||||||
_DTV_CMD(DTV_GUARD_INTERVAL, 1, 0),
|
_DTV_CMD(DTV_GUARD_INTERVAL),
|
||||||
_DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0),
|
_DTV_CMD(DTV_TRANSMISSION_MODE),
|
||||||
_DTV_CMD(DTV_INTERLEAVING, 1, 0),
|
_DTV_CMD(DTV_INTERLEAVING),
|
||||||
|
|
||||||
_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
|
_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION),
|
||||||
_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
|
_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING),
|
||||||
_DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0),
|
_DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID),
|
||||||
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0),
|
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX),
|
||||||
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0),
|
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYER_ENABLED),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERA_FEC),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERA_MODULATION),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERB_FEC),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERB_MODULATION),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERC_FEC),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERC_MODULATION),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT),
|
||||||
_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),
|
_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING),
|
||||||
|
|
||||||
_DTV_CMD(DTV_STREAM_ID, 1, 0),
|
_DTV_CMD(DTV_STREAM_ID),
|
||||||
_DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0),
|
_DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY),
|
||||||
_DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, 1, 0),
|
_DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX),
|
||||||
_DTV_CMD(DTV_LNA, 1, 0),
|
_DTV_CMD(DTV_LNA),
|
||||||
_DTV_CMD(DTV_INPUT, 1, 0),
|
_DTV_CMD(DTV_INPUT),
|
||||||
|
|
||||||
/* Get */
|
/* Get */
|
||||||
_DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
|
_DTV_CMD(DTV_DISEQC_SLAVE_REPLY),
|
||||||
_DTV_CMD(DTV_API_VERSION, 0, 0),
|
_DTV_CMD(DTV_API_VERSION),
|
||||||
|
|
||||||
_DTV_CMD(DTV_ENUM_DELSYS, 0, 0),
|
_DTV_CMD(DTV_ENUM_DELSYS),
|
||||||
|
|
||||||
_DTV_CMD(DTV_ATSCMH_PARADE_ID, 1, 0),
|
_DTV_CMD(DTV_ATSCMH_PARADE_ID),
|
||||||
_DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE, 1, 0),
|
_DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE),
|
||||||
|
|
||||||
_DTV_CMD(DTV_ATSCMH_FIC_VER, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_FIC_VER),
|
||||||
_DTV_CMD(DTV_ATSCMH_NOG, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_NOG),
|
||||||
_DTV_CMD(DTV_ATSCMH_TNOG, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_TNOG),
|
||||||
_DTV_CMD(DTV_ATSCMH_SGN, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_SGN),
|
||||||
_DTV_CMD(DTV_ATSCMH_PRC, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_PRC),
|
||||||
_DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE),
|
||||||
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI),
|
||||||
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC),
|
||||||
_DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE),
|
||||||
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_A, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_A),
|
||||||
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B),
|
||||||
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C),
|
||||||
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D, 0, 0),
|
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D),
|
||||||
|
|
||||||
/* Statistics API */
|
/* Statistics API */
|
||||||
_DTV_CMD(DTV_STAT_SIGNAL_STRENGTH, 0, 0),
|
_DTV_CMD(DTV_STAT_SIGNAL_STRENGTH),
|
||||||
_DTV_CMD(DTV_STAT_CNR, 0, 0),
|
_DTV_CMD(DTV_STAT_CNR),
|
||||||
_DTV_CMD(DTV_STAT_PRE_ERROR_BIT_COUNT, 0, 0),
|
_DTV_CMD(DTV_STAT_PRE_ERROR_BIT_COUNT),
|
||||||
_DTV_CMD(DTV_STAT_PRE_TOTAL_BIT_COUNT, 0, 0),
|
_DTV_CMD(DTV_STAT_PRE_TOTAL_BIT_COUNT),
|
||||||
_DTV_CMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0, 0),
|
_DTV_CMD(DTV_STAT_POST_ERROR_BIT_COUNT),
|
||||||
_DTV_CMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0, 0),
|
_DTV_CMD(DTV_STAT_POST_TOTAL_BIT_COUNT),
|
||||||
_DTV_CMD(DTV_STAT_ERROR_BLOCK_COUNT, 0, 0),
|
_DTV_CMD(DTV_STAT_ERROR_BLOCK_COUNT),
|
||||||
_DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0),
|
_DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char *dtv_cmd_name(u32 cmd)
|
||||||
|
{
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
|
||||||
|
cmd = array_index_nospec(cmd, DTV_MAX_COMMAND);
|
||||||
|
#endif
|
||||||
|
return dtv_cmds[cmd];
|
||||||
|
}
|
||||||
|
|
||||||
/* Synchronise the legacy tuning parameters into the cache, so that demodulator
|
/* Synchronise the legacy tuning parameters into the cache, so that demodulator
|
||||||
* drivers can use a single set_frontend tuning function, regardless of whether
|
* drivers can use a single set_frontend tuning function, regardless of whether
|
||||||
* it's being used for the legacy or new API, reducing code and complexity.
|
* it's being used for the legacy or new API, reducing code and complexity.
|
||||||
@ -1349,8 +1369,9 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
|
|||||||
struct file *file)
|
struct file *file)
|
||||||
{
|
{
|
||||||
int ncaps;
|
int ncaps;
|
||||||
|
unsigned int len = 1;
|
||||||
|
|
||||||
switch(tvp->cmd) {
|
switch (tvp->cmd) {
|
||||||
case DTV_ENUM_DELSYS:
|
case DTV_ENUM_DELSYS:
|
||||||
ncaps = 0;
|
ncaps = 0;
|
||||||
while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
|
while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
|
||||||
@ -1358,6 +1379,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
|
|||||||
ncaps++;
|
ncaps++;
|
||||||
}
|
}
|
||||||
tvp->u.buffer.len = ncaps;
|
tvp->u.buffer.len = ncaps;
|
||||||
|
len = ncaps;
|
||||||
break;
|
break;
|
||||||
case DTV_FREQUENCY:
|
case DTV_FREQUENCY:
|
||||||
tvp->u.data = c->frequency;
|
tvp->u.data = c->frequency;
|
||||||
@ -1543,27 +1565,51 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
|
|||||||
/* Fill quality measures */
|
/* Fill quality measures */
|
||||||
case DTV_STAT_SIGNAL_STRENGTH:
|
case DTV_STAT_SIGNAL_STRENGTH:
|
||||||
tvp->u.st = c->strength;
|
tvp->u.st = c->strength;
|
||||||
|
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
|
||||||
|
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
|
||||||
|
len = tvp->u.buffer.len;
|
||||||
break;
|
break;
|
||||||
case DTV_STAT_CNR:
|
case DTV_STAT_CNR:
|
||||||
tvp->u.st = c->cnr;
|
tvp->u.st = c->cnr;
|
||||||
|
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
|
||||||
|
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
|
||||||
|
len = tvp->u.buffer.len;
|
||||||
break;
|
break;
|
||||||
case DTV_STAT_PRE_ERROR_BIT_COUNT:
|
case DTV_STAT_PRE_ERROR_BIT_COUNT:
|
||||||
tvp->u.st = c->pre_bit_error;
|
tvp->u.st = c->pre_bit_error;
|
||||||
|
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
|
||||||
|
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
|
||||||
|
len = tvp->u.buffer.len;
|
||||||
break;
|
break;
|
||||||
case DTV_STAT_PRE_TOTAL_BIT_COUNT:
|
case DTV_STAT_PRE_TOTAL_BIT_COUNT:
|
||||||
tvp->u.st = c->pre_bit_count;
|
tvp->u.st = c->pre_bit_count;
|
||||||
|
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
|
||||||
|
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
|
||||||
|
len = tvp->u.buffer.len;
|
||||||
break;
|
break;
|
||||||
case DTV_STAT_POST_ERROR_BIT_COUNT:
|
case DTV_STAT_POST_ERROR_BIT_COUNT:
|
||||||
tvp->u.st = c->post_bit_error;
|
tvp->u.st = c->post_bit_error;
|
||||||
|
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
|
||||||
|
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
|
||||||
|
len = tvp->u.buffer.len;
|
||||||
break;
|
break;
|
||||||
case DTV_STAT_POST_TOTAL_BIT_COUNT:
|
case DTV_STAT_POST_TOTAL_BIT_COUNT:
|
||||||
tvp->u.st = c->post_bit_count;
|
tvp->u.st = c->post_bit_count;
|
||||||
|
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
|
||||||
|
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
|
||||||
|
len = tvp->u.buffer.len;
|
||||||
break;
|
break;
|
||||||
case DTV_STAT_ERROR_BLOCK_COUNT:
|
case DTV_STAT_ERROR_BLOCK_COUNT:
|
||||||
tvp->u.st = c->block_error;
|
tvp->u.st = c->block_error;
|
||||||
|
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
|
||||||
|
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
|
||||||
|
len = tvp->u.buffer.len;
|
||||||
break;
|
break;
|
||||||
case DTV_STAT_TOTAL_BLOCK_COUNT:
|
case DTV_STAT_TOTAL_BLOCK_COUNT:
|
||||||
tvp->u.st = c->block_count;
|
tvp->u.st = c->block_count;
|
||||||
|
if (tvp->u.buffer.len > MAX_DTV_STATS * sizeof(u32))
|
||||||
|
tvp->u.buffer.len = MAX_DTV_STATS * sizeof(u32);
|
||||||
|
len = tvp->u.buffer.len;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_dbg(fe->dvb->device,
|
dev_dbg(fe->dvb->device,
|
||||||
@ -1572,18 +1618,13 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dtv_cmds[tvp->cmd].buffer)
|
if (len < 1)
|
||||||
dev_dbg(fe->dvb->device,
|
len = 1;
|
||||||
"%s: GET cmd 0x%08x (%s) = 0x%08x\n",
|
|
||||||
__func__, tvp->cmd, dtv_cmds[tvp->cmd].name,
|
|
||||||
tvp->u.data);
|
|
||||||
else
|
|
||||||
dev_dbg(fe->dvb->device,
|
dev_dbg(fe->dvb->device,
|
||||||
"%s: GET cmd 0x%08x (%s) len %d: %*ph\n",
|
"%s: GET cmd 0x%08x (%s) len %d: %*ph\n",
|
||||||
__func__,
|
__func__, tvp->cmd, dtv_cmd_name(tvp->cmd),
|
||||||
tvp->cmd, dtv_cmds[tvp->cmd].name,
|
tvp->u.buffer.len, tvp->u.buffer.len, tvp->u.buffer.data);
|
||||||
tvp->u.buffer.len,
|
|
||||||
tvp->u.buffer.len, tvp->u.buffer.data);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1806,6 +1847,54 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe)
|
|||||||
return emulate_delivery_system(fe, delsys);
|
return emulate_delivery_system(fe, delsys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void prepare_tuning_algo_parameters(struct dvb_frontend *fe)
|
||||||
|
{
|
||||||
|
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||||
|
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||||
|
struct dvb_frontend_tune_settings fetunesettings = { 0 };
|
||||||
|
|
||||||
|
/* get frontend-specific tuning settings */
|
||||||
|
if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) {
|
||||||
|
fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
|
||||||
|
fepriv->max_drift = fetunesettings.max_drift;
|
||||||
|
fepriv->step_size = fetunesettings.step_size;
|
||||||
|
} else {
|
||||||
|
/* default values */
|
||||||
|
switch (c->delivery_system) {
|
||||||
|
case SYS_DSS:
|
||||||
|
case SYS_DVBS:
|
||||||
|
case SYS_DVBS2:
|
||||||
|
case SYS_ISDBS:
|
||||||
|
case SYS_TURBO:
|
||||||
|
case SYS_DVBC_ANNEX_A:
|
||||||
|
case SYS_DVBC_ANNEX_C:
|
||||||
|
fepriv->min_delay = HZ / 20;
|
||||||
|
fepriv->step_size = c->symbol_rate / 16000;
|
||||||
|
fepriv->max_drift = c->symbol_rate / 2000;
|
||||||
|
break;
|
||||||
|
case SYS_DVBT:
|
||||||
|
case SYS_DVBT2:
|
||||||
|
case SYS_ISDBT:
|
||||||
|
case SYS_DTMB:
|
||||||
|
fepriv->min_delay = HZ / 20;
|
||||||
|
fepriv->step_size = dvb_frontend_get_stepsize(fe) * 2;
|
||||||
|
fepriv->max_drift = fepriv->step_size + 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* FIXME: This sounds wrong! if freqency_stepsize is
|
||||||
|
* defined by the frontend, why not use it???
|
||||||
|
*/
|
||||||
|
fepriv->min_delay = HZ / 20;
|
||||||
|
fepriv->step_size = 0; /* no zigzag */
|
||||||
|
fepriv->max_drift = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dvb_override_tune_delay > 0)
|
||||||
|
fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dtv_property_process_set - Sets a single DTV property
|
* dtv_property_process_set - Sets a single DTV property
|
||||||
* @fe: Pointer to &struct dvb_frontend
|
* @fe: Pointer to &struct dvb_frontend
|
||||||
@ -1834,7 +1923,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
|
|||||||
else
|
else
|
||||||
dev_dbg(fe->dvb->device,
|
dev_dbg(fe->dvb->device,
|
||||||
"%s: SET cmd 0x%08x (%s) to 0x%08x\n",
|
"%s: SET cmd 0x%08x (%s) to 0x%08x\n",
|
||||||
__func__, cmd, dtv_cmds[cmd].name, data);
|
__func__, cmd, dtv_cmd_name(cmd), data);
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case DTV_CLEAR:
|
case DTV_CLEAR:
|
||||||
/*
|
/*
|
||||||
@ -2204,7 +2293,6 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
|
|||||||
{
|
{
|
||||||
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
struct dvb_frontend_private *fepriv = fe->frontend_priv;
|
||||||
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
|
||||||
struct dvb_frontend_tune_settings fetunesettings;
|
|
||||||
u32 rolloff = 0;
|
u32 rolloff = 0;
|
||||||
|
|
||||||
if (dvb_frontend_check_parameters(fe) < 0)
|
if (dvb_frontend_check_parameters(fe) < 0)
|
||||||
@ -2247,6 +2335,9 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
|
|||||||
case SYS_DVBC_ANNEX_C:
|
case SYS_DVBC_ANNEX_C:
|
||||||
rolloff = 113;
|
rolloff = 113;
|
||||||
break;
|
break;
|
||||||
|
case SYS_DSS:
|
||||||
|
rolloff = 120;
|
||||||
|
break;
|
||||||
case SYS_DVBS:
|
case SYS_DVBS:
|
||||||
case SYS_TURBO:
|
case SYS_TURBO:
|
||||||
case SYS_ISDBS:
|
case SYS_ISDBS:
|
||||||
@ -2282,46 +2373,7 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
|
|||||||
if (c->hierarchy == HIERARCHY_NONE && c->code_rate_LP == FEC_NONE)
|
if (c->hierarchy == HIERARCHY_NONE && c->code_rate_LP == FEC_NONE)
|
||||||
c->code_rate_LP = FEC_AUTO;
|
c->code_rate_LP = FEC_AUTO;
|
||||||
|
|
||||||
/* get frontend-specific tuning settings */
|
prepare_tuning_algo_parameters(fe);
|
||||||
memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
|
|
||||||
if (fe->ops.get_tune_settings && (fe->ops.get_tune_settings(fe, &fetunesettings) == 0)) {
|
|
||||||
fepriv->min_delay = (fetunesettings.min_delay_ms * HZ) / 1000;
|
|
||||||
fepriv->max_drift = fetunesettings.max_drift;
|
|
||||||
fepriv->step_size = fetunesettings.step_size;
|
|
||||||
} else {
|
|
||||||
/* default values */
|
|
||||||
switch (c->delivery_system) {
|
|
||||||
case SYS_DVBS:
|
|
||||||
case SYS_DVBS2:
|
|
||||||
case SYS_ISDBS:
|
|
||||||
case SYS_TURBO:
|
|
||||||
case SYS_DVBC_ANNEX_A:
|
|
||||||
case SYS_DVBC_ANNEX_C:
|
|
||||||
fepriv->min_delay = HZ / 20;
|
|
||||||
fepriv->step_size = c->symbol_rate / 16000;
|
|
||||||
fepriv->max_drift = c->symbol_rate / 2000;
|
|
||||||
break;
|
|
||||||
case SYS_DVBT:
|
|
||||||
case SYS_DVBT2:
|
|
||||||
case SYS_ISDBT:
|
|
||||||
case SYS_DTMB:
|
|
||||||
fepriv->min_delay = HZ / 20;
|
|
||||||
fepriv->step_size = dvb_frontend_get_stepsize(fe) * 2;
|
|
||||||
fepriv->max_drift = (dvb_frontend_get_stepsize(fe) * 2) + 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/*
|
|
||||||
* FIXME: This sounds wrong! if freqency_stepsize is
|
|
||||||
* defined by the frontend, why not use it???
|
|
||||||
*/
|
|
||||||
fepriv->min_delay = HZ / 20;
|
|
||||||
fepriv->step_size = 0; /* no zigzag */
|
|
||||||
fepriv->max_drift = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dvb_override_tune_delay > 0)
|
|
||||||
fepriv->min_delay = (dvb_override_tune_delay * HZ) / 1000;
|
|
||||||
|
|
||||||
fepriv->state = FESTATE_RETUNE;
|
fepriv->state = FESTATE_RETUNE;
|
||||||
|
|
||||||
@ -2336,7 +2388,6 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int dvb_get_property(struct dvb_frontend *fe, struct file *file,
|
static int dvb_get_property(struct dvb_frontend *fe, struct file *file,
|
||||||
struct dtv_properties *tvps)
|
struct dtv_properties *tvps)
|
||||||
{
|
{
|
||||||
@ -2557,8 +2608,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
|
|||||||
|
|
||||||
case FE_DISEQC_SEND_BURST:
|
case FE_DISEQC_SEND_BURST:
|
||||||
if (fe->ops.diseqc_send_burst) {
|
if (fe->ops.diseqc_send_burst) {
|
||||||
err = fe->ops.diseqc_send_burst(fe,
|
err = fe->ops.diseqc_send_burst(fe, (long)parg);
|
||||||
(enum fe_sec_mini_cmd)parg);
|
|
||||||
fepriv->state = FESTATE_DISEQC;
|
fepriv->state = FESTATE_DISEQC;
|
||||||
fepriv->status = 0;
|
fepriv->status = 0;
|
||||||
}
|
}
|
||||||
@ -2566,9 +2616,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
|
|||||||
|
|
||||||
case FE_SET_TONE:
|
case FE_SET_TONE:
|
||||||
if (fe->ops.set_tone) {
|
if (fe->ops.set_tone) {
|
||||||
err = fe->ops.set_tone(fe,
|
fepriv->tone = (long)parg;
|
||||||
(enum fe_sec_tone_mode)parg);
|
err = fe->ops.set_tone(fe, fepriv->tone);
|
||||||
fepriv->tone = (enum fe_sec_tone_mode)parg;
|
|
||||||
fepriv->state = FESTATE_DISEQC;
|
fepriv->state = FESTATE_DISEQC;
|
||||||
fepriv->status = 0;
|
fepriv->status = 0;
|
||||||
}
|
}
|
||||||
@ -2576,9 +2625,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
|
|||||||
|
|
||||||
case FE_SET_VOLTAGE:
|
case FE_SET_VOLTAGE:
|
||||||
if (fe->ops.set_voltage) {
|
if (fe->ops.set_voltage) {
|
||||||
err = fe->ops.set_voltage(fe,
|
fepriv->voltage = (long)parg;
|
||||||
(enum fe_sec_voltage)parg);
|
err = fe->ops.set_voltage(fe, fepriv->voltage);
|
||||||
fepriv->voltage = (enum fe_sec_voltage)parg;
|
|
||||||
fepriv->state = FESTATE_DISEQC;
|
fepriv->state = FESTATE_DISEQC;
|
||||||
fepriv->status = 0;
|
fepriv->status = 0;
|
||||||
}
|
}
|
||||||
@ -2742,7 +2790,6 @@ typedef unsigned int __poll_t;
|
|||||||
#define EPOLLOUT POLLOUT
|
#define EPOLLOUT POLLOUT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static __poll_t dvb_frontend_poll(struct file *file, struct poll_table_struct *wait)
|
static __poll_t dvb_frontend_poll(struct file *file, struct poll_table_struct *wait)
|
||||||
{
|
{
|
||||||
struct dvb_device *dvbdev = file->private_data;
|
struct dvb_device *dvbdev = file->private_data;
|
||||||
@ -2771,7 +2818,17 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
|
|||||||
if (fe->exit == DVB_FE_DEVICE_REMOVED)
|
if (fe->exit == DVB_FE_DEVICE_REMOVED)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (adapter->mfe_shared) {
|
if (adapter->mfe_shared == 2) {
|
||||||
|
mutex_lock(&adapter->mfe_lock);
|
||||||
|
if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
|
||||||
|
if (adapter->mfe_dvbdev &&
|
||||||
|
!adapter->mfe_dvbdev->writers) {
|
||||||
|
mutex_unlock(&adapter->mfe_lock);
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
adapter->mfe_dvbdev = dvbdev;
|
||||||
|
}
|
||||||
|
} else if (adapter->mfe_shared) {
|
||||||
mutex_lock(&adapter->mfe_lock);
|
mutex_lock(&adapter->mfe_lock);
|
||||||
|
|
||||||
if (!adapter->mfe_dvbdev)
|
if (!adapter->mfe_dvbdev)
|
||||||
@ -2949,7 +3006,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe)
|
|||||||
else if (fe->ops.tuner_ops.sleep)
|
else if (fe->ops.tuner_ops.sleep)
|
||||||
ret = fe->ops.tuner_ops.sleep(fe);
|
ret = fe->ops.tuner_ops.sleep(fe);
|
||||||
|
|
||||||
if (fe->ops.sleep)
|
if (fe->ops.suspend)
|
||||||
|
ret = fe->ops.suspend(fe);
|
||||||
|
else if (fe->ops.sleep)
|
||||||
ret = fe->ops.sleep(fe);
|
ret = fe->ops.sleep(fe);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -2965,7 +3024,9 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
|
|||||||
fe->id);
|
fe->id);
|
||||||
|
|
||||||
fe->exit = DVB_FE_DEVICE_RESUME;
|
fe->exit = DVB_FE_DEVICE_RESUME;
|
||||||
if (fe->ops.init)
|
if (fe->ops.resume)
|
||||||
|
ret = fe->ops.resume(fe);
|
||||||
|
else if (fe->ops.init)
|
||||||
ret = fe->ops.init(fe);
|
ret = fe->ops.init(fe);
|
||||||
|
|
||||||
if (fe->ops.tuner_ops.resume)
|
if (fe->ops.tuner_ops.resume)
|
||||||
@ -2999,6 +3060,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
|
|||||||
.name = fe->ops.info.name,
|
.name = fe->ops.info.name,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
int ret;
|
||||||
|
|
||||||
dev_dbg(dvb->device, "%s:\n", __func__);
|
dev_dbg(dvb->device, "%s:\n", __func__);
|
||||||
|
|
||||||
@ -3028,12 +3090,18 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
|
|||||||
fe->dvb = dvb;
|
fe->dvb = dvb;
|
||||||
fepriv->inversion = INVERSION_OFF;
|
fepriv->inversion = INVERSION_OFF;
|
||||||
|
|
||||||
|
ret = dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
|
||||||
|
fe, DVB_DEVICE_FRONTEND, 0);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
dvb_frontend_put(fe);
|
||||||
|
mutex_unlock(&frontend_mutex);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
dev_info(fe->dvb->device,
|
dev_info(fe->dvb->device,
|
||||||
"DVB: registering adapter %i frontend %i (%s)...\n",
|
"DVB: registering adapter %i frontend %i (%s)...\n",
|
||||||
fe->dvb->num, fe->id, fe->ops.info.name);
|
fe->dvb->num, fepriv->dvbdev->id, fe->ops.info.name);
|
||||||
|
|
||||||
dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
|
|
||||||
fe, DVB_DEVICE_FRONTEND, 0);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the cache to the proper values according with the
|
* Initialize the cache to the proper values according with the
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
/*
|
/*
|
||||||
* dvb-math provides some complex fixed-point math
|
* dvb-math provides some complex fixed-point math
|
||||||
* operations shared between the dvb related stuff
|
* operations shared between the dvb related stuff
|
||||||
@ -15,6 +16,7 @@
|
|||||||
* GNU Lesser General Public License for more details.
|
* GNU Lesser General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if (KERNEL_VERSION(6, 6, 0) > LINUX_VERSION_CODE)
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
@ -139,3 +141,6 @@ unsigned int intlog10(u32 value)
|
|||||||
return (log * 646456993) >> 31;
|
return (log * 646456993) >> 31;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(intlog10);
|
EXPORT_SYMBOL(intlog10);
|
||||||
|
#else
|
||||||
|
#include <linux/int_log.h>
|
||||||
|
#endif
|
||||||
|
@ -60,6 +60,9 @@
|
|||||||
|
|
||||||
#include <media/dvb_demux.h>
|
#include <media/dvb_demux.h>
|
||||||
#include <media/dvb_net.h>
|
#include <media/dvb_net.h>
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
|
||||||
|
#include <linux/nospec.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
|
static inline __u32 iov_crc32( __u32 c, struct kvec *iov, unsigned int cnt )
|
||||||
{
|
{
|
||||||
@ -553,7 +556,7 @@ static int dvb_net_ule_new_payload(struct dvb_net_ule_handle *h)
|
|||||||
h->priv->ule_sndu_type_1 = 1;
|
h->priv->ule_sndu_type_1 = 1;
|
||||||
h->ts_remain -= 1;
|
h->ts_remain -= 1;
|
||||||
h->from_where += 1;
|
h->from_where += 1;
|
||||||
/* fallthrough */
|
fallthrough;
|
||||||
case 0:
|
case 0:
|
||||||
h->new_ts = 1;
|
h->new_ts = 1;
|
||||||
h->ts += TS_SZ;
|
h->ts += TS_SZ;
|
||||||
@ -678,7 +681,7 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
|
|||||||
hexdump(ule_where - TS_SZ, TS_SZ);
|
hexdump(ule_where - TS_SZ, TS_SZ);
|
||||||
}
|
}
|
||||||
ule_dump = 1;
|
ule_dump = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
h->dev->stats.rx_errors++;
|
h->dev->stats.rx_errors++;
|
||||||
h->dev->stats.rx_crc_errors++;
|
h->dev->stats.rx_crc_errors++;
|
||||||
@ -1018,7 +1021,7 @@ static u8 mask_promisc[6]={0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
|||||||
|
|
||||||
static int dvb_net_filter_sec_set(struct net_device *dev,
|
static int dvb_net_filter_sec_set(struct net_device *dev,
|
||||||
struct dmx_section_filter **secfilter,
|
struct dmx_section_filter **secfilter,
|
||||||
u8 *mac, u8 *mac_mask)
|
const u8 *mac, u8 *mac_mask)
|
||||||
{
|
{
|
||||||
struct dvb_net_priv *priv = netdev_priv(dev);
|
struct dvb_net_priv *priv = netdev_priv(dev);
|
||||||
int ret;
|
int ret;
|
||||||
@ -1062,7 +1065,7 @@ static int dvb_net_feed_start(struct net_device *dev)
|
|||||||
int ret = 0, i;
|
int ret = 0, i;
|
||||||
struct dvb_net_priv *priv = netdev_priv(dev);
|
struct dvb_net_priv *priv = netdev_priv(dev);
|
||||||
struct dmx_demux *demux = priv->demux;
|
struct dmx_demux *demux = priv->demux;
|
||||||
unsigned char *mac = (unsigned char *) dev->dev_addr;
|
const unsigned char *mac = (const unsigned char *) dev->dev_addr;
|
||||||
|
|
||||||
netdev_dbg(dev, "rx_mode %i\n", priv->rx_mode);
|
netdev_dbg(dev, "rx_mode %i\n", priv->rx_mode);
|
||||||
mutex_lock(&priv->mutex);
|
mutex_lock(&priv->mutex);
|
||||||
@ -1282,7 +1285,11 @@ static int dvb_net_set_mac (struct net_device *dev, void *p)
|
|||||||
struct dvb_net_priv *priv = netdev_priv(dev);
|
struct dvb_net_priv *priv = netdev_priv(dev);
|
||||||
struct sockaddr *addr=p;
|
struct sockaddr *addr=p;
|
||||||
|
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0))
|
||||||
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
|
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
|
||||||
|
#else
|
||||||
|
eth_hw_addr_set(dev, addr->sa_data);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (netif_running(dev))
|
if (netif_running(dev))
|
||||||
schedule_work(&priv->restart_net_feed_wq);
|
schedule_work(&priv->restart_net_feed_wq);
|
||||||
@ -1381,8 +1388,11 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
|
|||||||
dvbnet->dvbdev->adapter->num, if_num);
|
dvbnet->dvbdev->adapter->num, if_num);
|
||||||
|
|
||||||
net->addr_len = 6;
|
net->addr_len = 6;
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0))
|
||||||
memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);
|
memcpy(net->dev_addr, dvbnet->dvbdev->adapter->proposed_mac, 6);
|
||||||
|
#else
|
||||||
|
eth_hw_addr_set(net, dvbnet->dvbdev->adapter->proposed_mac);
|
||||||
|
#endif
|
||||||
dvbnet->device[if_num] = net;
|
dvbnet->device[if_num] = net;
|
||||||
|
|
||||||
priv = netdev_priv(net);
|
priv = netdev_priv(net);
|
||||||
@ -1477,14 +1487,21 @@ static int dvb_net_do_ioctl(struct file *file,
|
|||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
struct dvb_net_priv *priv_data;
|
struct dvb_net_priv *priv_data;
|
||||||
struct dvb_net_if *dvbnetif = parg;
|
struct dvb_net_if *dvbnetif = parg;
|
||||||
|
int if_num = dvbnetif->if_num;
|
||||||
|
|
||||||
if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
|
if (if_num >= DVB_NET_DEVICES_MAX) {
|
||||||
!dvbnet->state[dvbnetif->if_num]) {
|
ret = -EINVAL;
|
||||||
|
goto ioctl_error;
|
||||||
|
}
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
|
||||||
|
if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX);
|
||||||
|
#endif
|
||||||
|
if (!dvbnet->state[if_num]) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto ioctl_error;
|
goto ioctl_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdev = dvbnet->device[dvbnetif->if_num];
|
netdev = dvbnet->device[if_num];
|
||||||
|
|
||||||
priv_data = netdev_priv(netdev);
|
priv_data = netdev_priv(netdev);
|
||||||
dvbnetif->pid=priv_data->pid;
|
dvbnetif->pid=priv_data->pid;
|
||||||
@ -1537,14 +1554,21 @@ static int dvb_net_do_ioctl(struct file *file,
|
|||||||
struct net_device *netdev;
|
struct net_device *netdev;
|
||||||
struct dvb_net_priv *priv_data;
|
struct dvb_net_priv *priv_data;
|
||||||
struct __dvb_net_if_old *dvbnetif = parg;
|
struct __dvb_net_if_old *dvbnetif = parg;
|
||||||
|
int if_num = dvbnetif->if_num;
|
||||||
|
|
||||||
if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
|
if (if_num >= DVB_NET_DEVICES_MAX) {
|
||||||
!dvbnet->state[dvbnetif->if_num]) {
|
ret = -EINVAL;
|
||||||
|
goto ioctl_error;
|
||||||
|
}
|
||||||
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 18))
|
||||||
|
if_num = array_index_nospec(if_num, DVB_NET_DEVICES_MAX);
|
||||||
|
#endif
|
||||||
|
if (!dvbnet->state[if_num]) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto ioctl_error;
|
goto ioctl_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdev = dvbnet->device[dvbnetif->if_num];
|
netdev = dvbnet->device[if_num];
|
||||||
|
|
||||||
priv_data = netdev_priv(netdev);
|
priv_data = netdev_priv(netdev);
|
||||||
dvbnetif->pid=priv_data->pid;
|
dvbnetif->pid=priv_data->pid;
|
||||||
@ -1566,15 +1590,43 @@ static long dvb_net_ioctl(struct file *file,
|
|||||||
return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl);
|
return dvb_usercopy(file, cmd, arg, dvb_net_do_ioctl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int locked_dvb_net_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
struct dvb_device *dvbdev = file->private_data;
|
||||||
|
struct dvb_net *dvbnet = dvbdev->priv;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (mutex_lock_interruptible(&dvbnet->remove_mutex))
|
||||||
|
return -ERESTARTSYS;
|
||||||
|
|
||||||
|
if (dvbnet->exit) {
|
||||||
|
mutex_unlock(&dvbnet->remove_mutex);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = dvb_generic_open(inode, file);
|
||||||
|
|
||||||
|
mutex_unlock(&dvbnet->remove_mutex);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int dvb_net_close(struct inode *inode, struct file *file)
|
static int dvb_net_close(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct dvb_device *dvbdev = file->private_data;
|
struct dvb_device *dvbdev = file->private_data;
|
||||||
struct dvb_net *dvbnet = dvbdev->priv;
|
struct dvb_net *dvbnet = dvbdev->priv;
|
||||||
|
|
||||||
|
mutex_lock(&dvbnet->remove_mutex);
|
||||||
|
|
||||||
dvb_generic_release(inode, file);
|
dvb_generic_release(inode, file);
|
||||||
|
|
||||||
if(dvbdev->users == 1 && dvbnet->exit == 1)
|
if (dvbdev->users == 1 && dvbnet->exit == 1) {
|
||||||
|
mutex_unlock(&dvbnet->remove_mutex);
|
||||||
wake_up(&dvbdev->wait_queue);
|
wake_up(&dvbdev->wait_queue);
|
||||||
|
} else {
|
||||||
|
mutex_unlock(&dvbnet->remove_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1582,7 +1634,7 @@ static int dvb_net_close(struct inode *inode, struct file *file)
|
|||||||
static const struct file_operations dvb_net_fops = {
|
static const struct file_operations dvb_net_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.unlocked_ioctl = dvb_net_ioctl,
|
.unlocked_ioctl = dvb_net_ioctl,
|
||||||
.open = dvb_generic_open,
|
.open = locked_dvb_net_open,
|
||||||
.release = dvb_net_close,
|
.release = dvb_net_close,
|
||||||
.llseek = noop_llseek,
|
.llseek = noop_llseek,
|
||||||
};
|
};
|
||||||
@ -1601,10 +1653,13 @@ void dvb_net_release (struct dvb_net *dvbnet)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
mutex_lock(&dvbnet->remove_mutex);
|
||||||
dvbnet->exit = 1;
|
dvbnet->exit = 1;
|
||||||
|
mutex_unlock(&dvbnet->remove_mutex);
|
||||||
|
|
||||||
if (dvbnet->dvbdev->users < 1)
|
if (dvbnet->dvbdev->users < 1)
|
||||||
wait_event(dvbnet->dvbdev->wait_queue,
|
wait_event(dvbnet->dvbdev->wait_queue,
|
||||||
dvbnet->dvbdev->users==1);
|
dvbnet->dvbdev->users == 1);
|
||||||
|
|
||||||
dvb_unregister_device(dvbnet->dvbdev);
|
dvb_unregister_device(dvbnet->dvbdev);
|
||||||
|
|
||||||
@ -1623,6 +1678,7 @@ int dvb_net_init (struct dvb_adapter *adap, struct dvb_net *dvbnet,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
mutex_init(&dvbnet->ioctl_mutex);
|
mutex_init(&dvbnet->ioctl_mutex);
|
||||||
|
mutex_init(&dvbnet->remove_mutex);
|
||||||
dvbnet->demux = dmx;
|
dvbnet->demux = dmx;
|
||||||
|
|
||||||
for (i=0; i<DVB_NET_DEVICES_MAX; i++)
|
for (i=0; i<DVB_NET_DEVICES_MAX; i++)
|
||||||
|
@ -63,7 +63,7 @@ int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
|
|||||||
* this pairs with smp_store_release() in dvb_ringbuffer_write(),
|
* this pairs with smp_store_release() in dvb_ringbuffer_write(),
|
||||||
* dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset()
|
* dvb_ringbuffer_write_user(), or dvb_ringbuffer_reset()
|
||||||
*
|
*
|
||||||
* for memory barriers also see Documentation/core-api/circular-buffers.txt
|
* for memory barriers also see Documentation/core-api/circular-buffers.rst
|
||||||
*/
|
*/
|
||||||
return (rbuf->pread == smp_load_acquire(&rbuf->pwrite));
|
return (rbuf->pread == smp_load_acquire(&rbuf->pwrite));
|
||||||
#endif
|
#endif
|
||||||
@ -75,7 +75,7 @@ ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
|
|||||||
{
|
{
|
||||||
ssize_t free;
|
ssize_t free;
|
||||||
|
|
||||||
/* ACCESS_ONCE() to load read pointer on writer side
|
/* READ_ONCE() to load read pointer on writer side
|
||||||
* this pairs with smp_store_release() in dvb_ringbuffer_read(),
|
* this pairs with smp_store_release() in dvb_ringbuffer_read(),
|
||||||
* dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(),
|
* dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(),
|
||||||
* or dvb_ringbuffer_reset()
|
* or dvb_ringbuffer_reset()
|
||||||
@ -171,7 +171,7 @@ ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, si
|
|||||||
#else
|
#else
|
||||||
/* smp_store_release() for read pointer update to ensure
|
/* smp_store_release() for read pointer update to ensure
|
||||||
* that buf is not overwritten until read is complete,
|
* that buf is not overwritten until read is complete,
|
||||||
* this pairs with ACCESS_ONCE() in dvb_ringbuffer_free()
|
* this pairs with READ_ONCE() in dvb_ringbuffer_free()
|
||||||
*/
|
*/
|
||||||
smp_store_release(&rbuf->pread, 0);
|
smp_store_release(&rbuf->pread, 0);
|
||||||
#endif
|
#endif
|
||||||
@ -203,7 +203,7 @@ void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
|
|||||||
#else
|
#else
|
||||||
/* smp_store_release() for read pointer update to ensure
|
/* smp_store_release() for read pointer update to ensure
|
||||||
* that buf is not overwritten until read is complete,
|
* that buf is not overwritten until read is complete,
|
||||||
* this pairs with ACCESS_ONCE() in dvb_ringbuffer_free()
|
* this pairs with READ_ONCE() in dvb_ringbuffer_free()
|
||||||
*/
|
*/
|
||||||
smp_store_release(&rbuf->pread, 0);
|
smp_store_release(&rbuf->pread, 0);
|
||||||
#endif
|
#endif
|
||||||
@ -391,7 +391,9 @@ ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t*
|
|||||||
idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
|
idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
consumed = (idx - rbuf->pread) % rbuf->size;
|
consumed = (idx - rbuf->pread);
|
||||||
|
if (consumed < 0)
|
||||||
|
consumed += rbuf->size;
|
||||||
|
|
||||||
while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {
|
while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {
|
||||||
|
|
||||||
|
@ -5,10 +5,6 @@
|
|||||||
* Copyright (C) 2015 Samsung Electronics
|
* Copyright (C) 2015 Samsung Electronics
|
||||||
*
|
*
|
||||||
* Author: jh1009.sung@samsung.com
|
* Author: jh1009.sung@samsung.com
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/err.h>
|
#include <linux/err.h>
|
||||||
@ -171,17 +167,14 @@ int dvb_vb2_init(struct dvb_vb2_ctx *ctx, const char *name, int nonblocking)
|
|||||||
|
|
||||||
memset(ctx, 0, sizeof(struct dvb_vb2_ctx));
|
memset(ctx, 0, sizeof(struct dvb_vb2_ctx));
|
||||||
q->type = DVB_BUF_TYPE_CAPTURE;
|
q->type = DVB_BUF_TYPE_CAPTURE;
|
||||||
/**capture type*/
|
|
||||||
q->is_output = 0;
|
|
||||||
/**only mmap is supported currently*/
|
/**only mmap is supported currently*/
|
||||||
q->io_modes = VB2_MMAP;
|
q->io_modes = VB2_MMAP;
|
||||||
q->drv_priv = ctx;
|
q->drv_priv = ctx;
|
||||||
q->buf_struct_size = sizeof(struct dvb_buffer);
|
q->buf_struct_size = sizeof(struct dvb_buffer);
|
||||||
q->min_buffers_needed = 1;
|
q->min_queued_buffers = 1;
|
||||||
q->ops = &dvb_vb2_qops;
|
q->ops = &dvb_vb2_qops;
|
||||||
q->mem_ops = &vb2_vmalloc_memops;
|
q->mem_ops = &vb2_vmalloc_memops;
|
||||||
q->buf_ops = &dvb_vb2_buf_ops;
|
q->buf_ops = &dvb_vb2_buf_ops;
|
||||||
q->num_buffers = 0;
|
|
||||||
ret = vb2_core_queue_init(q);
|
ret = vb2_core_queue_init(q);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ctx->state = DVB_VB2_STATE_NONE;
|
ctx->state = DVB_VB2_STATE_NONE;
|
||||||
@ -358,7 +351,14 @@ int dvb_vb2_reqbufs(struct dvb_vb2_ctx *ctx, struct dmx_requestbuffers *req)
|
|||||||
|
|
||||||
int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
|
int dvb_vb2_querybuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
|
||||||
{
|
{
|
||||||
vb2_core_querybuf(&ctx->vb_q, b->index, b);
|
struct vb2_queue *q = &ctx->vb_q;
|
||||||
|
struct vb2_buffer *vb2 = vb2_get_buffer(q, b->index);
|
||||||
|
|
||||||
|
if (!vb2) {
|
||||||
|
dprintk(1, "[%s] invalid buffer index\n", ctx->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
vb2_core_querybuf(&ctx->vb_q, vb2, b);
|
||||||
dprintk(3, "[%s] index=%d\n", ctx->name, b->index);
|
dprintk(3, "[%s] index=%d\n", ctx->name, b->index);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -368,7 +368,7 @@ int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp)
|
|||||||
struct vb2_queue *q = &ctx->vb_q;
|
struct vb2_queue *q = &ctx->vb_q;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, exp->index,
|
ret = vb2_core_expbuf(&ctx->vb_q, &exp->fd, q->type, q->bufs[exp->index],
|
||||||
0, exp->flags);
|
0, exp->flags);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
|
dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
|
||||||
@ -382,9 +382,15 @@ int dvb_vb2_expbuf(struct dvb_vb2_ctx *ctx, struct dmx_exportbuffer *exp)
|
|||||||
|
|
||||||
int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
|
int dvb_vb2_qbuf(struct dvb_vb2_ctx *ctx, struct dmx_buffer *b)
|
||||||
{
|
{
|
||||||
|
struct vb2_queue *q = &ctx->vb_q;
|
||||||
|
struct vb2_buffer *vb2 = vb2_get_buffer(q, b->index);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = vb2_core_qbuf(&ctx->vb_q, b->index, b, NULL);
|
if (!vb2) {
|
||||||
|
dprintk(1, "[%s] invalid buffer index\n", ctx->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
ret = vb2_core_qbuf(&ctx->vb_q, vb2, b, NULL);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
|
dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,
|
||||||
b->index, ret);
|
b->index, ret);
|
||||||
|
@ -1,20 +1,10 @@
|
|||||||
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||||
/*
|
/*
|
||||||
* dvbdev.c
|
* dvbdev.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
|
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
|
||||||
* & Marcus Metzler <marcus@convergence.de>
|
* & Marcus Metzler <marcus@convergence.de>
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define pr_fmt(fmt) "dvbdev: " fmt
|
#define pr_fmt(fmt) "dvbdev: " fmt
|
||||||
@ -40,6 +30,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static DEFINE_MUTEX(dvbdev_mutex);
|
static DEFINE_MUTEX(dvbdev_mutex);
|
||||||
|
static LIST_HEAD(dvbdevfops_list);
|
||||||
static int dvbdev_debug;
|
static int dvbdev_debug;
|
||||||
|
|
||||||
module_param(dvbdev_debug, int, 0644);
|
module_param(dvbdev_debug, int, 0644);
|
||||||
@ -86,12 +77,16 @@ static const u8 minor_type[] = {
|
|||||||
[DVB_DEVICE_CA] = 6,
|
[DVB_DEVICE_CA] = 6,
|
||||||
[DVB_DEVICE_NET] = 7,
|
[DVB_DEVICE_NET] = 7,
|
||||||
[DVB_DEVICE_OSD] = 8,
|
[DVB_DEVICE_OSD] = 8,
|
||||||
|
[DVB_DEVICE_CI] = 9,
|
||||||
|
[DVB_DEVICE_MOD] = 10,
|
||||||
|
[DVB_DEVICE_NS] = 11,
|
||||||
|
[DVB_DEVICE_NSD] = 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define nums2minor(num, type, id) \
|
#define nums2minor(num, type, id) \
|
||||||
(((num) << 6) | ((id) << 4) | minor_type[type])
|
(((num) << 6) | ((id) << 4) | minor_type[type])
|
||||||
|
|
||||||
#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
|
#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS * 64)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct class *dvb_class;
|
static struct class *dvb_class;
|
||||||
@ -114,7 +109,7 @@ static int dvb_device_open(struct inode *inode, struct file *file)
|
|||||||
new_fops = fops_get(dvbdev->fops);
|
new_fops = fops_get(dvbdev->fops);
|
||||||
if (!new_fops)
|
if (!new_fops)
|
||||||
goto fail;
|
goto fail;
|
||||||
file->private_data = dvbdev;
|
file->private_data = dvb_device_get(dvbdev);
|
||||||
replace_fops(file, new_fops);
|
replace_fops(file, new_fops);
|
||||||
if (file->f_op->open)
|
if (file->f_op->open)
|
||||||
err = file->f_op->open(inode, file);
|
err = file->f_op->open(inode, file);
|
||||||
@ -128,9 +123,7 @@ fail:
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct file_operations dvb_device_fops = {
|
||||||
static const struct file_operations dvb_device_fops =
|
|
||||||
{
|
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.open = dvb_device_open,
|
.open = dvb_device_open,
|
||||||
.llseek = noop_llseek,
|
.llseek = noop_llseek,
|
||||||
@ -141,29 +134,38 @@ static struct cdev dvb_device_cdev;
|
|||||||
int dvb_generic_open(struct inode *inode, struct file *file)
|
int dvb_generic_open(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct dvb_device *dvbdev = file->private_data;
|
struct dvb_device *dvbdev = file->private_data;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (!dvbdev)
|
if (!dvbdev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if (!dvbdev->users)
|
mutex_lock(&dvbdev->lock);
|
||||||
return -EBUSY;
|
if (!dvbdev->users) {
|
||||||
|
ret = -EBUSY;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
|
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
|
||||||
if (!dvbdev->readers)
|
if (!dvbdev->readers) {
|
||||||
return -EBUSY;
|
ret = -EBUSY;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
dvbdev->readers--;
|
dvbdev->readers--;
|
||||||
} else {
|
} else {
|
||||||
if (!dvbdev->writers)
|
if (!dvbdev->writers) {
|
||||||
return -EBUSY;
|
ret = -EBUSY;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
dvbdev->writers--;
|
dvbdev->writers--;
|
||||||
}
|
}
|
||||||
|
|
||||||
dvbdev->users--;
|
dvbdev->users--;
|
||||||
return 0;
|
unlock:
|
||||||
|
mutex_unlock(&dvbdev->lock);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_generic_open);
|
EXPORT_SYMBOL(dvb_generic_open);
|
||||||
|
|
||||||
|
|
||||||
int dvb_generic_release(struct inode *inode, struct file *file)
|
int dvb_generic_release(struct inode *inode, struct file *file)
|
||||||
{
|
{
|
||||||
struct dvb_device *dvbdev = file->private_data;
|
struct dvb_device *dvbdev = file->private_data;
|
||||||
@ -171,18 +173,21 @@ int dvb_generic_release(struct inode *inode, struct file *file)
|
|||||||
if (!dvbdev)
|
if (!dvbdev)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
|
mutex_lock(&dvbdev->lock);
|
||||||
|
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
|
||||||
dvbdev->readers++;
|
dvbdev->readers++;
|
||||||
} else {
|
else
|
||||||
dvbdev->writers++;
|
dvbdev->writers++;
|
||||||
}
|
|
||||||
|
|
||||||
dvbdev->users++;
|
dvbdev->users++;
|
||||||
|
mutex_unlock(&dvbdev->lock);
|
||||||
|
|
||||||
|
dvb_device_put(dvbdev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_generic_release);
|
EXPORT_SYMBOL(dvb_generic_release);
|
||||||
|
|
||||||
|
|
||||||
long dvb_generic_ioctl(struct file *file,
|
long dvb_generic_ioctl(struct file *file,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
@ -198,13 +203,13 @@ long dvb_generic_ioctl(struct file *file,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_generic_ioctl);
|
EXPORT_SYMBOL(dvb_generic_ioctl);
|
||||||
|
|
||||||
|
static int dvbdev_get_free_id(struct dvb_adapter *adap, int type)
|
||||||
static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
|
|
||||||
{
|
{
|
||||||
u32 id = 0;
|
u32 id = 0;
|
||||||
|
|
||||||
while (id < DVB_MAX_IDS) {
|
while (id < DVB_MAX_IDS) {
|
||||||
struct dvb_device *dev;
|
struct dvb_device *dev;
|
||||||
|
|
||||||
list_for_each_entry(dev, &adap->device_list, list_head)
|
list_for_each_entry(dev, &adap->device_list, list_head)
|
||||||
if (dev->type == type && dev->id == id)
|
if (dev->type == type && dev->id == id)
|
||||||
goto skip;
|
goto skip;
|
||||||
@ -248,6 +253,7 @@ static void dvb_media_device_free(struct dvb_device *dvbdev)
|
|||||||
|
|
||||||
if (dvbdev->adapter->conn) {
|
if (dvbdev->adapter->conn) {
|
||||||
media_device_unregister_entity(dvbdev->adapter->conn);
|
media_device_unregister_entity(dvbdev->adapter->conn);
|
||||||
|
kfree(dvbdev->adapter->conn);
|
||||||
dvbdev->adapter->conn = NULL;
|
dvbdev->adapter->conn = NULL;
|
||||||
kfree(dvbdev->adapter->conn_pads);
|
kfree(dvbdev->adapter->conn_pads);
|
||||||
dvbdev->adapter->conn_pads = NULL;
|
dvbdev->adapter->conn_pads = NULL;
|
||||||
@ -259,7 +265,7 @@ static void dvb_media_device_free(struct dvb_device *dvbdev)
|
|||||||
static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
|
static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
|
||||||
const char *name, int npads)
|
const char *name, int npads)
|
||||||
{
|
{
|
||||||
int i, ret = 0;
|
int i;
|
||||||
|
|
||||||
dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
|
dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
@ -276,6 +282,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
|
|||||||
for (i = 0; i < npads; i++) {
|
for (i = 0; i < npads; i++) {
|
||||||
struct media_pad *pads = &dvbdev->tsout_pads[i];
|
struct media_pad *pads = &dvbdev->tsout_pads[i];
|
||||||
struct media_entity *entity = &dvbdev->tsout_entity[i];
|
struct media_entity *entity = &dvbdev->tsout_entity[i];
|
||||||
|
int ret;
|
||||||
|
|
||||||
entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
|
entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
|
||||||
if (!entity->name)
|
if (!entity->name)
|
||||||
@ -346,8 +353,9 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
|
|||||||
if (npads) {
|
if (npads) {
|
||||||
dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
|
dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!dvbdev->pads){
|
if (!dvbdev->pads) {
|
||||||
kfree(dvbdev->entity);
|
kfree(dvbdev->entity);
|
||||||
|
dvbdev->entity = NULL;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,7 +405,7 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
|
|||||||
|
|
||||||
static int dvb_register_media_device(struct dvb_device *dvbdev,
|
static int dvb_register_media_device(struct dvb_device *dvbdev,
|
||||||
int type, int minor,
|
int type, int minor,
|
||||||
unsigned demux_sink_pads)
|
unsigned int demux_sink_pads)
|
||||||
{
|
{
|
||||||
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
|
#if defined(CONFIG_MEDIA_CONTROLLER_DVB)
|
||||||
struct media_link *link;
|
struct media_link *link;
|
||||||
@ -464,14 +472,16 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
|||||||
enum dvb_device_type type, int demux_sink_pads)
|
enum dvb_device_type type, int demux_sink_pads)
|
||||||
{
|
{
|
||||||
struct dvb_device *dvbdev;
|
struct dvb_device *dvbdev;
|
||||||
struct file_operations *dvbdevfops;
|
struct file_operations *dvbdevfops = NULL;
|
||||||
|
struct dvbdevfops_node *node = NULL, *new_node = NULL;
|
||||||
struct device *clsdev;
|
struct device *clsdev;
|
||||||
int minor;
|
int minor;
|
||||||
int id, ret;
|
int id, ret;
|
||||||
|
|
||||||
mutex_lock(&dvbdev_register_lock);
|
mutex_lock(&dvbdev_register_lock);
|
||||||
|
|
||||||
if ((id = dvbdev_get_free_id (adap, type)) < 0){
|
id = dvbdev_get_free_id(adap, type);
|
||||||
|
if (id < 0) {
|
||||||
mutex_unlock(&dvbdev_register_lock);
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
*pdvbdev = NULL;
|
*pdvbdev = NULL;
|
||||||
pr_err("%s: couldn't find free device id\n", __func__);
|
pr_err("%s: couldn't find free device id\n", __func__);
|
||||||
@ -479,40 +489,69 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
|||||||
}
|
}
|
||||||
|
|
||||||
*pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL);
|
*pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL);
|
||||||
|
if (!dvbdev) {
|
||||||
if (!dvbdev){
|
|
||||||
mutex_unlock(&dvbdev_register_lock);
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
|
/*
|
||||||
|
* When a device of the same type is probe()d more than once,
|
||||||
|
* the first allocated fops are used. This prevents memory leaks
|
||||||
|
* that can occur when the same device is probe()d repeatedly.
|
||||||
|
*/
|
||||||
|
list_for_each_entry(node, &dvbdevfops_list, list_head) {
|
||||||
|
if (node->fops->owner == adap->module &&
|
||||||
|
node->type == type && node->template == template) {
|
||||||
|
dvbdevfops = node->fops;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!dvbdevfops){
|
if (!dvbdevfops) {
|
||||||
kfree (dvbdev);
|
dvbdevfops = kmemdup(template->fops, sizeof(*dvbdevfops), GFP_KERNEL);
|
||||||
|
if (!dvbdevfops) {
|
||||||
|
kfree(dvbdev);
|
||||||
mutex_unlock(&dvbdev_register_lock);
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_node = kzalloc(sizeof(*new_node), GFP_KERNEL);
|
||||||
|
if (!new_node) {
|
||||||
|
kfree(dvbdevfops);
|
||||||
|
kfree(dvbdev);
|
||||||
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_node->fops = dvbdevfops;
|
||||||
|
new_node->type = type;
|
||||||
|
new_node->template = template;
|
||||||
|
list_add_tail(&new_node->list_head, &dvbdevfops_list);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(dvbdev, template, sizeof(struct dvb_device));
|
memcpy(dvbdev, template, sizeof(struct dvb_device));
|
||||||
|
kref_init(&dvbdev->ref);
|
||||||
dvbdev->type = type;
|
dvbdev->type = type;
|
||||||
dvbdev->id = id;
|
dvbdev->id = id;
|
||||||
dvbdev->adapter = adap;
|
dvbdev->adapter = adap;
|
||||||
dvbdev->priv = priv;
|
dvbdev->priv = priv;
|
||||||
dvbdev->fops = dvbdevfops;
|
dvbdev->fops = dvbdevfops;
|
||||||
init_waitqueue_head (&dvbdev->wait_queue);
|
mutex_init(&dvbdev->lock);
|
||||||
|
init_waitqueue_head(&dvbdev->wait_queue);
|
||||||
dvbdevfops->owner = adap->module;
|
dvbdevfops->owner = adap->module;
|
||||||
|
list_add_tail(&dvbdev->list_head, &adap->device_list);
|
||||||
list_add_tail (&dvbdev->list_head, &adap->device_list);
|
|
||||||
|
|
||||||
down_write(&minor_rwsem);
|
down_write(&minor_rwsem);
|
||||||
#ifdef CONFIG_DVB_DYNAMIC_MINORS
|
#ifdef CONFIG_DVB_DYNAMIC_MINORS
|
||||||
for (minor = 0; minor < MAX_DVB_MINORS; minor++)
|
for (minor = 0; minor < MAX_DVB_MINORS; minor++)
|
||||||
if (dvb_minors[minor] == NULL)
|
if (!dvb_minors[minor])
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (minor == MAX_DVB_MINORS) {
|
if (minor == MAX_DVB_MINORS) {
|
||||||
|
if (new_node) {
|
||||||
|
list_del(&new_node->list_head);
|
||||||
kfree(dvbdevfops);
|
kfree(dvbdevfops);
|
||||||
|
kfree(new_node);
|
||||||
|
}
|
||||||
|
list_del(&dvbdev->list_head);
|
||||||
kfree(dvbdev);
|
kfree(dvbdev);
|
||||||
up_write(&minor_rwsem);
|
up_write(&minor_rwsem);
|
||||||
mutex_unlock(&dvbdev_register_lock);
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
@ -521,41 +560,51 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
|||||||
#else
|
#else
|
||||||
minor = nums2minor(adap->num, type, id);
|
minor = nums2minor(adap->num, type, id);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dvbdev->minor = minor;
|
dvbdev->minor = minor;
|
||||||
dvb_minors[minor] = dvbdev;
|
dvb_minors[minor] = dvb_device_get(dvbdev);
|
||||||
up_write(&minor_rwsem);
|
up_write(&minor_rwsem);
|
||||||
|
|
||||||
ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
|
ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("%s: dvb_register_media_device failed to create the mediagraph\n",
|
pr_err("%s: dvb_register_media_device failed to create the mediagraph\n",
|
||||||
__func__);
|
__func__);
|
||||||
|
if (new_node) {
|
||||||
dvb_media_device_free(dvbdev);
|
list_del(&new_node->list_head);
|
||||||
kfree(dvbdevfops);
|
kfree(dvbdevfops);
|
||||||
|
kfree(new_node);
|
||||||
|
}
|
||||||
|
dvb_media_device_free(dvbdev);
|
||||||
|
list_del(&dvbdev->list_head);
|
||||||
kfree(dvbdev);
|
kfree(dvbdev);
|
||||||
mutex_unlock(&dvbdev_register_lock);
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&dvbdev_register_lock);
|
|
||||||
|
|
||||||
clsdev = device_create(dvb_class, adap->device,
|
clsdev = device_create(dvb_class, adap->device,
|
||||||
MKDEV(DVB_MAJOR, minor),
|
MKDEV(DVB_MAJOR, minor),
|
||||||
dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
|
dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
|
||||||
if (IS_ERR(clsdev)) {
|
if (IS_ERR(clsdev)) {
|
||||||
pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
|
pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
|
||||||
__func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
|
__func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
|
||||||
|
if (new_node) {
|
||||||
|
list_del(&new_node->list_head);
|
||||||
|
kfree(dvbdevfops);
|
||||||
|
kfree(new_node);
|
||||||
|
}
|
||||||
|
dvb_media_device_free(dvbdev);
|
||||||
|
list_del(&dvbdev->list_head);
|
||||||
|
kfree(dvbdev);
|
||||||
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
return PTR_ERR(clsdev);
|
return PTR_ERR(clsdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
|
dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
|
||||||
adap->num, dnames[type], id, minor, minor);
|
adap->num, dnames[type], id, minor, minor);
|
||||||
|
|
||||||
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_register_device);
|
EXPORT_SYMBOL(dvb_register_device);
|
||||||
|
|
||||||
|
|
||||||
void dvb_remove_device(struct dvb_device *dvbdev)
|
void dvb_remove_device(struct dvb_device *dvbdev)
|
||||||
{
|
{
|
||||||
if (!dvbdev)
|
if (!dvbdev)
|
||||||
@ -563,36 +612,44 @@ void dvb_remove_device(struct dvb_device *dvbdev)
|
|||||||
|
|
||||||
down_write(&minor_rwsem);
|
down_write(&minor_rwsem);
|
||||||
dvb_minors[dvbdev->minor] = NULL;
|
dvb_minors[dvbdev->minor] = NULL;
|
||||||
|
dvb_device_put(dvbdev);
|
||||||
up_write(&minor_rwsem);
|
up_write(&minor_rwsem);
|
||||||
|
|
||||||
dvb_media_device_free(dvbdev);
|
dvb_media_device_free(dvbdev);
|
||||||
|
|
||||||
device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
|
device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
|
||||||
|
|
||||||
list_del (&dvbdev->list_head);
|
list_del(&dvbdev->list_head);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_remove_device);
|
EXPORT_SYMBOL(dvb_remove_device);
|
||||||
|
|
||||||
|
static void dvb_free_device(struct kref *ref)
|
||||||
void dvb_free_device(struct dvb_device *dvbdev)
|
|
||||||
{
|
{
|
||||||
if (!dvbdev)
|
struct dvb_device *dvbdev = container_of(ref, struct dvb_device, ref);
|
||||||
return;
|
|
||||||
|
|
||||||
kfree (dvbdev->fops);
|
kfree(dvbdev);
|
||||||
kfree (dvbdev);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_free_device);
|
|
||||||
|
|
||||||
|
struct dvb_device *dvb_device_get(struct dvb_device *dvbdev)
|
||||||
|
{
|
||||||
|
kref_get(&dvbdev->ref);
|
||||||
|
return dvbdev;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(dvb_device_get);
|
||||||
|
|
||||||
|
void dvb_device_put(struct dvb_device *dvbdev)
|
||||||
|
{
|
||||||
|
if (dvbdev)
|
||||||
|
kref_put(&dvbdev->ref, dvb_free_device);
|
||||||
|
}
|
||||||
|
|
||||||
void dvb_unregister_device(struct dvb_device *dvbdev)
|
void dvb_unregister_device(struct dvb_device *dvbdev)
|
||||||
{
|
{
|
||||||
dvb_remove_device(dvbdev);
|
dvb_remove_device(dvbdev);
|
||||||
dvb_free_device(dvbdev);
|
dvb_device_put(dvbdev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_unregister_device);
|
EXPORT_SYMBOL(dvb_unregister_device);
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
|
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
|
||||||
|
|
||||||
static int dvb_create_io_intf_links(struct dvb_adapter *adap,
|
static int dvb_create_io_intf_links(struct dvb_adapter *adap,
|
||||||
@ -625,9 +682,9 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
|
|||||||
struct media_entity *demux = NULL, *ca = NULL;
|
struct media_entity *demux = NULL, *ca = NULL;
|
||||||
struct media_link *link;
|
struct media_link *link;
|
||||||
struct media_interface *intf;
|
struct media_interface *intf;
|
||||||
unsigned demux_pad = 0;
|
unsigned int demux_pad = 0;
|
||||||
unsigned dvr_pad = 0;
|
unsigned int dvr_pad = 0;
|
||||||
unsigned ntuner = 0, ndemod = 0;
|
unsigned int ntuner = 0, ndemod = 0;
|
||||||
int ret, pad_source, pad_sink;
|
int ret, pad_source, pad_sink;
|
||||||
static const char *connector_name = "Television";
|
static const char *connector_name = "Television";
|
||||||
|
|
||||||
@ -698,7 +755,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
|
|||||||
false);
|
false);
|
||||||
} else {
|
} else {
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0))
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0))
|
||||||
pad_sink = media_get_pad_index(tuner, true,
|
pad_sink = media_get_pad_index(tuner, MEDIA_PAD_FL_SINK,
|
||||||
PAD_SIGNAL_ANALOG);
|
PAD_SIGNAL_ANALOG);
|
||||||
if (pad_sink < 0)
|
if (pad_sink < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -720,7 +777,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
|
|||||||
if (ntuner && ndemod) {
|
if (ntuner && ndemod) {
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0))
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,2,0))
|
||||||
/* NOTE: first found tuner source pad presumed correct */
|
/* NOTE: first found tuner source pad presumed correct */
|
||||||
pad_source = media_get_pad_index(tuner, false,
|
pad_source = media_get_pad_index(tuner, MEDIA_PAD_FL_SOURCE,
|
||||||
PAD_SIGNAL_ANALOG);
|
PAD_SIGNAL_ANALOG);
|
||||||
if (pad_source < 0)
|
if (pad_source < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -829,8 +886,10 @@ EXPORT_SYMBOL_GPL(dvb_create_media_graph);
|
|||||||
static int dvbdev_check_free_adapter_num(int num)
|
static int dvbdev_check_free_adapter_num(int num)
|
||||||
{
|
{
|
||||||
struct list_head *entry;
|
struct list_head *entry;
|
||||||
|
|
||||||
list_for_each(entry, &dvb_adapter_list) {
|
list_for_each(entry, &dvb_adapter_list) {
|
||||||
struct dvb_adapter *adap;
|
struct dvb_adapter *adap;
|
||||||
|
|
||||||
adap = list_entry(entry, struct dvb_adapter, list_head);
|
adap = list_entry(entry, struct dvb_adapter, list_head);
|
||||||
if (adap->num == num)
|
if (adap->num == num)
|
||||||
return 0;
|
return 0;
|
||||||
@ -838,7 +897,7 @@ static int dvbdev_check_free_adapter_num(int num)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dvbdev_get_free_adapter_num (void)
|
static int dvbdev_get_free_adapter_num(void)
|
||||||
{
|
{
|
||||||
int num = 0;
|
int num = 0;
|
||||||
|
|
||||||
@ -851,7 +910,6 @@ static int dvbdev_get_free_adapter_num (void)
|
|||||||
return -ENFILE;
|
return -ENFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
|
int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
|
||||||
struct module *module, struct device *device,
|
struct module *module, struct device *device,
|
||||||
short *adapter_nums)
|
short *adapter_nums)
|
||||||
@ -878,8 +936,8 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
|
|||||||
return -ENFILE;
|
return -ENFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (adap, 0, sizeof(struct dvb_adapter));
|
memset(adap, 0, sizeof(struct dvb_adapter));
|
||||||
INIT_LIST_HEAD (&adap->device_list);
|
INIT_LIST_HEAD(&adap->device_list);
|
||||||
|
|
||||||
pr_info("DVB: registering new adapter (%s)\n", name);
|
pr_info("DVB: registering new adapter (%s)\n", name);
|
||||||
|
|
||||||
@ -889,13 +947,13 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
|
|||||||
adap->device = device;
|
adap->device = device;
|
||||||
adap->mfe_shared = 0;
|
adap->mfe_shared = 0;
|
||||||
adap->mfe_dvbdev = NULL;
|
adap->mfe_dvbdev = NULL;
|
||||||
mutex_init (&adap->mfe_lock);
|
mutex_init(&adap->mfe_lock);
|
||||||
|
|
||||||
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
|
#ifdef CONFIG_MEDIA_CONTROLLER_DVB
|
||||||
mutex_init(&adap->mdev_lock);
|
mutex_init(&adap->mdev_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
list_add_tail (&adap->list_head, &dvb_adapter_list);
|
list_add_tail(&adap->list_head, &dvb_adapter_list);
|
||||||
|
|
||||||
mutex_unlock(&dvbdev_register_lock);
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
|
|
||||||
@ -903,21 +961,22 @@ int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_register_adapter);
|
EXPORT_SYMBOL(dvb_register_adapter);
|
||||||
|
|
||||||
|
|
||||||
int dvb_unregister_adapter(struct dvb_adapter *adap)
|
int dvb_unregister_adapter(struct dvb_adapter *adap)
|
||||||
{
|
{
|
||||||
mutex_lock(&dvbdev_register_lock);
|
mutex_lock(&dvbdev_register_lock);
|
||||||
list_del (&adap->list_head);
|
list_del(&adap->list_head);
|
||||||
mutex_unlock(&dvbdev_register_lock);
|
mutex_unlock(&dvbdev_register_lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_unregister_adapter);
|
EXPORT_SYMBOL(dvb_unregister_adapter);
|
||||||
|
|
||||||
/* if the miracle happens and "generic_usercopy()" is included into
|
/*
|
||||||
the kernel, then this can vanish. please don't make the mistake and
|
* if the miracle happens and "generic_usercopy()" is included into
|
||||||
define this as video_usercopy(). this will introduce a dependency
|
* the kernel, then this can vanish. please don't make the mistake and
|
||||||
to the v4l "videodev.o" module, which is unnecessary for some
|
* define this as video_usercopy(). this will introduce a dependency
|
||||||
cards (ie. the budget dvb-cards don't need the v4l module...) */
|
* to the v4l "videodev.o" module, which is unnecessary for some
|
||||||
|
* cards (ie. the budget dvb-cards don't need the v4l module...)
|
||||||
|
*/
|
||||||
int dvb_usercopy(struct file *file,
|
int dvb_usercopy(struct file *file,
|
||||||
unsigned int cmd, unsigned long arg,
|
unsigned int cmd, unsigned long arg,
|
||||||
int (*func)(struct file *file,
|
int (*func)(struct file *file,
|
||||||
@ -935,7 +994,7 @@ int dvb_usercopy(struct file *file,
|
|||||||
* For this command, the pointer is actually an integer
|
* For this command, the pointer is actually an integer
|
||||||
* argument.
|
* argument.
|
||||||
*/
|
*/
|
||||||
parg = (void *) arg;
|
parg = (void *)arg;
|
||||||
break;
|
break;
|
||||||
case _IOC_READ: /* some v4l ioctls are marked wrong ... */
|
case _IOC_READ: /* some v4l ioctls are marked wrong ... */
|
||||||
case _IOC_WRITE:
|
case _IOC_WRITE:
|
||||||
@ -945,7 +1004,7 @@ int dvb_usercopy(struct file *file,
|
|||||||
} else {
|
} else {
|
||||||
/* too big to allocate from stack */
|
/* too big to allocate from stack */
|
||||||
mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
|
mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
|
||||||
if (NULL == mbuf)
|
if (!mbuf)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
parg = mbuf;
|
parg = mbuf;
|
||||||
}
|
}
|
||||||
@ -957,15 +1016,15 @@ int dvb_usercopy(struct file *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* call driver */
|
/* call driver */
|
||||||
if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
|
err = func(file, cmd, parg);
|
||||||
|
if (err == -ENOIOCTLCMD)
|
||||||
err = -ENOTTY;
|
err = -ENOTTY;
|
||||||
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Copy results into user buffer */
|
/* Copy results into user buffer */
|
||||||
switch (_IOC_DIR(cmd))
|
switch (_IOC_DIR(cmd)) {
|
||||||
{
|
|
||||||
case _IOC_READ:
|
case _IOC_READ:
|
||||||
case (_IOC_WRITE | _IOC_READ):
|
case (_IOC_WRITE | _IOC_READ):
|
||||||
if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
|
if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
|
||||||
@ -977,7 +1036,6 @@ out:
|
|||||||
kfree(mbuf);
|
kfree(mbuf);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dvb_usercopy);
|
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_I2C)
|
#if IS_ENABLED(CONFIG_I2C)
|
||||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,5,0))
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,5,0))
|
||||||
@ -1030,9 +1088,13 @@ EXPORT_SYMBOL_GPL(dvb_module_release);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (KERNEL_VERSION(6, 2, 0) > LINUX_VERSION_CODE)
|
||||||
static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
|
#else
|
||||||
|
static int dvb_uevent(const struct device *dev, struct kobj_uevent_env *env)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct dvb_device *dvbdev = dev_get_drvdata(dev);
|
const struct dvb_device *dvbdev = dev_get_drvdata(dev);
|
||||||
|
|
||||||
add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
|
add_uevent_var(env, "DVB_ADAPTER_NUM=%d", dvbdev->adapter->num);
|
||||||
add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]);
|
add_uevent_var(env, "DVB_DEVICE_TYPE=%s", dnames[dvbdev->type]);
|
||||||
@ -1040,9 +1102,13 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (KERNEL_VERSION(6, 2, 0) > LINUX_VERSION_CODE)
|
||||||
static char *dvb_devnode(struct device *dev, umode_t *mode)
|
static char *dvb_devnode(struct device *dev, umode_t *mode)
|
||||||
|
#else
|
||||||
|
static char *dvb_devnode(const struct device *dev, umode_t *mode)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct dvb_device *dvbdev = dev_get_drvdata(dev);
|
const struct dvb_device *dvbdev = dev_get_drvdata(dev);
|
||||||
|
|
||||||
return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d",
|
return kasprintf(GFP_KERNEL, "dvb/adapter%d/%s%d",
|
||||||
dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);
|
dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);
|
||||||
@ -1054,18 +1120,24 @@ static int __init init_dvbdev(void)
|
|||||||
int retval;
|
int retval;
|
||||||
dev_t dev = MKDEV(DVB_MAJOR, 0);
|
dev_t dev = MKDEV(DVB_MAJOR, 0);
|
||||||
|
|
||||||
if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
|
retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB");
|
||||||
|
if (retval != 0) {
|
||||||
pr_err("dvb-core: unable to get major %d\n", DVB_MAJOR);
|
pr_err("dvb-core: unable to get major %d\n", DVB_MAJOR);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdev_init(&dvb_device_cdev, &dvb_device_fops);
|
cdev_init(&dvb_device_cdev, &dvb_device_fops);
|
||||||
if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
|
retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS);
|
||||||
|
if (retval != 0) {
|
||||||
pr_err("dvb-core: unable register character device\n");
|
pr_err("dvb-core: unable register character device\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0))
|
||||||
dvb_class = class_create(THIS_MODULE, "dvb");
|
dvb_class = class_create(THIS_MODULE, "dvb");
|
||||||
|
#else
|
||||||
|
dvb_class = class_create("dvb");
|
||||||
|
#endif
|
||||||
if (IS_ERR(dvb_class)) {
|
if (IS_ERR(dvb_class)) {
|
||||||
retval = PTR_ERR(dvb_class);
|
retval = PTR_ERR(dvb_class);
|
||||||
goto error;
|
goto error;
|
||||||
@ -1080,12 +1152,19 @@ error:
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void __exit exit_dvbdev(void)
|
static void __exit exit_dvbdev(void)
|
||||||
{
|
{
|
||||||
|
struct dvbdevfops_node *node, *next;
|
||||||
|
|
||||||
class_destroy(dvb_class);
|
class_destroy(dvb_class);
|
||||||
cdev_del(&dvb_device_cdev);
|
cdev_del(&dvb_device_cdev);
|
||||||
unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
|
unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
|
||||||
|
|
||||||
|
list_for_each_entry_safe(node, next, &dvbdevfops_list, list_head) {
|
||||||
|
list_del(&node->list_head);
|
||||||
|
kfree(node->fops);
|
||||||
|
kfree(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
subsys_initcall(init_dvbdev);
|
subsys_initcall(init_dvbdev);
|
||||||
|
@ -9,6 +9,7 @@ EXTRA_CFLAGS += -DCONFIG_DVB_STV6110x
|
|||||||
EXTRA_CFLAGS += -DCONFIG_DVB_STV0367DD
|
EXTRA_CFLAGS += -DCONFIG_DVB_STV0367DD
|
||||||
#EXTRA_CFLAGS += -DCONFIG_DVB_TDA18212
|
#EXTRA_CFLAGS += -DCONFIG_DVB_TDA18212
|
||||||
EXTRA_CFLAGS += -DCONFIG_DVB_TDA18212DD
|
EXTRA_CFLAGS += -DCONFIG_DVB_TDA18212DD
|
||||||
|
EXTRA_CFLAGS += -DCONFIG_DVB_TDA18271C2DD
|
||||||
EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843
|
EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843
|
||||||
EXTRA_CFLAGS += -DCONFIG_DVB_STV6111
|
EXTRA_CFLAGS += -DCONFIG_DVB_STV6111
|
||||||
EXTRA_CFLAGS += -DCONFIG_DVB_STV0910
|
EXTRA_CFLAGS += -DCONFIG_DVB_STV0910
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
ccflags-y += -I$(srctree)/drivers/media/dvb-core/
|
ccflags-y += -I$(srctree)/drivers/media/dvb-core/
|
||||||
ccflags-y += -I$(srctree)/drivers/media/tuners/
|
ccflags-y += -I$(srctree)/drivers/media/tuners/
|
||||||
|
ccflags-y += --include=dd_compat.h
|
||||||
|
|
||||||
# FIXME: RTL2832 SDR driver uses power management directly from USB IF driver
|
# FIXME: RTL2832 SDR driver uses power management directly from USB IF driver
|
||||||
ifdef CONFIG_DVB_RTL2832_SDR
|
ifdef CONFIG_DVB_RTL2832_SDR
|
||||||
|
@ -780,7 +780,7 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
|
|||||||
|
|
||||||
return &ci->en;
|
return &ci->en;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(cxd2099_attach);
|
EXPORT_SYMBOL_GPL(cxd2099_attach);
|
||||||
|
|
||||||
MODULE_DESCRIPTION("cxd2099");
|
MODULE_DESCRIPTION("cxd2099");
|
||||||
MODULE_AUTHOR("Ralph Metzler");
|
MODULE_AUTHOR("Ralph Metzler");
|
||||||
|
@ -36,7 +36,11 @@
|
|||||||
#include <asm/div64.h>
|
#include <asm/div64.h>
|
||||||
|
|
||||||
#include <media/dvb_frontend.h>
|
#include <media/dvb_frontend.h>
|
||||||
|
#if (KERNEL_VERSION(6, 6, 0) > LINUX_VERSION_CODE)
|
||||||
#include <media/dvb_math.h>
|
#include <media/dvb_math.h>
|
||||||
|
#else
|
||||||
|
#include <linux/int_log.h>
|
||||||
|
#endif
|
||||||
#include "cxd2843.h"
|
#include "cxd2843.h"
|
||||||
|
|
||||||
#define Log10x100(x) ((s32)(((((u64) intlog2(x) * 0x1e1a5e2e) >> 47 ) + 1) >> 1))
|
#define Log10x100(x) ((s32)(((((u64) intlog2(x) * 0x1e1a5e2e) >> 47 ) + 1) >> 1))
|
||||||
@ -2701,7 +2705,7 @@ struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c,
|
|||||||
kfree(state);
|
kfree(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(cxd2843_attach);
|
EXPORT_SYMBOL_GPL(cxd2843_attach);
|
||||||
|
|
||||||
MODULE_DESCRIPTION("CXD2843/37/38 driver");
|
MODULE_DESCRIPTION("CXD2843/37/38 driver");
|
||||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||||
|
@ -62,16 +62,6 @@ static bool IsQAM(struct drxk_state *state)
|
|||||||
state->m_OperationMode == OM_QAM_ITU_C;
|
state->m_OperationMode == OM_QAM_ITU_C;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsA1WithPatchCode(struct drxk_state *state)
|
|
||||||
{
|
|
||||||
return state->m_DRXK_A1_PATCH_CODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsA1WithRomCode(struct drxk_state *state)
|
|
||||||
{
|
|
||||||
return state->m_DRXK_A1_ROM_CODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define NOA1ROM 0
|
#define NOA1ROM 0
|
||||||
|
|
||||||
#ifndef CHK_ERROR
|
#ifndef CHK_ERROR
|
||||||
@ -492,7 +482,7 @@ static int WriteBlock(struct drxk_state *state, u32 Address,
|
|||||||
#define DRXK_MAX_RETRIES_POWERUP 20
|
#define DRXK_MAX_RETRIES_POWERUP 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int PowerUpDevice(struct drxk_state *state)
|
static int PowerUpDevice(struct drxk_state *state)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
u8 data = 0;
|
u8 data = 0;
|
||||||
@ -1566,7 +1556,7 @@ static int SetOperationMode(struct drxk_state *state, enum OperationMode oMode)
|
|||||||
case OM_QAM_ITU_B:
|
case OM_QAM_ITU_B:
|
||||||
status = -1;
|
status = -1;
|
||||||
break;
|
break;
|
||||||
case OM_QAM_ITU_A: /* fallthrough */
|
case OM_QAM_ITU_A:
|
||||||
case OM_QAM_ITU_C:
|
case OM_QAM_ITU_C:
|
||||||
CHK_ERROR(MPEGTSStop(state));
|
CHK_ERROR(MPEGTSStop(state));
|
||||||
CHK_ERROR(PowerDownQAM(state));
|
CHK_ERROR(PowerDownQAM(state));
|
||||||
@ -1589,7 +1579,7 @@ static int SetOperationMode(struct drxk_state *state, enum OperationMode oMode)
|
|||||||
case OM_QAM_ITU_B:
|
case OM_QAM_ITU_B:
|
||||||
status = -1;
|
status = -1;
|
||||||
break;
|
break;
|
||||||
case OM_QAM_ITU_A: /* fallthrough */
|
case OM_QAM_ITU_A:
|
||||||
case OM_QAM_ITU_C:
|
case OM_QAM_ITU_C:
|
||||||
state->m_OperationMode = oMode;
|
state->m_OperationMode = oMode;
|
||||||
CHK_ERROR(SetQAMStandard(state,oMode));
|
CHK_ERROR(SetQAMStandard(state,oMode));
|
||||||
@ -1765,7 +1755,7 @@ static int MPEGTSDtoSetup(struct drxk_state *state, enum OperationMode oMode)
|
|||||||
fecOcRcnCtlRate = 0xC00000;
|
fecOcRcnCtlRate = 0xC00000;
|
||||||
staticCLK = state->m_DVBTStaticCLK;
|
staticCLK = state->m_DVBTStaticCLK;
|
||||||
break;
|
break;
|
||||||
case OM_QAM_ITU_A: /* fallthrough */
|
case OM_QAM_ITU_A:
|
||||||
case OM_QAM_ITU_C:
|
case OM_QAM_ITU_C:
|
||||||
fecOcTmdMode = 0x0004;
|
fecOcTmdMode = 0x0004;
|
||||||
fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
|
fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
|
||||||
@ -2804,12 +2794,12 @@ static int DVBTScCommand(struct drxk_state *state,
|
|||||||
case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
|
case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
|
||||||
status = Write16_0(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
|
status = Write16_0(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
|
||||||
/* All commands using 1 parameters */
|
/* All commands using 1 parameters */
|
||||||
/* fall through */
|
fallthrough;
|
||||||
case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
|
case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
|
||||||
case OFDM_SC_RA_RAM_CMD_USER_IO:
|
case OFDM_SC_RA_RAM_CMD_USER_IO:
|
||||||
status = Write16_0(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
|
status = Write16_0(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
|
||||||
/* All commands using 0 parameters */
|
/* All commands using 0 parameters */
|
||||||
/* fall through */
|
fallthrough;
|
||||||
case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
|
case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
|
||||||
case OFDM_SC_RA_RAM_CMD_NULL:
|
case OFDM_SC_RA_RAM_CMD_NULL:
|
||||||
/* Write command */
|
/* Write command */
|
||||||
@ -3218,7 +3208,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
|
|||||||
default:
|
default:
|
||||||
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
|
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
|
||||||
/* try first guess DRX_FFTMODE_8K */
|
/* try first guess DRX_FFTMODE_8K */
|
||||||
/* fall through */
|
fallthrough;
|
||||||
case TRANSMISSION_MODE_8K:
|
case TRANSMISSION_MODE_8K:
|
||||||
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
|
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
|
||||||
break;
|
break;
|
||||||
@ -3237,7 +3227,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
|
|||||||
case GUARD_INTERVAL_AUTO:
|
case GUARD_INTERVAL_AUTO:
|
||||||
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
|
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
|
||||||
/* try first guess DRX_GUARD_1DIV4 */
|
/* try first guess DRX_GUARD_1DIV4 */
|
||||||
/* fall through */
|
fallthrough;
|
||||||
case GUARD_INTERVAL_1_4:
|
case GUARD_INTERVAL_1_4:
|
||||||
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
|
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
|
||||||
break;
|
break;
|
||||||
@ -3265,7 +3255,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
|
|||||||
/* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
|
/* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
|
||||||
// transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO;
|
// transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO;
|
||||||
//break;
|
//break;
|
||||||
/* fall through */
|
fallthrough;
|
||||||
case HIERARCHY_1:
|
case HIERARCHY_1:
|
||||||
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
|
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
|
||||||
break;
|
break;
|
||||||
@ -3288,7 +3278,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
|
|||||||
default:
|
default:
|
||||||
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
|
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
|
||||||
/* try first guess DRX_CONSTELLATION_QAM64 */
|
/* try first guess DRX_CONSTELLATION_QAM64 */
|
||||||
/* fall through */
|
fallthrough;
|
||||||
case QAM_64:
|
case QAM_64:
|
||||||
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
|
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
|
||||||
break;
|
break;
|
||||||
@ -3311,7 +3301,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
|
|||||||
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
|
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
|
||||||
WR16(devAddr, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI));
|
WR16(devAddr, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI));
|
||||||
break;
|
break;
|
||||||
case DRX_PRIORITY_UNKNOWN : /* fall through */
|
case DRX_PRIORITY_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
return (DRX_STS_INVALID_ARG);
|
return (DRX_STS_INVALID_ARG);
|
||||||
break;
|
break;
|
||||||
@ -3332,7 +3322,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
|
|||||||
default:
|
default:
|
||||||
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
|
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
|
||||||
/* try first guess DRX_CODERATE_2DIV3 */
|
/* try first guess DRX_CODERATE_2DIV3 */
|
||||||
/* fall through */
|
fallthrough;
|
||||||
case FEC_2_3 :
|
case FEC_2_3 :
|
||||||
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
|
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
|
||||||
break;
|
break;
|
||||||
@ -5097,4 +5087,4 @@ MODULE_DESCRIPTION("DRX-K driver");
|
|||||||
MODULE_AUTHOR("Ralph Metzler");
|
MODULE_AUTHOR("Ralph Metzler");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
||||||
EXPORT_SYMBOL(drxk_attach);
|
EXPORT_SYMBOL_GPL(drxk_attach);
|
||||||
|
@ -152,7 +152,7 @@ struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe,
|
|||||||
|
|
||||||
return fe;
|
return fe;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(lnbh25_attach);
|
EXPORT_SYMBOL_GPL(lnbh25_attach);
|
||||||
|
|
||||||
MODULE_DESCRIPTION("LNBH25");
|
MODULE_DESCRIPTION("LNBH25");
|
||||||
MODULE_AUTHOR("Ralph Metzler");
|
MODULE_AUTHOR("Ralph Metzler");
|
||||||
|
@ -178,7 +178,7 @@ struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
|
|||||||
return lnbx2x_attach(fe, i2c, override_set, override_clear,
|
return lnbx2x_attach(fe, i2c, override_set, override_clear,
|
||||||
i2c_addr, LNBH24_TTX);
|
i2c_addr, LNBH24_TTX);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(lnbh24_attach);
|
EXPORT_SYMBOL_GPL(lnbh24_attach);
|
||||||
|
|
||||||
struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
|
struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
|
||||||
struct i2c_adapter *i2c, u8 override_set,
|
struct i2c_adapter *i2c, u8 override_set,
|
||||||
@ -187,7 +187,7 @@ struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
|
|||||||
return lnbx2x_attach(fe, i2c, override_set, override_clear,
|
return lnbx2x_attach(fe, i2c, override_set, override_clear,
|
||||||
0x08, LNBP21_ISEL);
|
0x08, LNBP21_ISEL);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(lnbp21_attach);
|
EXPORT_SYMBOL_GPL(lnbp21_attach);
|
||||||
|
|
||||||
MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
|
MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
|
||||||
MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
|
MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
|
||||||
|
@ -39,7 +39,9 @@
|
|||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <asm/div64.h>
|
#include <asm/div64.h>
|
||||||
|
#if (KERNEL_VERSION(6, 12, 0) > LINUX_VERSION_CODE)
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <media/dvb_frontend.h>
|
#include <media/dvb_frontend.h>
|
||||||
#include "mxl5xx.h"
|
#include "mxl5xx.h"
|
||||||
@ -786,7 +788,7 @@ static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* fallthrough */
|
fallthrough;
|
||||||
case SYS_DVBS:
|
case SYS_DVBS:
|
||||||
switch ((MXL_HYDRA_MODULATION_E)
|
switch ((MXL_HYDRA_MODULATION_E)
|
||||||
regData[DMD_MODULATION_SCHEME_ADDR]) {
|
regData[DMD_MODULATION_SCHEME_ADDR]) {
|
||||||
@ -823,15 +825,19 @@ static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties
|
|||||||
static int set_input(struct dvb_frontend *fe, int input)
|
static int set_input(struct dvb_frontend *fe, int input)
|
||||||
{
|
{
|
||||||
struct mxl *state = fe->demodulator_priv;
|
struct mxl *state = fe->demodulator_priv;
|
||||||
|
#ifndef KERNEL_DVB_CORE
|
||||||
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
|
||||||
|
#endif
|
||||||
|
|
||||||
state->tuner = p->input = input;
|
state->tuner = input;
|
||||||
|
#ifndef KERNEL_DVB_CORE
|
||||||
|
p->input = input;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct dvb_frontend_ops mxl_ops = {
|
static struct dvb_frontend_ops mxl_ops = {
|
||||||
.delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
|
.delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
|
||||||
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
|
|
||||||
.info = {
|
.info = {
|
||||||
.name = "MXL5XX",
|
.name = "MXL5XX",
|
||||||
.frequency_min_hz = 300000000,
|
.frequency_min_hz = 300000000,
|
||||||
@ -856,7 +862,10 @@ static struct dvb_frontend_ops mxl_ops = {
|
|||||||
.read_signal_strength = read_signal_strength,
|
.read_signal_strength = read_signal_strength,
|
||||||
.read_ucblocks = read_ucblocks,
|
.read_ucblocks = read_ucblocks,
|
||||||
.get_frontend = get_frontend,
|
.get_frontend = get_frontend,
|
||||||
|
#ifndef KERNEL_DVB_CORE
|
||||||
.set_input = set_input,
|
.set_input = set_input,
|
||||||
|
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
|
||||||
|
#endif
|
||||||
.diseqc_send_master_cmd = send_master_cmd,
|
.diseqc_send_master_cmd = send_master_cmd,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1873,7 +1882,8 @@ static int probe(struct mxl *state, struct mxl5xx_cfg *cfg)
|
|||||||
|
|
||||||
struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
|
struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
|
||||||
struct mxl5xx_cfg *cfg,
|
struct mxl5xx_cfg *cfg,
|
||||||
u32 demod, u32 tuner)
|
u32 demod, u32 tuner,
|
||||||
|
int (**fn_set_input)(struct dvb_frontend *, int))
|
||||||
{
|
{
|
||||||
struct mxl *state;
|
struct mxl *state;
|
||||||
struct mxl_base *base;
|
struct mxl_base *base;
|
||||||
@ -1913,9 +1923,12 @@ struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
|
|||||||
list_add(&base->mxllist, &mxllist);
|
list_add(&base->mxllist, &mxllist);
|
||||||
}
|
}
|
||||||
state->fe.ops = mxl_ops;
|
state->fe.ops = mxl_ops;
|
||||||
|
#ifndef KERNEL_DVB_CORE
|
||||||
state->fe.ops.xbar[1] = demod;
|
state->fe.ops.xbar[1] = demod;
|
||||||
state->fe.demodulator_priv = state;
|
|
||||||
state->fe.dtv_property_cache.input = tuner;
|
state->fe.dtv_property_cache.input = tuner;
|
||||||
|
#endif
|
||||||
|
state->fe.demodulator_priv = state;
|
||||||
|
*fn_set_input = set_input;
|
||||||
list_add(&state->mxl, &base->mxls);
|
list_add(&state->mxl, &base->mxls);
|
||||||
return &state->fe;
|
return &state->fe;
|
||||||
|
|
||||||
|
@ -23,12 +23,15 @@ struct mxl5xx_cfg {
|
|||||||
|
|
||||||
extern struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
|
extern struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
|
||||||
struct mxl5xx_cfg *cfg,
|
struct mxl5xx_cfg *cfg,
|
||||||
u32 demod, u32 tuner);
|
u32 demod, u32 tuner,
|
||||||
|
int (**fn_set_input)(struct dvb_frontend *, int));
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
|
static inline struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
|
||||||
struct mxl5xx_cfg *cfg,
|
struct mxl5xx_cfg *cfg,
|
||||||
u32 demod, u32 tuner)
|
u32 demod, u32 tuner,
|
||||||
|
int (**fn_set_input)(struct dvb_frontend *, int))
|
||||||
{
|
{
|
||||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2338,7 +2338,7 @@ error:
|
|||||||
kfree(state);
|
kfree(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(stv0367ter_attach);
|
EXPORT_SYMBOL_GPL(stv0367ter_attach);
|
||||||
|
|
||||||
static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable)
|
static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable)
|
||||||
{
|
{
|
||||||
@ -3462,7 +3462,7 @@ error:
|
|||||||
kfree(state);
|
kfree(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(stv0367cab_attach);
|
EXPORT_SYMBOL_GPL(stv0367cab_attach);
|
||||||
|
|
||||||
MODULE_PARM_DESC(debug, "Set debug");
|
MODULE_PARM_DESC(debug, "Set debug");
|
||||||
MODULE_PARM_DESC(i2c_debug, "Set i2c debug");
|
MODULE_PARM_DESC(i2c_debug, "Set i2c debug");
|
||||||
|
@ -1570,7 +1570,6 @@ static int ofdm_lock(struct stv_state *state)
|
|||||||
|
|
||||||
if (!(OFDM_Status & 0x40))
|
if (!(OFDM_Status & 0x40))
|
||||||
return -1;
|
return -1;
|
||||||
//printk("lock 1\n");
|
|
||||||
|
|
||||||
readreg(state, R367_OFDM_SYR_STAT,&SYR_STAT);
|
readreg(state, R367_OFDM_SYR_STAT,&SYR_STAT);
|
||||||
FFTMode = (SYR_STAT & 0x0C) >> 2;
|
FFTMode = (SYR_STAT & 0x0C) >> 2;
|
||||||
@ -1609,9 +1608,9 @@ static int ofdm_lock(struct stv_state *state)
|
|||||||
writereg(state, R367_TSGENERAL,tmp2 & ~0x01);
|
writereg(state, R367_TSGENERAL,tmp2 & ~0x01);
|
||||||
}
|
}
|
||||||
msleep(FECTimeOut);
|
msleep(FECTimeOut);
|
||||||
if( (OFDM_Status & 0x98) != 0x98 )
|
if( (OFDM_Status & 0x98) != 0x98 ) {
|
||||||
;//return -1;
|
;//return -1;
|
||||||
//printk("lock 2\n");
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
u8 Guard = (SYR_STAT & 0x03);
|
u8 Guard = (SYR_STAT & 0x03);
|
||||||
@ -2154,7 +2153,7 @@ MODULE_DESCRIPTION("STV0367DD driver");
|
|||||||
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
MODULE_AUTHOR("Ralph Metzler, Manfred Voelkel");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
|
||||||
EXPORT_SYMBOL(stv0367_attach);
|
EXPORT_SYMBOL_GPL(stv0367_attach);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5254,7 +5254,7 @@ error:
|
|||||||
kfree(state);
|
kfree(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(stv090x_attach);
|
EXPORT_SYMBOL_GPL(stv090x_attach);
|
||||||
MODULE_PARM_DESC(verbose, "Set Verbosity level");
|
MODULE_PARM_DESC(verbose, "Set Verbosity level");
|
||||||
MODULE_AUTHOR("Manu Abraham");
|
MODULE_AUTHOR("Manu Abraham");
|
||||||
MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend");
|
MODULE_DESCRIPTION("STV090x Multi-Std Broadcast frontend");
|
||||||
|
@ -118,6 +118,7 @@ struct stv {
|
|||||||
|
|
||||||
enum fe_code_rate puncture_rate;
|
enum fe_code_rate puncture_rate;
|
||||||
enum fe_stv0910_modcod modcod;
|
enum fe_stv0910_modcod modcod;
|
||||||
|
u8 pls;
|
||||||
enum dvbs2_fec_type fec_type;
|
enum dvbs2_fec_type fec_type;
|
||||||
u32 pilots;
|
u32 pilots;
|
||||||
enum fe_stv0910_roll_off fe_roll_off;
|
enum fe_stv0910_roll_off fe_roll_off;
|
||||||
@ -508,6 +509,7 @@ static int get_signal_parameters(struct stv *state)
|
|||||||
|
|
||||||
if (state->receive_mode == RCVMODE_DVBS2) {
|
if (state->receive_mode == RCVMODE_DVBS2) {
|
||||||
read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp);
|
read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp);
|
||||||
|
state->pls = tmp & 0x7f;
|
||||||
state->modcod = (enum fe_stv0910_modcod)((tmp & 0x7c) >> 2);
|
state->modcod = (enum fe_stv0910_modcod)((tmp & 0x7c) >> 2);
|
||||||
state->pilots = (tmp & 0x01) != 0;
|
state->pilots = (tmp & 0x01) != 0;
|
||||||
state->fec_type = (enum dvbs2_fec_type)((tmp & 0x02) >> 1);
|
state->fec_type = (enum dvbs2_fec_type)((tmp & 0x02) >> 1);
|
||||||
@ -1333,6 +1335,7 @@ static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties
|
|||||||
};
|
};
|
||||||
read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp);
|
read_reg(state, RSTV0910_P2_DMDMODCOD + state->regoff, &tmp);
|
||||||
mc = ((tmp & 0x7c) >> 2);
|
mc = ((tmp & 0x7c) >> 2);
|
||||||
|
p->transmission_mode = tmp & 0x7f;
|
||||||
p->pilot = (tmp & 0x01) ? PILOT_ON : PILOT_OFF;
|
p->pilot = (tmp & 0x01) ? PILOT_ON : PILOT_OFF;
|
||||||
p->modulation = modcod2mod[mc];
|
p->modulation = modcod2mod[mc];
|
||||||
p->fec_inner = modcod2fec[mc];
|
p->fec_inner = modcod2fec[mc];
|
||||||
@ -1643,7 +1646,7 @@ static int clear_slave(struct dvb_frontend *fe)
|
|||||||
|
|
||||||
get_field(RXEND, &done);
|
get_field(RXEND, &done);
|
||||||
get_reg(DISRXBYTES, &n);
|
get_reg(DISRXBYTES, &n);
|
||||||
printk("clear: done = %u, %u fifo bytes\n", done, n);
|
//printk("clear: done = %u, %u fifo bytes\n", done, n);
|
||||||
|
|
||||||
for (get_reg(DISRXBYTES, &n); n; n--)
|
for (get_reg(DISRXBYTES, &n); n; n--)
|
||||||
get_reg(DISRXFIFO, &d);
|
get_reg(DISRXFIFO, &d);
|
||||||
@ -1699,7 +1702,7 @@ static int recv_slave_reply(struct dvb_frontend *fe,
|
|||||||
msleep(10);
|
msleep(10);
|
||||||
}
|
}
|
||||||
get_reg(DISRXBYTES, &val);
|
get_reg(DISRXBYTES, &val);
|
||||||
printk("done = %u, %u fifo bytes, i=%u\n", done, val, i);
|
//printk("done = %u, %u fifo bytes, i=%u\n", done, val, i);
|
||||||
if (i == to && !val)
|
if (i == to && !val)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
if (done && !val)
|
if (done && !val)
|
||||||
|
@ -407,7 +407,7 @@ const struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
|
|||||||
printk(KERN_INFO "%s: Attaching STV6110x\n", __func__);
|
printk(KERN_INFO "%s: Attaching STV6110x\n", __func__);
|
||||||
return stv6110x->devctl;
|
return stv6110x->devctl;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(stv6110x_attach);
|
EXPORT_SYMBOL_GPL(stv6110x_attach);
|
||||||
|
|
||||||
MODULE_AUTHOR("Manu Abraham");
|
MODULE_AUTHOR("Manu Abraham");
|
||||||
MODULE_DESCRIPTION("STV6110x Silicon tuner");
|
MODULE_DESCRIPTION("STV6110x Silicon tuner");
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <asm/div64.h>
|
#include <asm/div64.h>
|
||||||
|
|
||||||
#include <media/dvb_frontend.h>
|
#include <media/dvb_frontend.h>
|
||||||
|
#include "stv6111.h"
|
||||||
|
|
||||||
static inline u32 MulDiv32(u32 a, u32 b, u32 c)
|
static inline u32 MulDiv32(u32 a, u32 b, u32 c)
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <asm/div64.h>
|
#include <asm/div64.h>
|
||||||
|
|
||||||
#include <media/dvb_frontend.h>
|
#include <media/dvb_frontend.h>
|
||||||
|
#include "tda18212dd.h"
|
||||||
|
|
||||||
#ifndef CHK_ERROR
|
#ifndef CHK_ERROR
|
||||||
#define CHK_ERROR(s) if ((status = s) < 0) break
|
#define CHK_ERROR(s) if ((status = s) < 0) break
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <asm/div64.h>
|
#include <asm/div64.h>
|
||||||
|
|
||||||
#include <media/dvb_frontend.h>
|
#include <media/dvb_frontend.h>
|
||||||
|
#include "tda18271c2dd.h"
|
||||||
|
|
||||||
struct SStandardParam {
|
struct SStandardParam {
|
||||||
s32 m_IFFrequency;
|
s32 m_IFFrequency;
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
#ifndef _TDA18271C2DD_H_
|
#ifndef _TDA18271C2DD_H_
|
||||||
#define _TDA18271C2DD_H_
|
#define _TDA18271C2DD_H_
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
|
||||||
#if defined(CONFIG_DVB_TDA18271C2DD) || \
|
#if defined(CONFIG_DVB_TDA18271C2DD) || \
|
||||||
(defined(CONFIG_DVB_TDA18271C2DD_MODULE) \
|
(defined(CONFIG_DVB_TDA18271C2DD_MODULE) \
|
||||||
&& defined(MODULE))
|
&& defined(MODULE))
|
||||||
|
31
include/dd_compat.h
Normal file
31
include/dd_compat.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include <linux/version.h>
|
||||||
|
|
||||||
|
#if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE)
|
||||||
|
#define __devexit
|
||||||
|
#define __devinit
|
||||||
|
#define __devinitconst
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
#define __has_attribute(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef fallthrough
|
||||||
|
#if __has_attribute(__fallthrough__)
|
||||||
|
# define fallthrough __attribute__((__fallthrough__))
|
||||||
|
#else
|
||||||
|
# define fallthrough do {} while (0) /* fallthrough */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef KERNEL_DVB_CORE
|
||||||
|
#define DVB_DEVICE_CI 0
|
||||||
|
#define DVB_DEVICE_NS 6
|
||||||
|
#define DVB_DEVICE_NSD 7
|
||||||
|
#define DVB_DEVICE_MOD 8
|
||||||
|
|
||||||
|
#define APSK_128 21
|
||||||
|
#define APSK_256 22
|
||||||
|
#define APSK_256_L 23
|
||||||
|
#endif
|
@ -7,21 +7,6 @@
|
|||||||
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
|
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
|
||||||
* & Marcus Metzler <marcus@convergence.de>
|
* & Marcus Metzler <marcus@convergence.de>
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Lesser Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DVBAUDIO_H_
|
#ifndef _DVBAUDIO_H_
|
||||||
@ -54,7 +39,7 @@ typedef enum {
|
|||||||
typedef struct audio_mixer {
|
typedef struct audio_mixer {
|
||||||
unsigned int volume_left;
|
unsigned int volume_left;
|
||||||
unsigned int volume_right;
|
unsigned int volume_right;
|
||||||
/* what else do we need? bass, pass-through, ... */
|
/* what else do we need? bass, pass-through, ... */
|
||||||
} audio_mixer_t;
|
} audio_mixer_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,21 +5,6 @@
|
|||||||
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
|
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
|
||||||
* & Marcus Metzler <marcus@convergence.de>
|
* & Marcus Metzler <marcus@convergence.de>
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Lesser Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DVBCA_H_
|
#ifndef _DVBCA_H_
|
||||||
@ -132,11 +117,6 @@ struct ca_descr {
|
|||||||
unsigned char cw[8];
|
unsigned char cw[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ca_pid {
|
|
||||||
unsigned int pid;
|
|
||||||
int index;/* -1 == disable*/
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CA_RESET _IO('o', 128)
|
#define CA_RESET _IO('o', 128)
|
||||||
#define CA_GET_CAP _IOR('o', 129, struct ca_caps)
|
#define CA_GET_CAP _IOR('o', 129, struct ca_caps)
|
||||||
#define CA_GET_SLOT_INFO _IOR('o', 130, struct ca_slot_info)
|
#define CA_GET_SLOT_INFO _IOR('o', 130, struct ca_slot_info)
|
||||||
@ -144,7 +124,6 @@ struct ca_pid {
|
|||||||
#define CA_GET_MSG _IOR('o', 132, struct ca_msg)
|
#define CA_GET_MSG _IOR('o', 132, struct ca_msg)
|
||||||
#define CA_SEND_MSG _IOW('o', 133, struct ca_msg)
|
#define CA_SEND_MSG _IOW('o', 133, struct ca_msg)
|
||||||
#define CA_SET_DESCR _IOW('o', 134, struct ca_descr)
|
#define CA_SET_DESCR _IOW('o', 134, struct ca_descr)
|
||||||
#define CA_SET_PID _IOW('o', 135, struct ca_pid)
|
|
||||||
|
|
||||||
#if !defined(__KERNEL__)
|
#if !defined(__KERNEL__)
|
||||||
|
|
||||||
@ -154,7 +133,6 @@ typedef struct ca_descr_info ca_descr_info_t;
|
|||||||
typedef struct ca_caps ca_caps_t;
|
typedef struct ca_caps ca_caps_t;
|
||||||
typedef struct ca_msg ca_msg_t;
|
typedef struct ca_msg ca_msg_t;
|
||||||
typedef struct ca_descr ca_descr_t;
|
typedef struct ca_descr ca_descr_t;
|
||||||
typedef struct ca_pid ca_pid_t;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -5,21 +5,6 @@
|
|||||||
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
|
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
|
||||||
* & Ralph Metzler <ralph@convergence.de>
|
* & Ralph Metzler <ralph@convergence.de>
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _UAPI_DVBDMX_H_
|
#ifndef _UAPI_DVBDMX_H_
|
||||||
|
@ -7,21 +7,6 @@
|
|||||||
* Holger Waechtler <holger@convergence.de>
|
* Holger Waechtler <holger@convergence.de>
|
||||||
* Andre Draszik <ad@convergence.de>
|
* Andre Draszik <ad@convergence.de>
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DVBFRONTEND_H_
|
#ifndef _DVBFRONTEND_H_
|
||||||
@ -282,7 +267,6 @@ enum fe_spectral_inversion {
|
|||||||
/**
|
/**
|
||||||
* enum fe_code_rate - Type of Forward Error Correction (FEC)
|
* enum fe_code_rate - Type of Forward Error Correction (FEC)
|
||||||
*
|
*
|
||||||
*
|
|
||||||
* @FEC_NONE: No Forward Error Correction Code
|
* @FEC_NONE: No Forward Error Correction Code
|
||||||
* @FEC_1_2: Forward Error Correction Code 1/2
|
* @FEC_1_2: Forward Error Correction Code 1/2
|
||||||
* @FEC_2_3: Forward Error Correction Code 2/3
|
* @FEC_2_3: Forward Error Correction Code 2/3
|
||||||
@ -296,6 +280,28 @@ enum fe_spectral_inversion {
|
|||||||
* @FEC_3_5: Forward Error Correction Code 3/5
|
* @FEC_3_5: Forward Error Correction Code 3/5
|
||||||
* @FEC_9_10: Forward Error Correction Code 9/10
|
* @FEC_9_10: Forward Error Correction Code 9/10
|
||||||
* @FEC_2_5: Forward Error Correction Code 2/5
|
* @FEC_2_5: Forward Error Correction Code 2/5
|
||||||
|
* @FEC_1_3: Forward Error Correction Code 1/3
|
||||||
|
* @FEC_1_4: Forward Error Correction Code 1/4
|
||||||
|
* @FEC_5_9: Forward Error Correction Code 5/9
|
||||||
|
* @FEC_7_9: Forward Error Correction Code 7/9
|
||||||
|
* @FEC_8_15: Forward Error Correction Code 8/15
|
||||||
|
* @FEC_11_15: Forward Error Correction Code 11/15
|
||||||
|
* @FEC_13_18: Forward Error Correction Code 13/18
|
||||||
|
* @FEC_9_20: Forward Error Correction Code 9/20
|
||||||
|
* @FEC_11_20: Forward Error Correction Code 11/20
|
||||||
|
* @FEC_23_36: Forward Error Correction Code 23/36
|
||||||
|
* @FEC_25_36: Forward Error Correction Code 25/36
|
||||||
|
* @FEC_13_45: Forward Error Correction Code 13/45
|
||||||
|
* @FEC_26_45: Forward Error Correction Code 26/45
|
||||||
|
* @FEC_28_45: Forward Error Correction Code 28/45
|
||||||
|
* @FEC_32_45: Forward Error Correction Code 32/45
|
||||||
|
* @FEC_77_90: Forward Error Correction Code 77/90
|
||||||
|
* @FEC_11_45: Forward Error Correction Code 11/45
|
||||||
|
* @FEC_4_15: Forward Error Correction Code 4/15
|
||||||
|
* @FEC_14_45: Forward Error Correction Code 14/45
|
||||||
|
* @FEC_7_15: Forward Error Correction Code 7/15
|
||||||
|
* @FEC_29_45: Forward Error Correction Code 29/45
|
||||||
|
* @FEC_31_45: Forward Error Correction Code 31/45
|
||||||
*
|
*
|
||||||
* Please note that not all FEC types are supported by a given standard.
|
* Please note that not all FEC types are supported by a given standard.
|
||||||
*/
|
*/
|
||||||
@ -313,8 +319,28 @@ enum fe_code_rate {
|
|||||||
FEC_3_5,
|
FEC_3_5,
|
||||||
FEC_9_10,
|
FEC_9_10,
|
||||||
FEC_2_5,
|
FEC_2_5,
|
||||||
FEC_1_4,
|
|
||||||
FEC_1_3,
|
FEC_1_3,
|
||||||
|
FEC_1_4,
|
||||||
|
FEC_5_9,
|
||||||
|
FEC_7_9,
|
||||||
|
FEC_8_15,
|
||||||
|
FEC_11_15,
|
||||||
|
FEC_13_18,
|
||||||
|
FEC_9_20,
|
||||||
|
FEC_11_20,
|
||||||
|
FEC_23_36,
|
||||||
|
FEC_25_36,
|
||||||
|
FEC_13_45,
|
||||||
|
FEC_26_45,
|
||||||
|
FEC_28_45,
|
||||||
|
FEC_32_45,
|
||||||
|
FEC_77_90,
|
||||||
|
FEC_11_45,
|
||||||
|
FEC_4_15,
|
||||||
|
FEC_14_45,
|
||||||
|
FEC_7_15,
|
||||||
|
FEC_29_45,
|
||||||
|
FEC_31_45,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -333,6 +359,16 @@ enum fe_code_rate {
|
|||||||
* @APSK_32: 32-APSK modulation
|
* @APSK_32: 32-APSK modulation
|
||||||
* @DQPSK: DQPSK modulation
|
* @DQPSK: DQPSK modulation
|
||||||
* @QAM_4_NR: 4-QAM-NR modulation
|
* @QAM_4_NR: 4-QAM-NR modulation
|
||||||
|
* @QAM_1024: 1024-QAM modulation
|
||||||
|
* @QAM_4096: 4096-QAM modulation
|
||||||
|
* @APSK_8_L: 8APSK-L modulation
|
||||||
|
* @APSK_16_L: 16APSK-L modulation
|
||||||
|
* @APSK_32_L: 32APSK-L modulation
|
||||||
|
* @APSK_64: 64APSK modulation
|
||||||
|
* @APSK_64_L: 64APSK-L modulation
|
||||||
|
* @APSK_128: 128APSK modulation
|
||||||
|
* @APSK_256: 256APSK modulation
|
||||||
|
* @APSK_256_L: 256APSK-L modulation
|
||||||
*
|
*
|
||||||
* Please note that not all modulations are supported by a given standard.
|
* Please note that not all modulations are supported by a given standard.
|
||||||
*
|
*
|
||||||
@ -352,9 +388,16 @@ enum fe_modulation {
|
|||||||
APSK_32,
|
APSK_32,
|
||||||
DQPSK,
|
DQPSK,
|
||||||
QAM_4_NR,
|
QAM_4_NR,
|
||||||
|
QAM_1024,
|
||||||
|
QAM_4096,
|
||||||
|
APSK_8_L,
|
||||||
|
APSK_16_L,
|
||||||
|
APSK_32_L,
|
||||||
APSK_64,
|
APSK_64,
|
||||||
|
APSK_64_L,
|
||||||
APSK_128,
|
APSK_128,
|
||||||
APSK_256,
|
APSK_256,
|
||||||
|
APSK_256_L,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -409,6 +452,7 @@ enum fe_transmit_mode {
|
|||||||
* @GUARD_INTERVAL_PN420: PN length 420 (1/4)
|
* @GUARD_INTERVAL_PN420: PN length 420 (1/4)
|
||||||
* @GUARD_INTERVAL_PN595: PN length 595 (1/6)
|
* @GUARD_INTERVAL_PN595: PN length 595 (1/6)
|
||||||
* @GUARD_INTERVAL_PN945: PN length 945 (1/9)
|
* @GUARD_INTERVAL_PN945: PN length 945 (1/9)
|
||||||
|
* @GUARD_INTERVAL_1_64: Guard interval 1/64
|
||||||
*
|
*
|
||||||
* Please note that not all guard intervals are supported by a given standard.
|
* Please note that not all guard intervals are supported by a given standard.
|
||||||
*/
|
*/
|
||||||
@ -424,6 +468,7 @@ enum fe_guard_interval {
|
|||||||
GUARD_INTERVAL_PN420,
|
GUARD_INTERVAL_PN420,
|
||||||
GUARD_INTERVAL_PN595,
|
GUARD_INTERVAL_PN595,
|
||||||
GUARD_INTERVAL_PN945,
|
GUARD_INTERVAL_PN945,
|
||||||
|
GUARD_INTERVAL_1_64,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -577,6 +622,9 @@ enum fe_pilot {
|
|||||||
* @ROLLOFF_20: Roloff factor: α=20%
|
* @ROLLOFF_20: Roloff factor: α=20%
|
||||||
* @ROLLOFF_25: Roloff factor: α=25%
|
* @ROLLOFF_25: Roloff factor: α=25%
|
||||||
* @ROLLOFF_AUTO: Auto-detect the roloff factor.
|
* @ROLLOFF_AUTO: Auto-detect the roloff factor.
|
||||||
|
* @ROLLOFF_15: Rolloff factor: α=15%
|
||||||
|
* @ROLLOFF_10: Rolloff factor: α=10%
|
||||||
|
* @ROLLOFF_5: Rolloff factor: α=5%
|
||||||
*
|
*
|
||||||
* .. note:
|
* .. note:
|
||||||
*
|
*
|
||||||
@ -603,6 +651,8 @@ enum fe_rolloff {
|
|||||||
* Cable TV: DVB-C following ITU-T J.83 Annex B spec (ClearQAM)
|
* Cable TV: DVB-C following ITU-T J.83 Annex B spec (ClearQAM)
|
||||||
* @SYS_DVBC_ANNEX_C:
|
* @SYS_DVBC_ANNEX_C:
|
||||||
* Cable TV: DVB-C following ITU-T J.83 Annex C spec
|
* Cable TV: DVB-C following ITU-T J.83 Annex C spec
|
||||||
|
* @SYS_DVBC2:
|
||||||
|
* Cable TV: DVB-C2
|
||||||
* @SYS_ISDBC:
|
* @SYS_ISDBC:
|
||||||
* Cable TV: ISDB-C (no drivers yet)
|
* Cable TV: ISDB-C (no drivers yet)
|
||||||
* @SYS_DVBT:
|
* @SYS_DVBT:
|
||||||
@ -620,7 +670,7 @@ enum fe_rolloff {
|
|||||||
* @SYS_DVBS:
|
* @SYS_DVBS:
|
||||||
* Satellite TV: DVB-S
|
* Satellite TV: DVB-S
|
||||||
* @SYS_DVBS2:
|
* @SYS_DVBS2:
|
||||||
* Satellite TV: DVB-S2
|
* Satellite TV: DVB-S2 and DVB-S2X
|
||||||
* @SYS_TURBO:
|
* @SYS_TURBO:
|
||||||
* Satellite TV: DVB-S Turbo
|
* Satellite TV: DVB-S Turbo
|
||||||
* @SYS_ISDBS:
|
* @SYS_ISDBS:
|
||||||
@ -730,7 +780,7 @@ enum atscmh_rs_frame_mode {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum atscmh_rs_code_mode
|
* enum atscmh_rs_code_mode - ATSC-M/H Reed Solomon modes
|
||||||
* @ATSCMH_RSCODE_211_187: Reed Solomon code (211,187).
|
* @ATSCMH_RSCODE_211_187: Reed Solomon code (211,187).
|
||||||
* @ATSCMH_RSCODE_223_187: Reed Solomon code (223,187).
|
* @ATSCMH_RSCODE_223_187: Reed Solomon code (223,187).
|
||||||
* @ATSCMH_RSCODE_235_187: Reed Solomon code (235,187).
|
* @ATSCMH_RSCODE_235_187: Reed Solomon code (235,187).
|
||||||
|
@ -5,21 +5,6 @@
|
|||||||
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
|
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
|
||||||
* & Ralph Metzler <ralph@convergence.de>
|
* & Ralph Metzler <ralph@convergence.de>
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DVBNET_H_
|
#ifndef _DVBNET_H_
|
||||||
|
@ -7,21 +7,6 @@
|
|||||||
* Copyright (C) 2001 Ralph Metzler <ralph@convergence.de>
|
* Copyright (C) 2001 Ralph Metzler <ralph@convergence.de>
|
||||||
* & Marcus Metzler <marcus@convergence.de>
|
* & Marcus Metzler <marcus@convergence.de>
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Lesser Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DVBOSD_H_
|
#ifndef _DVBOSD_H_
|
||||||
|
@ -4,27 +4,12 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2000 Holger Waechtler <holger@convergence.de>
|
* Copyright (C) 2000 Holger Waechtler <holger@convergence.de>
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _DVBVERSION_H_
|
#ifndef _DVBVERSION_H_
|
||||||
#define _DVBVERSION_H_
|
#define _DVBVERSION_H_
|
||||||
|
|
||||||
#define DVB_API_VERSION 5
|
#define DVB_API_VERSION 5
|
||||||
#define DVB_API_VERSION_MINOR 11
|
#define DVB_API_VERSION_MINOR 12
|
||||||
|
|
||||||
#endif /*_DVBVERSION_H_*/
|
#endif /*_DVBVERSION_H_*/
|
||||||
|
@ -7,21 +7,6 @@
|
|||||||
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
|
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
|
||||||
* & Ralph Metzler <ralph@convergence.de>
|
* & Ralph Metzler <ralph@convergence.de>
|
||||||
* for convergence integrated media GmbH
|
* for convergence integrated media GmbH
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _UAPI_DVBVIDEO_H_
|
#ifndef _UAPI_DVBVIDEO_H_
|
||||||
|
@ -1,246 +0,0 @@
|
|||||||
/*
|
|
||||||
* dvb_filter.h
|
|
||||||
*
|
|
||||||
* Copyright (C) 2003 Convergence GmbH
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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 Lesser General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _DVB_FILTER_H_
|
|
||||||
#define _DVB_FILTER_H_
|
|
||||||
|
|
||||||
#include <linux/slab.h>
|
|
||||||
|
|
||||||
#include "demux.h"
|
|
||||||
|
|
||||||
typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
|
|
||||||
|
|
||||||
struct dvb_filter_pes2ts {
|
|
||||||
unsigned char buf[188];
|
|
||||||
unsigned char cc;
|
|
||||||
dvb_filter_pes2ts_cb_t *cb;
|
|
||||||
void *priv;
|
|
||||||
};
|
|
||||||
|
|
||||||
void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
|
|
||||||
dvb_filter_pes2ts_cb_t *cb, void *priv);
|
|
||||||
|
|
||||||
int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
|
|
||||||
int len, int payload_start);
|
|
||||||
|
|
||||||
|
|
||||||
#define PROG_STREAM_MAP 0xBC
|
|
||||||
#define PRIVATE_STREAM1 0xBD
|
|
||||||
#define PADDING_STREAM 0xBE
|
|
||||||
#define PRIVATE_STREAM2 0xBF
|
|
||||||
#define AUDIO_STREAM_S 0xC0
|
|
||||||
#define AUDIO_STREAM_E 0xDF
|
|
||||||
#define VIDEO_STREAM_S 0xE0
|
|
||||||
#define VIDEO_STREAM_E 0xEF
|
|
||||||
#define ECM_STREAM 0xF0
|
|
||||||
#define EMM_STREAM 0xF1
|
|
||||||
#define DSM_CC_STREAM 0xF2
|
|
||||||
#define ISO13522_STREAM 0xF3
|
|
||||||
#define PROG_STREAM_DIR 0xFF
|
|
||||||
|
|
||||||
#define DVB_PICTURE_START 0x00
|
|
||||||
#define DVB_USER_START 0xb2
|
|
||||||
#define DVB_SEQUENCE_HEADER 0xb3
|
|
||||||
#define DVB_SEQUENCE_ERROR 0xb4
|
|
||||||
#define DVB_EXTENSION_START 0xb5
|
|
||||||
#define DVB_SEQUENCE_END 0xb7
|
|
||||||
#define DVB_GOP_START 0xb8
|
|
||||||
#define DVB_EXCEPT_SLICE 0xb0
|
|
||||||
|
|
||||||
#define SEQUENCE_EXTENSION 0x01
|
|
||||||
#define SEQUENCE_DISPLAY_EXTENSION 0x02
|
|
||||||
#define PICTURE_CODING_EXTENSION 0x08
|
|
||||||
#define QUANT_MATRIX_EXTENSION 0x03
|
|
||||||
#define PICTURE_DISPLAY_EXTENSION 0x07
|
|
||||||
|
|
||||||
#define I_FRAME 0x01
|
|
||||||
#define B_FRAME 0x02
|
|
||||||
#define P_FRAME 0x03
|
|
||||||
|
|
||||||
/* Initialize sequence_data */
|
|
||||||
#define INIT_HORIZONTAL_SIZE 720
|
|
||||||
#define INIT_VERTICAL_SIZE 576
|
|
||||||
#define INIT_ASPECT_RATIO 0x02
|
|
||||||
#define INIT_FRAME_RATE 0x03
|
|
||||||
#define INIT_DISP_HORIZONTAL_SIZE 540
|
|
||||||
#define INIT_DISP_VERTICAL_SIZE 576
|
|
||||||
|
|
||||||
|
|
||||||
//flags2
|
|
||||||
#define PTS_DTS_FLAGS 0xC0
|
|
||||||
#define ESCR_FLAG 0x20
|
|
||||||
#define ES_RATE_FLAG 0x10
|
|
||||||
#define DSM_TRICK_FLAG 0x08
|
|
||||||
#define ADD_CPY_FLAG 0x04
|
|
||||||
#define PES_CRC_FLAG 0x02
|
|
||||||
#define PES_EXT_FLAG 0x01
|
|
||||||
|
|
||||||
//pts_dts flags
|
|
||||||
#define PTS_ONLY 0x80
|
|
||||||
#define PTS_DTS 0xC0
|
|
||||||
|
|
||||||
#define TS_SIZE 188
|
|
||||||
#define TRANS_ERROR 0x80
|
|
||||||
#define PAY_START 0x40
|
|
||||||
#define TRANS_PRIO 0x20
|
|
||||||
#define PID_MASK_HI 0x1F
|
|
||||||
//flags
|
|
||||||
#define TRANS_SCRMBL1 0x80
|
|
||||||
#define TRANS_SCRMBL2 0x40
|
|
||||||
#define ADAPT_FIELD 0x20
|
|
||||||
#define PAYLOAD 0x10
|
|
||||||
#define COUNT_MASK 0x0F
|
|
||||||
|
|
||||||
// adaptation flags
|
|
||||||
#define DISCON_IND 0x80
|
|
||||||
#define RAND_ACC_IND 0x40
|
|
||||||
#define ES_PRI_IND 0x20
|
|
||||||
#define PCR_FLAG 0x10
|
|
||||||
#define OPCR_FLAG 0x08
|
|
||||||
#define SPLICE_FLAG 0x04
|
|
||||||
#define TRANS_PRIV 0x02
|
|
||||||
#define ADAP_EXT_FLAG 0x01
|
|
||||||
|
|
||||||
// adaptation extension flags
|
|
||||||
#define LTW_FLAG 0x80
|
|
||||||
#define PIECE_RATE 0x40
|
|
||||||
#define SEAM_SPLICE 0x20
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_PLENGTH 0xFFFF
|
|
||||||
#define MMAX_PLENGTH (256*MAX_PLENGTH)
|
|
||||||
|
|
||||||
#ifndef IPACKS
|
|
||||||
#define IPACKS 2048
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct ipack {
|
|
||||||
int size;
|
|
||||||
int found;
|
|
||||||
u8 *buf;
|
|
||||||
u8 cid;
|
|
||||||
u32 plength;
|
|
||||||
u8 plen[2];
|
|
||||||
u8 flag1;
|
|
||||||
u8 flag2;
|
|
||||||
u8 hlength;
|
|
||||||
u8 pts[5];
|
|
||||||
u16 *pid;
|
|
||||||
int mpeg;
|
|
||||||
u8 check;
|
|
||||||
int which;
|
|
||||||
int done;
|
|
||||||
void *data;
|
|
||||||
void (*func)(u8 *buf, int size, void *priv);
|
|
||||||
int count;
|
|
||||||
int repack_subids;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dvb_video_info {
|
|
||||||
u32 horizontal_size;
|
|
||||||
u32 vertical_size;
|
|
||||||
u32 aspect_ratio;
|
|
||||||
u32 framerate;
|
|
||||||
u32 video_format;
|
|
||||||
u32 bit_rate;
|
|
||||||
u32 comp_bit_rate;
|
|
||||||
u32 vbv_buffer_size;
|
|
||||||
s16 vbv_delay;
|
|
||||||
u32 CSPF;
|
|
||||||
u32 off;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define OFF_SIZE 4
|
|
||||||
#define FIRST_FIELD 0
|
|
||||||
#define SECOND_FIELD 1
|
|
||||||
#define VIDEO_FRAME_PICTURE 0x03
|
|
||||||
|
|
||||||
struct mpg_picture {
|
|
||||||
int channel;
|
|
||||||
struct dvb_video_info vinfo;
|
|
||||||
u32 *sequence_gop_header;
|
|
||||||
u32 *picture_header;
|
|
||||||
s32 time_code;
|
|
||||||
int low_delay;
|
|
||||||
int closed_gop;
|
|
||||||
int broken_link;
|
|
||||||
int sequence_header_flag;
|
|
||||||
int gop_flag;
|
|
||||||
int sequence_end_flag;
|
|
||||||
|
|
||||||
u8 profile_and_level;
|
|
||||||
s32 picture_coding_parameter;
|
|
||||||
u32 matrix[32];
|
|
||||||
s8 matrix_change_flag;
|
|
||||||
|
|
||||||
u8 picture_header_parameter;
|
|
||||||
/* bit 0 - 2: bwd f code
|
|
||||||
bit 3 : fpb vector
|
|
||||||
bit 4 - 6: fwd f code
|
|
||||||
bit 7 : fpf vector */
|
|
||||||
|
|
||||||
int mpeg1_flag;
|
|
||||||
int progressive_sequence;
|
|
||||||
int sequence_display_extension_flag;
|
|
||||||
u32 sequence_header_data;
|
|
||||||
s16 last_frame_centre_horizontal_offset;
|
|
||||||
s16 last_frame_centre_vertical_offset;
|
|
||||||
|
|
||||||
u32 pts[2]; /* [0] 1st field, [1] 2nd field */
|
|
||||||
int top_field_first;
|
|
||||||
int repeat_first_field;
|
|
||||||
int progressive_frame;
|
|
||||||
int bank;
|
|
||||||
int forward_bank;
|
|
||||||
int backward_bank;
|
|
||||||
int compress;
|
|
||||||
s16 frame_centre_horizontal_offset[OFF_SIZE];
|
|
||||||
/* [0-2] 1st field, [3] 2nd field */
|
|
||||||
s16 frame_centre_vertical_offset[OFF_SIZE];
|
|
||||||
/* [0-2] 1st field, [3] 2nd field */
|
|
||||||
s16 temporal_reference[2];
|
|
||||||
/* [0] 1st field, [1] 2nd field */
|
|
||||||
|
|
||||||
s8 picture_coding_type[2];
|
|
||||||
/* [0] 1st field, [1] 2nd field */
|
|
||||||
s8 picture_structure[2];
|
|
||||||
/* [0] 1st field, [1] 2nd field */
|
|
||||||
s8 picture_display_extension_flag[2];
|
|
||||||
/* [0] 1st field, [1] 2nd field */
|
|
||||||
/* picture_display_extenion() 0:no 1:exit*/
|
|
||||||
s8 pts_flag[2];
|
|
||||||
/* [0] 1st field, [1] 2nd field */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dvb_audio_info {
|
|
||||||
int layer;
|
|
||||||
u32 bit_rate;
|
|
||||||
u32 frequency;
|
|
||||||
u32 mode;
|
|
||||||
u32 mode_extension ;
|
|
||||||
u32 emphasis;
|
|
||||||
u32 framesize;
|
|
||||||
u32 off;
|
|
||||||
};
|
|
||||||
|
|
||||||
int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr);
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -369,6 +369,10 @@ struct dvb_frontend_internal_info {
|
|||||||
* allocated by the driver.
|
* allocated by the driver.
|
||||||
* @init: callback function used to initialize the tuner device.
|
* @init: callback function used to initialize the tuner device.
|
||||||
* @sleep: callback function used to put the tuner to sleep.
|
* @sleep: callback function used to put the tuner to sleep.
|
||||||
|
* @suspend: callback function used to inform that the Kernel will
|
||||||
|
* suspend.
|
||||||
|
* @resume: callback function used to inform that the Kernel is
|
||||||
|
* resuming from suspend.
|
||||||
* @write: callback function used by some demod legacy drivers to
|
* @write: callback function used by some demod legacy drivers to
|
||||||
* allow other drivers to write data into their registers.
|
* allow other drivers to write data into their registers.
|
||||||
* Should not be used on new drivers.
|
* Should not be used on new drivers.
|
||||||
@ -438,7 +442,6 @@ struct dvb_frontend_internal_info {
|
|||||||
* @analog_ops: pointer to &struct analog_demod_ops
|
* @analog_ops: pointer to &struct analog_demod_ops
|
||||||
*/
|
*/
|
||||||
struct dvb_frontend_ops {
|
struct dvb_frontend_ops {
|
||||||
|
|
||||||
struct dvb_frontend_internal_info info;
|
struct dvb_frontend_internal_info info;
|
||||||
|
|
||||||
u8 delsys[MAX_DELSYS];
|
u8 delsys[MAX_DELSYS];
|
||||||
@ -449,6 +452,8 @@ struct dvb_frontend_ops {
|
|||||||
|
|
||||||
int (*init)(struct dvb_frontend* fe);
|
int (*init)(struct dvb_frontend* fe);
|
||||||
int (*sleep)(struct dvb_frontend* fe);
|
int (*sleep)(struct dvb_frontend* fe);
|
||||||
|
int (*suspend)(struct dvb_frontend *fe);
|
||||||
|
int (*resume)(struct dvb_frontend *fe);
|
||||||
|
|
||||||
int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
|
int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
|
||||||
|
|
||||||
@ -765,7 +770,8 @@ void dvb_frontend_detach(struct dvb_frontend *fe);
|
|||||||
* &dvb_frontend_ops.tuner_ops.suspend\(\) is available, it calls it. Otherwise,
|
* &dvb_frontend_ops.tuner_ops.suspend\(\) is available, it calls it. Otherwise,
|
||||||
* it will call &dvb_frontend_ops.tuner_ops.sleep\(\), if available.
|
* it will call &dvb_frontend_ops.tuner_ops.sleep\(\), if available.
|
||||||
*
|
*
|
||||||
* It will also call &dvb_frontend_ops.sleep\(\) to put the demod to suspend.
|
* It will also call &dvb_frontend_ops.suspend\(\) to put the demod to suspend,
|
||||||
|
* if available. Otherwise it will call &dvb_frontend_ops.sleep\(\).
|
||||||
*
|
*
|
||||||
* The drivers should also call dvb_frontend_suspend\(\) as part of their
|
* The drivers should also call dvb_frontend_suspend\(\) as part of their
|
||||||
* handler for the &device_driver.suspend\(\).
|
* handler for the &device_driver.suspend\(\).
|
||||||
@ -779,7 +785,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe);
|
|||||||
*
|
*
|
||||||
* This function resumes the usual operation of the tuner after resume.
|
* This function resumes the usual operation of the tuner after resume.
|
||||||
*
|
*
|
||||||
* In order to resume the frontend, it calls the demod &dvb_frontend_ops.init\(\).
|
* In order to resume the frontend, it calls the demod
|
||||||
|
* &dvb_frontend_ops.resume\(\) if available. Otherwise it calls demod
|
||||||
|
* &dvb_frontend_ops.init\(\).
|
||||||
*
|
*
|
||||||
* If &dvb_frontend_ops.tuner_ops.resume\(\) is available, It, it calls it.
|
* If &dvb_frontend_ops.tuner_ops.resume\(\) is available, It, it calls it.
|
||||||
* Otherwise,t will call &dvb_frontend_ops.tuner_ops.init\(\), if available.
|
* Otherwise,t will call &dvb_frontend_ops.tuner_ops.init\(\), if available.
|
||||||
|
@ -19,13 +19,11 @@
|
|||||||
#define _DVB_NET_H_
|
#define _DVB_NET_H_
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/netdevice.h>
|
|
||||||
#include <linux/inetdevice.h>
|
|
||||||
#include <linux/etherdevice.h>
|
|
||||||
#include <linux/skbuff.h>
|
|
||||||
|
|
||||||
#include <media/dvbdev.h>
|
#include <media/dvbdev.h>
|
||||||
|
|
||||||
|
struct net_device;
|
||||||
|
|
||||||
#define DVB_NET_DEVICES_MAX 10
|
#define DVB_NET_DEVICES_MAX 10
|
||||||
|
|
||||||
#ifdef CONFIG_DVB_NET
|
#ifdef CONFIG_DVB_NET
|
||||||
@ -41,6 +39,9 @@
|
|||||||
* @exit: flag to indicate when the device is being removed.
|
* @exit: flag to indicate when the device is being removed.
|
||||||
* @demux: pointer to &struct dmx_demux.
|
* @demux: pointer to &struct dmx_demux.
|
||||||
* @ioctl_mutex: protect access to this struct.
|
* @ioctl_mutex: protect access to this struct.
|
||||||
|
* @remove_mutex: mutex that avoids a race condition between a callback
|
||||||
|
* called when the hardware is disconnected and the
|
||||||
|
* file_operations of dvb_net.
|
||||||
*
|
*
|
||||||
* Currently, the core supports up to %DVB_NET_DEVICES_MAX (10) network
|
* Currently, the core supports up to %DVB_NET_DEVICES_MAX (10) network
|
||||||
* devices.
|
* devices.
|
||||||
@ -53,6 +54,7 @@ struct dvb_net {
|
|||||||
unsigned int exit:1;
|
unsigned int exit:1;
|
||||||
struct dmx_demux *demux;
|
struct dmx_demux *demux;
|
||||||
struct mutex ioctl_mutex;
|
struct mutex ioctl_mutex;
|
||||||
|
struct mutex remove_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -214,7 +214,7 @@ extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
|
|||||||
* @buf: Buffer to write.
|
* @buf: Buffer to write.
|
||||||
* @len: Length of buffer (currently limited to 65535 bytes max).
|
* @len: Length of buffer (currently limited to 65535 bytes max).
|
||||||
*
|
*
|
||||||
* Return: Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
|
* Return: Number of bytes written, or -EFAULT, -ENOMEM, -EINVAL.
|
||||||
*/
|
*/
|
||||||
extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8 *buf,
|
extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8 *buf,
|
||||||
size_t len);
|
size_t len);
|
||||||
|
@ -27,11 +27,15 @@
|
|||||||
|
|
||||||
#define DVB_MAJOR 212
|
#define DVB_MAJOR 212
|
||||||
|
|
||||||
|
#if 0
|
||||||
#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
|
#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
|
||||||
#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
|
#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
|
||||||
#else
|
#else
|
||||||
#define DVB_MAX_ADAPTERS 64
|
#define DVB_MAX_ADAPTERS 64
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DVB_MAX_ADAPTERS 64
|
||||||
|
|
||||||
#define DVB_UNSET (-1)
|
#define DVB_UNSET (-1)
|
||||||
|
|
||||||
@ -92,7 +96,11 @@ struct dvb_frontend;
|
|||||||
* @device: pointer to struct device
|
* @device: pointer to struct device
|
||||||
* @module: pointer to struct module
|
* @module: pointer to struct module
|
||||||
* @mfe_shared: indicates mutually exclusive frontends.
|
* @mfe_shared: indicates mutually exclusive frontends.
|
||||||
* Use of this flag is currently deprecated.
|
* 1 = legacy exclusion behavior: blocking any open() call
|
||||||
|
* 2 = enhanced exclusion behavior, emulating the standard
|
||||||
|
* behavior of busy frontends: allowing read-only sharing
|
||||||
|
* and otherwise returning immediately with -EBUSY when any
|
||||||
|
* of the frontends is already opened with write access.
|
||||||
* @mfe_dvbdev: Frontend device in use, in the case of MFE
|
* @mfe_dvbdev: Frontend device in use, in the case of MFE
|
||||||
* @mfe_lock: Lock to prevent using the other frontends when MFE is
|
* @mfe_lock: Lock to prevent using the other frontends when MFE is
|
||||||
* used.
|
* used.
|
||||||
@ -131,6 +139,7 @@ struct dvb_adapter {
|
|||||||
* struct dvb_device - represents a DVB device node
|
* struct dvb_device - represents a DVB device node
|
||||||
*
|
*
|
||||||
* @list_head: List head with all DVB devices
|
* @list_head: List head with all DVB devices
|
||||||
|
* @ref: reference count for this device
|
||||||
* @fops: pointer to struct file_operations
|
* @fops: pointer to struct file_operations
|
||||||
* @adapter: pointer to the adapter that holds this device node
|
* @adapter: pointer to the adapter that holds this device node
|
||||||
* @type: type of the device, as defined by &enum dvb_device_type.
|
* @type: type of the device, as defined by &enum dvb_device_type.
|
||||||
@ -161,6 +170,7 @@ struct dvb_adapter {
|
|||||||
*/
|
*/
|
||||||
struct dvb_device {
|
struct dvb_device {
|
||||||
struct list_head list_head;
|
struct list_head list_head;
|
||||||
|
struct kref ref;
|
||||||
const struct file_operations *fops;
|
const struct file_operations *fops;
|
||||||
struct dvb_adapter *adapter;
|
struct dvb_adapter *adapter;
|
||||||
enum dvb_device_type type;
|
enum dvb_device_type type;
|
||||||
@ -172,6 +182,7 @@ struct dvb_device {
|
|||||||
int readers;
|
int readers;
|
||||||
int writers;
|
int writers;
|
||||||
int users;
|
int users;
|
||||||
|
struct mutex lock;
|
||||||
|
|
||||||
wait_queue_head_t wait_queue;
|
wait_queue_head_t wait_queue;
|
||||||
/* don't really need those !? -- FIXME: use video_usercopy */
|
/* don't really need those !? -- FIXME: use video_usercopy */
|
||||||
@ -192,6 +203,35 @@ struct dvb_device {
|
|||||||
void *priv;
|
void *priv;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct dvbdevfops_node - fops nodes registered in dvbdevfops_list
|
||||||
|
*
|
||||||
|
* @fops: Dynamically allocated fops for ->owner registration
|
||||||
|
* @type: type of dvb_device
|
||||||
|
* @template: dvb_device used for registration
|
||||||
|
* @list_head: list_head for dvbdevfops_list
|
||||||
|
*/
|
||||||
|
struct dvbdevfops_node {
|
||||||
|
struct file_operations *fops;
|
||||||
|
enum dvb_device_type type;
|
||||||
|
const struct dvb_device *template;
|
||||||
|
struct list_head list_head;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dvb_device_get - Increase dvb_device reference
|
||||||
|
*
|
||||||
|
* @dvbdev: pointer to struct dvb_device
|
||||||
|
*/
|
||||||
|
struct dvb_device *dvb_device_get(struct dvb_device *dvbdev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dvb_device_put - Decrease dvb_device reference
|
||||||
|
*
|
||||||
|
* @dvbdev: pointer to struct dvb_device
|
||||||
|
*/
|
||||||
|
void dvb_device_put(struct dvb_device *dvbdev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dvb_register_adapter - Registers a new DVB adapter
|
* dvb_register_adapter - Registers a new DVB adapter
|
||||||
*
|
*
|
||||||
@ -236,29 +276,16 @@ int dvb_register_device(struct dvb_adapter *adap,
|
|||||||
/**
|
/**
|
||||||
* dvb_remove_device - Remove a registered DVB device
|
* dvb_remove_device - Remove a registered DVB device
|
||||||
*
|
*
|
||||||
* This does not free memory. To do that, call dvb_free_device().
|
|
||||||
*
|
|
||||||
* @dvbdev: pointer to struct dvb_device
|
* @dvbdev: pointer to struct dvb_device
|
||||||
|
*
|
||||||
|
* This does not free memory. dvb_free_device() will do that when
|
||||||
|
* reference counter is empty
|
||||||
*/
|
*/
|
||||||
void dvb_remove_device(struct dvb_device *dvbdev);
|
void dvb_remove_device(struct dvb_device *dvbdev);
|
||||||
|
|
||||||
/**
|
|
||||||
* dvb_free_device - Free memory occupied by a DVB device.
|
|
||||||
*
|
|
||||||
* Call dvb_unregister_device() before calling this function.
|
|
||||||
*
|
|
||||||
* @dvbdev: pointer to struct dvb_device
|
|
||||||
*/
|
|
||||||
void dvb_free_device(struct dvb_device *dvbdev);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dvb_unregister_device - Unregisters a DVB device
|
* dvb_unregister_device - Unregisters a DVB device
|
||||||
*
|
*
|
||||||
* This is a combination of dvb_remove_device() and dvb_free_device().
|
|
||||||
* Using this function is usually a mistake, and is often an indicator
|
|
||||||
* for a use-after-free bug (when a userspace process keeps a file
|
|
||||||
* handle to a detached device).
|
|
||||||
*
|
|
||||||
* @dvbdev: pointer to struct dvb_device
|
* @dvbdev: pointer to struct dvb_device
|
||||||
*/
|
*/
|
||||||
void dvb_unregister_device(struct dvb_device *dvbdev);
|
void dvb_unregister_device(struct dvb_device *dvbdev);
|
||||||
@ -326,7 +353,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
|
|||||||
int dvb_generic_open(struct inode *inode, struct file *file);
|
int dvb_generic_open(struct inode *inode, struct file *file);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dvb_generic_close - Digital TV close function, used by DVB devices
|
* dvb_generic_release - Digital TV close function, used by DVB devices
|
||||||
*
|
*
|
||||||
* @inode: pointer to &struct inode.
|
* @inode: pointer to &struct inode.
|
||||||
* @file: pointer to &struct file.
|
* @file: pointer to &struct file.
|
||||||
@ -421,11 +448,12 @@ void dvb_module_release(struct i2c_client *client);
|
|||||||
|
|
||||||
/* Legacy generic DVB attach function. */
|
/* Legacy generic DVB attach function. */
|
||||||
#ifdef CONFIG_MEDIA_ATTACH
|
#ifdef CONFIG_MEDIA_ATTACH
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dvb_attach - attaches a DVB frontend into the DVB core.
|
* dvb_attach - attaches a DVB frontend into the DVB core.
|
||||||
*
|
*
|
||||||
* @FUNCTION: function on a frontend module to be called.
|
* @FUNCTION: function on a frontend module to be called.
|
||||||
* @ARGS...: @FUNCTION arguments.
|
* @ARGS: @FUNCTION arguments.
|
||||||
*
|
*
|
||||||
* This ancillary function loads a frontend module in runtime and runs
|
* This ancillary function loads a frontend module in runtime and runs
|
||||||
* the @FUNCTION function there, with @ARGS.
|
* the @FUNCTION function there, with @ARGS.
|
||||||
|
@ -3,8 +3,11 @@ The libdddvb provides a userspace library to simplify tuning and
|
|||||||
CI use. It detects DVB cards and their capabilities and selects
|
CI use. It detects DVB cards and their capabilities and selects
|
||||||
free frontends depending on a given delivery system.
|
free frontends depending on a given delivery system.
|
||||||
|
|
||||||
|
Please note that the libdddvb library and the ddzap tool are
|
||||||
|
provided as examples and for testing purposes.
|
||||||
|
|
||||||
In order to install the libdddvb library you need the dvben50221.
|
|
||||||
|
In order to install the libdddvb library you need the libdvben50221.
|
||||||
|
|
||||||
On an Ubuntu and other Debian based system you can install it like this:
|
On an Ubuntu and other Debian based system you can install it like this:
|
||||||
|
|
||||||
|
@ -17,3 +17,19 @@ Tuner5=5,984
|
|||||||
Tuner6=6,1020
|
Tuner6=6,1020
|
||||||
Tuner7=7,1056
|
Tuner7=7,1056
|
||||||
Tuner8=8,1092
|
Tuner8=8,1092
|
||||||
|
Tuner9=9,1128
|
||||||
|
Tuner10=10,1164
|
||||||
|
Tuner11=11,1256
|
||||||
|
Tuner12=12,1292
|
||||||
|
Tuner13=13,1328
|
||||||
|
Tuner14=14,1364
|
||||||
|
Tuner15=15,1458
|
||||||
|
Tuner16=16,1494
|
||||||
|
Tuner17=17,1530
|
||||||
|
Tuner18=18,1566
|
||||||
|
Tuner19=19,1602
|
||||||
|
Tuner20=20,1638
|
||||||
|
Tuner21=21,1716
|
||||||
|
Tuner22=22,1752
|
||||||
|
Tuner23=23,1788
|
||||||
|
Tuner24=24,1824
|
||||||
|
36
lib/config/dddvb.conf.example
Normal file
36
lib/config/dddvb.conf.example
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
[scif]
|
||||||
|
# SCIF Settings
|
||||||
|
# Manufacturer = nn : Index to selected manaufacturer (only used in config webpage)
|
||||||
|
# Unit = nn : Index to selected unit (only used in config webpage)
|
||||||
|
# Type = nn : Type of unit: 1: EN 50494, 2: TS 50607
|
||||||
|
# TunerN = Slot,Frequency[,Pin] Slot = 1..nn, Frequency = 950..2150, Pin = 0-255
|
||||||
|
# Slot = 0 (no SCIF)
|
||||||
|
# Slot = 1..8 for EN 50494, 1..32 for TS 50607
|
||||||
|
Type=0
|
||||||
|
Tuner1=0
|
||||||
|
Tuner2=0
|
||||||
|
Tuner3=0
|
||||||
|
Tuner4=0
|
||||||
|
Tuner5=0
|
||||||
|
Tuner6=0
|
||||||
|
Tuner7=0
|
||||||
|
Tuner8=0
|
||||||
|
[LNB]
|
||||||
|
#
|
||||||
|
# LNB 1 Setting
|
||||||
|
#
|
||||||
|
Tuner=1
|
||||||
|
Source=1
|
||||||
|
LOF1=9750
|
||||||
|
LOF2=10600
|
||||||
|
LOFS=11700
|
||||||
|
|
||||||
|
[LNB]
|
||||||
|
#
|
||||||
|
# LNB 2 Setting
|
||||||
|
#
|
||||||
|
Tuner=2
|
||||||
|
Source=1
|
||||||
|
LOF1=9750
|
||||||
|
LOF2=10600
|
||||||
|
LOFS=11700
|
37
lib/config/dddvb.conf.example_uni
Normal file
37
lib/config/dddvb.conf.example_uni
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
[CA]
|
||||||
|
family=unix
|
||||||
|
[scif]
|
||||||
|
# SCIF Settings
|
||||||
|
# Manufacturer = nn : Index to selected manaufacturer (only used in config webpage)
|
||||||
|
# Unit = nn : Index to selected unit (only used in config webpage)
|
||||||
|
# Type = nn : Type of unit: 1: EN 50494, 2: TS 50607
|
||||||
|
# TunerN = Slot,Frequency[,Pin] Slot = 1..nn, Frequency = 950..2150, Pin = 0-255
|
||||||
|
# Slot = 0 (no SCIF)
|
||||||
|
# Slot = 1..8 for EN 50494, 1..32 for TS 50607
|
||||||
|
Manufacturer=0
|
||||||
|
Unit=8
|
||||||
|
Type=2
|
||||||
|
Tuner1=1,1210
|
||||||
|
Tuner2=2,1420
|
||||||
|
Tuner3=3,1680
|
||||||
|
Tuner4=4,2040
|
||||||
|
Tuner5=5,984
|
||||||
|
Tuner6=6,1020
|
||||||
|
Tuner7=7,1056
|
||||||
|
Tuner8=8,1092
|
||||||
|
Tuner9=9,1128
|
||||||
|
Tuner10=10,1164
|
||||||
|
Tuner11=11,1256
|
||||||
|
Tuner12=12,1292
|
||||||
|
Tuner13=13,1328
|
||||||
|
Tuner14=14,1364
|
||||||
|
Tuner15=15,1458
|
||||||
|
Tuner16=16,1494
|
||||||
|
Tuner17=17,1530
|
||||||
|
Tuner18=18,1566
|
||||||
|
Tuner19=19,1602
|
||||||
|
Tuner20=20,1638
|
||||||
|
Tuner21=21,1716
|
||||||
|
Tuner22=22,1752
|
||||||
|
Tuner23=23,1788
|
||||||
|
Tuner24=24,1824
|
217
lib/ddzap.c
217
lib/ddzap.c
@ -1,5 +1,7 @@
|
|||||||
|
#define _LARGEFILE64_SOURCE
|
||||||
#include "../include/linux/dvb/frontend.h"
|
#include "../include/linux/dvb/frontend.h"
|
||||||
#include "src/libdddvb.h"
|
#include "src/libdddvb.h"
|
||||||
|
#include "src/dvb_filter.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -12,6 +14,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
char line_start[16] = "";
|
char line_start[16] = "";
|
||||||
char line_end[16] = "\r";
|
char line_end[16] = "\r";
|
||||||
@ -22,6 +26,14 @@ uint32_t packets = 0;
|
|||||||
uint32_t payload_packets = 0;
|
uint32_t payload_packets = 0;
|
||||||
uint32_t packet_errors = 0;
|
uint32_t packet_errors = 0;
|
||||||
|
|
||||||
|
|
||||||
|
#define SYS_FILE 200
|
||||||
|
uint16_t pmt_pid[16];
|
||||||
|
uint32_t numpmt = 0;
|
||||||
|
uint8_t *pmts[16];
|
||||||
|
int32_t ci = -1;
|
||||||
|
uint32_t loop = 1;
|
||||||
|
|
||||||
uint8_t cc[8192] = { 0 };
|
uint8_t cc[8192] = { 0 };
|
||||||
|
|
||||||
enum { IQ_RED=1, IQ_GREE, IQ_BLUE , IQ_EVIL, IQ_LOG_RED, IQ_LOG_GREEN, IQ_LOG_BLUE , IQ_LOG_EVIL , IQ_TEST, };
|
enum { IQ_RED=1, IQ_GREE, IQ_BLUE , IQ_EVIL, IQ_LOG_RED, IQ_LOG_GREEN, IQ_LOG_BLUE , IQ_LOG_EVIL , IQ_TEST, };
|
||||||
@ -224,6 +236,34 @@ void proc_ts(int i, uint8_t *buf)
|
|||||||
|
|
||||||
#define TSBUFSIZE (100*188)
|
#define TSBUFSIZE (100*188)
|
||||||
|
|
||||||
|
void tscheck_orig(int ts)
|
||||||
|
{
|
||||||
|
uint8_t *buf;
|
||||||
|
uint8_t id;
|
||||||
|
int i, nts;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
buf=(uint8_t *)malloc(TSBUFSIZE);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
len=read(ts, buf, TSBUFSIZE);
|
||||||
|
if (len<0)
|
||||||
|
continue;
|
||||||
|
if (len%188) { /* should not happen */
|
||||||
|
printf("blah\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (buf[0]!=0x47) {
|
||||||
|
printf("unaligned\n");
|
||||||
|
read(ts, buf, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
nts=len/188;
|
||||||
|
for (i=0; i<nts; i++)
|
||||||
|
proc_ts(i, buf+i*188);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void tscheck(int ts)
|
void tscheck(int ts)
|
||||||
{
|
{
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
@ -233,20 +273,19 @@ void tscheck(int ts)
|
|||||||
|
|
||||||
buf=(uint8_t *)malloc(TSBUFSIZE);
|
buf=(uint8_t *)malloc(TSBUFSIZE);
|
||||||
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
len=read(ts, buf, TSBUFSIZE);
|
len=read(ts, buf, TSBUFSIZE);
|
||||||
if (len<0) {
|
if (len<0)
|
||||||
|
continue;
|
||||||
|
if (len%188) { /* should not happen */
|
||||||
|
printf("blah\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (buf[0]!=0x47) {
|
if (buf[0]!=0x47) {
|
||||||
|
printf("unaligned\n");
|
||||||
read(ts, buf, 1);
|
read(ts, buf, 1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (len%188) { /* should not happen */
|
|
||||||
printf("blah\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
nts=len/188;
|
nts=len/188;
|
||||||
for (i=0; i<nts; i++)
|
for (i=0; i<nts; i++)
|
||||||
proc_ts(i, buf+i*188);
|
proc_ts(i, buf+i*188);
|
||||||
@ -265,6 +304,76 @@ static uint32_t root2gold(uint32_t root)
|
|||||||
return 0xffffffff;
|
return 0xffffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t rread(int fd, uint8_t *buf, size_t count)
|
||||||
|
{
|
||||||
|
size_t len, todo=count;
|
||||||
|
|
||||||
|
while (todo) {
|
||||||
|
len = read(fd, buf, todo);
|
||||||
|
if (len < 0)
|
||||||
|
return len;
|
||||||
|
if (len == 0 && fd && loop!=1) {
|
||||||
|
lseek64(fd, SEEK_SET, 0);
|
||||||
|
loop -= loop ? 1 : 0;
|
||||||
|
}
|
||||||
|
buf+=len;
|
||||||
|
todo-=len;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void decode(struct dddvb *dd, int fd)
|
||||||
|
{
|
||||||
|
uint8_t buf[200*188];
|
||||||
|
uint8_t ts[188];
|
||||||
|
struct dvbf_pid pidf[16];
|
||||||
|
int pmt;
|
||||||
|
ssize_t len, len2;
|
||||||
|
uint32_t count = 0;
|
||||||
|
|
||||||
|
for (pmt = 0; pmt < numpmt; pmt++) {
|
||||||
|
dvbf_init_pid(&pidf[pmt], pmt_pid[pmt]);
|
||||||
|
do {
|
||||||
|
len=rread(fd,ts,188);
|
||||||
|
if (len != 188) {
|
||||||
|
dprintf(2, "Error reading stream\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if (ts[0] != 0x47)
|
||||||
|
dprintf(2, "Alignment error ts\n");
|
||||||
|
//write(fileno(stdout),ts,188);
|
||||||
|
}
|
||||||
|
while (proc_pidf(&pidf[pmt], ts)<=0);
|
||||||
|
dprintf(2, "PMT %u of %u\n", pmt, numpmt);
|
||||||
|
//dump(stderr, pidf[pmt].buf, pidf[pmt].len);
|
||||||
|
pmts[pmt]=pidf[pmt].buf;
|
||||||
|
}
|
||||||
|
//sleep(10);
|
||||||
|
while (dddvb_ca_set_pmts(dd, ci, pmts) < 0)
|
||||||
|
sleep(1);
|
||||||
|
while (1) {
|
||||||
|
len = rread(fd, buf, sizeof(buf));
|
||||||
|
if (len < 0) {
|
||||||
|
dprintf(2, "Error reading stream %d\n", errno);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if (buf[0] != 0x47) {
|
||||||
|
rread(fd, buf, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
len2 = dddvb_ca_write(dd, ci, buf, len);
|
||||||
|
if (len2 != len)
|
||||||
|
dprintf(2, "Written less to CI %d\n", len);
|
||||||
|
len = dddvb_ca_read(dd, ci, buf, len2);
|
||||||
|
if (len < 0)
|
||||||
|
continue;
|
||||||
|
len2 = write(fileno(stdout), buf, len);
|
||||||
|
if (len2 != len)
|
||||||
|
dprintf(2, "Written less to output %d\n", len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct dddvb *dd;
|
struct dddvb *dd;
|
||||||
@ -285,7 +394,7 @@ int main(int argc, char **argv)
|
|||||||
int color = 0;
|
int color = 0;
|
||||||
pamdata iq;
|
pamdata iq;
|
||||||
|
|
||||||
|
memset(pmts, 0, sizeof(pmts));
|
||||||
while (1) {
|
while (1) {
|
||||||
int cur_optind = optind ? optind : 1;
|
int cur_optind = optind ? optind : 1;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
@ -308,20 +417,41 @@ int main(int argc, char **argv)
|
|||||||
{"tscheck", no_argument, 0, 't'},
|
{"tscheck", no_argument, 0, 't'},
|
||||||
{"tscheck_l", required_argument, 0, 'a'},
|
{"tscheck_l", required_argument, 0, 'a'},
|
||||||
{"nodvr", no_argument , 0, 'q'},
|
{"nodvr", no_argument , 0, 'q'},
|
||||||
{"pam", no_argument , 0, 'a'},
|
{"pam", no_argument , 0, 'P'},
|
||||||
|
{"pam_color", no_argument , 0, 'e'},
|
||||||
|
{"decode", required_argument, 0, 'x'},
|
||||||
|
{"loop", required_argument, 0, 'L'},
|
||||||
{"help", no_argument , 0, 'h'},
|
{"help", no_argument , 0, 'h'},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
c = getopt_long(argc, argv,
|
c = getopt_long(argc, argv,
|
||||||
"e:c:i:f:s:d:p:hg:r:n:b:l:v:m:ota:q",
|
"e:c:i:f:s:d:p:hg:r:n:b:l:v:m:ota:qPx:L:",
|
||||||
long_options, &option_index);
|
long_options, &option_index);
|
||||||
if (c==-1)
|
if (c==-1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'x':
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
char *str,*estr;
|
||||||
|
|
||||||
|
for (numpmt = 0, str = optarg; numpmt < 17 && *str; numpmt++, str=*estr?estr+1:estr) {
|
||||||
|
if (numpmt)
|
||||||
|
pmt_pid[numpmt-1] = strtoul(str, &estr, 10);
|
||||||
|
else
|
||||||
|
ci = strtoul(str, &estr, 10);
|
||||||
|
}
|
||||||
|
numpmt--;
|
||||||
|
odvr = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'L':
|
||||||
|
loop = strtoul(optarg, NULL, 0);
|
||||||
case 'e':
|
case 'e':
|
||||||
odvr = 2;
|
|
||||||
color = strtoul(optarg, NULL, 0);
|
color = strtoul(optarg, NULL, 0);
|
||||||
|
case 'P':
|
||||||
|
odvr = 2;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
fout = stderr;
|
fout = stderr;
|
||||||
@ -341,7 +471,7 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(fout,"performing continuity check\n");
|
fprintf(fout,"performing continuity check\n");
|
||||||
odvr = 2;
|
odvr = 3;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
config = strdup(optarg);
|
config = strdup(optarg);
|
||||||
@ -388,6 +518,10 @@ int main(int argc, char **argv)
|
|||||||
printf("unknown mtype %s\n", optarg);
|
printf("unknown mtype %s\n", optarg);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
|
if (!strcmp(optarg, "C2"))
|
||||||
|
delsys = SYS_DVBC2;
|
||||||
|
if (!strcmp(optarg, "DVBC2"))
|
||||||
|
delsys = SYS_DVBC2;
|
||||||
if (!strcmp(optarg, "C"))
|
if (!strcmp(optarg, "C"))
|
||||||
delsys = SYS_DVBC_ANNEX_A;
|
delsys = SYS_DVBC_ANNEX_A;
|
||||||
if (!strcmp(optarg, "DVBC"))
|
if (!strcmp(optarg, "DVBC"))
|
||||||
@ -416,6 +550,8 @@ int main(int argc, char **argv)
|
|||||||
delsys = SYS_ISDBT;
|
delsys = SYS_ISDBT;
|
||||||
if (!strcmp(optarg, "ISDBS"))
|
if (!strcmp(optarg, "ISDBS"))
|
||||||
delsys = SYS_ISDBS;
|
delsys = SYS_ISDBS;
|
||||||
|
if (!strcmp(optarg, "FILE"))
|
||||||
|
delsys = SYS_FILE;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (!strcmp(optarg, "h") || !strcmp(optarg, "H"))
|
if (!strcmp(optarg, "h") || !strcmp(optarg, "H"))
|
||||||
@ -427,12 +563,19 @@ int main(int argc, char **argv)
|
|||||||
get_ts = 0;
|
get_ts = 0;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
fprintf(fout,"ddzap [-d delivery_system] [-p polarity] [-c config_dir] [-f frequency(Hz)]\n"
|
fprintf(fout,"ddzap [-d delivery_system] [-p polarity] [-c config_dir]\n"
|
||||||
|
" [-f frequency(Hz for terr./kHz for SAT)]\n"
|
||||||
|
" [-m 16APSK/32APSK/64APSK/128APSK/256APSK]\n"
|
||||||
|
" (only needed for higher modulations than 8PSK) on some cards\n"
|
||||||
" [-b bandwidth(Hz)] [-s symbol_rate(Hz)]\n"
|
" [-b bandwidth(Hz)] [-s symbol_rate(Hz)]\n"
|
||||||
" [-g gold_code] [-r root_code] [-i id] [-n device_num]\n"
|
" [-g gold_code] [-r root_code] [-i id] [-n device_num]\n"
|
||||||
" [-o (write dvr to stdout)]\n"
|
" [-o (write dvr to stdout)]\n"
|
||||||
" [-l (tuner source for unicable)]\n"
|
" [-l (tuner source for unicable)]\n"
|
||||||
" [-t [display line](continuity check)]\n"
|
" [-t (continuity check)]\n"
|
||||||
|
" [-a [display line] (display continuity check in line)]\n"
|
||||||
|
" [-P (output IQ diagram as pam)]\n"
|
||||||
|
" [-e [color] (use color for pam 0=green)]\n"
|
||||||
|
" [-x cinum[,pmt0,pmt1,..,.pmt15]]\n"
|
||||||
"\n"
|
"\n"
|
||||||
" delivery_system = C,S,S2,T,T2,J83B,ISDBC,ISDBT\n"
|
" delivery_system = C,S,S2,T,T2,J83B,ISDBC,ISDBT\n"
|
||||||
" polarity = h/H,v/V\n"
|
" polarity = h/H,v/V\n"
|
||||||
@ -443,9 +586,20 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (optind < argc) {
|
if (delsys==SYS_FILE) {
|
||||||
fprintf(fout,"Warning: unused arguments\n");
|
if (optind >= argc) {
|
||||||
|
fd = 0;
|
||||||
|
} else {
|
||||||
|
fd = open(argv[optind], O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
fprintf(stderr,"error opening %s\n", argv[optind]);
|
||||||
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind < argc)
|
||||||
|
fprintf(fout,"Warning: unused arguments\n");
|
||||||
|
|
||||||
if (delsys == ~0) {
|
if (delsys == ~0) {
|
||||||
fprintf(fout,"You have to choose a delivery system: -d (C|S|S2|T|T2)\n");
|
fprintf(fout,"You have to choose a delivery system: -d (C|S|S2|T|T2)\n");
|
||||||
@ -463,7 +617,12 @@ int main(int argc, char **argv)
|
|||||||
fprintf(fout,"dddvb_init failed\n");
|
fprintf(fout,"dddvb_init failed\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
fprintf(fout,"dvbnum = %u\n", dd->dvbfe_num);
|
if (delsys==SYS_FILE) {
|
||||||
|
if (ci>=0)
|
||||||
|
decode(dd, fd);
|
||||||
|
fprintf(fout, "FILE delsys only alowed for decoding.\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
dddvb_get_ts(dd, get_ts);
|
dddvb_get_ts(dd, get_ts);
|
||||||
|
|
||||||
if (num != DDDVB_UNDEF)
|
if (num != DDDVB_UNDEF)
|
||||||
@ -486,14 +645,6 @@ int main(int argc, char **argv)
|
|||||||
dddvb_set_ssi(&p, ssi);
|
dddvb_set_ssi(&p, ssi);
|
||||||
dddvb_dvb_tune(fe, &p);
|
dddvb_dvb_tune(fe, &p);
|
||||||
|
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
uint8_t ts[188];
|
|
||||||
|
|
||||||
dddvb_ca_write(dd, 0, ts, 188);
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!odvr){
|
if (!odvr){
|
||||||
while (1) {
|
while (1) {
|
||||||
fe_status_t stat;
|
fe_status_t stat;
|
||||||
@ -503,14 +654,16 @@ int main(int argc, char **argv)
|
|||||||
str = dddvb_get_strength(fe);
|
str = dddvb_get_strength(fe);
|
||||||
cnr = dddvb_get_cnr(fe);
|
cnr = dddvb_get_cnr(fe);
|
||||||
|
|
||||||
printf("stat=%02x, str=%lld.%03llddB, snr=%lld.%03llddB \n",
|
printf("stat=%02x, str=%" PRId64 ".%03u dBm, "
|
||||||
stat, (long long int)str/1000,(long long int) abs(str%1000),(long long int) cnr/1000, (long long int)abs(cnr%1000));
|
"snr=%" PRId64 ".%03u dB\n",
|
||||||
|
stat, str/1000, abs(str%1000),
|
||||||
|
cnr/1000, abs(cnr%1000));
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#define BUFFSIZE (1024*188)
|
|
||||||
fe_status_t stat;
|
fe_status_t stat;
|
||||||
char filename[150];
|
char filename[150];
|
||||||
|
#define BUFFSIZE (1024*188)
|
||||||
uint8_t buf[BUFFSIZE];
|
uint8_t buf[BUFFSIZE];
|
||||||
|
|
||||||
stat = 0;
|
stat = 0;
|
||||||
@ -523,7 +676,8 @@ int main(int argc, char **argv)
|
|||||||
cnr = dddvb_get_cnr(fe);
|
cnr = dddvb_get_cnr(fe);
|
||||||
|
|
||||||
fprintf(stderr,"stat=%02x, str=%lld.%03llddB, snr=%lld.%03llddB \n",
|
fprintf(stderr,"stat=%02x, str=%lld.%03llddB, snr=%lld.%03llddB \n",
|
||||||
stat,(long long int) str/1000,(long long int) abs(str%1000),(long long int) cnr/1000, (long long int)abs(cnr%1000));
|
stat, (long long int) str/1000, (long long int) abs(str%1000),
|
||||||
|
(long long int) cnr/1000, (long long int)abs(cnr%1000));
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
fprintf(stderr,"got lock on %s\n", fe->name);
|
fprintf(stderr,"got lock on %s\n", fe->name);
|
||||||
@ -533,7 +687,6 @@ int main(int argc, char **argv)
|
|||||||
if ((fd = open(filename ,O_RDONLY)) < 0){
|
if ((fd = open(filename ,O_RDONLY)) < 0){
|
||||||
fprintf(stderr,"Error opening input file:%s\n",filename);
|
fprintf(stderr,"Error opening input file:%s\n",filename);
|
||||||
}
|
}
|
||||||
if (odvr > 0){
|
|
||||||
switch (odvr){
|
switch (odvr){
|
||||||
case 1:
|
case 1:
|
||||||
while(1){
|
while(1){
|
||||||
@ -549,13 +702,15 @@ int main(int argc, char **argv)
|
|||||||
pam_write(STDOUT_FILENO, &iq);
|
pam_write(STDOUT_FILENO, &iq);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case 3:
|
||||||
} else {
|
|
||||||
if( line >= 0 && line < 64 ){
|
if( line >= 0 && line < 64 ){
|
||||||
snprintf(line_start,sizeof(line_start)-1,"\0337\033[%d;0H",line);
|
snprintf(line_start,sizeof(line_start)-1,"\0337\033[%d;0H",line);
|
||||||
strncpy(line_end,"\0338",sizeof(line_end)-1);
|
strncpy(line_end,"\0338",sizeof(line_end)-1);
|
||||||
}
|
}
|
||||||
tscheck(fd);
|
tscheck(fd);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
decode(dd, fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
87
lib/src/ca.c
87
lib/src/ca.c
@ -2,11 +2,13 @@
|
|||||||
#include "dddvb.h"
|
#include "dddvb.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "dvb_filter.h"
|
||||||
|
|
||||||
#include <linux/dvb/dmx.h>
|
#include <linux/dvb/dmx.h>
|
||||||
#include <linux/dvb/frontend.h>
|
#include <linux/dvb/frontend.h>
|
||||||
#include <linux/dvb/video.h>
|
#include <linux/dvb/video.h>
|
||||||
#include <linux/dvb/net.h>
|
#include <linux/dvb/net.h>
|
||||||
|
#include <linux/dvb/ca.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -30,6 +32,23 @@
|
|||||||
#define MMI_STATE_ENQ 2
|
#define MMI_STATE_ENQ 2
|
||||||
#define MMI_STATE_MENU 3
|
#define MMI_STATE_MENU 3
|
||||||
|
|
||||||
|
void dump(FILE *fp, 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)
|
||||||
|
fprintf(fp, "%02x ", b[i]);
|
||||||
|
else
|
||||||
|
fprintf(fp, " ");
|
||||||
|
fprintf(fp, " | ");
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
if (i + j < l)
|
||||||
|
fprintf(fp, "%c", (b[i] > 31 && b[i] < 127) ? b[i] : '.');
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int set_nonblock(int fd)
|
int set_nonblock(int fd)
|
||||||
{
|
{
|
||||||
@ -165,23 +184,22 @@ static int handle_pmt(struct dvbca *ca, uint8_t *buf, int size)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void handle_tdt(struct dddvb_ca *ca)
|
static void handle_tdt(struct dddvb_ca *ca)
|
||||||
{
|
{
|
||||||
struct section *section;
|
struct section *section;
|
||||||
struct dvb_tdt_section *tdt;
|
struct dvb_tdt_section *tdt;
|
||||||
uint8_t sec[4096];
|
uint8_t *sec=ca->dvbf_tdt.buf;
|
||||||
time_t dvb_time;
|
time_t dvb_time;
|
||||||
int len;
|
int len=ca->dvbf_tdt.len;
|
||||||
|
|
||||||
|
if (sec[0] != 0x70)
|
||||||
|
return;
|
||||||
|
dbgprintf(DEBUG_CA, "got tdt\n");
|
||||||
|
//dump(stderr, sec,len);
|
||||||
if (ca->stdcam == NULL)
|
if (ca->stdcam == NULL)
|
||||||
return;
|
return;
|
||||||
if (ca->stdcam->dvbtime == NULL)
|
if (ca->stdcam->dvbtime == NULL)
|
||||||
return;
|
return;
|
||||||
len = getsec(ca->input, 0x14, 0, 0x70, sec);
|
|
||||||
if (len < 0)
|
|
||||||
return;
|
|
||||||
dbgprintf(DEBUG_CA, "got tdt\n");
|
|
||||||
|
|
||||||
section = section_codec(sec, len);
|
section = section_codec(sec, len);
|
||||||
if (section == NULL)
|
if (section == NULL)
|
||||||
@ -195,7 +213,7 @@ static void handle_tdt(struct dddvb_ca *ca)
|
|||||||
if (ca->stdcam->dvbtime)
|
if (ca->stdcam->dvbtime)
|
||||||
ca->stdcam->dvbtime(ca->stdcam, dvb_time);
|
ca->stdcam->dvbtime(ca->stdcam, dvb_time);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int handle_pmts(struct dddvb_ca *ca)
|
static int handle_pmts(struct dddvb_ca *ca)
|
||||||
{
|
{
|
||||||
@ -273,9 +291,27 @@ static int set_pmts(struct dddvb_ca *ca, uint8_t **pmts)
|
|||||||
len = ((sec[1] & 0x0f) << 8) | sec[2];
|
len = ((sec[1] & 0x0f) << 8) | sec[2];
|
||||||
len += 3;
|
len += 3;
|
||||||
memcpy(sec, pmts[i], len);
|
memcpy(sec, pmts[i], len);
|
||||||
|
//dump(stderr, sec, len);
|
||||||
section = section_codec(sec, len);
|
section = section_codec(sec, len);
|
||||||
|
if (!section) {
|
||||||
|
dbgprintf(DEBUG_CA, "section_codec failed\n");;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
section_ext = section_ext_decode(section, 0);
|
section_ext = section_ext_decode(section, 0);
|
||||||
|
if (!section_ext) {
|
||||||
|
dbgprintf(DEBUG_CA, "section_ext_decode failed\n");;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
//dump(stderr, (uint8_t *) section, len);
|
||||||
|
//dump(stderr, (uint8_t *) section_ext, len);
|
||||||
pmt = mpeg_pmt_section_codec(section_ext);
|
pmt = mpeg_pmt_section_codec(section_ext);
|
||||||
|
//pmt = (struct mpeg_pmt_section *) section_ext;
|
||||||
|
if (!pmt) {
|
||||||
|
dbgprintf(DEBUG_CA, "mpeg_pmt_section_codec failed\n");;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//dbgprintf(DEBUG_CA, "PMT = %p section=%p\n", pmt, section);
|
||||||
|
|
||||||
ca->ca_pmt_version[i] = section_ext->version_number;
|
ca->ca_pmt_version[i] = section_ext->version_number;
|
||||||
if (ca->sentpmt) {
|
if (ca->sentpmt) {
|
||||||
@ -291,14 +327,16 @@ static int set_pmts(struct dddvb_ca *ca, uint8_t **pmts)
|
|||||||
listmgmt = CA_LIST_MANAGEMENT_LAST;
|
listmgmt = CA_LIST_MANAGEMENT_LAST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dbgprintf(DEBUG_CA, "set ca_pmt\n");
|
//dump(stderr, (uint8_t *) pmt, len);
|
||||||
|
dbgprintf(DEBUG_CA, "format ca_pmt %p length %u\n", pmt, len);
|
||||||
|
|
||||||
if ((size = en50221_ca_format_pmt(pmt, capmt, sizeof(capmt), ca->moveca, listmgmt,
|
if ((size = en50221_ca_format_pmt(pmt, capmt, sizeof(capmt), ca->moveca, listmgmt,
|
||||||
CA_PMT_CMD_ID_OK_DESCRAMBLING)) < 0) {
|
CA_PMT_CMD_ID_OK_DESCRAMBLING)) < 0) {
|
||||||
dbgprintf(DEBUG_CA, "Failed to format PMT\n");
|
dbgprintf(DEBUG_CA, "Failed to format PMT\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//dump(capmt, size);
|
//dump(stderr, capmt, size);
|
||||||
|
dbgprintf(DEBUG_CA, "set ca_pmt\n");
|
||||||
if (en50221_app_ca_pmt(ca->stdcam->ca_resource, ca->stdcam->ca_session_number, capmt, size)) {
|
if (en50221_app_ca_pmt(ca->stdcam->ca_resource, ca->stdcam->ca_session_number, capmt, size)) {
|
||||||
dbgprintf(DEBUG_CA, "Failed to send PMT\n");
|
dbgprintf(DEBUG_CA, "Failed to send PMT\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -625,12 +663,27 @@ static int init_ca_stack(struct dddvb_ca *ca)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cam_reset(int fd)
|
||||||
|
{
|
||||||
|
ca_slot_info_t info;
|
||||||
|
|
||||||
|
info.num = 0;
|
||||||
|
if (ioctl(fd, CA_GET_SLOT_INFO, &info))
|
||||||
|
return;
|
||||||
|
if (info.flags & CA_CI_MODULE_READY)
|
||||||
|
return;
|
||||||
|
if (!(info.flags & CA_CI_MODULE_PRESENT))
|
||||||
|
return;
|
||||||
|
ioctl(fd, CA_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
static int init_ca(struct dddvb *dd, int a, int f, int fd)
|
static int init_ca(struct dddvb *dd, int a, int f, int fd)
|
||||||
{
|
{
|
||||||
struct dddvb_ca *ca;
|
struct dddvb_ca *ca;
|
||||||
char fname[80];
|
char fname[80];
|
||||||
|
|
||||||
|
if (dd->dvbca_num >= DDDVB_MAX_DVB_CA)
|
||||||
|
return -1;
|
||||||
ca = &dd->dvbca[dd->dvbca_num];
|
ca = &dd->dvbca[dd->dvbca_num];
|
||||||
ca->dd = dd;
|
ca->dd = dd;
|
||||||
ca->anum = a;
|
ca->anum = a;
|
||||||
@ -639,10 +692,13 @@ static int init_ca(struct dddvb *dd, int a, int f, int fd)
|
|||||||
ca->fd = fd;
|
ca->fd = fd;
|
||||||
pthread_mutex_init(&ca->mutex, 0);
|
pthread_mutex_init(&ca->mutex, 0);
|
||||||
|
|
||||||
|
//cam_reset(fd);
|
||||||
|
|
||||||
init_ca_stack(ca);
|
init_ca_stack(ca);
|
||||||
|
|
||||||
pthread_create(&ca->poll_pt, NULL, (void *) ci_poll, ca);
|
pthread_create(&ca->poll_pt, NULL, (void *) ci_poll, ca);
|
||||||
pthread_create(&ca->pt, NULL, (void *) handle_ci, ca);
|
pthread_create(&ca->pt, NULL, (void *) handle_ci, ca);
|
||||||
|
dvbf_init_pid(&ca->dvbf_tdt, 0x14);
|
||||||
|
|
||||||
sprintf(fname, "/dev/dvb/adapter%d/ci%d", a, f);
|
sprintf(fname, "/dev/dvb/adapter%d/ci%d", a, f);
|
||||||
ca->ci_wfd = open(fname, O_WRONLY);
|
ca->ci_wfd = open(fname, O_WRONLY);
|
||||||
@ -654,6 +710,15 @@ static int init_ca(struct dddvb *dd, int a, int f, int fd)
|
|||||||
int dddvb_ca_write(struct dddvb *dd, uint32_t nr, uint8_t *buf, uint32_t len)
|
int dddvb_ca_write(struct dddvb *dd, uint32_t nr, uint8_t *buf, uint32_t len)
|
||||||
{
|
{
|
||||||
struct dddvb_ca *ca = &dd->dvbca[nr];
|
struct dddvb_ca *ca = &dd->dvbca[nr];
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if (len%188)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i+=188) {
|
||||||
|
if (proc_pidf(&ca->dvbf_tdt, buf+i)>0)
|
||||||
|
handle_tdt(ca);
|
||||||
|
}
|
||||||
|
|
||||||
return write(ca->ci_wfd, buf, len);
|
return write(ca->ci_wfd, buf, len);
|
||||||
}
|
}
|
||||||
@ -669,7 +734,7 @@ int dddvb_ca_set_pmts(struct dddvb *dd, uint32_t nr, uint8_t **pmts)
|
|||||||
{
|
{
|
||||||
struct dddvb_ca *ca = &dd->dvbca[nr];
|
struct dddvb_ca *ca = &dd->dvbca[nr];
|
||||||
|
|
||||||
dbgprintf(DEBUG_CA, "ca_set_pmt\n");
|
dbgprintf(DEBUG_CA, "ca%u.%u.%u:ca_set_pmt\n", ca->nr,ca->anum,ca->fnum);
|
||||||
return set_pmts(ca, pmts);
|
return set_pmts(ca, pmts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user