178 Commits

Author SHA1 Message Date
da4938e3aa use correct input 2023-09-05 14:28:05 +02:00
3439fd7725 Merge branch 'internal' of hippo:rjkm/dddvb into internal 2023-08-01 22:31:15 +02:00
818b9cb58d support CI M2, M8 and M8A 2023-08-01 22:27:55 +02:00
0bafbf534f support alternative modulation types 2023-08-01 22:27:55 +02:00
e5072debc0 change lnb and ci bases to be configurable 2023-08-01 22:27:55 +02:00
2f49ece88c cleanup 2023-08-01 22:27:55 +02:00
52b40198eb only warn once about zigzag scanning 2023-08-01 22:27:55 +02:00
98f98fea0e adjust to 6.4.0 kernel change 2023-08-01 22:27:55 +02:00
ccfdc2b984 fix frontend allocation 2023-08-01 22:27:55 +02:00
9c920141ca adjust usage count for frontends which do not have their own module 2023-08-01 22:27:55 +02:00
6c2bbbe5b8 add ddb_mci_cmd_link_simple() 2023-08-01 22:27:55 +02:00
3eaae81e6a adapt MCI defines to firmware 2023-08-01 22:27:55 +02:00
aae6233b14 class has no owner field in kernel version >= 6.4.0 2023-08-01 22:27:55 +02:00
c8f3c122af let SSI be set (default 0 is ste in dvb-core), correct tuner/demod settings 2023-08-01 22:27:55 +02:00
7258b32045 add CI M2, M8 and M8A 2023-08-01 22:27:55 +02:00
c2a2a27500 appease conversion warnings 2023-08-01 22:27:55 +02:00
847aa3c044 flen was not defined yet, so move after assignment 2023-08-01 22:27:55 +02:00
48d9945769 change flashdump to void 2023-08-01 22:27:55 +02:00
307ce85223 select image start according to reg 0x10 2023-08-01 22:27:55 +02:00
23b2e6d6a0 missing return value 2023-08-01 22:27:55 +02:00
647e8d77c3 remove PCR mode setting 2023-08-01 22:27:55 +02:00
4943ea294a rename M4_ defines to MX_ 2023-08-01 22:27:55 +02:00
7118ecd9f5 adjust image start to card type 2023-08-01 22:27:55 +02:00
02ded87d78 support CI M2, M8 and M8A 2023-07-31 22:31:44 +02:00
9698b87204 support alternative modulation types 2023-07-31 22:31:23 +02:00
4d087a3b8c change lnb and ci bases to be configurable 2023-07-31 22:29:08 +02:00
a233c8a6f8 cleanup 2023-07-31 22:14:53 +02:00
e55ef2f0fb only warn once about zigzag scanning 2023-07-31 22:10:05 +02:00
a2f011f62d adjust to 6.4.0 kernel change 2023-07-31 22:08:22 +02:00
7250608d53 fix frontend allocation 2023-07-31 22:07:40 +02:00
5e5ff60b21 adjust usage count for frontends which do not have their own module 2023-07-31 22:04:49 +02:00
060eac06b8 add ddb_mci_cmd_link_simple() 2023-07-31 22:02:11 +02:00
dfde99c01e adapt MCI defines to firmware 2023-07-31 21:59:37 +02:00
73f270d850 class has no owner field in kernel version >= 6.4.0 2023-07-31 21:37:50 +02:00
781177ea44 let SSI be set (default 0 is ste in dvb-core), correct tuner/demod settings 2023-07-31 21:35:57 +02:00
330f2c1821 add CI M2, M8 and M8A 2023-07-31 21:30:56 +02:00
3fc610f546 appease conversion warnings 2023-07-31 21:30:29 +02:00
c522f28d68 flen was not defined yet, so move after assignment 2023-07-31 21:29:44 +02:00
0fa14cca02 change flashdump to void 2023-07-31 21:29:07 +02:00
ed14095a2f select image start according to reg 0x10 2023-07-31 21:28:24 +02:00
456886f4fb missing return value 2023-07-31 21:23:27 +02:00
abbb9e324a remove PCR mode setting 2023-07-31 21:22:45 +02:00
e18b425f41 rename M4_ defines to MX_ 2023-07-31 21:21:45 +02:00
88e65b4db6 adjust image start to card type 2023-07-22 21:28:35 +02:00
f27b64b186 remove Octopus Net Pro IDs 2023-07-22 19:48:59 +02:00
7478bcffb9 forgot to check in setmod1.c 2023-07-22 19:48:59 +02:00
0d9b5ca619 prevent clean error in case test.ts does not exist 2023-07-22 19:48:59 +02:00
e9399971f8 adapt to mainline kernel changes 2023-07-22 19:48:59 +02:00
626aa6d7be device pointer is const now 2023-07-22 19:48:59 +02:00
5bfa228d71 clean up app directory 2023-07-22 19:48:59 +02:00
42df1e88d4 add messages to see what is going on 2023-07-22 19:48:59 +02:00
57101c22b7 adapt to upstream header style 2023-07-22 19:48:59 +02:00
37e423d19b add DVB-C2 2023-07-22 19:48:58 +02:00
17914cb451 remove Octopus Net Pro IDs 2023-07-12 22:42:46 +02:00
25009b3afd forgot to check in setmod1.c 2023-06-12 11:32:14 +02:00
58535dd4e3 prevent clean error in case test.ts does not exist 2023-05-11 14:06:34 +02:00
b51b7c0598 adapt to mainline kernel changes 2023-05-11 14:06:34 +02:00
e9ed73b929 device pointer is const now 2023-05-11 14:06:34 +02:00
c0e174505a clean up app directory 2023-05-11 14:06:34 +02:00
87478ec63a add messages to see what is going on 2023-05-11 14:06:34 +02:00
4f9cb2810e adapt to upstream header style 2023-05-11 14:06:34 +02:00
5988565066 add DVB-C2 2023-05-11 14:06:34 +02:00
rjkm
6e4f8dc86b hardware DVB-T can only do 14 channels 2023-03-05 23:27:58 +01:00
drmocm
5d876b2615 edited help info 2023-03-05 23:27:58 +01:00
drmocm
2968f85c91 limit the number of modulators used with -m option 2023-03-05 23:27:58 +01:00
rjkm
c008e44bf6 hardware DVB-T can only do 14 channels 2023-03-03 13:44:57 +01:00
internal
7e9650c841 add actual frequency and symbol rate to debug output 2023-03-03 13:44:57 +01:00
internal
a6565abde3 emulate old API for latest FSM firmware 2023-03-03 13:44:57 +01:00
internal
ee7c48e6ff return actual modulation for DVB-C 2023-03-03 13:44:57 +01:00
internal
6ce49ed990 return actual symbol rate for all delivery systems 2023-03-03 13:44:57 +01:00
internal
0b36a69c44 check if MCI interface present 2023-03-03 13:44:57 +01:00
internal
e64ceb90fb simplify dummy frontend config 2023-03-03 13:44:57 +01:00
internal
efbf312d98 include link and port number in debug message 2023-03-03 13:44:57 +01:00
drmocm
0c3c1f5753 edited help info 2023-02-04 16:13:10 +01:00
drmocm
4bf1f48926 limit the number of modulators used with -m option 2023-02-04 15:19:11 +01:00
internal
7ce5232cd7 add actual frequency and symbol rate to debug output 2022-12-13 13:45:33 +01:00
internal
3f296bef62 emulate old API for latest FSM firmware 2022-12-13 13:44:34 +01:00
internal
ad01e9f508 return actual modulation for DVB-C 2022-12-13 13:34:22 +01:00
internal
e312df576c return actual symbol rate for all delivery systems 2022-12-13 13:33:57 +01:00
internal
4b5cd433f9 check if MCI interface present 2022-12-13 13:33:09 +01:00
internal
6c068c0cc3 simplify dummy frontend config 2022-12-13 13:32:03 +01:00
internal
1488f326d0 include link and port number in debug message 2022-12-13 13:31:02 +01:00
internal
c78905d4a2 keep original FSM card id if old license id is 7 2022-12-12 11:24:45 +01:00
internal
7eb5c6e658 read back actual symbol rate 2022-11-17 15:13:15 +01:00
internal
172c6c93ba do not create test.ts by default 2022-11-10 14:15:41 +01:00
internal
0dd4f106ab fix port number detection on revision 1 FSM cards 2022-10-30 23:23:44 +01:00
internal
60426304db add MDIR again but use proper empty default 2022-10-30 23:22:35 +01:00
internal
177e71d62a INSTALL_MOD_PATH=$(MDIR) does not work, partially revert "fix" 2022-10-28 15:18:46 +02:00
drmocm
cc03d96de2 added modtest.c 2022-10-26 13:16:21 +02:00
internal
6336bd3689 comment out test init 2022-10-25 19:35:16 +02:00
internal
be79cec76e set legacy signal strength workaround according to channel number 2022-10-25 19:33:25 +02:00
internal
24801ab41a add error return values 2022-10-25 19:32:51 +02:00
internal
390f67c03b remove modulator calls for octonet 2022-10-25 19:32:00 +02:00
internal
fa4e3331d8 move compatibility stuff to dd_compat.h 2022-10-25 19:30:52 +02:00
internal
29cc552a6b not only used on exit, also on failed init 2022-10-25 19:29:38 +02:00
internal
42a0b65235 use correct pointer type 2022-10-25 19:28:36 +02:00
internal
b8abf46d06 add consts 2022-10-25 19:27:44 +02:00
internal
ce06e50881 remove modulator from octonet 2022-10-25 19:25:05 +02:00
internal
22ffb0ecac allow alternative modules dir 2022-10-25 19:23:06 +02:00
internal
92f2132d79 fix printf type 2022-10-25 19:23:06 +02:00
internal
727fba48be ringbuffer fix from upstream 2022-10-25 19:23:06 +02:00
internal
09e8a15d78 Add clean for apps directory. 2022-10-25 19:23:06 +02:00
internal
45c9f076bd Do not use BIT_ULL, because older kernels do not have it. 2022-10-25 19:23:06 +02:00
internal
5c2757d581 Use eth_hw_addr_set in newer kernels. 2022-10-25 19:23:06 +02:00
drmocm
817a464f4a same Makefile changes for test.ts 2022-06-21 15:19:04 +02:00
drmocm
d627e6995f added modconfig and chnaged Makefile accordingly 2022-06-21 15:08:25 +02:00
internal
c8c1ee1835 style fixes 2022-06-07 16:37:10 +02:00
internal
002f39787a This line somehow got lost when adapting to mainline kernel version.
Signed-off-by: internal
2022-06-07 16:15:10 +02:00
internal
871821d6a0 pci_*_dma_mask no longer exists in 5.18 2022-06-07 16:12:19 +02:00
internal
2a88d220e4 allow MCI commands for SDR cards. 2022-06-04 10:42:22 +02:00
internal
457cb550bb do not use diseqc for scif type 3 2022-05-02 21:38:43 +02:00
internal
ffe8764c01 support bigger Winbond flashs. 2022-03-22 15:22:43 +01:00
internal
0892a225d2 support bigger Winbond flashs. 2022-03-21 17:40:11 +01:00
drmocm
431dd4f5ee more examples 2022-03-14 18:46:05 +01:00
rjkm
cdc5395996 translate old attenuator propert to new MCI API 2022-02-20 23:16:52 +01:00
rjkm
69fcf5d649 disable dumps 2022-02-16 15:53:20 +01:00
rjkm
d5d63ea2ef prepare new init for revision 1 FSM but do not use it for now 2022-02-16 15:52:53 +01:00
rjkm
4b69ae5399 cleanup defines, add license commands 2022-02-15 14:43:32 +01:00
rjkm
1cf0526b24 license register is different for revision 1 (MCI) cards 2022-02-15 14:42:37 +01:00
rjkm
73e8b9943e cleanup tables and add license dump 2022-02-15 14:41:25 +01:00
rjkm
4b09ad7e42 forgot to reenable disseqc 2022-02-15 14:40:32 +01:00
rjkm
c39b234fd6 add support for DVBC 2022-02-12 16:40:27 +01:00
rjkm
c2f86b6438 add MCI ioctl to be used through modX devices 2022-02-12 16:39:01 +01:00
rjkm
6a3ef9873d data64 is not definde in kernel version 2022-02-12 16:37:50 +01:00
rjkm
98b466a2d3 remove debug info 2022-02-12 16:37:00 +01:00
rjkm
78d30ff6ff remove unused function 2022-02-12 16:35:57 +01:00
rjkm
d849abd626 move device info output 2022-02-12 15:49:53 +01:00
rjkm
9517d698dc update modulator defines and structs 2022-02-12 15:47:09 +01:00
rjkm
75821a6e3c properly round SCR frequencies 2022-02-12 15:37:49 +01:00
rjkm
2194f8e03a correct ddB 2022-02-12 15:37:04 +01:00
rjkm
d9a846d199 use MCI interface for modulators with revision 1 2022-02-12 15:28:05 +01:00
rjkm
31a781c2e3 remove non-static definition of mci card configs 2022-02-12 15:19:05 +01:00
rjkm
9b458a72de allow compilation against kerne dvb_core if KERNEL_DVB_CORE defined 2022-02-12 15:14:44 +01:00
rjkm
e0fd8a0f35 snr define was deleted by mistake 2022-02-12 15:09:36 +01:00
rjkm
1b49bfb8f1 use dd_compat file and adjust fallthroughs 2022-02-12 15:07:59 +01:00
rjkm
4ce76407e2 add mci irq for fsm cards 2022-02-11 21:37:06 +01:00
rjkm
a6c53f5ece add backwards compatibility include 2022-02-11 16:08:50 +01:00
rjkm
86579d353e add SNR reading for XO2 CI and use correct I2C device 2022-02-07 19:55:31 +01:00
rjkm
63df691561 add type name for second input of dual CI 2022-02-07 19:15:45 +01:00
rjkm
4aa7a68e21 set roll-off to auto or dvb-core will select default
Signed-off-by: rjkm <none>
2022-01-14 20:23:32 +01:00
rjkm
b6d2a37ac2 adapt to latest mainline dvb-core 2022-01-14 20:23:32 +01:00
rjkm
90e6d4806b allow setting CMDREG_SW during init (disabled for now) 2022-01-14 20:23:32 +01:00
rjkm
d995849fdb add comment about IOMMU 2022-01-14 20:23:32 +01:00
rjkm
b5bb500106 move ns.h to ddbridge directory 2022-01-14 20:23:32 +01:00
rjkm
24b7f979c4 process output_start fails (input cannot fail) 2022-01-14 20:23:32 +01:00
rjkm
be19cdb31d define macro for older kernels 2022-01-14 20:23:32 +01:00
rjkm
56afb2acc1 style cleanup 2022-01-14 20:23:32 +01:00
rjkm
08b3218e5a use already resolved link and info 2022-01-14 20:23:32 +01:00
rjkm
e17abdbbb9 return start error 2022-01-14 20:23:32 +01:00
rjkm
811bea8010 show bb header info 2022-01-14 20:23:32 +01:00
drmocm
e89a868ad5 fixed pam and continuity options 2021-12-10 13:56:05 +01:00
rjkm
8bda007f05 add MCI registers for FSM 2021-12-06 14:54:51 +01:00
rjkm
b606a7b2b2 increase wit time after powerup and before reset to 300ms
Signed-off-by: rjkm <none>
2021-09-23 15:07:00 +02:00
rjkm
3757c4671e change printfs to debugging messages 2021-09-19 19:05:50 +02:00
rjkm
719ac4d231 remove workqueue and threaded interrupt modes, they are too laggy 2021-09-19 19:05:05 +02:00
root
a3c6b5acc1 use inttypes 2021-09-07 18:08:58 +02:00
rjkm
eeb013e0fa always allocate 64 adapters
this is for people who do not want to change the config by hand
it is preferred to use adapter_alloc=3 to have one adapter for
each physical DVB card
2021-08-20 14:29:29 +02:00
rjkm
7f40a54b39 standard is 1 for DVB-S, 0 or 2 otherwise 2021-08-20 14:28:28 +02:00
rjkm
1518ba54a4 hexdump complete BIST info for debugging 2021-08-20 14:27:36 +02:00
rjkm
a97787c3b6 add entries for more frontends (there is overlap but it is only for testing) 2021-08-20 14:26:04 +02:00
rjkm
d676919e72 provide kernel version when calling depmod 2021-08-20 14:24:29 +02:00
rjkm
19eea5d42d add getiq to get IQ values from MCI cards 2021-08-09 09:03:02 +02:00
rjkm
b23187a049 Add module paramaters for SX8 tuner flags and gain. 2021-08-08 22:14:42 +02:00
rjkm
0165538f13 prepare to get roll off for SDR mode from parameters but use fixed one
for now
2021-08-07 23:00:29 +02:00
rjkm
0b9d3ffa6b move lut for use in other functions 2021-08-07 22:57:40 +02:00
rjkm
61fd25836f report proper frontend number 2021-08-07 22:49:43 +02:00
rjkm
d4aa1c634e style fix 2021-08-07 22:49:03 +02:00
rjkm
5bb0a95b02 remove obsolete debugging line 2021-08-07 22:36:10 +02:00
rjkm
0a5fb7d6b9 add debugging output for actually tuned frequency 2021-08-07 22:35:22 +02:00
rjkm
fd21dbbd5e add more documentation for use of stream number in SDR modes 2021-08-07 22:32:41 +02:00
rjkm
f7fcc1511d add extended stats 2021-08-07 22:30:10 +02:00
rjkm
37ae102d57 use correct u8 type 2021-08-07 22:30:01 +02:00
rjkm
66b1cf3623 new signal loss counter field 2021-08-07 22:29:17 +02:00
rjkm
7f002f1356 add 7/8 to offset 4 2021-08-07 22:28:42 +02:00
rjkm
418bd83b40 only set tuner flags once 2021-07-05 18:42:05 +02:00
none
442b1c3bf6 add more S2 info and support cards via GT link 2021-06-23 11:19:55 +02:00
none
c23435e275 handle revision 1 mods differently 2021-06-23 11:18:35 +02:00
none
8f5af7742d do not use workqueues by dfault, they can lead to dma overflows 2021-06-22 20:51:28 +02:00
75 changed files with 3799 additions and 1928 deletions

6
Kbuild
View File

@@ -2,6 +2,12 @@
# Makefile for the kernel multimedia device drivers.
#
ifeq ($(KERNEL_DVB_CORE),y)
obj-y := ddbridge/ \
frontends/
else
obj-y := dvb-core/ \
ddbridge/ \
frontends/
endif

View File

@@ -1,4 +1,5 @@
kernelver ?= $(shell uname -r)
MDIR ?=
KDIR ?= /lib/modules/$(kernelver)/build
PWD := $(shell pwd)
@@ -6,8 +7,11 @@ MODDEFS := CONFIG_DVB_CORE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_DRXK=m CONFIG_DVB_
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
DDDVB_INC = "--include=$(KBUILD_EXTMOD)/include/dd_compat.h -I$(KBUILD_EXTMOD)/frontends -I$(KBUILD_EXTMOD)/include -I$(KBUILD_EXTMOD)/include/linux"
endif
all:
$(MAKE) -C $(KDIR) KBUILD_EXTMOD=$(PWD) $(MODDEFS) modules NOSTDINC_FLAGS=$(DDDVB_INC)
@@ -26,10 +30,11 @@ dep:
DIR=`pwd`; (cd $(TOPDIR); make KBUILD_EXTMOD=$$DIR dep)
install: all
$(MAKE) -C $(KDIR) KBUILD_EXTMOD=$(PWD) modules_install
depmod -a
$(MAKE) -C $(KDIR) KBUILD_EXTMOD=$(PWD) INSTALL_MOD_PATH=$(MDIR) modules_install
depmod $(kernelver)
clean:
rm -rf */.*.o.d */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
$(MAKE) -C apps clean

View File

@@ -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
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
$(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
$(CC) $(CFLAGS) -I../ddbridge -I../include/ $< -o $@
%.o: %.c
$(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

View File

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

View File

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

View File

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

View File

@@ -30,15 +30,30 @@ char *Rolloff[8] = {
"rsvd",
};
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");
}
}
void print_temp(struct mci_result *res)
{
printf("Die temperature = %u\n", res->sx8_bist.temperature);
}
int temp_info(int dev)
int temp_info(int dev, uint32_t link)
{
struct ddb_mci_msg msg = {
.link = 0,
.link = link,
.cmd.command = SX8_CMD_GETBIST,
};
int ret;
@@ -55,6 +70,9 @@ int temp_info(int dev)
}
print_temp(&msg.res);
printf("BIST info dump: ");
dump((uint8_t *) &msg.res, 16);
return ret;
}
@@ -221,7 +239,31 @@ char* PunctureRates[32] = {
/* 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) {
printf("\nDemod %u: stopped\n", demod);
@@ -231,29 +273,45 @@ void print_info(struct mci_result *res, uint8_t demod)
printf("\nDemod %u:\n", demod);
if (res->status == MCI_DEMOD_LOCKED) {
switch (res->mode) {
case M4_MODE_DVBSX:
if (res->dvbs2_signal_info.standard == 2) {
int short_frame = 0;
case 0:
case MX_MODE_DVBSX:
if (res->dvbs2_signal_info.standard != 1) {
int short_frame = 0, pilots = 0;
char *modcod = "unknown";
uint8_t pls = res->dvbs2_signal_info.pls_code;
if ((res->dvbs2_signal_info.pls_code >= 128) ||
((res->dvbs2_signal_info.roll_off & 0x7f) > 2))
if ((pls >= 128) || ((res->dvbs2_signal_info.roll_off & 0x7f) > 2))
printf("Demod Locked: DVB-S2X\n");
else
printf("Demod Locked: DVB-S2\n");
printf("PLS-Code: %u\n", res->dvbs2_signal_info.pls_code);
printf("Roll-Off: %s\n", Rolloff[res->dvbs2_signal_info.roll_off]);
printf("Inversion: %s\n", (res->dvbs2_signal_info.roll_off & 0x80) ? "on": "off");
printf("\n");
mci_bb(dev, link, demod);
if (pls >= 250) {
pilots = 1;
modcod = S2Xrsvd[pls - 250];
} else if (pls >= 132) {
pilots = pls & 1;
short_frame = pls > 216;
modcod = S2XModCods[(pls - 132)/2];
} else if (pls < 128) {
pilots = pls & 1;
short_frame = pls & 2;
modcod = S2ModCods[pls / 4];
}
printf("Roll-Off: %s\n", Rolloff[res->dvbs2_signal_info.roll_off & 7]);
printf("Pilots: %s\n", pilots ? "On" : "Off");
printf("Frame: %s\n", short_frame ? "Short" : "Normal");
} else {
printf("Demod Locked: DVB-S\n");
printf("PR: %s\n",
PunctureRates[res->dvbs2_signal_info.pls_code & 0x07]);
}
case M4_MODE_DVBT:
printf("Inversion: %s\n", (res->dvbs2_signal_info.roll_off & 0x80) ? "on": "off");
break;
case MX_MODE_DVBT:
printf("Locked DVB-T\n");
break;
case M4_MODE_DVBT2:
case MX_MODE_DVBT2:
printf("Locked DVB-T2\n");
break;
}
@@ -274,10 +332,37 @@ void print_info(struct mci_result *res, uint8_t demod)
}
int mci_info(int dev, uint8_t demod)
int readreg(int dev, uint32_t reg, uint32_t link, uint32_t *val)
{
struct ddb_reg ddbreg;
ddbreg.reg = reg + (link << 28);
if (ioctl(dev, IOCTL_DDB_READ_REG, &ddbreg) < 0)
return -1;
*val = ddbreg.val;
return 0;
}
void mci_firmware(int dev, uint32_t link)
{
union {
uint32_t u[4];
char s[16];
} version;
readreg(dev, MIC_INTERFACE_VER , link, &version.u[0]);
readreg(dev, MIC_INTERFACE_VER + 4, link, &version.u[1]);
readreg(dev, MIC_INTERFACE_VER + 8, link, &version.u[2]);
readreg(dev, MIC_INTERFACE_VER + 12, link, &version.u[3]);
printf("MCI firmware: %s.%d\n", &version.s, version.s[15]);
}
int mci_info(int dev, uint32_t link, uint8_t demod)
{
struct ddb_mci_msg msg = {
.link = 0,
.link = link,
.cmd.command = MCI_CMD_GETSIGNALINFO,
.cmd.demod = demod
};
@@ -290,7 +375,7 @@ int mci_info(int dev, uint8_t demod)
return ret;
}
print_info(&msg.res, demod);
print_info(dev, link, demod, &msg.res);
return ret;
}
@@ -380,20 +465,22 @@ static int card_info(int ddbnum, int demod)
id.hw, id.regmap, (id.hw & 0xff0000) >> 16, (id.hw & 0xffff));
switch (id.device) {
case 0x0009:
mci_firmware(ddb, link);
if (demod >= 0)
mci_info(ddb, demod);
mci_info(ddb, link, demod);
else {
for (i = 0; i < 8; i++)
mci_info(ddb, i);
mci_info(ddb, link, i);
}
temp_info(ddb);
temp_info(ddb, link);
break;
case 0x000a:
mci_firmware(ddb, link);
if (demod >= 0)
mci_info(ddb, demod);
mci_info(ddb, link, demod);
else {
for (i = 0; i < 4; i++)
mci_info(ddb, i);
mci_info(ddb, link, i);
}
break;
default:

View File

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

View File

@@ -83,103 +83,203 @@ struct param_table_entry {
};
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 = "GENERIC", .value = MOD_STANDARD_GENERIC },
{ .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 = "DVBT_7", .value = MOD_STANDARD_DVBT_7 },
{ .name = "DVBT2_7", .value = MOD_STANDARD_DVBT_7 },
{ .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 = "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 }
};
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 = "default", .value = MOD_FORMAT_DEFAULT },
{ .name = "1", .value = MOD_FORMAT_IQ16 },
{ .name = "IQ16", .value = MOD_FORMAT_IQ16 },
{ .name = "2", .value = MOD_FORMAT_IQ8 },
{ .name = "IQ8", .value = MOD_FORMAT_IQ8 },
{ .name = "3", .value = MOD_FORMAT_IDX8 },
{ .name = "IDX8", .value = MOD_FORMAT_IDX8 },
{ .name = "4", .value = MOD_FORMAT_TS },
{ .name = "TS", .value = MOD_FORMAT_TS },
{ .name = NULL, .value = 0 }
};
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 = "1/32", .value = MOD_DVBT_GI_1_32 },
{ .name = "1", .value = MOD_DVBT_GI_1_16 },
{ .name = "2", .value = MOD_DVBT_GI_1_8 },
{ .name = "3", .value = MOD_DVBT_GI_1_4 },
{ .name = "1/16", .value = MOD_DVBT_GI_1_16 },
{ .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 = "1/4", .value = MOD_DVBT_GI_1_4 },
{ .name = NULL, .value = 0 }
};
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/2", .value = MOD_DVBT_PR_1_2 },
{ .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/4", .value = MOD_DVBT_PR_3_4 },
{ .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/8", .value = MOD_DVBT_PR_7_8 },
{ .name = NULL, .value = 0 }
};
struct param_table_entry dvbt_constellation_table[] = {
{ .name = "0", .value = MOD_DVBT_QPSK },
{ .name = "qpsk", .value = MOD_DVBT_QPSK },
{ .name = "1", .value = MOD_DVBT_16QAM },
{ .name = "16qam", .value = MOD_DVBT_16QAM },
{ .name = "qam16", .value = MOD_DVBT_16QAM },
{ .name = "2", .value = MOD_DVBT_64QAM },
{ .name = "64qam", .value = MOD_DVBT_64QAM },
{ .name = "qam64", .value = MOD_DVBT_64QAM },
{ .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) {
*value = 0;
if (table) {
while (table->name) {
if( !strcasecmp(val,table->name)) {
*value = table->value;
printf("%s=%u\n", val, *value);
return 0;
}
table++;
}
}
}
printf("unknown value %s\n", val);
return -1;
}
void dump(const uint8_t *b, int l)
{
int i, j;
for (j = 0; j < l; j += 16, b += 16) {
for (i = 0; i < 16; i++)
if (i + j < l)
printf("%02x ", b[i]);
else
printf(" ");
printf(" | ");
for (i = 0; i < 16; i++)
if (i + j < l)
putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.');
printf("\n");
}
}
int mci_cmd(int dev, struct mci_command *cmd)
{
int ret;
struct ddb_mci_msg msg;
uint8_t status;
memset(&msg, 0, sizeof(msg));
msg.link = 0;
memcpy(&msg.cmd, cmd, sizeof(msg.cmd));
//dump((const uint8_t *) &msg.cmd, sizeof(msg.cmd));
ret = ioctl(dev, IOCTL_DDB_MCI_CMD, &msg);
if (ret < 0) {
dprintf(2, "mci_cmd error %d\n", errno);
dprintf(2, "mci_cmd error %d (%s)\n", errno, strerror(errno));
return ret;
}
status = msg.res.status;
@@ -210,12 +310,10 @@ struct mci_command msg_channels = {
struct mci_command msg_stream = {
.mod_command = MOD_SETUP_STREAM,
.mod_channel = 1,
.mod_channel = 0,
.mod_stream = 0,
.mod_setup_stream = {
.standard = MOD_STANDARD_DVBT_8,
.fft_size = 1,
.guard_interval = 0,
.standard = MOD_STANDARD_DVBC_8,
},
};
@@ -252,7 +350,7 @@ void output_cb(void *priv, char *par, char *val)
mc->output.mod_setup_output.channel_power = (int16_t) (strtod(val, NULL) * 100.0);
} else if (!strcasecmp(par, "channels")) {
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")) {
mc->output.mod_setup_output.unit = MOD_UNIT_DBUV;
} else if (!strcasecmp(val, "DBM")) {
@@ -277,11 +375,13 @@ void channels_cb(void *priv, char *par, char *val)
printf("frequency = %u\n", mc->channels.mod_setup_channels[0].frequency);
} else if (!strcasecmp(par, "channels")) {
mc->channels.mod_setup_channels[0].num_channels = strtol(val, NULL, 10);
printf("channels = %u\n", mc->channels.mod_setup_channels[0].num_channels);
} else if (!strcasecmp(par, "standard")) {
if (!parse_param(val,mod_standard_table,&value))
mc->stream.mod_setup_channels[0].standard = value;
if (!parse_param(val,mod_standard_table, &value))
mc->channels.mod_setup_channels[0].standard = value;
printf("standard = %u\n", value);
} else if (!strcasecmp(par, "offset")) {
mc->channels.mod_setup_channels[0].offset = (uint32_t) (strtod(val, NULL) * 1000000.0);
mc->channels.mod_setup_channels[0].offset = (uint32_t) (strtod(val, NULL) * 1000000.0);
} else if (!strcasecmp(par, "bandwidth")) {
mc->channels.mod_setup_channels[0].bandwidth = (uint32_t) (strtod(val, NULL) * 1000000.0);
mc->channels.mod_setup_channels[0].offset =
@@ -299,18 +399,23 @@ void streams_cb(void *priv, char *par, char *val)
return;
}
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")) {
if (!parse_param(val,guard_interval_table,&value))
mc->stream.mod_setup_stream.guard_interval = value;
if (!parse_param(val, guard_interval_table, &value))
mc->stream.mod_setup_stream.ofdm.guard_interval = value;
} else if (!strcasecmp(par, "puncture_rate")) {
if (!parse_param(val,puncture_rate_table,&value))
mc->stream.mod_setup_stream.puncture_rate = value;
if (!parse_param(val, puncture_rate_table, &value))
mc->stream.mod_setup_stream.ofdm.puncture_rate = value;
} else if (!strcasecmp(par, "constellation")) {
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")) {
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")) {
if (!parse_param(val,mod_standard_table,&value))
mc->stream.mod_setup_stream.standard = value;
@@ -324,11 +429,43 @@ void streams_cb(void *priv, char *par, char *val)
} else if (!strcasecmp(par, "stream")) {
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("%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);
} else
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 fd = -1;
@@ -353,7 +490,7 @@ int main(int argc, char*argv[])
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "d:c:",
c = getopt_long(argc, argv, "d:c:",
long_options, &option_index);
if (c == -1)
break;
@@ -375,18 +512,24 @@ int main(int argc, char*argv[])
printf("too many arguments\n");
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);
if (fd < 0) {
dprintf(2, "Could not open %s\n", fn);
return -1;
}
//mci_lic(fd);
mc.fd = fd;
parse(configname, "channels", (void *) &mc, channels_cb);
if (mc.set_channels)
if (mc.set_channels) {
printf("setting channels.\n");
mci_cmd(fd, &mc.channels);
}
parse(configname, "streams", (void *) &mc, streams_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);
}
}

View File

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

1316
apps/modtest.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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_S25FL164K: SectorSize = 4096; FlashSize = 0x800000; 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)
return 0;
@@ -575,6 +578,9 @@ int FlashProg(int dev,int argc, char* argv[],uint32_t Flags)
case SPANSION_S25FL132K:
case SPANSION_S25FL164K:
case WINBOND_W25Q16JV:
case WINBOND_W25Q32JV:
case WINBOND_W25Q64JV:
case WINBOND_W25Q128JV:
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) {
case WINBOND_W25Q16JV:
case WINBOND_W25Q32JV:
case WINBOND_W25Q64JV:
case WINBOND_W25Q128JV:
read_winbd(dev, Id);
len = 8;
break;
@@ -1353,7 +1362,7 @@ int read_id(int dev, int argc, char* argv[], uint32_t Flags)
for (i = 0; i < len; i++)
printf("%02x ", Id[i]);
printf("\n");
return 0;
}
int i2cread(int dev, int argc, char* argv[], uint32_t Flags)

View File

@@ -36,6 +36,7 @@ static int update_flash(struct ddflash *ddf)
char *fname, *default_fname;
int res, stat = 0;
char *name = 0, *dname;
uint32_t imgadr = 0x10000;
switch (ddf->id.device) {
case 0x300:
@@ -109,6 +110,14 @@ static int update_flash(struct ddflash *ddf)
return stat;
break;
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;
default_fname = devid2fname(ddf->id.device, &name);
if (!fname)
@@ -119,7 +128,8 @@ static int update_flash(struct ddflash *ddf)
printf("Flash: %s\n", ddf->flash_name);
printf("Version: %08x\n", ddf->id.hw);
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;
return stat;
}

View File

@@ -167,7 +167,7 @@ static int flashread(int ddb, int link, uint8_t *buf, uint32_t addr, uint32_t le
}
#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;
uint8_t buf[32];
@@ -630,13 +630,14 @@ int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset,
uint8_t cmd[260];
int i, j;
uint32_t flen, blen;
int blockerase = be && ((FlashOffset & 0xFFFF) == 0 ) && (flen >= 0x10000);
int blockerase;
blen = flen = lseek(dev, 0, SEEK_END) - fw_off;
if (blen % 0xff)
blen = (blen + 0xff) & 0xffffff00;
//printf("blen = %u, flen = %u\n", blen, flen);
setbuf(stdout, NULL);
blockerase = be && ((FlashOffset & 0xFFFF) == 0 ) && (flen >= 0x10000);
cmd[0] = 0x50; // EWSR
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(0x0012, "Octopus CI", "DVBBridgeV2B_DD01_0012_STD.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(0x0022, "Octopus MAXM8", "DVBBridgeV3A_DD01_0022_M8.fpga"),
DEV(0x0024, "Octopus MAXM8A", "DVBBridgeV3A_DD01_0024_M8A.fpga"),
DEV(0x0201, "Modulator", "DVBModulatorV1B_DVBModulatorV1B.bit"),
DEV(0x0203, "Modulator Test", "DVBModulatorV1B_DD01_0203.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);
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++) {
if (buf[p] == ':') {
buf[p] = 0;
val = &buf[p + 1];
val = (char *) &buf[p + 1];
}
}
if (val == NULL || p == fsize)

View File

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

View File

@@ -10,6 +10,7 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <getopt.h>
#include <linux/dvb/mod.h>
@@ -31,17 +32,134 @@ static int set_property(int fd, uint32_t cmd, uint32_t data)
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;
struct dvb_mod_params mp;
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);
set_property(fd, MODULATOR_SYMBOL_RATE, 6900000);
set_property(fd, MODULATOR_FREQUENCY, 114000000);
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 '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);
}

View File

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

View File

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

View File

@@ -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
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
#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
endif
#EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -Idrivers/media/dvb-frontends
#EXTRA_CFLAGS += -Idrivers/media/common/tuners

View File

@@ -1,15 +1,13 @@
#
# 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
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
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
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
obj-$(CONFIG_DVB_OCTONET) += octonet.o
#ccflags-y += -Idrivers/media/include/linux/
#ccflags-y += -Idrivers/media/dvb-frontends/
#ccflags-y += -Idrivers/media/tuners/
ccflags-y += -Idrivers/media/dvb-frontends/
ccflags-y += -Idrivers/media/tuners/

View File

@@ -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
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_OCTONET) += octonet.o
@@ -11,4 +11,5 @@ obj-$(CONFIG_DVB_OCTONET) += octonet.o
ccflags-y += -Idrivers/media/dvb-core/
ccflags-y += -Idrivers/media/dvb-frontends/
ccflags-y += -Idrivers/media/tuners/
ccflags-y += --include=dd_compat.h

View File

@@ -32,7 +32,7 @@ static int wait_ci_ready(struct ddb_ci *ci)
ndelay(500);
do {
if (ddbreadl(ci->port->dev,
CI_CONTROL(ci->nr)) & CI_READY)
CI_CONTROL(ci)) & CI_READY)
break;
usleep_range(1, 2);
if ((--count) == 0)
@@ -50,7 +50,7 @@ static int read_attribute_mem(struct dvb_ca_en50221 *ca,
if (address > CI_BUFFER_SIZE)
return -1;
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);
val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off);
return val;
@@ -62,7 +62,7 @@ static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
struct ddb_ci *ci = ca->data;
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);
return 0;
}
@@ -75,10 +75,10 @@ static int read_cam_control(struct dvb_ca_en50221 *ca,
u32 res;
ddbwritel(ci->port->dev, CI_READ_CMD | address,
CI_DO_IO_RW(ci->nr));
CI_DO_IO_RW(ci));
ndelay(500);
do {
res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr));
res = ddbreadl(ci->port->dev, CI_READDATA(ci));
if (res & CI_READY)
break;
usleep_range(1, 2);
@@ -94,7 +94,7 @@ static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
struct ddb_ci *ci = ca->data;
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);
return 0;
}
@@ -104,15 +104,15 @@ static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
struct ddb_ci *ci = ca->data;
ddbwritel(ci->port->dev, CI_POWER_ON,
CI_CONTROL(ci->nr));
msleep(100);
CI_CONTROL(ci));
msleep(300);
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,
CI_CONTROL(ci->nr));
CI_CONTROL(ci));
usleep_range(20, 25);
ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON,
CI_CONTROL(ci->nr));
CI_CONTROL(ci));
return 0;
}
@@ -120,7 +120,7 @@ static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
{
struct ddb_ci *ci = ca->data;
ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr));
ddbwritel(ci->port->dev, 0, CI_CONTROL(ci));
msleep(300);
return 0;
}
@@ -128,17 +128,17 @@ static int slot_shutdown(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;
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,
CI_CONTROL(ci->nr));
CI_CONTROL(ci));
return 0;
}
static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
{
struct ddb_ci *ci = ca->data;
u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci));
int stat = 0;
if (val & CI_CAM_DETECT)
@@ -162,6 +162,8 @@ static struct dvb_ca_en50221 en_templ = {
static void ci_attach(struct ddb_port *port)
{
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);
if (!ci)
@@ -171,6 +173,7 @@ static void ci_attach(struct ddb_port *port)
port->en = &ci->en;
ci->port = port;
ci->nr = port->nr - 2;
ci->regs = DDB_LINK_TAG(port->lnr) | (off + 32 * ci->nr);
}
/* DuoFlex Dual CI support */
@@ -236,7 +239,7 @@ static int slot_reset_xo2(struct dvb_ca_en50221 *ca, int slot)
write_creg(ci, 0x01, 0x01);
write_creg(ci, 0x04, 0x04);
msleep(20);
msleep(300);
write_creg(ci, 0x02, 0x02);
write_creg(ci, 0x00, 0x04);
write_creg(ci, 0x18, 0x18);

View File

@@ -95,6 +95,70 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
/****************************************************************************/
/****************************************************************************/
/* copied from dvb-core/dvbdev.c because kernel version does not export it */
int ddb_dvb_usercopy(struct file *file,
unsigned int cmd, unsigned long arg,
int (*func)(struct file *file,
unsigned int cmd, void *arg))
{
char sbuf[128];
void *mbuf = NULL;
void *parg = NULL;
int err = -EINVAL;
/* Copy arguments into temp kernel buffer */
switch (_IOC_DIR(cmd)) {
case _IOC_NONE:
/*
* For this command, the pointer is actually an integer
* argument.
*/
parg = (void *) arg;
break;
case _IOC_READ: /* some v4l ioctls are marked wrong ... */
case _IOC_WRITE:
case (_IOC_WRITE | _IOC_READ):
if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
parg = sbuf;
} else {
/* too big to allocate from stack */
mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
if (NULL == mbuf)
return -ENOMEM;
parg = mbuf;
}
err = -EFAULT;
if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
goto out;
break;
}
/* call driver */
if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
err = -ENOTTY;
if (err < 0)
goto out;
/* Copy results into user buffer */
switch (_IOC_DIR(cmd))
{
case _IOC_READ:
case (_IOC_WRITE | _IOC_READ):
if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
err = -EFAULT;
break;
}
out:
kfree(mbuf);
return err;
}
/****************************************************************************/
struct ddb_irq *ddb_irq_set(struct ddb *dev, u32 link, u32 nr,
void (*handler)(void *), void *data)
{
@@ -306,7 +370,7 @@ static int dma_alloc(struct pci_dev *pdev, struct ddb_dma *dma, int dir)
if (!dma->vbuf[i])
return -ENOMEM;
}
if (((u64)dma->vbuf[i] & 0xfff))
if (((uintptr_t) dma->vbuf[i] & 0xfff))
dev_err(&pdev->dev, "DMA memory at %px not aligned!\n", dma->vbuf[i]);
}
return 0;
@@ -336,7 +400,7 @@ static int ddb_buffers_alloc(struct ddb *dev)
if (dma_alloc(dev->pdev,
port->input[0]->dma, 0) < 0)
return -1;
/* fallthrough */
fallthrough;
case DDB_PORT_MOD:
if (port->output->dma)
if (dma_alloc(dev->pdev,
@@ -403,7 +467,7 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
gap = output->port->gap;
max_bitrate = 0;
}
if (dev->link[0].info->type == DDB_OCTOPUS_CI && output->port->nr > 1) {
if (dev->link[0].info->ci_mask && output->port->nr > 1) {
*con = 0x10c;
if (dev->link[0].ids.regmapid >= 0x10003 && !(flags & 1)) {
if (!(flags & 2)) {
@@ -457,10 +521,11 @@ static void calc_con(struct ddb_output *output, u32 *con, u32 *con2, u32 flags)
*con2 = (nco << 16) | gap;
}
static void ddb_output_start_unlocked(struct ddb_output *output)
static int ddb_output_start_unlocked(struct ddb_output *output)
{
struct ddb *dev = output->port->dev;
u32 con = 0x11c, con2 = 0;
int err = 0;
if (output->dma) {
output->dma->cbuf = 0;
@@ -469,7 +534,9 @@ static void ddb_output_start_unlocked(struct ddb_output *output)
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma));
}
if (output->port->class == DDB_PORT_MOD) {
ddbridge_mod_output_start(output);
#ifndef CONFIG_MACH_OCTONET
err = ddbridge_mod_output_start(output);
#endif
} else {
if (output->port->input[0]->port->class == DDB_PORT_LOOP)
con = (1UL << 13) | 0x14;
@@ -492,26 +559,32 @@ static void ddb_output_start_unlocked(struct ddb_output *output)
ddbwritel(dev, con | 1, TS_CONTROL(output));
if (output->dma)
output->dma->running = 1;
return err;
}
static void ddb_output_start(struct ddb_output *output)
static int ddb_output_start(struct ddb_output *output)
{
int err;
if (output->dma) {
spin_lock_irq(&output->dma->lock);
ddb_output_start_unlocked(output);
err = ddb_output_start_unlocked(output);
spin_unlock_irq(&output->dma->lock);
} else {
ddb_output_start_unlocked(output);
err = ddb_output_start_unlocked(output);
}
return err;
}
static void ddb_output_stop_unlocked(struct ddb_output *output)
{
struct ddb *dev = output->port->dev;
#ifndef CONFIG_MACH_OCTONET
if (output->port->class == DDB_PORT_MOD)
ddbridge_mod_output_stop(output);
else
#endif
ddbwritel(dev, 0, TS_CONTROL(output));
if (output->dma) {
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma));
@@ -553,12 +626,14 @@ static void ddb_input_stop_unlocked(struct ddb_input *input)
input->dma->running = 0;
if (input->dma->stall_count)
dev_warn(input->port->dev->dev,
"DMA stalled %u times!\n",
"l%ui%u: DMA stalled %u times!\n",
input->port->lnr, input->nr,
input->dma->stall_count);
update_loss(input->dma);
if (input->dma->packet_loss > 1)
dev_warn(input->port->dev->dev,
"%u packets lost due to low DMA performance!\n",
"l%ui%u: %u packets lost due to low DMA performance!\n",
input->port->lnr, input->nr,
input->dma->packet_loss);
}
}
@@ -934,7 +1009,7 @@ static int ts_open(struct inode *inode, struct file *file)
if ((file->f_flags & O_ACCMODE) == O_RDONLY)
ddb_input_start(input);
else if ((file->f_flags & O_ACCMODE) == O_WRONLY)
ddb_output_start(output);
err = ddb_output_start(output);
return err;
}
@@ -993,8 +1068,12 @@ static struct dvb_device dvbdev_ci = {
static long mod_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
return dvb_usercopy(file, cmd, arg, ddbridge_mod_do_ioctl);
}
#ifndef CONFIG_MACH_OCTONET
return ddb_dvb_usercopy(file, cmd, arg, ddbridge_mod_do_ioctl);
#else
return 0;
#endif
}
static const struct file_operations mod_fops = {
.owner = THIS_MODULE,
@@ -1043,15 +1122,24 @@ static int dummy_read_status(struct dvb_frontend *fe, enum fe_status *status)
static void dummy_release(struct dvb_frontend *fe)
{
kfree(fe);
#ifdef CONFIG_MEDIA_ATTACH
__module_get(THIS_MODULE);
#endif
}
static enum dvbfe_algo dummy_algo(struct dvb_frontend *fe)
{
return DVBFE_ALGO_HW;
}
static struct dvb_frontend_ops dummy_ops = {
.delsys = { SYS_DVBC_ANNEX_A, SYS_DVBS, SYS_DVBS2 },
.delsys = { SYS_DVBC_ANNEX_A },
.info = {
.name = "DUMMY DVB-C/C2 DVB-T/T2",
.frequency_stepsize_hz = 166667, /* DVB-T only */
.frequency_min_hz = 47000000, /* DVB-T: 47125000 */
.frequency_max_hz = 865000000, /* DVB-C: 862000000 */
.name = "DUMMY DVB-C",
.frequency_stepsize_hz = 0,
.frequency_tolerance_hz = 0,
.frequency_min_hz = 47000000,
.frequency_max_hz = 865000000,
.symbol_rate_min = 870000,
.symbol_rate_max = 11700000,
.caps = FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
@@ -1064,6 +1152,7 @@ static struct dvb_frontend_ops dummy_ops = {
FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO |
FE_CAN_RECOVER | FE_CAN_MUTE_TS | FE_CAN_2G_MODULATION
},
.get_frontend_algo = dummy_algo,
.release = dummy_release,
.read_status = dummy_read_status,
};
@@ -1084,11 +1173,7 @@ static int demod_attach_dummy(struct ddb_input *input)
{
struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
#if 0
dvb->fe = dvb_attach(dummy_attach);
#else
dvb->fe = dummy_attach();
#endif
return 0;
}
@@ -1159,6 +1244,7 @@ static int demod_attach_stv0367dd(struct ddb_input *input)
return 0;
}
#ifdef CONFIG_DVB_DRXK
static int tuner_attach_tda18271(struct ddb_input *input)
{
struct i2c_adapter *i2c = &input->port->i2c->adap;
@@ -1177,6 +1263,7 @@ static int tuner_attach_tda18271(struct ddb_input *input)
}
return 0;
}
#endif
static int tuner_attach_tda18212dd(struct ddb_input *input)
{
@@ -1446,35 +1533,37 @@ static void dvb_input_detach(struct ddb_input *input)
case 0x41:
if (dvb->fe2)
dvb_unregister_frontend(dvb->fe2);
/* fallthrough */
fallthrough;
case 0x40:
if (dvb->fe)
dvb_unregister_frontend(dvb->fe);
/* fallthrough */
fallthrough;
case 0x30:
dvb_frontend_detach(dvb->fe);
dvb->fe = NULL;
dvb->fe2 = NULL;
/* fallthrough */
fallthrough;
case 0x21:
if (input->port->dev->ns_num)
dvb_netstream_release(&dvb->dvbns);
/* fallthrough */
fallthrough;
case 0x20:
#ifdef CONFIG_DVB_NET
dvb_net_release(&dvb->dvbnet);
/* fallthrough */
#endif
fallthrough;
case 0x12:
dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
&dvb->hw_frontend);
dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
&dvb->mem_frontend);
/* fallthrough */
fallthrough;
case 0x11:
dvb_dmxdev_release(&dvb->dmxdev);
/* fallthrough */
fallthrough;
case 0x10:
dvb_dmx_release(&dvb->demux);
/* fallthrough */
fallthrough;
case 0x01:
break;
}
@@ -1507,8 +1596,7 @@ static int dvb_register_adapters(struct ddb *dev)
}
if (adapter_alloc >= 3 || dev->link[0].info->type == DDB_MOD ||
dev->link[0].info->type == DDB_OCTONET ||
dev->link[0].info->type == DDB_OCTOPRO) {
dev->link[0].info->type == DDB_OCTONET) {
port = &dev->port[0];
adap = port->dvb[0].adap;
ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE,
@@ -1640,9 +1728,11 @@ static int dvb_input_attach(struct ddb_input *input)
return ret;
dvb->attached = 0x12;
#ifdef CONFIG_DVB_NET
ret = dvb_net_init(adap, &dvb->dvbnet, dvb->dmxdev.demux);
if (ret < 0)
return ret;
#endif
dvb->attached = 0x20;
if (input->port->dev->ns_num) {
@@ -1715,7 +1805,7 @@ static int dvb_input_attach(struct ddb_input *input)
osc24 = 0;
else
osc24 = 1;
/* fallthrough */
fallthrough;
case DDB_TUNER_DVBCT2_SONY_P:
case DDB_TUNER_DVBC2T2_SONY_P:
case DDB_TUNER_ISDBT_SONY_P:
@@ -1732,7 +1822,7 @@ static int dvb_input_attach(struct ddb_input *input)
break;
case DDB_TUNER_DVBC2T2I_SONY:
osc24 = 1;
/* fallthrough */
fallthrough;
case DDB_TUNER_DVBCT2_SONY:
case DDB_TUNER_DVBC2T2_SONY:
case DDB_TUNER_ISDBT_SONY:
@@ -1748,6 +1838,9 @@ static int dvb_input_attach(struct ddb_input *input)
break;
case DDB_TUNER_MCI_SX8:
case DDB_TUNER_MCI_M4:
case DDB_TUNER_MCI_M8:
case DDB_TUNER_MCI_M8A:
case DDB_TUNER_MCI_M2:
if (ddb_fe_attach_mci(input, port->type) < 0)
return -ENODEV;
break;
@@ -2011,14 +2104,14 @@ static void ddb_port_probe(struct ddb_port *port)
return;
}
if (port->nr == 1 && dev->link[l].info->type == DDB_OCTOPUS_CI &&
if (port->nr == 1 && link->info->ci_mask &&
link->info->i2c_mask == 1) {
port->name = "NO TAB";
port->class = DDB_PORT_NONE;
return;
}
if (dev->link[l].info->type == DDB_MOD) {
if (link->info->type == DDB_MOD) {
port->name = "MOD";
port->class = DDB_PORT_MOD;
return;
@@ -2034,21 +2127,21 @@ static void ddb_port_probe(struct ddb_port *port)
return;
}
if (link->info->type == DDB_OCTOPUS_MCI) {
if (port->nr >= link->info->mci_ports)
return;
if ((link->info->type == DDB_OCTOPUS_MCI) &&
(port->nr < link->info->mci_ports)) {
port->name = "DUAL MCI";
port->type_name = "MCI";
port->class = DDB_PORT_TUNER;
port->type = DDB_TUNER_MCI + link->info->mci_type;
port->type = link->info->mci_type;
return;
}
if (port->nr > 1 && link->info->type == DDB_OCTOPUS_CI) {
if (port->nr > 1 && (link->info->ci_mask & (1 << port->nr))) {
port->name = "CI internal";
port->type_name = "INTERNAL";
port->class = DDB_PORT_CI;
port->type = DDB_CI_INTERNAL;
return;
}
if (!port->i2c)
@@ -2180,7 +2273,7 @@ static int ddb_port_attach(struct ddb_port *port)
ret = ddb_ci_attach(port, ci_bitrate);
if (ret < 0)
break;
/* fallthrough */
fallthrough;
case DDB_PORT_LOOP:
ret = dvb_register_device(port->dvb[0].adap,
&port->dvb[0].dev,
@@ -2336,15 +2429,9 @@ static void input_write_dvb(struct ddb_input *input,
}
}
#ifdef DDB_USE_WORK
static void input_work(struct work_struct *work)
{
struct ddb_dma *dma = container_of(work, struct ddb_dma, work);
#else
static void input_tasklet(unsigned long data)
{
struct ddb_dma *dma = (struct ddb_dma *)data;
#endif
struct ddb_input *input = (struct ddb_input *)dma->io;
struct ddb *dev = input->port->dev;
unsigned long flags;
@@ -2377,17 +2464,10 @@ static void input_handler(unsigned long data)
* just copy pointers and ACK. So, there is no need to go
* through the tasklet scheduler.
*/
#ifdef DDB_USE_WORK
if (input->redi)
queue_work(ddb_wq, &dma->work);
else
input_work(&dma->work);
#else
if (input->redi)
tasklet_schedule(&dma->tasklet);
else
input_tasklet(data);
#endif
}
#else
@@ -2396,23 +2476,13 @@ static void input_handler(void *data)
struct ddb_input *input = (struct ddb_input *)data;
struct ddb_dma *dma = input->dma;
#ifdef DDB_USE_WORK
queue_work(ddb_wq, &dma->work);
#else
input_tasklet((unsigned long)dma);
#endif
}
#endif
#ifdef DDB_USE_WORK
static void output_work(struct work_struct *work)
{
struct ddb_dma *dma = container_of(work, struct ddb_dma, work);
#else
static void output_tasklet(unsigned long data)
{
struct ddb_dma *dma = (struct ddb_dma *)data;
#endif
struct ddb_output *output = (struct ddb_output *)dma->io;
struct ddb *dev = output->port->dev;
unsigned long flags;
@@ -2454,11 +2524,7 @@ static void output_handler(void *data)
struct ddb_output *output = (struct ddb_output *)data;
struct ddb_dma *dma = output->dma;
#ifdef DDB_USE_WORK
queue_work(ddb_wq, &dma->work);
#else
tasklet_schedule(&dma->tasklet);
#endif
}
#endif
@@ -2489,11 +2555,7 @@ static void ddb_dma_init(struct ddb_io *io, int nr, int out, int irq_nr)
spin_lock_init(&dma->lock);
init_waitqueue_head(&dma->wq);
if (out) {
#ifdef DDB_USE_WORK
INIT_WORK(&dma->work, output_work);
#else
tasklet_init(&dma->tasklet, output_tasklet, (unsigned long)dma);
#endif
dma->regs = rm->odma->base + rm->odma->size * nr;
dma->bufregs = rm->odma_buf->base + rm->odma_buf->size * nr;
if (io->port->dev->link[0].info->type == DDB_MOD &&
@@ -2507,11 +2569,7 @@ static void ddb_dma_init(struct ddb_io *io, int nr, int out, int irq_nr)
dma->div = 1;
}
} else {
#ifdef DDB_USE_WORK
INIT_WORK(&dma->work, input_work);
#else
tasklet_init(&dma->tasklet, input_tasklet, (unsigned long)dma);
#endif
dma->regs = rm->idma->base + rm->idma->size * nr;
dma->bufregs = rm->idma_buf->base + rm->idma_buf->size * nr;
dma->num = dma_buf_num;
@@ -2602,7 +2660,7 @@ static int ddb_port_match_link_i2c(struct ddb_port *port)
static void ddb_ports_init(struct ddb *dev)
{
u32 i, l, p;
u32 i, l, p, ports;
struct ddb_port *port;
const struct ddb_info *info;
const struct ddb_regmap *rm;
@@ -2614,7 +2672,8 @@ static void ddb_ports_init(struct ddb *dev)
rm = info->regmap;
if (!rm)
continue;
for (i = 0; i < info->port_num; i++, p++) {
ports = info->port_num;
for (i = 0; i < ports; i++, p++) {
port = &dev->port[p];
port->dev = dev;
port->nr = i;
@@ -2636,6 +2695,7 @@ static void ddb_ports_init(struct ddb *dev)
port->class = DDB_PORT_CI;
port->type = DDB_CI_EXTERNAL_XO2_B;
port->name = "DuoFlex CI_B";
port->type_name = "CI_XO2_B";
port->i2c = dev->port[p - 1].i2c;
}
dev_info(dev->dev, "Port %u: Link %u, Link Port %u (TAB %u): %s\n",
@@ -2658,32 +2718,39 @@ static void ddb_ports_init(struct ddb *dev)
if (port->class == DDB_PORT_NONE)
continue;
switch (dev->link[l].info->type) {
case DDB_OCTOPUS_CI:
if (i >= 2) {
switch (info->type) {
case DDB_OCTONET:
case DDB_OCTOPUS:
if (info->ci_mask & (1 << i)) {
ddb_input_init(port, 2 + i, 0, 2 + i);
ddb_input_init(port, 4 + i, 1, 4 + i);
ddb_output_init(port, i);
break;
} /* fallthrough */
case DDB_OCTONET:
case DDB_OCTOPUS:
case DDB_OCTOPRO:
ddb_input_init(port, 2 * i, 0, 2 * i);
ddb_input_init(port, 2 * i + 1, 1, 2 * i + 1);
}
ddb_output_init(port, i);
ddb_input_init(port, 2 * i, 0, 2 * p);
ddb_input_init(port, 2 * i + 1, 1, 2 * p + 1);
ddb_output_init(port, i);
break;
case DDB_OCTOPUS_MAX:
case DDB_OCTOPUS_MAX_CT:
case DDB_OCTOPUS_MCI:
if (info->ci_mask & (1 << i)) {
ddb_input_init(port, 2 + i, 0, 2 + i);
ddb_input_init(port, 4 + i, 1, 4 + i);
ddb_output_init(port, i);
break;
}
ddb_input_init(port, 2 * i, 0, 2 * p);
ddb_input_init(port, 2 * i + 1, 1, 2 * p + 1);
break;
case DDB_MOD:
#ifndef CONFIG_MACH_OCTONET
ddb_output_init(port, i);
ddb_irq_set(dev, 0, i + rm->irq_base_rate,
&ddbridge_mod_rate_handler,
&dev->output[i]);
#endif
break;
default:
break;
@@ -2700,21 +2767,12 @@ void ddb_ports_release(struct ddb *dev)
for (i = 0; i < dev->port_num; i++) {
port = &dev->port[i];
#ifdef DDB_USE_WORK
if (port->input[0] && port->input[0]->dma)
cancel_work_sync(&port->input[0]->dma->work);
if (port->input[1] && port->input[1]->dma)
cancel_work_sync(&port->input[1]->dma->work);
if (port->output && port->output->dma)
cancel_work_sync(&port->output->dma->work);
#else
if (port->input[0] && port->input[0]->dma)
tasklet_kill(&port->input[0]->dma->tasklet);
if (port->input[1] && port->input[1]->dma)
tasklet_kill(&port->input[1]->dma->tasklet);
if (port->output && port->output->dma)
tasklet_kill(&port->output->dma->tasklet);
#endif
}
}
@@ -2818,9 +2876,6 @@ irqreturn_t ddb_irq_handler(int irq, void *dev_id)
irq_handle_msg(dev, s);
if (s & 0x0fffff00) {
irq_handle_io(dev, s);
#ifdef DDB_TEST_THREADED
ret = IRQ_WAKE_THREAD;
#endif
}
} while ((s = ddbreadl(dev, INTERRUPT_STATUS)));
@@ -2868,15 +2923,6 @@ irqreturn_t ddb_irq_handler_v2(int irq, void *dev_id)
return ret;
}
#ifdef DDB_TEST_THREADED
static irqreturn_t irq_thread(int irq, void *dev_id)
{
/* struct ddb *dev = (struct ddb *) dev_id; */
return IRQ_HANDLED;
}
#endif
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
@@ -3016,7 +3062,7 @@ static int nsd_do_ioctl(struct file *file, unsigned int cmd, void *parg)
static long nsd_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
return dvb_usercopy(file, cmd, arg, nsd_do_ioctl);
return ddb_dvb_usercopy(file, cmd, arg, nsd_do_ioctl);
}
static const struct file_operations nsd_fops = {
@@ -3266,8 +3312,8 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
ddbid.device = dev->link[0].ids.device;
ddbid.subvendor = dev->link[0].ids.subvendor;
ddbid.subdevice = dev->link[0].ids.subdevice;
ddbid.hw = ddbreadl(dev, 0);
ddbid.regmap = ddbreadl(dev, 4);
ddbid.hw = dev->link[0].ids.hwid;
ddbid.regmap = dev->link[0].ids.regmapid;
if (copy_to_user(parg, &ddbid, sizeof(ddbid)))
return -EFAULT;
break;
@@ -3429,7 +3475,11 @@ static const struct file_operations ddb_fops = {
#if (KERNEL_VERSION(3, 4, 0) > LINUX_VERSION_CODE)
static char *ddb_devnode(struct device *device, mode_t *mode)
#else
#if (KERNEL_VERSION(6, 2, 0) > LINUX_VERSION_CODE)
static char *ddb_devnode(struct device *device, umode_t *mode)
#else
static char *ddb_devnode(const struct device *device, umode_t *mode)
#endif
#endif
{
struct ddb *dev = dev_get_drvdata(device);
@@ -3674,19 +3724,23 @@ static ssize_t snr_show(struct device *device,
struct ddb *dev = dev_get_drvdata(device);
char snr[32];
int num = attr->attr.name[3] - 0x30;
struct ddb_port *port = &dev->port[num];
struct i2c_adapter *i2c = &port->i2c->adap;
if (dev->port[num].type >= DDB_TUNER_XO2) {
if (i2c_read_regs(&dev->i2c[num].adap, 0x10, 0x10, snr, 16) < 0)
switch (port->type) {
case DDB_CI_EXTERNAL_XO2:
case DDB_TUNER_XO2 ... DDB_TUNER_DVBC2T2I_SONY:
if (i2c_read_regs(i2c, 0x10, 0x10, snr, 16) < 0)
return sprintf(buf, "NO SNR\n");
snr[16] = 0;
} else {
break;
default:
/* serial number at 0x100-0x11f */
if (i2c_read_regs16(&dev->i2c[num].adap,
0x57, 0x100, snr, 32) < 0)
if (i2c_read_regs16(&dev->i2c[num].adap,
0x50, 0x100, snr, 32) < 0)
if (i2c_read_regs16(i2c, 0x57, 0x100, snr, 32) < 0)
if (i2c_read_regs16(i2c, 0x50, 0x100, snr, 32) < 0)
return sprintf(buf, "NO SNR\n");
snr[31] = 0; /* in case it is not terminated on EEPROM */
break;
}
return sprintf(buf, "%s\n", snr);
}
@@ -3697,15 +3751,17 @@ static ssize_t snr_store(struct device *device, struct device_attribute *attr,
struct ddb *dev = dev_get_drvdata(device);
int num = attr->attr.name[3] - 0x30;
u8 snr[34] = { 0x01, 0x00 };
struct ddb_port *port = &dev->port[num];
struct i2c_adapter *i2c = &port->i2c->adap;
return 0; /* NOE: remove completely? */
if (count > 31)
return -EINVAL;
if (dev->port[num].type >= DDB_TUNER_XO2)
if (port->type >= DDB_TUNER_XO2)
return -EINVAL;
memcpy(snr + 2, buf, count);
i2c_write(&dev->i2c[num].adap, 0x57, snr, 34);
i2c_write(&dev->i2c[num].adap, 0x50, snr, 34);
i2c_write(i2c, 0x57, snr, 34);
i2c_write(i2c, 0x50, snr, 34);
return count;
}
@@ -4000,7 +4056,9 @@ static struct device_attribute ddb_attrs_fanspeed[] = {
static struct class ddb_class = {
.name = "ddbridge",
#if (KERNEL_VERSION(6, 4, 0) > LINUX_VERSION_CODE)
.owner = THIS_MODULE,
#endif
.devnode = ddb_devnode,
};
@@ -4399,9 +4457,46 @@ static int ddb_init_boards(struct ddb *dev)
if (info->regmap->mci) {
if (link->info->type == DDB_OCTOPUS_MCI ||
((link->info->type == DDB_MOD) &&
(link->ids.regmapid & 0xfff0)))
(link->ids.regmapid & 0xfff0)) ||
((link->info->type == DDB_MOD) &&
(link->ids.revision == 1)))
mci_init(link);
}
if (l)
continue;
if (dev->link[0].info->type == DDB_MOD &&
dev->link[0].info->version == 2) {
u32 lic = ddbreadl(dev, 0x1c) & 7;
if (dev->link[0].ids.revision == 1)
lic = ddbreadl(dev, 0x260) >> 24;
switch (lic) {
case 0:
case 4:
dev->link[0].info =
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0000);
break;
case 1:
case 8:
dev->link[0].info =
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0003);
break;
case 2:
case 24:
dev->link[0].info =
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0001);
break;
case 3:
case 16:
dev->link[0].info =
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0002);
break;
default:
break;
}
dev_info(dev->dev, "Modulator channels: %u\n", dev->link[0].info->port_num);
}
}
return 0;
}
@@ -4428,8 +4523,10 @@ int ddb_init(struct ddb *dev)
if (ddb_i2c_init(dev) < 0)
goto fail;
ddb_ports_init(dev);
#ifndef CONFIG_MACH_OCTONET
if (dev->link[0].info->type == DDB_MOD)
ddbridge_mod_init(dev);
#endif
if (ddb_buffers_alloc(dev) < 0) {
dev_info(dev->dev,
"Could not allocate buffer memory\n");
@@ -4496,7 +4593,7 @@ int ddb_exit_ddbridge(int stage, int error)
default:
case 2:
destroy_workqueue(ddb_wq);
/* fallthrough */
fallthrough;
case 1:
ddb_class_destroy();
}

View File

@@ -246,7 +246,6 @@ static const struct ddb_regmap octopus_map = {
.odma = &octopus_odma,
.odma_buf = &octopus_odma_buf,
.input = &octopus_input,
.output = &octopus_output,
};
@@ -315,10 +314,14 @@ static const struct ddb_regmap octopus_mod_2_map = {
.irq_version = 2,
.irq_base_odma = 64,
.irq_base_rate = 32,
.irq_base_mci = 10,
.output = &octopus_output,
.odma = &octopus_mod_2_odma,
.odma_buf = &octopus_mod_2_odma_buf,
.channel = &octopus_mod_2_channel,
.mci = &sdr_mci,
.mci_buf = &sdr_mci_buf,
};
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 = {
.type = DDB_OCTOPUS_CI,
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus CI",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x03,
.ci_mask = 0x0c,
};
static const struct ddb_info ddb_cis = {
.type = DDB_OCTOPUS_CI,
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus CI single",
.regmap = &octopus_map,
.port_num = 3,
.i2c_mask = 0x03,
.ci_mask = 0x04,
};
static const struct ddb_info ddb_ci_s2_pro = {
.type = DDB_OCTOPUS_CI,
.type = DDB_OCTOPUS,
.name = "Digital Devices Octopus CI S2 Pro",
.regmap = &octopus_map,
.port_num = 4,
@@ -483,10 +488,11 @@ static const struct ddb_info ddb_ci_s2_pro = {
.board_control = 2,
.board_control_2 = 4,
.hw_min = 0x010007,
.ci_mask = 0x0c,
};
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",
.regmap = &octopus_map,
.port_num = 4,
@@ -494,6 +500,7 @@ static const struct ddb_info ddb_ci_s2_pro_a = {
.board_control = 2,
.board_control_2 = 4,
.hw_min = 0x010007,
.ci_mask = 0x0c,
};
static const struct ddb_info ddb_dvbct = {
@@ -566,6 +573,17 @@ static const struct ddb_info ddb_mod_fsm_4 = {
.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 = {
.type = DDB_MOD,
.name = "Digital Devices SDR ATV",
@@ -601,29 +619,11 @@ static const struct ddb_info ddb_sdr_dvbt = {
.name = "Digital Devices DVBT",
.version = 18,
.regmap = &octopus_sdr_map,
.port_num = 16,
.port_num = 14,
.temp_num = 1,
.tempmon_irq = 8,
};
static const struct ddb_info ddb_octopro_hdin = {
.type = DDB_OCTOPRO_HDIN,
.name = "Digital Devices OctopusNet Pro HDIN",
.regmap = &octopro_hdin_map,
.port_num = 10,
.i2c_mask = 0x3ff,
.mdio_base = 0x10020,
};
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 = {
.type = DDB_OCTOPUS_MAX,
.name = "Digital Devices MAX S8 4/8",
@@ -632,6 +632,7 @@ static const struct ddb_info ddb_s2_48 = {
.i2c_mask = 0x01,
.board_control = 1,
.tempmon_irq = 24,
.lnb_base = 0x400,
};
static const struct ddb_info ddb_ct2_8 = {
@@ -704,8 +705,9 @@ static const struct ddb_info ddb_s2x_48 = {
.i2c_mask = 0x00,
.tempmon_irq = 24,
.mci_ports = 4,
.mci_type = 0,
.mci_type = DDB_TUNER_MCI_SX8,
.temp_num = 1,
.lnb_base = 0x400,
};
static const struct ddb_info ddb_s2x_48_b = {
@@ -716,8 +718,9 @@ static const struct ddb_info ddb_s2x_48_b = {
.i2c_mask = 0x00,
.tempmon_irq = 24,
.mci_ports = 4,
.mci_type = 0,
.mci_type = DDB_TUNER_MCI_SX8,
.temp_num = 1,
.lnb_base = 0x400,
};
static const struct ddb_info ddb_m4 = {
@@ -728,8 +731,48 @@ static const struct ddb_info ddb_m4 = {
.i2c_mask = 0x00,
.tempmon_irq = 24,
.mci_ports = 2,
.mci_type = 1,
.mci_type = DDB_TUNER_MCI_M4,
.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_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,
};
/****************************************************************************/
@@ -862,13 +905,17 @@ static const struct ddb_device_id ddb_device_ids[] = {
DDB_DEVID(0x0012, 0x0042, ddb_ci),
DDB_DEVID(0x0013, 0x0043, ddb_ci_s2_pro),
DDB_DEVID(0x0013, 0x0044, ddb_ci_s2_pro_a),
DDB_DEVID(0x0014, 0x0045, ddb_ci_m2),
DDB_DEVID(0x0020, 0x0012, ddb_gtl_mini),
DDB_DEVID(0x0022, 0x0052, ddb_m8),
DDB_DEVID(0x0024, 0x0053, ddb_m8a),
/* Modulators */
DDB_DEVID(0x0201, 0x0001, ddb_mod),
DDB_DEVID(0x0201, 0x0002, ddb_mod),
DDB_DEVID(0x0201, 0x0004, ddb_mod_4), /* dummy entry ! */
DDB_DEVID(0x0203, 0x0001, ddb_mod),
DDB_DEVID(0x0210, 0x0004, ddb_mod_fsm), /* dummy entry ! */
DDB_DEVID(0x0210, 0x0000, ddb_mod_fsm_4), /* dummy entry ! */
DDB_DEVID(0x0210, 0x0001, ddb_mod_fsm_24),
DDB_DEVID(0x0210, 0x0002, ddb_mod_fsm_16),
@@ -877,15 +924,6 @@ static const struct ddb_device_id ddb_device_ids[] = {
DDB_DEVID(0x0221, 0x0001, ddb_sdr_iq),
DDB_DEVID(0x0222, 0x0001, ddb_sdr_dvbt),
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),
};

View File

@@ -72,11 +72,12 @@ static int search_s2(struct dvb_frontend *fe)
cmd.dvbs2_search.retry = 0;
cmd.dvbs2_search.frequency = p->frequency * 1000;
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)
cmd.dvbs2_search.input_stream_id = p->stream_id;
cmd.tuner = state->mci.nr;
cmd.demod = state->mci.tuner;
cmd.tuner = state->mci.tuner;
cmd.demod = state->mci.demod;
cmd.output = state->mci.nr;
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);
if (res.status == MCI_DEMOD_WAIT_SIGNAL)
*status = 0x01;
else if (res.status == M4_DEMOD_WAIT_TS)
else if (res.status == MX_DEMOD_WAIT_TS)
*status = 0x03;
else if (res.status == MCI_DEMOD_TIMEOUT)
*status = FE_TIMEDOUT;
@@ -456,6 +457,9 @@ static void release(struct dvb_frontend *fe)
kfree(mci_base);
}
kfree(state);
#ifdef CONFIG_MEDIA_ATTACH
__module_get(THIS_MODULE);
#endif
}
static enum dvbfe_algo get_algo(struct dvb_frontend *fe)
@@ -516,7 +520,7 @@ static int base_init(struct mci_base *mci_base)
return 0;
}
struct mci_cfg ddb_max_m4_cfg = {
static struct mci_cfg ddb_max_m4_cfg = {
.type = 0,
.fe_ops = &m4_ops,
.base_size = sizeof(struct m4_base),
@@ -524,3 +528,135 @@ struct mci_cfg ddb_max_m4_cfg = {
.init = 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_ISDBC,
SYS_DVBT, SYS_DVBT2, SYS_ISDBT,
SYS_DVBS, SYS_DVBS2, SYS_ISDBS, },
.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], nr, tuner);
}
EXPORT_SYMBOL(ddb_mx_attach);

View File

@@ -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) {
ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
@@ -114,7 +114,7 @@ static void __devexit ddb_msi_exit(struct ddb *dev)
#endif
}
static void __devexit ddb_irq_exit(struct ddb *dev)
static void ddb_irq_exit(struct ddb *dev)
{
ddb_irq_disable(dev);
if (dev->msi == 2)
@@ -255,17 +255,9 @@ static int __devinit ddb_irq_init(struct ddb *dev)
return stat;
}
} 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),
ddb_irq_handler,
irq_flag, "ddbridge", (void *)dev);
#endif
if (stat < 0)
return stat;
}
@@ -291,11 +283,17 @@ static int __devinit ddb_probe(struct pci_dev *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))) {
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
} else if (!pci_set_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));
if (!dev)
@@ -317,7 +315,6 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
dev->link[0].dev = dev;
dev->link[0].info = get_ddb_info(id->vendor, id->device,
id->subvendor, pdev->subsystem_device);
dev_info(dev->dev, "device name: %s\n", dev->link[0].info->name);
dev->regs_len = pci_resource_len(dev->pdev, 0);
dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
@@ -337,16 +334,12 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
dev->link[0].ids.hwid = ddbreadl(dev, 0);
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) <
dev->link[0].info->hw_min) {
u32 min = dev->link[0].info->hw_min;
dev_err(dev->dev, "Update firmware to at least version %u.%u to ensure full functionality!\n",
(min & 0xff0000) >> 16, min & 0xffff);
(min & 0xff0000) >> 16, min & 0xffff);
}
if (dev->link[0].info->ns_num) {
@@ -357,33 +350,27 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
if (dev->link[0].info->type != DDB_MOD)
ddbwritel(dev, 0, DMA_BASE_WRITE);
if (dev->link[0].info->type == DDB_MOD
&& dev->link[0].info->version <= 1) {
if (dev->link[0].info->type == DDB_MOD &&
dev->link[0].info->version <= 1) {
if (ddbreadl(dev, 0x1c) == 4)
dev->link[0].info =
get_ddb_info(0xdd01, 0x0201, 0xdd01, 0x0004);
}
if (dev->link[0].info->type == DDB_MOD
&& dev->link[0].info->version == 2) {
u32 lic = ddbreadl(dev, 0x1c) & 7;
switch (lic) {
case 0:
dev->link[0].info =
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0000);
break;
case 1:
dev->link[0].info =
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0003);
break;
case 3:
dev->link[0].info =
get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0002);
break;
default:
break;
}
if (dev->link[0].info->type == DDB_MOD &&
dev->link[0].info->version == 2) {
if (dev->link[0].ids.revision == 1)
dev->link[0].info = get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0004);
else if ((ddbreadl(dev, 0x1c) & 7) != 7)
dev->link[0].info = get_ddb_info(0xdd01, 0x0210, 0xdd01, 0x0004);
}
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);
if (stat < 0)
goto fail0;
@@ -408,6 +395,12 @@ fail:
/****************************************************************************/
/****************************************************************************/
#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) \
{ PCI_DEVICE_SUB(0xdd01, _device, 0xdd01, PCI_ANY_ID) }
@@ -424,7 +417,10 @@ static const struct pci_device_id ddb_id_table[] __devinitconst = {
DDB_DEVICE_ANY(0x0011),
DDB_DEVICE_ANY(0x0012),
DDB_DEVICE_ANY(0x0013),
DDB_DEVICE_ANY(0x0014),
DDB_DEVICE_ANY(0x0020),
DDB_DEVICE_ANY(0x0022),
DDB_DEVICE_ANY(0x0024),
DDB_DEVICE_ANY(0x0201),
DDB_DEVICE_ANY(0x0203),
DDB_DEVICE_ANY(0x0210),
@@ -432,17 +428,10 @@ static const struct pci_device_id ddb_id_table[] __devinitconst = {
DDB_DEVICE_ANY(0x0221),
DDB_DEVICE_ANY(0x0222),
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}
};
MODULE_DEVICE_TABLE(pci, ddb_id_table);
static pci_ers_result_t ddb_pci_slot_reset(struct pci_dev *dev)
{
pr_info("pci_slot_reset\n");
@@ -482,7 +471,6 @@ static const struct pci_error_handlers ddb_error = {
.resume = ddb_pci_resume,
};
static struct pci_driver ddb_pci_driver = {
.name = "ddbridge",
.id_table = ddb_id_table,

View File

@@ -28,6 +28,10 @@
/* 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;
module_param(fmode, int, 0444);
MODULE_PARM_DESC(fmode, "frontend emulation mode");
@@ -49,11 +53,12 @@ MODULE_PARM_DESC(no_voltage, "Do not enable voltage on LNBH (will also disable 2
static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
{
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));
ddbwritel(dev, cmd | v, tag | LNB_CONTROL(lnb));
ddbwritel(dev, cmd | v, tag | base | LNB_CONTROL(lnb));
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)
break;
msleep(20);
@@ -91,6 +96,7 @@ static int max_send_master_cmd(struct dvb_frontend *fe,
struct ddb *dev = port->dev;
struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
u32 tag = DDB_LINK_TAG(port->lnr);
u32 base = dev->link[port->lnr].info->lnb_base;
int i;
u32 fmode = dev->link[port->lnr].lnb.fmode;
@@ -105,9 +111,9 @@ static int max_send_master_cmd(struct dvb_frontend *fe,
dvb->diseqc_send_master_cmd(fe, cmd);
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++)
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);
mutex_unlock(&dev->link[port->lnr].lnb.lock);
return 0;
@@ -117,11 +123,12 @@ static int lnb_send_diseqc(struct ddb *dev, u32 link, u32 input,
struct dvb_diseqc_master_cmd *cmd)
{
u32 tag = DDB_LINK_TAG(link);
u32 base = dev->link[link].info->lnb_base;
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++)
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);
return 0;
}
@@ -369,6 +376,7 @@ static int max_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
struct ddb_port *port = input->port;
struct ddb *dev = port->dev;
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];
u32 fmode = dev->link[port->lnr].lnb.fmode;
@@ -377,14 +385,14 @@ static int max_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
default:
case 0:
case 3:
ddbwritel(dev, arg ? 0x34 : 0x01, tag | LNB_CONTROL(dvb->input));
ddbwritel(dev, arg ? 0x34 : 0x01, tag | base | LNB_CONTROL(dvb->input));
break;
case 1:
case 2:
ddbwritel(dev, arg ? 0x34 : 0x01, tag | LNB_CONTROL(0));
ddbwritel(dev, arg ? 0x34 : 0x01, tag | LNB_CONTROL(1));
ddbwritel(dev, arg ? 0x34 : 0x01, tag | LNB_CONTROL(2));
ddbwritel(dev, arg ? 0x34 : 0x01, tag | LNB_CONTROL(3));
ddbwritel(dev, arg ? 0x34 : 0x01, tag | base | LNB_CONTROL(0));
ddbwritel(dev, arg ? 0x34 : 0x01, tag | base | LNB_CONTROL(1));
ddbwritel(dev, arg ? 0x34 : 0x01, tag | base | LNB_CONTROL(2));
ddbwritel(dev, arg ? 0x34 : 0x01, tag | base | LNB_CONTROL(3));
break;
}
mutex_unlock(&dev->link[port->lnr].lnb.lock);
@@ -472,7 +480,8 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input)
tuner = demod & 3;
if (fmode >= 3)
tuner = 0;
dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, demod, tuner);
dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg,
demod, tuner, &dvb->set_input);
if (!dvb->fe) {
dev_err(dev->dev, "No MXL5XX found!\n");
return -ENODEV;
@@ -490,13 +499,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_burst = max_send_burst;
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;
#endif
dvb->input = tuner;
return 0;
}
/* 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)
{
@@ -505,30 +519,63 @@ int ddb_fe_attach_mci(struct ddb_input *input, u32 type)
struct ddb_port *port = input->port;
struct ddb_link *link = &dev->link[port->lnr];
int demod, tuner;
struct mci_cfg cfg;
int fm = fmode;
demod = input->nr;
tuner = demod & 3;
switch (type) {
case DDB_TUNER_MCI_SX8:
cfg = ddb_max_sx8_cfg;
if (fm >= 3)
tuner = 0;
dvb->fe = ddb_sx8_attach(input, demod, tuner, &dvb->set_input);
dvb->input = tuner;
break;
case DDB_TUNER_MCI_M4:
fm = 0;
cfg = ddb_max_m4_cfg;
dvb->fe = ddb_mx_attach(input, demod, tuner, 0);
dvb->input = tuner;
break;
case DDB_TUNER_MCI_M8:
fm = 3;
dvb->fe = ddb_mx_attach(input, demod, tuner, 1);
dvb->input = 0;
break;
case DDB_TUNER_MCI_M8A:
fm = 3;
dvb->fe = ddb_mx_attach(input, demod, tuner, 2);
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;
break;
case 1:
mode = 1;
mmode = demod ? 3 : 1;
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:
return -EINVAL;
}
dvb->fe = ddb_mci_attach(input, &cfg, demod, tuner);
if (!dvb->fe) {
dev_err(dev->dev, "No MCI card found!\n");
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_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF);
}
@@ -541,14 +588,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_burst = max_send_burst;
dvb->fe->sec_priv = input;
switch (type) {
case DDB_TUNER_MCI_M4:
break;
default:
dvb->set_input = dvb->fe->ops.set_input;
if (type == DDB_TUNER_MCI_SX8) {
#ifndef KERNEL_DVB_CORE
dvb->fe->ops.set_input = max_set_input;
break;
#endif
}
dvb->input = tuner;
return 0;
}

View File

@@ -134,6 +134,8 @@ int ddb_mci_cmd_link(struct ddb_link *link,
struct mci_result res;
int stat;
if (!link->mci_ok)
return -EFAULT;
if (!result)
result = &res;
mutex_lock(&link->mci_lock);
@@ -150,6 +152,17 @@ int ddb_mci_cmd_link(struct ddb_link *link,
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)
{
struct ddb_link *link = (struct ddb_link *) priv;
@@ -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);
}
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)
{
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] = {
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] = {
ROLLOFF_35, ROLLOFF_25, ROLLOFF_20, ROLLOFF_10,
@@ -309,6 +307,8 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
p->frequency =
mci->signal_info.dvbs2_signal_info.frequency;
p->symbol_rate =
mci->signal_info.dvbs2_signal_info.symbol_rate;
switch (p->delivery_system) {
default:
case SYS_DVBS:
@@ -353,6 +353,8 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
break;
}
case SYS_DVBC_ANNEX_A:
p->modulation =
mci->signal_info.dvbc_signal_info.constellation + 1;
break;
case SYS_DVBT:
break;

View File

@@ -96,11 +96,13 @@
#define SX8_DEMOD_IQ_MODE (1)
#define SX8_DEMOD_WAIT_MATYPE (3)
#define M4_DEMOD_WAIT_TS (6)
#define M4_DEMOD_C2SCAN (16)
#define MX_DEMOD_WAIT_TS (6)
#define MX_DEMOD_C2SCAN (16)
#define MCI_STATUS_OK (0x00)
#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_RETRY (0xFD)
#define MCI_STATUS_NOT_READY (0xFE)
@@ -111,6 +113,8 @@
#define MCI_CMD_GETSIGNALINFO (0x03)
//#define MCI_CMD_RFPOWER (0x04)
#define MCI_CMD_SET_INPUT_CONFIG (0x05)
#define MCI_CMD_SEARCH_DVBS (0x10)
#define MCI_CMD_SEARCH_ISDBS (0x11)
@@ -123,6 +127,9 @@
#define MCI_CMD_SEARCH_ISDBC (0x25)
#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_BANDWIDTH_UNKNOWN (0)
@@ -140,42 +147,45 @@
#define SX8_CMD_ENABLE_IQOUTPUT (0x44)
#define SX8_CMD_DISABLE_IQOUTPUT (0x45)
#define M4_CMD_GET_L1INFO (0x50)
#define M4_CMD_GET_IDS (0x51)
#define M4_CMD_GET_DVBT_TPS (0x52)
#define MX_CMD_GET_L1INFO (0x50)
#define MX_CMD_GET_IDS (0x51)
#define MX_CMD_GET_DVBT_TPS (0x52)
#define MCI_CMD_GET_BBHEADER (0x53)
#define M4_CMD_GET_ISDBT_TMCC (0x54)
#define M4_CMD_GET_ISDBS_TMCC (0x55)
#define M4_CMD_GET_ISDBC_TSMF (0x56)
#define MX_CMD_GET_ISDBT_TMCC (0x54)
#define MX_CMD_GET_ISDBS_TMCC (0x55)
#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 M4_L1INFO_SEL_DSINFO (1)
#define M4_L1INFO_SEL_PLPINFO (2)
#define M4_L1INFO_SEL_PLPINFO_C (3)
#define M4_L1INFO_SEL_SETID (0x80)
#define MX_L1INFO_SEL_PRE (0)
#define MX_L1INFO_SEL_DSINFO (1)
#define MX_L1INFO_SEL_PLPINFO (2)
#define MX_L1INFO_SEL_PLPINFO_C (3)
#define MX_L1INFO_SEL_SETID (0x80)
#define MCI_BANDWIDTH_EXTENSION (0x80) // currently used only for J83B in Japan
#define M4_MODE_DVBSX (2)
#define M4_MODE_DVBC (3)
#define M4_MODE_DVBT (4)
#define M4_MODE_DVBT2 (5)
#define M4_MODE_DVBC2 (6)
#define M4_MODE_J83B (7)
#define M4_MODE_ISDBT (8)
#define M4_MODE_ISDBC (9)
#define M4_MODE_ISDBS (10)
#define MX_MODE_DVBSX (2)
#define MX_MODE_DVBC (3)
#define MX_MODE_DVBT (4)
#define MX_MODE_DVBT2 (5)
#define MX_MODE_DVBC2 (6)
#define MX_MODE_J83B (7)
#define MX_MODE_ISDBT (8)
#define MX_MODE_ISDBC (9)
#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 M4_DVBC_CONSTELLATION_32QAM (1)
#define M4_DVBC_CONSTELLATION_64QAM (2) // also valid for J83B and ISDB-C
#define M4_DVBC_CONSTELLATION_128QAM (3)
#define M4_DVBC_CONSTELLATION_256QAM (4) // also valid for J83B and ISDB-C
#define MX_DVBC_CONSTELLATION_16QAM (0)
#define MX_DVBC_CONSTELLATION_32QAM (1)
#define MX_DVBC_CONSTELLATION_64QAM (2) // also valid for J83B and ISDB-C
#define MX_DVBC_CONSTELLATION_128QAM (3)
#define MX_DVBC_CONSTELLATION_256QAM (4) // also valid for J83B and ISDB-C
#define M4_SIGNALINFO_FLAG_CHANGE (0x01)
#define M4_SIGNALINFO_FLAG_EWS (0x02)
#define MX_SIGNALINFO_FLAG_CHANGE (0x01)
#define MX_SIGNALINFO_FLAG_EWS (0x02)
#define SX8_ROLLOFF_35 0
#define SX8_ROLLOFF_25 1
@@ -188,49 +198,86 @@
/********************************************************/
#define MOD_SETUP_CHANNELS (0x60)
#define MOD_SETUP_OUTPUT (0x61)
#define MOD_SETUP_STREAM (0x62)
#define MOD_SET_STREAM_CHANNEL (0x63)
#define MOD_SETUP_CHANNELS (0x60)
#define MOD_SETUP_OUTPUT (0x61)
#define MOD_SETUP_STREAM (0x62)
#define MOD_SET_STREAM_CHANNEL (0x63)
#define MOD_SETUP_FLAG_FIRST (0x01)
#define MOD_SETUP_FLAG_LAST (0x02)
#define MOD_SETUP_FLAG_VALID (0x80)
#define MOD_SETUP_FLAG_FIRST (0x01)
#define MOD_SETUP_FLAG_LAST (0x02)
#define MOD_SETUP_FLAG_VALID (0x80)
#define MOD_STANDARD_GENERIC (0x00)
#define MOD_STANDARD_DVBT_8 (0x01)
#define MOD_STANDARD_DVBT_7 (0x02)
#define MOD_STANDARD_DVBT_6 (0x03)
#define MOD_STANDARD_DVBT_5 (0x04)
#define MOD_STANDARD_GENERIC (0x00)
#define MOD_STANDARD_DVBT_8 (0x01)
#define MOD_STANDARD_DVBT_7 (0x02)
#define MOD_STANDARD_DVBT_6 (0x03)
#define MOD_STANDARD_DVBT_5 (0x04)
#define MOD_CONNECTOR_OFF (0x00)
#define MOD_CONNECTOR_F (0x01)
#define MOD_CONNECTOR_SMA (0x02)
#define MOD_STANDARD_DVBC_8 (0x08)
#define MOD_STANDARD_DVBC_7 (0x09)
#define MOD_STANDARD_DVBC_6 (0x0A)
#define MOD_UNIT_DBUV (0x00)
#define MOD_UNIT_DBM (0x01)
#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_FORMAT_DEFAULT (0x00)
#define MOD_FORMAT_IQ16 (0x01)
#define MOD_FORMAT_IQ8 (0x02)
#define MOD_FORMAT_IDX8 (0x03)
#define MOD_FORMAT_TS (0x04)
#define MOD_STANDARD_J83B_QAM64 (0x0B)
#define MOD_STANDARD_J83B_QAM256 (0x0C)
#define MOD_DVBT_FFT_8K (0x01)
#define MOD_DVBT_GI_1_32 (0x00)
#define MOD_DVBT_GI_1_16 (0x01)
#define MOD_DVBT_GI_1_8 (0x02)
#define MOD_DVBT_GI_1_4 (0x03)
#define MOD_STANDARD_ISDBC_QAM64 (0x0D)
#define MOD_STANDARD_ISDBC_QAM256 (0x0E)
#define MOD_DVBT_PR_1_2 (0x00)
#define MOD_DVBT_PR_2_3 (0x01)
#define MOD_DVBT_PR_3_4 (0x02)
#define MOD_DVBT_PR_5_6 (0x03)
#define MOD_DVBT_PR_7_8 (0x04)
#define MOD_STANDARD_J83C_QAM64 (MOD_STANDARD_ISDBC_QAM64 )
#define MOD_STANDARD_J83C_QAM256 (MOD_STANDARD_ISDBC_QAM256)
#define MOD_DVBT_QPSK (0x00)
#define MOD_DVBT_16QAM (0x01)
#define MOD_DVBT_64QAM (0x02)
#define MOD_CONNECTOR_OFF (0x00)
#define MOD_CONNECTOR_F (0x01)
#define MOD_CONNECTOR_SMA (0x02)
#define MOD_UNIT_DBUV (0x00)
#define MOD_UNIT_DBM (0x01)
#define MOD_FORMAT_DEFAULT (0x00)
#define MOD_FORMAT_IQ16 (0x01)
#define MOD_FORMAT_IQ8 (0x02)
#define MOD_FORMAT_IDX8 (0x03)
#define MOD_FORMAT_TS (0x04)
#define MOD_DVBT_FFT_8K (0x01)
#define MOD_DVBT_GI_1_32 (0x00)
#define MOD_DVBT_GI_1_16 (0x01)
#define MOD_DVBT_GI_1_8 (0x02)
#define MOD_DVBT_GI_1_4 (0x03)
#define MOD_DVBT_PR_1_2 (0x00)
#define MOD_DVBT_PR_2_3 (0x01)
#define MOD_DVBT_PR_3_4 (0x02)
#define MOD_DVBT_PR_5_6 (0x03)
#define MOD_DVBT_PR_7_8 (0x04)
#define MOD_DVBT_QPSK (0x00)
#define MOD_DVBT_16QAM (0x01)
#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 {
u8 flags;
@@ -242,17 +289,29 @@ struct mod_setup_channels {
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 {
u8 standard;
u8 stream_format;
u8 rsvd1[2];
u32 symbol_rate; /* only used when Standard doesn't define a fixed symbol rate */
u8 fft_size; /* 0 = 2K, 1 = 8K (2K 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;
u8 rsvd2[2]; /* Reserved for DVB-T hierarchical */
u16 cell_identifier;
union {
struct mod_ofdm_parameter ofdm;
struct mod_qam_parameter qam;
};
};
struct mod_setup_output {
@@ -283,6 +342,7 @@ struct mci_command {
};
union {
u32 params[31];
u8 params8[31*4];
struct {
u8 flags; /* Bit 0: DVB-S Enabled, 1: DVB-S2 Enabled,
5: ChannelBonding, 6: FrequencyRange, 7: InputStreamID */
@@ -431,6 +491,20 @@ struct mci_command {
struct mod_setup_channels mod_setup_channels[4];
struct mod_setup_stream mod_setup_stream;
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 rsvd2;
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 ber_numerator; /* Bit error rate: PreRS in DVB-S, PreBCH in DVB-S2X */
u32 ber_denominator;
@@ -614,8 +688,8 @@ struct mci_result {
struct {
u8 tps_info[7];
// uint16_t tps_cell_id;
} DVBT_TPSInfo;
// u16 tps_cell_id;
} dvbt_tps_info;
struct {
struct {
@@ -644,7 +718,7 @@ struct mci_result {
u8 CurrentRFIndex;
u8 T2Version_PostScrambled_BaseLite_Rsvd[2]; // 4,1,1,4 bit
u8 CRC32[4];
} DVBT2_L1Pre;
} dvbt2_l1_pre;
struct {
u8 SubSlicesPerFrame[2];
@@ -656,8 +730,8 @@ struct mci_result {
u8 FEFType;
u8 FEFLength[3];
u8 FEFInterval;
} DVBT2_L1Post;
} DVBT2_L1Info;
} dvbt2_l1_post;
} dvbt2_l1_info;
struct {
u8 PLPID;
@@ -677,7 +751,7 @@ struct mci_result {
u8 TimeILType;
u8 InBandAFlag;
u8 InBandBFlag_Rsvd1_Mode_StaticFlag_StaticPaddingFlag[2]; // 1,11,2,1,1
} DVBT2_PLPInfo;
} dvbt2_plp_info;
struct {
u8 NetworkID[2];
@@ -735,18 +809,18 @@ struct mci_result {
} DVBC2_PLPInfo;
struct {
u8 Valid;
u8 MATYPE_1;
u8 MATYPE_2;
u8 UPL[2];
u8 DFL[2];
u8 SYNC;
u8 SYNCD[2];
u8 valid;
u8 matype_1;
u8 matype_2;
u8 upl[2];
u8 dfl[2];
u8 sync;
u8 syncd[2];
u8 rsvd;
u8 ISSY[3];
u8 issy[3];
u8 min_input_stream_id;
u8 max_input_stream_id;
} BBHeader;
} bb_header;
struct {
u8 Mode; // FFT Mode 1,2,3
@@ -770,11 +844,41 @@ struct mci_result {
} ISDBS_TMCCInfo;
struct {
uint8_t cut;
uint8_t avs_code;
uint8_t temperature;
uint8_t rsvd[13];
u8 cut;
u8 avs_code;
u8 temperature;
u8 rsvd[13];
} 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];
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_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_snr(struct dvb_frontend *fe);
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_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

View File

@@ -23,8 +23,13 @@
#include "ddbridge.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>
#endif
#include <linux/gcd.h>
/****************************************************************************/
@@ -164,11 +169,6 @@ static void mod_calc_rateinc(struct ddb_mod *mod)
{
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) {
u64 d = mod->obitrate - mod->ibitrate;
@@ -195,6 +195,48 @@ static int mod_calc_obitrate(struct ddb_mod *mod)
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)
{
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_calc_obitrate(mod);
mod_set_stream(mod->port->output);
return 0;
}
@@ -227,6 +270,7 @@ static int mod_set_modulation(struct ddb_mod *mod,
ddbwritel(dev, qamtab[modulation],
CHANNEL_SETTINGS(mod->port->nr));
mod_calc_obitrate(mod);
mod_set_stream(mod->port->output);
return 0;
}
@@ -241,6 +285,7 @@ static int mod_set_frequency(struct ddb_mod *mod, u32 frequency)
if ((freq < 114) || (freq > 874))
return -EINVAL;
mod->frequency = frequency;
mod_set_stream(mod->port->output);
return 0;
}
@@ -322,14 +367,27 @@ int ddbridge_mod_output_start(struct ddb_output *output)
CHANNEL_CONTROL(output->nr));
udelay(10);
ddbwritel(dev, mod->Control, CHANNEL_CONTROL(output->nr));
if (dev->link[0].info->version == 2) {
switch (dev->link[0].info->version) {
case 2:
{
u32 Output = (mod->frequency - 114000000) / 8000000;
u32 KF = Symbolrate;
u32 LF = 9000000UL;
u32 d = gcd(KF, LF);
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, Output, CHANNEL_SETTINGS2(Channel));
@@ -356,16 +414,21 @@ int ddbridge_mod_output_start(struct ddb_output *output)
CHANNEL_CONTROL_CMD_SETUP))
return -EINVAL;
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 */
/* ddbwritel(dev, 0x604, CHANNEL_SETTINGS(output->nr)); */
ddbwritel(dev, qamtab[mod->modulation],
CHANNEL_SETTINGS(output->nr));
mod->Control |= (CHANNEL_CONTROL_ENABLE_IQ |
CHANNEL_CONTROL_ENABLE_DVB);
} else if (dev->link[0].info->version >= 16) {
break;
default:
mod->Control |= (CHANNEL_CONTROL_ENABLE_IQ |
CHANNEL_CONTROL_ENABLE_DVB);
break;
}
if (dev->link[0].info->version < 16) {
mod_set_rateinc(dev, output->nr);
@@ -622,7 +685,26 @@ static int mod_set_attenuator(struct ddb *dev, u32 Value)
{
if (Value > 31)
return -EINVAL;
ddbwritel(dev, Value, RF_ATTENUATOR);
if (dev->link[0].ids.revision == 1) {
struct ddb_link *link = &dev->link[0];
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 - Value * 100,
},
};
if (!link->mci_ok) {
return -EFAULT;
}
return ddb_mci_cmd_link(link, &cmd, &res);
} else
ddbwritel(dev, Value, RF_ATTENUATOR);
return 0;
}
@@ -1653,7 +1735,11 @@ static int mod_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp)
return mod_set_attenuator(mod->port->dev, tvp->u.data);
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);
#endif
case MODULATOR_GAIN:
if (mod->port->dev->link[0].info->version == 2)
@@ -1752,7 +1838,8 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
(struct dtv_properties __user *) parg;
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;
mutex_lock(&dev->ioctl_mutex);
switch (cmd) {
@@ -1844,6 +1931,27 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
mod->pcr_correction = cp->pcr_correction;
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)
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:
ret = -EINVAL;
break;
@@ -1852,6 +1960,18 @@ int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg)
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;
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)
{
int i, status, streams = dev->link[0].info->port_num;
@@ -2029,8 +2149,6 @@ static int mod_init_sdr_iq(struct ddb *dev)
ddbwritel(dev, 0x01, 0x240);
if (dev->link[0].ids.revision == 1)
return 0;
//mod3_set_base_frequency(dev, 602000000);
dev->mod_base.frequency = 570000000;
@@ -2038,9 +2156,11 @@ static int mod_init_sdr_iq(struct ddb *dev)
struct ddb_mod *mod = &dev->mod[i];
mod->port = &dev->port[i];
ddbwritel(dev, 0x00, SDR_CHANNEL_CONTROL(i));
if (dev->link[0].ids.revision != 1)
ddbwritel(dev, 0x00, SDR_CHANNEL_CONTROL(i));
}
if (dev->link[0].ids.revision == 1)
return ret;
mod_set_sdr_attenuator(dev, 0);
udelay(10);
mod_set_sdr_gain(dev, 120);
@@ -2049,6 +2169,25 @@ static int mod_init_sdr_iq(struct ddb *dev)
int ddbridge_mod_init(struct ddb *dev)
{
dev_info(dev->dev, "Revision: %u\n", dev->link[0].ids.revision);
if (dev->link[0].ids.revision == 1) {
switch (dev->link[0].info->version) {
case 0:
case 1:
return mod_init_1(dev, 722000000);
case 2: /* FSM */
if ((dev->link[0].ids.hwid & 0xffffff) >= 9065)
return mod_init_2_1(dev, 114000000);
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:

View File

@@ -248,8 +248,7 @@
/* ------------------------------------------------------------------------- */
#define LNB_BASE (0x400)
#define LNB_CONTROL(i) (LNB_BASE + (i) * 0x20 + 0x00)
#define LNB_CONTROL(i) ((i) * 0x20 + 0x00)
#define LNB_CMD (7ULL << 0)
#define LNB_CMD_NOP 0
#define LNB_CMD_INIT 1
@@ -260,32 +259,31 @@
#define LNB_CMD_DISEQC 6
#define LNB_CMD_SCIF 7
#define LNB_BUSY BIT_ULL(4)
#define LNB_TONE BIT_ULL(15)
#define LNB_BUSY (1ULL << 4)
#define LNB_TONE (1ULL << 15)
#define LNB_INTERRUPT_BASE 4
#define LNB_STATUS(i) (LNB_BASE + (i) * 0x20 + 0x04)
#define LNB_VOLTAGE(i) (LNB_BASE + (i) * 0x20 + 0x08)
#define LNB_CONFIG(i) (LNB_BASE + (i) * 0x20 + 0x0c)
#define LNB_BUF_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10)
#define LNB_BUF_WRITE(i) (LNB_BASE + (i) * 0x20 + 0x14)
#define LNB_STATUS(i) ((i) * 0x20 + 0x04)
#define LNB_VOLTAGE(i) ((i) * 0x20 + 0x08)
#define LNB_CONFIG(i) ((i) * 0x20 + 0x0c)
#define LNB_BUF_LEVEL(i) ((i) * 0x20 + 0x10)
#define LNB_BUF_WRITE(i) ((i) * 0x20 + 0x14)
#define LNB_SETTING(i) (LNB_BASE + (i) * 0x20 + 0x0c)
#define LNB_FIFO_LEVEL(i) (LNB_BASE + (i) * 0x20 + 0x10)
#define LNB_RESET_FIFO(i) (LNB_BASE + (i) * 0x20 + 0x10)
#define LNB_WRITE_FIFO(i) (LNB_BASE + (i) * 0x20 + 0x14)
#define LNB_SETTING(i) ((i) * 0x20 + 0x0c)
#define LNB_FIFO_LEVEL(i) ((i) * 0x20 + 0x10)
#define LNB_RESET_FIFO(i) ((i) * 0x20 + 0x10)
#define LNB_WRITE_FIFO(i) ((i) * 0x20 + 0x14)
/* ------------------------------------------------------------------------- */
/* CI Interface (only CI-Bridge) */
#define CI_BASE (0x400)
#define CI_CONTROL(i) (CI_BASE + (i) * 32 + 0x00)
#define CI_CONTROL(_ci) ((_ci)->regs + 0x00)
#define CI_DO_ATTRIBUTE_RW(i) (CI_BASE + (i) * 32 + 0x04)
#define CI_DO_IO_RW(i) (CI_BASE + (i) * 32 + 0x08)
#define CI_READDATA(i) (CI_BASE + (i) * 32 + 0x0c)
#define CI_DO_READ_ATTRIBUTES(i) (CI_BASE + (i) * 32 + 0x10)
#define CI_DO_ATTRIBUTE_RW(_ci) ((_ci)->regs + 0x04)
#define CI_DO_IO_RW(_ci) ((_ci)->regs + 0x08)
#define CI_READDATA(_ci) ((_ci)->regs + 0x0c)
#define CI_DO_READ_ATTRIBUTES(_ci) ((_ci)->regs + 0x10)
#define CI_RESET_CAM (0x00000001)
#define CI_POWER_ON (0x00000002)
@@ -305,8 +303,8 @@
#define CI_READ_CMD (0x40000000)
#define CI_WRITE_CMD (0x80000000)
#define CI_BLOCKIO_SEND(i) (CI_BASE + (i) * 32 + 0x14)
#define CI_BLOCKIO_RECEIVE(i) (CI_BASE + (i) * 32 + 0x18)
#define CI_BLOCKIO_SEND(_ci) ((_ci)->regs + 0x14)
#define CI_BLOCKIO_RECEIVE(_ci) ((_ci)->regs + 0x18)
#define CI_BLOCKIO_SEND_COMMAND (0x80000000)
#define CI_BLOCKIO_SEND_COMPLETE_ACK (0x40000000)

View File

@@ -23,7 +23,6 @@
#include "ddbridge.h"
#include "ddbridge-io.h"
#include "ddbridge-i2c.h"
#include "ddbridge-mci.h"
static int default_mod = 3;
@@ -34,6 +33,14 @@ static int direct_mode;
module_param(direct_mode, int, 0444);
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);
/* 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(state);
#ifdef CONFIG_MEDIA_ATTACH
__module_get(THIS_MODULE);
#endif
}
static int ddb_mci_tsconfig(struct mci *state, u32 config)
@@ -252,6 +262,11 @@ static int stop(struct dvb_frontend *fe)
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)
{
struct sx8 *state = fe->demodulator_priv;
@@ -266,10 +281,6 @@ static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
u32 bits_per_symbol = 0;
int i = -1, stat = 0;
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) {
/* Mask out higher modulations and MIS for Basic
@@ -345,7 +356,7 @@ static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config)
state->mci.demod = i;
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->iq_mode = (ts_config > 1);
unlock:
@@ -396,7 +407,7 @@ unlock:
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 mci_base *mci_base = state->mci.base;
@@ -423,6 +434,7 @@ static int start_iq(struct dvb_frontend *fe, u32 flags,
state->mci.demod = 0;
sx8_base->tuner_use_count[input]++;
sx8_base->iq_mode = 2;
mci_set_tuner(fe, input, 1, flags & 0xff, 0x40);
} else {
if ((state->iq_started & 0x07) != state->mci.nr) {
stat = -EBUSY;
@@ -433,11 +445,11 @@ unlock:
mutex_unlock(&mci_base->tuner_lock);
if (stat)
return stat;
mci_set_tuner(fe, input, 1, flags & 0xff, 0);
memset(&cmd, 0, sizeof(cmd));
cmd.command = SX8_CMD_START_IQ;
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.symbol_rate = p->symbol_rate;
cmd.sx8_start_iq.gain = (flags >> 8) & 0xff;
@@ -482,18 +494,21 @@ static int set_parameters(struct dvb_frontend *fe)
stop_iq(fe);
switch (p->modulation) {
case APSK_256:
case APSK_256_L:
mask = 0x7f;
break;
case APSK_128:
mask = 0x3f;
break;
case APSK_64:
case APSK_64_L:
mask = 0x1f;
break;
case APSK_32:
mask = 0x0f;
break;
case APSK_16:
case APSK_16_L:
mask = 0x07;
break;
default:
@@ -502,7 +517,7 @@ static int set_parameters(struct dvb_frontend *fe)
}
stat = start(fe, 3, mask, ts_config);
} else {
stat = start_iq(fe, isi & 0xffffff, 4, ts_config);
stat = start_iq(fe, isi & 0xffffff, ts_config);
}
mutex_unlock(&state->lock);
return stat;
@@ -546,7 +561,10 @@ static int set_input(struct dvb_frontend *fe, int input)
mutex_lock(&state->lock);
stop_iq(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);
return 0;
}
@@ -572,7 +590,6 @@ static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties
static struct dvb_frontend_ops sx8_ops = {
.delsys = { SYS_DVBS, SYS_DVBS2 },
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
.info = {
.name = "DVB-S/S2X",
.frequency_min_hz = 950000000,
@@ -592,7 +609,10 @@ static struct dvb_frontend_ops sx8_ops = {
.tune = tune,
.release = release,
.read_status = read_status,
#ifndef KERNEL_DVB_CORE
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
.set_input = set_input,
#endif
.set_lna = set_lna,
.sleep = sleep,
};
@@ -602,8 +622,10 @@ static int init(struct mci *mci)
struct sx8 *state = (struct sx8 *) mci;
state->mci.demod = SX8_DEMOD_NONE;
#ifndef KERNEL_DVB_CORE
mci->fe.ops.xbar[1] = mci->nr;
mci->fe.dtv_property_cache.input = mci->tuner;
#endif
mutex_init(&state->lock);
return 0;
}
@@ -615,7 +637,7 @@ static int base_init(struct mci_base *mci_base)
return 0;
}
struct mci_cfg ddb_max_sx8_cfg = {
static struct mci_cfg ddb_max_sx8_cfg = {
.type = 0,
.fe_ops = &sx8_ops,
.base_size = sizeof(struct sx8_base),
@@ -623,3 +645,10 @@ struct mci_cfg ddb_max_sx8_cfg = {
.init = 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);
}

View File

@@ -23,9 +23,6 @@
#ifndef _DDBRIDGE_H_
#define _DDBRIDGE_H_
#define DDB_USE_WORK
/*#define DDB_TEST_THREADED*/
#include <linux/version.h>
#if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE)
@@ -150,13 +147,10 @@ struct ddb_info {
u32 type;
#define DDB_NONE 0
#define DDB_OCTOPUS 1
#define DDB_OCTOPUS_CI 2
#define DDB_MOD 3
#define DDB_OCTONET 4
#define DDB_OCTOPUS_MAX 5
#define DDB_OCTOPUS_MAX_CT 6
#define DDB_OCTOPRO 7
#define DDB_OCTOPRO_HDIN 8
#define DDB_OCTOPUS_MCI 9
u32 version;
char *name;
@@ -178,11 +172,14 @@ struct ddb_info {
#define TS_QUIRK_ALT_OSC 8
u8 mci_ports;
u8 mci_type;
u8 ci_mask;
u32 tempmon_irq;
u32 lostlock_irq;
u32 mdio_base;
u32 hw_min;
u32 ci_base;
u32 lnb_base;
const struct ddb_regmap *regmap;
};
@@ -205,11 +202,7 @@ struct ddb_dma {
u32 div;
u32 bufval;
#ifdef DDB_USE_WORK
struct work_struct work;
#else
struct tasklet_struct tasklet;
#endif
spinlock_t lock; /* DMA lock */
wait_queue_head_t wq;
int running;
@@ -254,6 +247,7 @@ struct ddb_ci {
struct dvb_ca_en50221 en;
struct ddb_port *port;
u32 nr;
u32 regs;
};
struct ddb_io {
@@ -327,6 +321,9 @@ struct ddb_port {
#define DDB_TUNER_MCI 48
#define DDB_TUNER_MCI_SX8 (DDB_TUNER_MCI + 0)
#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)
struct ddb_input *input[2];
struct ddb_output *output;

View File

@@ -26,6 +26,9 @@
#include <linux/net.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,
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,
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 = {

View File

@@ -36,7 +36,7 @@
#include <linux/socket.h>
#include <linux/in.h>
#include <asm/uaccess.h>
#include <linux/dvb/ns.h>
#include "ns.h"
#include <media/dvbdev.h>

76
ddbridge/ns.h Normal file
View 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_*/

View File

@@ -7,7 +7,21 @@ API:
Currently DTV_STREAM_ID is misused.
0x10000000 - symbols (locked and tracked) at symbol rate
0x20000000 - samples at ADC rate (1550/24=64.583... MHz)
0x30000000 - samples at symbol rate
0x20000000 - 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

View File

@@ -28,3 +28,7 @@ devices in any way.
adapter_alloc=3 is rcommended when using redirect
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.
Redirect between cards in different IOMMU groups will not work!
Disable IOMMU if you have this problem.

View File

@@ -13,4 +13,3 @@ dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o \
obj-$(CONFIG_DVB_CORE) += dvb-core.o
EXTRA_CFLAGS += -DCONFIG_DVB_DYNAMIC_MINORS -DCONFIG_DVB_NET
#NOSTDINC_FLAGS += -I$(KBUILD_EXTMOD)/include -I$(KBUILD_EXTMOD)/include/linux

View File

@@ -11,3 +11,4 @@ dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
obj-$(CONFIG_DVB_CORE) += dvb-core.o
ccflags-y += -Idrivers/media/dvb-core/
ccflags-y += --include=dd_compat.h

View File

@@ -1,19 +1,9 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* dmxdev.c - DVB demultiplexer device
*
* Copyright (C) 2000 Ralph Metzler & Marcus Metzler
* 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
@@ -369,13 +359,13 @@ static int dvb_dmxdev_set_buffer_size(struct dmxdev_filter *dmxdevfilter,
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 15, 0))
static void dvb_dmxdev_filter_timeout(struct timer_list *t)
{
struct dmxdev_filter *dmxdevfilter = from_timer(dmxdevfilter, t, timer);
struct dmxdev_filter *dmxdevfilter = from_timer(dmxdevfilter, t, timer);
dmxdevfilter->buffer.error = -ETIMEDOUT;
spin_lock_irq(&dmxdevfilter->dev->lock);
dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT;
spin_unlock_irq(&dmxdevfilter->dev->lock);
wake_up(&dmxdevfilter->buffer.queue);
dmxdevfilter->buffer.error = -ETIMEDOUT;
spin_lock_irq(&dmxdevfilter->dev->lock);
dmxdevfilter->state = DMXDEV_STATE_TIMEDOUT;
spin_unlock_irq(&dmxdevfilter->dev->lock);
wake_up(&dmxdevfilter->buffer.queue);
}
static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
@@ -384,8 +374,8 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
del_timer(&dmxdevfilter->timer);
if (para->timeout) {
dmxdevfilter->timer.expires =
jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000;
dmxdevfilter->timer.expires =
jiffies + 1 + (HZ / 2 + HZ * para->timeout) / 1000;
add_timer(&dmxdevfilter->timer);
}
}
@@ -415,6 +405,7 @@ static void dvb_dmxdev_filter_timer(struct dmxdev_filter *dmxdevfilter)
}
}
#endif
static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len,
struct dmx_section_filter *filter,
@@ -475,11 +466,14 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len,
static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len,
const u8 *buffer2, size_t buffer2_len,
struct dmx_ts_feed *feed,
u32 *buffer_flags)
struct dmx_ts_feed *feed,
u32 *buffer_flags)
{
struct dmxdev_filter *dmxdevfilter = feed->priv;
struct dvb_ringbuffer *buffer;
#ifdef CONFIG_DVB_MMAP
struct dvb_vb2_ctx *ctx;
#endif
int ret;
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,
secfeed,
dvb_dmxdev_section_callback);
if (ret < 0) {
if (!*secfeed) {
pr_err("DVB (%s): could not alloc feed\n",
__func__);
return ret;
@@ -846,6 +840,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
if (dmxdev->exit) {
mutex_unlock(&dmxdev->mutex);
return -ENODEV;
}
for (i = 0; i < dmxdev->filternum; i++)
if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
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 i;
int i, ret;
if (dmxdev->demux->open(dmxdev->demux) < 0)
return -EUSERS;
@@ -1505,21 +1504,36 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter)
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_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);
if (ret < 0)
goto err_register_dvr_dvbdev;
dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192);
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);
void dvb_dmxdev_release(struct dmxdev *dmxdev)
{
mutex_lock(&dmxdev->mutex);
dmxdev->exit = 1;
mutex_unlock(&dmxdev->mutex);
if (dmxdev->dvbdev->users > 1) {
wait_event(dmxdev->dvbdev->wait_queue,
dmxdev->dvbdev->users == 1);

View File

@@ -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
*
@@ -164,7 +164,7 @@ static void dvb_ca_private_free(struct dvb_ca_private *ca)
{
unsigned int i;
dvb_free_device(ca->dvbdev);
dvb_device_put(ca->dvbdev);
for (i = 0; i < ca->slot_count; i++)
vfree(ca->slot_info[i].rx_buffer.data);
@@ -194,10 +194,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,
u8 *ebuf, int ecount);
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
u8 *ebuf, int ecount);
u8 *ebuf, int ecount, u8 flags);
/**
* Safely find needle in haystack.
* findstr - Safely find needle in haystack.
*
* @haystack: Buffer to look in.
* @hlen: Number of bytes in haystack.
@@ -377,7 +377,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);
if (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)
return -EIO;
ret = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
@@ -629,8 +629,8 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot)
* @ca: CA instance.
* @slot: Slot to read from.
* @ebuf: If non-NULL, the data will be written to this buffer. If NULL,
* the data will be added into the buffering system as a normal
* fragment.
* the data will be added into the buffering system as a normal
* fragment.
* @ecount: Size of ebuf. Ignored if ebuf is NULL.
*
* return: Number of bytes read, or < 0 on error
@@ -783,20 +783,20 @@ exit:
* @ca: CA instance.
* @slot: Slot to write 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.
*
* return: Number of bytes written, or < 0 on error.
*/
static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
u8 *buf, int bytes_write)
u8 *buf, int bytes_write, u8 flags)
{
struct dvb_ca_slot *sl = &ca->slot_info[slot];
int status;
int i;
dprintk("%s\n", __func__);
flags=0;
/* sanity check */
if (bytes_write > sl->link_buf_size)
return -EINVAL;
@@ -824,7 +824,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
/* OK, set HC bit */
status = ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND,
IRQEN | CMDREG_HC);
IRQEN | CMDREG_HC | flags);
if (status)
goto exit;
@@ -894,7 +894,7 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot,
buf[0], (buf[1] & 0x80) == 0, bytes_write);
exit:
ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN);
ca->pub->write_cam_control(ca->pub, slot, CTRLIF_COMMAND, IRQEN | flags);
exitnowrite:
return status;
@@ -1013,7 +1013,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_frda_irq);
/* EN50221 thread functions */
/**
* Wake up the DVB CA thread
* dvb_ca_en50221_thread_wakeup - Wake up the DVB CA thread
*
* @ca: CA instance.
*/
@@ -1027,7 +1027,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.
*/
@@ -1085,7 +1085,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.
* @slot: Slot to process.
@@ -1116,7 +1116,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.
* @slot: Slot to process.
@@ -1268,7 +1269,7 @@ static void dvb_ca_en50221_thread_state_machine(struct dvb_ca_private *ca,
sl->slot_state = DVB_CA_SLOTSTATE_RUNNING;
dvb_ca_en50221_thread_update_delay(ca);
pr_info("dvb_ca adapter %d: DVB CAM detected and initialised successfully\n",
ca->dvbdev->adapter->num);
ca->dvbdev->adapter->num);
break;
case DVB_CA_SLOTSTATE_RUNNING:
@@ -1347,13 +1348,14 @@ static int dvb_ca_en50221_thread(void *data)
/* EN50221 IO interface functions */
/**
* Real ioctl implementation.
* NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
* dvb_ca_en50221_io_do_ioctl - Real ioctl implementation.
*
* @file: File concerned.
* @cmd: IOCTL command.
* @parg: Associated argument.
*
* NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them.
*
* return: 0 on success, <0 on error.
*/
static int dvb_ca_en50221_io_do_ioctl(struct file *file,
@@ -1407,7 +1409,9 @@ static int dvb_ca_en50221_io_do_ioctl(struct file *file,
err = -EINVAL;
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->flags = 0;
sl = &ca->slot_info[slot];
@@ -1431,7 +1435,7 @@ out_unlock:
}
/**
* Wrapper for ioctl implementation.
* dvb_ca_en50221_io_ioctl - Wrapper for ioctl implementation.
*
* @file: File concerned.
* @cmd: IOCTL command.
@@ -1446,7 +1450,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.
* @buf: Source buffer.
@@ -1529,7 +1533,7 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
mutex_lock(&sl->slot_lock);
status = dvb_ca_en50221_write_data(ca, slot, fragbuf,
fraglen + 2);
fraglen + 2, 0);
mutex_unlock(&sl->slot_lock);
if (status == (fraglen + 2)) {
written = 1;
@@ -1603,7 +1607,7 @@ nextslot:
}
/**
* Implementation of read() syscall.
* dvb_ca_en50221_io_read - Implementation of read() syscall.
*
* @file: File structure.
* @buf: Destination buffer.
@@ -1714,7 +1718,7 @@ exit:
}
/**
* Implementation of file open syscall.
* dvb_ca_en50221_io_open - Implementation of file open syscall.
*
* @inode: Inode concerned.
* @file: File concerned.
@@ -1764,7 +1768,7 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file)
}
/**
* Implementation of file close syscall.
* dvb_ca_en50221_io_release - Implementation of file close syscall.
*
* @inode: Inode concerned.
* @file: File concerned.
@@ -1793,7 +1797,7 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file)
}
/**
* Implementation of poll() syscall.
* dvb_ca_en50221_io_poll - Implementation of poll() syscall.
*
* @file: File concerned.
* @wait: poll wait table.
@@ -1855,7 +1859,7 @@ static const struct dvb_device dvbdev_ca = {
/* 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.
* @pubca: The dvb_ca instance.
@@ -1947,7 +1951,7 @@ exit:
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.
*/

View File

@@ -1,20 +1,10 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* dvb_demux.c - DVB kernel demux API
*
* Copyright (C) 2000-2001 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
* 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
@@ -256,7 +246,7 @@ static int dvb_dmx_swfilter_section_copy_dump(struct dvb_demux_feed *feed,
{
struct dvb_demux *demux = feed->demux;
struct dmx_section_feed *sec = &feed->feed.sec;
u16 limit, seclen, n;
u16 limit, seclen;
if (sec->tsfeedp >= DMX_MAX_SECFEED_SIZE)
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 */
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);
if (seclen <= 0 || seclen > DMX_MAX_SECTION_SIZE
|| seclen + sec->secbufp > limit)
@@ -489,8 +479,8 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
}
dprintk_tscheck("TS packet counter mismatch. PID=0x%x expected 0x%x got 0x%x\n",
pid, demux->cnt_storage[pid],
buf[3] & 0xf);
pid, demux->cnt_storage[pid],
buf[3] & 0xf);
demux->cnt_storage[pid] = buf[3] & 0xf;
}
}

View File

@@ -20,6 +20,7 @@
#include <linux/version.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0))
#include <linux/sched/signal.h>
#include <linux/nospec.h>
#else
#include <linux/sched.h>
#endif
@@ -140,7 +141,7 @@ static void __dvb_frontend_free(struct dvb_frontend *fe)
struct dvb_frontend_private *fepriv = fe->frontend_priv;
if (fepriv)
dvb_free_device(fepriv->dvbdev);
dvb_device_put(fepriv->dvbdev);
dvb_frontend_invoke_release(fe, fe->ops.release);
@@ -487,6 +488,10 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache, tmp;
if (fepriv->max_drift)
dev_warn_once(fe->dvb->device,
"Frontend requested software zigzag, but didn't set the frequency step size\n");
/* if we've got no parameters, just keep idling */
if (fepriv->state & FESTATE_IDLE) {
fepriv->delay = 3 * HZ;
@@ -919,6 +924,7 @@ static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe,
/* If the standard is for satellite, convert frequencies to kHz */
switch (c->delivery_system) {
case SYS_DSS:
case SYS_DVBS:
case SYS_DVBS2:
case SYS_TURBO:
@@ -944,6 +950,7 @@ static u32 dvb_frontend_get_stepsize(struct dvb_frontend *fe)
u32 step = max(fe_step, tuner_step);
switch (c->delivery_system) {
case SYS_DSS:
case SYS_DVBS:
case SYS_DVBS2:
case SYS_TURBO:
@@ -975,6 +982,7 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
/* range check: symbol rate */
switch (c->delivery_system) {
case SYS_DSS:
case SYS_DVBS:
case SYS_DVBS2:
case SYS_TURBO:
@@ -990,6 +998,7 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe)
fe->ops.info.symbol_rate_max);
return -EINVAL;
}
break;
default:
break;
}
@@ -1041,6 +1050,10 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
c->input = NO_INPUT;
switch (c->delivery_system) {
case SYS_DSS:
c->modulation = QPSK;
c->rolloff = ROLLOFF_20;
break;
case SYS_DVBS:
case SYS_DVBS2:
case SYS_TURBO:
@@ -1065,108 +1078,100 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
return 0;
}
#define _DTV_CMD(n, s, b) \
[n] = { \
.name = #n, \
.cmd = n, \
.set = s,\
.buffer = b \
}
#define _DTV_CMD(n) \
[n] = #n
struct dtv_cmds_h {
char *name; /* A display name for debugging purposes */
__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),
static char *dtv_cmds[DTV_MAX_COMMAND + 1] = {
_DTV_CMD(DTV_TUNE),
_DTV_CMD(DTV_CLEAR),
/* Set */
_DTV_CMD(DTV_FREQUENCY, 1, 0),
_DTV_CMD(DTV_BANDWIDTH_HZ, 1, 0),
_DTV_CMD(DTV_MODULATION, 1, 0),
_DTV_CMD(DTV_INVERSION, 1, 0),
_DTV_CMD(DTV_DISEQC_MASTER, 1, 1),
_DTV_CMD(DTV_SYMBOL_RATE, 1, 0),
_DTV_CMD(DTV_INNER_FEC, 1, 0),
_DTV_CMD(DTV_VOLTAGE, 1, 0),
_DTV_CMD(DTV_TONE, 1, 0),
_DTV_CMD(DTV_PILOT, 1, 0),
_DTV_CMD(DTV_ROLLOFF, 1, 0),
_DTV_CMD(DTV_DELIVERY_SYSTEM, 1, 0),
_DTV_CMD(DTV_HIERARCHY, 1, 0),
_DTV_CMD(DTV_CODE_RATE_HP, 1, 0),
_DTV_CMD(DTV_CODE_RATE_LP, 1, 0),
_DTV_CMD(DTV_GUARD_INTERVAL, 1, 0),
_DTV_CMD(DTV_TRANSMISSION_MODE, 1, 0),
_DTV_CMD(DTV_INTERLEAVING, 1, 0),
_DTV_CMD(DTV_FREQUENCY),
_DTV_CMD(DTV_BANDWIDTH_HZ),
_DTV_CMD(DTV_MODULATION),
_DTV_CMD(DTV_INVERSION),
_DTV_CMD(DTV_DISEQC_MASTER),
_DTV_CMD(DTV_SYMBOL_RATE),
_DTV_CMD(DTV_INNER_FEC),
_DTV_CMD(DTV_VOLTAGE),
_DTV_CMD(DTV_TONE),
_DTV_CMD(DTV_PILOT),
_DTV_CMD(DTV_ROLLOFF),
_DTV_CMD(DTV_DELIVERY_SYSTEM),
_DTV_CMD(DTV_HIERARCHY),
_DTV_CMD(DTV_CODE_RATE_HP),
_DTV_CMD(DTV_CODE_RATE_LP),
_DTV_CMD(DTV_GUARD_INTERVAL),
_DTV_CMD(DTV_TRANSMISSION_MODE),
_DTV_CMD(DTV_INTERLEAVING),
_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
_DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0),
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0),
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),
_DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION),
_DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING),
_DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID),
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX),
_DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT),
_DTV_CMD(DTV_ISDBT_LAYER_ENABLED),
_DTV_CMD(DTV_ISDBT_LAYERA_FEC),
_DTV_CMD(DTV_ISDBT_LAYERA_MODULATION),
_DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT),
_DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING),
_DTV_CMD(DTV_ISDBT_LAYERB_FEC),
_DTV_CMD(DTV_ISDBT_LAYERB_MODULATION),
_DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT),
_DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING),
_DTV_CMD(DTV_ISDBT_LAYERC_FEC),
_DTV_CMD(DTV_ISDBT_LAYERC_MODULATION),
_DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT),
_DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING),
_DTV_CMD(DTV_STREAM_ID, 1, 0),
_DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY, 1, 0),
_DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, 1, 0),
_DTV_CMD(DTV_LNA, 1, 0),
_DTV_CMD(DTV_INPUT, 1, 0),
_DTV_CMD(DTV_STREAM_ID),
_DTV_CMD(DTV_DVBT2_PLP_ID_LEGACY),
_DTV_CMD(DTV_SCRAMBLING_SEQUENCE_INDEX),
_DTV_CMD(DTV_LNA),
_DTV_CMD(DTV_INPUT),
/* Get */
_DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1),
_DTV_CMD(DTV_API_VERSION, 0, 0),
_DTV_CMD(DTV_DISEQC_SLAVE_REPLY),
_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_RS_FRAME_ENSEMBLE, 1, 0),
_DTV_CMD(DTV_ATSCMH_PARADE_ID),
_DTV_CMD(DTV_ATSCMH_RS_FRAME_ENSEMBLE),
_DTV_CMD(DTV_ATSCMH_FIC_VER, 0, 0),
_DTV_CMD(DTV_ATSCMH_NOG, 0, 0),
_DTV_CMD(DTV_ATSCMH_TNOG, 0, 0),
_DTV_CMD(DTV_ATSCMH_SGN, 0, 0),
_DTV_CMD(DTV_ATSCMH_PRC, 0, 0),
_DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE, 0, 0),
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI, 0, 0),
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC, 0, 0),
_DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE, 0, 0),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_A, 0, 0),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B, 0, 0),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C, 0, 0),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D, 0, 0),
_DTV_CMD(DTV_ATSCMH_FIC_VER),
_DTV_CMD(DTV_ATSCMH_NOG),
_DTV_CMD(DTV_ATSCMH_TNOG),
_DTV_CMD(DTV_ATSCMH_SGN),
_DTV_CMD(DTV_ATSCMH_PRC),
_DTV_CMD(DTV_ATSCMH_RS_FRAME_MODE),
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_PRI),
_DTV_CMD(DTV_ATSCMH_RS_CODE_MODE_SEC),
_DTV_CMD(DTV_ATSCMH_SCCC_BLOCK_MODE),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_A),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_B),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_C),
_DTV_CMD(DTV_ATSCMH_SCCC_CODE_MODE_D),
/* Statistics API */
_DTV_CMD(DTV_STAT_SIGNAL_STRENGTH, 0, 0),
_DTV_CMD(DTV_STAT_CNR, 0, 0),
_DTV_CMD(DTV_STAT_PRE_ERROR_BIT_COUNT, 0, 0),
_DTV_CMD(DTV_STAT_PRE_TOTAL_BIT_COUNT, 0, 0),
_DTV_CMD(DTV_STAT_POST_ERROR_BIT_COUNT, 0, 0),
_DTV_CMD(DTV_STAT_POST_TOTAL_BIT_COUNT, 0, 0),
_DTV_CMD(DTV_STAT_ERROR_BLOCK_COUNT, 0, 0),
_DTV_CMD(DTV_STAT_TOTAL_BLOCK_COUNT, 0, 0),
_DTV_CMD(DTV_STAT_SIGNAL_STRENGTH),
_DTV_CMD(DTV_STAT_CNR),
_DTV_CMD(DTV_STAT_PRE_ERROR_BIT_COUNT),
_DTV_CMD(DTV_STAT_PRE_TOTAL_BIT_COUNT),
_DTV_CMD(DTV_STAT_POST_ERROR_BIT_COUNT),
_DTV_CMD(DTV_STAT_POST_TOTAL_BIT_COUNT),
_DTV_CMD(DTV_STAT_ERROR_BLOCK_COUNT),
_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
* 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.
@@ -1349,8 +1354,9 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
struct file *file)
{
int ncaps;
unsigned int len = 1;
switch(tvp->cmd) {
switch (tvp->cmd) {
case DTV_ENUM_DELSYS:
ncaps = 0;
while (ncaps < MAX_DELSYS && fe->ops.delsys[ncaps]) {
@@ -1358,6 +1364,7 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
ncaps++;
}
tvp->u.buffer.len = ncaps;
len = ncaps;
break;
case DTV_FREQUENCY:
tvp->u.data = c->frequency;
@@ -1543,27 +1550,51 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
/* Fill quality measures */
case DTV_STAT_SIGNAL_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;
case DTV_STAT_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;
case DTV_STAT_PRE_ERROR_BIT_COUNT:
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;
case DTV_STAT_PRE_TOTAL_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;
case DTV_STAT_POST_ERROR_BIT_COUNT:
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;
case DTV_STAT_POST_TOTAL_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;
case DTV_STAT_ERROR_BLOCK_COUNT:
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;
case DTV_STAT_TOTAL_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;
default:
dev_dbg(fe->dvb->device,
@@ -1572,18 +1603,13 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
return -EINVAL;
}
if (!dtv_cmds[tvp->cmd].buffer)
dev_dbg(fe->dvb->device,
"%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,
"%s: GET cmd 0x%08x (%s) len %d: %*ph\n",
__func__,
tvp->cmd, dtv_cmds[tvp->cmd].name,
tvp->u.buffer.len,
tvp->u.buffer.len, tvp->u.buffer.data);
if (len < 1)
len = 1;
dev_dbg(fe->dvb->device,
"%s: GET cmd 0x%08x (%s) len %d: %*ph\n",
__func__, tvp->cmd, dtv_cmd_name(tvp->cmd),
tvp->u.buffer.len, tvp->u.buffer.len, tvp->u.buffer.data);
return 0;
}
@@ -1806,6 +1832,54 @@ static int dvbv3_set_delivery_system(struct dvb_frontend *fe)
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
* @fe: Pointer to &struct dvb_frontend
@@ -1834,7 +1908,7 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
else
dev_dbg(fe->dvb->device,
"%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) {
case DTV_CLEAR:
/*
@@ -2204,7 +2278,6 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
{
struct dvb_frontend_private *fepriv = fe->frontend_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
struct dvb_frontend_tune_settings fetunesettings;
u32 rolloff = 0;
if (dvb_frontend_check_parameters(fe) < 0)
@@ -2247,6 +2320,9 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
case SYS_DVBC_ANNEX_C:
rolloff = 113;
break;
case SYS_DSS:
rolloff = 120;
break;
case SYS_DVBS:
case SYS_TURBO:
case SYS_ISDBS:
@@ -2282,46 +2358,7 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
if (c->hierarchy == HIERARCHY_NONE && c->code_rate_LP == FEC_NONE)
c->code_rate_LP = FEC_AUTO;
/* get frontend-specific tuning settings */
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;
prepare_tuning_algo_parameters(fe);
fepriv->state = FESTATE_RETUNE;
@@ -2336,7 +2373,6 @@ static int dtv_set_frontend(struct dvb_frontend *fe)
return 0;
}
static int dvb_get_property(struct dvb_frontend *fe, struct file *file,
struct dtv_properties *tvps)
{
@@ -2557,8 +2593,7 @@ static int dvb_frontend_handle_ioctl(struct file *file,
case FE_DISEQC_SEND_BURST:
if (fe->ops.diseqc_send_burst) {
err = fe->ops.diseqc_send_burst(fe,
(enum fe_sec_mini_cmd)parg);
err = fe->ops.diseqc_send_burst(fe, (long)parg);
fepriv->state = FESTATE_DISEQC;
fepriv->status = 0;
}
@@ -2566,9 +2601,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
case FE_SET_TONE:
if (fe->ops.set_tone) {
err = fe->ops.set_tone(fe,
(enum fe_sec_tone_mode)parg);
fepriv->tone = (enum fe_sec_tone_mode)parg;
fepriv->tone = (long)parg;
err = fe->ops.set_tone(fe, fepriv->tone);
fepriv->state = FESTATE_DISEQC;
fepriv->status = 0;
}
@@ -2576,9 +2610,8 @@ static int dvb_frontend_handle_ioctl(struct file *file,
case FE_SET_VOLTAGE:
if (fe->ops.set_voltage) {
err = fe->ops.set_voltage(fe,
(enum fe_sec_voltage)parg);
fepriv->voltage = (enum fe_sec_voltage)parg;
fepriv->voltage = (long)parg;
err = fe->ops.set_voltage(fe, fepriv->voltage);
fepriv->state = FESTATE_DISEQC;
fepriv->status = 0;
}
@@ -2742,7 +2775,6 @@ typedef unsigned int __poll_t;
#define EPOLLOUT POLLOUT
#endif
static __poll_t dvb_frontend_poll(struct file *file, struct poll_table_struct *wait)
{
struct dvb_device *dvbdev = file->private_data;
@@ -2771,7 +2803,17 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
if (fe->exit == DVB_FE_DEVICE_REMOVED)
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);
if (!adapter->mfe_dvbdev)
@@ -2949,7 +2991,9 @@ int dvb_frontend_suspend(struct dvb_frontend *fe)
else if (fe->ops.tuner_ops.sleep)
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);
return ret;
@@ -2965,7 +3009,9 @@ int dvb_frontend_resume(struct dvb_frontend *fe)
fe->id);
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);
if (fe->ops.tuner_ops.resume)
@@ -2999,6 +3045,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
.name = fe->ops.info.name,
#endif
};
int ret;
dev_dbg(dvb->device, "%s:\n", __func__);
@@ -3028,12 +3075,18 @@ int dvb_register_frontend(struct dvb_adapter *dvb,
fe->dvb = dvb;
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,
"DVB: registering adapter %i frontend %i (%s)...\n",
fe->dvb->num, fe->id, fe->ops.info.name);
dvb_register_device(fe->dvb, &fepriv->dvbdev, &dvbdev_template,
fe, DVB_DEVICE_FRONTEND, 0);
fe->dvb->num, fepriv->dvbdev->id, fe->ops.info.name);
/*
* Initialize the cache to the proper values according with the

View File

@@ -60,6 +60,9 @@
#include <media/dvb_demux.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 )
{
@@ -215,7 +218,7 @@ static int ule_exthdr_padding(struct dvb_net_priv *p)
}
/*
* Handle ULE extension headers.
* Handle ULE extension headers.
* Function is called after a successful CRC32 verification of an ULE SNDU to complete its decoding.
* Returns: >= 0: nr. of bytes consumed by next extension header
* -1: Mandatory extension header that is not recognized or TEST SNDU; discard.
@@ -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->ts_remain -= 1;
h->from_where += 1;
/* fallthrough */
fallthrough;
case 0:
h->new_ts = 1;
h->ts += TS_SZ;
@@ -662,7 +665,7 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
h->ts_remain > 2 ?
*(unsigned short *)h->from_where : 0);
#ifdef DVB_ULE_DEBUG
#ifdef DVB_ULE_DEBUG
hexdump(iov[0].iov_base, iov[0].iov_len);
hexdump(iov[1].iov_base, iov[1].iov_len);
hexdump(iov[2].iov_base, iov[2].iov_len);
@@ -678,7 +681,7 @@ static void dvb_net_ule_check_crc(struct dvb_net_ule_handle *h,
hexdump(ule_where - TS_SZ, TS_SZ);
}
ule_dump = 1;
#endif
#endif
h->dev->stats.rx_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,
struct dmx_section_filter **secfilter,
u8 *mac, u8 *mac_mask)
const u8 *mac, u8 *mac_mask)
{
struct dvb_net_priv *priv = netdev_priv(dev);
int ret;
@@ -1062,7 +1065,7 @@ static int dvb_net_feed_start(struct net_device *dev)
int ret = 0, i;
struct dvb_net_priv *priv = netdev_priv(dev);
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);
mutex_lock(&priv->mutex);
@@ -1282,8 +1285,11 @@ static int dvb_net_set_mac (struct net_device *dev, void *p)
struct dvb_net_priv *priv = netdev_priv(dev);
struct sockaddr *addr=p;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0))
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
#else
eth_hw_addr_set(dev, addr->sa_data);
#endif
if (netif_running(dev))
schedule_work(&priv->restart_net_feed_wq);
@@ -1381,8 +1387,11 @@ static int dvb_net_add_if(struct dvb_net *dvbnet, u16 pid, u8 feedtype)
dvbnet->dvbdev->adapter->num, if_num);
net->addr_len = 6;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 17, 0))
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;
priv = netdev_priv(net);
@@ -1477,14 +1486,21 @@ static int dvb_net_do_ioctl(struct file *file,
struct net_device *netdev;
struct dvb_net_priv *priv_data;
struct dvb_net_if *dvbnetif = parg;
int if_num = dvbnetif->if_num;
if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
!dvbnet->state[dvbnetif->if_num]) {
if (if_num >= DVB_NET_DEVICES_MAX) {
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;
goto ioctl_error;
}
netdev = dvbnet->device[dvbnetif->if_num];
netdev = dvbnet->device[if_num];
priv_data = netdev_priv(netdev);
dvbnetif->pid=priv_data->pid;
@@ -1537,14 +1553,21 @@ static int dvb_net_do_ioctl(struct file *file,
struct net_device *netdev;
struct dvb_net_priv *priv_data;
struct __dvb_net_if_old *dvbnetif = parg;
int if_num = dvbnetif->if_num;
if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
!dvbnet->state[dvbnetif->if_num]) {
if (if_num >= DVB_NET_DEVICES_MAX) {
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;
goto ioctl_error;
}
netdev = dvbnet->device[dvbnetif->if_num];
netdev = dvbnet->device[if_num];
priv_data = netdev_priv(netdev);
dvbnetif->pid=priv_data->pid;

View File

@@ -63,7 +63,7 @@ int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
* this pairs with smp_store_release() in dvb_ringbuffer_write(),
* 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));
#endif
@@ -75,7 +75,7 @@ ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
{
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(),
* dvb_ringbuffer_read_user(), dvb_ringbuffer_flush(),
* or dvb_ringbuffer_reset()
@@ -171,7 +171,7 @@ ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, si
#else
/* smp_store_release() for read pointer update to ensure
* 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);
#endif
@@ -203,7 +203,7 @@ void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
#else
/* smp_store_release() for read pointer update to ensure
* 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);
#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;
}
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) {

View File

@@ -5,10 +5,6 @@
* Copyright (C) 2015 Samsung Electronics
*
* 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>
@@ -358,6 +354,12 @@ 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)
{
struct vb2_queue *q = &ctx->vb_q;
if (b->index >= q->num_buffers) {
dprintk(1, "[%s] buffer index out of range\n", ctx->name);
return -EINVAL;
}
vb2_core_querybuf(&ctx->vb_q, b->index, b);
dprintk(3, "[%s] index=%d\n", ctx->name, b->index);
return 0;
@@ -382,8 +384,13 @@ 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)
{
struct vb2_queue *q = &ctx->vb_q;
int ret;
if (b->index >= q->num_buffers) {
dprintk(1, "[%s] buffer index out of range\n", ctx->name);
return -EINVAL;
}
ret = vb2_core_qbuf(&ctx->vb_q, b->index, b, NULL);
if (ret) {
dprintk(1, "[%s] index=%d errno=%d\n", ctx->name,

View File

@@ -1,20 +1,10 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* dvbdev.c
*
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
* 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
@@ -86,6 +76,10 @@ static const u8 minor_type[] = {
[DVB_DEVICE_CA] = 6,
[DVB_DEVICE_NET] = 7,
[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) \
@@ -114,7 +108,7 @@ static int dvb_device_open(struct inode *inode, struct file *file)
new_fops = fops_get(dvbdev->fops);
if (!new_fops)
goto fail;
file->private_data = dvbdev;
file->private_data = dvb_device_get(dvbdev);
replace_fops(file, new_fops);
if (file->f_op->open)
err = file->f_op->open(inode, file);
@@ -178,6 +172,9 @@ int dvb_generic_release(struct inode *inode, struct file *file)
}
dvbdev->users++;
dvb_device_put(dvbdev);
return 0;
}
EXPORT_SYMBOL(dvb_generic_release);
@@ -248,6 +245,7 @@ static void dvb_media_device_free(struct dvb_device *dvbdev)
if (dvbdev->adapter->conn) {
media_device_unregister_entity(dvbdev->adapter->conn);
kfree(dvbdev->adapter->conn);
dvbdev->adapter->conn = NULL;
kfree(dvbdev->adapter->conn_pads);
dvbdev->adapter->conn_pads = NULL;
@@ -259,7 +257,7 @@ static void dvb_media_device_free(struct dvb_device *dvbdev)
static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
const char *name, int npads)
{
int i, ret = 0;
int i;
dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads),
GFP_KERNEL);
@@ -276,6 +274,7 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev,
for (i = 0; i < npads; i++) {
struct media_pad *pads = &dvbdev->tsout_pads[i];
struct media_entity *entity = &dvbdev->tsout_entity[i];
int ret;
entity->name = kasprintf(GFP_KERNEL, "%s #%d", name, i);
if (!entity->name)
@@ -346,8 +345,9 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev,
if (npads) {
dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads),
GFP_KERNEL);
if (!dvbdev->pads){
if (!dvbdev->pads) {
kfree(dvbdev->entity);
dvbdev->entity = NULL;
return -ENOMEM;
}
}
@@ -494,6 +494,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
}
memcpy(dvbdev, template, sizeof(struct dvb_device));
kref_init(&dvbdev->ref);
dvbdev->type = type;
dvbdev->id = id;
dvbdev->adapter = adap;
@@ -512,6 +513,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
break;
if (minor == MAX_DVB_MINORS) {
list_del (&dvbdev->list_head);
kfree(dvbdevfops);
kfree(dvbdev);
up_write(&minor_rwsem);
@@ -523,7 +525,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
#endif
dvbdev->minor = minor;
dvb_minors[minor] = dvbdev;
dvb_minors[minor] = dvb_device_get(dvbdev);
up_write(&minor_rwsem);
ret = dvb_register_media_device(dvbdev, type, minor, demux_sink_pads);
@@ -532,6 +534,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
__func__);
dvb_media_device_free(dvbdev);
list_del (&dvbdev->list_head);
kfree(dvbdevfops);
kfree(dvbdev);
mutex_unlock(&dvbdev_register_lock);
@@ -546,6 +549,10 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
if (IS_ERR(clsdev)) {
pr_err("%s: failed to create device dvb%d.%s%d (%ld)\n",
__func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
dvb_media_device_free(dvbdev);
list_del (&dvbdev->list_head);
kfree(dvbdevfops);
kfree(dvbdev);
return PTR_ERR(clsdev);
}
dprintk("DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
@@ -563,6 +570,7 @@ void dvb_remove_device(struct dvb_device *dvbdev)
down_write(&minor_rwsem);
dvb_minors[dvbdev->minor] = NULL;
dvb_device_put(dvbdev);
up_write(&minor_rwsem);
dvb_media_device_free(dvbdev);
@@ -574,21 +582,34 @@ void dvb_remove_device(struct dvb_device *dvbdev)
EXPORT_SYMBOL(dvb_remove_device);
void dvb_free_device(struct dvb_device *dvbdev)
static void dvb_free_device(struct kref *ref)
{
if (!dvbdev)
return;
struct dvb_device *dvbdev = container_of(ref, struct dvb_device, ref);
kfree (dvbdev->fops);
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)
{
dvb_remove_device(dvbdev);
dvb_free_device(dvbdev);
dvb_device_put(dvbdev);
}
EXPORT_SYMBOL(dvb_unregister_device);
@@ -987,7 +1008,7 @@ struct i2c_client *dvb_module_probe(const char *module_name,
unsigned char addr,
void *platform_data)
{
struct i2c_client *client;
struct i2c_client *client;
struct i2c_board_info *board_info;
board_info = kzalloc(sizeof(*board_info), GFP_KERNEL);
@@ -1030,9 +1051,13 @@ EXPORT_SYMBOL_GPL(dvb_module_release);
#endif
#endif
#if (KERNEL_VERSION(6, 2, 0) > LINUX_VERSION_CODE)
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_DEVICE_TYPE=%s", dnames[dvbdev->type]);
@@ -1040,9 +1065,13 @@ static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
#if (KERNEL_VERSION(6, 2, 0) > LINUX_VERSION_CODE)
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",
dvbdev->adapter->num, dnames[dvbdev->type], dvbdev->id);
@@ -1065,7 +1094,11 @@ static int __init init_dvbdev(void)
goto error;
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,4,0))
dvb_class = class_create(THIS_MODULE, "dvb");
#else
dvb_class = class_create("dvb");
#endif
if (IS_ERR(dvb_class)) {
retval = PTR_ERR(dvb_class);
goto error;

View File

@@ -4,6 +4,7 @@
ccflags-y += -I$(srctree)/drivers/media/dvb-core/
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
ifdef CONFIG_DVB_RTL2832_SDR

View File

@@ -1566,7 +1566,7 @@ static int SetOperationMode(struct drxk_state *state, enum OperationMode oMode)
case OM_QAM_ITU_B:
status = -1;
break;
case OM_QAM_ITU_A: /* fallthrough */
case OM_QAM_ITU_A:
case OM_QAM_ITU_C:
CHK_ERROR(MPEGTSStop(state));
CHK_ERROR(PowerDownQAM(state));
@@ -1589,7 +1589,7 @@ static int SetOperationMode(struct drxk_state *state, enum OperationMode oMode)
case OM_QAM_ITU_B:
status = -1;
break;
case OM_QAM_ITU_A: /* fallthrough */
case OM_QAM_ITU_A:
case OM_QAM_ITU_C:
state->m_OperationMode = oMode;
CHK_ERROR(SetQAMStandard(state,oMode));
@@ -1765,7 +1765,7 @@ static int MPEGTSDtoSetup(struct drxk_state *state, enum OperationMode oMode)
fecOcRcnCtlRate = 0xC00000;
staticCLK = state->m_DVBTStaticCLK;
break;
case OM_QAM_ITU_A: /* fallthrough */
case OM_QAM_ITU_A:
case OM_QAM_ITU_C:
fecOcTmdMode = 0x0004;
fecOcRcnCtlRate = 0xD2B4EE; /* good for >63 Mb/s */
@@ -2804,12 +2804,12 @@ static int DVBTScCommand(struct drxk_state *state,
case OFDM_SC_RA_RAM_CMD_PROGRAM_PARAM:
status = Write16_0(state, OFDM_SC_RA_RAM_PARAM1__A, param1);
/* All commands using 1 parameters */
/* fall through */
fallthrough;
case OFDM_SC_RA_RAM_CMD_SET_ECHO_TIMING:
case OFDM_SC_RA_RAM_CMD_USER_IO:
status = Write16_0(state, OFDM_SC_RA_RAM_PARAM0__A, param0);
/* All commands using 0 parameters */
/* fall through */
fallthrough;
case OFDM_SC_RA_RAM_CMD_GET_OP_PARAM:
case OFDM_SC_RA_RAM_CMD_NULL:
/* Write command */
@@ -3218,7 +3218,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
default:
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_MODE__M;
/* try first guess DRX_FFTMODE_8K */
/* fall through */
fallthrough;
case TRANSMISSION_MODE_8K:
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_MODE_8K;
break;
@@ -3237,7 +3237,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
case GUARD_INTERVAL_AUTO:
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_GUARD__M;
/* try first guess DRX_GUARD_1DIV4 */
/* fall through */
fallthrough;
case GUARD_INTERVAL_1_4:
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_GUARD_4;
break;
@@ -3265,7 +3265,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
/* try first guess SC_RA_RAM_OP_PARAM_HIER_NO */
// transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_NO;
//break;
/* fall through */
fallthrough;
case HIERARCHY_1:
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_HIER_A1;
break;
@@ -3288,7 +3288,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
default:
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_CONST__M;
/* try first guess DRX_CONSTELLATION_QAM64 */
/* fall through */
fallthrough;
case QAM_64:
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_CONST_QAM64;
break;
@@ -3311,8 +3311,8 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_PRIO_HI;
WR16(devAddr, OFDM_EC_SB_PRIOR__A, OFDM_EC_SB_PRIOR_HI));
break;
case DRX_PRIORITY_UNKNOWN : /* fall through */
default:
case DRX_PRIORITY_UNKNOWN:
default:
return (DRX_STS_INVALID_ARG);
break;
}
@@ -3332,7 +3332,7 @@ static int SetDVBT (struct drxk_state *state,u16 IntermediateFreqkHz, s32 tunerF
default:
operationMode |= OFDM_SC_RA_RAM_OP_AUTO_RATE__M;
/* try first guess DRX_CODERATE_2DIV3 */
/* fall through */
fallthrough;
case FEC_2_3 :
transmissionParams |= OFDM_SC_RA_RAM_OP_PARAM_RATE_2_3;
break;

View File

@@ -786,7 +786,7 @@ static int get_frontend(struct dvb_frontend *fe, struct dtv_frontend_properties
default:
break;
}
/* fallthrough */
fallthrough;
case SYS_DVBS:
switch ((MXL_HYDRA_MODULATION_E)
regData[DMD_MODULATION_SCHEME_ADDR]) {
@@ -825,13 +825,15 @@ static int set_input(struct dvb_frontend *fe, int input)
struct mxl *state = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
state->tuner = p->input = input;
state->tuner = input;
#ifndef KERNEL_DVB_CORE
p->input = input;
#endif
return 0;
}
static struct dvb_frontend_ops mxl_ops = {
.delsys = { SYS_DVBS, SYS_DVBS2, SYS_DSS },
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
.info = {
.name = "MXL5XX",
.frequency_min_hz = 300000000,
@@ -856,7 +858,10 @@ static struct dvb_frontend_ops mxl_ops = {
.read_signal_strength = read_signal_strength,
.read_ucblocks = read_ucblocks,
.get_frontend = get_frontend,
#ifndef KERNEL_DVB_CORE
.set_input = set_input,
.xbar = { 4, 0, 8 }, /* tuner_max, demod id, demod_max */
#endif
.diseqc_send_master_cmd = send_master_cmd,
};
@@ -1873,7 +1878,8 @@ static int probe(struct mxl *state, struct mxl5xx_cfg *cfg)
struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
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_base *base;
@@ -1913,9 +1919,12 @@ struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
list_add(&base->mxllist, &mxllist);
}
state->fe.ops = mxl_ops;
#ifndef KERNEL_DVB_CORE
state->fe.ops.xbar[1] = demod;
state->fe.demodulator_priv = state;
state->fe.dtv_property_cache.input = tuner;
#endif
state->fe.demodulator_priv = state;
*fn_set_input = set_input;
list_add(&state->mxl, &base->mxls);
return &state->fe;

View File

@@ -23,12 +23,15 @@ struct mxl5xx_cfg {
extern struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
struct mxl5xx_cfg *cfg,
u32 demod, u32 tuner);
u32 demod, u32 tuner,
int (**fn_set_input)(struct dvb_frontend *, int));
#else
static inline struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
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__);
return NULL;

39
include/dd_compat.h Normal file
View File

@@ -0,0 +1,39 @@
#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_MOD 6
#define DVB_DEVICE_NS 7
#define DVB_DEVICE_NSD 8
#define SYS_DVBC2 19
#define ROLLOFF_15 4
#define ROLLOFF_10 5
#define ROLLOFF_5 6
#define FEC_1_4 13
#define FEC_1_3 14
#define APSK_64 14
#define APSK_128 15
#define APSK_256 16
#endif

View File

@@ -7,21 +7,6 @@
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
* 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_
@@ -54,7 +39,7 @@ typedef enum {
typedef struct audio_mixer {
unsigned int volume_left;
unsigned int volume_right;
/* what else do we need? bass, pass-through, ... */
/* what else do we need? bass, pass-through, ... */
} audio_mixer_t;

View File

@@ -5,21 +5,6 @@
* Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
* 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_
@@ -132,11 +117,6 @@ struct ca_descr {
unsigned char cw[8];
};
struct ca_pid {
unsigned int pid;
int index;/* -1 == disable*/
};
#define CA_RESET _IO('o', 128)
#define CA_GET_CAP _IOR('o', 129, struct ca_caps)
#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_SEND_MSG _IOW('o', 133, struct ca_msg)
#define CA_SET_DESCR _IOW('o', 134, struct ca_descr)
#define CA_SET_PID _IOW('o', 135, struct ca_pid)
#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_msg ca_msg_t;
typedef struct ca_descr ca_descr_t;
typedef struct ca_pid ca_pid_t;
#endif

View File

@@ -5,21 +5,6 @@
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
* & Ralph Metzler <ralph@convergence.de>
* 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_

View File

@@ -7,21 +7,6 @@
* Holger Waechtler <holger@convergence.de>
* Andre Draszik <ad@convergence.de>
* 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_
@@ -282,7 +267,6 @@ enum fe_spectral_inversion {
/**
* enum fe_code_rate - Type of Forward Error Correction (FEC)
*
*
* @FEC_NONE: No Forward Error Correction Code
* @FEC_1_2: Forward Error Correction Code 1/2
* @FEC_2_3: Forward Error Correction Code 2/3
@@ -296,7 +280,28 @@ enum fe_spectral_inversion {
* @FEC_3_5: Forward Error Correction Code 3/5
* @FEC_9_10: Forward Error Correction Code 9/10
* @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.
*/
enum fe_code_rate {
@@ -313,8 +318,28 @@ enum fe_code_rate {
FEC_3_5,
FEC_9_10,
FEC_2_5,
FEC_1_4,
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 +358,16 @@ enum fe_code_rate {
* @APSK_32: 32-APSK modulation
* @DQPSK: DQPSK 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.
*
@@ -352,9 +387,16 @@ enum fe_modulation {
APSK_32,
DQPSK,
QAM_4_NR,
QAM_1024,
QAM_4096,
APSK_8_L,
APSK_16_L,
APSK_32_L,
APSK_64,
APSK_64_L,
APSK_128,
APSK_256,
APSK_256_L,
};
/**
@@ -409,6 +451,7 @@ enum fe_transmit_mode {
* @GUARD_INTERVAL_PN420: PN length 420 (1/4)
* @GUARD_INTERVAL_PN595: PN length 595 (1/6)
* @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.
*/
@@ -424,6 +467,7 @@ enum fe_guard_interval {
GUARD_INTERVAL_PN420,
GUARD_INTERVAL_PN595,
GUARD_INTERVAL_PN945,
GUARD_INTERVAL_1_64,
};
/**
@@ -577,6 +621,9 @@ enum fe_pilot {
* @ROLLOFF_20: Roloff factor: α=20%
* @ROLLOFF_25: Roloff factor: α=25%
* @ROLLOFF_AUTO: Auto-detect the roloff factor.
* @ROLLOFF_15: Rolloff factor: α=15%
* @ROLLOFF_10: Rolloff factor: α=10%
* @ROLLOFF_5: Rolloff factor: α=5%
*
* .. note:
*
@@ -603,6 +650,8 @@ enum fe_rolloff {
* Cable TV: DVB-C following ITU-T J.83 Annex B spec (ClearQAM)
* @SYS_DVBC_ANNEX_C:
* Cable TV: DVB-C following ITU-T J.83 Annex C spec
* @SYS_DVBC2:
* Cable TV: DVB-C2
* @SYS_ISDBC:
* Cable TV: ISDB-C (no drivers yet)
* @SYS_DVBT:
@@ -620,7 +669,7 @@ enum fe_rolloff {
* @SYS_DVBS:
* Satellite TV: DVB-S
* @SYS_DVBS2:
* Satellite TV: DVB-S2
* Satellite TV: DVB-S2 and DVB-S2X
* @SYS_TURBO:
* Satellite TV: DVB-S Turbo
* @SYS_ISDBS:
@@ -730,7 +779,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_223_187: Reed Solomon code (223,187).
* @ATSCMH_RSCODE_235_187: Reed Solomon code (235,187).
@@ -771,8 +820,8 @@ enum fecap_scale_params {
* struct dtv_stats - Used for reading a DTV status property
*
* @scale:
* Filled with enum fecap_scale_params - the scale in usage
* for that parameter
* Filled with enum fecap_scale_params - the scale in usage
* for that parameter
*
* @svalue:
* integer value of the measure, for %FE_SCALE_DECIBEL,
@@ -841,18 +890,18 @@ struct dtv_fe_stats {
/**
* struct dtv_property - store one of frontend command and its value
*
* @cmd: Digital TV command.
* @reserved: Not used.
* @u: Union with the values for the command.
* @u.data: A unsigned 32 bits integer with command value.
* @u.buffer: Struct to store bigger properties.
* Currently unused.
* @u.buffer.data: an unsigned 32-bits array.
* @u.buffer.len: number of elements of the buffer.
* @u.buffer.reserved1: Reserved.
* @u.buffer.reserved2: Reserved.
* @u.st: a &struct dtv_fe_stats array of statistics.
* @result: Currently unused.
* @cmd: Digital TV command.
* @reserved: Not used.
* @u: Union with the values for the command.
* @u.data: A unsigned 32 bits integer with command value.
* @u.buffer: Struct to store bigger properties.
* Currently unused.
* @u.buffer.data: an unsigned 32-bits array.
* @u.buffer.len: number of elements of the buffer.
* @u.buffer.reserved1: Reserved.
* @u.buffer.reserved2: Reserved.
* @u.st: a &struct dtv_fe_stats array of statistics.
* @result: Currently unused.
*
*/
struct dtv_property {

View File

@@ -5,21 +5,6 @@
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
* & Ralph Metzler <ralph@convergence.de>
* 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_

View File

@@ -7,21 +7,6 @@
* Copyright (C) 2001 Ralph Metzler <ralph@convergence.de>
* & Marcus Metzler <marcus@convergence.de>
* 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_

View File

@@ -4,21 +4,6 @@
*
* Copyright (C) 2000 Holger Waechtler <holger@convergence.de>
* 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_

View File

@@ -7,21 +7,6 @@
* Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
* & Ralph Metzler <ralph@convergence.de>
* 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_

View File

@@ -369,6 +369,10 @@ struct dvb_frontend_internal_info {
* allocated by the driver.
* @init: callback function used to initialize the tuner device.
* @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
* allow other drivers to write data into their registers.
* Should not be used on new drivers.
@@ -438,7 +442,6 @@ struct dvb_frontend_internal_info {
* @analog_ops: pointer to &struct analog_demod_ops
*/
struct dvb_frontend_ops {
struct dvb_frontend_internal_info info;
u8 delsys[MAX_DELSYS];
@@ -449,6 +452,8 @@ struct dvb_frontend_ops {
int (*init)(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);
@@ -765,7 +770,8 @@ void dvb_frontend_detach(struct dvb_frontend *fe);
* &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 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
* 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.
*
* 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.
* Otherwise,t will call &dvb_frontend_ops.tuner_ops.init\(\), if available.

View File

@@ -214,7 +214,7 @@ extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf,
* @buf: Buffer to write.
* @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,
size_t len);

View File

@@ -27,11 +27,15 @@
#define DVB_MAJOR 212
#if 0
#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
#else
#define DVB_MAX_ADAPTERS 64
#endif
#endif
#define DVB_MAX_ADAPTERS 64
#define DVB_UNSET (-1)
@@ -92,7 +96,11 @@ struct dvb_frontend;
* @device: pointer to struct device
* @module: pointer to struct module
* @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_lock: Lock to prevent using the other frontends when MFE is
* used.
@@ -131,6 +139,7 @@ struct dvb_adapter {
* struct dvb_device - represents a DVB device node
*
* @list_head: List head with all DVB devices
* @ref: reference counter
* @fops: pointer to struct file_operations
* @adapter: pointer to the adapter that holds this device node
* @type: type of the device, as defined by &enum dvb_device_type.
@@ -161,6 +170,7 @@ struct dvb_adapter {
*/
struct dvb_device {
struct list_head list_head;
struct kref ref;
const struct file_operations *fops;
struct dvb_adapter *adapter;
enum dvb_device_type type;
@@ -192,6 +202,20 @@ struct dvb_device {
void *priv;
};
/**
* 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
*
@@ -236,29 +260,16 @@ int dvb_register_device(struct dvb_adapter *adap,
/**
* dvb_remove_device - Remove a registered DVB device
*
* This does not free memory. To do that, call dvb_free_device().
* This does not free memory. dvb_free_device() will do that when
* reference counter is empty
*
* @dvbdev: pointer to struct dvb_device
*/
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
*
* 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
*/
void dvb_unregister_device(struct dvb_device *dvbdev);
@@ -326,7 +337,7 @@ int dvb_create_media_graph(struct dvb_adapter *adap,
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.
* @file: pointer to &struct file.
@@ -421,11 +432,12 @@ void dvb_module_release(struct i2c_client *client);
/* Legacy generic DVB attach function. */
#ifdef CONFIG_MEDIA_ATTACH
/**
* dvb_attach - attaches a DVB frontend into the DVB core.
*
* @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
* the @FUNCTION function there, with @ARGS.

View File

@@ -17,3 +17,7 @@ Tuner5=5,984
Tuner6=6,1020
Tuner7=7,1056
Tuner8=8,1092
Tuner9=1,1210
Tuner10=2,1420
Tuner11=3,1680
Tuner12=4,2040

View 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

View 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

View File

@@ -12,6 +12,7 @@
#include <stdint.h>
#include <math.h>
#include <time.h>
#include <inttypes.h>
char line_start[16] = "";
char line_end[16] = "\r";
@@ -308,20 +309,22 @@ int main(int argc, char **argv)
{"tscheck", no_argument, 0, 't'},
{"tscheck_l", required_argument, 0, 'a'},
{"nodvr", no_argument , 0, 'q'},
{"pam", no_argument , 0, 'a'},
{"pam", no_argument , 0, 'P'},
{"pam_color", no_argument , 0, 'e'},
{"help", no_argument , 0, 'h'},
{0, 0, 0, 0}
};
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:qP",
long_options, &option_index);
if (c==-1)
break;
switch (c) {
case 'e':
odvr = 2;
color = strtoul(optarg, NULL, 0);
case 'P':
odvr = 2;
break;
case 'o':
fout = stderr;
@@ -341,7 +344,7 @@ int main(int argc, char **argv)
break;
}
fprintf(fout,"performing continuity check\n");
odvr = 2;
odvr = 3;
break;
case 'c':
config = strdup(optarg);
@@ -388,6 +391,10 @@ int main(int argc, char **argv)
printf("unknown mtype %s\n", optarg);
break;
case 'd':
if (!strcmp(optarg, "C2"))
delsys = SYS_DVBC2;
if (!strcmp(optarg, "DVBC2"))
delsys = SYS_DVBC2;
if (!strcmp(optarg, "C"))
delsys = SYS_DVBC_ANNEX_A;
if (!strcmp(optarg, "DVBC"))
@@ -427,12 +434,18 @@ int main(int argc, char **argv)
get_ts = 0;
break;
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"
" [-g gold_code] [-r root_code] [-i id] [-n device_num]\n"
" [-o (write dvr to stdout)]\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"
"\n"
" delivery_system = C,S,S2,T,T2,J83B,ISDBC,ISDBT\n"
" polarity = h/H,v/V\n"
@@ -471,7 +484,7 @@ int main(int argc, char **argv)
else
fe = dddvb_fe_alloc(dd, delsys);
if (!fe) {
fprintf(fout,"dddvb_fe_alloc failed\n");
fprintf(fout,"dddvb_fe_alloc failed\n");
exit(-1);
}
dddvb_param_init(&p);
@@ -503,8 +516,10 @@ int main(int argc, char **argv)
str = dddvb_get_strength(fe);
cnr = dddvb_get_cnr(fe);
printf("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));
printf("stat=%02x, str=%" PRId64 ".%03u dBm, "
"snr=%" PRId64 ".%03u dB\n",
stat, str/1000, abs(str%1000),
cnr/1000, abs(cnr%1000));
sleep(1);
}
} else {
@@ -523,7 +538,8 @@ int main(int argc, char **argv)
cnr = dddvb_get_cnr(fe);
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);
}
fprintf(stderr,"got lock on %s\n", fe->name);
@@ -533,29 +549,28 @@ int main(int argc, char **argv)
if ((fd = open(filename ,O_RDONLY)) < 0){
fprintf(stderr,"Error opening input file:%s\n",filename);
}
if (odvr > 0){
switch (odvr){
case 1:
while(1){
read(fd,buf,BUFFSIZE);
write(fileno(stdout),buf,BUFFSIZE);
}
break;
case 2:
fprintf(stderr,"writing pamdata\n");
init_pamdata(&iq,color);
while(1){
pam_read_data(fd, &iq);
pam_write(STDOUT_FILENO, &iq);
}
break;
switch (odvr){
case 1:
while(1){
read(fd,buf,BUFFSIZE);
write(fileno(stdout),buf,BUFFSIZE);
}
} else {
break;
case 2:
fprintf(stderr,"writing pamdata\n");
init_pamdata(&iq,color);
while(1){
pam_read_data(fd, &iq);
pam_write(STDOUT_FILENO, &iq);
}
break;
case 3:
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);
}
tscheck(fd);
break;
}
}
}

View File

@@ -41,7 +41,7 @@ int parse_config(struct dddvb *dd, char *name, char *sec,
memcpy(fname + config_len, "dddvb.conf", 11);
if ((f = fopen (fname, "r")) == NULL) {
printf("config file %s not found\n", fname);
dprintf(2, "config file %s not found\n", fname);
return -1;
}

View File

@@ -8,7 +8,7 @@ LIBDDDVB_EXPORTED struct dddvb *global_dd = NULL;
LIBDDDVB_EXPORTED pthread_mutex_t dddvb_mutex = PTHREAD_MUTEX_INITIALIZER;
void __attribute__ ((constructor)) setup(void) {
printf("SETUP\n");
//printf("SETUP\n");
}
LIBDDDVB_EXPORTED struct dddvb_fe *dddvb_fe_alloc_num(struct dddvb *dd, uint32_t type, uint32_t num)
@@ -30,7 +30,7 @@ LIBDDDVB_EXPORTED struct dddvb_fe *dddvb_fe_alloc_num(struct dddvb *dd, uint32_t
pthread_mutex_unlock(&dd->lock);
if (dddvb_fe_start(fe) < 0) {
dbgprintf(DEBUG_SYS, "fe %d busy\n", fe->nr);
return 0;
return NULL;
}
dbgprintf(DEBUG_SYS, "Allocated fe %d = %d/%d, fd=%d\n",
fe->nr, fe->anum, fe->fnum, fe->fd);
@@ -40,22 +40,25 @@ LIBDDDVB_EXPORTED struct dddvb_fe *dddvb_fe_alloc_num(struct dddvb *dd, uint32_t
LIBDDDVB_EXPORTED struct dddvb_fe *dddvb_fe_alloc(struct dddvb *dd, uint32_t type)
{
int i;
struct dddvb_fe *fe = NULL;
struct dddvb_fe *fe = NULL, *tfe;
pthread_mutex_lock(&dd->lock);
dbgprintf(DEBUG_SYS, "alloc_fe type %u\n", type);
for (i = 0; i < dd->dvbfe_num; i++) {
fe = &dd->dvbfe[i];
if (fe->state == 0 &&
(fe->type & (1UL << type))) {
tfe = &dd->dvbfe[i];
if (tfe->state == 0 &&
(tfe->type & (1UL << type))) {
fe = dddvb_fe_alloc_num(dd, type, i);
if (fe)
break;
}
}
pthread_mutex_unlock(&dd->lock);
if (!fe)
dbgprintf(DEBUG_SYS, "alloc_fe type %u\n failed!", type);
else
dbgprintf(DEBUG_SYS, "alloc_fe type %u success!\n", type);
return fe;
}
LIBDDDVB_EXPORTED int dddvb_dvb_tune(struct dddvb_fe *fe, struct dddvb_params *p)

View File

@@ -111,6 +111,7 @@ static int set_fe_input(struct dddvb_fe *fe, uint32_t fr,
{ .cmd = DTV_INVERSION, .u.data = INVERSION_AUTO },
{ .cmd = DTV_SYMBOL_RATE, .u.data = sr },
{ .cmd = DTV_INNER_FEC, .u.data = FEC_AUTO },
{ .cmd = DTV_ROLLOFF, .u.data = ROLLOFF_AUTO },
};
struct dtv_properties c;
int ret;
@@ -181,7 +182,16 @@ static int diseqc(int fd, int sat, int hor, int band)
return 0;
}
static int set_en50494(struct dddvb_fe *fe, uint32_t freq, uint32_t sr,
static int set_vol_tone(int fd, int hor, int band)
{
if (ioctl(fd, FE_SET_TONE, band ? SEC_TONE_ON : SEC_TONE_OFF))
perror("FE_SET_TONE failed");
if (ioctl(fd, FE_SET_VOLTAGE, hor ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13) == -1)
perror("FE_SET_VOLTAGE failed");
dbgprintf(DEBUG_DVB, "set_vol_tone hor=%u, band=%u\n", hor, band);
}
static int set_en50494(struct dddvb_fe *fe, uint32_t freq_khz, uint32_t sr,
int sat, int hor, int band,
uint32_t slot, uint32_t ubfreq,
fe_delivery_system_t ds)
@@ -193,8 +203,10 @@ static int set_en50494(struct dddvb_fe *fe, uint32_t freq, uint32_t sr,
uint16_t t;
uint32_t input = 3 & (sat >> 6);
int fd = fe->fd;
uint32_t freq = (freq_khz + 2000) / 4000;
int32_t fdiff = freq_khz - freq * 1000;
t = (freq + ubfreq + 2) / 4 - 350;
t = (freq_khz / 1000 + ubfreq + 2) / 4 - 350;
hor &= 1;
cmd.msg[3] = ((t & 0x0300) >> 8) |
@@ -218,7 +230,7 @@ static int set_en50494(struct dddvb_fe *fe, uint32_t freq, uint32_t sr,
cmd.msg[0], cmd.msg[1], cmd.msg[2], cmd.msg[3], cmd.msg[4]);
}
static int set_en50607(struct dddvb_fe *fe, uint32_t freq, uint32_t sr,
static int set_en50607(struct dddvb_fe *fe, uint32_t freq_khz, uint32_t sr,
int sat, int hor, int band,
uint32_t slot, uint32_t ubfreq,
fe_delivery_system_t ds)
@@ -227,11 +239,13 @@ static int set_en50607(struct dddvb_fe *fe, uint32_t freq, uint32_t sr,
.msg = {0x70, 0x00, 0x00, 0x00, 0x00},
.msg_len = 4
};
uint32_t freq = (freq_khz + 500) / 1000;
int32_t fdiff = freq_khz - freq * 1000;
uint32_t t = freq - 100;
uint32_t input = 3 & (sat >> 6);
int fd = fe->fd;
//printf("input = %u, sat = %u\n", input, sat&0x3f);
dbgprintf(DEBUG_DVB, "input = %u, sat = %u\n", input, sat&0x3f);
hor &= 1;
cmd.msg[1] = slot << 3;
cmd.msg[1] |= ((t >> 8) & 0x07);
@@ -250,11 +264,11 @@ static int set_en50607(struct dddvb_fe *fe, uint32_t freq, uint32_t sr,
if (ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_13) == -1)
perror("FE_SET_VOLTAGE failed");
set_fe_input(fe, ubfreq * 1000, sr, ds, input);
set_fe_input(fe, ubfreq * 1000 + fdiff, sr, ds, input);
dbgprintf(DEBUG_DVB, "EN50607 %02x %02x %02x %02x\n",
cmd.msg[0], cmd.msg[1], cmd.msg[2], cmd.msg[3]);
dbgprintf(DEBUG_DVB, "EN50607 freq %u sr %u hor %u\n",
freq, sr, hor);
dbgprintf(DEBUG_DVB, "EN50607 freq %u ubfreq %u fdiff %d sr %u hor %u\n",
freq, ubfreq, fdiff, sr, hor);
}
@@ -288,14 +302,20 @@ static int tune_sat(struct dddvb_fe *fe)
freq = lofs - freq;
}
#endif
if (freq > 3000000) {
if (lofs)
hi = (freq > lofs) ? 1 : 0;
if (hi)
freq -= fe->lof2[lnbc];
else
freq -= fe->lof1[lnbc];
if (lofs > 10000000) {
if (hi)
freq -= fe->lof2[lnbc];
else
freq -= fe->lof1[lnbc];
} else {
if (hi)
freq = fe->lof2[lnbc] - freq;
else
freq = fe->lof1[lnbc] - freq;
}
}
dbgprintf(DEBUG_DVB, "tune_sat IF=%u\n", freq);
if (fe->first) {
@@ -308,13 +328,13 @@ static int tune_sat(struct dddvb_fe *fe)
dbgprintf(DEBUG_DVB, "scif_type = %u\n", fe->scif_type);
if (fe->scif_type == 1) {
pthread_mutex_lock(&fe->dd->uni_lock);
set_en50494(fe, freq / 1000, fe->param.param[PARAM_SR],
set_en50494(fe, freq, fe->param.param[PARAM_SR],
lnb, fe->param.param[PARAM_POL], hi,
fe->scif_slot, fe->scif_freq, ds);
pthread_mutex_unlock(&fe->dd->uni_lock);
} else if (fe->scif_type == 2) {
pthread_mutex_lock(&fe->dd->uni_lock);
set_en50607(fe, freq / 1000, fe->param.param[PARAM_SR],
set_en50607(fe, freq, fe->param.param[PARAM_SR],
lnb, fe->param.param[PARAM_POL], hi,
fe->scif_slot, fe->scif_freq, ds);
pthread_mutex_unlock(&fe->dd->uni_lock);
@@ -323,11 +343,14 @@ static int tune_sat(struct dddvb_fe *fe)
if (input != DDDVB_UNDEF) {
input = 3 & (input >> 6);
printf("input = %u\n", input);
dbgprintf(DEBUG_DVB, "input = %u\n", input);
set_property(fe->fd, DTV_INPUT, input);
}
diseqc(fe->fd, lnb, fe->param.param[PARAM_POL], hi);
if (fe->scif_type == 3)
set_vol_tone(fe->fd, fe->param.param[PARAM_POL], hi);
else
diseqc(fe->fd, lnb, fe->param.param[PARAM_POL], hi);
set_fe_input(fe, freq, fe->param.param[PARAM_SR], ds, input);
//set_fe_input(fe, freq, fe->param.param[PARAM_SR], ds, DDDVB_UNDEF);
}
}
@@ -349,7 +372,7 @@ static int tune_c(struct dddvb_fe *fe)
struct dtv_properties c;
int ret;
printf("tune_c()\n");
dbgprintf(DEBUG_DVB, "tune_c()\n");
set_property(fe->fd, DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_A);
c.num = ARRAY_SIZE(p);
@@ -376,7 +399,7 @@ static int tune_j83b(struct dddvb_fe *fe)
struct dtv_properties c;
int ret;
printf("tune_j83b()\n");
dbgprintf(DEBUG_DVB, "tune_j83b()\n");
set_property(fe->fd, DTV_DELIVERY_SYSTEM, SYS_DVBC_ANNEX_B);
c.num = ARRAY_SIZE(p);
@@ -542,7 +565,7 @@ static int tune(struct dddvb_fe *fe)
{
int ret;
printf("tune()\n");
dbgprintf(DEBUG_DVB, "tune()\n");
switch (fe->param.param[PARAM_MSYS]) {
case SYS_DVBS:
case SYS_DVBS2:
@@ -603,7 +626,6 @@ static int open_fe(struct dddvb_fe *fe)
sprintf(fname, "/dev/dvb/adapter%d/frontend%d", fe->anum, fe->fnum);
fe->fd = open(fname, O_RDWR);
printf("open = %d\n", fe->fd);
if (fe->fd < 0)
return -1;
return 0;

View File

@@ -329,7 +329,7 @@ static void calc_lq(struct dddvb_fe *fe)
{
struct dtv_fe_stats st;
int64_t str, snr;
uint32_t mod, fec, ber_num, ber_den, trans, pilot = 0, quality = 0;
uint32_t mod, fec, ber_num, ber_den, trans, pilot = 0, quality = 0, freq, rate;
get_property(fe->fd, DTV_TRANSMISSION_MODE, &fe->pls_code);
dbgprintf(DEBUG_DVB, "fe%d: pls=0x%02x\n", fe->nr, fe->pls_code);
@@ -362,6 +362,10 @@ static void calc_lq(struct dddvb_fe *fe)
dbgprintf(DEBUG_DVB, "fe%d: snr=%lld ber=%llu/%llu\n",
fe->nr, snr, ber_num, ber_den);
dbgprintf(DEBUG_DVB, "fe%d: fec=%u mod=%u\n", fe->nr, fec, mod);
get_property(fe->fd, DTV_FREQUENCY, &freq);
dbgprintf(DEBUG_DVB, "fe%d: actual frequency=%u\n", fe->nr, freq);
get_property(fe->fd, DTV_SYMBOL_RATE, &rate);
dbgprintf(DEBUG_DVB, "fe%d: actual symbol rate=%u\n", fe->nr, rate);
switch (fe->n_param.param[PARAM_MSYS]) {
case SYS_DVBS:
quality = dvbsq(snr, fec, ber_num, ber_den);

View File

@@ -13,7 +13,7 @@ int sendlen(int sock, char *buf, int len)
for (todo = len; todo; todo -= done, buf += done)
if ((done = send(sock, buf, todo, 0)) < 0) {
printf("sendlen error\n");
dprintf(2, "sendlen error\n");
return done;
}
return len;