mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2023-10-10 13:37:43 +02:00
initial commit from dddvb-0.9.19c
This commit is contained in:
commit
9e2128c4fb
189
CHANGELOG
Normal file
189
CHANGELOG
Normal file
@ -0,0 +1,189 @@
|
||||
0.9.19c 2015.07.20
|
||||
- MAX S8:
|
||||
do not turn on diseqc and tuners on init
|
||||
of to save power
|
||||
turn off tuners when not used
|
||||
- support new Octopus CI in flashprog
|
||||
|
||||
0.9.19b 2015.06.15
|
||||
- fix version number
|
||||
- option "old_quattro=1" for old MAX S8 input numbering
|
||||
new is "VL VH HL HH", old is "VL HL VH HH"
|
||||
- set drive strength in mxl5xx to 1 to fix problems with
|
||||
8th demod
|
||||
|
||||
0.9.19 2015.06.14
|
||||
- lock flash access
|
||||
- support serial numbers for newer cards
|
||||
|
||||
0.9.18 2015.05.05
|
||||
- support GT links
|
||||
- fixes for mxl5xx tuning
|
||||
(prevent simultaneous tuning inside 100ms)
|
||||
- allow dynamic fmode change
|
||||
|
||||
0.9.18 (beta) 2015.01.24
|
||||
- initial support of GT links
|
||||
- fixes for mxl5xx tuning
|
||||
|
||||
0.9.17 2015.01.10
|
||||
- support input modes for MAX S8 4/8
|
||||
ddbridge parameter fmode:
|
||||
fmode = 0 : demod 0 & 4 on input 0, demod 1 & 5 on input 1, etc.
|
||||
input for each frontend can be changed with ioctl DTV_INPUT
|
||||
fmode = 1 : connect all lines to QUAD LNB
|
||||
fmode = 2 : connect to QUATTRO LNB: input 0=V,L, 1=H,L, 2=V,H, 3=H,H
|
||||
fmode = 3 : all demods on input 0
|
||||
send JESS or SCR commands from application
|
||||
|
||||
- preparations for support of GT links
|
||||
|
||||
0.9.16 2014.12.19
|
||||
- support MAX S8 4/8 production card
|
||||
|
||||
0.9.15a 2014.07.29
|
||||
- last minute fixes
|
||||
|
||||
0.9.15 2014.06.24
|
||||
- support MAX S8 4/8 prototype
|
||||
|
||||
0.9.14b 2014.04.24
|
||||
- fix fe read lockup in cxd2843
|
||||
|
||||
0.9.14a 2014.04.23
|
||||
- fix Cine S2 V7 PCIe ID
|
||||
|
||||
0.9.14 2014.04.20
|
||||
- support for CineCT V7 with C2
|
||||
- initial support for STV0910/STV6111/LNBH25
|
||||
- more coding style cleanups
|
||||
- API changes for modulator
|
||||
|
||||
0.9.13 2014.03.25
|
||||
- support for CineCT V7
|
||||
|
||||
0.9.12 2014.02.17
|
||||
- support for SNR in XO2 and LED connected to XO2
|
||||
|
||||
0.9.11 2014.02.04
|
||||
|
||||
- kernel style cleanups
|
||||
- attr alloc fixes for modulator card
|
||||
|
||||
0.9.10 2013.10.09
|
||||
|
||||
- Bugfixes CXD2843
|
||||
support slice id
|
||||
|
||||
0.9.9 2013.08.14
|
||||
|
||||
- support for CXD2843 DVB-C/T/C2/T2 demod
|
||||
|
||||
0.9.7 2013.04.15
|
||||
|
||||
- Octopus Net complete
|
||||
|
||||
- changes for 3.8 kernels
|
||||
|
||||
|
||||
0.9.6 2012.09.26
|
||||
|
||||
- basic Octopus Net support
|
||||
|
||||
|
||||
0.9.5 2012.08.05
|
||||
|
||||
- cleanup
|
||||
|
||||
0.9.4 2012.07.11
|
||||
|
||||
- support for new modulator bitstream 1.1
|
||||
|
||||
0.9.3 2012.06.13
|
||||
|
||||
- add hwid, remap attributes
|
||||
|
||||
0.9.2 2012.06.08
|
||||
|
||||
- fix cxd2099 address writing optmization
|
||||
|
||||
- add setting of TS output gap size through sysfs
|
||||
gap_size = (gap_value*2)+4
|
||||
bit rate = 72 Mbps * 188 / gap_size
|
||||
|
||||
0.9.1 2012.05.01
|
||||
|
||||
- support for reworked DVB-C modulator
|
||||
|
||||
- support for multiple channels
|
||||
|
||||
- move some funktions from tasklets back into
|
||||
interrupt in those cases where it is more efficient
|
||||
|
||||
|
||||
0.9.0 2012.03.05
|
||||
|
||||
- initial support of DVB-C modulator card
|
||||
|
||||
- rework of redirect mechanism to support modulator
|
||||
|
||||
|
||||
0.8.5 2012.01.30
|
||||
|
||||
- init DMA_BUFFER_CONTROL before starting input/output
|
||||
in case it was not stopped properly before reboot
|
||||
(can only happen on cards on PCIe extensions without reset line)
|
||||
|
||||
|
||||
0.8.4 2012.01.04
|
||||
|
||||
- support for reading bridge serial number
|
||||
|
||||
- test code for proper start/stop of redirected streams
|
||||
|
||||
|
||||
0.8.3 2011.12.18
|
||||
|
||||
- add support for EEProms on 0x50
|
||||
|
||||
- make flashprog safer to use for end users
|
||||
|
||||
- lost of kernel coding style adjustments
|
||||
|
||||
|
||||
0.8.2 2011.10.14
|
||||
|
||||
- added some documentation in docs/
|
||||
|
||||
0.8.1 2011.10.13
|
||||
|
||||
- signal strength and SNR for STV0367/TDA18212 combo
|
||||
|
||||
- serial number support via sysfs
|
||||
|
||||
|
||||
0.8 2011.07.30
|
||||
|
||||
- Support for DVB-C/T cards with stv0367 demod and TDA18212 tuner
|
||||
|
||||
- loopback TS for testing
|
||||
|
||||
- support of octopus cards with fan, led and temperature sensors
|
||||
via attributes.
|
||||
|
||||
- redirect of TS to CI and back
|
||||
|
||||
|
||||
0.7 2011.06.14
|
||||
|
||||
- Add IDs for new cards in ddbridge driver
|
||||
|
||||
- Change dvb adapter allocation for ddbridge driver
|
||||
Configurable with module parameter adapter_alloc:
|
||||
|
||||
0 = one adapter per io (old behavior)
|
||||
1 = one per tab with io present (tab connected to something)
|
||||
2 = one per tab regardless of something connected or not
|
||||
3 = one adapter for all devices of one card
|
||||
|
||||
|
7
Kbuild
Normal file
7
Kbuild
Normal file
@ -0,0 +1,7 @@
|
||||
#
|
||||
# Makefile for the kernel multimedia device drivers.
|
||||
#
|
||||
|
||||
obj-y := dvb-core/ \
|
||||
ddbridge/ \
|
||||
frontends/
|
19
Makefile
Normal file
19
Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
MODDEFS := CONFIG_DVB_CORE=m CONFIG_DVB_DDBRIDGE=m CONFIG_DVB_DRXK=m CONFIG_DVB_TDA18271C2DD=m CONFIG_DVB_CXD2099=m CONFIG_DVB_LNBP21=m CONFIG_DVB_STV090x=m CONFIG_DVB_STV6110x=m CONFIG_DVB_STV0367=m CONFIG_DVB_TDA18212=m CONFIG_DVB_STV0367DD=m CONFIG_DVB_TDA18212DD=m CONFIG_DVB_OCTONET=m CONFIG_DVB_CXD2843=m CONFIG_DVB_STV0910=m CONFIG_DVB_STV6111=m CONFIG_DVB_LNBH25=m CONFIG_DVB_MXL5XX=m
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MODDEFS) modules
|
||||
$(MAKE) -C apps
|
||||
|
||||
dep:
|
||||
DIR=`pwd`; (cd $(TOPDIR); make SUBDIRS=$$DIR dep)
|
||||
|
||||
install: all
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
|
||||
|
||||
clean:
|
||||
rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
|
||||
|
||||
|
19
apps/Makefile
Normal file
19
apps/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
all: cit citin flashprog modt ddtest setmod ddflash
|
||||
|
||||
cit: cit.c
|
||||
gcc -o cit cit.c -lpthread
|
||||
|
||||
modt: modt.c
|
||||
gcc -o modt modt.c -lpthread
|
||||
|
||||
setmod: setmod.c
|
||||
gcc -o setmod setmod.c -I../include/
|
||||
|
||||
flashprog: flashprog.c
|
||||
gcc -o flashprog flashprog.c
|
||||
|
||||
ddtest: ddtest.c
|
||||
gcc -o ddtest ddtest.c
|
||||
|
||||
ddflash: ddflash.c
|
||||
gcc -o ddflash ddflash.c
|
138
apps/cit.c
Normal file
138
apps/cit.c
Normal file
@ -0,0 +1,138 @@
|
||||
#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>
|
||||
|
||||
uint8_t fill[188]={0x47, 0x1f, 0xff, 0x10,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
|
||||
|
||||
uint8_t ts[188]={0x47, 0x0a, 0xaa, 0x00,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
|
||||
|
||||
void proc_buf(uint8_t *buf, uint32_t *d)
|
||||
{
|
||||
uint32_t c;
|
||||
static uint32_t tc=0;
|
||||
|
||||
|
||||
if (buf[1]==0x1f && buf[2]==0xff) {
|
||||
//printf("fill\n");
|
||||
return;
|
||||
}
|
||||
if (buf[1]==0x9f && buf[2]==0xff) {
|
||||
//printf("fill\n");
|
||||
return;
|
||||
}
|
||||
if (buf[1]==0x1a && buf[2]==0xbb) {
|
||||
tc++;
|
||||
if (!(tc&0xfff))
|
||||
printf("T %d\n", tc);
|
||||
return;
|
||||
}
|
||||
//printf("%02x %02x %02x %02x\n", buf[0], buf[1], buf [2], buf[3]);
|
||||
if (buf[1]!=0x0a || buf[2]!=0xaa)
|
||||
return;
|
||||
c=(buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|buf[7];
|
||||
if (c!=*d) {
|
||||
printf("CONT ERROR: got %08x expected %08x\n", c, *d);
|
||||
*d=c;
|
||||
} else {
|
||||
if (memcmp(ts+8, buf+8, 180))
|
||||
printf("error\n");
|
||||
if (!(c&0xffff))
|
||||
printf("R %08x\n", c);
|
||||
}
|
||||
(*d)++;
|
||||
}
|
||||
|
||||
void *get_ts(void *a)
|
||||
{
|
||||
uint8_t buf[188*1024];
|
||||
int len, off;
|
||||
|
||||
int fdi=open("/dev/dvb/adapter2/ci0", O_RDONLY);
|
||||
uint32_t d=0;
|
||||
|
||||
while (1) {
|
||||
len=read(fdi, buf, 188*1024);
|
||||
if (len<0)
|
||||
continue;
|
||||
if (buf[0]!=0x47) {
|
||||
read(fdi, buf, 1);
|
||||
continue;
|
||||
}
|
||||
for (off=0; off<len; off+=188) {
|
||||
proc_buf(buf+off, &d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SNUM 233
|
||||
//671
|
||||
void send(void)
|
||||
{
|
||||
uint8_t buf[188*SNUM], *cts;
|
||||
int i;
|
||||
uint32_t c=0;
|
||||
int fdo;
|
||||
|
||||
fdo=open("/dev/dvb/adapter2/ci0", O_WRONLY);
|
||||
|
||||
|
||||
while (1) {
|
||||
for (i=0; i<SNUM; i++) {
|
||||
cts=buf+i*188;
|
||||
memcpy(cts, ts, 188);
|
||||
cts[4]=(c>>24);
|
||||
cts[5]=(c>>16);
|
||||
cts[6]=(c>>8);
|
||||
cts[7]=c;
|
||||
//write(fdo, fill, 188);
|
||||
//printf("S %d\n", c);
|
||||
c++;
|
||||
//usleep(100000+0xffff&rand());
|
||||
//usleep(1000);
|
||||
}
|
||||
write(fdo, buf, 188*SNUM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
pthread_t th;
|
||||
|
||||
memset(ts+8, 180, 0x5a);
|
||||
pthread_create(&th, NULL, get_ts, NULL);
|
||||
usleep(10000);
|
||||
send();
|
||||
}
|
61
apps/citin.c
Normal file
61
apps/citin.c
Normal file
@ -0,0 +1,61 @@
|
||||
#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>
|
||||
|
||||
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();
|
||||
}
|
||||
|
55
apps/citout.c
Normal file
55
apps/citout.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/dvb/dmx.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include <linux/dvb/video.h>
|
||||
|
||||
#define TSBUFSIZE (100*188)
|
||||
|
||||
void citest()
|
||||
{
|
||||
uint8_t *buf;
|
||||
uint8_t id;
|
||||
int i, nts;
|
||||
int len;
|
||||
int ts0=open("/dev/dvb/adapter0/dvr0", O_RDONLY);
|
||||
int ts1=open("/dev/dvb/adapter4/sec0", O_WRONLY);
|
||||
int demux0=open("/dev/dvb/adapter0/demux0", O_RDWR);
|
||||
|
||||
struct dmx_pes_filter_params pesFilterParams;
|
||||
|
||||
pesFilterParams.input = DMX_IN_FRONTEND;
|
||||
pesFilterParams.output = DMX_OUT_TS_TAP;
|
||||
pesFilterParams.pes_type = DMX_PES_OTHER;
|
||||
pesFilterParams.flags = DMX_IMMEDIATE_START;
|
||||
|
||||
pesFilterParams.pid = 8192;
|
||||
if (ioctl(demux0, DMX_SET_PES_FILTER, &pesFilterParams) < 0) {
|
||||
printf("Could not set PES filter\n");
|
||||
return;
|
||||
}
|
||||
buf=(uint8_t *)malloc(TSBUFSIZE);
|
||||
|
||||
while(1) {
|
||||
len=read(ts0, buf, TSBUFSIZE);
|
||||
if (len<=0)
|
||||
break;
|
||||
if (buf[0]!=0x47)
|
||||
printf("oops\n");
|
||||
write(ts1, buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
citest();
|
||||
}
|
||||
|
1
apps/ddflash.c
Symbolic link
1
apps/ddflash.c
Symbolic link
@ -0,0 +1 @@
|
||||
octonet/ddflash.c
|
1
apps/ddtest.c
Symbolic link
1
apps/ddtest.c
Symbolic link
@ -0,0 +1 @@
|
||||
octonet/ddtest.c
|
1
apps/flash.h
Symbolic link
1
apps/flash.h
Symbolic link
@ -0,0 +1 @@
|
||||
./octonet/flash.h
|
722
apps/flashprog.c
Normal file
722
apps/flashprog.c
Normal file
@ -0,0 +1,722 @@
|
||||
/*
|
||||
/* 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>
|
||||
|
||||
#define DDB_MAGIC 'd'
|
||||
|
||||
static uint32_t linknr = 0;
|
||||
|
||||
struct ddb_id {
|
||||
__u16 vendor;
|
||||
__u16 device;
|
||||
__u16 subvendor;
|
||||
__u16 subdevice;
|
||||
__u32 hw;
|
||||
__u32 regmap;
|
||||
};
|
||||
|
||||
struct ddb_flashio {
|
||||
__u8 *write_buf;
|
||||
__u32 write_len;
|
||||
__u8 *read_buf;
|
||||
__u32 read_len;
|
||||
__u32 link;
|
||||
};
|
||||
|
||||
#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio)
|
||||
#define IOCTL_DDB_ID _IOR(DDB_MAGIC, 0x03, struct ddb_id)
|
||||
|
||||
|
||||
int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen)
|
||||
{
|
||||
struct ddb_flashio fio = {
|
||||
.write_buf=wbuf,
|
||||
.write_len=wlen,
|
||||
.read_buf=rbuf,
|
||||
.read_len=rlen,
|
||||
.link=linknr,
|
||||
};
|
||||
|
||||
return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio);
|
||||
}
|
||||
|
||||
enum {
|
||||
UNKNOWN_FLASH = 0,
|
||||
ATMEL_AT45DB642D = 1,
|
||||
SSTI_SST25VF016B = 2,
|
||||
SSTI_SST25VF032B = 3,
|
||||
SSTI_SST25VF064C = 4,
|
||||
SPANSION_S25FL116K = 5,
|
||||
};
|
||||
|
||||
|
||||
int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
|
||||
{
|
||||
uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,
|
||||
(addr >> 8) & 0xff, addr & 0xff};
|
||||
|
||||
return flashio(ddb, cmd, 4, buf, len);
|
||||
}
|
||||
|
||||
int flashdump(int ddb, uint32_t addr, uint32_t len)
|
||||
{
|
||||
int i, j;
|
||||
uint8_t buf[32];
|
||||
int bl = sizeof(buf);
|
||||
|
||||
for (j=0; j<len; j+=bl, addr+=bl) {
|
||||
flashread(ddb, buf, addr, bl);
|
||||
for (i=0; i<bl; i++) {
|
||||
printf("%02x ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int FlashDetect(int dev)
|
||||
{
|
||||
uint8_t Cmd = 0x9F;
|
||||
uint8_t Id[3];
|
||||
|
||||
int r = flashio(dev, &Cmd,1,Id,3);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x41 )
|
||||
r = SSTI_SST25VF016B;
|
||||
else if( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4A )
|
||||
r = SSTI_SST25VF032B;
|
||||
else if( Id[0] == 0x1F && Id[1] == 0x28 )
|
||||
r = ATMEL_AT45DB642D;
|
||||
else if( Id[0] == 0xBF && Id[1] == 0x25 && Id[2] == 0x4B )
|
||||
r = SSTI_SST25VF064C;
|
||||
else if( Id[0] == 0x01 && Id[1] == 0x40 && Id[2] == 0x15 )
|
||||
r = SPANSION_S25FL116K;
|
||||
else
|
||||
r = UNKNOWN_FLASH;
|
||||
|
||||
switch(r) {
|
||||
case UNKNOWN_FLASH:
|
||||
printf("Unknown Flash Flash ID = %02x %02x %02x\n",Id[0],Id[1],Id[2]);
|
||||
break;
|
||||
case ATMEL_AT45DB642D:
|
||||
printf("Flash: Atmel AT45DB642D 64 MBit\n");
|
||||
break;
|
||||
case SSTI_SST25VF016B:
|
||||
printf("Flash: SSTI SST25VF016B 16 MBit\n");
|
||||
break;
|
||||
case SSTI_SST25VF032B:
|
||||
printf("Flash: SSTI SST25VF032B 32 MBit\n"); break;
|
||||
case SSTI_SST25VF064C:
|
||||
printf("Flash: SSTI SST25VF064C 64 MBit\n"); break;
|
||||
case SPANSION_S25FL116K:
|
||||
printf("Flash: SPANSION S25FL116K 16 MBit\n"); break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize)
|
||||
{
|
||||
int err = 0;
|
||||
int BlockErase = BufferSize >= 8192;
|
||||
int i;
|
||||
|
||||
if (BlockErase) {
|
||||
for(i = 0; i < BufferSize; i += 8192 ) {
|
||||
uint8_t Cmd[4];
|
||||
if( (i & 0xFFFF) == 0 )
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
Cmd[0] = 0x50; // Block Erase
|
||||
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
err = flashio(dev,Cmd,4,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
Cmd[0] = 0xD7; // Read Status register
|
||||
err = flashio(dev,Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x80) == 0x80 ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < BufferSize; i += 1024 )
|
||||
{
|
||||
uint8_t Cmd[4 + 1024];
|
||||
if( (i & 0xFFFF) == 0 )
|
||||
{
|
||||
printf(" Program %08x\n",FlashOffset + i);
|
||||
}
|
||||
Cmd[0] = 0x84; // Buffer 1
|
||||
Cmd[1] = 0x00;
|
||||
Cmd[2] = 0x00;
|
||||
Cmd[3] = 0x00;
|
||||
memcpy(&Cmd[4],&Buffer[i],1024);
|
||||
|
||||
err = flashio(dev,Cmd,4 + 1024,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase)
|
||||
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
|
||||
err = flashio(dev,Cmd,4,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
Cmd[0] = 0xD7; // Read Status register
|
||||
err = flashio(dev,Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x80) == 0x80 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int FlashWritePageMode(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize, uint8_t LockBits)
|
||||
{
|
||||
int err = 0, i, j;
|
||||
uint8_t Cmd[260];
|
||||
|
||||
if( (BufferSize % 4096) != 0 )
|
||||
return -1; // Must be multiple of sector size
|
||||
|
||||
do {
|
||||
Cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev, Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x01; // WRSR
|
||||
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
|
||||
err = flashio(dev, Cmd,2,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
for(i = 0; i < BufferSize; i += 4096 ) {
|
||||
if( (i & 0xFFFF) == 0 ) {
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
}
|
||||
|
||||
Cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev, Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x20; // Sector erase ( 4Kb)
|
||||
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
err = flashio(dev, Cmd,4,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
while(1)
|
||||
{
|
||||
Cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev, Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
|
||||
for (j = BufferSize - 256; j >= 0; j -= 256 )
|
||||
{
|
||||
if( (j & 0xFFFF) == 0 )
|
||||
{
|
||||
printf(" Programm %08x\n",FlashOffset + j);
|
||||
}
|
||||
|
||||
Cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev, Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x02; // PP
|
||||
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
memcpy(&Cmd[4],&Buffer[j],256);
|
||||
err = flashio(dev, Cmd,260,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
while(1)
|
||||
{
|
||||
Cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev, Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev, Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x01; // WRSR
|
||||
Cmd[1] = LockBits; // BPx = 0, Lock all blocks
|
||||
err = flashio(dev, Cmd,2,NULL,0);
|
||||
|
||||
} while(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int FlashWriteSSTI_B(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize)
|
||||
{
|
||||
int err = 0;
|
||||
uint8_t Cmd[6];
|
||||
int i, j;
|
||||
|
||||
// Must be multiple of sector size
|
||||
if( (BufferSize % 4096) != 0 )
|
||||
return -1;
|
||||
|
||||
do {
|
||||
Cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev,Cmd,1,NULL,0);
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
Cmd[0] = 0x01; // WRSR
|
||||
Cmd[1] = 0x00; // BPx = 0, Unlock all blocks
|
||||
err = flashio(dev,Cmd,2,NULL,0);
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
for(i = 0; i < BufferSize; i += 4096 ) {
|
||||
if( (i & 0xFFFF) == 0 )
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
Cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev,Cmd,1,NULL,0);
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
Cmd[0] = 0x20; // Sector erase ( 4Kb)
|
||||
Cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
err = flashio(dev,Cmd,4,NULL,0);
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
Cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev,Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
}
|
||||
if( err < 0 )
|
||||
break;
|
||||
for(j = BufferSize - 4096; j >= 0; j -= 4096 ) {
|
||||
if( (j & 0xFFFF) == 0 )
|
||||
printf(" Program %08x\n",FlashOffset + j);
|
||||
|
||||
for(i = 0; i < 4096; i += 2 ) {
|
||||
if( i == 0 ) {
|
||||
Cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev,Cmd,1,NULL,0);
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
Cmd[0] = 0xAD; // AAI
|
||||
Cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
|
||||
Cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
|
||||
Cmd[3] = 0x00;
|
||||
Cmd[4] = Buffer[j+i];
|
||||
Cmd[5] = Buffer[j+i+1];
|
||||
err = flashio(dev,Cmd,6,NULL,0);
|
||||
} else {
|
||||
Cmd[0] = 0xAD; // AAI
|
||||
Cmd[1] = Buffer[j+i];
|
||||
Cmd[2] = Buffer[j+i+1];
|
||||
err = flashio(dev,Cmd,3,NULL,0);
|
||||
}
|
||||
if( err < 0 )
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
Cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev,Cmd,1,&Cmd[0],1);
|
||||
if( err < 0 ) break;
|
||||
if( (Cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x04; // WDIS
|
||||
err = flashio(dev,Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
}
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev,Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
Cmd[0] = 0x01; // WRSR
|
||||
Cmd[1] = 0x1C; // BPx = 0, Lock all blocks
|
||||
err = flashio(dev,Cmd,2,NULL,0);
|
||||
} while(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
void get_id(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, 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];
|
||||
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;
|
||||
int SectorSize=0;
|
||||
int FlashSize=0;
|
||||
int Flash;
|
||||
|
||||
uint32_t svid=0, jump=0, dump=0;
|
||||
int bin;
|
||||
|
||||
int ddbnum = 0;
|
||||
int force = 0;
|
||||
|
||||
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:dfhj",
|
||||
long_options, &option_index);
|
||||
if (c==-1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
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);
|
||||
|
||||
switch(Flash) {
|
||||
case ATMEL_AT45DB642D:
|
||||
SectorSize = 1024;
|
||||
FlashSize = 0x800000;
|
||||
break;
|
||||
case SSTI_SST25VF016B:
|
||||
SectorSize = 4096;
|
||||
FlashSize = 0x200000;
|
||||
break;
|
||||
case SSTI_SST25VF032B:
|
||||
SectorSize = 4096;
|
||||
FlashSize = 0x400000;
|
||||
break;
|
||||
case SSTI_SST25VF064C:
|
||||
SectorSize = 4096;
|
||||
FlashSize = 0x800000;
|
||||
break;
|
||||
case SPANSION_S25FL116K:
|
||||
SectorSize = 4096;
|
||||
FlashSize = 0x200000;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
get_id(ddb, &ddbid);
|
||||
#if 1
|
||||
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, dump, 128);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ddbid.device == 0x0011)
|
||||
type = 1;
|
||||
if (ddbid.device == 0x0201)
|
||||
type = 2;
|
||||
if (ddbid.device == 0x02)
|
||||
type = 3;
|
||||
if (ddbid.device == 0x03)
|
||||
type = 0;
|
||||
if (ddbid.device == 0x07)
|
||||
type = 4;
|
||||
if (ddbid.device == 0x320)
|
||||
type = 5;
|
||||
if (ddbid.device == 0x13)
|
||||
type = 6;
|
||||
if (ddbid.device == 0x12)
|
||||
type = 7;
|
||||
|
||||
if (!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 *fname;
|
||||
|
||||
switch (type) {
|
||||
case 0:
|
||||
fname="DVBBridgeV1B_DVBBridgeV1B.bit";
|
||||
printf("Octopus\n");
|
||||
break;
|
||||
case 1:
|
||||
fname="CIBridgeV1B_CIBridgeV1B.bit";
|
||||
printf("Octopus CI\n");
|
||||
break;
|
||||
case 2:
|
||||
fname="DVBModulatorV1B_DVBModulatorV1B.bit";
|
||||
printf("Modulator\n");
|
||||
break;
|
||||
case 3:
|
||||
fname="DVBBridgeV1A_DVBBridgeV1A.bit";
|
||||
printf("Octopus 35\n");
|
||||
break;
|
||||
case 4:
|
||||
fname="DVBBridgeV2A_DD01_0007_MXL.bit";
|
||||
printf("Octopus 4/8\n");
|
||||
break;
|
||||
case 6:
|
||||
fname="DVBBridgeV2B_DD01_0013_PRO.fpga";
|
||||
printf("Octopus PRO\n");
|
||||
break;
|
||||
case 7:
|
||||
fname="DVBBridgeV2B_DD01_0012_STD.fpga";
|
||||
printf("Octopus CI\n");
|
||||
break;
|
||||
default:
|
||||
printf("UNKNOWN\n");
|
||||
break;
|
||||
}
|
||||
fh = open(fname, O_RDONLY);
|
||||
if (fh < 0 ) {
|
||||
printf("File not found \n");
|
||||
return 0;
|
||||
}
|
||||
printf("Using bitstream %s\n", fname);
|
||||
|
||||
fsize = lseek(fh,0,SEEK_END);
|
||||
if( fsize > 4000000 || 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:
|
||||
err = FlashWritePageMode(ddb,FlashOffset,buffer,BufferSize,0x1C);
|
||||
break;
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
printf("Programming Error\n");
|
||||
else
|
||||
printf("Programming Done\n");
|
||||
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
36
apps/modt.c
Normal file
36
apps/modt.c
Normal file
@ -0,0 +1,36 @@
|
||||
#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();
|
||||
}
|
19
apps/octonet/Makefile
Normal file
19
apps/octonet/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
all: ddtest octonet octokey ddflash
|
||||
|
||||
install: all
|
||||
install -m 0755 ddtest $(DESTDIR)/usr/bin
|
||||
install -m 0755 octonet $(DESTDIR)/usr/bin
|
||||
install -m 0755 octokey $(DESTDIR)/usr/bin
|
||||
install -m 0755 ddflash $(DESTDIR)/usr/bin
|
||||
|
||||
ddflash: ddflash.c
|
||||
$(CC) -o ddflash ddflash.c
|
||||
|
||||
ddtest: ddtest.c
|
||||
$(CC) -o ddtest ddtest.c
|
||||
|
||||
octonet: octonet.c
|
||||
$(CC) -o octonet octonet.c
|
||||
|
||||
octokey: octokey.c
|
||||
$(CC) -o octokey octokey.c
|
791
apps/octonet/ddflash.c
Normal file
791
apps/octonet/ddflash.c
Normal file
@ -0,0 +1,791 @@
|
||||
/*
|
||||
/* ddflash - Programmer for flash on Digital Devices devices
|
||||
*
|
||||
* Copyright (C) 2013 Digital Devices GmbH
|
||||
* Ralph Metzler <rmetzler@digitaldevices.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 3 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 <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "flash.h"
|
||||
|
||||
static int reboot(uint32_t off)
|
||||
{
|
||||
FILE *f;
|
||||
uint32_t time;
|
||||
|
||||
if ((f = fopen ("/sys/class/rtc/rtc0/since_epoch", "r")) == NULL)
|
||||
return -1;
|
||||
fscanf(f, "%u", &time);
|
||||
fclose(f);
|
||||
|
||||
if ((f = fopen ("/sys/class/rtc/rtc0/wakealarm", "r+")) == NULL)
|
||||
return -1;
|
||||
fprintf(f, "%u", time + off);
|
||||
fclose(f);
|
||||
system("/sbin/poweroff");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ddflash {
|
||||
int fd;
|
||||
struct ddb_id id;
|
||||
uint32_t type;
|
||||
uint32_t version;
|
||||
|
||||
uint32_t sector_size;
|
||||
uint32_t size;
|
||||
|
||||
uint32_t bufsize;
|
||||
uint32_t block_erase;
|
||||
|
||||
uint8_t * buffer;
|
||||
};
|
||||
|
||||
int flashio(int ddb, uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen)
|
||||
{
|
||||
struct ddb_flashio fio = {
|
||||
.write_buf=wbuf,
|
||||
.write_len=wlen,
|
||||
.read_buf=rbuf,
|
||||
.read_len=rlen,
|
||||
.link=0,
|
||||
};
|
||||
|
||||
return ioctl(ddb, IOCTL_DDB_FLASHIO, &fio);
|
||||
}
|
||||
|
||||
enum {
|
||||
UNKNOWN_FLASH = 0,
|
||||
ATMEL_AT45DB642D = 1,
|
||||
SSTI_SST25VF016B = 2,
|
||||
SSTI_SST25VF032B = 3,
|
||||
};
|
||||
|
||||
static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
|
||||
{
|
||||
uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,
|
||||
(addr >> 8) & 0xff, addr & 0xff};
|
||||
|
||||
return flashio(ddb, cmd, 4, buf, len);
|
||||
}
|
||||
|
||||
static int flashdump(struct ddflash *ddf, uint32_t addr, uint32_t len)
|
||||
{
|
||||
int i, j;
|
||||
uint8_t buf[32];
|
||||
int bl = sizeof(buf);
|
||||
|
||||
for (j = 0; j < len; j += bl, addr += bl) {
|
||||
flashread(ddf->fd, buf, addr, bl);
|
||||
for (i = 0; i < bl; i++) {
|
||||
printf("%02x ", buf[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void dump(const uint8_t *b, int l)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < l; j += 16, b += 16) {
|
||||
for (i = 0; i < 16; i++)
|
||||
if (i + j < l)
|
||||
printf("%02x ", b[i]);
|
||||
else
|
||||
printf(" ");
|
||||
printf(" | ");
|
||||
for (i = 0; i < 16; i++)
|
||||
if (i + j < l)
|
||||
putchar((b[i] > 31 && b[i] < 127) ? b[i] : '.');
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static int flashwrite_SSTI(struct ddflash *ddf, int fs, uint32_t FlashOffset, uint32_t maxlen, uint32_t fw_off)
|
||||
{
|
||||
int err = 0;
|
||||
uint8_t cmd[6];
|
||||
int i, j;
|
||||
uint32_t flen, blen;
|
||||
|
||||
blen = flen = lseek(fs, 0, SEEK_END) - fw_off;
|
||||
if (blen % 0xfff)
|
||||
blen = (blen + 0xfff) & 0xfffff000;
|
||||
printf("blen = %u, flen = %u\n", blen, flen);
|
||||
do {
|
||||
#if 1
|
||||
cmd[0] = 0x50; // EWSR
|
||||
err = flashio(ddf->fd, cmd, 1, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = 0x00; // BPx = 0, Unlock all blocks
|
||||
err = flashio(ddf->fd, cmd, 2, NULL, 0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
for (i = 0; i < flen; i += 4096) {
|
||||
if ((i & 0xFFFF) == 0 )
|
||||
printf("Erase %08x\n", FlashOffset + i);
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(ddf->fd, cmd, 1, NULL, 0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
cmd[0] = 0x20; // Sector erase ( 4Kb)
|
||||
cmd[1] = (((FlashOffset + i ) >> 16) & 0xFF);
|
||||
cmd[2] = (((FlashOffset + i ) >> 8) & 0xFF);
|
||||
cmd[3] = 0x00;
|
||||
err = flashio(ddf->fd,cmd,4,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
cmd[0] = 0x05; // RDRS
|
||||
err = flashio(ddf->fd,cmd,1,&cmd[0],1);
|
||||
if (err < 0 ) break;
|
||||
if ((cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
}
|
||||
if (err < 0 )
|
||||
break;
|
||||
#endif
|
||||
for (j = blen - 4096; j >= 0; j -= 4096 ) {
|
||||
uint32_t len = 4096;
|
||||
ssize_t rlen;
|
||||
|
||||
if (lseek(fs, j + fw_off, SEEK_SET) < 0) {
|
||||
printf("seek error\n");
|
||||
return -1;
|
||||
}
|
||||
if (flen - j < 4096) {
|
||||
len = flen - j;
|
||||
memset(ddf->buffer, 0xff, 4096);
|
||||
}
|
||||
rlen = read(fs, ddf->buffer, len);
|
||||
if (rlen < 0 || rlen != len) {
|
||||
printf("file read error %d,%d at %u\n", rlen, errno, j);
|
||||
return -1;
|
||||
}
|
||||
printf ("write %u bytes at %08x\n", len, j);
|
||||
|
||||
if ((j & 0xFFFF) == 0 )
|
||||
printf(" Program %08x\n",FlashOffset + j);
|
||||
#if 1
|
||||
for (i = 0; i < 4096; i += 2) {
|
||||
if (i == 0) {
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(ddf->fd, cmd, 1, NULL, 0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
cmd[0] = 0xAD; // AAI
|
||||
cmd[1] = ((( FlashOffset + j ) >> 16) & 0xFF );
|
||||
cmd[2] = ((( FlashOffset + j ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
cmd[4] = ddf->buffer[i];
|
||||
cmd[5] = ddf->buffer[i + 1];
|
||||
err = flashio(ddf->fd,cmd,6,NULL,0);
|
||||
} else {
|
||||
cmd[0] = 0xAD; // AAI
|
||||
cmd[1] = ddf->buffer[i];
|
||||
cmd[2] = ddf->buffer[i + 1];
|
||||
err = flashio(ddf->fd,cmd,3,NULL,0);
|
||||
}
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
cmd[0] = 0x05; // RDRS
|
||||
err = flashio(ddf->fd,cmd,1,&cmd[0],1);
|
||||
if (err < 0 ) break;
|
||||
if ((cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if (err < 0 )
|
||||
break;
|
||||
}
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
cmd[0] = 0x04; // WDIS
|
||||
err = flashio(ddf->fd, cmd, 1, NULL, 0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
|
||||
cmd[0] = 0x50; // EWSR
|
||||
err = flashio(ddf->fd,cmd,1,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = 0x1C; // BPx = 0, Lock all blocks
|
||||
err = flashio(ddf->fd,cmd,2,NULL,0);
|
||||
} while(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off)
|
||||
{
|
||||
flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off);
|
||||
}
|
||||
|
||||
static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off)
|
||||
{
|
||||
off_t off;
|
||||
uint32_t len;
|
||||
int i, j, rlen;
|
||||
uint8_t buf[256], buf2[256];
|
||||
int bl = sizeof(buf);
|
||||
|
||||
off = lseek(fs, 0, SEEK_END);
|
||||
if (off < 0)
|
||||
return -1;
|
||||
len = off - fw_off;
|
||||
lseek(fs, fw_off, SEEK_SET);
|
||||
if (len > maxlen) {
|
||||
printf("file too big\n");
|
||||
return -1;
|
||||
}
|
||||
printf("flash file len %u, compare to %08x in flash\n", len, addr);
|
||||
for (j = 0; j < len; j += bl, addr += bl) {
|
||||
if (len - j < bl)
|
||||
bl = len - j;
|
||||
flashread(ddf->fd, buf, addr, bl);
|
||||
rlen = read(fs, buf2, bl);
|
||||
if (rlen < 0 || rlen != bl) {
|
||||
printf("read error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (memcmp(buf, buf2, bl)) {
|
||||
printf("flash differs at %08x (offset %u)\n", addr, j);
|
||||
dump(buf, 32);
|
||||
dump(buf2, 32);
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
printf("flash same as file\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
static int flash_detect(struct ddflash *ddf)
|
||||
{
|
||||
uint8_t cmd = 0x9F;
|
||||
uint8_t id[3];
|
||||
|
||||
int r = flashio(ddf->fd, &cmd, 1, id, 3);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x41) {
|
||||
r = SSTI_SST25VF016B;
|
||||
//printf("Flash: SSTI SST25VF016B 16 MBit\n");
|
||||
ddf->sector_size = 4096;
|
||||
ddf->size = 0x200000;
|
||||
} else if (id[0] == 0xBF && id[1] == 0x25 && id[2] == 0x4A) {
|
||||
r = SSTI_SST25VF032B;
|
||||
//printf("Flash: SSTI SST25VF032B 32 MBit\n");
|
||||
ddf->sector_size = 4096;
|
||||
ddf->size = 0x400000;
|
||||
} else if (id[0] == 0x1F && id[1] == 0x28) {
|
||||
r = ATMEL_AT45DB642D;
|
||||
//printf("Flash: Atmel AT45DB642D 64 MBit\n");
|
||||
ddf->sector_size = 1024;
|
||||
ddf->size = 0x800000;
|
||||
} else {
|
||||
r = UNKNOWN_FLASH;
|
||||
//printf("Unknown Flash Flash ID = %02x %02x %02x\n", id[0], id[1], id[2]);
|
||||
}
|
||||
if (ddf->sector_size) {
|
||||
ddf->buffer = malloc(ddf->sector_size);
|
||||
//printf("allocated buffer %08x@%08x\n", ddf->sector_size, (uint32_t) ddf->buffer);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int FlashWriteAtmel(int dev,uint32_t FlashOffset, uint8_t *Buffer,int BufferSize)
|
||||
{
|
||||
int err = 0;
|
||||
int BlockErase = BufferSize >= 8192;
|
||||
int i;
|
||||
|
||||
if (BlockErase) {
|
||||
for (i = 0; i < BufferSize; i += 8192 ) {
|
||||
uint8_t cmd[4];
|
||||
if ((i & 0xFFFF) == 0 )
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
cmd[0] = 0x50; // Block Erase
|
||||
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
err = flashio(dev,cmd,4,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
cmd[0] = 0xD7; // Read Status register
|
||||
err = flashio(dev,cmd,1,&cmd[0],1);
|
||||
if (err < 0 ) break;
|
||||
if ((cmd[0] & 0x80) == 0x80 ) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < BufferSize; i += 1024) {
|
||||
uint8_t cmd[4 + 1024];
|
||||
if ((i & 0xFFFF) == 0 )
|
||||
{
|
||||
printf(" Program %08x\n",FlashOffset + i);
|
||||
}
|
||||
cmd[0] = 0x84; // Buffer 1
|
||||
cmd[1] = 0x00;
|
||||
cmd[2] = 0x00;
|
||||
cmd[3] = 0x00;
|
||||
memcpy(&cmd[4],&Buffer[i],1024);
|
||||
|
||||
err = flashio(dev,cmd,4 + 1024,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
cmd[0] = BlockErase ? 0x88 : 0x83; // Buffer to Main Memory (with Erase)
|
||||
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
|
||||
err = flashio(dev,cmd,4,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
cmd[0] = 0xD7; // Read Status register
|
||||
err = flashio(dev,cmd,1,&cmd[0],1);
|
||||
if (err < 0 ) break;
|
||||
if ((cmd[0] & 0x80) == 0x80 ) break;
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int FlashWriteSSTI(int dev, uint32_t FlashOffset, uint8_t *Buffer, int BufferSize)
|
||||
{
|
||||
int err = 0;
|
||||
uint8_t cmd[6];
|
||||
int i, j;
|
||||
|
||||
// Must be multiple of sector size
|
||||
if ((BufferSize % 4096) != 0 )
|
||||
return -1;
|
||||
|
||||
do {
|
||||
cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev,cmd,1,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = 0x00; // BPx = 0, Unlock all blocks
|
||||
err = flashio(dev,cmd,2,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
for (i = 0; i < BufferSize; i += 4096 ) {
|
||||
if ((i & 0xFFFF) == 0 )
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev,cmd,1,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
cmd[0] = 0x20; // Sector erase ( 4Kb)
|
||||
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
err = flashio(dev,cmd,4,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev,cmd,1,&cmd[0],1);
|
||||
if (err < 0 ) break;
|
||||
if ((cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
}
|
||||
if (err < 0 )
|
||||
break;
|
||||
for (j = BufferSize - 4096; j >= 0; j -= 4096 ) {
|
||||
if ((j & 0xFFFF) == 0 )
|
||||
printf(" Program %08x\n",FlashOffset + j);
|
||||
|
||||
for (i = 0; i < 4096; i += 2 ) {
|
||||
if (i == 0 ) {
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(dev,cmd,1,NULL,0);
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
cmd[0] = 0xAD; // AAI
|
||||
cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
cmd[4] = Buffer[j+i];
|
||||
cmd[5] = Buffer[j+i+1];
|
||||
err = flashio(dev,cmd,6,NULL,0);
|
||||
} else {
|
||||
cmd[0] = 0xAD; // AAI
|
||||
cmd[1] = Buffer[j+i];
|
||||
cmd[2] = Buffer[j+i+1];
|
||||
err = flashio(dev,cmd,3,NULL,0);
|
||||
}
|
||||
if (err < 0 )
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
cmd[0] = 0x05; // RDRS
|
||||
err = flashio(dev,cmd,1,&cmd[0],1);
|
||||
if (err < 0 ) break;
|
||||
if ((cmd[0] & 0x01) == 0 ) break;
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
|
||||
cmd[0] = 0x04; // WDIS
|
||||
err = flashio(dev,cmd,1,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
}
|
||||
if (err < 0 ) break;
|
||||
|
||||
cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev,cmd,1,NULL,0);
|
||||
if (err < 0 ) break;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = 0x1C; // BPx = 0, Lock all blocks
|
||||
err = flashio(dev,cmd,2,NULL,0);
|
||||
} while(0);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int get_id(struct ddflash *ddf) {
|
||||
uint8_t id[4];
|
||||
|
||||
if (ioctl(ddf->fd, IOCTL_DDB_ID, &ddf->id) < 0)
|
||||
return -1;
|
||||
#if 1
|
||||
printf("%04x %04x %04x %04x %08x %08x\n",
|
||||
ddf->id.vendor, ddf->id.device,
|
||||
ddf->id.subvendor, ddf->id.subdevice,
|
||||
ddf->id.hw, ddf->id.regmap);
|
||||
#endif
|
||||
if (ddf->id.device == 0x0011)
|
||||
ddf->type = 1;
|
||||
if (ddf->id.device == 0x0201)
|
||||
ddf->type = 2;
|
||||
if (ddf->id.device == 0x02)
|
||||
ddf->type = 3;
|
||||
if (ddf->id.device == 0x03)
|
||||
ddf->type = 0;
|
||||
if (ddf->id.device == 0x0300)
|
||||
ddf->type = 4;
|
||||
if (ddf->id.device == 0x0320)
|
||||
ddf->type = 5;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off)
|
||||
{
|
||||
int fd, fsize, ret = 0;
|
||||
off_t off;
|
||||
uint32_t p, i;
|
||||
uint8_t *buf;
|
||||
uint8_t hdr[256];
|
||||
unsigned int devid, version, length;
|
||||
unsigned int cid[8];
|
||||
int cids = 0;
|
||||
uint32_t maxlen = 1024 * 1024;
|
||||
|
||||
fd = open(fn, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
printf("%s: not found\n", fn);
|
||||
return -1;
|
||||
}
|
||||
off = lseek(fd, 0, SEEK_END);
|
||||
if (off < 0)
|
||||
return -1;
|
||||
fsize = off;
|
||||
if (fsize > maxlen) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
buf = malloc(fsize);
|
||||
if (!buf)
|
||||
return -1;
|
||||
read(fd, buf, fsize);
|
||||
close(fd);
|
||||
|
||||
for (p = 0; p < fsize && buf[p]; p++) {
|
||||
char *key = &buf[p], *val = NULL;
|
||||
|
||||
for (; p < fsize && buf[p] != 0x0a; p++) {
|
||||
if (buf[p] == ':') {
|
||||
buf[p] = 0;
|
||||
val = &buf[p + 1];
|
||||
}
|
||||
}
|
||||
if (val == NULL || p == fsize)
|
||||
break;
|
||||
buf[p] = 0;
|
||||
//printf("%-20s:%s\n", key, val);
|
||||
if (!strcasecmp(key, "Devid")) {
|
||||
sscanf(val, "%x", &devid);
|
||||
} else if (!strcasecmp(key, "Compat")) {
|
||||
cids = sscanf(val, "%x,%x,%x,%x,%x,%x,%x,%x",
|
||||
&cid[0], &cid[1], &cid[2], &cid[3],
|
||||
&cid[4], &cid[5], &cid[6], &cid[7]);
|
||||
if (cids < 1)
|
||||
break;
|
||||
for (i = 0; i < cids; i++)
|
||||
if (cid[i] == ddf->id.device)
|
||||
break;
|
||||
if (i == cids) {
|
||||
printf("%s: no compatible id\n", fn);
|
||||
ret = -2; /* no compatible ID */
|
||||
goto out;
|
||||
}
|
||||
} else if (!strcasecmp(key, "Version")) {
|
||||
sscanf(val, "%x", &version);
|
||||
} else if (!strcasecmp(key, "Length")) {
|
||||
sscanf(val, "%u", &length);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
*fw_off = p;
|
||||
printf("devid = %04x\n", devid);
|
||||
printf("version = %08x %08x\n", version, ddf->id.hw);
|
||||
printf("length = %u\n", length);
|
||||
printf("fsize = %u, p = %u, f-p = %u\n", fsize, p, fsize - p);
|
||||
if (devid == ddf->id.device) {
|
||||
if (version <= (ddf->id.hw & 0xffffff)) {
|
||||
printf("%s: old version\n", fn);
|
||||
ret = -3; /* same id but no newer version */
|
||||
}
|
||||
} else
|
||||
ret = 1;
|
||||
|
||||
out:
|
||||
free(buf);
|
||||
printf("check_fw = %d\n", ret);
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int update_image(struct ddflash *ddf, char *fn,
|
||||
uint32_t adr, uint32_t len,
|
||||
int has_header, int no_change)
|
||||
{
|
||||
int fs, res = 0;
|
||||
uint32_t fw_off = 0;
|
||||
|
||||
printf("Check %s\n", fn);
|
||||
if (has_header) {
|
||||
int ck;
|
||||
|
||||
ck = check_fw(ddf, fn, &fw_off);
|
||||
if (ck < 0)
|
||||
return ck;
|
||||
if (ck == 1 && no_change)
|
||||
return 0;
|
||||
}
|
||||
fs = open(fn, O_RDONLY);
|
||||
if (fs < 0 ) {
|
||||
printf("File %s not found \n", fn);
|
||||
return -1;
|
||||
}
|
||||
res = flashcmp(ddf, fs, adr, len, fw_off);
|
||||
if (res == -2) {
|
||||
printf("%s: same as flash\n", fn);
|
||||
}
|
||||
if (res < 0)
|
||||
goto out;
|
||||
res = flashwrite(ddf, fs, adr, len, fw_off);
|
||||
if (res == 0)
|
||||
res = 1;
|
||||
out:
|
||||
close(fs);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int fexists(char *fn)
|
||||
{
|
||||
struct stat b;
|
||||
|
||||
return (!stat(fn, &b));
|
||||
}
|
||||
|
||||
static int update_flash(struct ddflash *ddf)
|
||||
{
|
||||
char *fname;
|
||||
int res, stat = 0;
|
||||
|
||||
switch (ddf->id.device) {
|
||||
case 0x300:
|
||||
case 0x301:
|
||||
case 0x302:
|
||||
case 0x307:
|
||||
if ((res = update_image(ddf, "/boot/bs.img", 0x4000, 0x1000, 0, 0)) == 1)
|
||||
stat |= 4;
|
||||
if ((res = update_image(ddf, "/boot/uboot.img", 0xb0000, 0xb0000, 0, 0)) == 1)
|
||||
stat |= 2;
|
||||
if (fexists("/config/gtl.enabled")) {
|
||||
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
} else if (fexists("/config/gtl.disabled")) {
|
||||
if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
} else {
|
||||
if ((res = update_image(ddf, "/config/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/boot/fpga.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/config/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
if (res == -1)
|
||||
if ((res = update_image(ddf, "/boot/fpga_gtl.img", 0x10000, 0xa0000, 1, 1)) == 1)
|
||||
stat |= 1;
|
||||
}
|
||||
break;
|
||||
case 0x320:
|
||||
//fname="/boot/DVBNetV1A_DD01_0300.bit";
|
||||
fname="/boot/fpga.img";
|
||||
if ((res = update_image(ddf, fname, 0x10000, 0x100000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
return stat;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct ddflash ddf;
|
||||
char ddbname[80];
|
||||
uint8_t *buffer = 0;
|
||||
uint32_t FlashOffset = 0x10000;
|
||||
int i, err, res;
|
||||
int ddbnum = 0;
|
||||
|
||||
uint32_t svid, jump, flash;
|
||||
|
||||
memset(&ddf, 0, sizeof(ddf));
|
||||
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
int c;
|
||||
static struct option long_options[] = {
|
||||
{"svid", required_argument, NULL, 's'},
|
||||
{"help", no_argument , NULL, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
c = getopt_long(argc, argv,
|
||||
"d:n:s:o:l:dfhj",
|
||||
long_options, &option_index);
|
||||
if (c==-1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
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 'j':
|
||||
jump = 1;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
if (optind < argc) {
|
||||
printf("Warning: unused arguments\n");
|
||||
}
|
||||
sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum);
|
||||
while ((ddf.fd = open(ddbname, O_RDWR)) < 0) {
|
||||
if (errno == EBUSY)
|
||||
usleep(100000);
|
||||
else {
|
||||
printf("Could not open device\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
flash = flash_detect(&ddf);
|
||||
get_id(&ddf);
|
||||
|
||||
res = update_flash(&ddf);
|
||||
|
||||
if (ddf.buffer)
|
||||
free(ddf.buffer);
|
||||
if (res < 0)
|
||||
return res;
|
||||
if (res & 1)
|
||||
reboot(40);
|
||||
return res;
|
||||
}
|
1528
apps/octonet/ddtest.c
Normal file
1528
apps/octonet/ddtest.c
Normal file
File diff suppressed because it is too large
Load Diff
63
apps/octonet/flash.h
Normal file
63
apps/octonet/flash.h
Normal file
@ -0,0 +1,63 @@
|
||||
#define DDB_MAGIC 'd'
|
||||
|
||||
|
||||
struct ddb_flashio {
|
||||
__u8 *write_buf;
|
||||
__u32 write_len;
|
||||
__u8 *read_buf;
|
||||
__u32 read_len;
|
||||
__u32 link;
|
||||
};
|
||||
|
||||
struct ddb_gpio {
|
||||
__u32 mask;
|
||||
__u32 data;
|
||||
};
|
||||
|
||||
struct ddb_id {
|
||||
__u16 vendor;
|
||||
__u16 device;
|
||||
__u16 subvendor;
|
||||
__u16 subdevice;
|
||||
__u32 hw;
|
||||
__u32 regmap;
|
||||
};
|
||||
|
||||
struct ddb_reg {
|
||||
__u32 reg;
|
||||
__u32 val;
|
||||
};
|
||||
|
||||
struct ddb_mem {
|
||||
__u32 off;
|
||||
__u8 *buf;
|
||||
__u32 len;
|
||||
};
|
||||
|
||||
struct ddb_mdio {
|
||||
__u8 adr;
|
||||
__u8 reg;
|
||||
__u16 val;
|
||||
};
|
||||
|
||||
struct ddb_i2c_msg {
|
||||
__u8 bus;
|
||||
__u8 adr;
|
||||
__u8 *hdr;
|
||||
__u32 hlen;
|
||||
__u8 *msg;
|
||||
__u32 mlen;
|
||||
};
|
||||
|
||||
#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio)
|
||||
#define IOCTL_DDB_GPIO_IN _IOWR(DDB_MAGIC, 0x01, struct ddb_gpio)
|
||||
#define IOCTL_DDB_GPIO_OUT _IOWR(DDB_MAGIC, 0x02, struct ddb_gpio)
|
||||
#define IOCTL_DDB_ID _IOR(DDB_MAGIC, 0x03, struct ddb_id)
|
||||
#define IOCTL_DDB_READ_REG _IOWR(DDB_MAGIC, 0x04, struct ddb_reg)
|
||||
#define IOCTL_DDB_WRITE_REG _IOW(DDB_MAGIC, 0x05, struct ddb_reg)
|
||||
#define IOCTL_DDB_READ_MEM _IOWR(DDB_MAGIC, 0x06, struct ddb_mem)
|
||||
#define IOCTL_DDB_WRITE_MEM _IOR(DDB_MAGIC, 0x07, struct ddb_mem)
|
||||
#define IOCTL_DDB_READ_MDIO _IOWR(DDB_MAGIC, 0x08, struct ddb_mdio)
|
||||
#define IOCTL_DDB_WRITE_MDIO _IOR(DDB_MAGIC, 0x09, struct ddb_mdio)
|
||||
#define IOCTL_DDB_READ_I2C _IOWR(DDB_MAGIC, 0x0a, struct ddb_i2c_msg)
|
||||
#define IOCTL_DDB_WRITE_I2C _IOR(DDB_MAGIC, 0x0b, struct ddb_i2c_msg)
|
68
apps/octonet/ns.h
Normal file
68
apps/octonet/ns.h
Normal file
@ -0,0 +1,68 @@
|
||||
#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 1
|
||||
#define DVB_NS_RTP 2
|
||||
#define DVB_NS_RTCP 4
|
||||
#define DVB_NS_RTP_TO 8
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#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)
|
||||
|
||||
#endif /*_UAPI_DVBNS_H_*/
|
37
apps/octonet/octokey.c
Normal file
37
apps/octonet/octokey.c
Normal file
@ -0,0 +1,37 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
#include <termios.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <linux/input.h>
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int fd, len;
|
||||
struct input_event ev;
|
||||
uint32_t time;
|
||||
|
||||
fd = open("/dev/input/event0", O_RDONLY);
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
while (1) {
|
||||
if ((len = read(fd, &ev, sizeof(ev)) < sizeof(struct input_event)))
|
||||
return -1;
|
||||
printf("%u.%06u %u %u %u\n", ev.time.tv_sec, ev.time.tv_usec, ev.type, ev.code, ev.value);
|
||||
}
|
||||
|
||||
|
||||
}
|
83
apps/octonet/octonet.c
Normal file
83
apps/octonet/octonet.c
Normal file
@ -0,0 +1,83 @@
|
||||
#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 "ns.h"
|
||||
|
||||
|
||||
struct dvb_ns_params nsp = {
|
||||
.dmac = { 0x00, 0x01, 0x2e, 0x3a, 0x66,0xfc },
|
||||
.smac = { 0x00, 0x12, 0x34, 0x56, 0x78,0x90 },
|
||||
.sip = { 192, 168, 2, 80 },
|
||||
.dip = { 192, 168, 2, 58 },
|
||||
.sport = 1234,
|
||||
.dport = 6670,
|
||||
.ssrc = { 0x91, 0x82, 0x73, 0x64 },
|
||||
};
|
||||
|
||||
static int set(int fd)
|
||||
{
|
||||
uint16_t pid = 0xa000;
|
||||
|
||||
ioctl(fd, NS_SET_NET, &nsp);
|
||||
ioctl(fd, NS_START);
|
||||
ioctl(fd, NS_SET_PID, &pid);
|
||||
while(1);
|
||||
ioctl(fd, NS_STOP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ddbnum;
|
||||
int force;
|
||||
int ddb;
|
||||
char ddbname[80];
|
||||
|
||||
while (1) {
|
||||
int oi = 0;
|
||||
int c;
|
||||
static struct option lopts[] = {
|
||||
{"help", no_argument , NULL, 'h'},
|
||||
{"force", no_argument , NULL, 'f'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
c = getopt_long(argc, argv,
|
||||
"n:l:fh",
|
||||
lopts, &oi);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c) {
|
||||
case 'm':
|
||||
|
||||
break;
|
||||
case 'n':
|
||||
ddbnum = strtol(optarg, NULL, 0);
|
||||
break;
|
||||
case 'f':
|
||||
force = 1;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
if (optind < argc) {
|
||||
printf("Warning: unused arguments\n");
|
||||
}
|
||||
sprintf(ddbname, "/dev/dvb/adapter0/ns%d", ddbnum);
|
||||
ddb=open(ddbname, O_RDWR);
|
||||
if (ddb < 0) {
|
||||
printf("Could not open device\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
33
apps/setmod.c
Normal file
33
apps/setmod.c
Normal file
@ -0,0 +1,33 @@
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <linux/dvb/mod.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
int fd;
|
||||
struct dvb_mod_params mp;
|
||||
struct dvb_mod_channel_params mc;
|
||||
|
||||
fd = open("/dev/dvb/adapter1/mod0", O_RDONLY);
|
||||
|
||||
mp.base_frequency = 722000000;
|
||||
mp.attenuator = 0;
|
||||
ioctl(fd, DVB_MOD_SET, &mp);
|
||||
|
||||
mc.modulation = QAM_256;
|
||||
mc.input_bitrate = 40000000ULL << 32;
|
||||
mc.pcr_correction = 0;
|
||||
ioctl(fd, DVB_MOD_CHANNEL_SET, &mc);
|
||||
close(fd);
|
||||
}
|
||||
|
8
ddbridge/Kbuild
Normal file
8
ddbridge/Kbuild
Normal file
@ -0,0 +1,8 @@
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843 -DCONFIG_DVB_LNBP21 -DCONFIG_DVB_STV090x -DCONFIG_DVB_STV6110x -DCONFIG_DVB_DRXK -DCONFIG_DVB_STV0910 -DCONFIG_DVB_STV6111 -DCONFIG_DVB_LNBH25 -DCONFIG_DVB_MXL5XX
|
||||
|
||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddbridge.o
|
||||
obj-$(CONFIG_DVB_OCTONET) += octonet.o
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -Idrivers/media/dvb-frontends
|
||||
EXTRA_CFLAGS += -Idrivers/media/common/tuners
|
||||
NOSTDINC_FLAGS += -I$(SUBDIRS)/frontends -I$(SUBDIRS)/include -I$(SUBDIRS)/dvb-core
|
19
ddbridge/Makefile
Normal file
19
ddbridge/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
MODDEFS := CONFIG_DVB_DDBRIDGE=m
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MODDEFS) modules
|
||||
$(MAKE) -C apps
|
||||
|
||||
dep:
|
||||
DIR=`pwd`; (cd $(TOPDIR); make SUBDIRS=$$DIR dep)
|
||||
|
||||
install: all
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
|
||||
|
||||
clean:
|
||||
rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
|
||||
|
||||
|
4641
ddbridge/ddbridge-core.c
Normal file
4641
ddbridge/ddbridge-core.c
Normal file
File diff suppressed because it is too large
Load Diff
275
ddbridge/ddbridge-i2c.c
Normal file
275
ddbridge/ddbridge-i2c.c
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* ddbridge-i2c.c: Digital Devices bridge i2c driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
static int i2c_io(struct i2c_adapter *adapter, u8 adr,
|
||||
u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = wbuf, .len = wlen },
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = rbuf, .len = rlen } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
|
||||
{
|
||||
struct i2c_msg msg = {.addr = adr, .flags = 0,
|
||||
.buf = data, .len = len};
|
||||
|
||||
return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
|
||||
{
|
||||
struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1 } };
|
||||
return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_read_regs(struct i2c_adapter *adapter,
|
||||
u8 adr, u8 reg, u8 *val, u8 len)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = ®, .len = 1 },
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = len } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_read_regs16(struct i2c_adapter *adapter,
|
||||
u8 adr, u16 reg, u8 *val, u8 len)
|
||||
{
|
||||
u8 reg16[2] = { reg >> 8, reg };
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = reg16, .len = 2 },
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = len } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = ®, .len = 1},
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1 } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
|
||||
u16 reg, u8 *val)
|
||||
{
|
||||
u8 msg[2] = {reg >> 8, reg & 0xff};
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = msg, .len = 2},
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1 } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static int i2c_write_reg16(struct i2c_adapter *adap, u8 adr,
|
||||
u16 reg, u8 val)
|
||||
{
|
||||
u8 msg[3] = {reg >> 8, reg & 0xff, val};
|
||||
|
||||
return i2c_write(adap, adr, msg, 3);
|
||||
}
|
||||
|
||||
static int i2c_write_reg(struct i2c_adapter *adap, u8 adr,
|
||||
u8 reg, u8 val)
|
||||
{
|
||||
u8 msg[2] = {reg, val};
|
||||
|
||||
return i2c_write(adap, adr, msg, 2);
|
||||
}
|
||||
|
||||
static int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd)
|
||||
{
|
||||
struct ddb *dev = i2c->dev;
|
||||
unsigned long stat;
|
||||
u32 val;
|
||||
|
||||
ddbwritel(dev, (adr << 9) | cmd, i2c->regs + I2C_COMMAND);
|
||||
stat = wait_for_completion_timeout(&i2c->completion, HZ);
|
||||
if (stat == 0) {
|
||||
pr_err("DDBridge I2C timeout, card %d, port %d, link %u\n",
|
||||
dev->nr, i2c->nr, i2c->link);
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
{ /* MSI debugging*/
|
||||
u32 istat = ddbreadl(dev, INTERRUPT_STATUS);
|
||||
|
||||
dev_err(dev->dev, "DDBridge IRS %08x\n", istat);
|
||||
ddbwritel(dev, istat, INTERRUPT_ACK);
|
||||
}
|
||||
#endif
|
||||
return -EIO;
|
||||
}
|
||||
val = ddbreadl(dev, i2c->regs + I2C_COMMAND);
|
||||
if (val & 0x70000)
|
||||
return -EIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ddb_i2c_master_xfer(struct i2c_adapter *adapter,
|
||||
struct i2c_msg msg[], int num)
|
||||
{
|
||||
struct ddb_i2c *i2c = (struct ddb_i2c *) i2c_get_adapdata(adapter);
|
||||
struct ddb *dev = i2c->dev;
|
||||
u8 addr = 0;
|
||||
|
||||
if (num != 1 && num != 2)
|
||||
return -EIO;
|
||||
addr = msg[0].addr;
|
||||
if (msg[0].len > i2c->bsize)
|
||||
return -EIO;
|
||||
if (num == 2 && msg[1].flags & I2C_M_RD &&
|
||||
!(msg[0].flags & I2C_M_RD)) {
|
||||
if (msg[1].len > i2c->bsize)
|
||||
return -EIO;
|
||||
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
|
||||
ddbwritel(dev, msg[0].len | (msg[1].len << 16),
|
||||
i2c->regs + I2C_TASKLENGTH);
|
||||
if (!ddb_i2c_cmd(i2c, addr, 1)) {
|
||||
ddbcpyfrom(dev, msg[1].buf,
|
||||
i2c->rbuf,
|
||||
msg[1].len);
|
||||
return num;
|
||||
}
|
||||
}
|
||||
if (num == 1 && !(msg[0].flags & I2C_M_RD)) {
|
||||
ddbcpyto(dev, i2c->wbuf, msg[0].buf, msg[0].len);
|
||||
ddbwritel(dev, msg[0].len, i2c->regs + I2C_TASKLENGTH);
|
||||
if (!ddb_i2c_cmd(i2c, addr, 2))
|
||||
return num;
|
||||
}
|
||||
if (num == 1 && (msg[0].flags & I2C_M_RD)) {
|
||||
ddbwritel(dev, msg[0].len << 16, i2c->regs + I2C_TASKLENGTH);
|
||||
if (!ddb_i2c_cmd(i2c, addr, 3)) {
|
||||
ddbcpyfrom(dev, msg[0].buf,
|
||||
i2c->rbuf, msg[0].len);
|
||||
return num;
|
||||
}
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
static u32 ddb_i2c_functionality(struct i2c_adapter *adap)
|
||||
{
|
||||
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
|
||||
}
|
||||
|
||||
struct i2c_algorithm ddb_i2c_algo = {
|
||||
.master_xfer = ddb_i2c_master_xfer,
|
||||
.functionality = ddb_i2c_functionality,
|
||||
};
|
||||
|
||||
static void ddb_i2c_release(struct ddb *dev)
|
||||
{
|
||||
int i;
|
||||
struct ddb_i2c *i2c;
|
||||
|
||||
for (i = 0; i < dev->i2c_num; i++) {
|
||||
i2c = &dev->i2c[i];
|
||||
i2c_del_adapter(&i2c->adap);
|
||||
}
|
||||
}
|
||||
|
||||
static void i2c_handler(unsigned long priv)
|
||||
{
|
||||
struct ddb_i2c *i2c = (struct ddb_i2c *) priv;
|
||||
|
||||
complete(&i2c->completion);
|
||||
}
|
||||
|
||||
static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
|
||||
struct ddb_regmap *regmap, int link, int i, int num)
|
||||
{
|
||||
struct i2c_adapter *adap;
|
||||
|
||||
i2c->nr = i;
|
||||
i2c->dev = dev;
|
||||
i2c->link = link;
|
||||
i2c->bsize = regmap->i2c_buf->size;
|
||||
i2c->wbuf = DDB_LINK_TAG(link) | (regmap->i2c_buf->base + i2c->bsize * i);
|
||||
i2c->rbuf = i2c->wbuf;// + i2c->bsize / 2;
|
||||
i2c->regs = DDB_LINK_TAG(link) | (regmap->i2c->base + regmap->i2c->size * i);
|
||||
ddbwritel(dev, I2C_SPEED_100, i2c->regs + I2C_TIMING);
|
||||
ddbwritel(dev, ((i2c->rbuf & 0xffff) << 16) | (i2c->wbuf & 0xffff),
|
||||
i2c->regs + I2C_TASKADDRESS);
|
||||
init_completion(&i2c->completion);
|
||||
|
||||
adap = &i2c->adap;
|
||||
i2c_set_adapdata(adap, i2c);
|
||||
#ifdef I2C_ADAP_CLASS_TV_DIGITAL
|
||||
adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG;
|
||||
#else
|
||||
#ifdef I2C_CLASS_TV_ANALOG
|
||||
adap->class = I2C_CLASS_TV_ANALOG;
|
||||
#endif
|
||||
#endif
|
||||
strcpy(adap->name, "ddbridge");
|
||||
adap->algo = &ddb_i2c_algo;
|
||||
adap->algo_data = (void *)i2c;
|
||||
adap->dev.parent = dev->dev;
|
||||
return i2c_add_adapter(adap);
|
||||
}
|
||||
|
||||
static int ddb_i2c_init(struct ddb *dev)
|
||||
{
|
||||
int stat = 0;
|
||||
u32 i, j, num = 0, l;
|
||||
struct ddb_i2c *i2c;
|
||||
struct i2c_adapter *adap;
|
||||
struct ddb_regmap *regmap;
|
||||
|
||||
for (l = 0; l < DDB_MAX_LINK; l++) {
|
||||
if (!dev->link[l].info)
|
||||
continue;
|
||||
regmap = dev->link[l].info->regmap;
|
||||
if (!regmap || !regmap->i2c)
|
||||
continue;
|
||||
for (i = 0; i < regmap->i2c->num; i++) {
|
||||
if (!(dev->link[l].info->i2c_mask & (1 << i)))
|
||||
continue;
|
||||
i2c = &dev->i2c[num];
|
||||
dev->handler_data[i + l * 32] = (unsigned long) i2c;
|
||||
dev->handler[i + l * 32] = i2c_handler;
|
||||
stat = ddb_i2c_add(dev, i2c, regmap, l, i, num);
|
||||
if (stat)
|
||||
break;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
if (stat) {
|
||||
for (j = 0; j < num; j++) {
|
||||
i2c = &dev->i2c[j];
|
||||
adap = &i2c->adap;
|
||||
i2c_del_adapter(adap);
|
||||
}
|
||||
} else
|
||||
dev->i2c_num = num;
|
||||
return stat;
|
||||
}
|
||||
|
116
ddbridge/ddbridge-i2c.h
Normal file
116
ddbridge/ddbridge-i2c.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
* ddbridge-i2c.h: Digital Devices bridge i2c driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _DDBRIDGE_I2C_H_
|
||||
#define _DDBRIDGE_I2C_H_
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
static inline int i2c_io(struct i2c_adapter *adapter, u8 adr,
|
||||
u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = wbuf, .len = wlen },
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = rbuf, .len = rlen } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int i2c_write(struct i2c_adapter *adap, u8 adr,
|
||||
u8 *data, int len)
|
||||
{
|
||||
struct i2c_msg msg = {.addr = adr, .flags = 0,
|
||||
.buf = data, .len = len};
|
||||
|
||||
return (i2c_transfer(adap, &msg, 1) == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val)
|
||||
{
|
||||
struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1 } };
|
||||
return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int i2c_read_regs(struct i2c_adapter *adapter,
|
||||
u8 adr, u8 reg, u8 *val, u8 len)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = ®, .len = 1 },
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = len } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int i2c_read_regs16(struct i2c_adapter *adapter,
|
||||
u8 adr, u16 reg, u8 *val, u8 len)
|
||||
{
|
||||
u8 reg16[2] = { reg >> 8, reg };
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = reg16, .len = 2 },
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = len } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int i2c_read_reg(struct i2c_adapter *adapter, u8 adr,
|
||||
u8 reg, u8 *val)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = ®, .len = 1},
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1 } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr,
|
||||
u16 reg, u8 *val)
|
||||
{
|
||||
u8 msg[2] = {reg >> 8, reg & 0xff};
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = msg, .len = 2},
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1 } };
|
||||
return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1;
|
||||
}
|
||||
|
||||
static inline int i2c_write_reg16(struct i2c_adapter *adap, u8 adr,
|
||||
u16 reg, u8 val)
|
||||
{
|
||||
u8 msg[3] = {reg >> 8, reg & 0xff, val};
|
||||
|
||||
return i2c_write(adap, adr, msg, 3);
|
||||
}
|
||||
|
||||
static inline int i2c_write_reg(struct i2c_adapter *adap, u8 adr,
|
||||
u8 reg, u8 val)
|
||||
{
|
||||
u8 msg[2] = {reg, val};
|
||||
|
||||
return i2c_write(adap, adr, msg, 2);
|
||||
}
|
||||
|
||||
#endif
|
1150
ddbridge/ddbridge-mod.c
Normal file
1150
ddbridge/ddbridge-mod.c
Normal file
File diff suppressed because it is too large
Load Diff
491
ddbridge/ddbridge-ns.c
Normal file
491
ddbridge/ddbridge-ns.c
Normal file
@ -0,0 +1,491 @@
|
||||
/*
|
||||
* ddbridge-ns.c: Digital Devices PCIe bridge driver net streaming
|
||||
*
|
||||
* Copyright (C) 2010-2015 Marcus Metzler <mocm@metzlerbros.de>
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* 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
|
||||
*/
|
||||
|
||||
static int ddb_dvb_ns_input_start(struct ddb_input *input);
|
||||
static int ddb_dvb_ns_input_stop(struct ddb_input *input);
|
||||
|
||||
static u16 calc_pcs(struct dvb_ns_params *p)
|
||||
{
|
||||
u32 sum = 0;
|
||||
u16 pcs;
|
||||
|
||||
sum += (p->sip[0] << 8) | p->sip[1];
|
||||
sum += (p->sip[2] << 8) | p->sip[3];
|
||||
sum += (p->dip[0] << 8) | p->dip[1];
|
||||
sum += (p->dip[2] << 8) | p->dip[3];
|
||||
sum += 0x11; /* UDP proto */
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
pcs = sum;
|
||||
return pcs;
|
||||
}
|
||||
|
||||
static u16 calc_pcs16(struct dvb_ns_params *p, int ipv)
|
||||
{
|
||||
u32 sum = 0, i;
|
||||
u16 pcs;
|
||||
|
||||
for (i = 0; i < ipv ? 16 : 4; i += 2) {
|
||||
sum += (p->sip[i] << 8) | p->sip[i + 1];
|
||||
sum += (p->dip[i] << 8) | p->dip[i + 1];
|
||||
}
|
||||
sum += 0x11; /* UDP proto */
|
||||
sum = (sum >> 16) + (sum & 0xffff);
|
||||
pcs = sum;
|
||||
return pcs;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static void ns_free(struct dvbnss *nss)
|
||||
{
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
dns->input = 0;
|
||||
mutex_unlock(&dev->mutex);
|
||||
}
|
||||
|
||||
static int ns_alloc(struct dvbnss *nss)
|
||||
{
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
int i, ret = -EBUSY;
|
||||
|
||||
mutex_lock(&dev->mutex);
|
||||
for (i = 0; i < dev->ns_num; i++) {
|
||||
if (dev->ns[i].input)
|
||||
continue;
|
||||
dev->ns[i].input = input;
|
||||
dev->ns[i].fe = input;
|
||||
nss->priv = &dev->ns[i];
|
||||
ret = 0;
|
||||
/*pr_info("%s i=%d fe=%d\n", __func__, i, input->nr); */
|
||||
break;
|
||||
}
|
||||
ddbwritel(dev, 0x03, RTP_MASTER_CONTROL);
|
||||
mutex_unlock(&dev->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ns_set_pids(struct dvbnss *nss)
|
||||
{
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
|
||||
if (dev->ids.devid == 0x0301dd01) {
|
||||
u32 sys = 0;
|
||||
int pid, j = 1;
|
||||
|
||||
sys |= nss->pids[0] & 3;
|
||||
sys |= (nss->pids[2] & 0x1f) << 4;
|
||||
ddbwritel(dev, sys, PID_FILTER_SYSTEM_PIDS(dns->nr));
|
||||
for (pid = 20; j < 5 && pid < 8192; pid++)
|
||||
if (nss->pids[pid >> 3] & (1 << (pid & 7))) {
|
||||
ddbwritel(dev, 0x8000 | pid,
|
||||
PID_FILTER_PID(dns->nr, j));
|
||||
j++;
|
||||
}
|
||||
/* disable unused pids */
|
||||
for (; j < 5; j++)
|
||||
ddbwritel(dev, 0, PID_FILTER_PID(dns->nr, j));
|
||||
} else
|
||||
ddbcpyto(dev, STREAM_PIDS(dns->nr), nss->pids, 0x400);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ns_set_pid(struct dvbnss *nss, u16 pid)
|
||||
{
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
u16 byte = (pid & 0x1fff) >> 3;
|
||||
u8 bit = 1 << (pid & 7);
|
||||
u32 off = STREAM_PIDS(dns->nr);
|
||||
|
||||
#if 1
|
||||
if (dev->ids.devid == 0x0301dd01) {
|
||||
if (pid & 0x2000) {
|
||||
if (pid & 0x8000)
|
||||
memset(nss->pids, 0xff, 0x400);
|
||||
else
|
||||
memset(nss->pids, 0x00, 0x400);
|
||||
} else {
|
||||
if (pid & 0x8000)
|
||||
nss->pids[byte] |= bit;
|
||||
else
|
||||
nss->pids[byte] &= ~bit;
|
||||
}
|
||||
ns_set_pids(nss);
|
||||
} else {
|
||||
if (pid & 0x2000) {
|
||||
if (pid & 0x8000)
|
||||
ddbmemset(dev, off, 0xff, 0x400);
|
||||
else
|
||||
ddbmemset(dev, off, 0x00, 0x400);
|
||||
} else {
|
||||
u8 val = ddbreadb(dev, off + byte);
|
||||
|
||||
if (pid & 0x8000)
|
||||
ddbwriteb(dev, val | bit, off + byte);
|
||||
else
|
||||
ddbwriteb(dev, val & ~bit, off + byte);
|
||||
}
|
||||
}
|
||||
#else
|
||||
ddbcpyto(dev, STREAM_PIDS(dns->nr), nss->pids, 0x400);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int citoport(struct ddb *dev, u8 ci)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = j = 0; i < dev->link[0].info->port_num; i++) {
|
||||
if (dev->port[i].class == DDB_PORT_CI) {
|
||||
if (j == ci)
|
||||
return i;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ns_set_ci(struct dvbnss *nss, u8 ci)
|
||||
{
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
int ciport;
|
||||
|
||||
if (ci == 255) {
|
||||
dns->fe = input;
|
||||
return 0;
|
||||
}
|
||||
ciport = citoport(dev, ci);
|
||||
if (ciport < 0)
|
||||
return -EINVAL;
|
||||
|
||||
pr_info("input %d.%d to ci %d at port %d\n", input->port->lnr, input->nr, ci, ciport);
|
||||
ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1c, TS_OUTPUT_CONTROL(ciport));
|
||||
usleep_range(1, 5);
|
||||
ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1d, TS_OUTPUT_CONTROL(ciport));
|
||||
dns->fe = dev->port[ciport].input[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 rtp_head[] = {
|
||||
0x80, 0x21,
|
||||
0x00, 0x00, /* seq number */
|
||||
0x00, 0x00, 0x00, 0x00, /* time stamp*/
|
||||
0x91, 0x82, 0x73, 0x64, /* SSRC */
|
||||
};
|
||||
|
||||
static u8 rtcp_head[] = {
|
||||
/* SR off 42:8 len 28*/
|
||||
0x80, 0xc8, /* SR type */
|
||||
0x00, 0x06, /* len */
|
||||
0x91, 0x82, 0x73, 0x64, /* SSRC */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* NTP */
|
||||
0x73, 0x64, 0x00, 0x00, /* RTP TS */
|
||||
0x00, 0x00, 0x00, 0x00, /* packet count */
|
||||
0x00, 0x00, 0x00, 0x00, /* octet count */
|
||||
/* SDES off 70:36 len 20 */
|
||||
0x81, 0xca, /* SDES */
|
||||
0x00, 0x03, /* len */
|
||||
0x91, 0x82, 0x73, 0x64, /* SSRC */
|
||||
0x01, 0x05, /* CNAME item */
|
||||
0x53, 0x41, 0x54, 0x49, 0x50, /* "SATIP" */
|
||||
0x00, /* item type 0 */
|
||||
/* APP off 86:52 len 16+string length */
|
||||
0x80, 0xcc, /* APP */
|
||||
0x00, 0x04, /* len */
|
||||
0x91, 0x82, 0x73, 0x64, /* SSRC */
|
||||
0x53, 0x45, 0x53, 0x31, /* "SES1" */
|
||||
0x00, 0x00, /* identifier */
|
||||
0x00, 0x00, /* string length */
|
||||
/* string off 102:68 */
|
||||
};
|
||||
|
||||
static int ns_set_rtcp_msg(struct dvbnss *nss, u8 *msg, u32 len)
|
||||
{
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
u32 off = STREAM_PACKET_ADR(dns->nr);
|
||||
u32 coff = 96;
|
||||
u16 wlen;
|
||||
|
||||
if (!len) {
|
||||
ddbwritel(dev, ddbreadl(dev, STREAM_CONTROL(dns->nr)) &
|
||||
~0x10,
|
||||
STREAM_CONTROL(dns->nr));
|
||||
return 0;
|
||||
}
|
||||
if (copy_from_user(dns->p + coff + dns->rtcp_len, msg, len))
|
||||
return -EFAULT;
|
||||
dns->p[coff + dns->rtcp_len - 2] = (len >> 8);
|
||||
dns->p[coff + dns->rtcp_len - 1] = (len & 0xff);
|
||||
if (len & 3) {
|
||||
u32 pad = 4 - (len & 3);
|
||||
|
||||
memset(dns->p + coff + dns->rtcp_len + len, 0, pad);
|
||||
len += pad;
|
||||
}
|
||||
wlen = len / 4;
|
||||
wlen += 3;
|
||||
dns->p[coff + dns->rtcp_len - 14] = (wlen >> 8);
|
||||
dns->p[coff + dns->rtcp_len - 13] = (wlen & 0xff);
|
||||
ddbcpyto(dev, off, dns->p, sizeof(dns->p));
|
||||
ddbwritel(dev, (dns->rtcp_udplen + len) |
|
||||
((STREAM_PACKET_OFF(dns->nr) + coff) << 16),
|
||||
STREAM_RTCP_PACKET(dns->nr));
|
||||
ddbwritel(dev, ddbreadl(dev, STREAM_CONTROL(dns->nr)) | 0x10,
|
||||
STREAM_CONTROL(dns->nr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u32 set_nsbuf(struct dvb_ns_params *p, u8 *buf,
|
||||
u32 *udplen, int rtcp, int vlan)
|
||||
{
|
||||
u32 c = 0;
|
||||
u16 pcs;
|
||||
u16 sport, dport;
|
||||
|
||||
sport = rtcp ? p->sport2 : p->sport;
|
||||
dport = rtcp ? p->dport2 : p->dport;
|
||||
|
||||
/* MAC header */
|
||||
memcpy(buf + c, p->dmac, 6);
|
||||
memcpy(buf + c + 6, p->smac, 6);
|
||||
c += 12;
|
||||
if (vlan) {
|
||||
buf[c + 0] = 0x81;
|
||||
buf[c + 1] = 0x00;
|
||||
buf[c + 2] = ((p->qos & 7) << 5) | ((p->vlan & 0xf00) >> 8);
|
||||
buf[c + 3] = p->vlan & 0xff;
|
||||
c += 4;
|
||||
}
|
||||
buf[c + 0] = 0x08;
|
||||
buf[c + 1] = 0x00;
|
||||
c += 2;
|
||||
|
||||
/* IP header */
|
||||
if (p->flags & DVB_NS_IPV6) {
|
||||
u8 ip6head[8] = { 0x65, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x11, 0x00, };
|
||||
memcpy(buf + c, ip6head, sizeof(ip6head));
|
||||
buf[c + 7] = p->ttl;
|
||||
memcpy(buf + c + 8, p->sip, 16);
|
||||
memcpy(buf + c + 24, p->dip, 16);
|
||||
c += 40;
|
||||
|
||||
/* UDP */
|
||||
buf[c + 0] = sport >> 8;
|
||||
buf[c + 1] = sport & 0xff;
|
||||
buf[c + 2] = dport >> 8;
|
||||
buf[c + 3] = dport & 0xff;
|
||||
buf[c + 4] = 0; /* length */
|
||||
buf[c + 5] = 0;
|
||||
pcs = calc_pcs16(p, p->flags & DVB_NS_IPV6);
|
||||
buf[c + 6] = pcs >> 8;
|
||||
buf[c + 7] = pcs & 0xff;
|
||||
c += 8;
|
||||
*udplen = 8;
|
||||
|
||||
} else {
|
||||
u8 ip4head[12] = { 0x45, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x40, 0x00, 0x40, 0x11, 0x00, 0x00 };
|
||||
|
||||
memcpy(buf + c, ip4head, sizeof(ip4head));
|
||||
buf[c + 8] = p->ttl;
|
||||
memcpy(buf + c + 12, p->sip, 4);
|
||||
memcpy(buf + c + 16, p->dip, 4);
|
||||
c += 20;
|
||||
|
||||
/* UDP */
|
||||
buf[c + 0] = sport >> 8;
|
||||
buf[c + 1] = sport & 0xff;
|
||||
buf[c + 2] = dport >> 8;
|
||||
buf[c + 3] = dport & 0xff;
|
||||
buf[c + 4] = 0; /* length */
|
||||
buf[c + 5] = 0;
|
||||
pcs = calc_pcs(p);
|
||||
buf[c + 6] = pcs >> 8;
|
||||
buf[c + 7] = pcs & 0xff;
|
||||
c += 8;
|
||||
*udplen = 8;
|
||||
}
|
||||
|
||||
if (rtcp) {
|
||||
memcpy(buf + c, rtcp_head, sizeof(rtcp_head));
|
||||
memcpy(buf + c + 4, p->ssrc, 4);
|
||||
memcpy(buf + c + 32, p->ssrc, 4);
|
||||
memcpy(buf + c + 48, p->ssrc, 4);
|
||||
c += sizeof(rtcp_head);
|
||||
*udplen += sizeof(rtcp_head);
|
||||
} else if (p->flags & DVB_NS_RTP) {
|
||||
memcpy(buf + c, rtp_head, sizeof(rtp_head));
|
||||
memcpy(buf + c + 8, p->ssrc, 4);
|
||||
c += sizeof(rtp_head);
|
||||
*udplen += sizeof(rtp_head);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static int ns_set_ts_packets(struct dvbnss *nss, u8 *buf, u32 len)
|
||||
{
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
u32 off = STREAM_PACKET_ADR(dns->nr);
|
||||
|
||||
if (nss->params.flags & DVB_NS_RTCP)
|
||||
return -EINVAL;
|
||||
|
||||
if (copy_from_user(dns->p + dns->ts_offset, buf, len))
|
||||
return -EFAULT;
|
||||
ddbcpyto(dev, off, dns->p, sizeof(dns->p));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ns_insert_ts_packets(struct dvbnss *nss, u8 count)
|
||||
{
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
u32 value = count;
|
||||
|
||||
if (nss->params.flags & DVB_NS_RTCP)
|
||||
return -EINVAL;
|
||||
|
||||
if (count < 1 || count > 2)
|
||||
return -EINVAL;
|
||||
|
||||
ddbwritel(dev, value, STREAM_INSERT_PACKET(dns->nr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ns_set_net(struct dvbnss *nss)
|
||||
{
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
struct dvb_ns_params *p = &nss->params;
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
u32 off = STREAM_PACKET_ADR(dns->nr);
|
||||
u32 coff = 96;
|
||||
|
||||
dns->ts_offset = set_nsbuf(p, dns->p, &dns->udplen, 0, dev->vlan);
|
||||
if (nss->params.flags & DVB_NS_RTCP)
|
||||
dns->rtcp_len = set_nsbuf(p, dns->p + coff,
|
||||
&dns->rtcp_udplen, 1, dev->vlan);
|
||||
ddbcpyto(dev, off, dns->p, sizeof(dns->p));
|
||||
ddbwritel(dev, dns->udplen | (STREAM_PACKET_OFF(dns->nr) << 16),
|
||||
STREAM_RTP_PACKET(dns->nr));
|
||||
ddbwritel(dev, dns->rtcp_udplen |
|
||||
((STREAM_PACKET_OFF(dns->nr) + coff) << 16),
|
||||
STREAM_RTCP_PACKET(dns->nr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ns_start(struct dvbnss *nss)
|
||||
{
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
u32 reg = 0x8003;
|
||||
|
||||
if (nss->params.flags & DVB_NS_RTCP)
|
||||
reg |= 0x10;
|
||||
if (nss->params.flags & DVB_NS_RTP_TO)
|
||||
reg |= 0x20;
|
||||
if (nss->params.flags & DVB_NS_RTP)
|
||||
reg |= 0x40;
|
||||
if (nss->params.flags & DVB_NS_IPV6)
|
||||
reg |= 0x80;
|
||||
if (dns->fe != input)
|
||||
ddb_dvb_ns_input_start(dns->fe);
|
||||
ddb_dvb_ns_input_start(input);
|
||||
printk("ns start ns %u, fe %u link %u\n", dns->nr, dns->fe->nr, dns->fe->port->lnr);
|
||||
ddbwritel(dev, reg | (dns->fe->nr << 8) | (dns->fe->port->lnr << 16),
|
||||
STREAM_CONTROL(dns->nr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ns_stop(struct dvbnss *nss)
|
||||
{
|
||||
struct ddb_ns *dns = (struct ddb_ns *) nss->priv;
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
struct ddb_input *input = ns->priv;
|
||||
struct ddb *dev = input->port->dev;
|
||||
|
||||
ddbwritel(dev, 0x00, STREAM_CONTROL(dns->nr));
|
||||
ddb_dvb_ns_input_stop(input);
|
||||
if (dns->fe != input)
|
||||
ddb_dvb_ns_input_stop(dns->fe);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netstream_init(struct ddb_input *input)
|
||||
{
|
||||
struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
|
||||
struct dvb_adapter *adap = dvb->adap;
|
||||
struct dvb_netstream *ns = &dvb->dvbns;
|
||||
struct ddb *dev = input->port->dev;
|
||||
int i, res;
|
||||
|
||||
ddbmemset(dev, STREAM_PIDS(input->nr), 0x00, 0x400);
|
||||
for (i = 0; i < dev->ns_num; i++)
|
||||
dev->ns[i].nr = i;
|
||||
ns->priv = input;
|
||||
ns->set_net = ns_set_net;
|
||||
ns->set_rtcp_msg = ns_set_rtcp_msg;
|
||||
ns->set_ts_packets = ns_set_ts_packets;
|
||||
ns->insert_ts_packets = ns_insert_ts_packets;
|
||||
ns->set_pid = ns_set_pid;
|
||||
ns->set_pids = ns_set_pids;
|
||||
ns->set_ci = ns_set_ci;
|
||||
ns->start = ns_start;
|
||||
ns->stop = ns_stop;
|
||||
ns->alloc = ns_alloc;
|
||||
ns->free = ns_free;
|
||||
res = dvb_netstream_init(adap, ns);
|
||||
return res;
|
||||
}
|
435
ddbridge/ddbridge-regs.h
Normal file
435
ddbridge/ddbridge-regs.h
Normal file
@ -0,0 +1,435 @@
|
||||
/*
|
||||
* ddbridge-regs.h: Digital Devices PCIe bridge driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 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
|
||||
*/
|
||||
|
||||
/* Register Definitions */
|
||||
|
||||
#define CUR_REGISTERMAP_VERSION 0x10003
|
||||
#define CUR_REGISTERMAP_VERSION_CI 0x10000
|
||||
#define CUR_REGISTERMAP_VERSION_MOD 0x10000
|
||||
|
||||
#define HARDWARE_VERSION 0x00
|
||||
#define REGISTERMAP_VERSION 0x04
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* SPI Controller */
|
||||
|
||||
#define SPI_CONTROL 0x10
|
||||
#define SPI_DATA 0x14
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* GPIO */
|
||||
|
||||
#define GPIO_OUTPUT 0x20
|
||||
#define GPIO_INPUT 0x24
|
||||
#define GPIO_DIRECTION 0x28
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* MDIO */
|
||||
|
||||
#define MDIO_CTRL 0x20
|
||||
#define MDIO_ADR 0x24
|
||||
#define MDIO_REG 0x28
|
||||
#define MDIO_VAL 0x2C
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define BOARD_CONTROL 0x30
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* Interrupt controller
|
||||
How many MSI's are available depends on HW (Min 2 max 8)
|
||||
How many are usable also depends on Host platform
|
||||
*/
|
||||
|
||||
#define INTERRUPT_BASE (0x40)
|
||||
|
||||
#define INTERRUPT_ENABLE (INTERRUPT_BASE + 0x00)
|
||||
#define MSI0_ENABLE (INTERRUPT_BASE + 0x00)
|
||||
#define MSI1_ENABLE (INTERRUPT_BASE + 0x04)
|
||||
#define MSI2_ENABLE (INTERRUPT_BASE + 0x08)
|
||||
#define MSI3_ENABLE (INTERRUPT_BASE + 0x0C)
|
||||
#define MSI4_ENABLE (INTERRUPT_BASE + 0x10)
|
||||
#define MSI5_ENABLE (INTERRUPT_BASE + 0x14)
|
||||
#define MSI6_ENABLE (INTERRUPT_BASE + 0x18)
|
||||
#define MSI7_ENABLE (INTERRUPT_BASE + 0x1C)
|
||||
|
||||
#define INTERRUPT_STATUS (INTERRUPT_BASE + 0x20)
|
||||
#define INTERRUPT_ACK (INTERRUPT_BASE + 0x20)
|
||||
|
||||
#define INTMASK_CLOCKGEN (0x00000001)
|
||||
#define INTMASK_TEMPMON (0x00000002)
|
||||
|
||||
#define INTMASK_I2C1 (0x00000001)
|
||||
#define INTMASK_I2C2 (0x00000002)
|
||||
#define INTMASK_I2C3 (0x00000004)
|
||||
#define INTMASK_I2C4 (0x00000008)
|
||||
|
||||
#define INTMASK_CIRQ1 (0x00000010)
|
||||
#define INTMASK_CIRQ2 (0x00000020)
|
||||
#define INTMASK_CIRQ3 (0x00000040)
|
||||
#define INTMASK_CIRQ4 (0x00000080)
|
||||
|
||||
#define INTMASK_TSINPUT1 (0x00000100)
|
||||
#define INTMASK_TSINPUT2 (0x00000200)
|
||||
#define INTMASK_TSINPUT3 (0x00000400)
|
||||
#define INTMASK_TSINPUT4 (0x00000800)
|
||||
#define INTMASK_TSINPUT5 (0x00001000)
|
||||
#define INTMASK_TSINPUT6 (0x00002000)
|
||||
#define INTMASK_TSINPUT7 (0x00004000)
|
||||
#define INTMASK_TSINPUT8 (0x00008000)
|
||||
|
||||
#define INTMASK_TSOUTPUT1 (0x00010000)
|
||||
#define INTMASK_TSOUTPUT2 (0x00020000)
|
||||
#define INTMASK_TSOUTPUT3 (0x00040000)
|
||||
#define INTMASK_TSOUTPUT4 (0x00080000)
|
||||
|
||||
|
||||
|
||||
/* Modulator registers */
|
||||
|
||||
/* Clock Generator ( Sil598 @ 0xAA I2c ) */
|
||||
#define CLOCKGEN_BASE (0x80)
|
||||
#define CLOCKGEN_CONTROL (CLOCKGEN_BASE + 0x00)
|
||||
#define CLOCKGEN_INDEX (CLOCKGEN_BASE + 0x04)
|
||||
#define CLOCKGEN_WRITEDATA (CLOCKGEN_BASE + 0x08)
|
||||
#define CLOCKGEN_READDATA (CLOCKGEN_BASE + 0x0C)
|
||||
|
||||
/* DAC ( AD9781/AD9783 SPI ) */
|
||||
#define DAC_BASE (0x090)
|
||||
#define DAC_CONTROL (DAC_BASE)
|
||||
#define DAC_WRITE_DATA (DAC_BASE+4)
|
||||
#define DAC_READ_DATA (DAC_BASE+8)
|
||||
|
||||
#define DAC_CONTROL_INSTRUCTION_REG (0xFF)
|
||||
#define DAC_CONTROL_STARTIO (0x100)
|
||||
#define DAC_CONTROL_RESET (0x200)
|
||||
|
||||
/* Temperature Monitor ( 2x LM75A @ 0x90,0x92 I2c ) */
|
||||
#define TEMPMON_BASE (0xA0)
|
||||
#define TEMPMON_CONTROL (TEMPMON_BASE + 0x00)
|
||||
/* SHORT Temperature in °C x 256 */
|
||||
#define TEMPMON_CORE (TEMPMON_BASE + 0x04)
|
||||
#define TEMPMON_SENSOR1 (TEMPMON_BASE + 0x08)
|
||||
#define TEMPMON_SENSOR2 (TEMPMON_BASE + 0x0C)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* I2C Master Controller */
|
||||
|
||||
#define I2C_BASE (0x80) /* Byte offset */
|
||||
|
||||
#define I2C_COMMAND (0x00)
|
||||
#define I2C_TIMING (0x04)
|
||||
#define I2C_TASKLENGTH (0x08) /* High read, low write */
|
||||
#define I2C_TASKADDRESS (0x0C) /* High read, low write */
|
||||
#define I2C_MONITOR (0x1C)
|
||||
|
||||
|
||||
#define I2C_SPEED_666 (0x02010202)
|
||||
#define I2C_SPEED_400 (0x04030404)
|
||||
#define I2C_SPEED_200 (0x09080909)
|
||||
#define I2C_SPEED_154 (0x0C0B0C0C)
|
||||
#define I2C_SPEED_100 (0x13121313)
|
||||
#define I2C_SPEED_77 (0x19181919)
|
||||
#define I2C_SPEED_50 (0x27262727)
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* DMA Controller */
|
||||
|
||||
#define DMA_BASE_WRITE (0x100)
|
||||
#define DMA_BASE_READ (0x140)
|
||||
|
||||
#define DMA_CONTROL (0x00)
|
||||
#define DMA_ERROR (0x04)
|
||||
|
||||
#define DMA_DIAG_CONTROL (0x1C)
|
||||
#define DMA_DIAG_PACKETCOUNTER_LOW (0x20)
|
||||
#define DMA_DIAG_PACKETCOUNTER_HIGH (0x24)
|
||||
#define DMA_DIAG_TIMECOUNTER_LOW (0x28)
|
||||
#define DMA_DIAG_TIMECOUNTER_HIGH (0x2C)
|
||||
#define DMA_DIAG_RECHECKCOUNTER (0x30)
|
||||
#define DMA_DIAG_WAITTIMEOUTINIT (0x34)
|
||||
#define DMA_DIAG_WAITOVERFLOWCOUNTER (0x38)
|
||||
#define DMA_DIAG_WAITCOUNTER (0x3C)
|
||||
|
||||
#define TS_INPUT_BASE (0x200)
|
||||
#define TS_INPUT_CONTROL(i) (TS_INPUT_BASE + (i) * 0x10 + 0x00)
|
||||
#define TS_INPUT_CONTROL2(i) (TS_INPUT_BASE + (i) * 0x10 + 0x04)
|
||||
|
||||
#define TS_OUTPUT_BASE (0x280)
|
||||
#define TS_OUTPUT_CONTROL(i) (TS_OUTPUT_BASE + (i) * 0x10 + 0x00)
|
||||
#define TS_OUTPUT_CONTROL2(i) (TS_OUTPUT_BASE + (i) * 0x10 + 0x04)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* DMA Buffer */
|
||||
|
||||
#define DMA_BUFFER_BASE (0x300)
|
||||
|
||||
#define DMA_BUFFER_CONTROL(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x00)
|
||||
#define DMA_BUFFER_ACK(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x04)
|
||||
#define DMA_BUFFER_CURRENT(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x08)
|
||||
#define DMA_BUFFER_SIZE(i) (DMA_BUFFER_BASE + (i) * 0x10 + 0x0c)
|
||||
|
||||
#define DMA_BASE_ADDRESS_TABLE (0x2000)
|
||||
#define DMA_BASE_ADDRESS_TABLE_ENTRIES (512)
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#define LNB_BASE (0x400)
|
||||
#define LNB_CONTROL(i) (LNB_BASE + (i) * 0x20 + 0x00)
|
||||
#define LNB_CMD (7ULL << 0)
|
||||
#define LNB_CMD_NOP 0
|
||||
#define LNB_CMD_INIT 1
|
||||
#define LNB_CMD_STATUS 2
|
||||
#define LNB_CMD_LOW 3
|
||||
#define LNB_CMD_HIGH 4
|
||||
#define LNB_CMD_OFF 5
|
||||
#define LNB_CMD_DISEQC 6
|
||||
#define LNB_CMD_UNI 7
|
||||
|
||||
#define LNB_BUSY (1ULL << 4)
|
||||
#define LNB_TONE (1ULL << 15)
|
||||
|
||||
#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)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* CI Interface (only CI-Bridge) */
|
||||
|
||||
#define CI_BASE (0x400)
|
||||
#define CI_CONTROL(i) (CI_BASE + (i) * 32 + 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_RESET_CAM (0x00000001)
|
||||
#define CI_POWER_ON (0x00000002)
|
||||
#define CI_ENABLE (0x00000004)
|
||||
#define CI_BLOCKIO_ENABLE (0x00000008)
|
||||
#define CI_BYPASS_DISABLE (0x00000010)
|
||||
#define CI_DISABLE_AUTO_OFF (0x00000020)
|
||||
|
||||
#define CI_CAM_READY (0x00010000)
|
||||
#define CI_CAM_DETECT (0x00020000)
|
||||
#define CI_READY (0x80000000)
|
||||
#define CI_BLOCKIO_ACTIVE (0x40000000)
|
||||
#define CI_BLOCKIO_RCVDATA (0x20000000)
|
||||
#define CI_BLOCKIO_SEND_PENDING (0x10000000)
|
||||
#define CI_BLOCKIO_SEND_COMPLETE (0x08000000)
|
||||
|
||||
#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_COMMAND (0x80000000)
|
||||
#define CI_BLOCKIO_SEND_COMPLETE_ACK (0x40000000)
|
||||
#define CI_BLOCKIO_RCVDATA_ACK (0x40000000)
|
||||
|
||||
#define CI_BUFFER_BASE (0x3000)
|
||||
#define CI_BUFFER_SIZE (0x0800)
|
||||
#define CI_BLOCKIO_BUFFER_SIZE (CI_BUFFER_SIZE/2)
|
||||
|
||||
#define CI_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE)
|
||||
#define CI_BLOCKIO_RECEIVE_BUFFER(i) (CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE)
|
||||
#define CI_BLOCKIO_SEND_BUFFER(i) \
|
||||
(CI_BUFFER_BASE + (i) * CI_BUFFER_SIZE + CI_BLOCKIO_BUFFER_SIZE)
|
||||
|
||||
#define VCO1_BASE (0xC0)
|
||||
#define VCO1_CONTROL (VCO1_BASE + 0x00)
|
||||
#define VCO1_DATA (VCO1_BASE + 0x04) /* 24 Bit */
|
||||
/* 1 = Trigger write, resets when done */
|
||||
#define VCO1_CONTROL_WRITE (0x00000001)
|
||||
/* 0 = Put VCO into power down */
|
||||
#define VCO1_CONTROL_CE (0x00000002)
|
||||
/* Muxout from VCO (usually = Lock) */
|
||||
#define VCO1_CONTROL_MUXOUT (0x00000004)
|
||||
|
||||
#define VCO2_BASE (0xC8)
|
||||
#define VCO2_CONTROL (VCO2_BASE + 0x00)
|
||||
#define VCO2_DATA (VCO2_BASE + 0x04) /* 24 Bit */
|
||||
/* 1 = Trigger write, resets when done */
|
||||
#define VCO2_CONTROL_WRITE (0x00000001)
|
||||
/* 0 = Put VCO into power down */
|
||||
#define VCO2_CONTROL_CE (0x00000002)
|
||||
/* Muxout from VCO (usually = Lock) */
|
||||
#define VCO2_CONTROL_MUXOUT (0x00000004)
|
||||
|
||||
#define VCO3_BASE (0xD0)
|
||||
#define VCO3_CONTROL (VCO3_BASE + 0x00)
|
||||
#define VCO3_DATA (VCO3_BASE + 0x04) /* 32 Bit */
|
||||
/* 1 = Trigger write, resets when done */
|
||||
#define VCO3_CONTROL_WRITE (0x00000001)
|
||||
/* 0 = Put VCO into power down */
|
||||
#define VCO3_CONTROL_CE (0x00000002)
|
||||
/* Muxout from VCO (usually = Lock) */
|
||||
#define VCO3_CONTROL_MUXOUT (0x00000004)
|
||||
|
||||
#define RF_ATTENUATOR (0xD8)
|
||||
/* 0x00 = 0 dB
|
||||
0x01 = 1 dB
|
||||
...
|
||||
0x1F = 31 dB
|
||||
*/
|
||||
|
||||
#define RF_POWER (0xE0)
|
||||
#define RF_POWER_BASE (0xE0)
|
||||
#define RF_POWER_CONTROL (RF_POWER_BASE + 0x00)
|
||||
#define RF_POWER_DATA (RF_POWER_BASE + 0x04)
|
||||
|
||||
#define RF_POWER_CONTROL_START (0x00000001)
|
||||
#define RF_POWER_CONTROL_DONE (0x00000002)
|
||||
#define RF_POWER_CONTROL_VALIDMASK (0x00000700)
|
||||
#define RF_POWER_CONTROL_VALID (0x00000500)
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Output control
|
||||
*/
|
||||
|
||||
#define IQOUTPUT_BASE (0x240)
|
||||
#define IQOUTPUT_CONTROL (IQOUTPUT_BASE + 0x00)
|
||||
#define IQOUTPUT_CONTROL2 (IQOUTPUT_BASE + 0x04)
|
||||
#define IQOUTPUT_PEAK_DETECTOR (IQOUTPUT_BASE + 0x08)
|
||||
#define IQOUTPUT_POSTSCALER (IQOUTPUT_BASE + 0x0C)
|
||||
#define IQOUTPUT_PRESCALER (IQOUTPUT_BASE + 0x10)
|
||||
|
||||
#define IQOUTPUT_EQUALIZER_0 (IQOUTPUT_BASE + 0x14)
|
||||
#define IQOUTPUT_EQUALIZER_1 (IQOUTPUT_BASE + 0x18)
|
||||
#define IQOUTPUT_EQUALIZER_2 (IQOUTPUT_BASE + 0x1C)
|
||||
#define IQOUTPUT_EQUALIZER_3 (IQOUTPUT_BASE + 0x20)
|
||||
#define IQOUTPUT_EQUALIZER_4 (IQOUTPUT_BASE + 0x24)
|
||||
#define IQOUTPUT_EQUALIZER_5 (IQOUTPUT_BASE + 0x28)
|
||||
#define IQOUTPUT_EQUALIZER_6 (IQOUTPUT_BASE + 0x2C)
|
||||
#define IQOUTPUT_EQUALIZER_7 (IQOUTPUT_BASE + 0x30)
|
||||
#define IQOUTPUT_EQUALIZER_8 (IQOUTPUT_BASE + 0x34)
|
||||
#define IQOUTPUT_EQUALIZER_9 (IQOUTPUT_BASE + 0x38)
|
||||
#define IQOUTPUT_EQUALIZER_10 (IQOUTPUT_BASE + 0x3C)
|
||||
|
||||
#define IQOUTPUT_EQUALIZER(i) (IQOUTPUT_EQUALIZER_0 + (i) * 4)
|
||||
|
||||
#define IQOUTPUT_CONTROL_RESET (0x00000001)
|
||||
#define IQOUTPUT_CONTROL_ENABLE (0x00000002)
|
||||
#define IQOUTPUT_CONTROL_RESET_PEAK (0x00000004)
|
||||
#define IQOUTPUT_CONTROL_ENABLE_PEAK (0x00000008)
|
||||
#define IQOUTPUT_CONTROL_BYPASS_EQUALIZER (0x00000010)
|
||||
|
||||
|
||||
/* Modulator Base */
|
||||
|
||||
#define MODULATOR_BASE (0x200)
|
||||
#define MODULATOR_CONTROL (MODULATOR_BASE)
|
||||
#define MODULATOR_IQTABLE_END (MODULATOR_BASE+4)
|
||||
#define MODULATOR_IQTABLE_INDEX (MODULATOR_BASE+8)
|
||||
#define MODULATOR_IQTABLE_DATA (MODULATOR_BASE+12)
|
||||
|
||||
#define MODULATOR_IQTABLE_INDEX_CHANNEL_MASK (0x000F0000)
|
||||
#define MODULATOR_IQTABLE_INDEX_IQ_MASK (0x00008000)
|
||||
#define MODULATOR_IQTABLE_INDEX_ADDRESS_MASK (0x000007FF)
|
||||
#define MODULATOR_IQTABLE_INDEX_SEL_I (0x00000000)
|
||||
#define MODULATOR_IQTABLE_INDEX_SEL_Q (MODULATOR_IQTABLE_INDEX_IQ_MASK)
|
||||
#define MODULATOR_IQTABLE_SIZE (2048)
|
||||
|
||||
|
||||
/* Modulator Channels */
|
||||
|
||||
#define CHANNEL_BASE (0x400)
|
||||
#define CHANNEL_CONTROL(i) (CHANNEL_BASE + (i) * 64 + 0x00)
|
||||
#define CHANNEL_SETTINGS(i) (CHANNEL_BASE + (i) * 64 + 0x04)
|
||||
#define CHANNEL_RATE_INCR(i) (CHANNEL_BASE + (i) * 64 + 0x0C)
|
||||
#define CHANNEL_PCR_ADJUST_OUTL(i) (CHANNEL_BASE + (i) * 64 + 0x10)
|
||||
#define CHANNEL_PCR_ADJUST_OUTH(i) (CHANNEL_BASE + (i) * 64 + 0x14)
|
||||
#define CHANNEL_PCR_ADJUST_INL(i) (CHANNEL_BASE + (i) * 64 + 0x18)
|
||||
#define CHANNEL_PCR_ADJUST_INH(i) (CHANNEL_BASE + (i) * 64 + 0x1C)
|
||||
#define CHANNEL_PCR_ADJUST_ACCUL(i) (CHANNEL_BASE + (i) * 64 + 0x20)
|
||||
#define CHANNEL_PCR_ADJUST_ACCUH(i) (CHANNEL_BASE + (i) * 64 + 0x24)
|
||||
#define CHANNEL_PKT_COUNT_OUT(i) (CHANNEL_BASE + (i) * 64 + 0x28)
|
||||
#define CHANNEL_PKT_COUNT_IN(i) (CHANNEL_BASE + (i) * 64 + 0x2C)
|
||||
|
||||
#define CHANNEL_CONTROL_RESET (0x00000001)
|
||||
#define CHANNEL_CONTROL_ENABLE_DVB (0x00000002)
|
||||
#define CHANNEL_CONTROL_ENABLE_IQ (0x00000004)
|
||||
#define CHANNEL_CONTROL_ENABLE_SOURCE (0x00000008)
|
||||
#define CHANNEL_CONTROL_ENABLE_PCRADJUST (0x00000010)
|
||||
#define CHANNEL_CONTROL_FREEZE_STATUS (0x00000100)
|
||||
|
||||
#define CHANNEL_CONTROL_RESET_ERROR (0x00010000)
|
||||
#define CHANNEL_CONTROL_BUSY (0x01000000)
|
||||
#define CHANNEL_CONTROL_ERROR_SYNC (0x20000000)
|
||||
#define CHANNEL_CONTROL_ERROR_UNDERRUN (0x40000000)
|
||||
#define CHANNEL_CONTROL_ERROR_FATAL (0x80000000)
|
||||
|
||||
#define CHANNEL_SETTINGS_QAM_MASK (0x00000007)
|
||||
#define CHANNEL_SETTINGS_QAM16 (0x00000000)
|
||||
#define CHANNEL_SETTINGS_QAM32 (0x00000001)
|
||||
#define CHANNEL_SETTINGS_QAM64 (0x00000002)
|
||||
#define CHANNEL_SETTINGS_QAM128 (0x00000003)
|
||||
#define CHANNEL_SETTINGS_QAM256 (0x00000004)
|
||||
|
||||
|
||||
/* OCTONET */
|
||||
|
||||
#define ETHER_BASE (0x100)
|
||||
#define ETHER_CONTROL (ETHER_BASE + 0x00)
|
||||
#define ETHER_LENGTH (ETHER_BASE + 0x04)
|
||||
|
||||
#define RTP_MASTER_BASE (0x120)
|
||||
#define RTP_MASTER_CONTROL (RTP_MASTER_BASE + 0x00)
|
||||
#define RTP_RTCP_INTERRUPT (RTP_MASTER_BASE + 0x04)
|
||||
#define RTP_MASTER_RTCP_SETTINGS (RTP_MASTER_BASE + 0x0c)
|
||||
|
||||
#define STREAM_BASE (0x400)
|
||||
#define STREAM_CONTROL(i) (STREAM_BASE + (i) * 0x20 + 0x00)
|
||||
#define STREAM_RTP_PACKET(i) (STREAM_BASE + (i) * 0x20 + 0x04)
|
||||
#define STREAM_RTCP_PACKET(i) (STREAM_BASE + (i) * 0x20 + 0x08)
|
||||
#define STREAM_RTP_SETTINGS(i) (STREAM_BASE + (i) * 0x20 + 0x0c)
|
||||
#define STREAM_INSERT_PACKET(i) (STREAM_BASE + (i) * 0x20 + 0x10)
|
||||
|
||||
#define STREAM_PACKET_OFF(i) ((i) * 0x200)
|
||||
#define STREAM_PACKET_ADR(i) (0x2000 + (STREAM_PACKET_OFF(i)))
|
||||
|
||||
#define STREAM_PIDS(i) (0x4000 + (i) * 0x400)
|
||||
|
||||
#define TS_CAPTURE_BASE (0x0140)
|
||||
#define TS_CAPTURE_CONTROL (TS_CAPTURE_BASE + 0x00)
|
||||
#define TS_CAPTURE_PID (TS_CAPTURE_BASE + 0x04)
|
||||
#define TS_CAPTURE_RECEIVED (TS_CAPTURE_BASE + 0x08)
|
||||
#define TS_CAPTURE_TIMEOUT (TS_CAPTURE_BASE + 0x0c)
|
||||
#define TS_CAPTURE_TABLESECTION (TS_CAPTURE_BASE + 0x10)
|
||||
|
||||
#define TS_CAPTURE_MEMORY (0x7000)
|
||||
|
||||
#define PID_FILTER_BASE (0x800)
|
||||
#define PID_FILTER_SYSTEM_PIDS(i) (PID_FILTER_BASE + (i) * 0x20)
|
||||
#define PID_FILTER_PID(i, j) (PID_FILTER_BASE + (i) * 0x20 + (j) * 4)
|
||||
|
||||
|
||||
|
533
ddbridge/ddbridge.c
Normal file
533
ddbridge/ddbridge.c
Normal file
@ -0,0 +1,533 @@
|
||||
/*
|
||||
* ddbridge.c: Digital Devices PCIe bridge driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* Ralph Metzler <rjkm@metzlerbros.de>
|
||||
* Marcus Metzler <mocm@metzlerbros.de>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 only, as published by the Free Software Foundation.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*/
|
||||
|
||||
/*#define DDB_ALT_DMA*/
|
||||
#define DDB_USE_WORK
|
||||
/*#define DDB_TEST_THREADED*/
|
||||
|
||||
#include "ddbridge.h"
|
||||
#include "ddbridge-regs.h"
|
||||
|
||||
static struct workqueue_struct *ddb_wq;
|
||||
|
||||
static int adapter_alloc;
|
||||
module_param(adapter_alloc, int, 0444);
|
||||
MODULE_PARM_DESC(adapter_alloc,
|
||||
"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all");
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
static int msi = 1;
|
||||
module_param(msi, int, 0444);
|
||||
MODULE_PARM_DESC(msi,
|
||||
" Control MSI interrupts: 0-disable, 1-enable (default)");
|
||||
#endif
|
||||
|
||||
#include "ddbridge-core.c"
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static void ddb_unmap(struct ddb *dev)
|
||||
{
|
||||
if (dev->regs)
|
||||
iounmap(dev->regs);
|
||||
vfree(dev);
|
||||
}
|
||||
|
||||
|
||||
static void __devexit ddb_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev);
|
||||
|
||||
ddb_nsd_detach(dev);
|
||||
ddb_ports_detach(dev);
|
||||
ddb_i2c_release(dev);
|
||||
|
||||
if (dev->link[0].info->ns_num)
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
ddbwritel(dev, 0, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0, MSI1_ENABLE);
|
||||
if (dev->msi == 2)
|
||||
free_irq(dev->pdev->irq + 1, dev);
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
if (dev->msi)
|
||||
pci_disable_msi(dev->pdev);
|
||||
#endif
|
||||
ddb_ports_release(dev);
|
||||
ddb_buffers_free(dev);
|
||||
ddb_device_destroy(dev);
|
||||
|
||||
ddb_unmap(dev);
|
||||
pci_set_drvdata(pdev, 0);
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
|
||||
#define __devinit
|
||||
#define __devinitdata
|
||||
#endif
|
||||
|
||||
static int __devinit ddb_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *id)
|
||||
{
|
||||
struct ddb *dev;
|
||||
int stat = 0;
|
||||
int irq_flag = IRQF_SHARED;
|
||||
|
||||
if (pci_enable_device(pdev) < 0)
|
||||
return -ENODEV;
|
||||
|
||||
dev = vzalloc(sizeof(struct ddb));
|
||||
if (dev == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&dev->mutex);
|
||||
dev->has_dma = 1;
|
||||
dev->pdev = pdev;
|
||||
dev->dev = &pdev->dev;
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
||||
dev->ids.vendor = id->vendor;
|
||||
dev->ids.device = id->device;
|
||||
dev->ids.subvendor = id->subvendor;
|
||||
dev->ids.subdevice = id->subdevice;
|
||||
|
||||
dev->link[0].dev = dev;
|
||||
dev->link[0].info = (struct ddb_info *) id->driver_data;
|
||||
pr_info("DDBridge driver detected: %s\n", dev->link[0].info->name);
|
||||
|
||||
dev->regs_len = pci_resource_len(dev->pdev, 0);
|
||||
dev->regs = ioremap(pci_resource_start(dev->pdev, 0),
|
||||
pci_resource_len(dev->pdev, 0));
|
||||
|
||||
if (!dev->regs) {
|
||||
pr_err("DDBridge: not enough memory for register map\n");
|
||||
stat = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
if (ddbreadl(dev, 0) == 0xffffffff) {
|
||||
pr_err("DDBridge: cannot read registers\n");
|
||||
stat = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dev->ids.hwid = ddbreadl(dev, 0);
|
||||
dev->ids.regmapid = ddbreadl(dev, 4);
|
||||
|
||||
pr_info("DDBridge: HW %08x REGMAP %08x\n",
|
||||
dev->ids.hwid, dev->ids.regmapid);
|
||||
|
||||
if (dev->link[0].info->ns_num) {
|
||||
int i;
|
||||
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
for (i = 0; i < 16; i++)
|
||||
ddbwritel(dev, 0x00, TS_OUTPUT_CONTROL(i));
|
||||
usleep_range(5000, 6000);
|
||||
}
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI2_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI3_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI4_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI5_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI6_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI7_ENABLE);
|
||||
|
||||
#ifdef CONFIG_PCI_MSI
|
||||
if (msi && pci_msi_enabled()) {
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
|
||||
stat = pci_enable_msi_range(dev->pdev, 1, 2);
|
||||
if (stat >= 1) {
|
||||
dev->msi = stat;
|
||||
pr_info("DDBridge: using %d MSI interrupt(s)\n", dev->msi);
|
||||
irq_flag = 0;
|
||||
} else
|
||||
pr_info("DDBridge: MSI not available.\n");
|
||||
|
||||
#else
|
||||
stat = pci_enable_msi_block(dev->pdev, 2);
|
||||
if (stat == 0) {
|
||||
dev->msi = 1;
|
||||
pr_info("DDBridge: using 2 MSI interrupts\n");
|
||||
}
|
||||
if (stat == 1)
|
||||
stat = pci_enable_msi(dev->pdev);
|
||||
if (stat < 0) {
|
||||
pr_info("DDBridge: MSI not available.\n");
|
||||
} else {
|
||||
irq_flag = 0;
|
||||
dev->msi++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (dev->msi == 2) {
|
||||
stat = request_irq(dev->pdev->irq, irq_handler0,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0)
|
||||
goto fail0;
|
||||
stat = request_irq(dev->pdev->irq + 1, irq_handler1,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
if (stat < 0) {
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
goto fail0;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
#ifdef DDB_TEST_THREADED
|
||||
stat = request_threaded_irq(dev->pdev->irq, irq_handler,
|
||||
irq_thread,
|
||||
irq_flag,
|
||||
"ddbridge", (void *) dev);
|
||||
#else
|
||||
stat = request_irq(dev->pdev->irq, irq_handler,
|
||||
irq_flag, "ddbridge", (void *) dev);
|
||||
#endif
|
||||
if (stat < 0)
|
||||
goto fail0;
|
||||
}
|
||||
ddbwritel(dev, 0, DMA_BASE_READ);
|
||||
if (dev->link[0].info->type != DDB_MOD)
|
||||
ddbwritel(dev, 0, DMA_BASE_WRITE);
|
||||
|
||||
if (dev->link[0].info->type == DDB_MOD) {
|
||||
if (ddbreadl(dev, 0x1c) == 4)
|
||||
dev->link[0].info->port_num = 4;
|
||||
}
|
||||
|
||||
/*ddbwritel(dev, 0xffffffff, INTERRUPT_ACK);*/
|
||||
if (dev->msi == 2) {
|
||||
ddbwritel(dev, 0x0fffff00, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x0000000f, MSI1_ENABLE);
|
||||
} else {
|
||||
ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0x00000000, MSI1_ENABLE);
|
||||
}
|
||||
if (ddb_init(dev) == 0)
|
||||
return 0;
|
||||
|
||||
ddbwritel(dev, 0, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0, MSI1_ENABLE);
|
||||
free_irq(dev->pdev->irq, dev);
|
||||
if (dev->msi == 2)
|
||||
free_irq(dev->pdev->irq + 1, dev);
|
||||
fail0:
|
||||
pr_err("fail0\n");
|
||||
if (dev->msi)
|
||||
pci_disable_msi(dev->pdev);
|
||||
fail:
|
||||
pr_err("fail\n");
|
||||
|
||||
ddb_unmap(dev);
|
||||
pci_set_drvdata(pdev, 0);
|
||||
pci_disable_device(pdev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_regset octopus_i2c = {
|
||||
.base = 0x80,
|
||||
.num = 0x04,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_i2c_buf = {
|
||||
.base = 0x1000,
|
||||
.num = 0x04,
|
||||
.size = 0x200,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
static struct ddb_regmap octopus_map = {
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_net_map = {
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_mod_map = {
|
||||
};
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_info ddb_none = {
|
||||
.type = DDB_NONE,
|
||||
.name = "unknown Digital Devices PCIe card, install newer driver",
|
||||
.regmap = &octopus_map,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopusv3 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus V3 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_le = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus LE DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 2,
|
||||
.i2c_mask = 0x03,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_oem = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus OEM",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.led_num = 1,
|
||||
.fan_num = 1,
|
||||
.temp_num = 1,
|
||||
.temp_bus = 0,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_mini = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus Mini",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_v6 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine S2 V6 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x07,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_v6_5 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine S2 V6.5 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_v7 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine S2 V7 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 2,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ctv7 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Cine CT V7 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.board_control = 3,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_satixS2v3 = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Mystique SaTiX-S2 V3 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x07,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ci = {
|
||||
.type = DDB_OCTOPUS_CI,
|
||||
.name = "Digital Devices Octopus CI",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x03,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_cis = {
|
||||
.type = DDB_OCTOPUS_CI,
|
||||
.name = "Digital Devices Octopus CI single",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x01,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_ci_s2_pro = {
|
||||
.type = DDB_OCTOPUS_CI,
|
||||
.name = "Digital Devices Octopus CI S2 Pro",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 3,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_dvbct = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices DVBCT V6.1 DVB adapter",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 3,
|
||||
.i2c_mask = 0x07,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static struct ddb_info ddb_s2_48 = {
|
||||
.type = DDB_OCTOPUS_MAX,
|
||||
.name = "Digital Devices MAX S8 4/8",
|
||||
.regmap = &octopus_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_mod = {
|
||||
.type = DDB_MOD,
|
||||
.name = "Digital Devices DVB-C modulator",
|
||||
.regmap = &octopus_mod_map,
|
||||
.port_num = 10,
|
||||
.temp_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octopus_net = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet network DVB adapter",
|
||||
.regmap = &octopus_net_map,
|
||||
.port_num = 10,
|
||||
.i2c_mask = 0x3ff,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
#define DDVID 0xdd01 /* Digital Devices Vendor ID */
|
||||
|
||||
#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \
|
||||
.vendor = _vend, .device = _dev, \
|
||||
.subvendor = _subvend, .subdevice = _subdev, \
|
||||
.driver_data = (unsigned long)&_driverdata }
|
||||
|
||||
static const struct pci_device_id ddb_id_tbl[] __devinitconst = {
|
||||
DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus),
|
||||
DDB_ID(DDVID, 0x0005, DDVID, 0x0004, ddb_octopusv3),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0003, ddb_octopus_oem),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus_mini),
|
||||
DDB_ID(DDVID, 0x0005, DDVID, 0x0011, ddb_octopus_mini),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0021, ddb_v6_5),
|
||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0022, ddb_v7),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0x0030, ddb_dvbct),
|
||||
DDB_ID(DDVID, 0x0003, DDVID, 0xdb03, ddb_satixS2v3),
|
||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0031, ddb_ctv7),
|
||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0032, ddb_ctv7),
|
||||
DDB_ID(DDVID, 0x0006, DDVID, 0x0033, ddb_ctv7),
|
||||
DDB_ID(DDVID, 0x0007, DDVID, 0x0023, ddb_s2_48),
|
||||
DDB_ID(DDVID, 0x0011, DDVID, 0x0040, ddb_ci),
|
||||
DDB_ID(DDVID, 0x0011, DDVID, 0x0041, ddb_cis),
|
||||
DDB_ID(DDVID, 0x0012, DDVID, 0x0042, ddb_ci),
|
||||
DDB_ID(DDVID, 0x0013, DDVID, 0x0043, ddb_ci_s2_pro),
|
||||
DDB_ID(DDVID, 0x0201, DDVID, 0x0001, ddb_mod),
|
||||
DDB_ID(DDVID, 0x0201, DDVID, 0x0002, ddb_mod),
|
||||
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_octopus_net),
|
||||
/* in case sub-ids got deleted in flash */
|
||||
DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0005, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0006, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0007, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0011, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0013, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0201, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
DDB_ID(DDVID, 0x0320, PCI_ANY_ID, PCI_ANY_ID, ddb_none),
|
||||
{0}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pci, ddb_id_tbl);
|
||||
|
||||
static struct pci_driver ddb_pci_driver = {
|
||||
.name = "ddbridge",
|
||||
.id_table = ddb_id_tbl,
|
||||
.probe = ddb_probe,
|
||||
.remove = ddb_remove,
|
||||
};
|
||||
|
||||
static __init int module_init_ddbridge(void)
|
||||
{
|
||||
int stat = -1;
|
||||
|
||||
pr_info("Digital Devices PCIE bridge driver "
|
||||
DDBRIDGE_VERSION
|
||||
", Copyright (C) 2010-15 Digital Devices GmbH\n");
|
||||
if (ddb_class_create() < 0)
|
||||
return -1;
|
||||
ddb_wq = create_workqueue("ddbridge");
|
||||
if (ddb_wq == NULL)
|
||||
goto exit1;
|
||||
stat = pci_register_driver(&ddb_pci_driver);
|
||||
if (stat < 0)
|
||||
goto exit2;
|
||||
return stat;
|
||||
exit2:
|
||||
destroy_workqueue(ddb_wq);
|
||||
exit1:
|
||||
ddb_class_destroy();
|
||||
return stat;
|
||||
}
|
||||
|
||||
static __exit void module_exit_ddbridge(void)
|
||||
{
|
||||
pci_unregister_driver(&ddb_pci_driver);
|
||||
destroy_workqueue(ddb_wq);
|
||||
ddb_class_destroy();
|
||||
}
|
||||
|
||||
module_init(module_init_ddbridge);
|
||||
module_exit(module_exit_ddbridge);
|
||||
|
||||
MODULE_DESCRIPTION("Digital Devices PCIe Bridge");
|
||||
MODULE_AUTHOR("Ralph and Marcus Metzler, Metzler Brothers Systementwicklung GbR");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DDBRIDGE_VERSION);
|
711
ddbridge/ddbridge.h
Normal file
711
ddbridge/ddbridge.h
Normal file
@ -0,0 +1,711 @@
|
||||
/*
|
||||
* ddbridge.h: Digital Devices PCIe bridge driver
|
||||
*
|
||||
* Copyright (C) 2010-2015 Digital Devices GmbH
|
||||
* Ralph Metzler <rmetzler@digitaldevices.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
|
||||
*/
|
||||
|
||||
#ifndef _DDBRIDGE_H_
|
||||
#define _DDBRIDGE_H_
|
||||
|
||||
#include <linux/version.h>
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
|
||||
#define __devexit
|
||||
#define __devinit
|
||||
#define __devinitconst
|
||||
#endif
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/pci.h>
|
||||
//#include <linux/pci_ids.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/swab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/completion.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <linux/dvb/ca.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "dvb_netstream.h"
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_ringbuffer.h"
|
||||
#include "dvb_ca_en50221.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "tda18271c2dd.h"
|
||||
#include "stv6110x.h"
|
||||
#include "stv090x.h"
|
||||
#include "lnbh24.h"
|
||||
#include "drxk.h"
|
||||
#include "stv0367dd.h"
|
||||
#include "tda18212dd.h"
|
||||
#include "cxd2843.h"
|
||||
#include "cxd2099.h"
|
||||
#include "stv0910.h"
|
||||
#include "stv6111.h"
|
||||
#include "lnbh25.h"
|
||||
#include "mxl5xx.h"
|
||||
|
||||
#define DDB_MAX_I2C 16
|
||||
#define DDB_MAX_PORT 16
|
||||
#define DDB_MAX_INPUT 44
|
||||
#define DDB_MAX_OUTPUT 10
|
||||
#define DDB_MAX_LINK 4
|
||||
#define DDB_LINK_SHIFT 28
|
||||
|
||||
#define DDB_LINK_TAG(_x) (_x << DDB_LINK_SHIFT)
|
||||
|
||||
struct ddb_regset {
|
||||
u32 base;
|
||||
u32 num;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct ddb_ports {
|
||||
u32 base;
|
||||
u32 num;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct ddb_regmap {
|
||||
struct ddb_ports *bc;
|
||||
struct ddb_regset *i2c;
|
||||
struct ddb_regset *i2c_buf;
|
||||
struct ddb_regset *dma;
|
||||
struct ddb_regset *dma_buf;
|
||||
struct ddb_regset *input;
|
||||
struct ddb_regset *output;
|
||||
struct ddb_regset *channel;
|
||||
struct ddb_regset *ci;
|
||||
struct ddb_regset *pid_filter;
|
||||
struct ddb_regset *ns;
|
||||
struct ddb_regset *gtl;
|
||||
};
|
||||
|
||||
struct ddb_ids {
|
||||
u16 vendor;
|
||||
u16 device;
|
||||
u16 subvendor;
|
||||
u16 subdevice;
|
||||
|
||||
u32 hwid;
|
||||
u32 regmapid;
|
||||
u32 devid;
|
||||
u32 mac;
|
||||
};
|
||||
|
||||
struct ddb_info {
|
||||
int 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
|
||||
char *name;
|
||||
u32 i2c_mask;
|
||||
u8 port_num;
|
||||
u8 led_num;
|
||||
u8 fan_num;
|
||||
u8 temp_num;
|
||||
u8 temp_bus;
|
||||
u8 board_control;
|
||||
u8 ns_num;
|
||||
u8 mdio_num;
|
||||
u8 con_clock;
|
||||
struct ddb_regmap *regmap;
|
||||
};
|
||||
|
||||
/* DMA_SIZE MUST be smaller than 256k and
|
||||
MUST be divisible by 188 and 128 !!! */
|
||||
|
||||
#define DMA_MAX_BUFS 32 /* hardware table limit */
|
||||
|
||||
#define INPUT_DMA_BUFS 8
|
||||
#define INPUT_DMA_SIZE (128*47*21)
|
||||
#define INPUT_DMA_IRQ_DIV 1
|
||||
|
||||
#define OUTPUT_DMA_BUFS 8
|
||||
#define OUTPUT_DMA_SIZE (128*47*21)
|
||||
#define OUTPUT_DMA_IRQ_DIV 1
|
||||
|
||||
struct ddb;
|
||||
struct ddb_port;
|
||||
|
||||
struct ddb_dma {
|
||||
void *io;
|
||||
u32 nr;
|
||||
dma_addr_t pbuf[DMA_MAX_BUFS];
|
||||
u8 *vbuf[DMA_MAX_BUFS];
|
||||
u32 num;
|
||||
u32 size;
|
||||
u32 div;
|
||||
u32 bufreg;
|
||||
|
||||
#ifdef DDB_USE_WORK
|
||||
struct work_struct work;
|
||||
#else
|
||||
struct tasklet_struct tasklet;
|
||||
#endif
|
||||
spinlock_t lock;
|
||||
wait_queue_head_t wq;
|
||||
int running;
|
||||
u32 stat;
|
||||
u32 ctrl;
|
||||
u32 cbuf;
|
||||
u32 coff;
|
||||
};
|
||||
|
||||
struct ddb_dvb {
|
||||
struct dvb_adapter *adap;
|
||||
int adap_registered;
|
||||
struct dvb_device *dev;
|
||||
struct dvb_frontend *fe;
|
||||
struct dvb_frontend *fe2;
|
||||
struct dmxdev dmxdev;
|
||||
struct dvb_demux demux;
|
||||
struct dvb_net dvbnet;
|
||||
struct dvb_netstream dvbns;
|
||||
struct dmx_frontend hw_frontend;
|
||||
struct dmx_frontend mem_frontend;
|
||||
int users;
|
||||
u32 attached;
|
||||
u8 input;
|
||||
|
||||
fe_sec_tone_mode_t tone;
|
||||
fe_sec_voltage_t voltage;
|
||||
|
||||
int (*i2c_gate_ctrl)(struct dvb_frontend *, int);
|
||||
int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
|
||||
int (*set_input)(struct dvb_frontend *fe, int input);
|
||||
int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
|
||||
};
|
||||
|
||||
struct ddb_ci {
|
||||
struct dvb_ca_en50221 en;
|
||||
struct ddb_port *port;
|
||||
u32 nr;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
struct ddb_io {
|
||||
struct ddb_port *port;
|
||||
u32 nr;
|
||||
struct ddb_dma *dma;
|
||||
struct ddb_io *redo;
|
||||
struct ddb_io *redi;
|
||||
};
|
||||
|
||||
#define ddb_output ddb_io
|
||||
#define ddb_input ddb_io
|
||||
|
||||
struct ddb_i2c {
|
||||
struct ddb *dev;
|
||||
u32 nr;
|
||||
u32 regs;
|
||||
u32 link;
|
||||
struct i2c_adapter adap;
|
||||
u32 rbuf;
|
||||
u32 wbuf;
|
||||
u32 bsize;
|
||||
struct completion completion;
|
||||
};
|
||||
|
||||
struct ddb_port {
|
||||
struct ddb *dev;
|
||||
u32 nr;
|
||||
u32 pnr;
|
||||
u32 regs;
|
||||
u32 lnr;
|
||||
struct ddb_i2c *i2c;
|
||||
struct mutex i2c_gate_lock;
|
||||
u32 class;
|
||||
#define DDB_PORT_NONE 0
|
||||
#define DDB_PORT_CI 1
|
||||
#define DDB_PORT_TUNER 2
|
||||
#define DDB_PORT_LOOP 3
|
||||
#define DDB_PORT_MOD 4
|
||||
char *name;
|
||||
u32 type;
|
||||
#define DDB_TUNER_NONE 0
|
||||
#define DDB_TUNER_DVBS_ST 1
|
||||
#define DDB_TUNER_DVBS_ST_AA 2
|
||||
#define DDB_TUNER_DVBCT_TR 3
|
||||
#define DDB_TUNER_DVBCT_ST 4
|
||||
#define DDB_CI_INTERNAL 5
|
||||
#define DDB_CI_EXTERNAL_SONY 6
|
||||
#define DDB_TUNER_DVBCT2_SONY_P 7
|
||||
#define DDB_TUNER_DVBC2T2_SONY_P 8
|
||||
#define DDB_TUNER_ISDBT_SONY_P 9
|
||||
#define DDB_TUNER_DVBS_STV0910_P 10
|
||||
#define DDB_TUNER_MXL5XX 11
|
||||
#define DDB_CI_EXTERNAL_XO2 12
|
||||
#define DDB_CI_EXTERNAL_XO2_B 13
|
||||
|
||||
#define DDB_TUNER_XO2 16
|
||||
#define DDB_TUNER_DVBS_STV0910 16
|
||||
#define DDB_TUNER_DVBCT2_SONY 17
|
||||
#define DDB_TUNER_ISDBT_SONY 18
|
||||
#define DDB_TUNER_DVBC2T2_SONY 19
|
||||
#define DDB_TUNER_ATSC_ST 20
|
||||
#define DDB_TUNER_DVBC2T2_ST 21
|
||||
|
||||
struct ddb_input *input[2];
|
||||
struct ddb_output *output;
|
||||
struct dvb_ca_en50221 *en;
|
||||
struct ddb_dvb dvb[2];
|
||||
u32 gap;
|
||||
u32 obr;
|
||||
u8 creg;
|
||||
};
|
||||
|
||||
struct mod_base {
|
||||
u32 frequency;
|
||||
u32 flat_start;
|
||||
u32 flat_end;
|
||||
};
|
||||
|
||||
struct mod_state {
|
||||
u32 modulation;
|
||||
u64 obitrate;
|
||||
u64 ibitrate;
|
||||
u32 pcr_correction;
|
||||
|
||||
u32 rate_inc;
|
||||
u32 Control;
|
||||
u32 State;
|
||||
u32 StateCounter;
|
||||
s32 LastPCRAdjust;
|
||||
s32 PCRAdjustSum;
|
||||
s32 InPacketsSum;
|
||||
s32 OutPacketsSum;
|
||||
s64 PCRIncrement;
|
||||
s64 PCRDecrement;
|
||||
s32 PCRRunningCorr;
|
||||
u32 OutOverflowPacketCount;
|
||||
u32 InOverflowPacketCount;
|
||||
u32 LastOutPacketCount;
|
||||
u32 LastInPacketCount;
|
||||
u64 LastOutPackets;
|
||||
u64 LastInPackets;
|
||||
u32 MinInputPackets;
|
||||
};
|
||||
|
||||
#define CM_STARTUP_DELAY 2
|
||||
#define CM_AVERAGE 20
|
||||
#define CM_GAIN 10
|
||||
|
||||
#define HW_LSB_SHIFT 12
|
||||
#define HW_LSB_MASK 0x1000
|
||||
|
||||
#define CM_IDLE 0
|
||||
#define CM_STARTUP 1
|
||||
#define CM_ADJUST 2
|
||||
|
||||
#define TS_CAPTURE_LEN (4096)
|
||||
|
||||
/* net streaming hardware block */
|
||||
|
||||
#define DDB_NS_MAX 15
|
||||
|
||||
struct ddb_ns {
|
||||
struct ddb_input *input;
|
||||
int nr;
|
||||
struct ddb_input *fe;
|
||||
u32 rtcp_udplen;
|
||||
u32 rtcp_len;
|
||||
u32 ts_offset;
|
||||
u32 udplen;
|
||||
u8 p[512];
|
||||
};
|
||||
|
||||
struct ddb_lnb {
|
||||
struct mutex lock;
|
||||
u32 tone;
|
||||
fe_sec_voltage_t oldvoltage[4];
|
||||
u32 voltage[4];
|
||||
u32 voltages;
|
||||
u32 fmode;
|
||||
u32 setmode;
|
||||
};
|
||||
|
||||
struct ddb_link {
|
||||
struct ddb *dev;
|
||||
struct ddb_info *info;
|
||||
u32 nr;
|
||||
u32 regs;
|
||||
spinlock_t lock;
|
||||
struct mutex flash_mutex;
|
||||
struct ddb_lnb lnb;
|
||||
struct tasklet_struct tasklet;
|
||||
};
|
||||
|
||||
struct ddb {
|
||||
struct pci_dev *pdev;
|
||||
struct platform_device *pfdev;
|
||||
struct device *dev;
|
||||
struct ddb_ids ids;
|
||||
|
||||
int msi;
|
||||
struct workqueue_struct *wq;
|
||||
u32 has_dma;
|
||||
u32 has_ns;
|
||||
|
||||
struct ddb_link link[DDB_MAX_LINK];
|
||||
unsigned char *regs;
|
||||
u32 regs_len;
|
||||
u32 port_num;
|
||||
struct ddb_port port[DDB_MAX_PORT];
|
||||
u32 i2c_num;
|
||||
struct ddb_i2c i2c[DDB_MAX_I2C];
|
||||
struct ddb_input input[DDB_MAX_INPUT];
|
||||
struct ddb_output output[DDB_MAX_OUTPUT];
|
||||
struct dvb_adapter adap[DDB_MAX_INPUT];
|
||||
struct ddb_dma dma[DDB_MAX_INPUT + DDB_MAX_OUTPUT];
|
||||
|
||||
void (*handler[128])(unsigned long);
|
||||
unsigned long handler_data[128];
|
||||
|
||||
struct device *ddb_dev;
|
||||
u32 ddb_dev_users;
|
||||
u32 nr;
|
||||
u8 iobuf[1028];
|
||||
|
||||
u8 leds;
|
||||
u32 ts_irq;
|
||||
u32 i2c_irq;
|
||||
|
||||
int ns_num;
|
||||
struct ddb_ns ns[DDB_NS_MAX];
|
||||
int vlan;
|
||||
struct mutex mutex;
|
||||
|
||||
struct dvb_device *nsd_dev;
|
||||
u8 tsbuf[TS_CAPTURE_LEN];
|
||||
|
||||
struct mod_base mod_base;
|
||||
struct mod_state mod[10];
|
||||
};
|
||||
|
||||
static inline void ddbwriteb(struct ddb *dev, u32 val, u32 adr)
|
||||
{
|
||||
writeb(val, (char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static inline u32 ddbreadb(struct ddb *dev, u32 adr)
|
||||
{
|
||||
return readb((char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static inline void ddbwritel0(struct ddb_link *link, u32 val, u32 adr)
|
||||
{
|
||||
writel(val, (char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static inline u32 ddbreadl0(struct ddb_link *link, u32 adr)
|
||||
{
|
||||
return readl((char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline void gtlw(struct ddb_link *link)
|
||||
{
|
||||
u32 count = 0;
|
||||
static u32 max = 0;
|
||||
|
||||
while (1 & ddbreadl0(link, link->regs + 0x10)) {
|
||||
if (++count == 1024) {
|
||||
printk("LTO\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (count > max) {
|
||||
max = count;
|
||||
printk("TO=%u\n", max);
|
||||
}
|
||||
if (ddbreadl0(link, link->regs + 0x10) & 0x8000)
|
||||
printk("link error\n");
|
||||
}
|
||||
#else
|
||||
static inline void gtlw(struct ddb_link *link)
|
||||
{
|
||||
while (1 & ddbreadl0(link, link->regs + 0x10));
|
||||
}
|
||||
#endif
|
||||
|
||||
static u32 ddblreadl(struct ddb_link *link, u32 adr)
|
||||
{
|
||||
if (unlikely(link->nr)) {
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
|
||||
ddbwritel0(link, 3, link->regs + 0x10);
|
||||
gtlw(link);
|
||||
val = ddbreadl0(link, link->regs + 0x1c);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return val;
|
||||
}
|
||||
return readl((char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static void ddblwritel(struct ddb_link *link, u32 val, u32 adr)
|
||||
{
|
||||
if (unlikely(link->nr)) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
|
||||
ddbwritel0(link, val, link->regs + 0x18);
|
||||
ddbwritel0(link, 1, link->regs + 0x10);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return;
|
||||
}
|
||||
writel(val, (char *) (link->dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static u32 ddbreadl(struct ddb *dev, u32 adr)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000)) {
|
||||
unsigned long flags;
|
||||
u32 val, l = (adr >> DDB_LINK_SHIFT);
|
||||
struct ddb_link *link = &dev->link[l];
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, adr & 0xfffc, link->regs + 0x14);
|
||||
ddbwritel0(link, 3, link->regs + 0x10);
|
||||
gtlw(link);
|
||||
val = ddbreadl0(link, link->regs + 0x1c);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return val;
|
||||
}
|
||||
return readl((char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static void ddbwritel(struct ddb *dev, u32 val, u32 adr)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000)) {
|
||||
unsigned long flags;
|
||||
u32 l = (adr >> DDB_LINK_SHIFT);
|
||||
struct ddb_link *link = &dev->link[l];
|
||||
|
||||
spin_lock_irqsave(&link->lock, flags);
|
||||
gtlw(link);
|
||||
ddbwritel0(link, 0xf0000 | (adr & 0xfffc), link->regs + 0x14);
|
||||
ddbwritel0(link, val, link->regs + 0x18);
|
||||
ddbwritel0(link, 1, link->regs + 0x10);
|
||||
spin_unlock_irqrestore(&link->lock, flags);
|
||||
return;
|
||||
}
|
||||
writel(val, (char *) (dev->regs + (adr)));
|
||||
}
|
||||
|
||||
static void gtlcpyto(struct ddb *dev, u32 adr, const u8 *buf,
|
||||
unsigned int count)
|
||||
{
|
||||
u32 val = 0, p = adr;
|
||||
u32 aa = p & 3;
|
||||
|
||||
if (aa) {
|
||||
while (p & 3 && count) {
|
||||
val >>= 8;
|
||||
val |= *buf << 24;
|
||||
p++;
|
||||
buf++;
|
||||
count--;
|
||||
}
|
||||
ddbwritel(dev, val, adr);
|
||||
}
|
||||
while (count >= 4) {
|
||||
val = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
|
||||
ddbwritel(dev, val, p);
|
||||
p += 4;
|
||||
buf += 4;
|
||||
count -= 4;
|
||||
}
|
||||
if (count) {
|
||||
val = buf[0];
|
||||
if (count > 1)
|
||||
val |= buf[1] << 8;
|
||||
if (count > 2)
|
||||
val |= buf[2] << 16;
|
||||
ddbwritel(dev, val, p);
|
||||
}
|
||||
}
|
||||
|
||||
static void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count)
|
||||
{
|
||||
u32 val = 0, p = adr;
|
||||
u32 a = p & 3;
|
||||
|
||||
if (a) {
|
||||
val = ddbreadl(dev, p) >> (8 * a);
|
||||
while (p & 3 && count) {
|
||||
*buf = val & 0xff;
|
||||
val >>= 8;
|
||||
p++;
|
||||
buf++;
|
||||
count--;
|
||||
}
|
||||
}
|
||||
while (count >= 4) {
|
||||
val = ddbreadl(dev, p);
|
||||
buf[0] = val & 0xff;
|
||||
buf[1] = (val >> 8) & 0xff;
|
||||
buf[2] = (val >> 16) & 0xff;
|
||||
buf[3] = (val >> 24) & 0xff;
|
||||
p += 4;
|
||||
buf += 4;
|
||||
count -= 4;
|
||||
}
|
||||
if (count) {
|
||||
val = ddbreadl(dev, p);
|
||||
buf[0] = val & 0xff;
|
||||
if (count > 1)
|
||||
buf[1] = (val >> 8) & 0xff;
|
||||
if (count > 2)
|
||||
buf[2] = (val >> 16) & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
static void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000))
|
||||
return gtlcpyto(dev, adr, src, count);
|
||||
return memcpy_toio((char *) (dev->regs + adr), src, count);
|
||||
}
|
||||
|
||||
static void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count)
|
||||
{
|
||||
if (unlikely(adr & 0xf0000000))
|
||||
return gtlcpyfrom(dev, dst, adr, count);
|
||||
return memcpy_fromio(dst, (char *) (dev->regs + adr), count);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
#define ddbcpyto(_dev, _adr, _src, _count) \
|
||||
memcpy_toio((char *) (_dev->regs + (_adr)), (_src), (_count))
|
||||
|
||||
#define ddbcpyfrom(_dev, _dst, _adr, _count) \
|
||||
memcpy_fromio((_dst), (char *) (_dev->regs + (_adr)), (_count))
|
||||
#endif
|
||||
|
||||
#define ddbmemset(_dev, _adr, _val, _count) \
|
||||
memset_io((char *) (_dev->regs + (_adr)), (_val), (_count))
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
#define dd_uint8 u8
|
||||
#define dd_uint16 u16
|
||||
#define dd_int16 s16
|
||||
#define dd_uint32 u32
|
||||
#define dd_int32 s32
|
||||
#define dd_uint64 u64
|
||||
#define dd_int64 s64
|
||||
|
||||
#define DDMOD_FLASH_START 0x1000
|
||||
|
||||
struct DDMOD_FLASH_DS {
|
||||
dd_uint32 Symbolrate; /* kSymbols/s */
|
||||
dd_uint32 DACFrequency; /* kHz */
|
||||
dd_uint16 FrequencyResolution; /* kHz */
|
||||
dd_uint16 IQTableLength;
|
||||
dd_uint16 FrequencyFactor;
|
||||
dd_int16 PhaseCorr; /* TBD */
|
||||
dd_uint32 Control2;
|
||||
dd_uint16 PostScaleI;
|
||||
dd_uint16 PostScaleQ;
|
||||
dd_uint16 PreScale;
|
||||
dd_int16 EQTap[11];
|
||||
dd_uint16 FlatStart;
|
||||
dd_uint16 FlatEnd;
|
||||
dd_uint32 FlashOffsetPrecalculatedIQTables; /* 0 = none */
|
||||
dd_uint8 Reserved[28];
|
||||
|
||||
};
|
||||
|
||||
struct DDMOD_FLASH {
|
||||
dd_uint32 Magic;
|
||||
dd_uint16 Version;
|
||||
dd_uint16 DataSets;
|
||||
|
||||
dd_uint16 VCORefFrequency; /* MHz */
|
||||
dd_uint16 VCO1Frequency; /* MHz */
|
||||
dd_uint16 VCO2Frequency; /* MHz */
|
||||
|
||||
dd_uint16 DACAux1; /* TBD */
|
||||
dd_uint16 DACAux2; /* TBD */
|
||||
|
||||
dd_uint8 Reserved1[238];
|
||||
|
||||
struct DDMOD_FLASH_DS DataSet[1];
|
||||
};
|
||||
|
||||
#define DDMOD_FLASH_MAGIC 0x5F564d5F
|
||||
|
||||
|
||||
int ddbridge_mod_do_ioctl(struct file *file, unsigned int cmd, void *parg);
|
||||
int ddbridge_mod_init(struct ddb *dev);
|
||||
void ddbridge_mod_output_stop(struct ddb_output *output);
|
||||
void ddbridge_mod_output_start(struct ddb_output *output);
|
||||
void ddbridge_mod_rate_handler(unsigned long data);
|
||||
|
||||
|
||||
int ddbridge_flashread(struct ddb *dev, u32 link, u8 *buf, u32 addr, u32 len);
|
||||
|
||||
#define DDBRIDGE_VERSION "0.9.19"
|
||||
|
||||
#endif
|
260
ddbridge/octonet.c
Normal file
260
ddbridge/octonet.c
Normal file
@ -0,0 +1,260 @@
|
||||
/*
|
||||
* octonet.c: Digital Devices network tuner driver
|
||||
*
|
||||
* Copyright (C) 2012-15 Digital Devices GmbH
|
||||
* 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 "ddbridge.h"
|
||||
#include "ddbridge-regs.h"
|
||||
#include <asm-generic/pci-dma-compat.h>
|
||||
|
||||
static int adapter_alloc = 3;
|
||||
module_param(adapter_alloc, int, 0444);
|
||||
MODULE_PARM_DESC(adapter_alloc,
|
||||
"0-one adapter per io, 1-one per tab with io, 2-one per tab, 3-one for all");
|
||||
|
||||
#include "ddbridge-core.c"
|
||||
|
||||
static struct ddb_regset octopus_i2c = {
|
||||
.base = 0x80,
|
||||
.num = 0x04,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_i2c_buf = {
|
||||
.base = 0x1000,
|
||||
.num = 0x04,
|
||||
.size = 0x200,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_net_map = {
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
};
|
||||
|
||||
static struct ddb_regset octopus_gtl = {
|
||||
.base = 0x180,
|
||||
.num = 0x01,
|
||||
.size = 0x20,
|
||||
};
|
||||
|
||||
static struct ddb_regmap octopus_net_gtl = {
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
.gtl = &octopus_gtl,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet network DVB adapter",
|
||||
.regmap = &octopus_net_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet_jse = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet network DVB adapter JSE",
|
||||
.regmap = &octopus_net_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x0f,
|
||||
.ns_num = 15,
|
||||
.mdio_num = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet_gtl = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet GTL",
|
||||
.regmap = &octopus_net_gtl,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x05,
|
||||
.ns_num = 12,
|
||||
.mdio_num = 1,
|
||||
.con_clock = 1,
|
||||
};
|
||||
|
||||
static struct ddb_info ddb_octonet_tbd = {
|
||||
.type = DDB_OCTONET,
|
||||
.name = "Digital Devices OctopusNet",
|
||||
.regmap = &octopus_net_map,
|
||||
};
|
||||
|
||||
static void octonet_unmap(struct ddb *dev)
|
||||
{
|
||||
if (dev->regs)
|
||||
iounmap(dev->regs);
|
||||
vfree(dev);
|
||||
}
|
||||
|
||||
static int __exit octonet_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct ddb *dev;
|
||||
|
||||
dev = platform_get_drvdata(pdev);
|
||||
|
||||
ddb_nsd_detach(dev);
|
||||
ddb_ports_detach(dev);
|
||||
ddb_i2c_release(dev);
|
||||
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
ddbwritel(dev, 0, INTERRUPT_ENABLE);
|
||||
free_irq(platform_get_irq(dev->pfdev, 0), dev);
|
||||
|
||||
ddb_ports_release(dev);
|
||||
ddb_device_destroy(dev);
|
||||
octonet_unmap(dev);
|
||||
platform_set_drvdata(pdev, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init octonet_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct ddb *dev;
|
||||
struct resource *regs;
|
||||
int irq;
|
||||
int i;
|
||||
|
||||
dev = vzalloc(sizeof(struct ddb));
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, dev);
|
||||
dev->dev = &pdev->dev;
|
||||
dev->pfdev = pdev;
|
||||
|
||||
mutex_init(&dev->mutex);
|
||||
regs = platform_get_resource(dev->pfdev, IORESOURCE_MEM, 0);
|
||||
if (!regs)
|
||||
return -ENXIO;
|
||||
dev->regs_len = (regs->end - regs->start) + 1;
|
||||
dev_info(dev->dev, "regs_start=%08x regs_len=%08x\n",
|
||||
(u32) regs->start, (u32) dev->regs_len);
|
||||
dev->regs = ioremap(regs->start, dev->regs_len);
|
||||
|
||||
if (!dev->regs) {
|
||||
dev_err(dev->dev, "ioremap failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dev->ids.hwid = ddbreadl(dev, 0);
|
||||
dev->ids.regmapid = ddbreadl(dev, 4);
|
||||
dev->ids.devid = ddbreadl(dev, 8);
|
||||
dev->ids.mac = ddbreadl(dev, 12);
|
||||
|
||||
dev->ids.vendor = dev->ids.devid & 0xffff;
|
||||
dev->ids.device = dev->ids.devid >> 16;
|
||||
dev->ids.subvendor = dev->ids.devid & 0xffff;
|
||||
dev->ids.subdevice = dev->ids.devid >> 16;
|
||||
|
||||
dev->link[0].dev = dev;
|
||||
if (dev->ids.devid == 0x0300dd01)
|
||||
dev->link[0].info = &ddb_octonet;
|
||||
else if (dev->ids.devid == 0x0301dd01)
|
||||
dev->link[0].info = &ddb_octonet_jse;
|
||||
else if (dev->ids.devid == 0x0307dd01)
|
||||
dev->link[0].info = &ddb_octonet_gtl;
|
||||
else
|
||||
dev->link[0].info = &ddb_octonet_tbd;
|
||||
|
||||
pr_info("HW %08x REGMAP %08x\n", dev->ids.hwid, dev->ids.regmapid);
|
||||
pr_info("MAC %08x DEVID %08x\n", dev->ids.mac, dev->ids.devid);
|
||||
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
|
||||
ddbwritel(dev, 0xffffffff, INTERRUPT_STATUS);
|
||||
for (i = 0; i < 16; i++)
|
||||
ddbwritel(dev, 0x00, TS_OUTPUT_CONTROL(i));
|
||||
usleep_range(5000, 6000);
|
||||
|
||||
irq = platform_get_irq(dev->pfdev, 0);
|
||||
if (irq < 0)
|
||||
goto fail;
|
||||
if (request_irq(irq, irq_handler,
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
||||
"octonet-dvb", (void *) dev) < 0)
|
||||
goto fail;
|
||||
ddbwritel(dev, 0x0fffff0f, INTERRUPT_ENABLE);
|
||||
|
||||
if (ddb_init(dev) == 0)
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
dev_err(dev->dev, "fail\n");
|
||||
ddbwritel(dev, 0, ETHER_CONTROL);
|
||||
ddbwritel(dev, 0, INTERRUPT_ENABLE);
|
||||
octonet_unmap(dev);
|
||||
platform_set_drvdata(pdev, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id octonet_dt_ids[] = {
|
||||
{ .compatible = "digitaldevices,octonet-dvb" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, octonet_dt_ids);
|
||||
#endif
|
||||
|
||||
static struct platform_driver octonet_driver = {
|
||||
.remove = __exit_p(octonet_remove),
|
||||
.probe = octonet_probe,
|
||||
.driver = {
|
||||
.name = "octonet-dvb",
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_OF
|
||||
.of_match_table = of_match_ptr(octonet_dt_ids),
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
static __init int init_octonet(void)
|
||||
{
|
||||
int res;
|
||||
|
||||
pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION
|
||||
", Copyright (C) 2010-14 Digital Devices GmbH\n");
|
||||
res = ddb_class_create();
|
||||
if (res)
|
||||
return res;
|
||||
res = platform_driver_probe(&octonet_driver, octonet_probe);
|
||||
if (res) {
|
||||
ddb_class_destroy();
|
||||
return res;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __exit void exit_octonet(void)
|
||||
{
|
||||
platform_driver_unregister(&octonet_driver);
|
||||
ddb_class_destroy();
|
||||
}
|
||||
|
||||
module_init(init_octonet);
|
||||
module_exit(exit_octonet);
|
||||
|
||||
MODULE_DESCRIPTION("GPL");
|
||||
MODULE_AUTHOR("Marcus and Ralph Metzler, Metzler Brothers Systementwicklung GbR");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("0.6");
|
5
ddip/Kbuild
Normal file
5
ddip/Kbuild
Normal file
@ -0,0 +1,5 @@
|
||||
obj-$(CONFIG_DVB_DDBRIDGE) += ddip.o
|
||||
|
||||
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -Idrivers/media/dvb-frontends
|
||||
EXTRA_CFLAGS += -Idrivers/media/common/tuners
|
||||
NOSTDINC_FLAGS += -I$(SUBDIRS)/frontends -I$(SUBDIRS)/include -I$(SUBDIRS)/dvb-core
|
18
ddip/Makefile
Normal file
18
ddip/Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
KDIR ?= /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
MODDEFS := CONFIG_DVB_DDIP=m
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MODDEFS) modules
|
||||
|
||||
dep:
|
||||
DIR=`pwd`; (cd $(TOPDIR); make SUBDIRS=$$DIR dep)
|
||||
|
||||
install: all
|
||||
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
|
||||
|
||||
clean:
|
||||
rm -rf */*.o */*.ko */*.mod.c */.*.cmd .tmp_versions Module* modules*
|
||||
|
||||
|
24
ddip/ddip.c
Normal file
24
ddip/ddip.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
|
||||
static __init int init_ddip(void)
|
||||
{
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __exit void exit_ddip(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(init_ddip);
|
||||
module_exit(exit_ddip);
|
||||
|
||||
MODULE_DESCRIPTION("GPL");
|
||||
MODULE_AUTHOR("Metzler Brothers Systementwicklung");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION("0.1");
|
||||
|
7
docs/adapter_alloc
Normal file
7
docs/adapter_alloc
Normal file
@ -0,0 +1,7 @@
|
||||
The module parameter adapter_alloc lets you choose how adapter names are allocated.
|
||||
|
||||
0 = one adapter per io if modules are present
|
||||
1 = one adapter for each tab on which a module was detected
|
||||
2 = one per tab even if no modules were detected
|
||||
3 = one adapter for all devices of one card
|
||||
|
31
docs/ci
Normal file
31
docs/ci
Normal file
@ -0,0 +1,31 @@
|
||||
The caX device associated with a CI device behaves just like any other
|
||||
caX interface. You usually use it through a library like libdvben50221
|
||||
which is part of the dvb-apps package available at linuxtv.org.
|
||||
|
||||
But contrary to other hardware where the CI module is physically placed
|
||||
in the data path between the the demod and PCIe bridge, in the Digital
|
||||
Devices cards the CI module is separate hardware.
|
||||
So, you have to feed data to the CI module by writing to the secX
|
||||
(in later kernel ci0) device and read it back from the same secX device.
|
||||
The advantage is that the CI module can be used with any data coming from
|
||||
any frontend or file. The disadvantage is that the user application has to
|
||||
write/read the data to/from the module by itself.
|
||||
|
||||
The sample application apps/cit.c shows how to pipe a stream through
|
||||
the CI interface. In its ouput it will show discontinuities. Those should
|
||||
only occur at the start of the program (due to old packets inside the CI
|
||||
interface hardware and the CI module itself) and when a CI module is
|
||||
inserted or removed.
|
||||
|
||||
Since some users have problems using standard software which cannot use
|
||||
the CI interface in this way, there is now the redirect feature which allows
|
||||
you to tell the driver to automatically pass the data coming from one
|
||||
demod through a CI before offering it through the normal demux/dvr interface.
|
||||
But note that this is a kludge to support old software until they can
|
||||
use the new interface.
|
||||
See docs/redirect for more info.
|
||||
|
||||
|
||||
|
||||
|
||||
|
29
docs/modulator
Normal file
29
docs/modulator
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
Modulator channels will automatically be enabled if you redirect data
|
||||
from a demodulator to it.
|
||||
E.g._:
|
||||
|
||||
first demod on bridge 0 TAB1, modulator on bridge 1.
|
||||
|
||||
echo "00 10" > /sys/class/ddbridge/ddbridge0/redirect
|
||||
|
||||
Currently it is fixed to QAM256. Controls will be added later.
|
||||
Rate control is experimental and PCR correction also not
|
||||
implemented yet. So, depending on the reception device
|
||||
there can be disturbances in playback.
|
||||
|
||||
It is now also possible to chain redirects.
|
||||
E.g., demod and modulator as above, CI on bridge 0 TAB 2:
|
||||
|
||||
echo "00 01" > /sys/class/ddbridge/ddbridge0/redirect
|
||||
echo "02 10" > /sys/class/ddbridge/ddbridge0/redirect
|
||||
|
||||
The stream is also still available at the demux device
|
||||
belonging to the demod devices.
|
||||
|
||||
Now write and start an application (not provided) that
|
||||
talks to the CI to decrypt the desired services.
|
||||
For testing one can use a standard application that
|
||||
supports decryption. Additionally to seeing the
|
||||
decoded service on the PC it will then also be streamed
|
||||
into cable by the modulator.
|
89
docs/octopusnet
Normal file
89
docs/octopusnet
Normal file
@ -0,0 +1,89 @@
|
||||
OctopusNet
|
||||
----------
|
||||
|
||||
Hardware:
|
||||
|
||||
- SoC Atmel SAM9G45 400MHz ARM 926
|
||||
64 MB DRAM
|
||||
256 MB NAND flash
|
||||
|
||||
- FPGA Lattice ECP3 17
|
||||
data flash
|
||||
|
||||
- 5 port switch Marvell 88E6175R
|
||||
|
||||
|
||||
The FPGA is connected to the memory bus of the G45 and maps control registers into the memory space
|
||||
of the G45. This is mainly to control the data flow on the FPGA. Only minimal data can be transferred
|
||||
(e.g. single sections). Transport streams cannot be transferred to the G45 this way!
|
||||
The FPGA can receive up to 8 TS from up to 4 Duo-Flex cards. You can also can alternatively connect
|
||||
CI modules to port 2 and 3 (TAP 3 and 4).
|
||||
|
||||
The FPGA is also connected to one of the ports of the gigabit switch.
|
||||
There are up to 12 channels. Each channel can select one input TS, which is then passed through
|
||||
a PID filter (8192 bit array) and sent to the switch as a UDP/RTP stream.
|
||||
|
||||
The G45 is connected to another port of the switch (but only with 100 MBit)
|
||||
|
||||
|
||||
Booting:
|
||||
|
||||
The G45 does not boot from the NAND flash but from the dataflash connected to the FPGA. The G45
|
||||
does not support error correction for the boot sector and NAND with zero error boot pages
|
||||
is no longer easily available.
|
||||
Newer Atmel SoCs support 4-bit error correction in boot ROM but not the G45.
|
||||
|
||||
So, the G45 boot looks like this:
|
||||
|
||||
- Run a minimal boot rom mapped by the FPGA.
|
||||
- Boot rom loads a modified bootstrap via SPI (provided via FPGA ports) from the dataflash.
|
||||
- Bootstrap loads u-boot via SPI from dataflash.
|
||||
- u-boot boots Linux ...
|
||||
|
||||
If you remove jumper XX, boot rom is disabled and the G45 will boot from NAND flash like this:
|
||||
|
||||
- Internal G45 boot rom bootstrap from NAND flash.
|
||||
- Bootstrap boots u-boot from NAND flash
|
||||
- u-boot boots Linux ...
|
||||
|
||||
This is just a fall-back since page 0 can contain errors which cannot be corrected by the G45 boot ROM
|
||||
and the bootstrap code which loads u-boot also does not contain error correction.
|
||||
|
||||
|
||||
|
||||
- SPI dataflash
|
||||
|
||||
0x000000 - 0x003fff FPGA config data
|
||||
0x004000 - 0x005fff G45 bootstrap
|
||||
0x010000 - 0x0affff FPGA bitstream
|
||||
0x0b0000 - 0x15ffff G45 u-boot
|
||||
0x160000 - 0x1fefff FPGA golden image
|
||||
0x1ff000 - 0x1fffff FPGA jump to golden image
|
||||
|
||||
|
||||
- NAND flash 256MB, block size 128K (0x20000)
|
||||
|
||||
0x00000000 - 0x0001ffff G45 bootstrap (fallback bootstrap if SPI corrupted, pull jumper to use)
|
||||
0x00020000 - 0x0007ffff G45 u-boot (fallback u-boot if SPI corrupted)
|
||||
0x00080000 - 0x0009ffff spare (e.g. for bigger u-boot)
|
||||
0x000a0000 - 0x000bffff G45 u-boot environment
|
||||
0x000c0000 - 0x000dffff G45 u-boot redundant environment
|
||||
0x000e0000 - 0x000fffff spare
|
||||
0x00100000 - 0x01ffffff G45 Linux recovery
|
||||
0x02000000 - 0x0fffffff Linux UBI
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
104
docs/octopusnet.multicast
Normal file
104
docs/octopusnet.multicast
Normal file
@ -0,0 +1,104 @@
|
||||
Multicast
|
||||
---------
|
||||
|
||||
Multicast setup supports 2 file formats.
|
||||
1) Simple variant for the avarage home user
|
||||
2) More parameters for the expert.
|
||||
|
||||
The file is in csv (comma seperated values) format, which can be created with any plain text editor or imported/exported
|
||||
to/from Microsoft Office Excel or OpenOffice Scalc. With Excel or Scalc care for character set (should be UTF-8) and
|
||||
column formats is required. First line is contain then column headers.
|
||||
|
||||
Standard parameters
|
||||
-------------------
|
||||
|
||||
TITLE: Stream Title
|
||||
|
||||
REQUEST: SAT>IP tune request string without the pid parameter. Exact format depends on frontend (DVB-S,DVB-T ..)
|
||||
use "-" to stream another program from the previous full entry (tuner sharing)
|
||||
|
||||
PIDS: Pid list. Must start with a P, the values separated with a colon. "Pall" streams the whole transponder.
|
||||
(The P is there to ensure Excel or Scalc don't do some fancy format detection, like time conversion)
|
||||
|
||||
LANPORTS: Empty or a list with colon separated lan ports starting with L, "Lall" = all ports.
|
||||
If empty, the stream will only be activated when subscribed with an IGMPv3 request. It will also
|
||||
only be active on the lan ports through which an IGMPv3 request for the stream has benn received.
|
||||
(For details how IGMPv3 works look up the relevant RFCs.)
|
||||
If not empty the stream will be preactived on the listed lan ports (and permanently using bandwidth!).
|
||||
It still can be subscribed with IGMPv3 on the other ports.
|
||||
|
||||
|
||||
TITLE,REQUEST,PIDS,LANPORTS
|
||||
"Das Erste","?freq=346&msys=dvbc&sr=6900&mtype=256qam","P0:100:101:104:102:103:106",""
|
||||
"Bayerisches FS Nord","-","P0:500:201:204:202:203:206",""
|
||||
"hr-fernsehen","-","P0:300:301:304:302:303",""
|
||||
"SWR Fernsehen BW","-","P0:800:801:804:802:803:806",""
|
||||
"WDR Köln","-","P0:600:601:604:602:603",""
|
||||
"ZDF","?freq=370&msys=dvbc&sr=6900&mtype=256qam","P0:100:110:130:120:121:122:125",""
|
||||
"ZDF HD","-","P0:6100:6110:6130:6120:6121:6122:6123",""
|
||||
"zdf neo","-","P0:650:660:680:670:671:672:675",""
|
||||
"zdf kultur","-","P0:1100:1110:1130:1120:1121:1122:1125",""
|
||||
"ZDFInfo","-","P0:600:610:630:620:621:622:625",""
|
||||
"KiKA","-","P0:300:310:330:320:321:325","L3:4:5"
|
||||
"3sat","-","P0:200:210:230:220:221:222:225",""
|
||||
|
||||
|
||||
Expert parameters:
|
||||
------------------
|
||||
|
||||
PROTO: Protocol, must be "RTP" or "UDP". If you don't know what this means use "RTP".
|
||||
|
||||
IP: Multicast IP address, recommended range 239.5.0.0 - 239.126.255.255, see notes below
|
||||
about selecting a multicast IP address.
|
||||
|
||||
PORT: Destination port. If you don't know what this means set it to 6670
|
||||
|
||||
TTL: Time to live used in the IP headers. If you don't know what this means set it to 5.
|
||||
|
||||
|
||||
TITLE,REQUEST,PIDS,PROTO,IP,PORT,TTL,LANPORTS
|
||||
"Das Erste","?freq=346&msys=dvbc&sr=6900&mtype=256qam","P0:100:101:104:102:103:106","UDP","239.7.7.100",1234,7,""
|
||||
"Bayerisches FS Nord","-","P0:500:201:204:202:203:206","UDP","239.7.7.101",1234,7,""
|
||||
"hr-fernsehen","-","P0:300:301:304:302:303","UDP","239.7.7.102",1234,7,""
|
||||
"SWR Fernsehen BW","-","P0:800:801:804:802:803:806","UDP","239.7.7.103",1234,7,""
|
||||
"WDR Köln","-","P0:600:601:604:602:603","UDP","239.7.7.104",1234,7,""
|
||||
"ZDF","?freq=370&msys=dvbc&sr=6900&mtype=256qam","P0:100:110:130:120:121:122:125","UDP","239.7.8.100",1234,7,""
|
||||
"ZDF HD","-","P0:6100:6110:6130:6120:6121:6122:6123","UDP","239.7.8.101",1234,7,""
|
||||
"zdf neo","-","P0:650:660:680:670:671:672:675","UDP","239.7.8.102",1234,7,""
|
||||
"zdf kultur","-","P0:1100:1110:1130:1120:1121:1122:1125","UDP","239.7.8.103",1234,7,""
|
||||
"ZDFInfo","-","P0:600:610:630:620:621:622:625","UDP","239.7.8.104",1234,7,""
|
||||
"KiKA","-","P0:300:310:330:320:321:325","UDP","239.7.8.105",1234,7,"L3:4:5"
|
||||
"3sat","-","P0:200:210:230:220:221:222:225","UDP","239.7.8.106",1234,7,""
|
||||
|
||||
|
||||
Selecting a multicast IP address.
|
||||
---------------------------------
|
||||
|
||||
It is obvious that there should be no conflicts with other services (like UPnP, Windows network ...)
|
||||
which also use Multicast for communication and advertisments.
|
||||
|
||||
For media streaming usually an IP in the range 239.0.0.0 - 239.255.255.255 is used and
|
||||
will usually only conflict with other media sources. But this is not the whole truth!
|
||||
|
||||
The complete IP multicast range is 224.0.0.0 - 255.255.255.254, that is 536870911 different values.
|
||||
But there are only 8388608 different Ethernet MAC addresses allocated for IPv4 multicast. That
|
||||
means a lot of collisions. For example, 239.0.0.22 uses the same MAC address as 224.0.0.22 (IGMP).
|
||||
This means that 239.0.0.22 can't be blocked in an Ethernet switch without breaking IGMP.
|
||||
An IP from the range 239.5.0.0 - 239.126.255.255 does not collide with most documented
|
||||
services, and should be safe to use in most situations and the benefit from IGMPv3
|
||||
snooping Ethernet switches.
|
||||
|
||||
Multicast and WLAN
|
||||
------------------
|
||||
|
||||
As there is no real support for it (due to encryption) Multicast over WLAN will not work very well.
|
||||
Therefor it should be avoided to send a out a multicast stream on a lan port there a WLAN router
|
||||
is connected (at least when the WLAN router is configured as LAN-WLAN bridge).
|
||||
|
||||
As long there are free streams on the OctopusNet a RTSP player (including WLAN connected players)
|
||||
can request any service from a configured multicast source.
|
||||
For exmaple RTSP://<onetip>/stream=2?pids=0,300,310,330,320,321,325 will request KIKA
|
||||
as single cast stream from the above example. This is possible even if the entry for KIKA
|
||||
is removed from the multicast setup.
|
||||
(the above sample has no free streams left, but it should be clear what is meant)
|
||||
|
9
docs/octopusnetpro
Normal file
9
docs/octopusnetpro
Normal file
@ -0,0 +1,9 @@
|
||||
- NAND flash
|
||||
|
||||
0x00000000 - 0x0025ffff U-boot
|
||||
0x00260000 - 0x0027ffff ENV
|
||||
0x00300000 - 0x00ffffff Linux image
|
||||
|
||||
0x01000000 - 0x01ffffff Linux recovery
|
||||
0x02000000 - 0x1fffffff Linux UBI
|
||||
|
30
docs/redirect
Normal file
30
docs/redirect
Normal file
@ -0,0 +1,30 @@
|
||||
NOTE: This is an unsupported hack so that legacy software works
|
||||
with the hardware!
|
||||
To properly pass data through a CI CAM you should read
|
||||
the TS from a dvr device and write it to a ci device
|
||||
in user space!
|
||||
|
||||
Redirection of TS streams through CI modules is now supported
|
||||
through /sys/class/ddbridge/ddbridge0/redirect.
|
||||
It only works with cards based on the ddbridge PCIe bridge, not
|
||||
with nGene based cards.
|
||||
|
||||
It is set up in such a way that you can write "AB CD" to
|
||||
a "redirect" attribute and data from input B of card A is then piped through
|
||||
port D (meaning TAB (D+1) which uses output D and input 2*D for CI io)
|
||||
of card C and then shows up in the demux device belonging to
|
||||
input B (input (B&1) of TAB (B/2+1)) of card A.
|
||||
|
||||
E.g.:
|
||||
|
||||
echo "00 01" > /sys/class/ddbridge/ddbridge0/redirect
|
||||
|
||||
will pipe input 0 of card 0 through CI at port 1 (TAB 2) of card 0.
|
||||
|
||||
Redirection should only be done right after loading the driver
|
||||
(or booting if the driver is built-in) and before using the
|
||||
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.
|
12
dvb-core/Makefile
Normal file
12
dvb-core/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# Makefile for the kernel DVB device drivers.
|
||||
#
|
||||
|
||||
dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \
|
||||
dvb_ca_en50221.o dvb_frontend.o \
|
||||
dvb_net.o dvb_ringbuffer.o dvb_math.o dvb_netstream.o
|
||||
|
||||
obj-$(CONFIG_DVB_CORE) += dvb-core.o
|
||||
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_DYNAMIC_MINORS -DCONFIG_DVB_NET
|
||||
NOSTDINC_FLAGS += -I$(SUBDIRS)/include -I$(SUBDIRS)/dvb-core
|
241
dvb-core/demux.h
Normal file
241
dvb-core/demux.h
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* demux.h
|
||||
*
|
||||
* Copyright (c) 2002 Convergence GmbH
|
||||
*
|
||||
* based on code:
|
||||
* Copyright (c) 2000 Nokia Research Center
|
||||
* Tampere, FINLAND
|
||||
*
|
||||
* 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 __DEMUX_H
|
||||
#define __DEMUX_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/dvb/dmx.h>
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Common definitions */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
|
||||
*/
|
||||
|
||||
#ifndef DMX_MAX_FILTER_SIZE
|
||||
#define DMX_MAX_FILTER_SIZE 18
|
||||
#endif
|
||||
|
||||
/*
|
||||
* DMX_MAX_SECFEED_SIZE: Maximum length (in bytes) of a private section feed filter.
|
||||
*/
|
||||
|
||||
#ifndef DMX_MAX_SECTION_SIZE
|
||||
#define DMX_MAX_SECTION_SIZE 4096
|
||||
#endif
|
||||
#ifndef DMX_MAX_SECFEED_SIZE
|
||||
#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* enum dmx_success: Success codes for the Demux Callback API.
|
||||
*/
|
||||
|
||||
enum dmx_success {
|
||||
DMX_OK = 0, /* Received Ok */
|
||||
DMX_LENGTH_ERROR, /* Incorrect length */
|
||||
DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
|
||||
DMX_CRC_ERROR, /* Incorrect CRC */
|
||||
DMX_FRAME_ERROR, /* Frame alignment error */
|
||||
DMX_FIFO_ERROR, /* Receiver FIFO overrun */
|
||||
DMX_MISSED_ERROR /* Receiver missed packet */
|
||||
} ;
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* TS packet reception */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/* TS filter type for set() */
|
||||
|
||||
#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */
|
||||
#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS
|
||||
payload (<=184 bytes per packet) to callback */
|
||||
#define TS_DECODER 4 /* send stream to built-in decoder (if present) */
|
||||
#define TS_DEMUX 8 /* in case TS_PACKET is set, send the TS to
|
||||
the demux device, not to the dvr device */
|
||||
|
||||
struct dmx_ts_feed {
|
||||
int is_filtering; /* Set to non-zero when filtering in progress */
|
||||
struct dmx_demux *parent; /* Back-pointer */
|
||||
void *priv; /* Pointer to private data of the API client */
|
||||
int (*set) (struct dmx_ts_feed *feed,
|
||||
u16 pid,
|
||||
int type,
|
||||
enum dmx_ts_pes pes_type,
|
||||
size_t circular_buffer_size,
|
||||
struct timespec timeout);
|
||||
int (*start_filtering) (struct dmx_ts_feed* feed);
|
||||
int (*stop_filtering) (struct dmx_ts_feed* feed);
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Section reception */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
struct dmx_section_filter {
|
||||
u8 filter_value [DMX_MAX_FILTER_SIZE];
|
||||
u8 filter_mask [DMX_MAX_FILTER_SIZE];
|
||||
u8 filter_mode [DMX_MAX_FILTER_SIZE];
|
||||
struct dmx_section_feed* parent; /* Back-pointer */
|
||||
void* priv; /* Pointer to private data of the API client */
|
||||
};
|
||||
|
||||
struct dmx_section_feed {
|
||||
int is_filtering; /* Set to non-zero when filtering in progress */
|
||||
struct dmx_demux* parent; /* Back-pointer */
|
||||
void* priv; /* Pointer to private data of the API client */
|
||||
|
||||
int check_crc;
|
||||
u32 crc_val;
|
||||
|
||||
u8 *secbuf;
|
||||
u8 secbuf_base[DMX_MAX_SECFEED_SIZE];
|
||||
u16 secbufp, seclen, tsfeedp;
|
||||
|
||||
int (*set) (struct dmx_section_feed* feed,
|
||||
u16 pid,
|
||||
size_t circular_buffer_size,
|
||||
int check_crc);
|
||||
int (*allocate_filter) (struct dmx_section_feed* feed,
|
||||
struct dmx_section_filter** filter);
|
||||
int (*release_filter) (struct dmx_section_feed* feed,
|
||||
struct dmx_section_filter* filter);
|
||||
int (*start_filtering) (struct dmx_section_feed* feed);
|
||||
int (*stop_filtering) (struct dmx_section_feed* feed);
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Callback functions */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
typedef int (*dmx_ts_cb) ( const u8 * buffer1,
|
||||
size_t buffer1_length,
|
||||
const u8 * buffer2,
|
||||
size_t buffer2_length,
|
||||
struct dmx_ts_feed* source,
|
||||
enum dmx_success success);
|
||||
|
||||
typedef int (*dmx_section_cb) ( const u8 * buffer1,
|
||||
size_t buffer1_len,
|
||||
const u8 * buffer2,
|
||||
size_t buffer2_len,
|
||||
struct dmx_section_filter * source,
|
||||
enum dmx_success success);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* DVB Front-End */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
enum dmx_frontend_source {
|
||||
DMX_MEMORY_FE,
|
||||
DMX_FRONTEND_0,
|
||||
DMX_FRONTEND_1,
|
||||
DMX_FRONTEND_2,
|
||||
DMX_FRONTEND_3,
|
||||
DMX_STREAM_0, /* external stream input, e.g. LVDS */
|
||||
DMX_STREAM_1,
|
||||
DMX_STREAM_2,
|
||||
DMX_STREAM_3
|
||||
};
|
||||
|
||||
struct dmx_frontend {
|
||||
struct list_head connectivity_list; /* List of front-ends that can
|
||||
be connected to a particular
|
||||
demux */
|
||||
enum dmx_frontend_source source;
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* MPEG-2 TS Demux */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Flags OR'ed in the capabilities field of struct dmx_demux.
|
||||
*/
|
||||
|
||||
#define DMX_TS_FILTERING 1
|
||||
#define DMX_PES_FILTERING 2
|
||||
#define DMX_SECTION_FILTERING 4
|
||||
#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
|
||||
#define DMX_CRC_CHECKING 16
|
||||
#define DMX_TS_DESCRAMBLING 32
|
||||
|
||||
/*
|
||||
* Demux resource type identifier.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DMX_FE_ENTRY(): Casts elements in the list of registered
|
||||
* front-ends from the generic type struct list_head
|
||||
* to the type * struct dmx_frontend
|
||||
*.
|
||||
*/
|
||||
|
||||
#define DMX_FE_ENTRY(list) list_entry(list, struct dmx_frontend, connectivity_list)
|
||||
|
||||
struct dmx_demux {
|
||||
u32 capabilities; /* Bitfield of capability flags */
|
||||
struct dmx_frontend* frontend; /* Front-end connected to the demux */
|
||||
void* priv; /* Pointer to private data of the API client */
|
||||
int (*open) (struct dmx_demux* demux);
|
||||
int (*close) (struct dmx_demux* demux);
|
||||
int (*write) (struct dmx_demux* demux, const char __user *buf, size_t count);
|
||||
int (*allocate_ts_feed) (struct dmx_demux* demux,
|
||||
struct dmx_ts_feed** feed,
|
||||
dmx_ts_cb callback);
|
||||
int (*release_ts_feed) (struct dmx_demux* demux,
|
||||
struct dmx_ts_feed* feed);
|
||||
int (*allocate_section_feed) (struct dmx_demux* demux,
|
||||
struct dmx_section_feed** feed,
|
||||
dmx_section_cb callback);
|
||||
int (*release_section_feed) (struct dmx_demux* demux,
|
||||
struct dmx_section_feed* feed);
|
||||
int (*add_frontend) (struct dmx_demux* demux,
|
||||
struct dmx_frontend* frontend);
|
||||
int (*remove_frontend) (struct dmx_demux* demux,
|
||||
struct dmx_frontend* frontend);
|
||||
struct list_head* (*get_frontends) (struct dmx_demux* demux);
|
||||
int (*connect_frontend) (struct dmx_demux* demux,
|
||||
struct dmx_frontend* frontend);
|
||||
int (*disconnect_frontend) (struct dmx_demux* demux);
|
||||
|
||||
int (*get_pes_pids) (struct dmx_demux* demux, u16 *pids);
|
||||
|
||||
int (*get_caps) (struct dmx_demux* demux, struct dmx_caps *caps);
|
||||
|
||||
int (*set_source) (struct dmx_demux* demux, const dmx_source_t *src);
|
||||
|
||||
int (*get_stc) (struct dmx_demux* demux, unsigned int num,
|
||||
u64 *stc, unsigned int *base);
|
||||
};
|
||||
|
||||
#endif /* #ifndef __DEMUX_H */
|
1272
dvb-core/dmxdev.c
Normal file
1272
dvb-core/dmxdev.c
Normal file
File diff suppressed because it is too large
Load Diff
119
dvb-core/dmxdev.h
Normal file
119
dvb-core/dmxdev.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* dmxdev.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 _DMXDEV_H_
|
||||
#define _DMXDEV_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/dvb/dmx.h>
|
||||
|
||||
#include "dvbdev.h"
|
||||
#include "demux.h"
|
||||
#include "dvb_ringbuffer.h"
|
||||
|
||||
enum dmxdev_type {
|
||||
DMXDEV_TYPE_NONE,
|
||||
DMXDEV_TYPE_SEC,
|
||||
DMXDEV_TYPE_PES,
|
||||
};
|
||||
|
||||
enum dmxdev_state {
|
||||
DMXDEV_STATE_FREE,
|
||||
DMXDEV_STATE_ALLOCATED,
|
||||
DMXDEV_STATE_SET,
|
||||
DMXDEV_STATE_GO,
|
||||
DMXDEV_STATE_DONE,
|
||||
DMXDEV_STATE_TIMEDOUT
|
||||
};
|
||||
|
||||
struct dmxdev_feed {
|
||||
u16 pid;
|
||||
struct dmx_ts_feed *ts;
|
||||
struct list_head next;
|
||||
};
|
||||
|
||||
struct dmxdev_filter {
|
||||
union {
|
||||
struct dmx_section_filter *sec;
|
||||
} filter;
|
||||
|
||||
union {
|
||||
/* list of TS and PES feeds (struct dmxdev_feed) */
|
||||
struct list_head ts;
|
||||
struct dmx_section_feed *sec;
|
||||
} feed;
|
||||
|
||||
union {
|
||||
struct dmx_sct_filter_params sec;
|
||||
struct dmx_pes_filter_params pes;
|
||||
} params;
|
||||
|
||||
enum dmxdev_type type;
|
||||
enum dmxdev_state state;
|
||||
struct dmxdev *dev;
|
||||
struct dvb_ringbuffer buffer;
|
||||
|
||||
struct mutex mutex;
|
||||
|
||||
/* only for sections */
|
||||
struct timer_list timer;
|
||||
int todo;
|
||||
u8 secheader[3];
|
||||
};
|
||||
|
||||
|
||||
struct dmxdev {
|
||||
struct dvb_device *dvbdev;
|
||||
struct dvb_device *dvr_dvbdev;
|
||||
|
||||
struct dmxdev_filter *filter;
|
||||
struct dmx_demux *demux;
|
||||
|
||||
int filternum;
|
||||
int capabilities;
|
||||
|
||||
unsigned int exit:1;
|
||||
#define DMXDEV_CAP_DUPLEX 1
|
||||
struct dmx_frontend *dvr_orig_fe;
|
||||
|
||||
struct dvb_ringbuffer dvr_buffer;
|
||||
#define DVR_BUFFER_SIZE (10*188*1024)
|
||||
|
||||
struct mutex mutex;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
|
||||
int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *);
|
||||
void dvb_dmxdev_release(struct dmxdev *dmxdev);
|
||||
|
||||
#endif /* _DMXDEV_H_ */
|
1814
dvb-core/dvb_ca_en50221.c
Normal file
1814
dvb-core/dvb_ca_en50221.c
Normal file
File diff suppressed because it is too large
Load Diff
140
dvb-core/dvb_ca_en50221.h
Normal file
140
dvb-core/dvb_ca_en50221.h
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* dvb_ca.h: generic DVB functions for EN50221 CA interfaces
|
||||
*
|
||||
* Copyright (C) 2004 Andrew de Quincey
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _DVB_CA_EN50221_H_
|
||||
#define _DVB_CA_EN50221_H_
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/dvb/ca.h>
|
||||
|
||||
#include "dvbdev.h"
|
||||
|
||||
#define DVB_CA_EN50221_POLL_CAM_PRESENT 1
|
||||
#define DVB_CA_EN50221_POLL_CAM_CHANGED 2
|
||||
#define DVB_CA_EN50221_POLL_CAM_READY 4
|
||||
|
||||
#define DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE 1
|
||||
#define DVB_CA_EN50221_FLAG_IRQ_FR 2
|
||||
#define DVB_CA_EN50221_FLAG_IRQ_DA 4
|
||||
|
||||
#define DVB_CA_EN50221_CAMCHANGE_REMOVED 0
|
||||
#define DVB_CA_EN50221_CAMCHANGE_INSERTED 1
|
||||
|
||||
|
||||
|
||||
/* Structure describing a CA interface */
|
||||
struct dvb_ca_en50221 {
|
||||
|
||||
/* the module owning this structure */
|
||||
struct module* owner;
|
||||
|
||||
/* NOTE: the read_*, write_* and poll_slot_status functions will be
|
||||
* called for different slots concurrently and need to use locks where
|
||||
* and if appropriate. There will be no concurrent access to one slot.
|
||||
*/
|
||||
|
||||
/* functions for accessing attribute memory on the CAM */
|
||||
int (*read_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address);
|
||||
int (*write_attribute_mem)(struct dvb_ca_en50221* ca, int slot, int address, u8 value);
|
||||
|
||||
/* functions for accessing the control interface on the CAM */
|
||||
int (*read_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address);
|
||||
int (*write_cam_control)(struct dvb_ca_en50221* ca, int slot, u8 address, u8 value);
|
||||
|
||||
/* functions for readin/writing data */
|
||||
int (*read_data)(struct dvb_ca_en50221* ca, int slot, u8 *ebuf, int ecount);
|
||||
int (*write_data)(struct dvb_ca_en50221* ca, int slot, u8 *ebuf, int ecount);
|
||||
|
||||
/* Functions for controlling slots */
|
||||
int (*slot_reset)(struct dvb_ca_en50221* ca, int slot);
|
||||
int (*slot_shutdown)(struct dvb_ca_en50221* ca, int slot);
|
||||
int (*slot_ts_enable)(struct dvb_ca_en50221* ca, int slot);
|
||||
|
||||
/*
|
||||
* Poll slot status.
|
||||
* Only necessary if DVB_CA_FLAG_EN50221_IRQ_CAMCHANGE is not set
|
||||
*/
|
||||
int (*poll_slot_status)(struct dvb_ca_en50221* ca, int slot, int open);
|
||||
|
||||
/* private data, used by caller */
|
||||
void* data;
|
||||
|
||||
/* Opaque data used by the dvb_ca core. Do not modify! */
|
||||
void* private;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/* ******************************************************************************** */
|
||||
/* Functions for reporting IRQ events */
|
||||
|
||||
/**
|
||||
* A CAMCHANGE IRQ has occurred.
|
||||
*
|
||||
* @param ca CA instance.
|
||||
* @param slot Slot concerned.
|
||||
* @param change_type One of the DVB_CA_CAMCHANGE_* values
|
||||
*/
|
||||
void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int change_type);
|
||||
|
||||
/**
|
||||
* A CAMREADY IRQ has occurred.
|
||||
*
|
||||
* @param ca CA instance.
|
||||
* @param slot Slot concerned.
|
||||
*/
|
||||
void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot);
|
||||
|
||||
/**
|
||||
* An FR or a DA IRQ has occurred.
|
||||
*
|
||||
* @param ca CA instance.
|
||||
* @param slot Slot concerned.
|
||||
*/
|
||||
void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot);
|
||||
|
||||
|
||||
|
||||
/* ******************************************************************************** */
|
||||
/* Initialisation/shutdown functions */
|
||||
|
||||
/**
|
||||
* Initialise a new DVB CA device.
|
||||
*
|
||||
* @param dvb_adapter DVB adapter to attach the new CA device to.
|
||||
* @param ca The dvb_ca instance.
|
||||
* @param flags Flags describing the CA device (DVB_CA_EN50221_FLAG_*).
|
||||
* @param slot_count Number of slots supported.
|
||||
*
|
||||
* @return 0 on success, nonzero on failure
|
||||
*/
|
||||
extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_en50221* ca, int flags, int slot_count);
|
||||
|
||||
/**
|
||||
* Release a DVB CA device.
|
||||
*
|
||||
* @param ca The associated dvb_ca instance.
|
||||
*/
|
||||
extern void dvb_ca_en50221_release(struct dvb_ca_en50221* ca);
|
||||
|
||||
|
||||
|
||||
#endif
|
1320
dvb-core/dvb_demux.c
Normal file
1320
dvb-core/dvb_demux.c
Normal file
File diff suppressed because it is too large
Load Diff
151
dvb-core/dvb_demux.h
Normal file
151
dvb-core/dvb_demux.h
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* dvb_demux.h: DVB kernel demux API
|
||||
*
|
||||
* Copyright (C) 2000-2001 Marcus Metzler & Ralph 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.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DVB_DEMUX_H_
|
||||
#define _DVB_DEMUX_H_
|
||||
|
||||
#include <linux/time.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#include "demux.h"
|
||||
|
||||
#define DMX_TYPE_TS 0
|
||||
#define DMX_TYPE_SEC 1
|
||||
#define DMX_TYPE_PES 2
|
||||
|
||||
#define DMX_STATE_FREE 0
|
||||
#define DMX_STATE_ALLOCATED 1
|
||||
#define DMX_STATE_SET 2
|
||||
#define DMX_STATE_READY 3
|
||||
#define DMX_STATE_GO 4
|
||||
|
||||
#define DVB_DEMUX_MASK_MAX 18
|
||||
|
||||
#define MAX_PID 0x1fff
|
||||
|
||||
#define SPEED_PKTS_INTERVAL 50000
|
||||
|
||||
struct dvb_demux_filter {
|
||||
struct dmx_section_filter filter;
|
||||
u8 maskandmode[DMX_MAX_FILTER_SIZE];
|
||||
u8 maskandnotmode[DMX_MAX_FILTER_SIZE];
|
||||
int doneq;
|
||||
|
||||
struct dvb_demux_filter *next;
|
||||
struct dvb_demux_feed *feed;
|
||||
int index;
|
||||
int state;
|
||||
int type;
|
||||
|
||||
u16 hw_handle;
|
||||
struct timer_list timer;
|
||||
};
|
||||
|
||||
#define DMX_FEED_ENTRY(pos) list_entry(pos, struct dvb_demux_feed, list_head)
|
||||
|
||||
struct dvb_demux_feed {
|
||||
union {
|
||||
struct dmx_ts_feed ts;
|
||||
struct dmx_section_feed sec;
|
||||
} feed;
|
||||
|
||||
union {
|
||||
dmx_ts_cb ts;
|
||||
dmx_section_cb sec;
|
||||
} cb;
|
||||
|
||||
struct dvb_demux *demux;
|
||||
void *priv;
|
||||
int type;
|
||||
int state;
|
||||
u16 pid;
|
||||
u8 *buffer;
|
||||
int buffer_size;
|
||||
|
||||
struct timespec timeout;
|
||||
struct dvb_demux_filter *filter;
|
||||
|
||||
int ts_type;
|
||||
enum dmx_ts_pes pes_type;
|
||||
|
||||
int cc;
|
||||
int pusi_seen; /* prevents feeding of garbage from previous section */
|
||||
|
||||
u16 peslen;
|
||||
|
||||
struct list_head list_head;
|
||||
unsigned int index; /* a unique index for each feed (can be used as hardware pid filter index) */
|
||||
};
|
||||
|
||||
struct dvb_demux {
|
||||
struct dmx_demux dmx;
|
||||
void *priv;
|
||||
int filternum;
|
||||
int feednum;
|
||||
int (*start_feed)(struct dvb_demux_feed *feed);
|
||||
int (*stop_feed)(struct dvb_demux_feed *feed);
|
||||
int (*write_to_decoder)(struct dvb_demux_feed *feed,
|
||||
const u8 *buf, size_t len);
|
||||
u32 (*check_crc32)(struct dvb_demux_feed *feed,
|
||||
const u8 *buf, size_t len);
|
||||
void (*memcopy)(struct dvb_demux_feed *feed, u8 *dst,
|
||||
const u8 *src, size_t len);
|
||||
|
||||
int users;
|
||||
#define MAX_DVB_DEMUX_USERS 10
|
||||
struct dvb_demux_filter *filter;
|
||||
struct dvb_demux_feed *feed;
|
||||
|
||||
struct list_head frontend_list;
|
||||
|
||||
struct dvb_demux_feed *pesfilter[DMX_PES_OTHER];
|
||||
u16 pids[DMX_PES_OTHER];
|
||||
int playing;
|
||||
int recording;
|
||||
|
||||
#define DMX_MAX_PID 0x2000
|
||||
struct list_head feed_list;
|
||||
u8 tsbuf[204];
|
||||
int tsbufp;
|
||||
|
||||
struct mutex mutex;
|
||||
spinlock_t lock;
|
||||
|
||||
uint8_t *cnt_storage; /* for TS continuity check */
|
||||
|
||||
struct timespec speed_last_time; /* for TS speed check */
|
||||
uint32_t speed_pkts_cnt; /* for TS speed check */
|
||||
};
|
||||
|
||||
int dvb_dmx_init(struct dvb_demux *dvbdemux);
|
||||
void dvb_dmx_release(struct dvb_demux *dvbdemux);
|
||||
void dvb_dmx_swfilter_packets(struct dvb_demux *dvbdmx, const u8 *buf,
|
||||
size_t count);
|
||||
void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count);
|
||||
void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf,
|
||||
size_t count);
|
||||
void dvb_dmx_swfilter_raw(struct dvb_demux *demux, const u8 *buf,
|
||||
size_t count);
|
||||
|
||||
#endif /* _DVB_DEMUX_H_ */
|
603
dvb-core/dvb_filter.c
Normal file
603
dvb-core/dvb_filter.c
Normal file
@ -0,0 +1,603 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include "dvb_filter.h"
|
||||
|
||||
#if 0
|
||||
static unsigned int bitrates[3][16] =
|
||||
{{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},
|
||||
{0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},
|
||||
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}};
|
||||
#endif
|
||||
|
||||
static u32 freq[4] = {480, 441, 320, 0};
|
||||
|
||||
static unsigned int ac3_bitrates[32] =
|
||||
{32,40,48,56,64,80,96,112,128,160,192,224,256,320,384,448,512,576,640,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
static u32 ac3_frames[3][32] =
|
||||
{{64,80,96,112,128,160,192,224,256,320,384,448,512,640,768,896,1024,
|
||||
1152,1280,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{69,87,104,121,139,174,208,243,278,348,417,487,557,696,835,975,1114,
|
||||
1253,1393,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
||||
{96,120,144,168,192,240,288,336,384,480,576,672,768,960,1152,1344,
|
||||
1536,1728,1920,0,0,0,0,0,0,0,0,0,0,0,0,0}};
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
static void setup_ts2pes(ipack *pa, ipack *pv, u16 *pida, u16 *pidv,
|
||||
void (*pes_write)(u8 *buf, int count, void *data),
|
||||
void *priv)
|
||||
{
|
||||
dvb_filter_ipack_init(pa, IPACKS, pes_write);
|
||||
dvb_filter_ipack_init(pv, IPACKS, pes_write);
|
||||
pa->pid = pida;
|
||||
pv->pid = pidv;
|
||||
pa->data = priv;
|
||||
pv->data = priv;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void ts_to_pes(ipack *p, u8 *buf) // don't need count (=188)
|
||||
{
|
||||
u8 off = 0;
|
||||
|
||||
if (!buf || !p ){
|
||||
printk("NULL POINTER IDIOT\n");
|
||||
return;
|
||||
}
|
||||
if (buf[1]&PAY_START) {
|
||||
if (p->plength == MMAX_PLENGTH-6 && p->found>6){
|
||||
p->plength = p->found-6;
|
||||
p->found = 0;
|
||||
send_ipack(p);
|
||||
dvb_filter_ipack_reset(p);
|
||||
}
|
||||
}
|
||||
if (buf[3] & ADAPT_FIELD) { // adaptation field?
|
||||
off = buf[4] + 1;
|
||||
if (off+4 > 187) return;
|
||||
}
|
||||
dvb_filter_instant_repack(buf+4+off, TS_SIZE-4-off, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* needs 5 byte input, returns picture coding type*/
|
||||
static int read_picture_header(u8 *headr, struct mpg_picture *pic, int field, int pr)
|
||||
{
|
||||
u8 pct;
|
||||
|
||||
if (pr) printk( "Pic header: ");
|
||||
pic->temporal_reference[field] = (( headr[0] << 2 ) |
|
||||
(headr[1] & 0x03) )& 0x03ff;
|
||||
if (pr) printk( " temp ref: 0x%04x", pic->temporal_reference[field]);
|
||||
|
||||
pct = ( headr[1] >> 2 ) & 0x07;
|
||||
pic->picture_coding_type[field] = pct;
|
||||
if (pr) {
|
||||
switch(pct){
|
||||
case I_FRAME:
|
||||
printk( " I-FRAME");
|
||||
break;
|
||||
case B_FRAME:
|
||||
printk( " B-FRAME");
|
||||
break;
|
||||
case P_FRAME:
|
||||
printk( " P-FRAME");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pic->vinfo.vbv_delay = (( headr[1] >> 5 ) | ( headr[2] << 3) |
|
||||
( (headr[3] & 0x1F) << 11) ) & 0xffff;
|
||||
|
||||
if (pr) printk( " vbv delay: 0x%04x", pic->vinfo.vbv_delay);
|
||||
|
||||
pic->picture_header_parameter = ( headr[3] & 0xe0 ) |
|
||||
((headr[4] & 0x80) >> 3);
|
||||
|
||||
if ( pct == B_FRAME ){
|
||||
pic->picture_header_parameter |= ( headr[4] >> 3 ) & 0x0f;
|
||||
}
|
||||
if (pr) printk( " pic head param: 0x%x",
|
||||
pic->picture_header_parameter);
|
||||
|
||||
return pct;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* needs 4 byte input */
|
||||
static int read_gop_header(u8 *headr, struct mpg_picture *pic, int pr)
|
||||
{
|
||||
if (pr) printk("GOP header: ");
|
||||
|
||||
pic->time_code = (( headr[0] << 17 ) | ( headr[1] << 9) |
|
||||
( headr[2] << 1 ) | (headr[3] &0x01)) & 0x1ffffff;
|
||||
|
||||
if (pr) printk(" time: %d:%d.%d ", (headr[0]>>2)& 0x1F,
|
||||
((headr[0]<<4)& 0x30)| ((headr[1]>>4)& 0x0F),
|
||||
((headr[1]<<3)& 0x38)| ((headr[2]>>5)& 0x0F));
|
||||
|
||||
if ( ( headr[3] & 0x40 ) != 0 ){
|
||||
pic->closed_gop = 1;
|
||||
} else {
|
||||
pic->closed_gop = 0;
|
||||
}
|
||||
if (pr) printk("closed: %d", pic->closed_gop);
|
||||
|
||||
if ( ( headr[3] & 0x20 ) != 0 ){
|
||||
pic->broken_link = 1;
|
||||
} else {
|
||||
pic->broken_link = 0;
|
||||
}
|
||||
if (pr) printk(" broken: %d\n", pic->broken_link);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* needs 8 byte input */
|
||||
static int read_sequence_header(u8 *headr, struct dvb_video_info *vi, int pr)
|
||||
{
|
||||
int sw;
|
||||
int form = -1;
|
||||
|
||||
if (pr) printk("Reading sequence header\n");
|
||||
|
||||
vi->horizontal_size = ((headr[1] &0xF0) >> 4) | (headr[0] << 4);
|
||||
vi->vertical_size = ((headr[1] &0x0F) << 8) | (headr[2]);
|
||||
|
||||
sw = (int)((headr[3]&0xF0) >> 4) ;
|
||||
|
||||
switch( sw ){
|
||||
case 1:
|
||||
if (pr)
|
||||
printk("Videostream: ASPECT: 1:1");
|
||||
vi->aspect_ratio = 100;
|
||||
break;
|
||||
case 2:
|
||||
if (pr)
|
||||
printk("Videostream: ASPECT: 4:3");
|
||||
vi->aspect_ratio = 133;
|
||||
break;
|
||||
case 3:
|
||||
if (pr)
|
||||
printk("Videostream: ASPECT: 16:9");
|
||||
vi->aspect_ratio = 177;
|
||||
break;
|
||||
case 4:
|
||||
if (pr)
|
||||
printk("Videostream: ASPECT: 2.21:1");
|
||||
vi->aspect_ratio = 221;
|
||||
break;
|
||||
|
||||
case 5 ... 15:
|
||||
if (pr)
|
||||
printk("Videostream: ASPECT: reserved");
|
||||
vi->aspect_ratio = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
vi->aspect_ratio = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pr)
|
||||
printk(" Size = %dx%d",vi->horizontal_size,vi->vertical_size);
|
||||
|
||||
sw = (int)(headr[3]&0x0F);
|
||||
|
||||
switch ( sw ) {
|
||||
case 1:
|
||||
if (pr)
|
||||
printk(" FRate: 23.976 fps");
|
||||
vi->framerate = 23976;
|
||||
form = -1;
|
||||
break;
|
||||
case 2:
|
||||
if (pr)
|
||||
printk(" FRate: 24 fps");
|
||||
vi->framerate = 24000;
|
||||
form = -1;
|
||||
break;
|
||||
case 3:
|
||||
if (pr)
|
||||
printk(" FRate: 25 fps");
|
||||
vi->framerate = 25000;
|
||||
form = VIDEO_MODE_PAL;
|
||||
break;
|
||||
case 4:
|
||||
if (pr)
|
||||
printk(" FRate: 29.97 fps");
|
||||
vi->framerate = 29970;
|
||||
form = VIDEO_MODE_NTSC;
|
||||
break;
|
||||
case 5:
|
||||
if (pr)
|
||||
printk(" FRate: 30 fps");
|
||||
vi->framerate = 30000;
|
||||
form = VIDEO_MODE_NTSC;
|
||||
break;
|
||||
case 6:
|
||||
if (pr)
|
||||
printk(" FRate: 50 fps");
|
||||
vi->framerate = 50000;
|
||||
form = VIDEO_MODE_PAL;
|
||||
break;
|
||||
case 7:
|
||||
if (pr)
|
||||
printk(" FRate: 60 fps");
|
||||
vi->framerate = 60000;
|
||||
form = VIDEO_MODE_NTSC;
|
||||
break;
|
||||
}
|
||||
|
||||
vi->bit_rate = (headr[4] << 10) | (headr[5] << 2) | (headr[6] & 0x03);
|
||||
|
||||
vi->vbv_buffer_size
|
||||
= (( headr[6] & 0xF8) >> 3 ) | (( headr[7] & 0x1F )<< 5);
|
||||
|
||||
if (pr){
|
||||
printk(" BRate: %d Mbit/s",4*(vi->bit_rate)/10000);
|
||||
printk(" vbvbuffer %d",16*1024*(vi->vbv_buffer_size));
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
vi->video_format = form;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
static int get_vinfo(u8 *mbuf, int count, struct dvb_video_info *vi, int pr)
|
||||
{
|
||||
u8 *headr;
|
||||
int found = 0;
|
||||
int c = 0;
|
||||
|
||||
while (found < 4 && c+4 < count){
|
||||
u8 *b;
|
||||
|
||||
b = mbuf+c;
|
||||
if ( b[0] == 0x00 && b[1] == 0x00 && b[2] == 0x01
|
||||
&& b[3] == 0xb3) found = 4;
|
||||
else {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found) return -1;
|
||||
c += 4;
|
||||
if (c+12 >= count) return -1;
|
||||
headr = mbuf+c;
|
||||
if (read_sequence_header(headr, vi, pr) < 0) return -1;
|
||||
vi->off = c-4;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
static int get_ainfo(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
|
||||
{
|
||||
u8 *headr;
|
||||
int found = 0;
|
||||
int c = 0;
|
||||
int fr = 0;
|
||||
|
||||
while (found < 2 && c < count){
|
||||
u8 b[2];
|
||||
memcpy( b, mbuf+c, 2);
|
||||
|
||||
if ( b[0] == 0xff && (b[1] & 0xf8) == 0xf8)
|
||||
found = 2;
|
||||
else {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) return -1;
|
||||
|
||||
if (c+3 >= count) return -1;
|
||||
headr = mbuf+c;
|
||||
|
||||
ai->layer = (headr[1] & 0x06) >> 1;
|
||||
|
||||
if (pr)
|
||||
printk("Audiostream: Layer: %d", 4-ai->layer);
|
||||
|
||||
|
||||
ai->bit_rate = bitrates[(3-ai->layer)][(headr[2] >> 4 )]*1000;
|
||||
|
||||
if (pr){
|
||||
if (ai->bit_rate == 0)
|
||||
printk(" Bit rate: free");
|
||||
else if (ai->bit_rate == 0xf)
|
||||
printk(" BRate: reserved");
|
||||
else
|
||||
printk(" BRate: %d kb/s", ai->bit_rate/1000);
|
||||
}
|
||||
|
||||
fr = (headr[2] & 0x0c ) >> 2;
|
||||
ai->frequency = freq[fr]*100;
|
||||
if (pr){
|
||||
if (ai->frequency == 3)
|
||||
printk(" Freq: reserved\n");
|
||||
else
|
||||
printk(" Freq: %d kHz\n",ai->frequency);
|
||||
|
||||
}
|
||||
ai->off = c;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr)
|
||||
{
|
||||
u8 *headr;
|
||||
int found = 0;
|
||||
int c = 0;
|
||||
u8 frame = 0;
|
||||
int fr = 0;
|
||||
|
||||
while ( !found && c < count){
|
||||
u8 *b = mbuf+c;
|
||||
|
||||
if ( b[0] == 0x0b && b[1] == 0x77 )
|
||||
found = 1;
|
||||
else {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) return -1;
|
||||
if (pr)
|
||||
printk("Audiostream: AC3");
|
||||
|
||||
ai->off = c;
|
||||
if (c+5 >= count) return -1;
|
||||
|
||||
ai->layer = 0; // 0 for AC3
|
||||
headr = mbuf+c+2;
|
||||
|
||||
frame = (headr[2]&0x3f);
|
||||
ai->bit_rate = ac3_bitrates[frame >> 1]*1000;
|
||||
|
||||
if (pr)
|
||||
printk(" BRate: %d kb/s", (int) ai->bit_rate/1000);
|
||||
|
||||
ai->frequency = (headr[2] & 0xc0 ) >> 6;
|
||||
fr = (headr[2] & 0xc0 ) >> 6;
|
||||
ai->frequency = freq[fr]*100;
|
||||
if (pr) printk (" Freq: %d Hz\n", (int) ai->frequency);
|
||||
|
||||
|
||||
ai->framesize = ac3_frames[fr][frame >> 1];
|
||||
if ((frame & 1) && (fr == 1)) ai->framesize++;
|
||||
ai->framesize = ai->framesize << 1;
|
||||
if (pr) printk (" Framesize %d\n",(int) ai->framesize);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_filter_get_ac3info);
|
||||
|
||||
|
||||
#if 0
|
||||
static u8 *skip_pes_header(u8 **bufp)
|
||||
{
|
||||
u8 *inbuf = *bufp;
|
||||
u8 *buf = inbuf;
|
||||
u8 *pts = NULL;
|
||||
int skip = 0;
|
||||
|
||||
static const int mpeg1_skip_table[16] = {
|
||||
1, 0xffff, 5, 10, 0xffff, 0xffff, 0xffff, 0xffff,
|
||||
0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff
|
||||
};
|
||||
|
||||
|
||||
if ((inbuf[6] & 0xc0) == 0x80){ /* mpeg2 */
|
||||
if (buf[7] & PTS_ONLY)
|
||||
pts = buf+9;
|
||||
else pts = NULL;
|
||||
buf = inbuf + 9 + inbuf[8];
|
||||
} else { /* mpeg1 */
|
||||
for (buf = inbuf + 6; *buf == 0xff; buf++)
|
||||
if (buf == inbuf + 6 + 16) {
|
||||
break;
|
||||
}
|
||||
if ((*buf & 0xc0) == 0x40)
|
||||
buf += 2;
|
||||
skip = mpeg1_skip_table [*buf >> 4];
|
||||
if (skip == 5 || skip == 10) pts = buf;
|
||||
else pts = NULL;
|
||||
|
||||
buf += mpeg1_skip_table [*buf >> 4];
|
||||
}
|
||||
|
||||
*bufp = buf;
|
||||
return pts;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void initialize_quant_matrix( u32 *matrix )
|
||||
{
|
||||
int i;
|
||||
|
||||
matrix[0] = 0x08101013;
|
||||
matrix[1] = 0x10131616;
|
||||
matrix[2] = 0x16161616;
|
||||
matrix[3] = 0x1a181a1b;
|
||||
matrix[4] = 0x1b1b1a1a;
|
||||
matrix[5] = 0x1a1a1b1b;
|
||||
matrix[6] = 0x1b1d1d1d;
|
||||
matrix[7] = 0x2222221d;
|
||||
matrix[8] = 0x1d1d1b1b;
|
||||
matrix[9] = 0x1d1d2020;
|
||||
matrix[10] = 0x22222526;
|
||||
matrix[11] = 0x25232322;
|
||||
matrix[12] = 0x23262628;
|
||||
matrix[13] = 0x28283030;
|
||||
matrix[14] = 0x2e2e3838;
|
||||
matrix[15] = 0x3a454553;
|
||||
|
||||
for ( i = 16 ; i < 32 ; i++ )
|
||||
matrix[i] = 0x10101010;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void initialize_mpg_picture(struct mpg_picture *pic)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* set MPEG1 */
|
||||
pic->mpeg1_flag = 1;
|
||||
pic->profile_and_level = 0x4A ; /* MP@LL */
|
||||
pic->progressive_sequence = 1;
|
||||
pic->low_delay = 0;
|
||||
|
||||
pic->sequence_display_extension_flag = 0;
|
||||
for ( i = 0 ; i < 4 ; i++ ){
|
||||
pic->frame_centre_horizontal_offset[i] = 0;
|
||||
pic->frame_centre_vertical_offset[i] = 0;
|
||||
}
|
||||
pic->last_frame_centre_horizontal_offset = 0;
|
||||
pic->last_frame_centre_vertical_offset = 0;
|
||||
|
||||
pic->picture_display_extension_flag[0] = 0;
|
||||
pic->picture_display_extension_flag[1] = 0;
|
||||
pic->sequence_header_flag = 0;
|
||||
pic->gop_flag = 0;
|
||||
pic->sequence_end_flag = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void mpg_set_picture_parameter( int32_t field_type, struct mpg_picture *pic )
|
||||
{
|
||||
int16_t last_h_offset;
|
||||
int16_t last_v_offset;
|
||||
|
||||
int16_t *p_h_offset;
|
||||
int16_t *p_v_offset;
|
||||
|
||||
if ( pic->mpeg1_flag ){
|
||||
pic->picture_structure[field_type] = VIDEO_FRAME_PICTURE;
|
||||
pic->top_field_first = 0;
|
||||
pic->repeat_first_field = 0;
|
||||
pic->progressive_frame = 1;
|
||||
pic->picture_coding_parameter = 0x000010;
|
||||
}
|
||||
|
||||
/* Reset flag */
|
||||
pic->picture_display_extension_flag[field_type] = 0;
|
||||
|
||||
last_h_offset = pic->last_frame_centre_horizontal_offset;
|
||||
last_v_offset = pic->last_frame_centre_vertical_offset;
|
||||
if ( field_type == FIRST_FIELD ){
|
||||
p_h_offset = pic->frame_centre_horizontal_offset;
|
||||
p_v_offset = pic->frame_centre_vertical_offset;
|
||||
*p_h_offset = last_h_offset;
|
||||
*(p_h_offset + 1) = last_h_offset;
|
||||
*(p_h_offset + 2) = last_h_offset;
|
||||
*p_v_offset = last_v_offset;
|
||||
*(p_v_offset + 1) = last_v_offset;
|
||||
*(p_v_offset + 2) = last_v_offset;
|
||||
} else {
|
||||
pic->frame_centre_horizontal_offset[3] = last_h_offset;
|
||||
pic->frame_centre_vertical_offset[3] = last_v_offset;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void init_mpg_picture( struct mpg_picture *pic, int chan, int32_t field_type)
|
||||
{
|
||||
pic->picture_header = 0;
|
||||
pic->sequence_header_data
|
||||
= ( INIT_HORIZONTAL_SIZE << 20 )
|
||||
| ( INIT_VERTICAL_SIZE << 8 )
|
||||
| ( INIT_ASPECT_RATIO << 4 )
|
||||
| ( INIT_FRAME_RATE );
|
||||
pic->mpeg1_flag = 0;
|
||||
pic->vinfo.horizontal_size
|
||||
= INIT_DISP_HORIZONTAL_SIZE;
|
||||
pic->vinfo.vertical_size
|
||||
= INIT_DISP_VERTICAL_SIZE;
|
||||
pic->picture_display_extension_flag[field_type]
|
||||
= 0;
|
||||
pic->pts_flag[field_type] = 0;
|
||||
|
||||
pic->sequence_gop_header = 0;
|
||||
pic->picture_header = 0;
|
||||
pic->sequence_header_flag = 0;
|
||||
pic->gop_flag = 0;
|
||||
pic->sequence_end_flag = 0;
|
||||
pic->sequence_display_extension_flag = 0;
|
||||
pic->last_frame_centre_horizontal_offset = 0;
|
||||
pic->last_frame_centre_vertical_offset = 0;
|
||||
pic->channel = chan;
|
||||
}
|
||||
#endif
|
||||
|
||||
void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
|
||||
dvb_filter_pes2ts_cb_t *cb, void *priv)
|
||||
{
|
||||
unsigned char *buf=p2ts->buf;
|
||||
|
||||
buf[0]=0x47;
|
||||
buf[1]=(pid>>8);
|
||||
buf[2]=pid&0xff;
|
||||
p2ts->cc=0;
|
||||
p2ts->cb=cb;
|
||||
p2ts->priv=priv;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_filter_pes2ts_init);
|
||||
|
||||
int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
|
||||
int len, int payload_start)
|
||||
{
|
||||
unsigned char *buf=p2ts->buf;
|
||||
int ret=0, rest;
|
||||
|
||||
//len=6+((pes[4]<<8)|pes[5]);
|
||||
|
||||
if (payload_start)
|
||||
buf[1]|=0x40;
|
||||
else
|
||||
buf[1]&=~0x40;
|
||||
while (len>=184) {
|
||||
buf[3]=0x10|((p2ts->cc++)&0x0f);
|
||||
memcpy(buf+4, pes, 184);
|
||||
if ((ret=p2ts->cb(p2ts->priv, buf)))
|
||||
return ret;
|
||||
len-=184; pes+=184;
|
||||
buf[1]&=~0x40;
|
||||
}
|
||||
if (!len)
|
||||
return 0;
|
||||
buf[3]=0x30|((p2ts->cc++)&0x0f);
|
||||
rest=183-len;
|
||||
if (rest) {
|
||||
buf[5]=0x00;
|
||||
if (rest-1)
|
||||
memset(buf+6, 0xff, rest-1);
|
||||
}
|
||||
buf[4]=rest;
|
||||
memcpy(buf+5+rest, pes, len);
|
||||
return p2ts->cb(p2ts->priv, buf);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_filter_pes2ts);
|
246
dvb-core/dvb_filter.h
Normal file
246
dvb-core/dvb_filter.h
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* dvb_filter.h
|
||||
*
|
||||
* Copyright (C) 2003 Convergence GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _DVB_FILTER_H_
|
||||
#define _DVB_FILTER_H_
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "demux.h"
|
||||
|
||||
typedef int (dvb_filter_pes2ts_cb_t) (void *, unsigned char *);
|
||||
|
||||
struct dvb_filter_pes2ts {
|
||||
unsigned char buf[188];
|
||||
unsigned char cc;
|
||||
dvb_filter_pes2ts_cb_t *cb;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
void dvb_filter_pes2ts_init(struct dvb_filter_pes2ts *p2ts, unsigned short pid,
|
||||
dvb_filter_pes2ts_cb_t *cb, void *priv);
|
||||
|
||||
int dvb_filter_pes2ts(struct dvb_filter_pes2ts *p2ts, unsigned char *pes,
|
||||
int len, int payload_start);
|
||||
|
||||
|
||||
#define PROG_STREAM_MAP 0xBC
|
||||
#define PRIVATE_STREAM1 0xBD
|
||||
#define PADDING_STREAM 0xBE
|
||||
#define PRIVATE_STREAM2 0xBF
|
||||
#define AUDIO_STREAM_S 0xC0
|
||||
#define AUDIO_STREAM_E 0xDF
|
||||
#define VIDEO_STREAM_S 0xE0
|
||||
#define VIDEO_STREAM_E 0xEF
|
||||
#define ECM_STREAM 0xF0
|
||||
#define EMM_STREAM 0xF1
|
||||
#define DSM_CC_STREAM 0xF2
|
||||
#define ISO13522_STREAM 0xF3
|
||||
#define PROG_STREAM_DIR 0xFF
|
||||
|
||||
#define DVB_PICTURE_START 0x00
|
||||
#define DVB_USER_START 0xb2
|
||||
#define DVB_SEQUENCE_HEADER 0xb3
|
||||
#define DVB_SEQUENCE_ERROR 0xb4
|
||||
#define DVB_EXTENSION_START 0xb5
|
||||
#define DVB_SEQUENCE_END 0xb7
|
||||
#define DVB_GOP_START 0xb8
|
||||
#define DVB_EXCEPT_SLICE 0xb0
|
||||
|
||||
#define SEQUENCE_EXTENSION 0x01
|
||||
#define SEQUENCE_DISPLAY_EXTENSION 0x02
|
||||
#define PICTURE_CODING_EXTENSION 0x08
|
||||
#define QUANT_MATRIX_EXTENSION 0x03
|
||||
#define PICTURE_DISPLAY_EXTENSION 0x07
|
||||
|
||||
#define I_FRAME 0x01
|
||||
#define B_FRAME 0x02
|
||||
#define P_FRAME 0x03
|
||||
|
||||
/* Initialize sequence_data */
|
||||
#define INIT_HORIZONTAL_SIZE 720
|
||||
#define INIT_VERTICAL_SIZE 576
|
||||
#define INIT_ASPECT_RATIO 0x02
|
||||
#define INIT_FRAME_RATE 0x03
|
||||
#define INIT_DISP_HORIZONTAL_SIZE 540
|
||||
#define INIT_DISP_VERTICAL_SIZE 576
|
||||
|
||||
|
||||
//flags2
|
||||
#define PTS_DTS_FLAGS 0xC0
|
||||
#define ESCR_FLAG 0x20
|
||||
#define ES_RATE_FLAG 0x10
|
||||
#define DSM_TRICK_FLAG 0x08
|
||||
#define ADD_CPY_FLAG 0x04
|
||||
#define PES_CRC_FLAG 0x02
|
||||
#define PES_EXT_FLAG 0x01
|
||||
|
||||
//pts_dts flags
|
||||
#define PTS_ONLY 0x80
|
||||
#define PTS_DTS 0xC0
|
||||
|
||||
#define TS_SIZE 188
|
||||
#define TRANS_ERROR 0x80
|
||||
#define PAY_START 0x40
|
||||
#define TRANS_PRIO 0x20
|
||||
#define PID_MASK_HI 0x1F
|
||||
//flags
|
||||
#define TRANS_SCRMBL1 0x80
|
||||
#define TRANS_SCRMBL2 0x40
|
||||
#define ADAPT_FIELD 0x20
|
||||
#define PAYLOAD 0x10
|
||||
#define COUNT_MASK 0x0F
|
||||
|
||||
// adaptation flags
|
||||
#define DISCON_IND 0x80
|
||||
#define RAND_ACC_IND 0x40
|
||||
#define ES_PRI_IND 0x20
|
||||
#define PCR_FLAG 0x10
|
||||
#define OPCR_FLAG 0x08
|
||||
#define SPLICE_FLAG 0x04
|
||||
#define TRANS_PRIV 0x02
|
||||
#define ADAP_EXT_FLAG 0x01
|
||||
|
||||
// adaptation extension flags
|
||||
#define LTW_FLAG 0x80
|
||||
#define PIECE_RATE 0x40
|
||||
#define SEAM_SPLICE 0x20
|
||||
|
||||
|
||||
#define MAX_PLENGTH 0xFFFF
|
||||
#define MMAX_PLENGTH (256*MAX_PLENGTH)
|
||||
|
||||
#ifndef IPACKS
|
||||
#define IPACKS 2048
|
||||
#endif
|
||||
|
||||
struct ipack {
|
||||
int size;
|
||||
int found;
|
||||
u8 *buf;
|
||||
u8 cid;
|
||||
u32 plength;
|
||||
u8 plen[2];
|
||||
u8 flag1;
|
||||
u8 flag2;
|
||||
u8 hlength;
|
||||
u8 pts[5];
|
||||
u16 *pid;
|
||||
int mpeg;
|
||||
u8 check;
|
||||
int which;
|
||||
int done;
|
||||
void *data;
|
||||
void (*func)(u8 *buf, int size, void *priv);
|
||||
int count;
|
||||
int repack_subids;
|
||||
};
|
||||
|
||||
struct dvb_video_info {
|
||||
u32 horizontal_size;
|
||||
u32 vertical_size;
|
||||
u32 aspect_ratio;
|
||||
u32 framerate;
|
||||
u32 video_format;
|
||||
u32 bit_rate;
|
||||
u32 comp_bit_rate;
|
||||
u32 vbv_buffer_size;
|
||||
s16 vbv_delay;
|
||||
u32 CSPF;
|
||||
u32 off;
|
||||
};
|
||||
|
||||
#define OFF_SIZE 4
|
||||
#define FIRST_FIELD 0
|
||||
#define SECOND_FIELD 1
|
||||
#define VIDEO_FRAME_PICTURE 0x03
|
||||
|
||||
struct mpg_picture {
|
||||
int channel;
|
||||
struct dvb_video_info vinfo;
|
||||
u32 *sequence_gop_header;
|
||||
u32 *picture_header;
|
||||
s32 time_code;
|
||||
int low_delay;
|
||||
int closed_gop;
|
||||
int broken_link;
|
||||
int sequence_header_flag;
|
||||
int gop_flag;
|
||||
int sequence_end_flag;
|
||||
|
||||
u8 profile_and_level;
|
||||
s32 picture_coding_parameter;
|
||||
u32 matrix[32];
|
||||
s8 matrix_change_flag;
|
||||
|
||||
u8 picture_header_parameter;
|
||||
/* bit 0 - 2: bwd f code
|
||||
bit 3 : fpb vector
|
||||
bit 4 - 6: fwd f code
|
||||
bit 7 : fpf vector */
|
||||
|
||||
int mpeg1_flag;
|
||||
int progressive_sequence;
|
||||
int sequence_display_extension_flag;
|
||||
u32 sequence_header_data;
|
||||
s16 last_frame_centre_horizontal_offset;
|
||||
s16 last_frame_centre_vertical_offset;
|
||||
|
||||
u32 pts[2]; /* [0] 1st field, [1] 2nd field */
|
||||
int top_field_first;
|
||||
int repeat_first_field;
|
||||
int progressive_frame;
|
||||
int bank;
|
||||
int forward_bank;
|
||||
int backward_bank;
|
||||
int compress;
|
||||
s16 frame_centre_horizontal_offset[OFF_SIZE];
|
||||
/* [0-2] 1st field, [3] 2nd field */
|
||||
s16 frame_centre_vertical_offset[OFF_SIZE];
|
||||
/* [0-2] 1st field, [3] 2nd field */
|
||||
s16 temporal_reference[2];
|
||||
/* [0] 1st field, [1] 2nd field */
|
||||
|
||||
s8 picture_coding_type[2];
|
||||
/* [0] 1st field, [1] 2nd field */
|
||||
s8 picture_structure[2];
|
||||
/* [0] 1st field, [1] 2nd field */
|
||||
s8 picture_display_extension_flag[2];
|
||||
/* [0] 1st field, [1] 2nd field */
|
||||
/* picture_display_extenion() 0:no 1:exit*/
|
||||
s8 pts_flag[2];
|
||||
/* [0] 1st field, [1] 2nd field */
|
||||
};
|
||||
|
||||
struct dvb_audio_info {
|
||||
int layer;
|
||||
u32 bit_rate;
|
||||
u32 frequency;
|
||||
u32 mode;
|
||||
u32 mode_extension ;
|
||||
u32 emphasis;
|
||||
u32 framesize;
|
||||
u32 off;
|
||||
};
|
||||
|
||||
int dvb_filter_get_ac3info(u8 *mbuf, int count, struct dvb_audio_info *ai, int pr);
|
||||
|
||||
|
||||
#endif
|
2713
dvb-core/dvb_frontend.c
Normal file
2713
dvb-core/dvb_frontend.c
Normal file
File diff suppressed because it is too large
Load Diff
441
dvb-core/dvb_frontend.h
Normal file
441
dvb-core/dvb_frontend.h
Normal file
@ -0,0 +1,441 @@
|
||||
/*
|
||||
* dvb_frontend.h
|
||||
*
|
||||
* Copyright (C) 2001 convergence integrated media GmbH
|
||||
* Copyright (C) 2004 convergence GmbH
|
||||
*
|
||||
* Written by Ralph Metzler
|
||||
* Overhauled by Holger Waechtler
|
||||
* Kernel I2C stuff by Michael Hunold <hunold@convergence.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public License
|
||||
* as published by the Free Software Foundation; either version 2.1
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DVB_FRONTEND_H_
|
||||
#define _DVB_FRONTEND_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#include "dvbdev.h"
|
||||
|
||||
/*
|
||||
* Maximum number of Delivery systems per frontend. It
|
||||
* should be smaller or equal to 32
|
||||
*/
|
||||
#define MAX_DELSYS 8
|
||||
|
||||
struct dvb_frontend_tune_settings {
|
||||
int min_delay_ms;
|
||||
int step_size;
|
||||
int max_drift;
|
||||
};
|
||||
|
||||
struct dvb_frontend;
|
||||
|
||||
struct dvb_tuner_info {
|
||||
char name[128];
|
||||
|
||||
u32 frequency_min;
|
||||
u32 frequency_max;
|
||||
u32 frequency_step;
|
||||
|
||||
u32 bandwidth_min;
|
||||
u32 bandwidth_max;
|
||||
u32 bandwidth_step;
|
||||
};
|
||||
|
||||
struct analog_parameters {
|
||||
unsigned int frequency;
|
||||
unsigned int mode;
|
||||
unsigned int audmode;
|
||||
u64 std;
|
||||
};
|
||||
|
||||
enum dvbfe_modcod {
|
||||
DVBFE_MODCOD_DUMMY_PLFRAME = 0,
|
||||
DVBFE_MODCOD_QPSK_1_4,
|
||||
DVBFE_MODCOD_QPSK_1_3,
|
||||
DVBFE_MODCOD_QPSK_2_5,
|
||||
DVBFE_MODCOD_QPSK_1_2,
|
||||
DVBFE_MODCOD_QPSK_3_5,
|
||||
DVBFE_MODCOD_QPSK_2_3,
|
||||
DVBFE_MODCOD_QPSK_3_4,
|
||||
DVBFE_MODCOD_QPSK_4_5,
|
||||
DVBFE_MODCOD_QPSK_5_6,
|
||||
DVBFE_MODCOD_QPSK_8_9,
|
||||
DVBFE_MODCOD_QPSK_9_10,
|
||||
DVBFE_MODCOD_8PSK_3_5,
|
||||
DVBFE_MODCOD_8PSK_2_3,
|
||||
DVBFE_MODCOD_8PSK_3_4,
|
||||
DVBFE_MODCOD_8PSK_5_6,
|
||||
DVBFE_MODCOD_8PSK_8_9,
|
||||
DVBFE_MODCOD_8PSK_9_10,
|
||||
DVBFE_MODCOD_16APSK_2_3,
|
||||
DVBFE_MODCOD_16APSK_3_4,
|
||||
DVBFE_MODCOD_16APSK_4_5,
|
||||
DVBFE_MODCOD_16APSK_5_6,
|
||||
DVBFE_MODCOD_16APSK_8_9,
|
||||
DVBFE_MODCOD_16APSK_9_10,
|
||||
DVBFE_MODCOD_32APSK_3_4,
|
||||
DVBFE_MODCOD_32APSK_4_5,
|
||||
DVBFE_MODCOD_32APSK_5_6,
|
||||
DVBFE_MODCOD_32APSK_8_9,
|
||||
DVBFE_MODCOD_32APSK_9_10,
|
||||
DVBFE_MODCOD_RESERVED_1,
|
||||
DVBFE_MODCOD_BPSK_1_3,
|
||||
DVBFE_MODCOD_BPSK_1_4,
|
||||
DVBFE_MODCOD_RESERVED_2
|
||||
};
|
||||
|
||||
enum tuner_param {
|
||||
DVBFE_TUNER_FREQUENCY = (1 << 0),
|
||||
DVBFE_TUNER_TUNERSTEP = (1 << 1),
|
||||
DVBFE_TUNER_IFFREQ = (1 << 2),
|
||||
DVBFE_TUNER_BANDWIDTH = (1 << 3),
|
||||
DVBFE_TUNER_REFCLOCK = (1 << 4),
|
||||
DVBFE_TUNER_IQSENSE = (1 << 5),
|
||||
DVBFE_TUNER_DUMMY = (1 << 31)
|
||||
};
|
||||
|
||||
/*
|
||||
* ALGO_HW: (Hardware Algorithm)
|
||||
* ----------------------------------------------------------------
|
||||
* Devices that support this algorithm do everything in hardware
|
||||
* and no software support is needed to handle them.
|
||||
* Requesting these devices to LOCK is the only thing required,
|
||||
* device is supposed to do everything in the hardware.
|
||||
*
|
||||
* ALGO_SW: (Software Algorithm)
|
||||
* ----------------------------------------------------------------
|
||||
* These are dumb devices, that require software to do everything
|
||||
*
|
||||
* ALGO_CUSTOM: (Customizable Agorithm)
|
||||
* ----------------------------------------------------------------
|
||||
* Devices having this algorithm can be customized to have specific
|
||||
* algorithms in the frontend driver, rather than simply doing a
|
||||
* software zig-zag. In this case the zigzag maybe hardware assisted
|
||||
* or it maybe completely done in hardware. In all cases, usage of
|
||||
* this algorithm, in conjunction with the search and track
|
||||
* callbacks, utilizes the driver specific algorithm.
|
||||
*
|
||||
* ALGO_RECOVERY: (Recovery Algorithm)
|
||||
* ----------------------------------------------------------------
|
||||
* These devices have AUTO recovery capabilities from LOCK failure
|
||||
*/
|
||||
enum dvbfe_algo {
|
||||
DVBFE_ALGO_HW = (1 << 0),
|
||||
DVBFE_ALGO_SW = (1 << 1),
|
||||
DVBFE_ALGO_CUSTOM = (1 << 2),
|
||||
DVBFE_ALGO_RECOVERY = (1 << 31)
|
||||
};
|
||||
|
||||
struct tuner_state {
|
||||
u32 frequency;
|
||||
u32 tunerstep;
|
||||
u32 ifreq;
|
||||
u32 bandwidth;
|
||||
u32 iqsense;
|
||||
u32 refclock;
|
||||
};
|
||||
|
||||
/*
|
||||
* search callback possible return status
|
||||
*
|
||||
* DVBFE_ALGO_SEARCH_SUCCESS
|
||||
* The frontend search algorithm completed and returned successfully
|
||||
*
|
||||
* DVBFE_ALGO_SEARCH_ASLEEP
|
||||
* The frontend search algorithm is sleeping
|
||||
*
|
||||
* DVBFE_ALGO_SEARCH_FAILED
|
||||
* The frontend search for a signal failed
|
||||
*
|
||||
* DVBFE_ALGO_SEARCH_INVALID
|
||||
* The frontend search algorith was probably supplied with invalid
|
||||
* parameters and the search is an invalid one
|
||||
*
|
||||
* DVBFE_ALGO_SEARCH_ERROR
|
||||
* The frontend search algorithm failed due to some error
|
||||
*
|
||||
* DVBFE_ALGO_SEARCH_AGAIN
|
||||
* The frontend search algorithm was requested to search again
|
||||
*/
|
||||
enum dvbfe_search {
|
||||
DVBFE_ALGO_SEARCH_SUCCESS = (1 << 0),
|
||||
DVBFE_ALGO_SEARCH_ASLEEP = (1 << 1),
|
||||
DVBFE_ALGO_SEARCH_FAILED = (1 << 2),
|
||||
DVBFE_ALGO_SEARCH_INVALID = (1 << 3),
|
||||
DVBFE_ALGO_SEARCH_AGAIN = (1 << 4),
|
||||
DVBFE_ALGO_SEARCH_ERROR = (1 << 31),
|
||||
};
|
||||
|
||||
|
||||
struct dvb_tuner_ops {
|
||||
|
||||
struct dvb_tuner_info info;
|
||||
|
||||
int (*release)(struct dvb_frontend *fe);
|
||||
int (*init)(struct dvb_frontend *fe);
|
||||
int (*sleep)(struct dvb_frontend *fe);
|
||||
|
||||
/** This is for simple PLLs - set all parameters in one go. */
|
||||
int (*set_params)(struct dvb_frontend *fe);
|
||||
int (*set_analog_params)(struct dvb_frontend *fe, struct analog_parameters *p);
|
||||
|
||||
/** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
|
||||
int (*calc_regs)(struct dvb_frontend *fe, u8 *buf, int buf_len);
|
||||
|
||||
/** This is to allow setting tuner-specific configs */
|
||||
int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
|
||||
|
||||
int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency);
|
||||
int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
|
||||
int (*get_if_frequency)(struct dvb_frontend *fe, u32 *frequency);
|
||||
|
||||
#define TUNER_STATUS_LOCKED 1
|
||||
#define TUNER_STATUS_STEREO 2
|
||||
int (*get_status)(struct dvb_frontend *fe, u32 *status);
|
||||
int (*get_rf_strength)(struct dvb_frontend *fe, u16 *strength);
|
||||
int (*get_afc)(struct dvb_frontend *fe, s32 *afc);
|
||||
|
||||
/** These are provided separately from set_params in order to facilitate silicon
|
||||
* tuners which require sophisticated tuning loops, controlling each parameter separately. */
|
||||
int (*set_frequency)(struct dvb_frontend *fe, u32 frequency);
|
||||
int (*set_bandwidth)(struct dvb_frontend *fe, u32 bandwidth);
|
||||
|
||||
/*
|
||||
* These are provided separately from set_params in order to facilitate silicon
|
||||
* tuners which require sophisticated tuning loops, controlling each parameter separately.
|
||||
*/
|
||||
int (*set_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
|
||||
int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state);
|
||||
};
|
||||
|
||||
struct analog_demod_info {
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct analog_demod_ops {
|
||||
|
||||
struct analog_demod_info info;
|
||||
|
||||
void (*set_params)(struct dvb_frontend *fe,
|
||||
struct analog_parameters *params);
|
||||
int (*has_signal)(struct dvb_frontend *fe, u16 *signal);
|
||||
int (*get_afc)(struct dvb_frontend *fe, s32 *afc);
|
||||
void (*tuner_status)(struct dvb_frontend *fe);
|
||||
void (*standby)(struct dvb_frontend *fe);
|
||||
void (*release)(struct dvb_frontend *fe);
|
||||
int (*i2c_gate_ctrl)(struct dvb_frontend *fe, int enable);
|
||||
|
||||
/** This is to allow setting tuner-specific configuration */
|
||||
int (*set_config)(struct dvb_frontend *fe, void *priv_cfg);
|
||||
};
|
||||
|
||||
struct dtv_frontend_properties;
|
||||
|
||||
struct dvb_frontend_ops {
|
||||
|
||||
struct dvb_frontend_info info;
|
||||
|
||||
u8 delsys[MAX_DELSYS];
|
||||
|
||||
void (*release)(struct dvb_frontend* fe);
|
||||
void (*release_sec)(struct dvb_frontend* fe);
|
||||
|
||||
int (*init)(struct dvb_frontend* fe);
|
||||
int (*sleep)(struct dvb_frontend* fe);
|
||||
|
||||
int (*write)(struct dvb_frontend* fe, const u8 buf[], int len);
|
||||
|
||||
/* if this is set, it overrides the default swzigzag */
|
||||
int (*tune)(struct dvb_frontend* fe,
|
||||
bool re_tune,
|
||||
unsigned int mode_flags,
|
||||
unsigned int *delay,
|
||||
fe_status_t *status);
|
||||
/* get frontend tuning algorithm from the module */
|
||||
enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe);
|
||||
|
||||
/* these two are only used for the swzigzag code */
|
||||
int (*set_frontend)(struct dvb_frontend *fe);
|
||||
int (*get_tune_settings)(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings);
|
||||
|
||||
int (*get_frontend)(struct dvb_frontend *fe);
|
||||
|
||||
int (*read_status)(struct dvb_frontend* fe, fe_status_t* status);
|
||||
int (*read_ber)(struct dvb_frontend* fe, u32* ber);
|
||||
int (*read_signal_strength)(struct dvb_frontend* fe, u16* strength);
|
||||
int (*read_snr)(struct dvb_frontend* fe, u16* snr);
|
||||
int (*read_ucblocks)(struct dvb_frontend* fe, u32* ucblocks);
|
||||
|
||||
int (*diseqc_reset_overload)(struct dvb_frontend* fe);
|
||||
int (*diseqc_send_master_cmd)(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd);
|
||||
int (*diseqc_recv_slave_reply)(struct dvb_frontend* fe, struct dvb_diseqc_slave_reply* reply);
|
||||
int (*diseqc_send_burst)(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd);
|
||||
int (*set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
|
||||
int (*set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
|
||||
int (*enable_high_lnb_voltage)(struct dvb_frontend* fe, long arg);
|
||||
int (*dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned long cmd);
|
||||
int (*i2c_gate_ctrl)(struct dvb_frontend* fe, int enable);
|
||||
int (*ts_bus_ctrl)(struct dvb_frontend* fe, int acquire);
|
||||
int (*set_lna)(struct dvb_frontend *);
|
||||
int (*set_input)(struct dvb_frontend *, int);
|
||||
|
||||
/* These callbacks are for devices that implement their own
|
||||
* tuning algorithms, rather than a simple swzigzag
|
||||
*/
|
||||
enum dvbfe_search (*search)(struct dvb_frontend *fe);
|
||||
|
||||
struct dvb_tuner_ops tuner_ops;
|
||||
struct analog_demod_ops analog_ops;
|
||||
|
||||
int (*set_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
|
||||
int (*get_property)(struct dvb_frontend* fe, struct dtv_property* tvp);
|
||||
|
||||
u8 xbar[3];
|
||||
};
|
||||
|
||||
#ifdef __DVB_CORE__
|
||||
#define MAX_EVENT 8
|
||||
|
||||
struct dvb_fe_events {
|
||||
struct dvb_frontend_event events[MAX_EVENT];
|
||||
int eventw;
|
||||
int eventr;
|
||||
int overflow;
|
||||
wait_queue_head_t wait_queue;
|
||||
struct mutex mtx;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct dtv_frontend_properties {
|
||||
|
||||
/* Cache State */
|
||||
u32 state;
|
||||
|
||||
u32 frequency;
|
||||
fe_modulation_t modulation;
|
||||
|
||||
fe_sec_voltage_t voltage;
|
||||
fe_sec_tone_mode_t sectone;
|
||||
fe_spectral_inversion_t inversion;
|
||||
fe_code_rate_t fec_inner;
|
||||
fe_transmit_mode_t transmission_mode;
|
||||
u32 bandwidth_hz; /* 0 = AUTO */
|
||||
fe_guard_interval_t guard_interval;
|
||||
fe_hierarchy_t hierarchy;
|
||||
u32 symbol_rate;
|
||||
fe_code_rate_t code_rate_HP;
|
||||
fe_code_rate_t code_rate_LP;
|
||||
|
||||
fe_pilot_t pilot;
|
||||
fe_rolloff_t rolloff;
|
||||
|
||||
fe_delivery_system_t delivery_system;
|
||||
|
||||
enum fe_interleaving interleaving;
|
||||
|
||||
/* ISDB-T specifics */
|
||||
u8 isdbt_partial_reception;
|
||||
u8 isdbt_sb_mode;
|
||||
u8 isdbt_sb_subchannel;
|
||||
u32 isdbt_sb_segment_idx;
|
||||
u32 isdbt_sb_segment_count;
|
||||
u8 isdbt_layer_enabled;
|
||||
struct {
|
||||
u8 segment_count;
|
||||
fe_code_rate_t fec;
|
||||
fe_modulation_t modulation;
|
||||
u8 interleaving;
|
||||
} layer[3];
|
||||
|
||||
/* Multistream specifics */
|
||||
u32 stream_id;
|
||||
|
||||
/* ATSC-MH specifics */
|
||||
u8 atscmh_fic_ver;
|
||||
u8 atscmh_parade_id;
|
||||
u8 atscmh_nog;
|
||||
u8 atscmh_tnog;
|
||||
u8 atscmh_sgn;
|
||||
u8 atscmh_prc;
|
||||
|
||||
u8 atscmh_rs_frame_mode;
|
||||
u8 atscmh_rs_frame_ensemble;
|
||||
u8 atscmh_rs_code_mode_pri;
|
||||
u8 atscmh_rs_code_mode_sec;
|
||||
u8 atscmh_sccc_block_mode;
|
||||
u8 atscmh_sccc_code_mode_a;
|
||||
u8 atscmh_sccc_code_mode_b;
|
||||
u8 atscmh_sccc_code_mode_c;
|
||||
u8 atscmh_sccc_code_mode_d;
|
||||
|
||||
u32 lna;
|
||||
s32 input;
|
||||
|
||||
/* statistics data */
|
||||
struct dtv_fe_stats strength;
|
||||
struct dtv_fe_stats cnr;
|
||||
struct dtv_fe_stats pre_bit_error;
|
||||
struct dtv_fe_stats pre_bit_count;
|
||||
struct dtv_fe_stats post_bit_error;
|
||||
struct dtv_fe_stats post_bit_count;
|
||||
struct dtv_fe_stats block_error;
|
||||
struct dtv_fe_stats block_count;
|
||||
};
|
||||
|
||||
struct dvb_frontend {
|
||||
struct dvb_frontend_ops ops;
|
||||
struct dvb_adapter *dvb;
|
||||
void *demodulator_priv;
|
||||
void *tuner_priv;
|
||||
void *frontend_priv;
|
||||
void *sec_priv;
|
||||
void *analog_demod_priv;
|
||||
struct dtv_frontend_properties dtv_property_cache;
|
||||
#define DVB_FRONTEND_COMPONENT_TUNER 0
|
||||
#define DVB_FRONTEND_COMPONENT_DEMOD 1
|
||||
int (*callback)(void *adapter_priv, int component, int cmd, int arg);
|
||||
int id;
|
||||
};
|
||||
|
||||
extern int dvb_register_frontend(struct dvb_adapter *dvb,
|
||||
struct dvb_frontend *fe);
|
||||
|
||||
extern int dvb_unregister_frontend(struct dvb_frontend *fe);
|
||||
|
||||
extern void dvb_frontend_detach(struct dvb_frontend *fe);
|
||||
|
||||
extern void dvb_frontend_reinitialise(struct dvb_frontend *fe);
|
||||
extern int dvb_frontend_suspend(struct dvb_frontend *fe);
|
||||
extern int dvb_frontend_resume(struct dvb_frontend *fe);
|
||||
|
||||
extern void dvb_frontend_sleep_until(struct timeval *waketime, u32 add_usec);
|
||||
extern s32 timeval_usec_diff(struct timeval lasttime, struct timeval curtime);
|
||||
|
||||
#endif
|
145
dvb-core/dvb_math.c
Normal file
145
dvb-core/dvb_math.c
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* dvb-math provides some complex fixed-point math
|
||||
* operations shared between the dvb related stuff
|
||||
*
|
||||
* Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
|
||||
*
|
||||
* This library 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/bug.h>
|
||||
#include "dvb_math.h"
|
||||
|
||||
static const unsigned short logtable[256] = {
|
||||
0x0000, 0x0171, 0x02e0, 0x044e, 0x05ba, 0x0725, 0x088e, 0x09f7,
|
||||
0x0b5d, 0x0cc3, 0x0e27, 0x0f8a, 0x10eb, 0x124b, 0x13aa, 0x1508,
|
||||
0x1664, 0x17bf, 0x1919, 0x1a71, 0x1bc8, 0x1d1e, 0x1e73, 0x1fc6,
|
||||
0x2119, 0x226a, 0x23ba, 0x2508, 0x2656, 0x27a2, 0x28ed, 0x2a37,
|
||||
0x2b80, 0x2cc8, 0x2e0f, 0x2f54, 0x3098, 0x31dc, 0x331e, 0x345f,
|
||||
0x359f, 0x36de, 0x381b, 0x3958, 0x3a94, 0x3bce, 0x3d08, 0x3e41,
|
||||
0x3f78, 0x40af, 0x41e4, 0x4319, 0x444c, 0x457f, 0x46b0, 0x47e1,
|
||||
0x4910, 0x4a3f, 0x4b6c, 0x4c99, 0x4dc5, 0x4eef, 0x5019, 0x5142,
|
||||
0x526a, 0x5391, 0x54b7, 0x55dc, 0x5700, 0x5824, 0x5946, 0x5a68,
|
||||
0x5b89, 0x5ca8, 0x5dc7, 0x5ee5, 0x6003, 0x611f, 0x623a, 0x6355,
|
||||
0x646f, 0x6588, 0x66a0, 0x67b7, 0x68ce, 0x69e4, 0x6af8, 0x6c0c,
|
||||
0x6d20, 0x6e32, 0x6f44, 0x7055, 0x7165, 0x7274, 0x7383, 0x7490,
|
||||
0x759d, 0x76aa, 0x77b5, 0x78c0, 0x79ca, 0x7ad3, 0x7bdb, 0x7ce3,
|
||||
0x7dea, 0x7ef0, 0x7ff6, 0x80fb, 0x81ff, 0x8302, 0x8405, 0x8507,
|
||||
0x8608, 0x8709, 0x8809, 0x8908, 0x8a06, 0x8b04, 0x8c01, 0x8cfe,
|
||||
0x8dfa, 0x8ef5, 0x8fef, 0x90e9, 0x91e2, 0x92db, 0x93d2, 0x94ca,
|
||||
0x95c0, 0x96b6, 0x97ab, 0x98a0, 0x9994, 0x9a87, 0x9b7a, 0x9c6c,
|
||||
0x9d5e, 0x9e4f, 0x9f3f, 0xa02e, 0xa11e, 0xa20c, 0xa2fa, 0xa3e7,
|
||||
0xa4d4, 0xa5c0, 0xa6ab, 0xa796, 0xa881, 0xa96a, 0xaa53, 0xab3c,
|
||||
0xac24, 0xad0c, 0xadf2, 0xaed9, 0xafbe, 0xb0a4, 0xb188, 0xb26c,
|
||||
0xb350, 0xb433, 0xb515, 0xb5f7, 0xb6d9, 0xb7ba, 0xb89a, 0xb97a,
|
||||
0xba59, 0xbb38, 0xbc16, 0xbcf4, 0xbdd1, 0xbead, 0xbf8a, 0xc065,
|
||||
0xc140, 0xc21b, 0xc2f5, 0xc3cf, 0xc4a8, 0xc580, 0xc658, 0xc730,
|
||||
0xc807, 0xc8de, 0xc9b4, 0xca8a, 0xcb5f, 0xcc34, 0xcd08, 0xcddc,
|
||||
0xceaf, 0xcf82, 0xd054, 0xd126, 0xd1f7, 0xd2c8, 0xd399, 0xd469,
|
||||
0xd538, 0xd607, 0xd6d6, 0xd7a4, 0xd872, 0xd93f, 0xda0c, 0xdad9,
|
||||
0xdba5, 0xdc70, 0xdd3b, 0xde06, 0xded0, 0xdf9a, 0xe063, 0xe12c,
|
||||
0xe1f5, 0xe2bd, 0xe385, 0xe44c, 0xe513, 0xe5d9, 0xe69f, 0xe765,
|
||||
0xe82a, 0xe8ef, 0xe9b3, 0xea77, 0xeb3b, 0xebfe, 0xecc1, 0xed83,
|
||||
0xee45, 0xef06, 0xefc8, 0xf088, 0xf149, 0xf209, 0xf2c8, 0xf387,
|
||||
0xf446, 0xf505, 0xf5c3, 0xf680, 0xf73e, 0xf7fb, 0xf8b7, 0xf973,
|
||||
0xfa2f, 0xfaea, 0xfba5, 0xfc60, 0xfd1a, 0xfdd4, 0xfe8e, 0xff47
|
||||
};
|
||||
|
||||
unsigned int intlog2(u32 value)
|
||||
{
|
||||
/**
|
||||
* returns: log2(value) * 2^24
|
||||
* wrong result if value = 0 (log2(0) is undefined)
|
||||
*/
|
||||
unsigned int msb;
|
||||
unsigned int logentry;
|
||||
unsigned int significand;
|
||||
unsigned int interpolation;
|
||||
|
||||
if (unlikely(value == 0)) {
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* first detect the msb (count begins at 0) */
|
||||
msb = fls(value) - 1;
|
||||
|
||||
/**
|
||||
* now we use a logtable after the following method:
|
||||
*
|
||||
* log2(2^x * y) * 2^24 = x * 2^24 + log2(y) * 2^24
|
||||
* where x = msb and therefore 1 <= y < 2
|
||||
* first y is determined by shifting the value left
|
||||
* so that msb is bit 31
|
||||
* 0x00231f56 -> 0x8C7D5800
|
||||
* the result is y * 2^31 -> "significand"
|
||||
* then the highest 9 bits are used for a table lookup
|
||||
* the highest bit is discarded because it's always set
|
||||
* the highest nine bits in our example are 100011000
|
||||
* so we would use the entry 0x18
|
||||
*/
|
||||
significand = value << (31 - msb);
|
||||
logentry = (significand >> 23) & 0xff;
|
||||
|
||||
/**
|
||||
* last step we do is interpolation because of the
|
||||
* limitations of the log table the error is that part of
|
||||
* the significand which isn't used for lookup then we
|
||||
* compute the ratio between the error and the next table entry
|
||||
* and interpolate it between the log table entry used and the
|
||||
* next one the biggest error possible is 0x7fffff
|
||||
* (in our example it's 0x7D5800)
|
||||
* needed value for next table entry is 0x800000
|
||||
* so the interpolation is
|
||||
* (error / 0x800000) * (logtable_next - logtable_current)
|
||||
* in the implementation the division is moved to the end for
|
||||
* better accuracy there is also an overflow correction if
|
||||
* logtable_next is 256
|
||||
*/
|
||||
interpolation = ((significand & 0x7fffff) *
|
||||
((logtable[(logentry + 1) & 0xff] -
|
||||
logtable[logentry]) & 0xffff)) >> 15;
|
||||
|
||||
/* now we return the result */
|
||||
return ((msb << 24) + (logtable[logentry] << 8) + interpolation);
|
||||
}
|
||||
EXPORT_SYMBOL(intlog2);
|
||||
|
||||
unsigned int intlog10(u32 value)
|
||||
{
|
||||
/**
|
||||
* returns: log10(value) * 2^24
|
||||
* wrong result if value = 0 (log10(0) is undefined)
|
||||
*/
|
||||
u64 log;
|
||||
|
||||
if (unlikely(value == 0)) {
|
||||
WARN_ON(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log = intlog2(value);
|
||||
|
||||
/**
|
||||
* we use the following method:
|
||||
* log10(x) = log2(x) * log10(2)
|
||||
*/
|
||||
|
||||
return (log * 646456993) >> 31;
|
||||
}
|
||||
EXPORT_SYMBOL(intlog10);
|
58
dvb-core/dvb_math.h
Normal file
58
dvb-core/dvb_math.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* dvb-math provides some complex fixed-point math
|
||||
* operations shared between the dvb related stuff
|
||||
*
|
||||
* Copyright (C) 2006 Christoph Pfister (christophpfister@gmail.com)
|
||||
*
|
||||
* This library 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef __DVB_MATH_H
|
||||
#define __DVB_MATH_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/**
|
||||
* computes log2 of a value; the result is shifted left by 24 bits
|
||||
*
|
||||
* to use rational values you can use the following method:
|
||||
* intlog2(value) = intlog2(value * 2^x) - x * 2^24
|
||||
*
|
||||
* example: intlog2(8) will give 3 << 24 = 3 * 2^24
|
||||
* example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24
|
||||
* example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24
|
||||
*
|
||||
* @param value The value (must be != 0)
|
||||
* @return log2(value) * 2^24
|
||||
*/
|
||||
extern unsigned int intlog2(u32 value);
|
||||
|
||||
/**
|
||||
* computes log10 of a value; the result is shifted left by 24 bits
|
||||
*
|
||||
* to use rational values you can use the following method:
|
||||
* intlog10(value) = intlog10(value * 10^x) - x * 2^24
|
||||
*
|
||||
* example: intlog10(1000) will give 3 << 24 = 3 * 2^24
|
||||
* due to the implementation intlog10(1000) might be not exactly 3 * 2^24
|
||||
*
|
||||
* look at intlog2 for similar examples
|
||||
*
|
||||
* @param value The value (must be != 0)
|
||||
* @return log10(value) * 2^24
|
||||
*/
|
||||
extern unsigned int intlog10(u32 value);
|
||||
|
||||
#endif
|
1547
dvb-core/dvb_net.c
Normal file
1547
dvb-core/dvb_net.c
Normal file
File diff suppressed because it is too large
Load Diff
67
dvb-core/dvb_net.h
Normal file
67
dvb-core/dvb_net.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* dvb_net.h
|
||||
*
|
||||
* Copyright (C) 2001 Ralph 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.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _DVB_NET_H_
|
||||
#define _DVB_NET_H_
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/inetdevice.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include "dvbdev.h"
|
||||
|
||||
#define DVB_NET_DEVICES_MAX 10
|
||||
|
||||
#ifdef CONFIG_DVB_NET
|
||||
|
||||
struct dvb_net {
|
||||
struct dvb_device *dvbdev;
|
||||
struct net_device *device[DVB_NET_DEVICES_MAX];
|
||||
int state[DVB_NET_DEVICES_MAX];
|
||||
unsigned int exit:1;
|
||||
struct dmx_demux *demux;
|
||||
struct mutex ioctl_mutex;
|
||||
};
|
||||
|
||||
void dvb_net_release(struct dvb_net *);
|
||||
int dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *);
|
||||
|
||||
#else
|
||||
|
||||
struct dvb_net {
|
||||
struct dvb_device *dvbdev;
|
||||
};
|
||||
|
||||
static inline void dvb_net_release(struct dvb_net *dvbnet)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int dvb_net_init(struct dvb_adapter *adap,
|
||||
struct dvb_net *dvbnet, struct dmx_demux *dmx)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ifdef CONFIG_DVB_NET */
|
||||
|
||||
#endif
|
259
dvb-core/dvb_netstream.c
Normal file
259
dvb-core/dvb_netstream.c
Normal file
@ -0,0 +1,259 @@
|
||||
/*
|
||||
* dvb_netstream.c: support for DVB to network streaming hardware
|
||||
*
|
||||
* Copyright (C) 2012-2013 Marcus and Ralph Metzler
|
||||
* for 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 <linux/net.h>
|
||||
#include "dvb_netstream.h"
|
||||
|
||||
static ssize_t ns_write(struct file *file, const char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
pr_info("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t ns_read(struct file *file, char *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
pr_info("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int ns_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
pr_info("%s\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ns_stop(struct dvbnss *nss)
|
||||
{
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
|
||||
mutex_lock(&ns->mutex);
|
||||
if (nss->running && ns->stop) {
|
||||
ns->stop(nss);
|
||||
nss->running = 0;
|
||||
}
|
||||
mutex_unlock(&ns->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ns_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct dvbnss *nss = file->private_data;
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
|
||||
ns_stop(nss);
|
||||
if (ns->free)
|
||||
ns->free(nss);
|
||||
mutex_lock(&ns->mutex);
|
||||
list_del(&nss->nssl);
|
||||
mutex_unlock(&ns->mutex);
|
||||
vfree(nss);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ns_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
struct dvb_netstream *ns = dvbdev->priv;
|
||||
struct dvbnss *nss;
|
||||
|
||||
nss = vmalloc(sizeof(*nss));
|
||||
if (!nss)
|
||||
return -ENOMEM;
|
||||
nss->ns = ns;
|
||||
if (ns->alloc && ns->alloc(nss) < 0) {
|
||||
vfree(nss);
|
||||
return -EBUSY;
|
||||
}
|
||||
file->private_data = nss;
|
||||
nss->running = 0;
|
||||
mutex_lock(&ns->mutex);
|
||||
list_add(&nss->nssl, &ns->nssl);
|
||||
mutex_unlock(&ns->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_net(struct dvbnss *nss, struct dvb_ns_params *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_ioctl(struct file *file, unsigned int cmd, void *parg)
|
||||
{
|
||||
struct dvbnss *nss = file->private_data;
|
||||
struct dvb_netstream *ns = nss->ns;
|
||||
/*unsigned long arg = (unsigned long) parg;*/
|
||||
int ret = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case NS_SET_RTCP_MSG:
|
||||
{
|
||||
struct dvb_ns_rtcp *rtcpm = parg;
|
||||
|
||||
if (ns->set_rtcp_msg)
|
||||
ret = ns->set_rtcp_msg(nss, rtcpm->msg, rtcpm->len);
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_SET_NET:
|
||||
memcpy(&nss->params, parg, sizeof(nss->params));
|
||||
if (ns->set_net)
|
||||
ret = ns->set_net(nss);
|
||||
else
|
||||
ret = set_net(nss, (struct dvb_ns_params *) parg);
|
||||
break;
|
||||
|
||||
case NS_START:
|
||||
mutex_lock(&ns->mutex);
|
||||
if (nss->running) {
|
||||
ret = -EBUSY;
|
||||
} else if (ns->start) {
|
||||
ret = ns->start(nss);
|
||||
nss->running = 1;
|
||||
}
|
||||
mutex_unlock(&ns->mutex);
|
||||
break;
|
||||
|
||||
case NS_STOP:
|
||||
ns_stop(nss);
|
||||
break;
|
||||
|
||||
case NS_SET_PACKETS:
|
||||
{
|
||||
struct dvb_ns_packet *packet = parg;
|
||||
|
||||
if (ns->set_ts_packets)
|
||||
ret = ns->set_ts_packets(nss, packet->buf,
|
||||
packet->count * 188);
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_INSERT_PACKETS:
|
||||
{
|
||||
u8 count = *(u8 *) parg;
|
||||
|
||||
if (ns->insert_ts_packets)
|
||||
ret = ns->insert_ts_packets(nss, count);
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_SET_PID:
|
||||
{
|
||||
u16 pid = *(u16 *) parg;
|
||||
u16 byte = (pid & 0x1fff) >> 3;
|
||||
u8 bit = 1 << (pid & 7);
|
||||
|
||||
if (pid & 0x2000) {
|
||||
if (pid & 0x8000)
|
||||
memset(nss->pids, 0xff, 0x400);
|
||||
else
|
||||
memset(nss->pids, 0x00, 0x400);
|
||||
} else {
|
||||
if (pid & 0x8000)
|
||||
nss->pids[byte] |= bit;
|
||||
else
|
||||
nss->pids[byte] &= ~bit;
|
||||
}
|
||||
if (ns->set_pid)
|
||||
ret = ns->set_pid(nss, pid);
|
||||
break;
|
||||
}
|
||||
|
||||
case NS_SET_PIDS:
|
||||
ret = copy_from_user(nss->pids, *(u8 **) parg, 0x400);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ns->set_pids)
|
||||
ret = ns->set_pids(nss);
|
||||
break;
|
||||
|
||||
case NS_SET_CI:
|
||||
{
|
||||
u8 ci = *(u8 *) parg;
|
||||
|
||||
if (nss->running)
|
||||
ret = -EBUSY;
|
||||
else if (ns->set_ci)
|
||||
ret = ns->set_ci(nss, ci);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static long ns_ioctl(struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
return dvb_usercopy(file, cmd, arg, do_ioctl);
|
||||
}
|
||||
|
||||
static const struct file_operations ns_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.read = ns_read,
|
||||
.write = ns_write,
|
||||
.open = ns_open,
|
||||
.release = ns_release,
|
||||
.poll = ns_poll,
|
||||
.mmap = 0,
|
||||
.unlocked_ioctl = ns_ioctl,
|
||||
};
|
||||
|
||||
static struct dvb_device ns_dev = {
|
||||
.priv = 0,
|
||||
.readers = 1,
|
||||
.writers = 1,
|
||||
.users = 1,
|
||||
.fops = &ns_fops,
|
||||
};
|
||||
|
||||
|
||||
int dvb_netstream_init(struct dvb_adapter *dvb_adapter,
|
||||
struct dvb_netstream *ns)
|
||||
{
|
||||
mutex_init(&ns->mutex);
|
||||
spin_lock_init(&ns->lock);
|
||||
ns->exit = 0;
|
||||
dvb_register_device(dvb_adapter, &ns->dvbdev, &ns_dev, ns,
|
||||
DVB_DEVICE_NS);
|
||||
INIT_LIST_HEAD(&ns->nssl);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_netstream_init);
|
||||
|
||||
void dvb_netstream_release(struct dvb_netstream *ns)
|
||||
{
|
||||
ns->exit = 1;
|
||||
if (ns->dvbdev->users > 1) {
|
||||
wait_event(ns->dvbdev->wait_queue,
|
||||
ns->dvbdev->users == 1);
|
||||
}
|
||||
dvb_unregister_device(ns->dvbdev);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_netstream_release);
|
93
dvb-core/dvb_netstream.h
Normal file
93
dvb-core/dvb_netstream.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* dvb_netstream.c: support for DVB to network streaming hardware
|
||||
*
|
||||
* Copyright (C) 2012-2013 Marcus and Ralph Metzler
|
||||
* for 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
|
||||
*/
|
||||
|
||||
#ifndef _DVB_NETSTREAM_H_
|
||||
#define _DVB_NETSTREAM_H_
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/in.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/dvb/ns.h>
|
||||
|
||||
#include "dvbdev.h"
|
||||
|
||||
#define DVBNS_MAXPIDS 32
|
||||
|
||||
struct dvbnss {
|
||||
struct dvb_netstream *ns;
|
||||
void *priv;
|
||||
|
||||
u8 pids[1024];
|
||||
u8 packet[1328];
|
||||
u32 pp;
|
||||
|
||||
struct socket *sock;
|
||||
struct sockaddr_in sadr;
|
||||
u32 sn;
|
||||
|
||||
struct dvb_ns_params params;
|
||||
|
||||
struct list_head nssl;
|
||||
int running;
|
||||
};
|
||||
|
||||
#define MAX_DVBNSS 32
|
||||
|
||||
struct dvb_netstream {
|
||||
void *priv;
|
||||
|
||||
struct mutex mutex;
|
||||
spinlock_t lock;
|
||||
struct dvb_device *dvbdev;
|
||||
int exit;
|
||||
|
||||
struct list_head nssl;
|
||||
|
||||
int (*set_net)(struct dvbnss *);
|
||||
int (*set_pid)(struct dvbnss *, u16);
|
||||
int (*set_pids)(struct dvbnss *);
|
||||
int (*set_ci)(struct dvbnss *, u8);
|
||||
int (*set_rtcp_msg)(struct dvbnss *, u8 *, u32);
|
||||
int (*set_ts_packets)(struct dvbnss *, u8 *, u32);
|
||||
int (*insert_ts_packets)(struct dvbnss *, u8);
|
||||
int (*start)(struct dvbnss *);
|
||||
int (*stop)(struct dvbnss *);
|
||||
int (*alloc)(struct dvbnss *);
|
||||
void (*free)(struct dvbnss *);
|
||||
};
|
||||
|
||||
|
||||
void dvb_netstream_release(struct dvb_netstream *);
|
||||
int dvb_netstream_init(struct dvb_adapter *, struct dvb_netstream *);
|
||||
|
||||
|
||||
#endif
|
299
dvb-core/dvb_ringbuffer.c
Normal file
299
dvb-core/dvb_ringbuffer.c
Normal file
@ -0,0 +1,299 @@
|
||||
/*
|
||||
*
|
||||
* dvb_ringbuffer.c: ring buffer implementation for the dvb driver
|
||||
*
|
||||
* Copyright (C) 2003 Oliver Endriss
|
||||
* Copyright (C) 2004 Andrew de Quincey
|
||||
*
|
||||
* based on code originally found in av7110.c & dvb_ci.c:
|
||||
* Copyright (C) 1999-2003 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 Lesser 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/string.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include "dvb_ringbuffer.h"
|
||||
|
||||
#define PKT_READY 0
|
||||
#define PKT_DISPOSED 1
|
||||
|
||||
|
||||
void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len)
|
||||
{
|
||||
rbuf->pread=rbuf->pwrite=0;
|
||||
rbuf->data=data;
|
||||
rbuf->size=len;
|
||||
rbuf->error=0;
|
||||
|
||||
init_waitqueue_head(&rbuf->queue);
|
||||
|
||||
spin_lock_init(&(rbuf->lock));
|
||||
}
|
||||
|
||||
|
||||
|
||||
int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf)
|
||||
{
|
||||
return (rbuf->pread==rbuf->pwrite);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf)
|
||||
{
|
||||
ssize_t free;
|
||||
|
||||
free = rbuf->pread - rbuf->pwrite;
|
||||
if (free <= 0)
|
||||
free += rbuf->size;
|
||||
return free-1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf)
|
||||
{
|
||||
ssize_t avail;
|
||||
|
||||
avail = rbuf->pwrite - rbuf->pread;
|
||||
if (avail < 0)
|
||||
avail += rbuf->size;
|
||||
return avail;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf)
|
||||
{
|
||||
rbuf->pread = rbuf->pwrite;
|
||||
rbuf->error = 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_flush);
|
||||
|
||||
void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf)
|
||||
{
|
||||
rbuf->pread = rbuf->pwrite = 0;
|
||||
rbuf->error = 0;
|
||||
}
|
||||
|
||||
void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&rbuf->lock, flags);
|
||||
dvb_ringbuffer_flush(rbuf);
|
||||
spin_unlock_irqrestore(&rbuf->lock, flags);
|
||||
|
||||
wake_up(&rbuf->queue);
|
||||
}
|
||||
|
||||
ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len)
|
||||
{
|
||||
size_t todo = len;
|
||||
size_t split;
|
||||
|
||||
split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
|
||||
if (split > 0) {
|
||||
if (copy_to_user(buf, rbuf->data+rbuf->pread, split))
|
||||
return -EFAULT;
|
||||
buf += split;
|
||||
todo -= split;
|
||||
rbuf->pread = 0;
|
||||
}
|
||||
if (copy_to_user(buf, rbuf->data+rbuf->pread, todo))
|
||||
return -EFAULT;
|
||||
|
||||
rbuf->pread = (rbuf->pread + todo) % rbuf->size;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, u8 *buf, size_t len)
|
||||
{
|
||||
size_t todo = len;
|
||||
size_t split;
|
||||
|
||||
split = (rbuf->pread + len > rbuf->size) ? rbuf->size - rbuf->pread : 0;
|
||||
if (split > 0) {
|
||||
memcpy(buf, rbuf->data+rbuf->pread, split);
|
||||
buf += split;
|
||||
todo -= split;
|
||||
rbuf->pread = 0;
|
||||
}
|
||||
memcpy(buf, rbuf->data+rbuf->pread, todo);
|
||||
|
||||
rbuf->pread = (rbuf->pread + todo) % rbuf->size;
|
||||
}
|
||||
|
||||
|
||||
ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len)
|
||||
{
|
||||
size_t todo = len;
|
||||
size_t split;
|
||||
|
||||
split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0;
|
||||
|
||||
if (split > 0) {
|
||||
memcpy(rbuf->data+rbuf->pwrite, buf, split);
|
||||
buf += split;
|
||||
todo -= split;
|
||||
rbuf->pwrite = 0;
|
||||
}
|
||||
memcpy(rbuf->data+rbuf->pwrite, buf, todo);
|
||||
rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len)
|
||||
{
|
||||
int status;
|
||||
ssize_t oldpwrite = rbuf->pwrite;
|
||||
|
||||
DVB_RINGBUFFER_WRITE_BYTE(rbuf, len >> 8);
|
||||
DVB_RINGBUFFER_WRITE_BYTE(rbuf, len & 0xff);
|
||||
DVB_RINGBUFFER_WRITE_BYTE(rbuf, PKT_READY);
|
||||
status = dvb_ringbuffer_write(rbuf, buf, len);
|
||||
|
||||
if (status < 0) rbuf->pwrite = oldpwrite;
|
||||
return status;
|
||||
}
|
||||
|
||||
ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
|
||||
int offset, u8 __user *buf, size_t len)
|
||||
{
|
||||
size_t todo;
|
||||
size_t split;
|
||||
size_t pktlen;
|
||||
|
||||
pktlen = rbuf->data[idx] << 8;
|
||||
pktlen |= rbuf->data[(idx + 1) % rbuf->size];
|
||||
if (offset > pktlen) return -EINVAL;
|
||||
if ((offset + len) > pktlen) len = pktlen - offset;
|
||||
|
||||
idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
|
||||
todo = len;
|
||||
split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
|
||||
if (split > 0) {
|
||||
if (copy_to_user(buf, rbuf->data+idx, split))
|
||||
return -EFAULT;
|
||||
buf += split;
|
||||
todo -= split;
|
||||
idx = 0;
|
||||
}
|
||||
if (copy_to_user(buf, rbuf->data+idx, todo))
|
||||
return -EFAULT;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
|
||||
int offset, u8* buf, size_t len)
|
||||
{
|
||||
size_t todo;
|
||||
size_t split;
|
||||
size_t pktlen;
|
||||
|
||||
pktlen = rbuf->data[idx] << 8;
|
||||
pktlen |= rbuf->data[(idx + 1) % rbuf->size];
|
||||
if (offset > pktlen) return -EINVAL;
|
||||
if ((offset + len) > pktlen) len = pktlen - offset;
|
||||
|
||||
idx = (idx + DVB_RINGBUFFER_PKTHDRSIZE + offset) % rbuf->size;
|
||||
todo = len;
|
||||
split = ((idx + len) > rbuf->size) ? rbuf->size - idx : 0;
|
||||
if (split > 0) {
|
||||
memcpy(buf, rbuf->data+idx, split);
|
||||
buf += split;
|
||||
todo -= split;
|
||||
idx = 0;
|
||||
}
|
||||
memcpy(buf, rbuf->data+idx, todo);
|
||||
return len;
|
||||
}
|
||||
|
||||
void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx)
|
||||
{
|
||||
size_t pktlen;
|
||||
|
||||
rbuf->data[(idx + 2) % rbuf->size] = PKT_DISPOSED;
|
||||
|
||||
// clean up disposed packets
|
||||
while(dvb_ringbuffer_avail(rbuf) > DVB_RINGBUFFER_PKTHDRSIZE) {
|
||||
if (DVB_RINGBUFFER_PEEK(rbuf, 2) == PKT_DISPOSED) {
|
||||
pktlen = DVB_RINGBUFFER_PEEK(rbuf, 0) << 8;
|
||||
pktlen |= DVB_RINGBUFFER_PEEK(rbuf, 1);
|
||||
DVB_RINGBUFFER_SKIP(rbuf, pktlen + DVB_RINGBUFFER_PKTHDRSIZE);
|
||||
} else {
|
||||
// first packet is not disposed, so we stop cleaning now
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen)
|
||||
{
|
||||
int consumed;
|
||||
int curpktlen;
|
||||
int curpktstatus;
|
||||
|
||||
if (idx == -1) {
|
||||
idx = rbuf->pread;
|
||||
} else {
|
||||
curpktlen = rbuf->data[idx] << 8;
|
||||
curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
|
||||
idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
|
||||
}
|
||||
|
||||
consumed = (idx - rbuf->pread) % rbuf->size;
|
||||
|
||||
while((dvb_ringbuffer_avail(rbuf) - consumed) > DVB_RINGBUFFER_PKTHDRSIZE) {
|
||||
|
||||
curpktlen = rbuf->data[idx] << 8;
|
||||
curpktlen |= rbuf->data[(idx + 1) % rbuf->size];
|
||||
curpktstatus = rbuf->data[(idx + 2) % rbuf->size];
|
||||
|
||||
if (curpktstatus == PKT_READY) {
|
||||
*pktlen = curpktlen;
|
||||
return idx;
|
||||
}
|
||||
|
||||
consumed += curpktlen + DVB_RINGBUFFER_PKTHDRSIZE;
|
||||
idx = (idx + curpktlen + DVB_RINGBUFFER_PKTHDRSIZE) % rbuf->size;
|
||||
}
|
||||
|
||||
// no packets available
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_init);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_empty);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_free);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_avail);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_read_user);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_read);
|
||||
EXPORT_SYMBOL(dvb_ringbuffer_write);
|
186
dvb-core/dvb_ringbuffer.h
Normal file
186
dvb-core/dvb_ringbuffer.h
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
*
|
||||
* dvb_ringbuffer.h: ring buffer implementation for the dvb driver
|
||||
*
|
||||
* Copyright (C) 2003 Oliver Endriss
|
||||
* Copyright (C) 2004 Andrew de Quincey
|
||||
*
|
||||
* based on code originally found in av7110.c & dvb_ci.c:
|
||||
* Copyright (C) 1999-2003 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 Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _DVB_RINGBUFFER_H_
|
||||
#define _DVB_RINGBUFFER_H_
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
struct dvb_ringbuffer {
|
||||
u8 *data;
|
||||
ssize_t size;
|
||||
ssize_t pread;
|
||||
ssize_t pwrite;
|
||||
int error;
|
||||
|
||||
wait_queue_head_t queue;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
#define DVB_RINGBUFFER_PKTHDRSIZE 3
|
||||
|
||||
|
||||
/*
|
||||
** Notes:
|
||||
** ------
|
||||
** (1) For performance reasons read and write routines don't check buffer sizes
|
||||
** and/or number of bytes free/available. This has to be done before these
|
||||
** routines are called. For example:
|
||||
**
|
||||
** *** write <buflen> bytes ***
|
||||
** free = dvb_ringbuffer_free(rbuf);
|
||||
** if (free >= buflen)
|
||||
** count = dvb_ringbuffer_write(rbuf, buffer, buflen);
|
||||
** else
|
||||
** ...
|
||||
**
|
||||
** *** read min. 1000, max. <bufsize> bytes ***
|
||||
** avail = dvb_ringbuffer_avail(rbuf);
|
||||
** if (avail >= 1000)
|
||||
** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize));
|
||||
** else
|
||||
** ...
|
||||
**
|
||||
** (2) If there is exactly one reader and one writer, there is no need
|
||||
** to lock read or write operations.
|
||||
** Two or more readers must be locked against each other.
|
||||
** Flushing the buffer counts as a read operation.
|
||||
** Resetting the buffer counts as a read and write operation.
|
||||
** Two or more writers must be locked against each other.
|
||||
*/
|
||||
|
||||
/* initialize ring buffer, lock and queue */
|
||||
extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len);
|
||||
|
||||
/* test whether buffer is empty */
|
||||
extern int dvb_ringbuffer_empty(struct dvb_ringbuffer *rbuf);
|
||||
|
||||
/* return the number of free bytes in the buffer */
|
||||
extern ssize_t dvb_ringbuffer_free(struct dvb_ringbuffer *rbuf);
|
||||
|
||||
/* return the number of bytes waiting in the buffer */
|
||||
extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf);
|
||||
|
||||
|
||||
/*
|
||||
** Reset the read and write pointers to zero and flush the buffer
|
||||
** This counts as a read and write operation
|
||||
*/
|
||||
extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf);
|
||||
|
||||
|
||||
/* read routines & macros */
|
||||
/* ---------------------- */
|
||||
/* flush buffer */
|
||||
extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf);
|
||||
|
||||
/* flush buffer protected by spinlock and wake-up waiting task(s) */
|
||||
extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf);
|
||||
|
||||
/* peek at byte <offs> in the buffer */
|
||||
#define DVB_RINGBUFFER_PEEK(rbuf,offs) \
|
||||
(rbuf)->data[((rbuf)->pread+(offs))%(rbuf)->size]
|
||||
|
||||
/* advance read ptr by <num> bytes */
|
||||
#define DVB_RINGBUFFER_SKIP(rbuf,num) \
|
||||
(rbuf)->pread=((rbuf)->pread+(num))%(rbuf)->size
|
||||
|
||||
/*
|
||||
** read <len> bytes from ring buffer into <buf>
|
||||
** <usermem> specifies whether <buf> resides in user space
|
||||
** returns number of bytes transferred or -EFAULT
|
||||
*/
|
||||
extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf,
|
||||
u8 __user *buf, size_t len);
|
||||
extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf,
|
||||
u8 *buf, size_t len);
|
||||
|
||||
|
||||
/* write routines & macros */
|
||||
/* ----------------------- */
|
||||
/* write single byte to ring buffer */
|
||||
#define DVB_RINGBUFFER_WRITE_BYTE(rbuf,byte) \
|
||||
{ (rbuf)->data[(rbuf)->pwrite]=(byte); \
|
||||
(rbuf)->pwrite=((rbuf)->pwrite+1)%(rbuf)->size; }
|
||||
/*
|
||||
** write <len> bytes to ring buffer
|
||||
** <usermem> specifies whether <buf> resides in user space
|
||||
** returns number of bytes transferred or -EFAULT
|
||||
*/
|
||||
extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf,
|
||||
size_t len);
|
||||
|
||||
|
||||
/**
|
||||
* Write a packet into the ringbuffer.
|
||||
*
|
||||
* <rbuf> Ringbuffer to write to.
|
||||
* <buf> Buffer to write.
|
||||
* <len> Length of buffer (currently limited to 65535 bytes max).
|
||||
* returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL.
|
||||
*/
|
||||
extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this
|
||||
* does NOT update the read pointer in the ringbuffer. You must use
|
||||
* dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required.
|
||||
*
|
||||
* <rbuf> Ringbuffer concerned.
|
||||
* <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
|
||||
* <offset> Offset into packet to read from.
|
||||
* <buf> Destination buffer for data.
|
||||
* <len> Size of destination buffer.
|
||||
* <usermem> Set to 1 if <buf> is in userspace.
|
||||
* returns Number of bytes read, or -EFAULT.
|
||||
*/
|
||||
extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx,
|
||||
int offset, u8 __user *buf, size_t len);
|
||||
extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx,
|
||||
int offset, u8 *buf, size_t len);
|
||||
|
||||
/**
|
||||
* Dispose of a packet in the ring buffer.
|
||||
*
|
||||
* <rbuf> Ring buffer concerned.
|
||||
* <idx> Packet index as returned by dvb_ringbuffer_pkt_next().
|
||||
*/
|
||||
extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx);
|
||||
|
||||
/**
|
||||
* Get the index of the next packet in a ringbuffer.
|
||||
*
|
||||
* <rbuf> Ringbuffer concerned.
|
||||
* <idx> Previous packet index, or -1 to return the first packet index.
|
||||
* <pktlen> On success, will be updated to contain the length of the packet in bytes.
|
||||
* returns Packet index (if >=0), or -1 if no packets available.
|
||||
*/
|
||||
extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen);
|
||||
|
||||
|
||||
#endif /* _DVB_RINGBUFFER_H_ */
|
514
dvb-core/dvbdev.c
Normal file
514
dvb-core/dvbdev.c
Normal file
@ -0,0 +1,514 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/version.h>
|
||||
#include "dvbdev.h"
|
||||
|
||||
static DEFINE_MUTEX(dvbdev_mutex);
|
||||
static int dvbdev_debug;
|
||||
|
||||
module_param(dvbdev_debug, int, 0644);
|
||||
MODULE_PARM_DESC(dvbdev_debug, "Turn on/off device debugging (default:off).");
|
||||
|
||||
#define dprintk if (dvbdev_debug) printk
|
||||
|
||||
static LIST_HEAD(dvb_adapter_list);
|
||||
static DEFINE_MUTEX(dvbdev_register_lock);
|
||||
|
||||
static const char * const dnames[] = {
|
||||
"video", "audio", "sec", "frontend", "demux", "dvr", "ca",
|
||||
"net", "osd", "ci", "mod", "ns", "nsd"
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DVB_DYNAMIC_MINORS
|
||||
#define MAX_DVB_MINORS 256
|
||||
#define DVB_MAX_IDS MAX_DVB_MINORS
|
||||
#else
|
||||
#define DVB_MAX_IDS 4
|
||||
#define nums2minor(num,type,id) ((num << 6) | (id << 4) | type)
|
||||
#define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64)
|
||||
#endif
|
||||
|
||||
static struct class *dvb_class;
|
||||
|
||||
static struct dvb_device *dvb_minors[MAX_DVB_MINORS];
|
||||
static DECLARE_RWSEM(minor_rwsem);
|
||||
|
||||
static int dvb_device_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct dvb_device *dvbdev;
|
||||
|
||||
mutex_lock(&dvbdev_mutex);
|
||||
down_read(&minor_rwsem);
|
||||
dvbdev = dvb_minors[iminor(inode)];
|
||||
|
||||
if (dvbdev && dvbdev->fops) {
|
||||
int err = 0;
|
||||
const struct file_operations *old_fops;
|
||||
|
||||
file->private_data = dvbdev;
|
||||
old_fops = file->f_op;
|
||||
file->f_op = fops_get(dvbdev->fops);
|
||||
if (file->f_op == NULL) {
|
||||
file->f_op = old_fops;
|
||||
goto fail;
|
||||
}
|
||||
if(file->f_op->open)
|
||||
err = file->f_op->open(inode,file);
|
||||
if (err) {
|
||||
fops_put(file->f_op);
|
||||
file->f_op = fops_get(old_fops);
|
||||
}
|
||||
fops_put(old_fops);
|
||||
up_read(&minor_rwsem);
|
||||
mutex_unlock(&dvbdev_mutex);
|
||||
return err;
|
||||
}
|
||||
fail:
|
||||
up_read(&minor_rwsem);
|
||||
mutex_unlock(&dvbdev_mutex);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
||||
static const struct file_operations dvb_device_fops =
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
.open = dvb_device_open,
|
||||
.llseek = noop_llseek,
|
||||
};
|
||||
|
||||
static struct cdev dvb_device_cdev;
|
||||
|
||||
int dvb_generic_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
|
||||
if (!dvbdev)
|
||||
return -ENODEV;
|
||||
|
||||
if (!dvbdev->users)
|
||||
return -EBUSY;
|
||||
|
||||
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
|
||||
if (!dvbdev->readers)
|
||||
return -EBUSY;
|
||||
dvbdev->readers--;
|
||||
} else {
|
||||
if (!dvbdev->writers)
|
||||
return -EBUSY;
|
||||
dvbdev->writers--;
|
||||
}
|
||||
|
||||
dvbdev->users--;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_generic_open);
|
||||
|
||||
|
||||
int dvb_generic_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
|
||||
if (!dvbdev)
|
||||
return -ENODEV;
|
||||
|
||||
if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
|
||||
dvbdev->readers++;
|
||||
} else {
|
||||
dvbdev->writers++;
|
||||
}
|
||||
|
||||
dvbdev->users++;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_generic_release);
|
||||
|
||||
|
||||
long dvb_generic_ioctl(struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct dvb_device *dvbdev = file->private_data;
|
||||
|
||||
if (!dvbdev)
|
||||
return -ENODEV;
|
||||
|
||||
if (!dvbdev->kernel_ioctl)
|
||||
return -EINVAL;
|
||||
|
||||
return dvb_usercopy(file, cmd, arg, dvbdev->kernel_ioctl);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_generic_ioctl);
|
||||
|
||||
|
||||
static int dvbdev_get_free_id (struct dvb_adapter *adap, int type)
|
||||
{
|
||||
u32 id = 0;
|
||||
|
||||
while (id < DVB_MAX_IDS) {
|
||||
struct dvb_device *dev;
|
||||
list_for_each_entry(dev, &adap->device_list, list_head)
|
||||
if (dev->type == type && dev->id == id)
|
||||
goto skip;
|
||||
return id;
|
||||
skip:
|
||||
id++;
|
||||
}
|
||||
return -ENFILE;
|
||||
}
|
||||
|
||||
|
||||
int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
|
||||
const struct dvb_device *template, void *priv, int type)
|
||||
{
|
||||
struct dvb_device *dvbdev;
|
||||
struct file_operations *dvbdevfops;
|
||||
struct device *clsdev;
|
||||
int minor;
|
||||
int id;
|
||||
|
||||
mutex_lock(&dvbdev_register_lock);
|
||||
|
||||
if ((id = dvbdev_get_free_id (adap, type)) < 0){
|
||||
mutex_unlock(&dvbdev_register_lock);
|
||||
*pdvbdev = NULL;
|
||||
printk(KERN_ERR "%s: couldn't find free device id\n", __func__);
|
||||
return -ENFILE;
|
||||
}
|
||||
|
||||
*pdvbdev = dvbdev = kmalloc(sizeof(struct dvb_device), GFP_KERNEL);
|
||||
|
||||
if (!dvbdev){
|
||||
mutex_unlock(&dvbdev_register_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dvbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
|
||||
|
||||
if (!dvbdevfops){
|
||||
kfree (dvbdev);
|
||||
mutex_unlock(&dvbdev_register_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(dvbdev, template, sizeof(struct dvb_device));
|
||||
dvbdev->type = type;
|
||||
dvbdev->id = id;
|
||||
dvbdev->adapter = adap;
|
||||
dvbdev->priv = priv;
|
||||
dvbdev->fops = dvbdevfops;
|
||||
init_waitqueue_head (&dvbdev->wait_queue);
|
||||
|
||||
memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
|
||||
dvbdevfops->owner = adap->module;
|
||||
|
||||
list_add_tail (&dvbdev->list_head, &adap->device_list);
|
||||
|
||||
down_write(&minor_rwsem);
|
||||
#ifdef CONFIG_DVB_DYNAMIC_MINORS
|
||||
for (minor = 0; minor < MAX_DVB_MINORS; minor++)
|
||||
if (dvb_minors[minor] == NULL)
|
||||
break;
|
||||
|
||||
if (minor == MAX_DVB_MINORS) {
|
||||
kfree(dvbdevfops);
|
||||
kfree(dvbdev);
|
||||
up_write(&minor_rwsem);
|
||||
mutex_unlock(&dvbdev_register_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
#else
|
||||
minor = nums2minor(adap->num, type, id);
|
||||
#endif
|
||||
|
||||
dvbdev->minor = minor;
|
||||
dvb_minors[minor] = dvbdev;
|
||||
up_write(&minor_rwsem);
|
||||
|
||||
mutex_unlock(&dvbdev_register_lock);
|
||||
|
||||
clsdev = device_create(dvb_class, adap->device,
|
||||
MKDEV(DVB_MAJOR, minor),
|
||||
dvbdev, "dvb%d.%s%d", adap->num, dnames[type], id);
|
||||
if (IS_ERR(clsdev)) {
|
||||
printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
|
||||
__func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
|
||||
return PTR_ERR(clsdev);
|
||||
}
|
||||
|
||||
dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n",
|
||||
adap->num, dnames[type], id, minor, minor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_register_device);
|
||||
|
||||
|
||||
void dvb_unregister_device(struct dvb_device *dvbdev)
|
||||
{
|
||||
if (!dvbdev)
|
||||
return;
|
||||
|
||||
down_write(&minor_rwsem);
|
||||
dvb_minors[dvbdev->minor] = NULL;
|
||||
up_write(&minor_rwsem);
|
||||
|
||||
device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor));
|
||||
|
||||
list_del (&dvbdev->list_head);
|
||||
kfree (dvbdev->fops);
|
||||
kfree (dvbdev);
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_unregister_device);
|
||||
|
||||
static int dvbdev_check_free_adapter_num(int num)
|
||||
{
|
||||
struct list_head *entry;
|
||||
list_for_each(entry, &dvb_adapter_list) {
|
||||
struct dvb_adapter *adap;
|
||||
adap = list_entry(entry, struct dvb_adapter, list_head);
|
||||
if (adap->num == num)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dvbdev_get_free_adapter_num (void)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
while (num < DVB_MAX_ADAPTERS) {
|
||||
if (dvbdev_check_free_adapter_num(num))
|
||||
return num;
|
||||
num++;
|
||||
}
|
||||
|
||||
return -ENFILE;
|
||||
}
|
||||
|
||||
|
||||
int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
|
||||
struct module *module, struct device *device,
|
||||
short *adapter_nums)
|
||||
{
|
||||
int i, num;
|
||||
|
||||
mutex_lock(&dvbdev_register_lock);
|
||||
|
||||
for (i = 0; i < DVB_MAX_ADAPTERS; ++i) {
|
||||
num = adapter_nums[i];
|
||||
if (num >= 0 && num < DVB_MAX_ADAPTERS) {
|
||||
/* use the one the driver asked for */
|
||||
if (dvbdev_check_free_adapter_num(num))
|
||||
break;
|
||||
} else {
|
||||
num = dvbdev_get_free_adapter_num();
|
||||
break;
|
||||
}
|
||||
num = -1;
|
||||
}
|
||||
|
||||
if (num < 0) {
|
||||
mutex_unlock(&dvbdev_register_lock);
|
||||
return -ENFILE;
|
||||
}
|
||||
|
||||
memset (adap, 0, sizeof(struct dvb_adapter));
|
||||
INIT_LIST_HEAD (&adap->device_list);
|
||||
|
||||
printk(KERN_INFO "DVB: registering new adapter (%s)\n", name);
|
||||
|
||||
adap->num = num;
|
||||
adap->name = name;
|
||||
adap->module = module;
|
||||
adap->device = device;
|
||||
adap->mfe_shared = 0;
|
||||
adap->mfe_dvbdev = NULL;
|
||||
mutex_init (&adap->mfe_lock);
|
||||
|
||||
list_add_tail (&adap->list_head, &dvb_adapter_list);
|
||||
|
||||
mutex_unlock(&dvbdev_register_lock);
|
||||
|
||||
return num;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_register_adapter);
|
||||
|
||||
|
||||
int dvb_unregister_adapter(struct dvb_adapter *adap)
|
||||
{
|
||||
mutex_lock(&dvbdev_register_lock);
|
||||
list_del (&adap->list_head);
|
||||
mutex_unlock(&dvbdev_register_lock);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_unregister_adapter);
|
||||
|
||||
/* if the miracle happens and "generic_usercopy()" is included into
|
||||
the kernel, then this can vanish. please don't make the mistake and
|
||||
define this as video_usercopy(). this will introduce a dependecy
|
||||
to the v4l "videodev.o" module, which is unnecessary for some
|
||||
cards (ie. the budget dvb-cards don't need the v4l module...) */
|
||||
int dvb_usercopy(struct file *file,
|
||||
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 */
|
||||
/* this lock is much too coarse */
|
||||
//mutex_lock(&dvbdev_mutex);
|
||||
if ((err = func(file, cmd, parg)) == -ENOIOCTLCMD)
|
||||
err = -ENOTTY;
|
||||
//mutex_unlock(&dvbdev_mutex);
|
||||
|
||||
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;
|
||||
}
|
||||
EXPORT_SYMBOL(dvb_usercopy);
|
||||
|
||||
static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||
{
|
||||
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]);
|
||||
add_uevent_var(env, "DVB_DEVICE_NUM=%d", dvbdev->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
|
||||
static char *dvb_devnode(struct device *dev, mode_t *mode)
|
||||
#else
|
||||
static char *dvb_devnode(struct device *dev, umode_t *mode)
|
||||
#endif
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
static int __init init_dvbdev(void)
|
||||
{
|
||||
int retval;
|
||||
dev_t dev = MKDEV(DVB_MAJOR, 0);
|
||||
|
||||
if ((retval = register_chrdev_region(dev, MAX_DVB_MINORS, "DVB")) != 0) {
|
||||
printk(KERN_ERR "dvb-core: unable to get major %d\n", DVB_MAJOR);
|
||||
return retval;
|
||||
}
|
||||
|
||||
cdev_init(&dvb_device_cdev, &dvb_device_fops);
|
||||
if ((retval = cdev_add(&dvb_device_cdev, dev, MAX_DVB_MINORS)) != 0) {
|
||||
printk(KERN_ERR "dvb-core: unable register character device\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
dvb_class = class_create(THIS_MODULE, "dvb");
|
||||
if (IS_ERR(dvb_class)) {
|
||||
retval = PTR_ERR(dvb_class);
|
||||
goto error;
|
||||
}
|
||||
dvb_class->dev_uevent = dvb_uevent;
|
||||
dvb_class->devnode = dvb_devnode;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cdev_del(&dvb_device_cdev);
|
||||
unregister_chrdev_region(dev, MAX_DVB_MINORS);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static void __exit exit_dvbdev(void)
|
||||
{
|
||||
class_destroy(dvb_class);
|
||||
cdev_del(&dvb_device_cdev);
|
||||
unregister_chrdev_region(MKDEV(DVB_MAJOR, 0), MAX_DVB_MINORS);
|
||||
}
|
||||
|
||||
subsys_initcall(init_dvbdev);
|
||||
module_exit(exit_dvbdev);
|
||||
|
||||
MODULE_DESCRIPTION("DVB Core Driver");
|
||||
MODULE_AUTHOR("Marcus Metzler, Ralph Metzler, Holger Waechtler");
|
||||
MODULE_LICENSE("GPL");
|
150
dvb-core/dvbdev.h
Normal file
150
dvb-core/dvbdev.h
Normal file
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* dvbdev.h
|
||||
*
|
||||
* 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 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 _DVBDEV_H_
|
||||
#define _DVBDEV_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
#define DVB_MAJOR 212
|
||||
|
||||
#if defined(CONFIG_DVB_MAX_ADAPTERS) && CONFIG_DVB_MAX_ADAPTERS > 0
|
||||
#define DVB_MAX_ADAPTERS CONFIG_DVB_MAX_ADAPTERS
|
||||
#else
|
||||
#define DVB_MAX_ADAPTERS 8
|
||||
#endif
|
||||
|
||||
#define DVB_UNSET (-1)
|
||||
|
||||
#define DVB_DEVICE_VIDEO 0
|
||||
#define DVB_DEVICE_AUDIO 1
|
||||
#define DVB_DEVICE_SEC 2
|
||||
#define DVB_DEVICE_FRONTEND 3
|
||||
#define DVB_DEVICE_DEMUX 4
|
||||
#define DVB_DEVICE_DVR 5
|
||||
#define DVB_DEVICE_CA 6
|
||||
#define DVB_DEVICE_NET 7
|
||||
#define DVB_DEVICE_OSD 8
|
||||
#define DVB_DEVICE_CI 9
|
||||
#define DVB_DEVICE_MOD 10
|
||||
#define DVB_DEVICE_NS 11
|
||||
#define DVB_DEVICE_NSD 12
|
||||
|
||||
#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr) \
|
||||
static short adapter_nr[] = \
|
||||
{[0 ... (DVB_MAX_ADAPTERS - 1)] = DVB_UNSET }; \
|
||||
module_param_array(adapter_nr, short, NULL, 0444); \
|
||||
MODULE_PARM_DESC(adapter_nr, "DVB adapter numbers")
|
||||
|
||||
struct dvb_frontend;
|
||||
|
||||
struct dvb_adapter {
|
||||
int num;
|
||||
struct list_head list_head;
|
||||
struct list_head device_list;
|
||||
const char *name;
|
||||
u8 proposed_mac [6];
|
||||
void* priv;
|
||||
|
||||
struct device *device;
|
||||
|
||||
struct module *module;
|
||||
|
||||
int mfe_shared; /* indicates mutually exclusive frontends */
|
||||
struct dvb_device *mfe_dvbdev; /* frontend device in use */
|
||||
struct mutex mfe_lock; /* access lock for thread creation */
|
||||
};
|
||||
|
||||
|
||||
struct dvb_device {
|
||||
struct list_head list_head;
|
||||
const struct file_operations *fops;
|
||||
struct dvb_adapter *adapter;
|
||||
int type;
|
||||
int minor;
|
||||
u32 id;
|
||||
|
||||
/* in theory, 'users' can vanish now,
|
||||
but I don't want to change too much now... */
|
||||
int readers;
|
||||
int writers;
|
||||
int users;
|
||||
|
||||
wait_queue_head_t wait_queue;
|
||||
/* don't really need those !? -- FIXME: use video_usercopy */
|
||||
int (*kernel_ioctl)(struct file *file, unsigned int cmd, void *arg);
|
||||
|
||||
void *priv;
|
||||
};
|
||||
|
||||
|
||||
extern int dvb_register_adapter(struct dvb_adapter *adap, const char *name,
|
||||
struct module *module, struct device *device,
|
||||
short *adapter_nums);
|
||||
extern int dvb_unregister_adapter (struct dvb_adapter *adap);
|
||||
|
||||
extern int dvb_register_device (struct dvb_adapter *adap,
|
||||
struct dvb_device **pdvbdev,
|
||||
const struct dvb_device *template,
|
||||
void *priv,
|
||||
int type);
|
||||
|
||||
extern void dvb_unregister_device (struct dvb_device *dvbdev);
|
||||
|
||||
extern int dvb_generic_open (struct inode *inode, struct file *file);
|
||||
extern int dvb_generic_release (struct inode *inode, struct file *file);
|
||||
extern long dvb_generic_ioctl (struct file *file,
|
||||
unsigned int cmd, unsigned long arg);
|
||||
|
||||
/* we don't mess with video_usercopy() any more,
|
||||
we simply define out own dvb_usercopy(), which will hopefully become
|
||||
generic_usercopy() someday... */
|
||||
|
||||
extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
|
||||
int (*func)(struct file *file, unsigned int cmd, void *arg));
|
||||
|
||||
/** generic DVB attach function. */
|
||||
#ifdef CONFIG_MEDIA_ATTACH
|
||||
#define dvb_attach(FUNCTION, ARGS...) ({ \
|
||||
void *__r = NULL; \
|
||||
typeof(&FUNCTION) __a = symbol_request(FUNCTION); \
|
||||
if (__a) { \
|
||||
__r = (void *) __a(ARGS); \
|
||||
if (__r == NULL) \
|
||||
symbol_put(FUNCTION); \
|
||||
} else { \
|
||||
printk(KERN_ERR "DVB: Unable to find symbol "#FUNCTION"()\n"); \
|
||||
} \
|
||||
__r; \
|
||||
})
|
||||
|
||||
#else
|
||||
#define dvb_attach(FUNCTION, ARGS...) ({ \
|
||||
FUNCTION(ARGS); \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* #ifndef _DVBDEV_H_ */
|
37
frontends/Makefile
Normal file
37
frontends/Makefile
Normal file
@ -0,0 +1,37 @@
|
||||
#
|
||||
# Makefile for the kernel DVB frontend device drivers.
|
||||
#
|
||||
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_LNBP21
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_STV090x
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_STV6110x
|
||||
#EXTRA_CFLAGS += -DCONFIG_DVB_STV0367
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_STV0367DD
|
||||
#EXTRA_CFLAGS += -DCONFIG_DVB_TDA18212
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_TDA18212DD
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_CXD2843
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_STV6111
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_STV0910
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_LNBH25
|
||||
EXTRA_CFLAGS += -DCONFIG_DVB_MXL5XX
|
||||
EXTRA_CFLAGS += -DDBVALS
|
||||
NOSTDINC_FLAGS += -I$(SUBDIRS)/include -I$(SUBDIRS)/dvb-core
|
||||
|
||||
drxk-objs := drxk_hard.o
|
||||
obj-$(CONFIG_DVB_DRXK) += drxk.o
|
||||
|
||||
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
|
||||
obj-$(CONFIG_DVB_STV090x) += stv090x.o
|
||||
obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
|
||||
obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
|
||||
obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o
|
||||
#obj-$(CONFIG_DVB_STV0367) += stv0367.o
|
||||
obj-$(CONFIG_DVB_STV0367DD) += stv0367dd.o
|
||||
#obj-$(CONFIG_DVB_TDA18212) += tda18212.o
|
||||
obj-$(CONFIG_DVB_TDA18212DD) += tda18212dd.o
|
||||
obj-$(CONFIG_DVB_CXD2843) += cxd2843.o
|
||||
obj-$(CONFIG_DVB_STV6111) += stv6111.o
|
||||
obj-$(CONFIG_DVB_STV0910) += stv0910.o
|
||||
obj-$(CONFIG_DVB_LNBH25) += lnbh25.o
|
||||
obj-$(CONFIG_DVB_MXL5XX) += mxl5xx.o
|
||||
|
726
frontends/cxd2099.c
Normal file
726
frontends/cxd2099.c
Normal file
@ -0,0 +1,726 @@
|
||||
/*
|
||||
* cxd2099.c: Driver for the CXD2099AR Common Interface Controller
|
||||
*
|
||||
* Copyright (C) 2010-2013 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 <linux/version.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "cxd2099.h"
|
||||
|
||||
//#define BUFFER_MODE 1
|
||||
|
||||
static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount);
|
||||
|
||||
struct cxd {
|
||||
struct dvb_ca_en50221 en;
|
||||
|
||||
struct i2c_adapter *i2c;
|
||||
struct cxd2099_cfg cfg;
|
||||
|
||||
u8 regs[0x23];
|
||||
u8 lastaddress;
|
||||
u8 clk_reg_f;
|
||||
u8 clk_reg_b;
|
||||
int mode;
|
||||
int ready;
|
||||
int dr;
|
||||
int write_busy;
|
||||
int slot_stat;
|
||||
|
||||
u8 amem[1024];
|
||||
int amem_read;
|
||||
|
||||
int cammode;
|
||||
struct mutex lock;
|
||||
|
||||
u8 rbuf[1028];
|
||||
u8 wbuf[1028];
|
||||
};
|
||||
|
||||
static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr,
|
||||
u8 reg, u8 data)
|
||||
{
|
||||
u8 m[2] = {reg, data};
|
||||
struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 2};
|
||||
|
||||
if (i2c_transfer(adapter, &msg, 1) != 1) {
|
||||
pr_err("Failed to write to I2C register %02x@%02x!\n",
|
||||
reg, adr);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_write(struct i2c_adapter *adapter, u8 adr,
|
||||
u8 *data, u16 len)
|
||||
{
|
||||
struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len};
|
||||
|
||||
if (i2c_transfer(adapter, &msg, 1) != 1) {
|
||||
pr_err("Failed to write to I2C!\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr,
|
||||
u8 reg, u8 *val)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = ®, .len = 1},
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = val, .len = 1} };
|
||||
|
||||
if (i2c_transfer(adapter, msgs, 2) != 2) {
|
||||
pr_err("error in i2c_read_reg\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_read(struct i2c_adapter *adapter, u8 adr,
|
||||
u8 reg, u8 *data, u16 n)
|
||||
{
|
||||
struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
|
||||
.buf = ®, .len = 1},
|
||||
{.addr = adr, .flags = I2C_M_RD,
|
||||
.buf = data, .len = n} };
|
||||
|
||||
if (i2c_transfer(adapter, msgs, 2) != 2) {
|
||||
pr_err("error in i2c_read\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_block(struct cxd *ci, u8 adr, u8 *data, u16 n)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
if (ci->lastaddress != adr)
|
||||
status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, adr);
|
||||
if (!status) {
|
||||
ci->lastaddress = adr;
|
||||
|
||||
while (n) {
|
||||
int len = n;
|
||||
|
||||
if (ci->cfg.max_i2c &&
|
||||
len > ci->cfg.max_i2c)
|
||||
len = ci->cfg.max_i2c;
|
||||
status = i2c_read(ci->i2c, ci->cfg.adr, 1, data, len);
|
||||
if (status)
|
||||
return status;
|
||||
data += len;
|
||||
n -= len;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int read_reg(struct cxd *ci, u8 reg, u8 *val)
|
||||
{
|
||||
return read_block(ci, reg, val, 1);
|
||||
}
|
||||
|
||||
|
||||
static int read_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
|
||||
{
|
||||
int status;
|
||||
u8 addr[3] = {2, address & 0xff, address >> 8};
|
||||
|
||||
status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3);
|
||||
if (!status)
|
||||
status = i2c_read(ci->i2c, ci->cfg.adr, 3, data, n);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int write_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
|
||||
{
|
||||
int status;
|
||||
u8 addr[3] = {2, address & 0xff, address >> 8};
|
||||
|
||||
status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3);
|
||||
if (!status) {
|
||||
u8 buf[256] = {3};
|
||||
|
||||
memcpy(buf + 1, data, n);
|
||||
status = i2c_write(ci->i2c, ci->cfg.adr, buf, n+1);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int read_io(struct cxd *ci, u16 address, u8 *val)
|
||||
{
|
||||
int status;
|
||||
u8 addr[3] = {2, address & 0xff, address >> 8};
|
||||
|
||||
status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3);
|
||||
if (!status)
|
||||
status = i2c_read(ci->i2c, ci->cfg.adr, 3, val, 1);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int write_io(struct cxd *ci, u16 address, u8 val)
|
||||
{
|
||||
int status;
|
||||
u8 addr[3] = {2, address & 0xff, address >> 8};
|
||||
u8 buf[2] = {3, val};
|
||||
|
||||
status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3);
|
||||
if (!status)
|
||||
status = i2c_write(ci->i2c, ci->cfg.adr, buf, 2);
|
||||
return status;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int read_io_data(struct cxd *ci, u8 *data, u16 n)
|
||||
{
|
||||
int status;
|
||||
u8 addr[3] = { 2, 0, 0 };
|
||||
|
||||
status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3);
|
||||
if (!status)
|
||||
status = i2c_read(ci->i2c, ci->cfg.adr, 3, data, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_io_data(struct cxd *ci, u8 *data, u16 n)
|
||||
{
|
||||
int status;
|
||||
u8 addr[3] = {2, 0, 0};
|
||||
|
||||
status = i2c_write(ci->i2c, ci->cfg.adr, addr, 3);
|
||||
if (!status) {
|
||||
u8 buf[256] = {3};
|
||||
|
||||
memcpy(buf + 1, data, n);
|
||||
status = i2c_write(ci->i2c, ci->cfg.adr, buf, n + 1);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
if (ci->lastaddress != reg)
|
||||
status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, reg);
|
||||
if (!status && reg >= 6 && reg <= 8 && mask != 0xff)
|
||||
status = i2c_read_reg(ci->i2c, ci->cfg.adr, 1, &ci->regs[reg]);
|
||||
ci->lastaddress = reg;
|
||||
ci->regs[reg] = (ci->regs[reg] & (~mask)) | val;
|
||||
if (!status)
|
||||
status = i2c_write_reg(ci->i2c, ci->cfg.adr, 1, ci->regs[reg]);
|
||||
if (reg == 0x20)
|
||||
ci->regs[reg] &= 0x7f;
|
||||
return status;
|
||||
}
|
||||
|
||||
static int write_reg(struct cxd *ci, u8 reg, u8 val)
|
||||
{
|
||||
return write_regm(ci, reg, val, 0xff);
|
||||
}
|
||||
|
||||
#ifdef BUFFER_MODE
|
||||
static int write_block(struct cxd *ci, u8 adr, u8 *data, u16 n)
|
||||
{
|
||||
int status = 0;
|
||||
u8 *buf = ci->wbuf;
|
||||
|
||||
if (ci->lastaddress != adr)
|
||||
status = i2c_write_reg(ci->i2c, ci->cfg.adr, 0, adr);
|
||||
if (status)
|
||||
return status;
|
||||
printk("write_block %d\n", n);
|
||||
|
||||
ci->lastaddress = adr;
|
||||
buf[0] = 1;
|
||||
while (n) {
|
||||
int len = n;
|
||||
|
||||
if (ci->cfg.max_i2c &&
|
||||
len + 1 > ci->cfg.max_i2c)
|
||||
len = ci->cfg.max_i2c - 1;
|
||||
printk("write %d\n", len);
|
||||
memcpy(buf + 1, data, len);
|
||||
status = i2c_write(ci->i2c, ci->cfg.adr, buf, len + 1);
|
||||
if (status)
|
||||
return status;
|
||||
n -= len;
|
||||
data += len;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void set_mode(struct cxd *ci, int mode)
|
||||
{
|
||||
if (mode == ci->mode)
|
||||
return;
|
||||
|
||||
switch (mode) {
|
||||
case 0x00: /* IO mem */
|
||||
write_regm(ci, 0x06, 0x00, 0x07);
|
||||
break;
|
||||
case 0x01: /* ATT mem */
|
||||
write_regm(ci, 0x06, 0x02, 0x07);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ci->mode = mode;
|
||||
}
|
||||
|
||||
static void cam_mode(struct cxd *ci, int mode)
|
||||
{
|
||||
u8 dummy;
|
||||
|
||||
if (mode == ci->cammode)
|
||||
return;
|
||||
|
||||
switch (mode) {
|
||||
case 0x00:
|
||||
write_regm(ci, 0x20, 0x80, 0x80);
|
||||
break;
|
||||
case 0x01:
|
||||
if (!ci->en.read_data)
|
||||
return;
|
||||
ci->write_busy = 0;
|
||||
pr_info("enable cam buffer mode\n");
|
||||
write_reg(ci, 0x0d, 0x00);
|
||||
write_reg(ci, 0x0e, 0x01);
|
||||
write_regm(ci, 0x08, 0x40, 0x40);
|
||||
read_reg(ci, 0x12, &dummy);
|
||||
write_regm(ci, 0x08, 0x80, 0x80);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ci->cammode = mode;
|
||||
}
|
||||
|
||||
#define CHK_ERROR(s) if ((status = s)) break
|
||||
|
||||
static int init(struct cxd *ci)
|
||||
{
|
||||
int status;
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
ci->mode = -1;
|
||||
do {
|
||||
CHK_ERROR(write_reg(ci, 0x00, 0x00));
|
||||
CHK_ERROR(write_reg(ci, 0x01, 0x00));
|
||||
CHK_ERROR(write_reg(ci, 0x02, 0x10));
|
||||
CHK_ERROR(write_reg(ci, 0x03, 0x00));
|
||||
CHK_ERROR(write_reg(ci, 0x05, 0xFF));
|
||||
CHK_ERROR(write_reg(ci, 0x06, 0x1F));
|
||||
CHK_ERROR(write_reg(ci, 0x07, 0x1F));
|
||||
CHK_ERROR(write_reg(ci, 0x08, 0x28));
|
||||
CHK_ERROR(write_reg(ci, 0x14, 0x20));
|
||||
|
||||
/* TOSTRT = 8, Mode B (gated clock), falling Edge,
|
||||
Serial, POL=HIGH, MSB */
|
||||
CHK_ERROR(write_reg(ci, 0x0A, 0xA7));
|
||||
|
||||
CHK_ERROR(write_reg(ci, 0x0B, 0x33));
|
||||
CHK_ERROR(write_reg(ci, 0x0C, 0x33));
|
||||
|
||||
CHK_ERROR(write_regm(ci, 0x14, 0x00, 0x0F));
|
||||
CHK_ERROR(write_reg(ci, 0x15, ci->clk_reg_b));
|
||||
CHK_ERROR(write_regm(ci, 0x16, 0x00, 0x0F));
|
||||
CHK_ERROR(write_reg(ci, 0x17, ci->clk_reg_f));
|
||||
|
||||
if (ci->cfg.clock_mode == 2) {
|
||||
/* bitrate*2^13/ 72000 */
|
||||
u32 reg = ((ci->cfg.bitrate << 13) + 71999) / 72000;
|
||||
|
||||
if (ci->cfg.polarity) {
|
||||
CHK_ERROR(write_reg(ci, 0x09, 0x6f));
|
||||
} else {
|
||||
CHK_ERROR(write_reg(ci, 0x09, 0x6d));
|
||||
}
|
||||
CHK_ERROR(write_reg(ci, 0x20, 0x08));
|
||||
CHK_ERROR(write_reg(ci, 0x21, (reg >> 8) & 0xff));
|
||||
CHK_ERROR(write_reg(ci, 0x22, reg & 0xff));
|
||||
} else if (ci->cfg.clock_mode == 1) {
|
||||
if (ci->cfg.polarity) {
|
||||
CHK_ERROR(write_reg(ci, 0x09, 0x6f)); /* D */
|
||||
} else {
|
||||
CHK_ERROR(write_reg(ci, 0x09, 0x6d));
|
||||
}
|
||||
CHK_ERROR(write_reg(ci, 0x20, 0x68));
|
||||
CHK_ERROR(write_reg(ci, 0x21, 0x00));
|
||||
CHK_ERROR(write_reg(ci, 0x22, 0x02));
|
||||
} else {
|
||||
if (ci->cfg.polarity) {
|
||||
CHK_ERROR(write_reg(ci, 0x09, 0x4f)); /* C */
|
||||
} else {
|
||||
CHK_ERROR(write_reg(ci, 0x09, 0x4d));
|
||||
}
|
||||
CHK_ERROR(write_reg(ci, 0x20, 0x28));
|
||||
CHK_ERROR(write_reg(ci, 0x21, 0x00));
|
||||
CHK_ERROR(write_reg(ci, 0x22, 0x07));
|
||||
}
|
||||
|
||||
CHK_ERROR(write_regm(ci, 0x20, 0x80, 0x80));
|
||||
CHK_ERROR(write_regm(ci, 0x03, 0x02, 0x02));
|
||||
CHK_ERROR(write_reg(ci, 0x01, 0x04));
|
||||
CHK_ERROR(write_reg(ci, 0x00, 0x31));
|
||||
|
||||
/* Put TS in bypass */
|
||||
CHK_ERROR(write_regm(ci, 0x09, 0x08, 0x08));
|
||||
ci->cammode = -1;
|
||||
cam_mode(ci, 0);
|
||||
} while (0);
|
||||
mutex_unlock(&ci->lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_attribute_mem(struct dvb_ca_en50221 *ca,
|
||||
int slot, int address)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
#if 0
|
||||
if (ci->amem_read) {
|
||||
if (address <= 0 || address > 1024)
|
||||
return -EIO;
|
||||
return ci->amem[address];
|
||||
}
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
write_regm(ci, 0x06, 0x00, 0x05);
|
||||
read_pccard(ci, 0, &ci->amem[0], 128);
|
||||
read_pccard(ci, 128, &ci->amem[0], 128);
|
||||
read_pccard(ci, 256, &ci->amem[0], 128);
|
||||
read_pccard(ci, 384, &ci->amem[0], 128);
|
||||
write_regm(ci, 0x06, 0x05, 0x05);
|
||||
mutex_unlock(&ci->lock);
|
||||
return ci->amem[address];
|
||||
#else
|
||||
u8 val;
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
set_mode(ci, 1);
|
||||
read_pccard(ci, address, &val, 1);
|
||||
mutex_unlock(&ci->lock);
|
||||
return val;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
|
||||
int address, u8 value)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
set_mode(ci, 1);
|
||||
write_pccard(ci, address, &value, 1);
|
||||
mutex_unlock(&ci->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_cam_control(struct dvb_ca_en50221 *ca,
|
||||
int slot, u8 address)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
u8 val;
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
set_mode(ci, 0);
|
||||
read_io(ci, address, &val);
|
||||
mutex_unlock(&ci->lock);
|
||||
return val;
|
||||
}
|
||||
|
||||
static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
|
||||
u8 address, u8 value)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
set_mode(ci, 0);
|
||||
write_io(ci, address, value);
|
||||
mutex_unlock(&ci->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
|
||||
if (ci->cammode)
|
||||
read_data(ca, slot, ci->rbuf, 0);
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
#if 0
|
||||
write_reg(ci, 0x00, 0x21);
|
||||
write_reg(ci, 0x06, 0x1F);
|
||||
write_reg(ci, 0x00, 0x31);
|
||||
#else
|
||||
#if 0
|
||||
write_reg(ci, 0x06, 0x1F);
|
||||
write_reg(ci, 0x06, 0x2F);
|
||||
#else
|
||||
cam_mode(ci, 0);
|
||||
write_reg(ci, 0x00, 0x21);
|
||||
write_reg(ci, 0x06, 0x1F);
|
||||
/*msleep(300);*/
|
||||
write_reg(ci, 0x00, 0x31);
|
||||
write_regm(ci, 0x20, 0x80, 0x80);
|
||||
write_reg(ci, 0x03, 0x02);
|
||||
ci->ready = 0;
|
||||
#endif
|
||||
#endif
|
||||
ci->mode = -1;
|
||||
{
|
||||
int i;
|
||||
#if 0
|
||||
u8 val;
|
||||
#endif
|
||||
for (i = 0; i < 100; i++) {
|
||||
msleep(20);
|
||||
#if 0
|
||||
read_reg(ci, 0x06, &val);
|
||||
pr_info(KERN_INFO "%d:%02x\n", i, val);
|
||||
if (!(val&0x10))
|
||||
break;
|
||||
#else
|
||||
if (ci->ready)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ci->lock);
|
||||
/* msleep(500); */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
|
||||
pr_info("slot_shutdown\n");
|
||||
if (ci->cammode)
|
||||
read_data(ca, slot, ci->rbuf, 0);
|
||||
mutex_lock(&ci->lock);
|
||||
write_reg(ci, 0x00, 0x21);
|
||||
write_reg(ci, 0x06, 0x1F);
|
||||
msleep(300);
|
||||
|
||||
write_regm(ci, 0x09, 0x08, 0x08);
|
||||
write_regm(ci, 0x20, 0x80, 0x80); /* Reset CAM Mode */
|
||||
write_regm(ci, 0x06, 0x07, 0x07); /* Clear IO Mode */
|
||||
|
||||
ci->mode = -1;
|
||||
ci->write_busy = 0;
|
||||
mutex_unlock(&ci->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
write_regm(ci, 0x09, 0x00, 0x08);
|
||||
set_mode(ci, 0);
|
||||
cam_mode(ci, 1);
|
||||
mutex_unlock(&ci->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int campoll(struct cxd *ci)
|
||||
{
|
||||
u8 istat;
|
||||
|
||||
read_reg(ci, 0x04, &istat);
|
||||
if (!istat)
|
||||
return 0;
|
||||
write_reg(ci, 0x05, istat);
|
||||
|
||||
if (istat & 0x40)
|
||||
ci->dr = 1;
|
||||
if (istat & 0x20)
|
||||
ci->write_busy = 0;
|
||||
if (istat & 2) {
|
||||
u8 slotstat;
|
||||
|
||||
read_reg(ci, 0x01, &slotstat);
|
||||
if (!(2 & slotstat)) {
|
||||
if (!ci->slot_stat) {
|
||||
ci->slot_stat |=
|
||||
DVB_CA_EN50221_POLL_CAM_PRESENT;
|
||||
write_regm(ci, 0x03, 0x08, 0x08);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ci->slot_stat) {
|
||||
ci->slot_stat = 0;
|
||||
write_regm(ci, 0x03, 0x00, 0x08);
|
||||
pr_info("NO CAM\n");
|
||||
ci->ready = 0;
|
||||
}
|
||||
}
|
||||
if ((istat & 8) &&
|
||||
(ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT)) {
|
||||
ci->ready = 1;
|
||||
ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
u8 slotstat;
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
campoll(ci);
|
||||
read_reg(ci, 0x01, &slotstat);
|
||||
mutex_unlock(&ci->lock);
|
||||
|
||||
return ci->slot_stat;
|
||||
}
|
||||
|
||||
static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
u8 msb, lsb;
|
||||
u16 len;
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
campoll(ci);
|
||||
mutex_unlock(&ci->lock);
|
||||
|
||||
if (!ci->dr)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&ci->lock);
|
||||
read_reg(ci, 0x0f, &msb);
|
||||
read_reg(ci, 0x10, &lsb);
|
||||
len = ((u16) msb << 8) | lsb;
|
||||
if (len > ecount || len < 2) {
|
||||
/* read it anyway or cxd may hang */
|
||||
read_block(ci, 0x12, ci->rbuf, len);
|
||||
mutex_unlock(&ci->lock);
|
||||
return -EIO;
|
||||
}
|
||||
read_block(ci, 0x12, ebuf, len);
|
||||
ci->dr = 0;
|
||||
mutex_unlock(&ci->lock);
|
||||
#if 0
|
||||
pr_info("read_data %d\n", len);
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
pr_info("%02x ", ebuf[i]);
|
||||
pr_info("\n");
|
||||
}
|
||||
#endif
|
||||
return len;
|
||||
}
|
||||
|
||||
#ifdef BUFFER_MODE
|
||||
|
||||
static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
|
||||
{
|
||||
struct cxd *ci = ca->data;
|
||||
|
||||
if (ci->write_busy)
|
||||
return -EAGAIN;
|
||||
mutex_lock(&ci->lock);
|
||||
write_reg(ci, 0x0d, ecount >> 8);
|
||||
write_reg(ci, 0x0e, ecount & 0xff);
|
||||
write_block(ci, 0x11, ebuf, ecount);
|
||||
ci->write_busy = 1;
|
||||
mutex_unlock(&ci->lock);
|
||||
return ecount;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct dvb_ca_en50221 en_templ = {
|
||||
.read_attribute_mem = read_attribute_mem,
|
||||
.write_attribute_mem = write_attribute_mem,
|
||||
.read_cam_control = read_cam_control,
|
||||
.write_cam_control = write_cam_control,
|
||||
.slot_reset = slot_reset,
|
||||
.slot_shutdown = slot_shutdown,
|
||||
.slot_ts_enable = slot_ts_enable,
|
||||
.poll_slot_status = poll_slot_status,
|
||||
#ifdef BUFFER_MODE
|
||||
.read_data = read_data,
|
||||
.write_data = write_data,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
|
||||
void *priv,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct cxd *ci = 0;
|
||||
u8 val;
|
||||
|
||||
if (i2c_read_reg(i2c, cfg->adr, 0, &val) < 0) {
|
||||
pr_info("No CXD2099 detected at %02x\n", cfg->adr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ci = kzalloc(sizeof(struct cxd), GFP_KERNEL);
|
||||
if (!ci)
|
||||
return 0;
|
||||
|
||||
mutex_init(&ci->lock);
|
||||
memcpy(&ci->cfg, cfg, sizeof(struct cxd2099_cfg));
|
||||
ci->i2c = i2c;
|
||||
ci->lastaddress = 0xff;
|
||||
ci->clk_reg_b = 0x4a;
|
||||
ci->clk_reg_f = 0x1b;
|
||||
|
||||
memcpy(&ci->en, &en_templ, sizeof(en_templ));
|
||||
ci->en.data = ci;
|
||||
init(ci);
|
||||
pr_info("Attached CXD2099AR at %02x\n", ci->cfg.adr);
|
||||
return &ci->en;
|
||||
}
|
||||
EXPORT_SYMBOL(cxd2099_attach);
|
||||
|
||||
MODULE_DESCRIPTION("cxd2099");
|
||||
MODULE_AUTHOR("Ralph Metzler");
|
||||
MODULE_LICENSE("GPL");
|
43
frontends/cxd2099.h
Normal file
43
frontends/cxd2099.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* cxd2099.h: Driver for the CXD2099AR Common Interface Controller
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef _CXD2099_H_
|
||||
#define _CXD2099_H_
|
||||
|
||||
#include <dvb_ca_en50221.h>
|
||||
|
||||
struct cxd2099_cfg {
|
||||
u32 bitrate;
|
||||
u8 adr;
|
||||
u8 polarity;
|
||||
u8 clock_mode;
|
||||
|
||||
u32 max_i2c;
|
||||
};
|
||||
|
||||
struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
|
||||
void *priv, struct i2c_adapter *i2c);
|
||||
|
||||
|
||||
#endif
|
2042
frontends/cxd2843.c
Normal file
2042
frontends/cxd2843.c
Normal file
File diff suppressed because it is too large
Load Diff
30
frontends/cxd2843.h
Normal file
30
frontends/cxd2843.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef _CXD2843_H_
|
||||
#define _CXD2843_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
struct cxd2843_cfg {
|
||||
u8 adr;
|
||||
u32 ts_clock;
|
||||
u8 parallel;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_CXD2843) || \
|
||||
(defined(CONFIG_DVB_CXD2843_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c,
|
||||
struct cxd2843_cfg *cfg);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *cxd2843_attach(struct i2c_adapter *i2c,
|
||||
struct cxd2843_cfg *cfg)
|
||||
{
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
10
frontends/drxk.h
Normal file
10
frontends/drxk.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef _DRXK_H_
|
||||
#define _DRXK_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
extern struct dvb_frontend *drxk_attach(struct i2c_adapter *i2c,
|
||||
u8 adr,
|
||||
struct dvb_frontend **fe_t);
|
||||
#endif
|
BIN
frontends/drxk_a3.mc
Normal file
BIN
frontends/drxk_a3.mc
Normal file
Binary file not shown.
5097
frontends/drxk_hard.c
Normal file
5097
frontends/drxk_hard.c
Normal file
File diff suppressed because it is too large
Load Diff
343
frontends/drxk_hard.h
Normal file
343
frontends/drxk_hard.h
Normal file
@ -0,0 +1,343 @@
|
||||
#include "drxk_map.h"
|
||||
|
||||
#define DRXK_VERSION_MAJOR 0
|
||||
#define DRXK_VERSION_MINOR 9
|
||||
#define DRXK_VERSION_PATCH 4300
|
||||
|
||||
#define HI_I2C_DELAY 42
|
||||
#define HI_I2C_BRIDGE_DELAY 350
|
||||
#define DRXK_MAX_RETRIES 100
|
||||
|
||||
#define DRIVER_4400 1
|
||||
|
||||
#define DRXX_JTAGID 0x039210D9
|
||||
#define DRXX_J_JTAGID 0x239310D9
|
||||
#define DRXX_K_JTAGID 0x039210D9
|
||||
|
||||
#define DRX_UNKNOWN 254
|
||||
#define DRX_AUTO 255
|
||||
|
||||
#define DRX_SCU_READY 0
|
||||
#define DRXK_MAX_WAITTIME (200)
|
||||
#define SCU_RESULT_OK 0
|
||||
#define SCU_RESULT_UNKSTD -2
|
||||
#define SCU_RESULT_UNKCMD -1
|
||||
|
||||
#ifndef DRXK_OFDM_TR_SHUTDOWN_TIMEOUT
|
||||
#define DRXK_OFDM_TR_SHUTDOWN_TIMEOUT (200)
|
||||
#endif
|
||||
|
||||
#define DRXK_8VSB_MPEG_BIT_RATE 19392658UL /*bps*/
|
||||
#define DRXK_DVBT_MPEG_BIT_RATE 32000000UL /*bps*/
|
||||
#define DRXK_QAM16_MPEG_BIT_RATE 27000000UL /*bps*/
|
||||
#define DRXK_QAM32_MPEG_BIT_RATE 33000000UL /*bps*/
|
||||
#define DRXK_QAM64_MPEG_BIT_RATE 40000000UL /*bps*/
|
||||
#define DRXK_QAM128_MPEG_BIT_RATE 46000000UL /*bps*/
|
||||
#define DRXK_QAM256_MPEG_BIT_RATE 52000000UL /*bps*/
|
||||
#define DRXK_MAX_MPEG_BIT_RATE 52000000UL /*bps*/
|
||||
|
||||
#define IQM_CF_OUT_ENA_OFDM__M 0x4
|
||||
#define IQM_FS_ADJ_SEL_B_QAM 0x1
|
||||
#define IQM_FS_ADJ_SEL_B_OFF 0x0
|
||||
#define IQM_FS_ADJ_SEL_B_VSB 0x2
|
||||
#define IQM_RC_ADJ_SEL_B_OFF 0x0
|
||||
#define IQM_RC_ADJ_SEL_B_QAM 0x1
|
||||
#define IQM_RC_ADJ_SEL_B_VSB 0x2
|
||||
|
||||
enum OperationMode {
|
||||
OM_NONE,
|
||||
OM_QAM_ITU_A,
|
||||
OM_QAM_ITU_B,
|
||||
OM_QAM_ITU_C,
|
||||
OM_DVBT
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
DRX_POWER_UP = 0,
|
||||
DRX_POWER_MODE_1,
|
||||
DRX_POWER_MODE_2,
|
||||
DRX_POWER_MODE_3,
|
||||
DRX_POWER_MODE_4,
|
||||
DRX_POWER_MODE_5,
|
||||
DRX_POWER_MODE_6,
|
||||
DRX_POWER_MODE_7,
|
||||
DRX_POWER_MODE_8,
|
||||
|
||||
DRX_POWER_MODE_9,
|
||||
DRX_POWER_MODE_10,
|
||||
DRX_POWER_MODE_11,
|
||||
DRX_POWER_MODE_12,
|
||||
DRX_POWER_MODE_13,
|
||||
DRX_POWER_MODE_14,
|
||||
DRX_POWER_MODE_15,
|
||||
DRX_POWER_MODE_16,
|
||||
DRX_POWER_DOWN = 255
|
||||
}DRXPowerMode_t, *pDRXPowerMode_t;
|
||||
|
||||
|
||||
/** /brief Intermediate power mode for DRXK, power down OFDM clock domain */
|
||||
#ifndef DRXK_POWER_DOWN_OFDM
|
||||
#define DRXK_POWER_DOWN_OFDM DRX_POWER_MODE_1
|
||||
#endif
|
||||
|
||||
/** /brief Intermediate power mode for DRXK, power down core (sysclk) */
|
||||
#ifndef DRXK_POWER_DOWN_CORE
|
||||
#define DRXK_POWER_DOWN_CORE DRX_POWER_MODE_9
|
||||
#endif
|
||||
|
||||
/** /brief Intermediate power mode for DRXK, power down pll (only osc runs) */
|
||||
#ifndef DRXK_POWER_DOWN_PLL
|
||||
#define DRXK_POWER_DOWN_PLL DRX_POWER_MODE_10
|
||||
#endif
|
||||
|
||||
|
||||
enum AGC_CTRL_MODE { DRXK_AGC_CTRL_AUTO = 0, DRXK_AGC_CTRL_USER, DRXK_AGC_CTRL_OFF };
|
||||
enum EDrxkState { DRXK_UNINITIALIZED = 0, DRXK_STOPPED, DRXK_DTV_STARTED, DRXK_ATV_STARTED, DRXK_POWERED_DOWN };
|
||||
enum EDrxkCoefArrayIndex {
|
||||
DRXK_COEF_IDX_MN = 0,
|
||||
DRXK_COEF_IDX_FM ,
|
||||
DRXK_COEF_IDX_L ,
|
||||
DRXK_COEF_IDX_LP ,
|
||||
DRXK_COEF_IDX_BG ,
|
||||
DRXK_COEF_IDX_DK ,
|
||||
DRXK_COEF_IDX_I ,
|
||||
DRXK_COEF_IDX_MAX
|
||||
};
|
||||
enum EDrxkSifAttenuation {
|
||||
DRXK_SIF_ATTENUATION_0DB,
|
||||
DRXK_SIF_ATTENUATION_3DB,
|
||||
DRXK_SIF_ATTENUATION_6DB,
|
||||
DRXK_SIF_ATTENUATION_9DB
|
||||
};
|
||||
enum EDrxkConstellation {
|
||||
DRX_CONSTELLATION_BPSK = 0,
|
||||
DRX_CONSTELLATION_QPSK,
|
||||
DRX_CONSTELLATION_PSK8,
|
||||
DRX_CONSTELLATION_QAM16,
|
||||
DRX_CONSTELLATION_QAM32,
|
||||
DRX_CONSTELLATION_QAM64,
|
||||
DRX_CONSTELLATION_QAM128,
|
||||
DRX_CONSTELLATION_QAM256,
|
||||
DRX_CONSTELLATION_QAM512,
|
||||
DRX_CONSTELLATION_QAM1024,
|
||||
DRX_CONSTELLATION_UNKNOWN = DRX_UNKNOWN,
|
||||
DRX_CONSTELLATION_AUTO = DRX_AUTO
|
||||
};
|
||||
enum EDrxkInterleaveMode {
|
||||
DRXK_QAM_I12_J17 = 16,
|
||||
DRXK_QAM_I_UNKNOWN = DRX_UNKNOWN
|
||||
};
|
||||
enum {
|
||||
DRXK_SPIN_A1 = 0,
|
||||
DRXK_SPIN_A2,
|
||||
DRXK_SPIN_A3,
|
||||
DRXK_SPIN_UNKNOWN
|
||||
};
|
||||
|
||||
enum DRXKCfgDvbtSqiSpeed {
|
||||
DRXK_DVBT_SQI_SPEED_FAST = 0,
|
||||
DRXK_DVBT_SQI_SPEED_MEDIUM,
|
||||
DRXK_DVBT_SQI_SPEED_SLOW,
|
||||
DRXK_DVBT_SQI_SPEED_UNKNOWN = DRX_UNKNOWN
|
||||
} ;
|
||||
|
||||
enum DRXFftmode_t {
|
||||
DRX_FFTMODE_2K = 0,
|
||||
DRX_FFTMODE_4K,
|
||||
DRX_FFTMODE_8K,
|
||||
DRX_FFTMODE_UNKNOWN = DRX_UNKNOWN,
|
||||
DRX_FFTMODE_AUTO = DRX_AUTO
|
||||
};
|
||||
|
||||
enum DRXMPEGStrWidth_t {
|
||||
DRX_MPEG_STR_WIDTH_1,
|
||||
DRX_MPEG_STR_WIDTH_8
|
||||
};
|
||||
|
||||
enum DRXQamLockRange_t {
|
||||
DRX_QAM_LOCKRANGE_NORMAL,
|
||||
DRX_QAM_LOCKRANGE_EXTENDED
|
||||
};
|
||||
|
||||
struct DRXKCfgDvbtEchoThres_t {
|
||||
u16 threshold;
|
||||
enum DRXFftmode_t fftMode;
|
||||
} ;
|
||||
|
||||
struct SCfgAgc
|
||||
{
|
||||
enum AGC_CTRL_MODE ctrlMode; /* off, user, auto */
|
||||
u16 outputLevel; /* range dependent on AGC */
|
||||
u16 minOutputLevel; /* range dependent on AGC */
|
||||
u16 maxOutputLevel; /* range dependent on AGC */
|
||||
u16 speed; /* range dependent on AGC */
|
||||
u16 top; /* rf-agc take over point */
|
||||
u16 cutOffCurrent; /* rf-agc is accelerated if output current
|
||||
is below cut-off current */
|
||||
u16 IngainTgtMax;
|
||||
u16 FastClipCtrlDelay;
|
||||
};
|
||||
|
||||
struct SCfgPreSaw
|
||||
{
|
||||
u16 reference; /* pre SAW reference value, range 0 .. 31 */
|
||||
bool usePreSaw; /* TRUE algorithms must use pre SAW sense */
|
||||
};
|
||||
|
||||
struct DRXKOfdmScCmd_t
|
||||
{
|
||||
u16 cmd; /**< Command number */
|
||||
u16 subcmd; /**< Sub-command parameter*/
|
||||
u16 param0; /**< General purpous param */
|
||||
u16 param1; /**< General purpous param */
|
||||
u16 param2; /**< General purpous param */
|
||||
u16 param3; /**< General purpous param */
|
||||
u16 param4; /**< General purpous param */
|
||||
};
|
||||
|
||||
struct drxk_state {
|
||||
struct dvb_frontend c_frontend;
|
||||
struct dvb_frontend t_frontend;
|
||||
#ifndef USE_API3
|
||||
struct dtv_frontend_properties props;
|
||||
#else
|
||||
struct dvb_frontend_parameters param;
|
||||
#endif
|
||||
struct device *dev;
|
||||
|
||||
struct i2c_adapter *i2c;
|
||||
u8 demod_address;
|
||||
void *priv;
|
||||
|
||||
struct mutex mutex;
|
||||
struct mutex ctlock;
|
||||
|
||||
u32 m_Instance; ///< Channel 1,2,3 or 4
|
||||
|
||||
int m_ChunkSize;
|
||||
u8 Chunk[256];
|
||||
|
||||
bool m_hasLNA;
|
||||
bool m_hasDVBT;
|
||||
bool m_hasDVBC;
|
||||
bool m_hasAudio;
|
||||
bool m_hasATV;
|
||||
bool m_hasOOB;
|
||||
bool m_hasSAWSW; /**< TRUE if mat_tx is available */
|
||||
bool m_hasGPIO1; /**< TRUE if mat_rx is available */
|
||||
bool m_hasGPIO2; /**< TRUE if GPIO is available */
|
||||
bool m_hasIRQN; /**< TRUE if IRQN is available */
|
||||
u16 m_oscClockFreq;
|
||||
u16 m_HICfgTimingDiv;
|
||||
u16 m_HICfgBridgeDelay;
|
||||
u16 m_HICfgWakeUpKey;
|
||||
u16 m_HICfgTimeout;
|
||||
u16 m_HICfgCtrl;
|
||||
s32 m_sysClockFreq ; ///< system clock frequency in kHz
|
||||
|
||||
enum EDrxkState m_DrxkState; ///< State of Drxk (init,stopped,started)
|
||||
enum OperationMode m_OperationMode; ///< digital standards
|
||||
struct SCfgAgc m_vsbRfAgcCfg; ///< settings for VSB RF-AGC
|
||||
struct SCfgAgc m_vsbIfAgcCfg; ///< settings for VSB IF-AGC
|
||||
u16 m_vsbPgaCfg; ///< settings for VSB PGA
|
||||
struct SCfgPreSaw m_vsbPreSawCfg; ///< settings for pre SAW sense
|
||||
s32 m_Quality83percent; ///< MER level (*0.1 dB) for 83% quality indication
|
||||
s32 m_Quality93percent; ///< MER level (*0.1 dB) for 93% quality indication
|
||||
bool m_smartAntInverted;
|
||||
bool m_bDebugEnableBridge;
|
||||
bool m_bPDownOpenBridge; ///< only open DRXK bridge before power-down once it has been accessed
|
||||
bool m_bPowerDown; ///< Power down when not used
|
||||
|
||||
u32 m_IqmFsRateOfs; ///< frequency shift as written to DRXK register (28bit fixpoint)
|
||||
|
||||
bool m_enableMPEGOutput; /**< If TRUE, enable MPEG output */
|
||||
bool m_insertRSByte; /**< If TRUE, insert RS byte */
|
||||
bool m_enableParallel; /**< If TRUE, parallel out otherwise serial */
|
||||
bool m_invertDATA; /**< If TRUE, invert DATA signals */
|
||||
bool m_invertERR; /**< If TRUE, invert ERR signal */
|
||||
bool m_invertSTR; /**< If TRUE, invert STR signals */
|
||||
bool m_invertVAL; /**< If TRUE, invert VAL signals */
|
||||
bool m_invertCLK; /**< If TRUE, invert CLK signals */
|
||||
bool m_DVBCStaticCLK;
|
||||
bool m_DVBTStaticCLK; /**< If TRUE, static MPEG clockrate will
|
||||
be used, otherwise clockrate will
|
||||
adapt to the bitrate of the TS */
|
||||
u32 m_DVBTBitrate;
|
||||
u32 m_DVBCBitrate;
|
||||
|
||||
u8 m_TSDataStrength;
|
||||
u8 m_TSClockkStrength;
|
||||
|
||||
enum DRXMPEGStrWidth_t m_widthSTR; /**< MPEG start width**/
|
||||
u32 m_mpegTsStaticBitrate; /**< Maximum bitrate in b/s in case
|
||||
static clockrate is selected */
|
||||
|
||||
//LARGE_INTEGER m_StartTime; ///< Contains the time of the last demod start
|
||||
s32 m_MpegLockTimeOut; ///< WaitForLockStatus Timeout (counts from start time)
|
||||
s32 m_DemodLockTimeOut; ///< WaitForLockStatus Timeout (counts from start time)
|
||||
|
||||
bool m_disableTEIhandling;
|
||||
|
||||
bool m_RfAgcPol;
|
||||
bool m_IfAgcPol;
|
||||
|
||||
struct SCfgAgc m_atvRfAgcCfg; ///< settings for ATV RF-AGC
|
||||
struct SCfgAgc m_atvIfAgcCfg; ///< settings for ATV IF-AGC
|
||||
struct SCfgPreSaw m_atvPreSawCfg; ///< settings for ATV pre SAW sense
|
||||
bool m_phaseCorrectionBypass;
|
||||
s16 m_atvTopVidPeak;
|
||||
u16 m_atvTopNoiseTh;
|
||||
enum EDrxkSifAttenuation m_sifAttenuation;
|
||||
bool m_enableCVBSOutput;
|
||||
bool m_enableSIFOutput;
|
||||
bool m_bMirrorFreqSpect;
|
||||
enum EDrxkConstellation m_Constellation; ///< Constellation type of the channel
|
||||
u32 m_CurrSymbolRate; ///< Current QAM symbol rate
|
||||
struct SCfgAgc m_qamRfAgcCfg; ///< settings for QAM RF-AGC
|
||||
struct SCfgAgc m_qamIfAgcCfg; ///< settings for QAM IF-AGC
|
||||
u16 m_qamPgaCfg; ///< settings for QAM PGA
|
||||
struct SCfgPreSaw m_qamPreSawCfg; ///< settings for QAM pre SAW sense
|
||||
enum EDrxkInterleaveMode m_qamInterleaveMode; ///< QAM Interleave mode
|
||||
u16 m_fecRsPlen;
|
||||
u16 m_fecRsPrescale;
|
||||
|
||||
enum DRXKCfgDvbtSqiSpeed m_sqiSpeed;
|
||||
|
||||
u16 m_GPIO;
|
||||
u16 m_GPIOCfg;
|
||||
|
||||
struct SCfgAgc m_dvbtRfAgcCfg; ///< settings for QAM RF-AGC
|
||||
struct SCfgAgc m_dvbtIfAgcCfg; ///< settings for QAM IF-AGC
|
||||
struct SCfgPreSaw m_dvbtPreSawCfg; ///< settings for QAM pre SAW sense
|
||||
|
||||
u16 m_agcFastClipCtrlDelay;
|
||||
bool m_adcCompPassed;
|
||||
u16 m_adcCompCoef[64];
|
||||
u16 m_adcState;
|
||||
|
||||
u8 *m_microcode;
|
||||
int m_microcode_length;
|
||||
bool m_DRXK_A1_PATCH_CODE;
|
||||
bool m_DRXK_A1_ROM_CODE;
|
||||
bool m_DRXK_A2_ROM_CODE;
|
||||
bool m_DRXK_A3_ROM_CODE;
|
||||
bool m_DRXK_A2_PATCH_CODE;
|
||||
bool m_DRXK_A3_PATCH_CODE;
|
||||
|
||||
bool m_rfmirror;
|
||||
u8 m_deviceSpin;
|
||||
u32 m_iqmRcRate;
|
||||
|
||||
u16 m_AntennaDVBC;
|
||||
u16 m_AntennaDVBT;
|
||||
u16 m_AntennaSwitchDVBTDVBC;
|
||||
|
||||
DRXPowerMode_t m_currentPowerMode;
|
||||
};
|
||||
|
||||
#define NEVER_LOCK 0
|
||||
#define NOT_LOCKED 1
|
||||
#define DEMOD_LOCK 2
|
||||
#define FEC_LOCK 3
|
||||
#define MPEG_LOCK 4
|
||||
|
16438
frontends/drxk_map.h
Normal file
16438
frontends/drxk_map.h
Normal file
File diff suppressed because it is too large
Load Diff
4340
frontends/drxk_map_b.h
Normal file
4340
frontends/drxk_map_b.h
Normal file
File diff suppressed because it is too large
Load Diff
55
frontends/lnbh24.h
Normal file
55
frontends/lnbh24.h
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* lnbh24.h - driver for lnb supply and control ic lnbh24
|
||||
*
|
||||
* Copyright (C) 2009 NetUP Inc.
|
||||
* Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
|
||||
*
|
||||
* 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; either version 2 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef _LNBH24_H
|
||||
#define _LNBH24_H
|
||||
|
||||
/* system register bits */
|
||||
#define LNBH24_OLF 0x01
|
||||
#define LNBH24_OTF 0x02
|
||||
#define LNBH24_EN 0x04
|
||||
#define LNBH24_VSEL 0x08
|
||||
#define LNBH24_LLC 0x10
|
||||
#define LNBH24_TEN 0x20
|
||||
#define LNBH24_TTX 0x40
|
||||
#define LNBH24_PCL 0x80
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
|
||||
&& defined(MODULE))
|
||||
/* override_set and override_clear control which
|
||||
system register bits (above) to always set & clear */
|
||||
extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, u8 override_set,
|
||||
u8 override_clear, u8 i2c_addr);
|
||||
#else
|
||||
static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, u8 override_set,
|
||||
u8 override_clear, u8 i2c_addr)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
157
frontends/lnbh25.c
Normal file
157
frontends/lnbh25.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* Driver for the ST LNBH25
|
||||
*
|
||||
* Copyright (C) 2014 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 <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "lnbh25.h"
|
||||
|
||||
struct lnbh25 {
|
||||
struct i2c_adapter *i2c;
|
||||
u8 adr;
|
||||
u8 reg[4];
|
||||
u8 boost;
|
||||
};
|
||||
|
||||
static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 *data, int len)
|
||||
{
|
||||
struct i2c_msg msg = {.addr = adr, .flags = 0,
|
||||
.buf = data, .len = len};
|
||||
|
||||
if (i2c_transfer(adap, &msg, 1) != 1) {
|
||||
pr_err("lnbh25: i2c_write error\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lnbh25_write_regs(struct lnbh25 *lnbh, int reg, int len)
|
||||
{
|
||||
u8 d[5];
|
||||
|
||||
memcpy(&d[1], &lnbh->reg[reg], len);
|
||||
d[0] = reg + 2;
|
||||
return i2c_write(lnbh->i2c, lnbh->adr, d, len + 1);
|
||||
}
|
||||
|
||||
static int lnbh25_set_voltage(struct dvb_frontend *fe,
|
||||
fe_sec_voltage_t voltage)
|
||||
{
|
||||
struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv;
|
||||
u8 oldreg0 = lnbh->reg[0];
|
||||
|
||||
switch (voltage) {
|
||||
case SEC_VOLTAGE_OFF:
|
||||
lnbh->reg[0] = 0x00;
|
||||
lnbh->reg[1] &= ~0x01; /* Disable Tone */
|
||||
lnbh->reg[2] = 0x00;
|
||||
return lnbh25_write_regs(lnbh, 0, 3);
|
||||
case SEC_VOLTAGE_13:
|
||||
lnbh->reg[0] = lnbh->boost + 1;
|
||||
break;
|
||||
case SEC_VOLTAGE_18:
|
||||
lnbh->reg[0] = lnbh->boost + 8;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
if (lnbh->reg[0] == 0x00) {
|
||||
lnbh->reg[2] = 4;
|
||||
lnbh25_write_regs(lnbh, 2, 2);
|
||||
} else if (lnbh->reg[2] != 0x00) {
|
||||
lnbh->reg[2] = 0;
|
||||
lnbh25_write_regs(lnbh, 2, 2);
|
||||
}
|
||||
lnbh->reg[1] |= 0x01;
|
||||
lnbh25_write_regs(lnbh, 0, 3);
|
||||
if (oldreg0 == 0)
|
||||
msleep(100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lnbh25_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
|
||||
{
|
||||
struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv;
|
||||
|
||||
lnbh->boost = arg ? 3 : 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lnbh25_set_tone(struct dvb_frontend *fe,
|
||||
fe_sec_tone_mode_t tone)
|
||||
{
|
||||
/* struct lnbh25 *lnbh = (struct lnbh25 *) fe->sec_priv; */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lnbh25_init(struct lnbh25 *lnbh)
|
||||
{
|
||||
return lnbh25_write_regs(lnbh, 0, 2);
|
||||
}
|
||||
|
||||
static void lnbh25_release(struct dvb_frontend *fe)
|
||||
{
|
||||
kfree(fe->sec_priv);
|
||||
fe->sec_priv = NULL;
|
||||
}
|
||||
|
||||
struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
u8 adr)
|
||||
{
|
||||
struct lnbh25 *lnbh = kzalloc(sizeof(struct lnbh25), GFP_KERNEL);
|
||||
if (!lnbh)
|
||||
return NULL;
|
||||
|
||||
lnbh->i2c = i2c;
|
||||
lnbh->adr = adr;
|
||||
lnbh->boost = 3;
|
||||
|
||||
if (lnbh25_init(lnbh)) {
|
||||
kfree(lnbh);
|
||||
return NULL;
|
||||
}
|
||||
fe->sec_priv = lnbh;
|
||||
fe->ops.set_voltage = lnbh25_set_voltage;
|
||||
fe->ops.enable_high_lnb_voltage = lnbh25_enable_high_lnb_voltage;
|
||||
fe->ops.release_sec = lnbh25_release;
|
||||
|
||||
pr_info("LNB25 on %02x\n", lnbh->adr);
|
||||
|
||||
return fe;
|
||||
}
|
||||
EXPORT_SYMBOL(lnbh25_attach);
|
||||
|
||||
MODULE_DESCRIPTION("LNBH25");
|
||||
MODULE_AUTHOR("Ralph Metzler");
|
||||
MODULE_LICENSE("GPL");
|
28
frontends/lnbh25.h
Normal file
28
frontends/lnbh25.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* lnbh25.h
|
||||
*/
|
||||
|
||||
#ifndef _LNBH25_H
|
||||
#define _LNBH25_H
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#if defined(CONFIG_DVB_LNBH25) || \
|
||||
(defined(CONFIG_DVB_LNBH25_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
u8 i2c_addr);
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c,
|
||||
u8 i2c_addr)
|
||||
{
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
194
frontends/lnbp21.c
Normal file
194
frontends/lnbp21.c
Normal file
@ -0,0 +1,194 @@
|
||||
/*
|
||||
* lnbp21.c - driver for lnb supply and control ic lnbp21
|
||||
*
|
||||
* Copyright (C) 2006, 2009 Oliver Endriss <o.endriss@gmx.de>
|
||||
* Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
|
||||
*
|
||||
* 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; either version 2
|
||||
* 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 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.
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
*
|
||||
* the project's page is at http://www.linuxtv.org
|
||||
*/
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "lnbp21.h"
|
||||
#include "lnbh24.h"
|
||||
|
||||
struct lnbp21 {
|
||||
u8 config;
|
||||
u8 override_or;
|
||||
u8 override_and;
|
||||
struct i2c_adapter *i2c;
|
||||
u8 i2c_addr;
|
||||
};
|
||||
|
||||
static int lnbp21_set_voltage(struct dvb_frontend *fe,
|
||||
fe_sec_voltage_t voltage)
|
||||
{
|
||||
struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
|
||||
struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
|
||||
.buf = &lnbp21->config,
|
||||
.len = sizeof(lnbp21->config) };
|
||||
|
||||
lnbp21->config &= ~(LNBP21_VSEL | LNBP21_EN);
|
||||
|
||||
|
||||
if ((lnbp21->config & LNBP21_EN) == 0)
|
||||
lnbp21->config |= 0x80;
|
||||
else
|
||||
lnbp21->config &= 0x7f;
|
||||
|
||||
switch(voltage) {
|
||||
case SEC_VOLTAGE_OFF:
|
||||
break;
|
||||
case SEC_VOLTAGE_13:
|
||||
lnbp21->config |= LNBP21_EN;
|
||||
break;
|
||||
case SEC_VOLTAGE_18:
|
||||
lnbp21->config |= (LNBP21_EN | LNBP21_VSEL);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
lnbp21->config |= lnbp21->override_or;
|
||||
lnbp21->config &= lnbp21->override_and;
|
||||
|
||||
return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
|
||||
{
|
||||
struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
|
||||
struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
|
||||
.buf = &lnbp21->config,
|
||||
.len = sizeof(lnbp21->config) };
|
||||
|
||||
if (arg)
|
||||
lnbp21->config |= LNBP21_LLC;
|
||||
else
|
||||
lnbp21->config &= ~LNBP21_LLC;
|
||||
|
||||
lnbp21->config |= lnbp21->override_or;
|
||||
lnbp21->config &= lnbp21->override_and;
|
||||
|
||||
return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static int lnbp21_set_tone(struct dvb_frontend *fe,
|
||||
fe_sec_tone_mode_t tone)
|
||||
{
|
||||
struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
|
||||
struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
|
||||
.buf = &lnbp21->config,
|
||||
.len = sizeof(lnbp21->config) };
|
||||
|
||||
switch (tone) {
|
||||
case SEC_TONE_OFF:
|
||||
lnbp21->config &= ~LNBP21_TEN;
|
||||
break;
|
||||
case SEC_TONE_ON:
|
||||
lnbp21->config |= LNBP21_TEN;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
lnbp21->config |= lnbp21->override_or;
|
||||
lnbp21->config &= lnbp21->override_and;
|
||||
|
||||
return (i2c_transfer(lnbp21->i2c, &msg, 1) == 1) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static void lnbp21_release(struct dvb_frontend *fe)
|
||||
{
|
||||
/* LNBP power off */
|
||||
lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
|
||||
|
||||
/* free data */
|
||||
kfree(fe->sec_priv);
|
||||
fe->sec_priv = NULL;
|
||||
}
|
||||
|
||||
static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, u8 override_set,
|
||||
u8 override_clear, u8 i2c_addr, u8 config)
|
||||
{
|
||||
struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
|
||||
if (!lnbp21)
|
||||
return NULL;
|
||||
|
||||
/* default configuration */
|
||||
lnbp21->config = config;
|
||||
lnbp21->i2c = i2c;
|
||||
lnbp21->i2c_addr = i2c_addr;
|
||||
fe->sec_priv = lnbp21;
|
||||
|
||||
/* bits which should be forced to '1' */
|
||||
lnbp21->override_or = override_set;
|
||||
|
||||
/* bits which should be forced to '0' */
|
||||
lnbp21->override_and = ~override_clear;
|
||||
|
||||
/* detect if it is present or not */
|
||||
if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) {
|
||||
kfree(lnbp21);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* install release callback */
|
||||
fe->ops.release_sec = lnbp21_release;
|
||||
|
||||
/* override frontend ops */
|
||||
fe->ops.set_voltage = lnbp21_set_voltage;
|
||||
fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
|
||||
if (!(override_clear & LNBH24_TEN)) /*22kHz logic controlled by demod*/
|
||||
fe->ops.set_tone = lnbp21_set_tone;
|
||||
printk(KERN_INFO "LNBx2x attached on addr=%x\n", lnbp21->i2c_addr);
|
||||
|
||||
return fe;
|
||||
}
|
||||
|
||||
struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, u8 override_set,
|
||||
u8 override_clear, u8 i2c_addr)
|
||||
{
|
||||
return lnbx2x_attach(fe, i2c, override_set, override_clear,
|
||||
i2c_addr, LNBH24_TTX);
|
||||
}
|
||||
EXPORT_SYMBOL(lnbh24_attach);
|
||||
|
||||
struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, u8 override_set,
|
||||
u8 override_clear)
|
||||
{
|
||||
return lnbx2x_attach(fe, i2c, override_set, override_clear,
|
||||
0x08, LNBP21_ISEL);
|
||||
}
|
||||
EXPORT_SYMBOL(lnbp21_attach);
|
||||
|
||||
MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
|
||||
MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
|
||||
MODULE_LICENSE("GPL");
|
75
frontends/lnbp21.h
Normal file
75
frontends/lnbp21.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* lnbp21.h - driver for lnb supply and control ic lnbp21
|
||||
*
|
||||
* Copyright (C) 2006 Oliver Endriss
|
||||
*
|
||||
* 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; either version 2
|
||||
* 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 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.
|
||||
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
*
|
||||
* the project's page is at http://www.linuxtv.org
|
||||
*/
|
||||
|
||||
#ifndef _LNBP21_H
|
||||
#define _LNBP21_H
|
||||
|
||||
/* system register bits */
|
||||
/* [RO] 0=OK; 1=over current limit flag */
|
||||
#define LNBP21_OLF 0x01
|
||||
/* [RO] 0=OK; 1=over temperature flag (150 C) */
|
||||
#define LNBP21_OTF 0x02
|
||||
/* [RW] 0=disable LNB power, enable loopthrough
|
||||
1=enable LNB power, disable loopthrough */
|
||||
#define LNBP21_EN 0x04
|
||||
/* [RW] 0=low voltage (13/14V, vert pol)
|
||||
1=high voltage (18/19V,horiz pol) */
|
||||
#define LNBP21_VSEL 0x08
|
||||
/* [RW] increase LNB voltage by 1V:
|
||||
0=13/18V; 1=14/19V */
|
||||
#define LNBP21_LLC 0x10
|
||||
/* [RW] 0=tone controlled by DSQIN pin
|
||||
1=tone enable, disable DSQIN */
|
||||
#define LNBP21_TEN 0x20
|
||||
/* [RW] current limit select:
|
||||
0:Iout=500-650mA Isc=300mA
|
||||
1:Iout=400-550mA Isc=200mA */
|
||||
#define LNBP21_ISEL 0x40
|
||||
/* [RW] short-circuit protect:
|
||||
0=pulsed (dynamic) curr limiting
|
||||
1=static curr limiting */
|
||||
#define LNBP21_PCL 0x80
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
|
||||
&& defined(MODULE))
|
||||
/* override_set and override_clear control which
|
||||
system register bits (above) to always set & clear */
|
||||
extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, u8 override_set,
|
||||
u8 override_clear);
|
||||
#else
|
||||
static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
|
||||
struct i2c_adapter *i2c, u8 override_set,
|
||||
u8 override_clear)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
1735
frontends/mxl5xx.c
Normal file
1735
frontends/mxl5xx.c
Normal file
File diff suppressed because it is too large
Load Diff
39
frontends/mxl5xx.h
Normal file
39
frontends/mxl5xx.h
Normal file
@ -0,0 +1,39 @@
|
||||
#ifndef _MXL5XX_H_
|
||||
#define _MXL5XX_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
struct mxl5xx_cfg {
|
||||
u8 adr;
|
||||
u8 type;
|
||||
u32 cap;
|
||||
u32 clk;
|
||||
u32 ts_clk;
|
||||
|
||||
u8 *fw;
|
||||
u32 fw_len;
|
||||
|
||||
int (*fw_read)(void *priv, u8 *buf, u32 len);
|
||||
void *fw_priv;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_MXL5XX) || \
|
||||
(defined(CONFIG_DVB_MXL5XX_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
|
||||
struct mxl5xx_cfg *cfg,
|
||||
u32 demod, u32 tuner);
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c,
|
||||
struct mxl5xx_cfg *cfg,
|
||||
u32 demod, u32 tuner)
|
||||
{
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
819
frontends/mxl5xx_defs.h
Normal file
819
frontends/mxl5xx_defs.h
Normal file
@ -0,0 +1,819 @@
|
||||
/*
|
||||
* Defines for the Maxlinear MX58x family of tuners/demods
|
||||
*
|
||||
* Copyright (C) 2014 Digital Devices GmbH
|
||||
*
|
||||
* based on code:
|
||||
* Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved
|
||||
* which was released under GPL V2
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_DISABLE = 0,
|
||||
MXL_ENABLE = 1,
|
||||
|
||||
MXL_FALSE = 0,
|
||||
MXL_TRUE = 1,
|
||||
|
||||
MXL_INVALID = 0,
|
||||
MXL_VALID = 1,
|
||||
|
||||
MXL_NO = 0,
|
||||
MXL_YES = 1,
|
||||
|
||||
MXL_OFF = 0,
|
||||
MXL_ON = 1
|
||||
} MXL_BOOL_E;
|
||||
|
||||
// Firmware-Host Command IDs
|
||||
typedef enum
|
||||
{
|
||||
//--Device command IDs--
|
||||
MXL_HYDRA_DEV_NO_OP_CMD = 0, //No OP
|
||||
|
||||
MXL_HYDRA_DEV_SET_POWER_MODE_CMD = 1,
|
||||
MXL_HYDRA_DEV_SET_OVERWRITE_DEF_CMD = 2,
|
||||
|
||||
// Host-used CMD, not used by firmware
|
||||
MXL_HYDRA_DEV_FIRMWARE_DOWNLOAD_CMD = 3,
|
||||
|
||||
// Additional CONTROL types from DTV
|
||||
MXL_HYDRA_DEV_SET_BROADCAST_PID_STB_ID_CMD = 4,
|
||||
MXL_HYDRA_DEV_GET_PMM_SLEEP_CMD = 5,
|
||||
|
||||
//--Tuner command IDs--
|
||||
MXL_HYDRA_TUNER_TUNE_CMD = 6,
|
||||
MXL_HYDRA_TUNER_GET_STATUS_CMD = 7,
|
||||
|
||||
//--Demod command IDs--
|
||||
MXL_HYDRA_DEMOD_SET_PARAM_CMD = 8,
|
||||
MXL_HYDRA_DEMOD_GET_STATUS_CMD = 9,
|
||||
|
||||
MXL_HYDRA_DEMOD_RESET_FEC_COUNTER_CMD = 10,
|
||||
|
||||
MXL_HYDRA_DEMOD_SET_PKT_NUM_CMD = 11,
|
||||
|
||||
MXL_HYDRA_DEMOD_SET_IQ_SOURCE_CMD = 12,
|
||||
MXL_HYDRA_DEMOD_GET_IQ_DATA_CMD = 13,
|
||||
|
||||
MXL_HYDRA_DEMOD_GET_M68HC05_VER_CMD = 14,
|
||||
|
||||
MXL_HYDRA_DEMOD_SET_ERROR_COUNTER_MODE_CMD = 15,
|
||||
|
||||
//--- ABORT channel tune
|
||||
MXL_HYDRA_ABORT_TUNE_CMD = 16, // Abort current tune command.
|
||||
|
||||
//--SWM/FSK command IDs--
|
||||
MXL_HYDRA_FSK_RESET_CMD = 17,
|
||||
MXL_HYDRA_FSK_MSG_CMD = 18,
|
||||
MXL_HYDRA_FSK_SET_OP_MODE_CMD = 19,
|
||||
|
||||
//--DiSeqC command IDs--
|
||||
MXL_HYDRA_DISEQC_MSG_CMD = 20,
|
||||
MXL_HYDRA_DISEQC_COPY_MSG_TO_MAILBOX = 21,
|
||||
MXL_HYDRA_DISEQC_CFG_MSG_CMD = 22,
|
||||
|
||||
//--- FFT Debug Command IDs--
|
||||
MXL_HYDRA_REQ_FFT_SPECTRUM_CMD = 23,
|
||||
|
||||
// -- Demod scramblle code
|
||||
MXL_HYDRA_DEMOD_SCRAMBLE_CODE_CMD = 24,
|
||||
|
||||
//---For host to know how many commands in total---
|
||||
MXL_HYDRA_LAST_HOST_CMD = 25,
|
||||
|
||||
MXL_HYDRA_DEMOD_INTR_TYPE_CMD = 47,
|
||||
MXL_HYDRA_DEV_INTR_CLEAR_CMD = 48,
|
||||
MXL_HYDRA_TUNER_SPECTRUM_REQ_CMD = 53,
|
||||
MXL_HYDRA_TUNER_ACTIVATE_CMD = 55,
|
||||
MXL_HYDRA_DEV_CFG_POWER_MODE_CMD = 56,
|
||||
MXL_HYDRA_DEV_XTAL_CAP_CMD = 57,
|
||||
MXL_HYDRA_DEV_CFG_SKU_CMD = 58,
|
||||
MXL_HYDRA_TUNER_SPECTRUM_MIN_GAIN_CMD = 59,
|
||||
MXL_HYDRA_DISEQC_CONT_TONE_CFG = 60,
|
||||
MXL_HYDRA_DEV_RF_WAKE_UP_CMD = 61,
|
||||
MXL_HYDRA_DEMOD_CFG_EQ_CTRL_PARAM_CMD = 62,
|
||||
MXL_HYDRA_DEMOD_FREQ_OFFSET_SEARCH_RANGE_CMD = 63,
|
||||
MXL_HYDRA_DEV_REQ_PWR_FROM_ADCRSSI_CMD = 64,
|
||||
|
||||
MXL_XCPU_PID_FLT_CFG_CMD = 65,
|
||||
MXL_XCPU_SHMEM_TEST_CMD = 66,
|
||||
MXL_XCPU_ABORT_TUNE_CMD = 67,
|
||||
MXL_XCPU_CHAN_TUNE_CMD = 68,
|
||||
MXL_XCPU_FLT_BOND_HDRS_CMD = 69,
|
||||
|
||||
MXL_HYDRA_DEV_BROADCAST_WAKE_UP_CMD = 70,
|
||||
MXL_HYDRA_FSK_CFG_FSK_FREQ_CMD = 71,
|
||||
MXL_HYDRA_FSK_POWER_DOWN_CMD = 72,
|
||||
MXL_XCPU_CLEAR_CB_STATS_CMD = 73,
|
||||
MXL_XCPU_CHAN_BOND_RESTART_CMD = 74
|
||||
} MXL_HYDRA_HOST_CMD_ID_E;
|
||||
|
||||
#define MXL_ENABLE_BIG_ENDIAN (0)
|
||||
|
||||
#define MXL_HYDRA_OEM_MAX_BLOCK_WRITE_LENGTH 248
|
||||
|
||||
#define MXL_HYDRA_OEM_MAX_CMD_BUFF_LEN (248)
|
||||
|
||||
#define MXL_HYDRA_CAP_MIN 10
|
||||
#define MXL_HYDRA_CAP_MAX 33
|
||||
|
||||
#define MXL_HYDRA_PLID_REG_READ 0xFB // Read register PLID
|
||||
#define MXL_HYDRA_PLID_REG_WRITE 0xFC // Write register PLID
|
||||
|
||||
#define MXL_HYDRA_PLID_CMD_READ 0xFD // Command Read PLID
|
||||
#define MXL_HYDRA_PLID_CMD_WRITE 0xFE // Command Write PLID
|
||||
|
||||
#define MXL_HYDRA_REG_SIZE_IN_BYTES 4 // Hydra register size in bytes
|
||||
#define MXL_HYDRA_I2C_HDR_SIZE (2 * sizeof(u8)) // PLID + LEN(0xFF)
|
||||
#define MXL_HYDRA_CMD_HEADER_SIZE (MXL_HYDRA_REG_SIZE_IN_BYTES + MXL_HYDRA_I2C_HDR_SIZE)
|
||||
|
||||
#define MXL_HYDRA_SKU_ID_581 0
|
||||
#define MXL_HYDRA_SKU_ID_584 1
|
||||
#define MXL_HYDRA_SKU_ID_585 2
|
||||
#define MXL_HYDRA_SKU_ID_544 3
|
||||
#define MXL_HYDRA_SKU_ID_561 4
|
||||
#define MXL_HYDRA_SKU_ID_582 5
|
||||
#define MXL_HYDRA_SKU_ID_568 6
|
||||
|
||||
// macro for register write data buffer size (PLID + LEN (0xFF) + RegAddr + RegData)
|
||||
#define MXL_HYDRA_REG_WRITE_LEN (MXL_HYDRA_I2C_HDR_SIZE + (2 * MXL_HYDRA_REG_SIZE_IN_BYTES))
|
||||
|
||||
// maro to extract a single byte from 4-byte(32-bit) data
|
||||
#define GET_BYTE(x,n) (((x) >> (8*(n))) & 0xFF)
|
||||
|
||||
#define MAX_CMD_DATA 512
|
||||
|
||||
#define MXL_GET_REG_MASK_32(lsbLoc,numOfBits) ((0xFFFFFFFF >> (32 - (numOfBits))) << (lsbLoc))
|
||||
|
||||
#define GET_REG_FIELD_DATA(fieldName, dataPtr) read_by_mnemonic(state, fieldName, dataPtr);
|
||||
#define SET_REG_FIELD_DATA(fieldName, data) update_by_mnemonic(state, fieldName, data);
|
||||
|
||||
#define FW_DL_SIGN (0xDEADBEEF)
|
||||
|
||||
#define MBIN_FORMAT_VERSION '1'
|
||||
#define MBIN_FILE_HEADER_ID 'M'
|
||||
#define MBIN_SEGMENT_HEADER_ID 'S'
|
||||
#define MBIN_MAX_FILE_LENGTH (1<<23)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 id;
|
||||
u8 fmtVersion;
|
||||
u8 headerLen;
|
||||
u8 numSegments;
|
||||
u8 entryAddress[4];
|
||||
u8 imageSize24[3];
|
||||
u8 imageChecksum;
|
||||
u8 reserved[4];
|
||||
} MBIN_FILE_HEADER_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MBIN_FILE_HEADER_T header;
|
||||
u8 data[1];
|
||||
} MBIN_FILE_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 id;
|
||||
u8 len24[3];
|
||||
u8 address[4];
|
||||
} MBIN_SEGMENT_HEADER_T;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MBIN_SEGMENT_HEADER_T header;
|
||||
u8 data[1];
|
||||
} MBIN_SEGMENT_T;
|
||||
|
||||
|
||||
typedef enum { MXL_CMD_WRITE = 0, MXL_CMD_READ} MXL_CMD_TYPE_E;
|
||||
|
||||
#define BUILD_HYDRA_CMD(cmdID, reqType, size, dataPtr, cmdBuff) \
|
||||
do { \
|
||||
cmdBuff[0] = ((reqType == MXL_CMD_WRITE) ? MXL_HYDRA_PLID_CMD_WRITE : MXL_HYDRA_PLID_CMD_READ); \
|
||||
cmdBuff[1] = (size > 251) ? 0xff : (u8) (size + 4); \
|
||||
cmdBuff[2] = size; \
|
||||
cmdBuff[3] = cmdID; \
|
||||
cmdBuff[4] = 0x00; \
|
||||
cmdBuff[5] = 0x00; \
|
||||
convert_endian(MXL_ENABLE_BIG_ENDIAN, size, (u8 *)dataPtr); \
|
||||
memcpy((void *)&cmdBuff[6], dataPtr, size); \
|
||||
} while(0) //;
|
||||
|
||||
typedef struct {
|
||||
u32 regAddr;
|
||||
u8 lsbPos;
|
||||
u8 numOfBits;
|
||||
} MXL_REG_FIELD_T;
|
||||
|
||||
typedef struct {
|
||||
u32 dataSize;
|
||||
u8 data[MAX_CMD_DATA];
|
||||
} MXL_DEV_CMD_DATA_T;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_SKU_TYPE_MIN = 0x00,
|
||||
MXL_HYDRA_SKU_TYPE_581 = 0x00,
|
||||
MXL_HYDRA_SKU_TYPE_584 = 0x01,
|
||||
MXL_HYDRA_SKU_TYPE_585 = 0x02,
|
||||
MXL_HYDRA_SKU_TYPE_544 = 0x03,
|
||||
MXL_HYDRA_SKU_TYPE_561 = 0x04,
|
||||
MXL_HYDRA_SKU_TYPE_5xx = 0x05,
|
||||
MXL_HYDRA_SKU_TYPE_5yy = 0x06,
|
||||
MXL_HYDRA_SKU_TYPE_511 = 0x07,
|
||||
MXL_HYDRA_SKU_TYPE_561_DE = 0x08,
|
||||
MXL_HYDRA_SKU_TYPE_582 = 0x09,
|
||||
MXL_HYDRA_SKU_TYPE_541 = 0x0A,
|
||||
MXL_HYDRA_SKU_TYPE_568 = 0x0B,
|
||||
MXL_HYDRA_SKU_TYPE_542 = 0x0C,
|
||||
MXL_HYDRA_SKU_TYPE_MAX = 0x0D,
|
||||
} MXL_HYDRA_SKU_TYPE_E;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MXL_HYDRA_SKU_TYPE_E skuType;
|
||||
} MXL_HYDRA_SKU_COMMAND_T;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_DEMOD_ID_0 = 0,
|
||||
MXL_HYDRA_DEMOD_ID_1,
|
||||
MXL_HYDRA_DEMOD_ID_2,
|
||||
MXL_HYDRA_DEMOD_ID_3,
|
||||
MXL_HYDRA_DEMOD_ID_4,
|
||||
MXL_HYDRA_DEMOD_ID_5,
|
||||
MXL_HYDRA_DEMOD_ID_6,
|
||||
MXL_HYDRA_DEMOD_ID_7,
|
||||
MXL_HYDRA_DEMOD_MAX
|
||||
} MXL_HYDRA_DEMOD_ID_E;
|
||||
|
||||
#define MXL_DEMOD_SCRAMBLE_SEQ_LEN 12
|
||||
|
||||
#define MAX_STEP_SIZE_24_XTAL_102_05_KHZ 195
|
||||
#define MAX_STEP_SIZE_24_XTAL_204_10_KHZ 215
|
||||
#define MAX_STEP_SIZE_24_XTAL_306_15_KHZ 203
|
||||
#define MAX_STEP_SIZE_24_XTAL_408_20_KHZ 177
|
||||
|
||||
#define MAX_STEP_SIZE_27_XTAL_102_05_KHZ 195
|
||||
#define MAX_STEP_SIZE_27_XTAL_204_10_KHZ 215
|
||||
#define MAX_STEP_SIZE_27_XTAL_306_15_KHZ 203
|
||||
#define MAX_STEP_SIZE_27_XTAL_408_20_KHZ 177
|
||||
|
||||
#define MXL_HYDRA_SPECTRUM_MIN_FREQ_KHZ 300000
|
||||
#define MXL_HYDRA_SPECTRUM_MAX_FREQ_KHZ 2350000
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DMD_STANDARD_ADDR = 0,
|
||||
DMD_SPECTRUM_INVERSION_ADDR,
|
||||
DMD_SPECTRUM_ROLL_OFF_ADDR,
|
||||
DMD_SYMBOL_RATE_ADDR,
|
||||
DMD_MODULATION_SCHEME_ADDR,
|
||||
DMD_FEC_CODE_RATE_ADDR,
|
||||
DMD_SNR_ADDR,
|
||||
DMD_FREQ_OFFSET_ADDR,
|
||||
DMD_CTL_FREQ_OFFSET_ADDR,
|
||||
DMD_STR_FREQ_OFFSET_ADDR,
|
||||
DMD_FTL_FREQ_OFFSET_ADDR,
|
||||
DMD_STR_NBC_SYNC_LOCK_ADDR,
|
||||
DMD_CYCLE_SLIP_COUNT_ADDR,
|
||||
DMD_DISPLAY_IQ_ADDR,
|
||||
DMD_DVBS2_CRC_ERRORS_ADDR,
|
||||
DMD_DVBS2_PER_COUNT_ADDR,
|
||||
DMD_DVBS2_PER_WINDOW_ADDR,
|
||||
DMD_DVBS_CORR_RS_ERRORS_ADDR,
|
||||
DMD_DVBS_UNCORR_RS_ERRORS_ADDR,
|
||||
DMD_DVBS_BER_COUNT_ADDR,
|
||||
DMD_DVBS_BER_WINDOW_ADDR,
|
||||
DMD_TUNER_ID_ADDR,
|
||||
DMD_DVBS2_PILOT_ON_OFF_ADDR,
|
||||
DMD_FREQ_SEARCH_RANGE_IN_KHZ_ADDR,
|
||||
|
||||
MXL_DEMOD_CHAN_PARAMS_BUFF_SIZE,
|
||||
} MXL_DEMOD_CHAN_PARAMS_OFFSET_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_TUNER_ID_0 = 0,
|
||||
MXL_HYDRA_TUNER_ID_1,
|
||||
MXL_HYDRA_TUNER_ID_2,
|
||||
MXL_HYDRA_TUNER_ID_3,
|
||||
MXL_HYDRA_TUNER_MAX
|
||||
} MXL_HYDRA_TUNER_ID_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_DSS = 0,
|
||||
MXL_HYDRA_DVBS,
|
||||
MXL_HYDRA_DVBS2,
|
||||
} MXL_HYDRA_BCAST_STD_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_FEC_AUTO = 0,
|
||||
MXL_HYDRA_FEC_1_2,
|
||||
MXL_HYDRA_FEC_3_5,
|
||||
MXL_HYDRA_FEC_2_3,
|
||||
MXL_HYDRA_FEC_3_4,
|
||||
MXL_HYDRA_FEC_4_5,
|
||||
MXL_HYDRA_FEC_5_6,
|
||||
MXL_HYDRA_FEC_6_7,
|
||||
MXL_HYDRA_FEC_7_8,
|
||||
MXL_HYDRA_FEC_8_9,
|
||||
MXL_HYDRA_FEC_9_10,
|
||||
} MXL_HYDRA_FEC_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_MOD_AUTO = 0,
|
||||
MXL_HYDRA_MOD_QPSK,
|
||||
MXL_HYDRA_MOD_8PSK
|
||||
} MXL_HYDRA_MODULATION_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_SPECTRUM_AUTO = 0,
|
||||
MXL_HYDRA_SPECTRUM_INVERTED,
|
||||
MXL_HYDRA_SPECTRUM_NON_INVERTED,
|
||||
} MXL_HYDRA_SPECTRUM_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_ROLLOFF_AUTO = 0,
|
||||
MXL_HYDRA_ROLLOFF_0_20,
|
||||
MXL_HYDRA_ROLLOFF_0_25,
|
||||
MXL_HYDRA_ROLLOFF_0_35
|
||||
} MXL_HYDRA_ROLLOFF_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_PILOTS_OFF = 0,
|
||||
MXL_HYDRA_PILOTS_ON,
|
||||
MXL_HYDRA_PILOTS_AUTO
|
||||
} MXL_HYDRA_PILOTS_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_FORMATTER = 0,
|
||||
MXL_HYDRA_LEGACY_FEC,
|
||||
MXL_HYDRA_FREQ_RECOVERY,
|
||||
MXL_HYDRA_NBC,
|
||||
MXL_HYDRA_CTL,
|
||||
MXL_HYDRA_EQ,
|
||||
} MXL_HYDRA_CONSTELLATION_SRC_E;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int agcLock; // AGC lock info
|
||||
int fecLock; // Demod FEC block lock info
|
||||
} MXL_HYDRA_DEMOD_LOCK_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 rsErrors; // RS decoder err counter
|
||||
u32 berWindow; // Ber Windows
|
||||
u32 berCount; // BER count
|
||||
u32 berWindow_Iter1; // Ber Windows - post viterbi
|
||||
u32 berCount_Iter1; // BER count - post viterbi
|
||||
} MXL_HYDRA_DEMOD_STATUS_DVBS_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 rsErrors; // RS decoder err counter
|
||||
u32 berWindow; // Ber Windows
|
||||
u32 berCount; // BER count
|
||||
} MXL_HYDRA_DEMOD_STATUS_DSS_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 crcErrors; // CRC error counter
|
||||
u32 packetErrorCount; // Number of packet errors
|
||||
u32 totalPackets; // Total packets
|
||||
} MXL_HYDRA_DEMOD_STATUS_DVBS2_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MXL_HYDRA_BCAST_STD_E standardMask; // Standard DVB-S, DVB-S2 or DSS
|
||||
|
||||
union
|
||||
{
|
||||
MXL_HYDRA_DEMOD_STATUS_DVBS_T demodStatus_DVBS; // DVB-S demod status
|
||||
MXL_HYDRA_DEMOD_STATUS_DVBS2_T demodStatus_DVBS2; // DVB-S2 demod status
|
||||
MXL_HYDRA_DEMOD_STATUS_DSS_T demodStatus_DSS; // DSS demod status
|
||||
} u;
|
||||
|
||||
} MXL_HYDRA_DEMOD_STATUS_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s32 carrierOffsetInHz; // CRL offset info
|
||||
s32 symbolOffsetInSymbol; // SRL offset info
|
||||
} MXL_HYDRA_DEMOD_SIG_OFFSET_INFO_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 scrambleSequence[MXL_DEMOD_SCRAMBLE_SEQ_LEN]; // scramble sequence
|
||||
u32 scrambleCode; // scramble gold code
|
||||
} MXL_HYDRA_DEMOD_SCRAMBLE_INFO_T;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_STEP_SIZE_24_XTAL_102_05KHZ, // 102.05 KHz for 24 MHz XTAL
|
||||
MXL_HYDRA_STEP_SIZE_24_XTAL_204_10KHZ, // 204.10 KHz for 24 MHz XTAL
|
||||
MXL_HYDRA_STEP_SIZE_24_XTAL_306_15KHZ, // 306.15 KHz for 24 MHz XTAL
|
||||
MXL_HYDRA_STEP_SIZE_24_XTAL_408_20KHZ, // 408.20 KHz for 24 MHz XTAL
|
||||
|
||||
MXL_HYDRA_STEP_SIZE_27_XTAL_102_05KHZ, // 102.05 KHz for 27 MHz XTAL
|
||||
MXL_HYDRA_STEP_SIZE_27_XTAL_204_35KHZ, // 204.35 KHz for 27 MHz XTAL
|
||||
MXL_HYDRA_STEP_SIZE_27_XTAL_306_52KHZ, // 306.52 KHz for 27 MHz XTAL
|
||||
MXL_HYDRA_STEP_SIZE_27_XTAL_408_69KHZ, // 408.69 KHz for 27 MHz XTAL
|
||||
|
||||
} MXL_HYDRA_SPECTRUM_STEP_SIZE_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_SPECTRUM_RESOLUTION_00_1_DB, // 0.1 dB
|
||||
MXL_HYDRA_SPECTRUM_RESOLUTION_01_0_DB, // 1.0 dB
|
||||
MXL_HYDRA_SPECTRUM_RESOLUTION_05_0_DB, // 5.0 dB
|
||||
MXL_HYDRA_SPECTRUM_RESOLUTION_10_0_DB, // 10 dB
|
||||
} MXL_HYDRA_SPECTRUM_RESOLUTION_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_SPECTRUM_NO_ERROR,
|
||||
MXL_SPECTRUM_INVALID_PARAMETER,
|
||||
MXL_SPECTRUM_INVALID_STEP_SIZE,
|
||||
MXL_SPECTRUM_BW_CANNOT_BE_COVERED,
|
||||
MXL_SPECTRUM_DEMOD_BUSY,
|
||||
MXL_SPECTRUM_TUNER_NOT_ENABLED,
|
||||
|
||||
} MXL_HYDRA_SPECTRUM_ERROR_CODE_E;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 tunerIndex; // TUNER Ctrl: one of MXL58x_TUNER_ID_E
|
||||
u32 demodIndex; // DEMOD Ctrl: one of MXL58x_DEMOD_ID_E
|
||||
MXL_HYDRA_SPECTRUM_STEP_SIZE_E stepSizeInKHz;
|
||||
u32 startingFreqInkHz;
|
||||
u32 totalSteps;
|
||||
MXL_HYDRA_SPECTRUM_RESOLUTION_E spectrumDivision;
|
||||
} MXL_HYDRA_SPECTRUM_REQ_T;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_SEARCH_MAX_OFFSET = 0, // DMD searches for max freq offset (i.e. 5MHz)
|
||||
MXL_HYDRA_SEARCH_BW_PLUS_ROLLOFF, // DMD searches for BW + ROLLOFF/2
|
||||
} MXL_HYDRA_SEARCH_FREQ_OFFSET_TYPE_E;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 demodIndex;
|
||||
MXL_HYDRA_SEARCH_FREQ_OFFSET_TYPE_E searchType;
|
||||
} MXL58x_CFG_FREQ_OFF_SEARCH_RANGE_T;
|
||||
|
||||
|
||||
|
||||
|
||||
// there are two slices
|
||||
// slice0 - TS0, TS1, TS2 & TS3
|
||||
// slice1 - TS4, TS5, TS6 & TS7
|
||||
#define MXL_HYDRA_TS_SLICE_MAX 2
|
||||
|
||||
#define MAX_FIXED_PID_NUM 32
|
||||
|
||||
#define MXL_HYDRA_NCO_CLK 418 // 418 MHz
|
||||
|
||||
#define MXL_HYDRA_MAX_TS_CLOCK 139 // 139 MHz
|
||||
|
||||
#define MXL_HYDRA_TS_FIXED_PID_FILT_SIZE 32
|
||||
|
||||
#define MXL_HYDRA_SHARED_PID_FILT_SIZE_DEFAULT 33 // Shared PID filter size in 1-1 mux mode
|
||||
#define MXL_HYDRA_SHARED_PID_FILT_SIZE_2_TO_1 66 // Shared PID filter size in 2-1 mux mode
|
||||
#define MXL_HYDRA_SHARED_PID_FILT_SIZE_4_TO_1 132 // Shared PID filter size in 4-1 mux mode
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_SOFTWARE_PID_BANK = 0,
|
||||
MXL_HYDRA_HARDWARE_PID_BANK,
|
||||
} MXL_HYDRA_PID_BANK_TYPE_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_TS_MUX_PID_REMAP = 0,
|
||||
MXL_HYDRA_TS_MUX_PREFIX_EXTRA_HEADER = 1,
|
||||
} MXL_HYDRA_TS_MUX_MODE_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_TS_MUX_DISABLE = 0, // No Mux ( 1 TSIF to 1 TSIF)
|
||||
MXL_HYDRA_TS_MUX_2_TO_1, // Mux 2 TSIF to 1 TSIF
|
||||
MXL_HYDRA_TS_MUX_4_TO_1, // Mux 4 TSIF to 1 TSIF
|
||||
} MXL_HYDRA_TS_MUX_TYPE_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_TS_GROUP_0_3 = 0, // TS group 0 to 3 (TS0, TS1, TS2 & TS3)
|
||||
MXL_HYDRA_TS_GROUP_4_7, // TS group 0 to 3 (TS4, TS5, TS6 & TS7)
|
||||
} MXL_HYDRA_TS_GROUP_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_TS_PIDS_ALLOW_ALL = 0, // Allow all pids
|
||||
MXL_HYDRA_TS_PIDS_DROP_ALL, // Drop all pids
|
||||
MXL_HYDRA_TS_INVALIDATE_PID_FILTER, // Delete current PD filter in the device
|
||||
|
||||
} MXL_HYDRA_TS_PID_FLT_CTRL_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_TS_PID_FIXED = 0,
|
||||
MXL_HYDRA_TS_PID_REGULAR,
|
||||
} MXL_HYDRA_TS_PID_TYPE_E;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u16 originalPid; // pid from TS
|
||||
u16 remappedPid; // remapped pid
|
||||
MXL_BOOL_E enable; // enable or disable pid
|
||||
MXL_BOOL_E allowOrDrop; // allow or drop pid
|
||||
MXL_BOOL_E enablePidRemap; // enable or disable pid remap
|
||||
u8 bondId; // Bond ID in A0 always 0 - Only for 568 Sku
|
||||
u8 destId; // Output port ID for the PID - Only for 568 Sku
|
||||
} MXL_HYDRA_TS_PID_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MXL_BOOL_E enable;
|
||||
u8 numByte;
|
||||
u8 header[12];
|
||||
} MXL_HYDRA_TS_MUX_PREFIX_HEADER_T;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_PID_BANK_A = 0,
|
||||
MXL_HYDRA_PID_BANK_B,
|
||||
} MXL_HYDRA_PID_FILTER_BANK_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_MPEG_SERIAL_MSB_1ST = 0,
|
||||
MXL_HYDRA_MPEG_SERIAL_LSB_1ST,
|
||||
|
||||
MXL_HYDRA_MPEG_SYNC_WIDTH_BIT = 0,
|
||||
MXL_HYDRA_MPEG_SYNC_WIDTH_BYTE
|
||||
} MXL_HYDRA_MPEG_DATA_FMT_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_MPEG_MODE_SERIAL_4_WIRE = 0, // MPEG 4 Wire serial mode
|
||||
MXL_HYDRA_MPEG_MODE_SERIAL_3_WIRE, // MPEG 3 Wire serial mode
|
||||
MXL_HYDRA_MPEG_MODE_SERIAL_2_WIRE, // MPEG 2 Wire serial mode
|
||||
MXL_HYDRA_MPEG_MODE_PARALLEL // MPEG parallel mode - valid only for MxL581
|
||||
} MXL_HYDRA_MPEG_MODE_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_MPEG_CLK_CONTINUOUS = 0, // Continuous MPEG clock
|
||||
MXL_HYDRA_MPEG_CLK_GAPPED, // Gapped (gated) MPEG clock
|
||||
} MXL_HYDRA_MPEG_CLK_TYPE_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_MPEG_ACTIVE_LOW = 0,
|
||||
MXL_HYDRA_MPEG_ACTIVE_HIGH,
|
||||
|
||||
MXL_HYDRA_MPEG_CLK_NEGATIVE = 0,
|
||||
MXL_HYDRA_MPEG_CLK_POSITIVE,
|
||||
|
||||
MXL_HYDRA_MPEG_CLK_IN_PHASE = 0,
|
||||
MXL_HYDRA_MPEG_CLK_INVERTED,
|
||||
} MXL_HYDRA_MPEG_CLK_FMT_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_0_DEG = 0,
|
||||
MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_90_DEG,
|
||||
MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_180_DEG,
|
||||
MXL_HYDRA_MPEG_CLK_PHASE_SHIFT_270_DEG
|
||||
} MXL_HYDRA_MPEG_CLK_PHASE_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_MPEG_ERR_REPLACE_SYNC = 0,
|
||||
MXL_HYDRA_MPEG_ERR_REPLACE_VALID,
|
||||
MXL_HYDRA_MPEG_ERR_INDICATION_DISABLED
|
||||
} MXL_HYDRA_MPEG_ERR_INDICATION_E;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int enable; // Enable or Disable MPEG OUT
|
||||
MXL_HYDRA_MPEG_CLK_TYPE_E mpegClkType; // Continuous or gapped
|
||||
MXL_HYDRA_MPEG_CLK_FMT_E mpegClkPol; // MPEG Clk polarity
|
||||
u8 maxMpegClkRate; // Max MPEG Clk rate (0 104 MHz, 139 MHz)
|
||||
MXL_HYDRA_MPEG_CLK_PHASE_E mpegClkPhase; // MPEG Clk phase
|
||||
MXL_HYDRA_MPEG_DATA_FMT_E lsbOrMsbFirst; // LSB first or MSB first in TS transmission
|
||||
MXL_HYDRA_MPEG_DATA_FMT_E mpegSyncPulseWidth; // MPEG SYNC pulse width (1-bit or 1-byte)
|
||||
MXL_HYDRA_MPEG_CLK_FMT_E mpegValidPol; // MPEG VALID polarity
|
||||
MXL_HYDRA_MPEG_CLK_FMT_E mpegSyncPol; // MPEG SYNC polarity
|
||||
MXL_HYDRA_MPEG_MODE_E mpegMode; // config 4/3/2-wire serial or parallel TS out
|
||||
MXL_HYDRA_MPEG_ERR_INDICATION_E mpegErrorIndication; // Enable or Disable MPEG error indication
|
||||
} MXL_HYDRA_MPEGOUT_PARAM_T;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_EXT_TS_IN_0 = 0,
|
||||
MXL_HYDRA_EXT_TS_IN_1,
|
||||
MXL_HYDRA_EXT_TS_IN_2,
|
||||
MXL_HYDRA_EXT_TS_IN_3,
|
||||
MXL_HYDRA_EXT_TS_IN_MAX
|
||||
|
||||
} MXL_HYDRA_EXT_TS_IN_ID_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_TS_OUT_0 = 0,
|
||||
MXL_HYDRA_TS_OUT_1,
|
||||
MXL_HYDRA_TS_OUT_2,
|
||||
MXL_HYDRA_TS_OUT_3,
|
||||
MXL_HYDRA_TS_OUT_4,
|
||||
MXL_HYDRA_TS_OUT_5,
|
||||
MXL_HYDRA_TS_OUT_6,
|
||||
MXL_HYDRA_TS_OUT_7,
|
||||
MXL_HYDRA_TS_OUT_MAX
|
||||
|
||||
} MXL_HYDRA_TS_OUT_ID_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_TS_DRIVE_STRENGTH_1x = 0,
|
||||
MXL_HYDRA_TS_DRIVE_STRENGTH_2x,
|
||||
MXL_HYDRA_TS_DRIVE_STRENGTH_3x,
|
||||
MXL_HYDRA_TS_DRIVE_STRENGTH_4x,
|
||||
MXL_HYDRA_TS_DRIVE_STRENGTH_5x,
|
||||
MXL_HYDRA_TS_DRIVE_STRENGTH_6x,
|
||||
MXL_HYDRA_TS_DRIVE_STRENGTH_7x,
|
||||
MXL_HYDRA_TS_DRIVE_STRENGTH_8x
|
||||
|
||||
} MXL_HYDRA_TS_DRIVE_STRENGTH_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_DEVICE_581 = 0,
|
||||
MXL_HYDRA_DEVICE_584,
|
||||
MXL_HYDRA_DEVICE_585,
|
||||
MXL_HYDRA_DEVICE_544,
|
||||
MXL_HYDRA_DEVICE_561,
|
||||
MXL_HYDRA_DEVICE_TEST,
|
||||
MXL_HYDRA_DEVICE_582,
|
||||
MXL_HYDRA_DEVICE_541,
|
||||
MXL_HYDRA_DEVICE_568,
|
||||
MXL_HYDRA_DEVICE_542,
|
||||
MXL_HYDRA_DEVICE_541S,
|
||||
MXL_HYDRA_DEVICE_561S,
|
||||
MXL_HYDRA_DEVICE_581S,
|
||||
MXL_HYDRA_DEVICE_MAX
|
||||
} MXL_HYDRA_DEVICE_E;
|
||||
|
||||
|
||||
// Demod IQ data
|
||||
typedef struct
|
||||
{
|
||||
u32 demodId;
|
||||
u32 sourceOfIQ; // ==0, it means I/Q comes from Formatter
|
||||
// ==1, Legacy FEC
|
||||
// ==2, Frequency Recovery
|
||||
// ==3, NBC
|
||||
// ==4, CTL
|
||||
// ==5, EQ
|
||||
// ==6, FPGA
|
||||
} MXL_HYDRA_DEMOD_IQ_SRC_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 demodId;
|
||||
} MXL_HYDRA_DEMOD_ABORT_TUNE_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 tunerId;
|
||||
u8 enable;
|
||||
} MxL_HYDRA_TUNER_CMD;
|
||||
|
||||
// Demod Para for Channel Tune
|
||||
typedef struct
|
||||
{
|
||||
u32 tunerIndex;
|
||||
u32 demodIndex;
|
||||
u32 frequencyInHz; // Frequency
|
||||
u32 standard; // one of MXL_HYDRA_BCAST_STD_E
|
||||
u32 spectrumInversion; // Input : Spectrum inversion.
|
||||
u32 rollOff; /* rollOff (alpha) factor */
|
||||
u32 symbolRateInHz; /* Symbol rate */
|
||||
u32 pilots; /* TRUE = pilots enabled */
|
||||
u32 modulationScheme; // Input : Modulation Scheme is one of MXL_HYDRA_MODULATION_E
|
||||
u32 fecCodeRate; // Input : Forward error correction rate. Is one of MXL_HYDRA_FEC_E
|
||||
u32 maxCarrierOffsetInMHz; // Maximum carrier freq offset in MHz. Same as freqSearchRangeKHz, but in unit of MHz.
|
||||
} MXL_HYDRA_DEMOD_PARAM_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 demodIndex;
|
||||
u8 scrambleSequence[12]; // scramble sequence
|
||||
u32 scrambleCode; // scramble gold code
|
||||
} MXL_HYDRA_DEMOD_SCRAMBLE_CODE_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 intrType;
|
||||
u32 intrDurationInNanoSecs;
|
||||
u32 intrMask;
|
||||
} MXL_INTR_CFG_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 powerMode; // enumeration values are defined in MXL_HYDRA_PWR_MODE_E (device API.h)
|
||||
} MxL_HYDRA_POWER_MODE_CMD;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 timeIntervalInSeconds; // in seconds
|
||||
u32 tunerIndex;
|
||||
s32 rssiThreshold;
|
||||
|
||||
} MXL_HYDRA_RF_WAKEUP_PARAM_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 tunerCount;
|
||||
MXL_HYDRA_RF_WAKEUP_PARAM_T params;
|
||||
} MXL_HYDRA_RF_WAKEUP_CFG_T;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_AUX_CTRL_MODE_FSK = 0, // Select FSK controller
|
||||
MXL_HYDRA_AUX_CTRL_MODE_DISEQC, // Select DiSEqC controller
|
||||
} MXL_HYDRA_AUX_CTRL_MODE_E;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_DISEQC_ENVELOPE_MODE = 0,
|
||||
MXL_HYDRA_DISEQC_TONE_MODE,
|
||||
} MXL_HYDRA_DISEQC_OPMODE_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_DISEQC_1_X = 0, // Config DiSEqC 1.x mode
|
||||
MXL_HYDRA_DISEQC_2_X, // Config DiSEqC 2.x mode
|
||||
MXL_HYDRA_DISEQC_DISABLE // Disable DiSEqC
|
||||
} MXL_HYDRA_DISEQC_VER_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_DISEQC_CARRIER_FREQ_22KHZ= 0, // DiSEqC signal frequency of 22 KHz
|
||||
MXL_HYDRA_DISEQC_CARRIER_FREQ_33KHZ, // DiSEqC signal frequency of 33 KHz
|
||||
MXL_HYDRA_DISEQC_CARRIER_FREQ_44KHZ // DiSEqC signal frequency of 44 KHz
|
||||
} MXL_HYDRA_DISEQC_CARRIER_FREQ_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_DISEQC_ID_0 = 0,
|
||||
MXL_HYDRA_DISEQC_ID_1,
|
||||
MXL_HYDRA_DISEQC_ID_2,
|
||||
MXL_HYDRA_DISEQC_ID_3
|
||||
} MXL_HYDRA_DISEQC_ID_E;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MXL_HYDRA_FSK_CFG_TYPE_39KPBS = 0, // 39.0kbps
|
||||
MXL_HYDRA_FSK_CFG_TYPE_39_017KPBS, // 39.017kbps
|
||||
MXL_HYDRA_FSK_CFG_TYPE_115_2KPBS // 115.2kbps
|
||||
} MXL_HYDRA_FSK_OP_MODE_E;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 diseqcId; // DSQ 0, 1, 2 or 3
|
||||
u32 opMode; // Envelope mode (0) or internal tone mode (1)
|
||||
u32 version; // 0: 1.0 , 1: 1.1 , 2: Disable
|
||||
u32 centerFreq; // 0: 22KHz, 1: 33KHz and 2: 44 KHz
|
||||
}MXL58x_DSQ_OP_MODE_T;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 diseqcId;
|
||||
u32 contToneFlag; // 1: Enable , 0: Disable
|
||||
} MXL_HYDRA_DISEQC_CFG_CONT_TONE_T;
|
||||
|
941
frontends/mxl5xx_regs.h
Normal file
941
frontends/mxl5xx_regs.h
Normal file
@ -0,0 +1,941 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2013 MaxLinear, Inc. All rights reserved
|
||||
*
|
||||
* License type: GPLv2
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* This program may alternatively be licensed under a proprietary license from
|
||||
* MaxLinear, Inc.
|
||||
*
|
||||
* See terms and conditions defined in file 'LICENSE.txt', which is part of this
|
||||
* source code package.
|
||||
*/
|
||||
|
||||
#ifndef __MXL58X_REGISTERS_H__
|
||||
#define __MXL58X_REGISTERS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HYDRA_INTR_STATUS_REG 0x80030008
|
||||
#define HYDRA_INTR_MASK_REG 0x8003000C
|
||||
|
||||
#define HYDRA_CRYSTAL_SETTING 0x3FFFC5F0 // 0 - 24 MHz & 1 - 27 MHz
|
||||
#define HYDRA_CRYSTAL_CAP 0x3FFFEDA4 // 0 - 24 MHz & 1 - 27 MHz
|
||||
|
||||
#define HYDRA_CPU_RESET_REG 0x8003003C
|
||||
#define HYDRA_CPU_RESET_DATA 0x00000400
|
||||
|
||||
#define HYDRA_RESET_TRANSPORT_FIFO_REG 0x80030028
|
||||
#define HYDRA_RESET_TRANSPORT_FIFO_DATA 0x00000000
|
||||
|
||||
#define HYDRA_RESET_BBAND_REG 0x80030024
|
||||
#define HYDRA_RESET_BBAND_DATA 0x00000000
|
||||
|
||||
#define HYDRA_RESET_XBAR_REG 0x80030020
|
||||
#define HYDRA_RESET_XBAR_DATA 0x00000000
|
||||
|
||||
#define HYDRA_MODULES_CLK_1_REG 0x80030014
|
||||
#define HYDRA_DISABLE_CLK_1 0x00000000
|
||||
|
||||
#define HYDRA_MODULES_CLK_2_REG 0x8003001C
|
||||
#define HYDRA_DISABLE_CLK_2 0x0000000B
|
||||
|
||||
#define HYDRA_PRCM_ROOT_CLK_REG 0x80030018
|
||||
#define HYDRA_PRCM_ROOT_CLK_DISABLE 0x00000000
|
||||
|
||||
#define HYDRA_CPU_RESET_CHECK_REG 0x80030008
|
||||
#define HYDRA_CPU_RESET_CHECK_OFFSET 0x40000000 // <bit 30>
|
||||
|
||||
#define HYDRA_SKU_ID_REG 0x90000190
|
||||
|
||||
#define FW_DL_SIGN_ADDR 0x3FFFEAE0
|
||||
|
||||
// Register to check if FW is running or not
|
||||
#define HYDRA_HEAR_BEAT 0x3FFFEDDC
|
||||
|
||||
// Firmware version
|
||||
#define HYDRA_FIRMWARE_VERSION 0x3FFFEDB8
|
||||
#define HYDRA_FW_RC_VERSION 0x3FFFCFAC
|
||||
|
||||
// Firmware patch version
|
||||
#define HYDRA_FIRMWARE_PATCH_VERSION 0x3FFFEDC2
|
||||
|
||||
// SOC operating temperature in C
|
||||
#define HYDRA_TEMPARATURE 0x3FFFEDB4
|
||||
|
||||
// Demod & Tuner status registers
|
||||
// Demod 0 status base address
|
||||
#define HYDRA_DEMOD_0_BASE_ADDR 0x3FFFC64C
|
||||
|
||||
// Tuner 0 status base address
|
||||
#define HYDRA_TUNER_0_BASE_ADDR 0x3FFFCE4C
|
||||
|
||||
#define POWER_FROM_ADCRSSI_READBACK 0x3FFFEB6C
|
||||
|
||||
// Macros to determine base address of respective demod or tuner
|
||||
#define HYDRA_DMD_STATUS_OFFSET(demodID) ((demodID) * 0x100)
|
||||
#define HYDRA_TUNER_STATUS_OFFSET(tunerID) ((tunerID) * 0x40)
|
||||
|
||||
// Demod status address offset from respective demod's base address
|
||||
#define HYDRA_DMD_AGC_DIG_LEVEL_ADDR_OFFSET 0x3FFFC64C
|
||||
#define HYDRA_DMD_LOCK_STATUS_ADDR_OFFSET 0x3FFFC650
|
||||
#define HYDRA_DMD_ACQ_STATUS_ADDR_OFFSET 0x3FFFC654
|
||||
|
||||
#define HYDRA_DMD_STANDARD_ADDR_OFFSET 0x3FFFC658
|
||||
#define HYDRA_DMD_SPECTRUM_INVERSION_ADDR_OFFSET 0x3FFFC65C
|
||||
#define HYDRA_DMD_SPECTRUM_ROLL_OFF_ADDR_OFFSET 0x3FFFC660
|
||||
#define HYDRA_DMD_SYMBOL_RATE_ADDR_OFFSET 0x3FFFC664
|
||||
#define HYDRA_DMD_MODULATION_SCHEME_ADDR_OFFSET 0x3FFFC668
|
||||
#define HYDRA_DMD_FEC_CODE_RATE_ADDR_OFFSET 0x3FFFC66C
|
||||
|
||||
#define HYDRA_DMD_SNR_ADDR_OFFSET 0x3FFFC670
|
||||
#define HYDRA_DMD_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC674
|
||||
#define HYDRA_DMD_CTL_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC678
|
||||
#define HYDRA_DMD_STR_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC67C
|
||||
#define HYDRA_DMD_FTL_FREQ_OFFSET_ADDR_OFFSET 0x3FFFC680
|
||||
#define HYDRA_DMD_STR_NBC_SYNC_LOCK_ADDR_OFFSET 0x3FFFC684
|
||||
#define HYDRA_DMD_CYCLE_SLIP_COUNT_ADDR_OFFSET 0x3FFFC688
|
||||
|
||||
#define HYDRA_DMD_DISPLAY_I_ADDR_OFFSET 0x3FFFC68C
|
||||
#define HYDRA_DMD_DISPLAY_Q_ADDR_OFFSET 0x3FFFC68E
|
||||
|
||||
#define HYDRA_DMD_DVBS2_CRC_ERRORS_ADDR_OFFSET 0x3FFFC690
|
||||
#define HYDRA_DMD_DVBS2_PER_COUNT_ADDR_OFFSET 0x3FFFC694
|
||||
#define HYDRA_DMD_DVBS2_PER_WINDOW_ADDR_OFFSET 0x3FFFC698
|
||||
|
||||
#define HYDRA_DMD_DVBS_CORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC69C
|
||||
#define HYDRA_DMD_DVBS_UNCORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6A0
|
||||
#define HYDRA_DMD_DVBS_BER_COUNT_ADDR_OFFSET 0x3FFFC6A4
|
||||
#define HYDRA_DMD_DVBS_BER_WINDOW_ADDR_OFFSET 0x3FFFC6A8
|
||||
|
||||
// Debug-purpose DVB-S DMD 0
|
||||
#define HYDRA_DMD_DVBS_1ST_CORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6C8 // corrected RS Errors: 1st iteration
|
||||
#define HYDRA_DMD_DVBS_1ST_UNCORR_RS_ERRORS_ADDR_OFFSET 0x3FFFC6CC // uncorrected RS Errors: 1st iteration
|
||||
#define HYDRA_DMD_DVBS_BER_COUNT_1ST_ADDR_OFFSET 0x3FFFC6D0
|
||||
#define HYDRA_DMD_DVBS_BER_WINDOW_1ST_ADDR_OFFSET 0x3FFFC6D4
|
||||
|
||||
#define HYDRA_DMD_TUNER_ID_ADDR_OFFSET 0x3FFFC6AC
|
||||
#define HYDRA_DMD_DVBS2_PILOT_ON_OFF_ADDR_OFFSET 0x3FFFC6B0
|
||||
#define HYDRA_DMD_FREQ_SEARCH_RANGE_KHZ_ADDR_OFFSET 0x3FFFC6B4
|
||||
#define HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET 0x3FFFC6B8
|
||||
#define HYDRA_DMD_STATUS_CENTER_FREQ_IN_KHZ_ADDR 0x3FFFC704
|
||||
#define HYDRA_DMD_STATUS_INPUT_POWER_ADDR 0x3FFFC708
|
||||
|
||||
// DVB-S new scaled_BER_count for a new BER API, see HYDRA-1343 "DVB-S post viterbi information"
|
||||
#define DMD0_STATUS_DVBS_1ST_SCALED_BER_COUNT_ADDR 0x3FFFC710 // DMD 0: 1st iteration BER count scaled by HYDRA_BER_COUNT_SCALING_FACTOR
|
||||
#define DMD0_STATUS_DVBS_SCALED_BER_COUNT_ADDR 0x3FFFC714 // DMD 0: 2nd iteration BER count scaled by HYDRA_BER_COUNT_SCALING_FACTOR
|
||||
|
||||
#define DMD0_SPECTRUM_MIN_GAIN_STATUS 0x3FFFC73C
|
||||
#define DMD0_SPECTRUM_MIN_GAIN_WB_SAGC_VALUE 0x3FFFC740
|
||||
#define DMD0_SPECTRUM_ MIN_GAIN_NB_SAGC_VALUE 0x3FFFC744
|
||||
|
||||
#define HYDRA_DMD_STATUS_END_ADDR_OFFSET 0x3FFFC748
|
||||
|
||||
// Tuner status address offset from respective tuners's base address
|
||||
#define HYDRA_TUNER_DEMOD_ID_ADDR_OFFSET 0x3FFFCE4C
|
||||
#define HYDRA_TUNER_AGC_LOCK_OFFSET 0x3FFFCE50
|
||||
#define HYDRA_TUNER_SPECTRUM_STATUS_OFFSET 0x3FFFCE54
|
||||
#define HYDRA_TUNER_SPECTRUM_BIN_SIZE_OFFSET 0x3FFFCE58
|
||||
#define HYDRA_TUNER_SPECTRUM_ADDRESS_OFFSET 0x3FFFCE5C
|
||||
#define HYDRA_TUNER_ENABLE_COMPLETE 0x3FFFEB78
|
||||
|
||||
#define HYDRA_DEMOD_STATUS_LOCK(devId, demodId) write_register(devId, (HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET + HYDRA_DMD_STATUS_OFFSET(demodId)), MXL_YES)
|
||||
#define HYDRA_DEMOD_STATUS_UNLOCK(devId, demodId) write_register(devId, (HYDRA_DMD_STATUS_LOCK_ADDR_OFFSET + HYDRA_DMD_STATUS_OFFSET(demodId)), MXL_NO)
|
||||
|
||||
#define HYDRA_TUNER_STATUS_LOCK(devId,tunerId) MxLWare_HYDRA_WriteRegister(devId,(HYDRA_TUNER_STATUS_LOCK_ADDR_OFFSET + HYDRA_TUNER_STATUS_OFFSET(tunerId)), MXL_YES)
|
||||
#define HYDRA_TUNER_STATUS_UNLOCK(devId,tunerId) MxLWare_HYDRA_WriteRegister(devId,(HYDRA_TUNER_STATUS_LOCK_ADDR_OFFSET + HYDRA_TUNER_STATUS_OFFSET(tunerId)), MXL_NO)
|
||||
|
||||
#define HYDRA_VERSION 0x3FFFEDB8
|
||||
#define HYDRA_DEMOD0_VERSION 0x3FFFEDBC
|
||||
#define HYDRA_DEMOD1_VERSION 0x3FFFEDC0
|
||||
#define HYDRA_DEMOD2_VERSION 0x3FFFEDC4
|
||||
#define HYDRA_DEMOD3_VERSION 0x3FFFEDC8
|
||||
#define HYDRA_DEMOD4_VERSION 0x3FFFEDCC
|
||||
#define HYDRA_DEMOD5_VERSION 0x3FFFEDD0
|
||||
#define HYDRA_DEMOD6_VERSION 0x3FFFEDD4
|
||||
#define HYDRA_DEMOD7_VERSION 0x3FFFEDD8
|
||||
#define HYDRA_HEAR_BEAT 0x3FFFEDDC
|
||||
#define HYDRA_SKU_MGMT 0x3FFFEBC0
|
||||
|
||||
#define MXL_HYDRA_FPGA_A_ADDRESS 0x91C00000
|
||||
#define MXL_HYDRA_FPGA_B_ADDRESS 0x91D00000
|
||||
|
||||
// TS control base address
|
||||
#define HYDRA_TS_CTRL_BASE_ADDR 0x90700000
|
||||
|
||||
#define MPEG_MUX_MODE_SLICE0_REG HYDRA_TS_CTRL_BASE_ADDR + 0x08
|
||||
#define MPEG_MUX_MODE_SLICE0_OFFSET (0),(2)
|
||||
|
||||
#define MPEG_MUX_MODE_SLICE1_REG HYDRA_TS_CTRL_BASE_ADDR + 0x08
|
||||
#define MPEG_MUX_MODE_SLICE1_OFFSET (2),(2)
|
||||
|
||||
#define PID_BANK_SEL_SLICE0_REG HYDRA_TS_CTRL_BASE_ADDR + 0x190
|
||||
#define PID_BANK_SEL_SLICE1_REG HYDRA_TS_CTRL_BASE_ADDR + 0x1B0
|
||||
|
||||
#define SW_REGULAR_PID_SW_BANK_OFFSET 0,1
|
||||
#define SW_FIXED_PID_SW_BANK_OFFSET 1,1
|
||||
|
||||
#define HW_REGULAR_PID_BANK_OFFSET 8,4
|
||||
#define HW_FIXED_PID_BANK_OFFSET 4,4
|
||||
|
||||
#define MPEG_CLK_GATED_REG HYDRA_TS_CTRL_BASE_ADDR + 0x20
|
||||
#define MPEG_CLK_GATED_OFFSET 0,1
|
||||
|
||||
#define MPEG_CLK_ALWAYS_ON_REG HYDRA_TS_CTRL_BASE_ADDR + 0x1D4
|
||||
#define MPEG_CLK_ALWAYS_ON_OFFSET 0,1
|
||||
|
||||
#define HYDRA_REGULAR_PID_BANK_A_REG HYDRA_TS_CTRL_BASE_ADDR + 0x190
|
||||
#define HYDRA_REGULAR_PID_BAN K_A_OFFSET 0,1
|
||||
|
||||
#define HYDRA_FIXED_PID_BANK_A_REG HYDRA_TS_CTRL_BASE_ADDR + 0x190
|
||||
#define HYDRA_FIXED_PID_BANK_A_OFFSET 1,1
|
||||
|
||||
#define HYDRA_REGULAR_PID_BANK_B_REG HYDRA_TS_CTRL_BASE_ADDR + 0x1B0
|
||||
#define HYDRA_REGULAR_PID_BANK_B_OFFSET 0,1
|
||||
|
||||
#define HYDRA_FIXED_PID_BANK_B_REG HYDRA_TS_CTRL_BASE_ADDR + 0x1B0
|
||||
#define HYDRA_FIXED_PID_BANK_B_OFFSET 1,1
|
||||
|
||||
#define FIXED_PID_TBL_REG_ADDRESS_0 HYDRA_TS_CTRL_BASE_ADDR + 0x9000
|
||||
#define FIXED_PID_TBL_REG_ADDRESS_1 HYDRA_TS_CTRL_BASE_ADDR + 0x9100
|
||||
#define FIXED_PID_TBL_REG_ADDRESS_2 HYDRA_TS_CTRL_BASE_ADDR + 0x9200
|
||||
#define FIXED_PID_TBL_REG_ADDRESS_3 HYDRA_TS_CTRL_BASE_ADDR + 0x9300
|
||||
|
||||
#define FIXED_PID_TBL_REG_ADDRESS_4 HYDRA_TS_CTRL_BASE_ADDR + 0xB000
|
||||
#define FIXED_PID_TBL_REG_ADDRESS_5 HYDRA_TS_CTRL_BASE_ADDR + 0xB100
|
||||
#define FIXED_PID_TBL_REG_ADDRESS_6 HYDRA_TS_CTRL_BASE_ADDR + 0xB200
|
||||
#define FIXED_PID_TBL_REG_ADDRESS_7 HYDRA_TS_CTRL_BASE_ADDR + 0xB300
|
||||
|
||||
#define REGULAR_PID_TBL_REG_ADDRESS_0 HYDRA_TS_CTRL_BASE_ADDR + 0x8000
|
||||
#define REGULAR_PID_TBL_REG_ADDRESS_1 HYDRA_TS_CTRL_BASE_ADDR + 0x8200
|
||||
#define REGULAR_PID_TBL_REG_ADDRESS_2 HYDRA_TS_CTRL_BASE_ADDR + 0x8400
|
||||
#define REGULAR_PID_TBL_REG_ADDRESS_3 HYDRA_TS_CTRL_BASE_ADDR + 0x8600
|
||||
|
||||
#define REGULAR_PID_TBL_REG_ADDRESS_4 HYDRA_TS_CTRL_BASE_ADDR + 0xA000
|
||||
#define REGULAR_PID_TBL_REG_ADDRESS_5 HYDRA_TS_CTRL_BASE_ADDR + 0xA200
|
||||
#define REGULAR_PID_TBL_REG_ADDRESS_6 HYDRA_TS_CTRL_BASE_ADDR + 0xA400
|
||||
#define REGULAR_PID_TBL_REG_ADDRESS_7 HYDRA_TS_CTRL_BASE_ADDR + 0xA600
|
||||
|
||||
#define PID_VALID_OFFSET 0,1
|
||||
#define PID_DROP_OFFSET 1,1
|
||||
#define PID_REMAP_ENABLE_OFFSET 2,1
|
||||
#define PID_VALUE_OFFSET 4,13
|
||||
#define PID_MASK_OFFSET 19,13
|
||||
|
||||
#define REGULAR_PID_REMAP_VALUE_OFFSET 0,13
|
||||
#define FIXED_PID_REMAP_VALUE_OFFSET 0,16
|
||||
#define PID_DEMODID_OFFSET 16,3
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
#define AFE_REG_D2A_TA_ADC_CLK_OUT_FLIP 0x90200004,12,1
|
||||
#define AFE_REG_D2A_TA_RFFE_LNACAPLOAD_1P8 0x90200028,24,4
|
||||
#define AFE_REG_D2A_TA_RFFE_RF1_EN_1P8 0x90200028,5,1
|
||||
#define AFE_REG_D2A_TA_RFFE_SPARE_1P8 0x90200028,8,8
|
||||
#define AFE_REG_D2A_TB_ADC_CLK_OUT_FLIP 0x9020000C,23,1
|
||||
#define AFE_REG_D2A_TB_RFFE_LNACAPLOAD_1P8 0x90200030,16,4
|
||||
#define AFE_REG_D2A_TB_RFFE_RF1_EN_1P8 0x9020002C,21,1
|
||||
#define AFE_REG_D2A_TB_RFFE_SPARE_1P8 0x90200030,0,8
|
||||
#define AFE_REG_D2A_TC_ADC_CLK_OUT_FLIP 0x90200018,7,1
|
||||
#define AFE_REG_D2A_TC_RFFE_LNACAPLOAD_1P8 0x90200038,2,4
|
||||
#define AFE_REG_D2A_TC_RFFE_RF1_EN_1P8 0x90200034,14,1
|
||||
#define AFE_REG_D2A_TC_RFFE_SPARE_1P8 0x90200034,17,8
|
||||
#define AFE_REG_D2A_TD_ADC_CLK_OUT_FLIP 0x90200020,18,1
|
||||
#define AFE_REG_D2A_TD_RFFE_LNACAPLOAD_1P8 0x9020003C,17,4
|
||||
#define AFE_REG_D2A_TD_RFFE_RF1_EN_1P8 0x90200038,29,1
|
||||
#define AFE_REG_D2A_TD_RFFE_SPARE_1P8 0x9020003C,1,8
|
||||
#endif
|
||||
#define AFE_REG_D2A_XTAL_EN_CLKOUT_1P8 0x90200054,23,1
|
||||
|
||||
#define PAD_MUX_TS0_IN_CLK_PINMUX_SEL 0x90000018,0,3
|
||||
#define PAD_MUX_TS0_IN_DATA_PINMUX_SEL 0x90000018,4,3
|
||||
#define PAD_MUX_TS1_IN_CLK_PINMUX_SEL 0x90000018,8,3
|
||||
#define PAD_MUX_TS1_IN_DATA_PINMUX_SEL 0x90000018,12,3
|
||||
#define PAD_MUX_TS2_IN_CLK_PINMUX_SEL 0x90000018,16,3
|
||||
#define PAD_MUX_TS2_IN_DATA_PINMUX_SEL 0x90000018,20,3
|
||||
#define PAD_MUX_TS3_IN_CLK_PINMUX_SEL 0x90000018,24,3
|
||||
#define PAD_MUX_TS3_IN_DATA_PINMUX_SEL 0x90000018,28,3
|
||||
|
||||
#define PAD_MUX_GPIO_00_SYNC_BASEADDR 0x90000188
|
||||
#define PAD_MUX_GPIO_01_SYNC_IN PAD_MUX_GPIO_00_SYNC_BASEADDR,1,1
|
||||
|
||||
#define PRCM_AFE_SOC_ID 0x80030004,24,8
|
||||
|
||||
#define PAD_MUX_UART_RX_C_PINMUX_BASEADDR 0x9000001C
|
||||
#define PAD_MUX_UART_RX_C_PINMUX_SEL PAD_MUX_UART_RX_C_PINMUX_BASEADDR,0,3
|
||||
#define PAD_MUX_UART_RX_D_PINMUX_SEL PAD_MUX_UART_RX_C_PINMUX_BASEADDR,4,3
|
||||
#define PAD_MUX_BOND_OPTION 0x90000190,0,3
|
||||
#define PAD_MUX_DIGIO_01_PINMUX_SEL 0x9000016C,4,3
|
||||
#define PAD_MUX_DIGIO_02_PINMUX_SEL 0x9000016C,8,3
|
||||
#define PAD_MUX_DIGIO_03_PINMUX_SEL 0x9000016C,12,3
|
||||
#define PAD_MUX_DIGIO_04_PINMUX_SEL 0x9000016C,16,3
|
||||
#define PAD_MUX_DIGIO_05_PINMUX_SEL 0x9000016C,20,3
|
||||
#define PAD_MUX_DIGIO_06_PINMUX_SEL 0x9000016C,24,3
|
||||
#define PAD_MUX_DIGIO_07_PINMUX_SEL 0x9000016C,28,3
|
||||
#define PAD_MUX_DIGIO_08_PINMUX_SEL 0x90000170,0,3
|
||||
#define PAD_MUX_DIGIO_09_PINMUX_SEL 0x90000170,4,3
|
||||
#define PAD_MUX_DIGIO_10_PINMUX_SEL 0x90000170,8,3
|
||||
#define PAD_MUX_DIGIO_11_PINMUX_SEL 0x90000170,12,3
|
||||
#define PAD_MUX_DIGIO_12_PINMUX_SEL 0x90000170,16,3
|
||||
#define PAD_MUX_DIGIO_13_PINMUX_SEL 0x90000170,20,3
|
||||
#define PAD_MUX_DIGIO_14_PINMUX_SEL 0x90000170,24,3
|
||||
#define PAD_MUX_DIGIO_15_PINMUX_SEL 0x90000170,28,3
|
||||
#define PAD_MUX_DIGIO_16_PINMUX_SEL 0x90000174,0,3
|
||||
#define PAD_MUX_DIGIO_17_PINMUX_SEL 0x90000174,4,3
|
||||
#define PAD_MUX_DIGIO_18_PINMUX_SEL 0x90000174,8,3
|
||||
#define PAD_MUX_DIGIO_19_PINMUX_SEL 0x90000174,12,3
|
||||
#define PAD_MUX_DIGIO_20_PINMUX_SEL 0x90000174,16,3
|
||||
#define PAD_MUX_DIGIO_21_PINMUX_SEL 0x90000174,20,3
|
||||
#define PAD_MUX_DIGIO_22_PINMUX_SEL 0x90000174,24,3
|
||||
#define PAD_MUX_DIGIO_23_PINMUX_SEL 0x90000174,28,3
|
||||
#define PAD_MUX_DIGIO_24_PINMUX_SEL 0x90000178,0,3
|
||||
#define PAD_MUX_DIGIO_25_PINMUX_SEL 0x90000178,4,3
|
||||
#define PAD_MUX_DIGIO_26_PINMUX_SEL 0x90000178,8,3
|
||||
#define PAD_MUX_DIGIO_27_PINMUX_SEL 0x90000178,12,3
|
||||
#define PAD_MUX_DIGIO_28_PINMUX_SEL 0x90000178,16,3
|
||||
#define PAD_MUX_DIGIO_29_PINMUX_SEL 0x90000178,20,3
|
||||
#define PAD_MUX_DIGIO_30_PINMUX_SEL 0x90000178,24,3
|
||||
#define PAD_MUX_DIGIO_31_PINMUX_SEL 0x90000178,28,3
|
||||
#define PAD_MUX_DIGIO_32_PINMUX_SEL 0x9000017C,0,3
|
||||
#define PAD_MUX_DIGIO_33_PINMUX_SEL 0x9000017C,4,3
|
||||
#define PAD_MUX_DIGIO_34_PINMUX_SEL 0x9000017C,8,3
|
||||
#define PAD_MUX_EJTAG_TCK_PINMUX_SEL 0x90000020,0,3
|
||||
#define PAD_MUX_EJTAG_TDI_PINMUX_SEL 0x90000020,8,3
|
||||
#define PAD_MUX_EJTAG_TMS_PINMUX_SEL 0x90000020,4,3
|
||||
#define PAD_MUX_EJTAG_TRSTN_PINMUX_SEL 0x90000020,12,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_00 0x90000194,0,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_05 0x90000194,20,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_06 0x90000194,24,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_11 0x90000198,12,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_12 0x90000198,16,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_13 0x90000198,20,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_14 0x90000198,24,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_16 0x9000019C,0,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_17 0x9000019C,4,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_18 0x9000019C,8,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_22 0x9000019C,24,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_23 0x9000019C,28,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_24 0x900001A0,0,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_25 0x900001A0,4,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_29 0x900001A0,20,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_30 0x900001A0,24,3
|
||||
#define PAD_MUX_PAD_DRV_DIGIO_31 0x900001A0,28,3
|
||||
#define PRCM_AFE_REG_CLOCK_ENABLE 0x80030014,9,1
|
||||
#define PRCM_CHIP_VERSION 0x80030000,12,4
|
||||
#define PRCM_AFE_CHIP_MMSK_VER 0x80030004,8,8
|
||||
#define PRCM_PRCM_AFE_REG_SOFT_RST_N 0x8003003C,12,1
|
||||
#define PRCM_PRCM_CPU_SOFT_RST_N 0x8003003C,0,1
|
||||
#define PRCM_PRCM_DIGRF_APB_DATA_BB0 0x80030074,0,20
|
||||
#define PRCM_PRCM_DIGRF_APB_DATA_BB1 0x80030078,0,20
|
||||
#define PRCM_PRCM_DIGRF_APB_DATA_BB2 0x8003007C,0,20
|
||||
#define PRCM_PRCM_DIGRF_APB_DATA_BB3 0x80030080,0,20
|
||||
#define PRCM_PRCM_DIGRF_APB_DATA_BB4 0x80030084,0,20
|
||||
#define PRCM_PRCM_DIGRF_APB_DATA_BB5 0x80030088,0,20
|
||||
#define PRCM_PRCM_DIGRF_APB_DATA_BB6 0x8003008C,0,20
|
||||
#define PRCM_PRCM_DIGRF_APB_DATA_BB7 0x80030090,0,20
|
||||
#define PRCM_PRCM_DIGRF_CAPT_DONE 0x80030070,24,8
|
||||
#define PRCM_PRCM_DIGRF_START_CAPT 0x80030064,2,1
|
||||
#define PRCM_PRCM_PAD_MUX_SOFT_RST_N 0x8003003C,11,1
|
||||
#define PRCM_PRCM_XPT_PARALLEL_FIFO_RST_N 0x80030028,20,1
|
||||
#define XPT_APPEND_BYTES0 0x90700008,4,2
|
||||
#define XPT_APPEND_BYTES1 0x90700008,6,2
|
||||
#define XPT_CLOCK_POLARITY0 0x90700010,16,1
|
||||
#define XPT_CLOCK_POLARITY1 0x90700010,17,1
|
||||
#define XPT_CLOCK_POLARITY2 0x90700010,18,1
|
||||
#define XPT_CLOCK_POLARITY3 0x90700010,19,1
|
||||
#define XPT_CLOCK_POLARITY4 0x90700010,20,1
|
||||
#define XPT_CLOCK_POLARITY5 0x90700010,21,1
|
||||
#define XPT_CLOCK_POLARITY6 0x90700010,22,1
|
||||
#define XPT_CLOCK_POLARITY7 0x90700010,23,1
|
||||
#define XPT_DSS_DVB_ENCAP_EN0 0x90700000,16,1
|
||||
#define XPT_DSS_DVB_ENCAP_EN1 0x90700000,17,1
|
||||
#define XPT_DSS_DVB_ENCAP_EN2 0x90700000,18,1
|
||||
#define XPT_DSS_DVB_ENCAP_EN3 0x90700000,19,1
|
||||
#define XPT_DSS_DVB_ENCAP_EN4 0x90700000,20,1
|
||||
#define XPT_DSS_DVB_ENCAP_EN5 0x90700000,21,1
|
||||
#define XPT_DSS_DVB_ENCAP_EN6 0x90700000,22,1
|
||||
#define XPT_DSS_DVB_ENCAP_EN7 0x90700000,23,1
|
||||
#define XPT_DVB_MATCH_BYTE 0x9070017C,16,8
|
||||
#define XPT_DVB_PACKET_SIZE0 0x90700180,0,8
|
||||
#define XPT_DVB_PACKET_SIZE1 0x90700180,8,8
|
||||
#define XPT_DVB_PACKET_SIZE2 0x90700180,16,8
|
||||
#define XPT_DVB_PACKET_SIZE3 0x90700180,24,8
|
||||
#define XPT_ENABLE_DVB_INPUT0 0x90700178,0,1
|
||||
#define XPT_ENABLE_DVB_INPUT1 0x90700178,1,1
|
||||
#define XPT_ENABLE_DVB_INPUT2 0x90700178,2,1
|
||||
#define XPT_ENABLE_DVB_INPUT3 0x90700178,3,1
|
||||
#define XPT_ENABLE_INPUT0 0x90700000,0,1
|
||||
#define XPT_ENABLE_INPUT1 0x90700000,1,1
|
||||
#define XPT_ENABLE_INPUT2 0x90700000,2,1
|
||||
#define XPT_ENABLE_INPUT3 0x90700000,3,1
|
||||
#define XPT_ENABLE_INPUT4 0x90700000,4,1
|
||||
#define XPT_ENABLE_INPUT5 0x90700000,5,1
|
||||
#define XPT_ENABLE_INPUT6 0x90700000,6,1
|
||||
#define XPT_ENABLE_INPUT7 0x90700000,7,1
|
||||
#define XPT_ENABLE_OUTPUT0 0x9070000C,0,1
|
||||
#define XPT_ENABLE_OUTPUT1 0x9070000C,1,1
|
||||
#define XPT_ENABLE_OUTPUT2 0x9070000C,2,1
|
||||
#define XPT_ENABLE_OUTPUT3 0x9070000C,3,1
|
||||
#define XPT_ENABLE_OUTPUT4 0x9070000C,4,1
|
||||
#define XPT_ENABLE_OUTPUT5 0x9070000C,5,1
|
||||
#define XPT_ENABLE_OUTPUT6 0x9070000C,6,1
|
||||
#define XPT_ENABLE_OUTPUT7 0x9070000C,7,1
|
||||
#define XPT_ENABLE_PARALLEL_OUTPUT 0x90700010,27,1
|
||||
#define XPT_ENABLE_PCR_COUNT 0x90700184,1,1
|
||||
#define XPT_ERROR_REPLACE_SYNC0 0x9070000C,24,1
|
||||
#define XPT_ERROR_REPLACE_SYNC1 0x9070000C,25,1
|
||||
#define XPT_ERROR_REPLACE_SYNC2 0x9070000C,26,1
|
||||
#define XPT_ERROR_REPLACE_SYNC3 0x9070000C,27,1
|
||||
#define XPT_ERROR_REPLACE_SYNC4 0x9070000C,28,1
|
||||
#define XPT_ERROR_REPLACE_SYNC5 0x9070000C,29,1
|
||||
#define XPT_ERROR_REPLACE_SYNC6 0x9070000C,30,1
|
||||
#define XPT_ERROR_REPLACE_SYNC7 0x9070000C,31,1
|
||||
#define XPT_ERROR_REPLACE_VALID0 0x90700014,8,1
|
||||
#define XPT_ERROR_REPLACE_VALID1 0x90700014,9,1
|
||||
#define XPT_ERROR_REPLACE_VALID2 0x90700014,10,1
|
||||
#define XPT_ERROR_REPLACE_VALID3 0x90700014,11,1
|
||||
#define XPT_ERROR_REPLACE_VALID4 0x90700014,12,1
|
||||
#define XPT_ERROR_REPLACE_VALID5 0x90700014,13,1
|
||||
#define XPT_ERROR_REPLACE_VALID6 0x90700014,14,1
|
||||
#define XPT_ERROR_REPLACE_VALID7 0x90700014,15,1
|
||||
#define XPT_INP0_MERGE_HDR0 0x90700058,0,32
|
||||
#define XPT_INP0_MERGE_HDR1 0x9070005C,0,32
|
||||
#define XPT_INP0_MERGE_HDR2 0x90700060,0,32
|
||||
#define XPT_INP1_MERGE_HDR0 0x90700064,0,32
|
||||
#define XPT_INP1_MERGE_HDR1 0x90700068,0,32
|
||||
#define XPT_INP1_MERGE_HDR2 0x9070006C,0,32
|
||||
#define XPT_INP2_MERGE_HDR0 0x90700070,0,32
|
||||
#define XPT_INP2_MERGE_HDR1 0x90700074,0,32
|
||||
#define XPT_INP2_MERGE_HDR2 0x90700078,0,32
|
||||
#define XPT_INP3_MERGE_HDR0 0x9070007C,0,32
|
||||
#define XPT_INP3_MERGE_HDR1 0x90700080,0,32
|
||||
#define XPT_INP3_MERGE_HDR2 0x90700084,0,32
|
||||
#define XPT_INP4_MERGE_HDR0 0x90700088,0,32
|
||||
#define XPT_INP4_MERGE_HDR1 0x9070008C,0,32
|
||||
#define XPT_INP4_MERGE_HDR2 0x90700090,0,32
|
||||
#define XPT_INP5_MERGE_HDR0 0x90700094,0,32
|
||||
#define XPT_INP5_MERGE_HDR1 0x90700098,0,32
|
||||
#define XPT_INP5_MERGE_HDR2 0x9070009C,0,32
|
||||
#define XPT_INP6_MERGE_HDR0 0x907000A0,0,32
|
||||
#define XPT_INP6_MERGE_HDR1 0x907000A4,0,32
|
||||
#define XPT_INP6_MERGE_HDR2 0x907000A8,0,32
|
||||
#define XPT_INP7_MERGE_HDR0 0x907000AC,0,32
|
||||
#define XPT_INP7_MERGE_HDR1 0x907000B0,0,32
|
||||
#define XPT_INP7_MERGE_HDR2 0x907000B4,0,32
|
||||
#define XPT_INP_MODE_DSS0 0x90700000,8,1
|
||||
#define XPT_INP_MODE_DSS1 0x90700000,9,1
|
||||
#define XPT_INP_MODE_DSS2 0x90700000,10,1
|
||||
#define XPT_INP_MODE_DSS3 0x90700000,11,1
|
||||
#define XPT_INP_MODE_DSS4 0x90700000,12,1
|
||||
#define XPT_INP_MODE_DSS5 0x90700000,13,1
|
||||
#define XPT_INP_MODE_DSS6 0x90700000,14,1
|
||||
#define XPT_INP_MODE_DSS7 0x90700000,15,1
|
||||
#define XPT_KNOWN_PID_MUX_SELECT0 0x90700190,8,4
|
||||
#define XPT_KNOWN_PID_MUX_SELECT1 0x907001B0,8,4
|
||||
#define XPT_LSB_FIRST0 0x9070000C,16,1
|
||||
#define XPT_LSB_FIRST1 0x9070000C,17,1
|
||||
#define XPT_LSB_FIRST2 0x9070000C,18,1
|
||||
#define XPT_LSB_FIRST3 0x9070000C,19,1
|
||||
#define XPT_LSB_FIRST4 0x9070000C,20,1
|
||||
#define XPT_LSB_FIRST5 0x9070000C,21,1
|
||||
#define XPT_LSB_FIRST6 0x9070000C,22,1
|
||||
#define XPT_LSB_FIRST7 0x9070000C,23,1
|
||||
#define XPT_MODE_27MHZ 0x90700184,0,1
|
||||
#define XPT_NCO_COUNT_MIN 0x90700044,16,8
|
||||
#define XPT_OUTPUT_MODE_DSS0 0x9070000C,8,1
|
||||
#define XPT_OUTPUT_MODE_DSS1 0x9070000C,9,1
|
||||
#define XPT_OUTPUT_MODE_DSS2 0x9070000C,10,1
|
||||
#define XPT_OUTPUT_MODE_DSS3 0x9070000C,11,1
|
||||
#define XPT_OUTPUT_MODE_DSS4 0x9070000C,12,1
|
||||
#define XPT_OUTPUT_MODE_DSS5 0x9070000C,13,1
|
||||
#define XPT_OUTPUT_MODE_DSS6 0x9070000C,14,1
|
||||
#define XPT_OUTPUT_MODE_DSS7 0x9070000C,15,1
|
||||
#define XPT_OUTPUT_MODE_MUXGATING0 0x90700020,0,1
|
||||
#define XPT_OUTPUT_MODE_MUXGATING1 0x90700020,1,1
|
||||
#define XPT_OUTPUT_MODE_MUXGATING2 0x90700020,2,1
|
||||
#define XPT_OUTPUT_MODE_MUXGATING3 0x90700020,3,1
|
||||
#define XPT_OUTPUT_MODE_MUXGATING4 0x90700020,4,1
|
||||
#define XPT_OUTPUT_MODE_MUXGATING5 0x90700020,5,1
|
||||
#define XPT_OUTPUT_MODE_MUXGATING6 0x90700020,6,1
|
||||
#define XPT_OUTPUT_MODE_MUXGATING7 0x90700020,7,1
|
||||
#define XPT_OUTPUT_MUXSELECT0 0x9070001C,0,3
|
||||
#define XPT_OUTPUT_MUXSELECT1 0x9070001C,4,3
|
||||
#define XPT_OUTPUT_MUXSELECT2 0x9070001C,8,3
|
||||
#define XPT_OUTPUT_MUXSELECT3 0x9070001C,12,3
|
||||
#define XPT_OUTPUT_MUXSELECT4 0x9070001C,16,3
|
||||
#define XPT_OUTPUT_MUXSELECT5 0x9070001C,20,3
|
||||
#define XPT_PCR_RTS_CORRECTION_ENABLE 0x90700008,14,1
|
||||
#define XPT_PID_DEFAULT_DROP0 0x90700190,12,1
|
||||
#define XPT_PID_DEFAULT_DROP1 0x90700190,13,1
|
||||
#define XPT_PID_DEFAULT_DROP2 0x90700190,14,1
|
||||
#define XPT_PID_DEFAULT_DROP3 0x90700190,15,1
|
||||
#define XPT_PID_DEFAULT_DROP4 0x907001B0,12,1
|
||||
#define XPT_PID_DEFAULT_DROP5 0x907001B0,13,1
|
||||
#define XPT_PID_DEFAULT_DROP6 0x907001B0,14,1
|
||||
#define XPT_PID_DEFAULT_DROP7 0x907001B0,15,1
|
||||
#define XPT_PID_MUX_SELECT0 0x90700190,4,4
|
||||
#define XPT_PID_MUX_SELECT1 0x907001B0,4,4
|
||||
#define XPT_STREAM_MUXMODE0 0x90700008,0,2
|
||||
#define XPT_STREAM_MUXMODE1 0x90700008,2,2
|
||||
#define XPT_SYNC_FULL_BYTE0 0x90700010,0,1
|
||||
#define XPT_SYNC_FULL_BYTE1 0x90700010,1,1
|
||||
#define XPT_SYNC_FULL_BYTE2 0x90700010,2,1
|
||||
#define XPT_SYNC_FULL_BYTE3 0x90700010,3,1
|
||||
#define XPT_SYNC_FULL_BYTE4 0x90700010,4,1
|
||||
#define XPT_SYNC_FULL_BYTE5 0x90700010,5,1
|
||||
#define XPT_SYNC_FULL_BYTE6 0x90700010,6,1
|
||||
#define XPT_SYNC_FULL_BYTE7 0x90700010,7,1
|
||||
#define XPT_SYNC_LOCK_THRESHOLD 0x9070017C,0,8
|
||||
#define XPT_SYNC_MISS_THRESHOLD 0x9070017C,8,8
|
||||
#define XPT_SYNC_POLARITY0 0x90700010,8,1
|
||||
#define XPT_SYNC_POLARITY1 0x90700010,9,1
|
||||
#define XPT_SYNC_POLARITY2 0x90700010,10,1
|
||||
#define XPT_SYNC_POLARITY3 0x90700010,11,1
|
||||
#define XPT_SYNC_POLARITY4 0x90700010,12,1
|
||||
#define XPT_SYNC_POLARITY5 0x90700010,13,1
|
||||
#define XPT_SYNC_POLARITY6 0x90700010,14,1
|
||||
#define XPT_SYNC_POLARITY7 0x90700010,15,1
|
||||
#define XPT_TS_CLK_OUT_EN0 0x907001D4,0,1
|
||||
#define XPT_TS_CLK_OUT_EN1 0x907001D4,1,1
|
||||
#define XPT_TS_CLK_OUT_EN2 0x907001D4,2,1
|
||||
#define XPT_TS_CLK_OUT_EN3 0x907001D4,3,1
|
||||
#define XPT_TS_CLK_OUT_EN4 0x907001D4,4,1
|
||||
#define XPT_TS_CLK_OUT_EN5 0x907001D4,5,1
|
||||
#define XPT_TS_CLK_OUT_EN6 0x907001D4,6,1
|
||||
#define XPT_TS_CLK_OUT_EN7 0x907001D4,7,1
|
||||
#define XPT_TS_CLK_OUT_EN_PARALLEL 0x907001D4,8,1
|
||||
#define XPT_TS_CLK_PHASE0 0x90700018,0,3
|
||||
#define XPT_TS_CLK_PHASE1 0x90700018,4,3
|
||||
#define XPT_TS_CLK_PHASE2 0x90700018,8,3
|
||||
#define XPT_TS_CLK_PHASE3 0x90700018,12,3
|
||||
#define XPT_TS_CLK_PHASE4 0x90700018,16,3
|
||||
#define XPT_TS_CLK_PHASE5 0x90700018,20,3
|
||||
#define XPT_TS_CLK_PHASE6 0x90700018,24,3
|
||||
#define XPT_TS_CLK_PHASE7 0x90700018,28,3
|
||||
#define XPT_VALID_POLARITY0 0x90700014,0,1
|
||||
#define XPT_VALID_POLARITY1 0x90700014,1,1
|
||||
#define XPT_VALID_POLARITY2 0x90700014,2,1
|
||||
#define XPT_VALID_POLARITY3 0x90700014,3,1
|
||||
#define XPT_VALID_POLARITY4 0x90700014,4,1
|
||||
#define XPT_VALID_POLARITY5 0x90700014,5,1
|
||||
#define XPT_VALID_POLARITY6 0x90700014,6,1
|
||||
#define XPT_VALID_POLARITY7 0x90700014,7,1
|
||||
#define XPT_ZERO_FILL_COUNT 0x90700008,8,6
|
||||
|
||||
#define XPT_PACKET_GAP_MIN_BASEADDR 0x90700044
|
||||
#define XPT_PACKET_GAP_MIN_TIMER XPT_PACKET_GAP_MIN_BASEADDR,0,16
|
||||
#define XPT_NCO_COUNT_MIN0 XPT_PACKET_GAP_MIN_BASEADDR,16,8
|
||||
#define XPT_NCO_COUNT_BASEADDR 0x90700238
|
||||
#define XPT_NCO_COUNT_MIN1 XPT_NCO_COUNT_BASEADDR,0,8
|
||||
#define XPT_NCO_COUNT_MIN2 XPT_NCO_COUNT_BASEADDR,8,8
|
||||
#define XPT_NCO_COUNT_MIN3 XPT_NCO_COUNT_BASEADDR,16,8
|
||||
#define XPT_NCO_COUNT_MIN4 XPT_NCO_COUNT_BASEADDR,24,8
|
||||
|
||||
#define XPT_NCO_COUNT_BASEADDR1 0x9070023C
|
||||
#define XPT_NCO_COUNT_MIN5 XPT_NCO_COUNT_BASEADDR1,0,8
|
||||
#define XPT_NCO_COUNT_MIN6 XPT_NCO_COUNT_BASEADDR1,8,8
|
||||
#define XPT_NCO_COUNT_MIN7 XPT_NCO_COUNT_BASEADDR1,16,8
|
||||
|
||||
// V2 DigRF status register
|
||||
#define BB0_DIGRF_CAPT_DONE 0x908000CC,0,1
|
||||
#define PRCM_PRCM_CHIP_ID 0x80030000,0,12
|
||||
|
||||
#define XPT_PID_BASEADDR 0x90708000
|
||||
#define XPT_PID_VALID0 XPT_PID_BASEADDR,0,1
|
||||
#define XPT_PID_DROP0 XPT_PID_BASEADDR,1,1
|
||||
#define XPT_PID_REMAP0 XPT_PID_BASEADDR,2,1
|
||||
#define XPT_PID_VALUE0 XPT_PID_BASEADDR,4,13
|
||||
#define XPT_PID_MASK0 XPT_PID_BASEADDR,19,13
|
||||
|
||||
#define XPT_PID_REMAP_BASEADDR 0x90708004
|
||||
#define XPT_PID_REMAP_VALUE0 XPT_PID_REMAP_BASEADDR,0,13
|
||||
#define XPT_PID_PORT_ID0 XPT_PID_REMAP_BASEADDR,16,3
|
||||
|
||||
#define XPT_KNOWN_PID_BASEADDR 0x90709000
|
||||
#define XPT_KNOWN_PID_VALID0 XPT_KNOWN_PID_BASEADDR,0,1
|
||||
#define XPT_KNOWN_PID_DROP0 XPT_KNOWN_PID_BASEADDR,1,1
|
||||
#define XPT_KNOWN_PID_REMAP0 XPT_KNOWN_PID_BASEADDR,2,1
|
||||
#define XPT_KNOWN_PID_REMAP_VALUE0 XPT_KNOWN_PID_BASEADDR,16,13
|
||||
|
||||
#define XPT_PID_BASEADDR1 0x9070A000
|
||||
#define XPT_PID_VALID1 XPT_PID_BASEADDR1,0,1
|
||||
#define XPT_PID_DROP1 XPT_PID_BASEADDR1,1,1
|
||||
#define XPT_PID_REMAP1 XPT_PID_BASEADDR1,2,1
|
||||
#define XPT_PID_VALUE1 XPT_PID_BASEADDR1,4,13
|
||||
#define XPT_PID_MASK1 XPT_PID_BASEADDR1,19,13
|
||||
|
||||
#define XPT_PID_REMAP_BASEADDR1 0x9070A004
|
||||
#define XPT_PID_REMAP_VALUE1 XPT_PID_REMAP_BASEADDR1,0,13
|
||||
|
||||
#define XPT_KNOWN_PID_BASEADDR1 0x9070B000
|
||||
#define XPT_KNOWN_PID_VALID1 XPT_KNOWN_PID_BASEADDR1,0,1
|
||||
#define XPT_KNOWN_PID_DROP1 XPT_KNOWN_PID_BASEADDR1,1,1
|
||||
#define XPT_KNOWN_PID_REMAP1 XPT_KNOWN_PID_BASEADDR1,2,1
|
||||
#define XPT_KNOWN_PID_REMAP_VALUE1 XPT_KNOWN_PID_BASEADDR1,16,13
|
||||
|
||||
#define XPT_BERT_LOCK_BASEADDR 0x907000B8
|
||||
#define XPT_BERT_LOCK_THRESHOLD XPT_BERT_LOCK_BASEADDR,0,8
|
||||
#define XPT_BERT_LOCK_WINDOW XPT_BERT_LOCK_BASEADDR,8,8
|
||||
|
||||
#define XPT_BERT_BASEADDR 0x907000BC
|
||||
#define XPT_BERT_ENABLE0 XPT_BERT_BASEADDR,0,1
|
||||
#define XPT_BERT_ENABLE1 XPT_BERT_BASEADDR,1,1
|
||||
#define XPT_BERT_ENABLE2 XPT_BERT_BASEADDR,2,1
|
||||
#define XPT_BERT_ENABLE3 XPT_BERT_BASEADDR,3,1
|
||||
#define XPT_BERT_ENABLE4 XPT_BERT_BASEADDR,4,1
|
||||
#define XPT_BERT_ENABLE5 XPT_BERT_BASEADDR,5,1
|
||||
#define XPT_BERT_ENABLE6 XPT_BERT_BASEADDR,6,1
|
||||
#define XPT_BERT_ENABLE7 XPT_BERT_BASEADDR,7,1
|
||||
#define XPT_BERT_SEQUENCE_PN23_0 XPT_BERT_BASEADDR,8,1
|
||||
#define XPT_BERT_SEQUENCE_PN23_1 XPT_BERT_BASEADDR,9,1
|
||||
#define XPT_BERT_SEQUENCE_PN23_2 XPT_BERT_BASEADDR,10,1
|
||||
#define XPT_BERT_SEQUENCE_PN23_3 XPT_BERT_BASEADDR,11,1
|
||||
#define XPT_BERT_SEQUENCE_PN23_4 XPT_BERT_BASEADDR,12,1
|
||||
#define XPT_BERT_SEQUENCE_PN23_5 XPT_BERT_BASEADDR,13,1
|
||||
#define XPT_BERT_SEQUENCE_PN23_6 XPT_BERT_BASEADDR,14,1
|
||||
#define XPT_BERT_SEQUENCE_PN23_7 XPT_BERT_BASEADDR,15,1
|
||||
#define XPT_LOCK_RESYNC0 XPT_BERT_BASEADDR,16,1
|
||||
#define XPT_LOCK_RESYNC1 XPT_BERT_BASEADDR,17,1
|
||||
#define XPT_LOCK_RESYNC2 XPT_BERT_BASEADDR,18,1
|
||||
#define XPT_LOCK_RESYNC3 XPT_BERT_BASEADDR,19,1
|
||||
#define XPT_LOCK_RESYNC4 XPT_BERT_BASEADDR,20,1
|
||||
#define XPT_LOCK_RESYNC5 XPT_BERT_BASEADDR,21,1
|
||||
#define XPT_LOCK_RESYNC6 XPT_BERT_BASEADDR,22,1
|
||||
#define XPT_LOCK_RESYNC7 XPT_BERT_BASEADDR,23,1
|
||||
#define XPT_BERT_DATA_POLARITY0 XPT_BERT_BASEADDR,24,1
|
||||
#define XPT_BERT_DATA_POLARITY1 XPT_BERT_BASEADDR,25,1
|
||||
#define XPT_BERT_DATA_POLARITY2 XPT_BERT_BASEADDR,26,1
|
||||
#define XPT_BERT_DATA_POLARITY3 XPT_BERT_BASEADDR,27,1
|
||||
#define XPT_BERT_DATA_POLARITY4 XPT_BERT_BASEADDR,28,1
|
||||
#define XPT_BERT_DATA_POLARITY5 XPT_BERT_BASEADDR,29,1
|
||||
#define XPT_BERT_DATA_POLARITY6 XPT_BERT_BASEADDR,30,1
|
||||
#define XPT_BERT_DATA_POLARITY7 XPT_BERT_BASEADDR,31,1
|
||||
|
||||
#define XPT_BERT_INVERT_BASEADDR 0x907000C0
|
||||
#define XPT_BERT_INVERT_DATA0 XPT_BERT_INVERT_BASEADDR,0,1
|
||||
#define XPT_BERT_INVERT_DATA1 XPT_BERT_INVERT_BASEADDR,1,1
|
||||
#define XPT_BERT_INVERT_DATA2 XPT_BERT_INVERT_BASEADDR,2,1
|
||||
#define XPT_BERT_INVERT_DATA3 XPT_BERT_INVERT_BASEADDR,3,1
|
||||
#define XPT_BERT_INVERT_DATA4 XPT_BERT_INVERT_BASEADDR,4,1
|
||||
#define XPT_BERT_INVERT_DATA5 XPT_BERT_INVERT_BASEADDR,5,1
|
||||
#define XPT_BERT_INVERT_DATA6 XPT_BERT_INVERT_BASEADDR,6,1
|
||||
#define XPT_BERT_INVERT_DATA7 XPT_BERT_INVERT_BASEADDR,7,1
|
||||
#define XPT_BERT_INVERT_SEQUENCE0 XPT_BERT_INVERT_BASEADDR,8,1
|
||||
#define XPT_BERT_INVERT_SEQUENCE1 XPT_BERT_INVERT_BASEADDR,9,1
|
||||
#define XPT_BERT_INVERT_SEQUENCE2 XPT_BERT_INVERT_BASEADDR,10,1
|
||||
#define XPT_BERT_INVERT_SEQUENCE3 XPT_BERT_INVERT_BASEADDR,11,1
|
||||
#define XPT_BERT_INVERT_SEQUENCE4 XPT_BERT_INVERT_BASEADDR,12,1
|
||||
#define XPT_BERT_INVERT_SEQUENCE5 XPT_BERT_INVERT_BASEADDR,13,1
|
||||
#define XPT_BERT_INVERT_SEQUENCE6 XPT_BERT_INVERT_BASEADDR,14,1
|
||||
#define XPT_BERT_INVERT_SEQUENCE7 XPT_BERT_INVERT_BASEADDR,15,1
|
||||
#define XPT_BERT_OUTPUT_POLARITY0 XPT_BERT_INVERT_BASEADDR,16,1
|
||||
#define XPT_BERT_OUTPUT_POLARITY1 XPT_BERT_INVERT_BASEADDR,17,1
|
||||
#define XPT_BERT_OUTPUT_POLARITY2 XPT_BERT_INVERT_BASEADDR,18,1
|
||||
#define XPT_BERT_OUTPUT_POLARITY3 XPT_BERT_INVERT_BASEADDR,19,1
|
||||
#define XPT_BERT_OUTPUT_POLARITY4 XPT_BERT_INVERT_BASEADDR,20,1
|
||||
#define XPT_BERT_OUTPUT_POLARITY5 XPT_BERT_INVERT_BASEADDR,21,1
|
||||
#define XPT_BERT_OUTPUT_POLARITY6 XPT_BERT_INVERT_BASEADDR,22,1
|
||||
#define XPT_BERT_OUTPUT_POLARITY7 XPT_BERT_INVERT_BASEADDR,23,1
|
||||
|
||||
#define XPT_BERT_HEADER_BASEADDR 0x907000C4
|
||||
#define XPT_BERT_HEADER_MODE0 XPT_BERT_HEADER_BASEADDR,0,2
|
||||
#define XPT_BERT_HEADER_MODE1 XPT_BERT_HEADER_BASEADDR,2,2
|
||||
#define XPT_BERT_HEADER_MODE2 XPT_BERT_HEADER_BASEADDR,4,2
|
||||
#define XPT_BERT_HEADER_MODE3 XPT_BERT_HEADER_BASEADDR,6,2
|
||||
#define XPT_BERT_HEADER_MODE4 XPT_BERT_HEADER_BASEADDR,8,2
|
||||
#define XPT_BERT_HEADER_MODE5 XPT_BERT_HEADER_BASEADDR,10,2
|
||||
#define XPT_BERT_HEADER_MODE6 XPT_BERT_HEADER_BASEADDR,12,2
|
||||
#define XPT_BERT_HEADER_MODE7 XPT_BERT_HEADER_BASEADDR,14,2
|
||||
|
||||
#define XPT_BERT_BASEADDR1 0x907000C8
|
||||
#define XPT_BERT_LOCKED0 XPT_BERT_BASEADDR1,0,1
|
||||
#define XPT_BERT_LOCKED1 XPT_BERT_BASEADDR1,1,1
|
||||
#define XPT_BERT_LOCKED2 XPT_BERT_BASEADDR1,2,1
|
||||
#define XPT_BERT_LOCKED3 XPT_BERT_BASEADDR1,3,1
|
||||
#define XPT_BERT_LOCKED4 XPT_BERT_BASEADDR1,4,1
|
||||
#define XPT_BERT_LOCKED5 XPT_BERT_BASEADDR1,5,1
|
||||
#define XPT_BERT_LOCKED6 XPT_BERT_BASEADDR1,6,1
|
||||
#define XPT_BERT_LOCKED7 XPT_BERT_BASEADDR1,7,1
|
||||
#define XPT_BERT_BIT_COUNT_SAT0 XPT_BERT_BASEADDR1,8,1
|
||||
#define XPT_BERT_BIT_COUNT_SAT1 XPT_BERT_BASEADDR1,9,1
|
||||
#define XPT_BERT_BIT_COUNT_SAT2 XPT_BERT_BASEADDR1,10,1
|
||||
#define XPT_BERT_BIT_COUNT_SAT3 XPT_BERT_BASEADDR1,11,1
|
||||
#define XPT_BERT_BIT_COUNT_SAT4 XPT_BERT_BASEADDR1,12,1
|
||||
#define XPT_BERT_BIT_COUNT_SAT5 XPT_BERT_BASEADDR1,13,1
|
||||
#define XPT_BERT_BIT_COUNT_SAT6 XPT_BERT_BASEADDR1,14,1
|
||||
#define XPT_BERT_BIT_COUNT_SAT7 XPT_BERT_BASEADDR1,15,1
|
||||
|
||||
#define XPT_BERT_BIT_COUNT0_BASEADDR 0x907000CC
|
||||
#define XPT_BERT_BIT_COUNT0_LO XPT_BERT_BIT_COUNT0_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_BIT_COUNT0_BASEADDR1 0x907000D0
|
||||
#define XPT_BERT_BIT_COUNT0_HI XPT_BERT_BIT_COUNT0_BASEADDR1,0,18
|
||||
|
||||
#define XPT_BERT_BIT_COUNT1_BASEADDR 0x907000D4
|
||||
#define XPT_BERT_BIT_COUNT1_LO XPT_BERT_BIT_COUNT1_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_BIT_COUNT1_BASEADDR1 0x907000D8
|
||||
#define XPT_BERT_BIT_COUNT1_HI XPT_BERT_BIT_COUNT1_BASEADDR1,0,18
|
||||
|
||||
#define XPT_BERT_BIT_COUNT2_BASEADDR 0x907000DC
|
||||
#define XPT_BERT_BIT_COUNT2_LO XPT_BERT_BIT_COUNT2_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_BIT_COUNT2_BASEADDR1 0x907000E0
|
||||
#define XPT_BERT_BIT_COUNT2_HI XPT_BERT_BIT_COUNT2_BASEADDR1,0,18
|
||||
|
||||
#define XPT_BERT_BIT_COUNT3_BASEADDR 0x907000E4
|
||||
#define XPT_BERT_BIT_COUNT3_LO XPT_BERT_BIT_COUNT3_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_BIT_COUNT3_BASEADDR1 0x907000E8
|
||||
#define XPT_BERT_BIT_COUNT3_HI XPT_BERT_BIT_COUNT3_BASEADDR1,0,18
|
||||
|
||||
#define XPT_BERT_BIT_COUNT4_BASEADDR 0x907000EC
|
||||
#define XPT_BERT_BIT_COUNT4_LO XPT_BERT_BIT_COUNT4_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_BIT_COUNT4_BASEADDR1 0x907000F0
|
||||
#define XPT_BERT_BIT_COUNT4_HI XPT_BERT_BIT_COUNT4_BASEADDR1,0,18
|
||||
|
||||
#define XPT_BERT_BIT_COUNT5_BASEADDR 0x907000F4
|
||||
#define XPT_BERT_BIT_COUNT5_LO XPT_BERT_BIT_COUNT5_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_BIT_COUNT5_BASEADDR1 0x907000F8
|
||||
#define XPT_BERT_BIT_COUNT5_HI XPT_BERT_BIT_COUNT5_BASEADDR1,0,18
|
||||
|
||||
#define XPT_BERT_BIT_COUNT6_BASEADDR 0x907000FC
|
||||
#define XPT_BERT_BIT_COUNT6_LO XPT_BERT_BIT_COUNT6_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_BIT_COUNT6_BASEADDR1 0x90700100
|
||||
#define XPT_BERT_BIT_COUNT6_HI XPT_BERT_BIT_COUNT6_BASEADDR1,0,18
|
||||
|
||||
#define XPT_BERT_BIT_COUNT7_BASEADDR 0x90700104
|
||||
#define XPT_BERT_BIT_COUNT7_LO XPT_BERT_BIT_COUNT7_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_BIT_COUNT7_BASEADDR1 0x90700108
|
||||
#define XPT_BERT_BIT_COUNT7_HI XPT_BERT_BIT_COUNT7_BASEADDR1,0,18
|
||||
|
||||
#define XPT_BERT_ERR_COUNT0_BASEADDR 0x9070010C
|
||||
#define XPT_BERT_ERR_COUNT0_LO XPT_BERT_ERR_COUNT0_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_ERR_COUNT0_BASEADDR1 0x90700110
|
||||
#define XPT_BERT_ERR_COUNT0_HI XPT_BERT_ERR_COUNT0_BASEADDR1,0,8
|
||||
|
||||
#define XPT_BERT_ERR_COUNT1_BASEADDR 0x90700114
|
||||
#define XPT_BERT_ERR_COUNT1_LO XPT_BERT_ERR_COUNT1_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_ERR_COUNT1_BASEADDR1 0x90700118
|
||||
#define XPT_BERT_ERR_COUNT1_HI XPT_BERT_ERR_COUNT1_BASEADDR1,0,8
|
||||
|
||||
#define XPT_BERT_ERR_COUNT2_BASEADDR 0x9070011C
|
||||
#define XPT_BERT_ERR_COUNT2_LO XPT_BERT_ERR_COUNT2_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_ERR_COUNT2_BASEADDR1 0x90700120
|
||||
#define XPT_BERT_ERR_COUNT2_HI XPT_BERT_ERR_COUNT2_BASEADDR1,0,8
|
||||
|
||||
#define XPT_BERT_ERR_COUNT3_BASEADDR 0x90700124
|
||||
#define XPT_BERT_ERR_COUNT3_LO XPT_BERT_ERR_COUNT3_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_ERR_COUNT3_BASEADDR1 0x90700128
|
||||
#define XPT_BERT_ERR_COUNT3_HI XPT_BERT_ERR_COUNT3_BASEADDR1,0,8
|
||||
|
||||
#define XPT_BERT_ERR_COUNT4_BASEADDR 0x9070012C
|
||||
#define XPT_BERT_ERR_COUNT4_LO XPT_BERT_ERR_COUNT4_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_ERR_COUNT4_BASEADDR1 0x90700130
|
||||
#define XPT_BERT_ERR_COUNT4_HI XPT_BERT_ERR_COUNT4_BASEADDR1,0,8
|
||||
|
||||
#define XPT_BERT_ERR_COUNT5_BASEADDR 0x90700134
|
||||
#define XPT_BERT_ERR_COUNT5_LO XPT_BERT_ERR_COUNT5_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_ERR_COUNT5_BASEADDR1 0x90700138
|
||||
#define XPT_BERT_ERR_COUNT5_HI XPT_BERT_ERR_COUNT5_BASEADDR1,0,8
|
||||
|
||||
#define XPT_BERT_ERR_COUNT6_BASEADDR 0x9070013C
|
||||
#define XPT_BERT_ERR_COUNT6_LO XPT_BERT_ERR_COUNT6_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_ERR_COUNT6_BASEADDR1 0x90700140
|
||||
#define XPT_BERT_ERR_COUNT6_HI XPT_BERT_ERR_COUNT6_BASEADDR1,0,8
|
||||
|
||||
#define XPT_BERT_ERR_COUNT7_BASEADDR 0x90700144
|
||||
#define XPT_BERT_ERR_COUNT7_LO XPT_BERT_ERR_COUNT7_BASEADDR,0,32
|
||||
|
||||
#define XPT_BERT_ERR_COUNT7_BASEADDR1 0x90700148
|
||||
#define XPT_BERT_ERR_COUNT7_HI XPT_BERT_ERR_COUNT7_BASEADDR1,0,8
|
||||
|
||||
#define XPT_BERT_ERROR_BASEADDR 0x9070014C
|
||||
#define XPT_BERT_ERROR_INSERT XPT_BERT_ERROR_BASEADDR,0,24
|
||||
|
||||
#define XPT_BERT_ANALYZER_BASEADDR 0x90700150
|
||||
#define XPT_BERT_ANALYZER_ENABLE XPT_BERT_ANALYZER_BASEADDR,0,1
|
||||
#define XPT_BERT_ANALYZER_PORT XPT_BERT_ANALYZER_BASEADDR,4,3
|
||||
#define XPT_BERT_ANALYZER_ERR_THRES XPT_BERT_ANALYZER_BASEADDR,15,17
|
||||
|
||||
#define XPT_BERT_ANALYZER_BASEADDR1 0x90700154
|
||||
#define XPT_BERT_ANALYZER_START XPT_BERT_ANALYZER_BASEADDR1,0,32
|
||||
|
||||
#define XPT_BERT_ANALYZER_BASEADDR2 0x90700158
|
||||
#define XPT_BERT_ANALYZER_TSTAMP0 XPT_BERT_ANALYZER_BASEADDR2,0,32
|
||||
|
||||
#define XPT_BERT_ANALYZER_BASEADDR3 0x9070015C
|
||||
#define XPT_BERT_ANALYZER_TSTAMP1 XPT_BERT_ANALYZER_BASEADDR3,0,32
|
||||
|
||||
#define XPT_BERT_ANALYZER_BASEADDR4 0x90700160
|
||||
#define XPT_BERT_ANALYZER_TSTAMP2 XPT_BERT_ANALYZER_BASEADDR4,0,32
|
||||
|
||||
#define XPT_BERT_ANALYZER_BASEADDR5 0x90700164
|
||||
#define XPT_BERT_ANALYZER_TSTAMP3 XPT_BERT_ANALYZER_BASEADDR5,0,32
|
||||
|
||||
#define XPT_BERT_ANALYZER_BASEADDR6 0x90700168
|
||||
#define XPT_BERT_ANALYZER_TSTAMP4 XPT_BERT_ANALYZER_BASEADDR6,0,32
|
||||
|
||||
#define XPT_BERT_ANALYZER_BASEADDR7 0x9070016C
|
||||
#define XPT_BERT_ANALYZER_TSTAMP5 XPT_BERT_ANALYZER_BASEADDR7,0,32
|
||||
|
||||
#define XPT_BERT_ANALYZER_BASEADDR8 0x90700170
|
||||
#define XPT_BERT_ANALYZER_TSTAMP6 XPT_BERT_ANALYZER_BASEADDR8,0,32
|
||||
|
||||
#define XPT_BERT_ANALYZER_BASEADDR9 0x90700174
|
||||
#define XPT_BERT_ANALYZER_TSTAMP7 XPT_BERT_ANALYZER_BASEADDR9,0,32
|
||||
|
||||
#define XPT_DMD0_BASEADDR 0x9070024C
|
||||
#define XPT_DMD0_SEL XPT_DMD0_BASEADDR,0,3
|
||||
#define XPT_DMD1_SEL XPT_DMD0_BASEADDR,4,3
|
||||
#define XPT_DMD2_SEL XPT_DMD0_BASEADDR,8,3
|
||||
#define XPT_DMD3_SEL XPT_DMD0_BASEADDR,12,3
|
||||
#define XPT_DMD4_SEL XPT_DMD0_BASEADDR,16,3
|
||||
#define XPT_DMD5_SEL XPT_DMD0_BASEADDR,20,3
|
||||
#define XPT_DMD6_SEL XPT_DMD0_BASEADDR,24,3
|
||||
#define XPT_DMD7_SEL XPT_DMD0_BASEADDR,28,3
|
||||
|
||||
// V2 AGC Gain Freeze & step
|
||||
#define DBG_ENABLE_DISABLE_AGC (0x3FFFCF60) // 1: DISABLE, 0:ENABLE
|
||||
#define WB_DFE0_DFE_FB_RF1_BASEADDR 0x903004A4
|
||||
#define WB_DFE0_DFE_FB_RF1_BO WB_DFE0_DFE_FB_RF1_BASEADDR,0,3
|
||||
#define WB_DFE0_DFE_FB_RF2_BO WB_DFE0_DFE_FB_RF1_BASEADDR,4,4
|
||||
#define WB_DFE0_DFE_FB_LNA_BO WB_DFE0_DFE_FB_RF1_BASEADDR,8,2
|
||||
|
||||
#define WB_DFE1_DFE_FB_RF1_BASEADDR 0x904004A4
|
||||
#define WB_DFE1_DFE_FB_RF1_BO WB_DFE1_DFE_FB_RF1_BASEADDR,0,3
|
||||
#define WB_DFE1_DFE_FB_RF2_BO WB_DFE1_DFE_FB_RF1_BASEADDR,4,4
|
||||
#define WB_DFE1_DFE_FB_LNA_BO WB_DFE1_DFE_FB_RF1_BASEADDR,8,2
|
||||
|
||||
#define WB_DFE2_DFE_FB_RF1_BASEADDR 0x905004A4
|
||||
#define WB_DFE2_DFE_FB_RF1_BO WB_DFE2_DFE_FB_RF1_BASEADDR,0,3
|
||||
#define WB_DFE2_DFE_FB_RF2_BO WB_DFE2_DFE_FB_RF1_BASEADDR,4,4
|
||||
#define WB_DFE2_DFE_FB_LNA_BO WB_DFE2_DFE_FB_RF1_BASEADDR,8,2
|
||||
|
||||
#define WB_DFE3_DFE_FB_RF1_BASEADDR 0x906004A4
|
||||
#define WB_DFE3_DFE_FB_RF1_BO WB_DFE3_DFE_FB_RF1_BASEADDR,0,3
|
||||
#define WB_DFE3_DFE_FB_RF2_BO WB_DFE3_DFE_FB_RF1_BASEADDR,4,4
|
||||
#define WB_DFE3_DFE_FB_LNA_BO WB_DFE3_DFE_FB_RF1_BASEADDR,8,2
|
||||
|
||||
#define AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR 0x90200104
|
||||
#define AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_2 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,0,1
|
||||
#define AFE_REG_D2A_TA_RFFE_RF1_BO_1P8_3 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,1,1
|
||||
#define AFE_REG_D2A_TB_RFFE_LNA_BO_1P8_2 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,2,1
|
||||
#define AFE_REG_D2A_TB_RFFE_RF1_BO_1P8_3 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,3,1
|
||||
#define AFE_REG_D2A_TC_RFFE_LNA_BO_1P8_2 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,4,1
|
||||
#define AFE_REG_D2A_TC_RFFE_RF1_BO_1P8_3 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,5,1
|
||||
#define AFE_REG_D2A_TD_RFFE_LNA_BO_1P8_2 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,6,1
|
||||
#define AFE_REG_D2A_TD_RFFE_RF1_BO_1P8_3 AFE_REG_D2A_TA_RFFE_LNA_BO_1P8_BASEADDR,7,1
|
||||
|
||||
#define AFE_REG_AFE_REG_SPARE_BASEADDR 0x902000A0
|
||||
#define AFE_REG_D2A_TA_RFFE_RF1_CAP_1P8 AFE_REG_AFE_REG_SPARE_BASEADDR,13,5
|
||||
|
||||
#define AFE_REG_AFE_REG_SPARE_BASEADDR1 0x902000B4
|
||||
#define AFE_REG_D2A_TB_RFFE_RF1_CAP_1P8 AFE_REG_AFE_REG_SPARE_BASEADDR1,13,5
|
||||
|
||||
#define AFE_REG_AFE_REG_SPARE_BASEADDR2 0x902000C4
|
||||
#define AFE_REG_D2A_TC_RFFE_RF1_CAP_1P8 AFE_REG_AFE_REG_SPARE_BASEADDR2,13,5
|
||||
|
||||
#define AFE_REG_AFE_REG_SPARE_BASEADDR3 0x902000D4
|
||||
#define AFE_REG_D2A_TD_RFFE_RF1_CAP_1P8 AFE_REG_AFE_REG_SPARE_BASEADDR3,13,5
|
||||
|
||||
#define WB_DFE0_DFE_FB_AGC_BASEADDR 0x90300498
|
||||
#define WB_DFE0_DFE_FB_AGC_APPLY WB_DFE0_DFE_FB_AGC_BASEADDR,0,1
|
||||
|
||||
#define WB_DFE1_DFE_FB_AGC_BASEADDR 0x90400498
|
||||
#define WB_DFE1_DFE_FB_AGC_APPLY WB_DFE1_DFE_FB_AGC_BASEADDR,0,1
|
||||
|
||||
#define WB_DFE2_DFE_FB_AGC_BASEADDR 0x90500498
|
||||
#define WB_DFE2_DFE_FB_AGC_APPLY WB_DFE2_DFE_FB_AGC_BASEADDR,0,1
|
||||
|
||||
#define WB_DFE3_DFE_FB_AGC_BASEADDR 0x90600498
|
||||
#define WB_DFE3_DFE_FB_AGC_APPLY WB_DFE3_DFE_FB_AGC_BASEADDR,0,1
|
||||
|
||||
#define WDT_WD_INT_BASEADDR 0x8002000C
|
||||
#define WDT_WD_INT_STATUS WDT_WD_INT_BASEADDR,0,1
|
||||
|
||||
#define FSK_TX_FTM_BASEADDR 0x80090000
|
||||
#define FSK_TX_FTM_OE FSK_TX_FTM_BASEADDR,12,1
|
||||
#define FSK_TX_FTM_TX_EN FSK_TX_FTM_BASEADDR,10,1
|
||||
#define FSK_TX_FTM_FORCE_CARRIER_ON FSK_TX_FTM_BASEADDR,1,1
|
||||
#define FSK_TX_FTM_FORCE_MARK_SPACE FSK_TX_FTM_BASEADDR,0,1
|
||||
|
||||
#define FSK_TX_FTM_TX_CNT_BASEADDR 0x80090018
|
||||
#define FSK_TX_FTM_TX_CNT_INT FSK_TX_FTM_TX_CNT_BASEADDR,8,4
|
||||
#define FSK_TX_FTM_TX_INT_EN FSK_TX_FTM_TX_CNT_BASEADDR,4,1
|
||||
#define FSK_TX_FTM_TX_INT_SRC_SEL FSK_TX_FTM_TX_CNT_BASEADDR,0,2
|
||||
|
||||
#define AFE_REG_D2A_FSK_BIAS_BASEADDR 0x90200040
|
||||
#define AFE_REG_D2A_FSK_BIAS_EN AFE_REG_D2A_FSK_BIAS_BASEADDR,0,1
|
||||
#define AFE_REG_D2A_FSK_TEST_EN AFE_REG_D2A_FSK_BIAS_BASEADDR,10,1
|
||||
#define AFE_REG_D2A_FSK_TEST_MODE AFE_REG_D2A_FSK_BIAS_BASEADDR,11,4
|
||||
#define AFE_REG_D2A_FSK_TERM_INT_EN AFE_REG_D2A_FSK_BIAS_BASEADDR,15,1
|
||||
#define AFE_REG_D2A_FSK_RESETB_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,16,1
|
||||
#define AFE_REG_D2A_FSK_REG_EN_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,17,1
|
||||
#define AFE_REG_D2A_FSK_REG_EN_LKG_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,18,1
|
||||
#define AFE_REG_D2A_FSK_REG_AMP_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,19,3
|
||||
#define AFE_REG_D2A_FSK_REG_TEST_CTRL_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,22,2
|
||||
#define AFE_REG_D2A_DSQ_RX_MODE AFE_REG_D2A_FSK_BIAS_BASEADDR,24,1
|
||||
#define AFE_REG_D2A_DSQ_RX_EN AFE_REG_D2A_FSK_BIAS_BASEADDR,25,1
|
||||
#define AFE_REG_D2A_DSQ_HYST AFE_REG_D2A_FSK_BIAS_BASEADDR,26,2
|
||||
#define AFE_REG_D2A_DSQ_RESETB_1P8 AFE_REG_D2A_FSK_BIAS_BASEADDR,28,1
|
||||
#define AFE_REG_D2A_FSK_CLKRX_ENA AFE_REG_D2A_FSK_BIAS_BASEADDR,29,1
|
||||
|
||||
#define DMD_TEI_BASEADDR 0x3FFFEBE0
|
||||
#define DMD_TEI_ENA DMD_TEI_BASEADDR,0,1
|
||||
|
||||
#define xpt_shm_input_control0 0x90700270,0,8
|
||||
#define xpt_shm_input_control1 0x90700270,8,8
|
||||
#define xpt_shm_input_control2 0x90700270,16,8
|
||||
#define xpt_shm_input_control3 0x90700270,24,8
|
||||
#define xpt_shm_input_control4 0x90700274,0,8
|
||||
#define xpt_shm_input_control5 0x90700274,8,8
|
||||
#define xpt_shm_input_control6 0x90700274,16,8
|
||||
#define xpt_shm_input_control7 0x90700274,24,8
|
||||
|
||||
|
||||
#define xpt_shm_output_control0 0x90700278,0,8
|
||||
#define xpt_shm_output_control1 0x90700278,8,8
|
||||
#define xpt_shm_output_control2 0x90700278,16,8
|
||||
#define xpt_shm_output_control3 0x90700278,24,8
|
||||
#define xpt_shm_output_control4 0x9070027C,0,8
|
||||
#define xpt_shm_output_control5 0x9070027C,8,8
|
||||
#define xpt_shm_output_control6 0x9070027C,16,8
|
||||
#define xpt_shm_output_control7 0x9070027C,24,8
|
||||
|
||||
#define xpt_mode_27mhz 0x90700184,0,1
|
||||
#define xpt_enable_pcr_count 0x90700184,1,1
|
||||
|
||||
#define xcpu_ctrl_003c_reg 0x9072003C,0,4
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //__MXL58X_REGISTERS_H__
|
3472
frontends/stv0367.c
Normal file
3472
frontends/stv0367.c
Normal file
File diff suppressed because it is too large
Load Diff
89
frontends/stv0367.h
Normal file
89
frontends/stv0367.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* stv0367.h
|
||||
*
|
||||
* Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
|
||||
*
|
||||
* Copyright (C) ST Microelectronics.
|
||||
* Copyright (C) 2010,2011 NetUP Inc.
|
||||
* Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
|
||||
*
|
||||
* 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; either version 2 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef STV0367_H
|
||||
#define STV0367_H
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
enum stv0367_ts_mode {
|
||||
STV0367_OUTPUTMODE_DEFAULT,
|
||||
STV0367_SERIAL_PUNCT_CLOCK,
|
||||
STV0367_SERIAL_CONT_CLOCK,
|
||||
STV0367_PARALLEL_PUNCT_CLOCK,
|
||||
STV0367_DVBCI_CLOCK
|
||||
};
|
||||
|
||||
enum stv0367_clk_pol {
|
||||
STV0367_CLOCKPOLARITY_DEFAULT,
|
||||
STV0367_RISINGEDGE_CLOCK,
|
||||
STV0367_FALLINGEDGE_CLOCK
|
||||
};
|
||||
|
||||
struct stv0367_config {
|
||||
u8 demod_address;
|
||||
u32 xtal;
|
||||
u32 if_khz;/*4500*/
|
||||
int if_iq_mode;
|
||||
int ts_mode;
|
||||
int clk_pol;
|
||||
};
|
||||
|
||||
enum stv0367_ter_if_iq_mode {
|
||||
FE_TER_NORMAL_IF_TUNER = 0,
|
||||
FE_TER_LONGPATH_IF_TUNER = 1,
|
||||
FE_TER_IQ_TUNER = 2
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if defined(CONFIG_DVB_STV0367) || (defined(CONFIG_DVB_STV0367_MODULE) \
|
||||
&& defined(MODULE))
|
||||
extern struct
|
||||
dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
extern struct
|
||||
dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
#else
|
||||
static inline struct
|
||||
dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
static inline struct
|
||||
dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
191
frontends/stv0367_priv.h
Normal file
191
frontends/stv0367_priv.h
Normal file
@ -0,0 +1,191 @@
|
||||
/*
|
||||
* stv0367_priv.h
|
||||
*
|
||||
* Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
|
||||
*
|
||||
* Copyright (C) ST Microelectronics.
|
||||
* Copyright (C) 2010,2011 NetUP Inc.
|
||||
* Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
|
||||
*
|
||||
* 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; either version 2 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 General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* Common driver error constants */
|
||||
|
||||
#ifndef STV0367_PRIV_H
|
||||
#define STV0367_PRIV_H
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE (1 == 1)
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE (!TRUE)
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/* MACRO definitions */
|
||||
#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
|
||||
#define MAX(X, Y) ((X) >= (Y) ? (X) : (Y))
|
||||
#define MIN(X, Y) ((X) <= (Y) ? (X) : (Y))
|
||||
#define INRANGE(X, Y, Z) \
|
||||
((((X) <= (Y)) && ((Y) <= (Z))) || \
|
||||
(((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
|
||||
|
||||
#ifndef MAKEWORD
|
||||
#define MAKEWORD(X, Y) (((X) << 8) + (Y))
|
||||
#endif
|
||||
|
||||
#define LSB(X) (((X) & 0xff))
|
||||
#define MSB(Y) (((Y) >> 8) & 0xff)
|
||||
#define MMSB(Y)(((Y) >> 16) & 0xff)
|
||||
|
||||
enum stv0367_ter_signal_type {
|
||||
FE_TER_NOAGC = 0,
|
||||
FE_TER_AGCOK = 5,
|
||||
FE_TER_NOTPS = 6,
|
||||
FE_TER_TPSOK = 7,
|
||||
FE_TER_NOSYMBOL = 8,
|
||||
FE_TER_BAD_CPQ = 9,
|
||||
FE_TER_PRFOUNDOK = 10,
|
||||
FE_TER_NOPRFOUND = 11,
|
||||
FE_TER_LOCKOK = 12,
|
||||
FE_TER_NOLOCK = 13,
|
||||
FE_TER_SYMBOLOK = 15,
|
||||
FE_TER_CPAMPOK = 16,
|
||||
FE_TER_NOCPAMP = 17,
|
||||
FE_TER_SWNOK = 18
|
||||
};
|
||||
|
||||
enum stv0367_ter_bw {
|
||||
FE_TER_CHAN_BW_6M = 6,
|
||||
FE_TER_CHAN_BW_7M = 7,
|
||||
FE_TER_CHAN_BW_8M = 8
|
||||
};
|
||||
|
||||
#if 0
|
||||
enum FE_TER_Rate_TPS {
|
||||
FE_TER_TPS_1_2 = 0,
|
||||
FE_TER_TPS_2_3 = 1,
|
||||
FE_TER_TPS_3_4 = 2,
|
||||
FE_TER_TPS_5_6 = 3,
|
||||
FE_TER_TPS_7_8 = 4
|
||||
};
|
||||
#endif
|
||||
|
||||
enum stv0367_ter_mode {
|
||||
FE_TER_MODE_2K,
|
||||
FE_TER_MODE_8K,
|
||||
FE_TER_MODE_4K
|
||||
};
|
||||
#if 0
|
||||
enum FE_TER_Hierarchy_Alpha {
|
||||
FE_TER_HIER_ALPHA_NONE, /* Regular modulation */
|
||||
FE_TER_HIER_ALPHA_1, /* Hierarchical modulation a = 1*/
|
||||
FE_TER_HIER_ALPHA_2, /* Hierarchical modulation a = 2*/
|
||||
FE_TER_HIER_ALPHA_4 /* Hierarchical modulation a = 4*/
|
||||
};
|
||||
#endif
|
||||
enum stv0367_ter_hierarchy {
|
||||
FE_TER_HIER_NONE, /*Hierarchy None*/
|
||||
FE_TER_HIER_LOW_PRIO, /*Hierarchy : Low Priority*/
|
||||
FE_TER_HIER_HIGH_PRIO, /*Hierarchy : High Priority*/
|
||||
FE_TER_HIER_PRIO_ANY /*Hierarchy :Any*/
|
||||
};
|
||||
|
||||
#if 0
|
||||
enum fe_stv0367_ter_spec {
|
||||
FE_TER_INVERSION_NONE = 0,
|
||||
FE_TER_INVERSION = 1,
|
||||
FE_TER_INVERSION_AUTO = 2,
|
||||
FE_TER_INVERSION_UNK = 4
|
||||
};
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
enum FE_TER_FECRate {
|
||||
FE_TER_FEC_NONE = 0x00, /* no FEC rate specified */
|
||||
FE_TER_FEC_ALL = 0xFF, /* Logical OR of all FECs */
|
||||
FE_TER_FEC_1_2 = 1,
|
||||
FE_TER_FEC_2_3 = (1 << 1),
|
||||
FE_TER_FEC_3_4 = (1 << 2),
|
||||
FE_TER_FEC_4_5 = (1 << 3),
|
||||
FE_TER_FEC_5_6 = (1 << 4),
|
||||
FE_TER_FEC_6_7 = (1 << 5),
|
||||
FE_TER_FEC_7_8 = (1 << 6),
|
||||
FE_TER_FEC_8_9 = (1 << 7)
|
||||
};
|
||||
|
||||
enum FE_TER_Rate {
|
||||
FE_TER_FE_1_2 = 0,
|
||||
FE_TER_FE_2_3 = 1,
|
||||
FE_TER_FE_3_4 = 2,
|
||||
FE_TER_FE_5_6 = 3,
|
||||
FE_TER_FE_6_7 = 4,
|
||||
FE_TER_FE_7_8 = 5
|
||||
};
|
||||
#endif
|
||||
|
||||
enum stv0367_ter_force {
|
||||
FE_TER_FORCENONE = 0,
|
||||
FE_TER_FORCE_M_G = 1
|
||||
};
|
||||
|
||||
enum stv0367cab_mod {
|
||||
FE_CAB_MOD_QAM4,
|
||||
FE_CAB_MOD_QAM16,
|
||||
FE_CAB_MOD_QAM32,
|
||||
FE_CAB_MOD_QAM64,
|
||||
FE_CAB_MOD_QAM128,
|
||||
FE_CAB_MOD_QAM256,
|
||||
FE_CAB_MOD_QAM512,
|
||||
FE_CAB_MOD_QAM1024
|
||||
};
|
||||
#if 0
|
||||
enum {
|
||||
FE_CAB_FEC_A = 1, /* J83 Annex A */
|
||||
FE_CAB_FEC_B = (1 << 1),/* J83 Annex B */
|
||||
FE_CAB_FEC_C = (1 << 2) /* J83 Annex C */
|
||||
} FE_CAB_FECType_t;
|
||||
#endif
|
||||
struct stv0367_cab_signal_info {
|
||||
int locked;
|
||||
u32 frequency; /* kHz */
|
||||
u32 symbol_rate; /* Mbds */
|
||||
enum stv0367cab_mod modulation;
|
||||
fe_spectral_inversion_t spect_inv;
|
||||
s32 Power_dBmx10; /* Power of the RF signal (dBm x 10) */
|
||||
u32 CN_dBx10; /* Carrier to noise ratio (dB x 10) */
|
||||
u32 BER; /* Bit error rate (x 10000000) */
|
||||
};
|
||||
|
||||
enum stv0367_cab_signal_type {
|
||||
FE_CAB_NOTUNER,
|
||||
FE_CAB_NOAGC,
|
||||
FE_CAB_NOSIGNAL,
|
||||
FE_CAB_NOTIMING,
|
||||
FE_CAB_TIMINGOK,
|
||||
FE_CAB_NOCARRIER,
|
||||
FE_CAB_CARRIEROK,
|
||||
FE_CAB_NOBLIND,
|
||||
FE_CAB_BLINDOK,
|
||||
FE_CAB_NODEMOD,
|
||||
FE_CAB_DEMODOK,
|
||||
FE_CAB_DATAOK
|
||||
};
|
||||
|
||||
#endif
|
3614
frontends/stv0367_regs.h
Normal file
3614
frontends/stv0367_regs.h
Normal file
File diff suppressed because it is too large
Load Diff
2161
frontends/stv0367dd.c
Normal file
2161
frontends/stv0367dd.c
Normal file
File diff suppressed because it is too large
Load Diff
18
frontends/stv0367dd.h
Normal file
18
frontends/stv0367dd.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef _STV0367DD_H_
|
||||
#define _STV0367DD_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
struct stv0367_cfg {
|
||||
u8 adr;
|
||||
u32 xtal;
|
||||
u8 parallel;
|
||||
u8 cont_clock;
|
||||
};
|
||||
|
||||
|
||||
extern struct dvb_frontend *stv0367_attach(struct i2c_adapter *i2c,
|
||||
struct stv0367_cfg *cfg,
|
||||
struct dvb_frontend **fe_t);
|
||||
#endif
|
3431
frontends/stv0367dd_regs.h
Normal file
3431
frontends/stv0367dd_regs.h
Normal file
File diff suppressed because it is too large
Load Diff
4936
frontends/stv090x.c
Normal file
4936
frontends/stv090x.c
Normal file
File diff suppressed because it is too large
Load Diff
134
frontends/stv090x.h
Normal file
134
frontends/stv090x.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
STV0900/0903 Multistandard Broadcast Frontend driver
|
||||
Copyright (C) Manu Abraham <abraham.manu@gmail.com>
|
||||
|
||||
Copyright (C) ST Microelectronics
|
||||
|
||||
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; either version 2 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 General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __STV090x_H
|
||||
#define __STV090x_H
|
||||
|
||||
enum stv090x_demodulator {
|
||||
STV090x_DEMODULATOR_0 = 1,
|
||||
STV090x_DEMODULATOR_1
|
||||
};
|
||||
|
||||
enum stv090x_device {
|
||||
STV0903 = 0,
|
||||
STV0900,
|
||||
};
|
||||
|
||||
enum stv090x_mode {
|
||||
STV090x_DUAL = 0,
|
||||
STV090x_SINGLE
|
||||
};
|
||||
|
||||
enum stv090x_tsmode {
|
||||
STV090x_TSMODE_SERIAL_PUNCTURED = 1,
|
||||
STV090x_TSMODE_SERIAL_CONTINUOUS,
|
||||
STV090x_TSMODE_PARALLEL_PUNCTURED,
|
||||
STV090x_TSMODE_DVBCI
|
||||
};
|
||||
|
||||
enum stv090x_clkmode {
|
||||
STV090x_CLK_INT = 0, /* Clk i/p = CLKI */
|
||||
STV090x_CLK_EXT = 2 /* Clk i/p = XTALI */
|
||||
};
|
||||
|
||||
enum stv090x_i2crpt {
|
||||
STV090x_RPTLEVEL_256 = 0,
|
||||
STV090x_RPTLEVEL_128 = 1,
|
||||
STV090x_RPTLEVEL_64 = 2,
|
||||
STV090x_RPTLEVEL_32 = 3,
|
||||
STV090x_RPTLEVEL_16 = 4,
|
||||
STV090x_RPTLEVEL_8 = 5,
|
||||
STV090x_RPTLEVEL_4 = 6,
|
||||
STV090x_RPTLEVEL_2 = 7,
|
||||
};
|
||||
|
||||
enum stv090x_adc_range {
|
||||
STV090x_ADC_2Vpp = 0,
|
||||
STV090x_ADC_1Vpp = 1
|
||||
};
|
||||
|
||||
struct stv090x_config {
|
||||
enum stv090x_device device;
|
||||
enum stv090x_mode demod_mode;
|
||||
enum stv090x_clkmode clk_mode;
|
||||
|
||||
u32 xtal; /* default: 8000000 */
|
||||
u8 address; /* default: 0x68 */
|
||||
|
||||
u8 ts1_mode;
|
||||
u8 ts2_mode;
|
||||
u32 ts1_clk;
|
||||
u32 ts2_clk;
|
||||
|
||||
u8 ts1_tei : 1;
|
||||
u8 ts2_tei : 1;
|
||||
|
||||
enum stv090x_i2crpt repeater_level;
|
||||
|
||||
u8 tuner_bbgain; /* default: 10db */
|
||||
enum stv090x_adc_range adc1_range; /* default: 2Vpp */
|
||||
enum stv090x_adc_range adc2_range; /* default: 2Vpp */
|
||||
|
||||
bool diseqc_envelope_mode;
|
||||
|
||||
int (*tuner_init) (struct dvb_frontend *fe);
|
||||
int (*tuner_sleep) (struct dvb_frontend *fe);
|
||||
int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
|
||||
int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
|
||||
int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
|
||||
int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
|
||||
int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
|
||||
int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
|
||||
int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
|
||||
int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
|
||||
int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
|
||||
void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock);
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
|
||||
struct i2c_adapter *i2c,
|
||||
enum stv090x_demodulator demod);
|
||||
|
||||
/* dir = 0 -> output, dir = 1 -> input/open-drain */
|
||||
extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
|
||||
u8 dir, u8 value, u8 xor_value);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
|
||||
struct i2c_adapter *i2c,
|
||||
enum stv090x_demodulator demod)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
|
||||
u8 opd, u8 value, u8 xor_value)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_DVB_STV090x */
|
||||
|
||||
#endif /* __STV090x_H */
|
279
frontends/stv090x_priv.h
Normal file
279
frontends/stv090x_priv.h
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
STV0900/0903 Multistandard Broadcast Frontend driver
|
||||
Copyright (C) Manu Abraham <abraham.manu@gmail.com>
|
||||
|
||||
Copyright (C) ST Microelectronics
|
||||
|
||||
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; either version 2 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 General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __STV090x_PRIV_H
|
||||
#define __STV090x_PRIV_H
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
#define FE_ERROR 0
|
||||
#define FE_NOTICE 1
|
||||
#define FE_INFO 2
|
||||
#define FE_DEBUG 3
|
||||
#define FE_DEBUGREG 4
|
||||
|
||||
#define dprintk(__y, __z, format, arg...) do { \
|
||||
if (__z) { \
|
||||
if ((verbose > FE_ERROR) && (verbose > __y)) \
|
||||
printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
|
||||
else if ((verbose > FE_NOTICE) && (verbose > __y)) \
|
||||
printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
|
||||
else if ((verbose > FE_INFO) && (verbose > __y)) \
|
||||
printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
|
||||
else if ((verbose > FE_DEBUG) && (verbose > __y)) \
|
||||
printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
|
||||
} else { \
|
||||
if (verbose > __y) \
|
||||
printk(format, ##arg); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STV090x_READ_DEMOD(__state, __reg) (( \
|
||||
(__state)->demod == STV090x_DEMODULATOR_1) ? \
|
||||
stv090x_read_reg(__state, STV090x_P2_##__reg) : \
|
||||
stv090x_read_reg(__state, STV090x_P1_##__reg))
|
||||
|
||||
#define STV090x_WRITE_DEMOD(__state, __reg, __data) (( \
|
||||
(__state)->demod == STV090x_DEMODULATOR_1) ? \
|
||||
stv090x_write_reg(__state, STV090x_P2_##__reg, __data) :\
|
||||
stv090x_write_reg(__state, STV090x_P1_##__reg, __data))
|
||||
|
||||
#define STV090x_ADDR_OFFST(__state, __x) (( \
|
||||
(__state->demod) == STV090x_DEMODULATOR_1) ? \
|
||||
STV090x_P1_##__x : \
|
||||
STV090x_P2_##__x)
|
||||
|
||||
|
||||
#define STV090x_SETFIELD(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_##bitf) - 1) <<\
|
||||
STV090x_OFFST_##bitf))) | \
|
||||
(val << STV090x_OFFST_##bitf))
|
||||
|
||||
#define STV090x_GETFIELD(val, bitf) ((val >> STV090x_OFFST_##bitf) & ((1 << STV090x_WIDTH_##bitf) - 1))
|
||||
|
||||
|
||||
#define STV090x_SETFIELD_Px(mask, bitf, val) (mask = (mask & (~(((1 << STV090x_WIDTH_Px_##bitf) - 1) <<\
|
||||
STV090x_OFFST_Px_##bitf))) | \
|
||||
(val << STV090x_OFFST_Px_##bitf))
|
||||
|
||||
#define STV090x_GETFIELD_Px(val, bitf) ((val >> STV090x_OFFST_Px_##bitf) & ((1 << STV090x_WIDTH_Px_##bitf) - 1))
|
||||
|
||||
#define MAKEWORD16(__a, __b) (((__a) << 8) | (__b))
|
||||
|
||||
#define MSB(__x) ((__x >> 8) & 0xff)
|
||||
#define LSB(__x) (__x & 0xff)
|
||||
|
||||
|
||||
#define STV090x_IQPOWER_THRESHOLD 30
|
||||
#define STV090x_SEARCH_AGC2_TH_CUT20 700
|
||||
#define STV090x_SEARCH_AGC2_TH_CUT30 1400
|
||||
|
||||
#define STV090x_SEARCH_AGC2_TH(__ver) \
|
||||
((__ver <= 0x20) ? \
|
||||
STV090x_SEARCH_AGC2_TH_CUT20 : \
|
||||
STV090x_SEARCH_AGC2_TH_CUT30)
|
||||
|
||||
enum stv090x_signal_state {
|
||||
STV090x_NOAGC1,
|
||||
STV090x_NOCARRIER,
|
||||
STV090x_NODATA,
|
||||
STV090x_DATAOK,
|
||||
STV090x_RANGEOK,
|
||||
STV090x_OUTOFRANGE
|
||||
};
|
||||
|
||||
enum stv090x_fec {
|
||||
STV090x_PR12 = 0,
|
||||
STV090x_PR23,
|
||||
STV090x_PR34,
|
||||
STV090x_PR45,
|
||||
STV090x_PR56,
|
||||
STV090x_PR67,
|
||||
STV090x_PR78,
|
||||
STV090x_PR89,
|
||||
STV090x_PR910,
|
||||
STV090x_PRERR
|
||||
};
|
||||
|
||||
enum stv090x_modulation {
|
||||
STV090x_QPSK,
|
||||
STV090x_8PSK,
|
||||
STV090x_16APSK,
|
||||
STV090x_32APSK,
|
||||
STV090x_UNKNOWN
|
||||
};
|
||||
|
||||
enum stv090x_frame {
|
||||
STV090x_LONG_FRAME,
|
||||
STV090x_SHORT_FRAME
|
||||
};
|
||||
|
||||
enum stv090x_pilot {
|
||||
STV090x_PILOTS_OFF,
|
||||
STV090x_PILOTS_ON
|
||||
};
|
||||
|
||||
enum stv090x_rolloff {
|
||||
STV090x_RO_35,
|
||||
STV090x_RO_25,
|
||||
STV090x_RO_20
|
||||
};
|
||||
|
||||
enum stv090x_inversion {
|
||||
STV090x_IQ_AUTO,
|
||||
STV090x_IQ_NORMAL,
|
||||
STV090x_IQ_SWAP
|
||||
};
|
||||
|
||||
enum stv090x_modcod {
|
||||
STV090x_DUMMY_PLF = 0,
|
||||
STV090x_QPSK_14,
|
||||
STV090x_QPSK_13,
|
||||
STV090x_QPSK_25,
|
||||
STV090x_QPSK_12,
|
||||
STV090x_QPSK_35,
|
||||
STV090x_QPSK_23,
|
||||
STV090x_QPSK_34,
|
||||
STV090x_QPSK_45,
|
||||
STV090x_QPSK_56,
|
||||
STV090x_QPSK_89,
|
||||
STV090x_QPSK_910,
|
||||
STV090x_8PSK_35,
|
||||
STV090x_8PSK_23,
|
||||
STV090x_8PSK_34,
|
||||
STV090x_8PSK_56,
|
||||
STV090x_8PSK_89,
|
||||
STV090x_8PSK_910,
|
||||
STV090x_16APSK_23,
|
||||
STV090x_16APSK_34,
|
||||
STV090x_16APSK_45,
|
||||
STV090x_16APSK_56,
|
||||
STV090x_16APSK_89,
|
||||
STV090x_16APSK_910,
|
||||
STV090x_32APSK_34,
|
||||
STV090x_32APSK_45,
|
||||
STV090x_32APSK_56,
|
||||
STV090x_32APSK_89,
|
||||
STV090x_32APSK_910,
|
||||
STV090x_MODCODE_UNKNOWN
|
||||
};
|
||||
|
||||
enum stv090x_search {
|
||||
STV090x_SEARCH_DSS = 0,
|
||||
STV090x_SEARCH_DVBS1,
|
||||
STV090x_SEARCH_DVBS2,
|
||||
STV090x_SEARCH_AUTO
|
||||
};
|
||||
|
||||
enum stv090x_algo {
|
||||
STV090x_BLIND_SEARCH,
|
||||
STV090x_COLD_SEARCH,
|
||||
STV090x_WARM_SEARCH
|
||||
};
|
||||
|
||||
enum stv090x_delsys {
|
||||
STV090x_ERROR = 0,
|
||||
STV090x_DVBS1 = 1,
|
||||
STV090x_DVBS2,
|
||||
STV090x_DSS
|
||||
};
|
||||
|
||||
struct stv090x_long_frame_crloop {
|
||||
enum stv090x_modcod modcod;
|
||||
|
||||
u8 crl_pilots_on_2;
|
||||
u8 crl_pilots_off_2;
|
||||
u8 crl_pilots_on_5;
|
||||
u8 crl_pilots_off_5;
|
||||
u8 crl_pilots_on_10;
|
||||
u8 crl_pilots_off_10;
|
||||
u8 crl_pilots_on_20;
|
||||
u8 crl_pilots_off_20;
|
||||
u8 crl_pilots_on_30;
|
||||
u8 crl_pilots_off_30;
|
||||
};
|
||||
|
||||
struct stv090x_short_frame_crloop {
|
||||
enum stv090x_modulation modulation;
|
||||
|
||||
u8 crl_2; /* SR < 3M */
|
||||
u8 crl_5; /* 3 < SR <= 7M */
|
||||
u8 crl_10; /* 7 < SR <= 15M */
|
||||
u8 crl_20; /* 10 < SR <= 25M */
|
||||
u8 crl_30; /* 10 < SR <= 45M */
|
||||
};
|
||||
|
||||
struct stv090x_reg {
|
||||
u16 addr;
|
||||
u8 data;
|
||||
};
|
||||
|
||||
struct stv090x_tab {
|
||||
s32 real;
|
||||
s32 read;
|
||||
};
|
||||
|
||||
struct stv090x_internal {
|
||||
struct i2c_adapter *i2c_adap;
|
||||
u8 i2c_addr;
|
||||
|
||||
struct mutex demod_lock; /* Lock access to shared register */
|
||||
struct mutex tuner_lock; /* Lock access to tuners */
|
||||
s32 mclk; /* Masterclock Divider factor */
|
||||
u32 dev_ver;
|
||||
|
||||
int num_used;
|
||||
};
|
||||
|
||||
struct stv090x_state {
|
||||
enum stv090x_device device;
|
||||
enum stv090x_demodulator demod;
|
||||
enum stv090x_mode demod_mode;
|
||||
struct stv090x_internal *internal;
|
||||
|
||||
struct i2c_adapter *i2c;
|
||||
const struct stv090x_config *config;
|
||||
struct dvb_frontend frontend;
|
||||
|
||||
u32 *verbose; /* Cached module verbosity */
|
||||
|
||||
enum stv090x_delsys delsys;
|
||||
enum stv090x_fec fec;
|
||||
enum stv090x_modulation modulation;
|
||||
enum stv090x_modcod modcod;
|
||||
enum stv090x_search search_mode;
|
||||
enum stv090x_frame frame_len;
|
||||
enum stv090x_pilot pilots;
|
||||
enum stv090x_rolloff rolloff;
|
||||
enum stv090x_inversion inversion;
|
||||
enum stv090x_algo algo;
|
||||
|
||||
u32 frequency;
|
||||
u32 srate;
|
||||
|
||||
s32 tuner_bw;
|
||||
|
||||
s32 search_range;
|
||||
|
||||
s32 DemodTimeout;
|
||||
s32 FecTimeout;
|
||||
};
|
||||
|
||||
#endif /* __STV090x_PRIV_H */
|
2371
frontends/stv090x_reg.h
Normal file
2371
frontends/stv090x_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
1406
frontends/stv0910.c
Normal file
1406
frontends/stv0910.c
Normal file
File diff suppressed because it is too large
Load Diff
31
frontends/stv0910.h
Normal file
31
frontends/stv0910.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef _STV0910_H_
|
||||
#define _STV0910_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
struct stv0910_cfg {
|
||||
u32 clk;
|
||||
u8 adr;
|
||||
u8 parallel;
|
||||
u8 rptlvl;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_STV0910) || \
|
||||
(defined(CONFIG_DVB_STV0910_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c,
|
||||
struct stv0910_cfg *cfg, int nr);
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c,
|
||||
struct stv0910_cfg *cfg,
|
||||
int nr)
|
||||
{
|
||||
pr_warn("%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
3998
frontends/stv0910_regs.h
Normal file
3998
frontends/stv0910_regs.h
Normal file
File diff suppressed because it is too large
Load Diff
405
frontends/stv6110x.c
Normal file
405
frontends/stv6110x.c
Normal file
@ -0,0 +1,405 @@
|
||||
/*
|
||||
STV6110(A) Silicon tuner driver
|
||||
|
||||
Copyright (C) Manu Abraham <abraham.manu@gmail.com>
|
||||
|
||||
Copyright (C) ST Microelectronics
|
||||
|
||||
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; either version 2 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 General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
#include "stv6110x_reg.h"
|
||||
#include "stv6110x.h"
|
||||
#include "stv6110x_priv.h"
|
||||
|
||||
static unsigned int verbose;
|
||||
module_param(verbose, int, 0644);
|
||||
MODULE_PARM_DESC(verbose, "Set Verbosity level");
|
||||
|
||||
static int stv6110x_read_reg(struct stv6110x_state *stv6110x, u8 reg, u8 *data)
|
||||
{
|
||||
int ret;
|
||||
const struct stv6110x_config *config = stv6110x->config;
|
||||
u8 b0[] = { reg };
|
||||
u8 b1[] = { 0 };
|
||||
struct i2c_msg msg[] = {
|
||||
{ .addr = config->addr, .flags = 0, .buf = b0, .len = 1 },
|
||||
{ .addr = config->addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }
|
||||
};
|
||||
|
||||
ret = i2c_transfer(stv6110x->i2c, msg, 2);
|
||||
if (ret != 2) {
|
||||
dprintk(FE_ERROR, 1, "I/O Error");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
*data = b1[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_write_regs(struct stv6110x_state *stv6110x, int start, u8 data[], int len)
|
||||
{
|
||||
int ret;
|
||||
const struct stv6110x_config *config = stv6110x->config;
|
||||
u8 buf[len + 1];
|
||||
struct i2c_msg msg = {
|
||||
.addr = config->addr,
|
||||
.flags = 0,
|
||||
.buf = buf,
|
||||
.len = len + 1
|
||||
};
|
||||
|
||||
if (start + len > 8)
|
||||
return -EINVAL;
|
||||
|
||||
buf[0] = start;
|
||||
memcpy(&buf[1], data, len);
|
||||
|
||||
ret = i2c_transfer(stv6110x->i2c, &msg, 1);
|
||||
if (ret != 1) {
|
||||
dprintk(FE_ERROR, 1, "I/O Error");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_write_reg(struct stv6110x_state *stv6110x, u8 reg, u8 data)
|
||||
{
|
||||
return stv6110x_write_regs(stv6110x, reg, &data, 1);
|
||||
}
|
||||
|
||||
static int stv6110x_init(struct dvb_frontend *fe)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
int ret;
|
||||
|
||||
ret = stv6110x_write_regs(stv6110x, 0, stv6110x->regs,
|
||||
ARRAY_SIZE(stv6110x->regs));
|
||||
if (ret < 0) {
|
||||
dprintk(FE_ERROR, 1, "Initialization failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_set_frequency(struct dvb_frontend *fe, u32 frequency)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
u32 rDiv, divider;
|
||||
s32 pVal, pCalc, rDivOpt = 0, pCalcOpt = 1000;
|
||||
u8 i;
|
||||
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_K, (REFCLOCK_MHz - 16));
|
||||
|
||||
if (frequency <= 1023000) {
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
|
||||
pVal = 40;
|
||||
} else if (frequency <= 1300000) {
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 1);
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
|
||||
pVal = 40;
|
||||
} else if (frequency <= 2046000) {
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 0);
|
||||
pVal = 20;
|
||||
} else {
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_DIV4SEL, 0);
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_PRESC32_ON, 1);
|
||||
pVal = 20;
|
||||
}
|
||||
|
||||
for (rDiv = 0; rDiv <= 3; rDiv++) {
|
||||
pCalc = (REFCLOCK_kHz / 100) / R_DIV(rDiv);
|
||||
|
||||
if ((abs((s32)(pCalc - pVal))) < (abs((s32)(pCalcOpt - pVal))))
|
||||
rDivOpt = rDiv;
|
||||
|
||||
pCalcOpt = (REFCLOCK_kHz / 100) / R_DIV(rDivOpt);
|
||||
}
|
||||
|
||||
divider = (frequency * R_DIV(rDivOpt) * pVal) / REFCLOCK_kHz;
|
||||
divider = (divider + 5) / 10;
|
||||
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_R_DIV, rDivOpt);
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG1], TNG1_N_DIV_11_8, MSB(divider));
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_TNG0], TNG0_N_DIV_7_0, LSB(divider));
|
||||
|
||||
/* VCO Auto calibration */
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALVCO_STRT, 1);
|
||||
|
||||
stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
|
||||
stv6110x_write_reg(stv6110x, STV6110x_TNG1, stv6110x->regs[STV6110x_TNG1]);
|
||||
stv6110x_write_reg(stv6110x, STV6110x_TNG0, stv6110x->regs[STV6110x_TNG0]);
|
||||
stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
|
||||
|
||||
for (i = 0; i < TRIALS; i++) {
|
||||
stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
|
||||
if (!STV6110x_GETFIELD(STAT1_CALVCO_STRT, stv6110x->regs[STV6110x_STAT1]))
|
||||
break;
|
||||
msleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
|
||||
stv6110x_read_reg(stv6110x, STV6110x_TNG1, &stv6110x->regs[STV6110x_TNG1]);
|
||||
stv6110x_read_reg(stv6110x, STV6110x_TNG0, &stv6110x->regs[STV6110x_TNG0]);
|
||||
|
||||
*frequency = (MAKEWORD16(STV6110x_GETFIELD(TNG1_N_DIV_11_8, stv6110x->regs[STV6110x_TNG1]),
|
||||
STV6110x_GETFIELD(TNG0_N_DIV_7_0, stv6110x->regs[STV6110x_TNG0]))) * REFCLOCK_kHz;
|
||||
|
||||
*frequency /= (1 << (STV6110x_GETFIELD(TNG1_R_DIV, stv6110x->regs[STV6110x_TNG1]) +
|
||||
STV6110x_GETFIELD(TNG1_DIV4SEL, stv6110x->regs[STV6110x_TNG1])));
|
||||
|
||||
*frequency >>= 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
u32 halfbw;
|
||||
u8 i;
|
||||
|
||||
halfbw = bandwidth >> 1;
|
||||
|
||||
if (halfbw > 36000000)
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 31); /* LPF */
|
||||
else if (halfbw < 5000000)
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, 0); /* LPF */
|
||||
else
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_CF, ((halfbw / 1000000) - 5)); /* LPF */
|
||||
|
||||
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x0); /* cal. clk activated */
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_STAT1], STAT1_CALRC_STRT, 0x1); /* LPF auto cal */
|
||||
|
||||
stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
|
||||
stv6110x_write_reg(stv6110x, STV6110x_STAT1, stv6110x->regs[STV6110x_STAT1]);
|
||||
|
||||
for (i = 0; i < TRIALS; i++) {
|
||||
stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
|
||||
if (!STV6110x_GETFIELD(STAT1_CALRC_STRT, stv6110x->regs[STV6110x_STAT1]))
|
||||
break;
|
||||
msleep(1);
|
||||
}
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL3], CTRL3_RCCLK_OFF, 0x1); /* cal. done */
|
||||
stv6110x_write_reg(stv6110x, STV6110x_CTRL3, stv6110x->regs[STV6110x_CTRL3]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
|
||||
stv6110x_read_reg(stv6110x, STV6110x_CTRL3, &stv6110x->regs[STV6110x_CTRL3]);
|
||||
*bandwidth = (STV6110x_GETFIELD(CTRL3_CF, stv6110x->regs[STV6110x_CTRL3]) + 5) * 2000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_set_refclock(struct dvb_frontend *fe, u32 refclock)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
|
||||
/* setup divider */
|
||||
switch (refclock) {
|
||||
default:
|
||||
case 1:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
|
||||
break;
|
||||
case 2:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
|
||||
break;
|
||||
case 4:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
|
||||
break;
|
||||
case 8:
|
||||
case 0:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
|
||||
break;
|
||||
}
|
||||
stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_get_bbgain(struct dvb_frontend *fe, u32 *gain)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
|
||||
stv6110x_read_reg(stv6110x, STV6110x_CTRL2, &stv6110x->regs[STV6110x_CTRL2]);
|
||||
*gain = 2 * STV6110x_GETFIELD(CTRL2_BBGAIN, stv6110x->regs[STV6110x_CTRL2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_set_bbgain(struct dvb_frontend *fe, u32 gain)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_BBGAIN, gain / 2);
|
||||
stv6110x_write_reg(stv6110x, STV6110x_CTRL2, stv6110x->regs[STV6110x_CTRL2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_set_mode(struct dvb_frontend *fe, enum tuner_mode mode)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
int ret;
|
||||
|
||||
switch (mode) {
|
||||
case TUNER_SLEEP:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 0);
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 0);
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 0);
|
||||
break;
|
||||
|
||||
case TUNER_WAKE:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_SYN, 1);
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_RX, 1);
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL1], CTRL1_LPT, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = stv6110x_write_reg(stv6110x, STV6110x_CTRL1, stv6110x->regs[STV6110x_CTRL1]);
|
||||
if (ret < 0) {
|
||||
dprintk(FE_ERROR, 1, "I/O Error");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_sleep(struct dvb_frontend *fe)
|
||||
{
|
||||
if (fe->tuner_priv)
|
||||
return stv6110x_set_mode(fe, TUNER_SLEEP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stv6110x_get_status(struct dvb_frontend *fe, u32 *status)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
|
||||
stv6110x_read_reg(stv6110x, STV6110x_STAT1, &stv6110x->regs[STV6110x_STAT1]);
|
||||
|
||||
if (STV6110x_GETFIELD(STAT1_LOCK, stv6110x->regs[STV6110x_STAT1]))
|
||||
*status = TUNER_PHASELOCKED;
|
||||
else
|
||||
*status = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int stv6110x_release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct stv6110x_state *stv6110x = fe->tuner_priv;
|
||||
|
||||
fe->tuner_priv = NULL;
|
||||
kfree(stv6110x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_tuner_ops stv6110x_ops = {
|
||||
.info = {
|
||||
.name = "STV6110(A) Silicon Tuner",
|
||||
.frequency_min = 950000,
|
||||
.frequency_max = 2150000,
|
||||
.frequency_step = 0,
|
||||
},
|
||||
.release = stv6110x_release
|
||||
};
|
||||
|
||||
static struct stv6110x_devctl stv6110x_ctl = {
|
||||
.tuner_init = stv6110x_init,
|
||||
.tuner_sleep = stv6110x_sleep,
|
||||
.tuner_set_mode = stv6110x_set_mode,
|
||||
.tuner_set_frequency = stv6110x_set_frequency,
|
||||
.tuner_get_frequency = stv6110x_get_frequency,
|
||||
.tuner_set_bandwidth = stv6110x_set_bandwidth,
|
||||
.tuner_get_bandwidth = stv6110x_get_bandwidth,
|
||||
.tuner_set_bbgain = stv6110x_set_bbgain,
|
||||
.tuner_get_bbgain = stv6110x_get_bbgain,
|
||||
.tuner_set_refclk = stv6110x_set_refclock,
|
||||
.tuner_get_status = stv6110x_get_status,
|
||||
};
|
||||
|
||||
struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
|
||||
const struct stv6110x_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct stv6110x_state *stv6110x;
|
||||
u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e};
|
||||
|
||||
stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL);
|
||||
if (!stv6110x)
|
||||
return NULL;
|
||||
|
||||
stv6110x->i2c = i2c;
|
||||
stv6110x->config = config;
|
||||
stv6110x->devctl = &stv6110x_ctl;
|
||||
memcpy(stv6110x->regs, default_regs, 8);
|
||||
|
||||
/* setup divider */
|
||||
switch (stv6110x->config->clk_div) {
|
||||
default:
|
||||
case 1:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0);
|
||||
break;
|
||||
case 2:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1);
|
||||
break;
|
||||
case 4:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2);
|
||||
break;
|
||||
case 8:
|
||||
case 0:
|
||||
STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3);
|
||||
break;
|
||||
}
|
||||
|
||||
fe->tuner_priv = stv6110x;
|
||||
fe->ops.tuner_ops = stv6110x_ops;
|
||||
|
||||
printk(KERN_INFO "%s: Attaching STV6110x\n", __func__);
|
||||
return stv6110x->devctl;
|
||||
}
|
||||
EXPORT_SYMBOL(stv6110x_attach);
|
||||
|
||||
MODULE_AUTHOR("Manu Abraham");
|
||||
MODULE_DESCRIPTION("STV6110x Silicon tuner");
|
||||
MODULE_LICENSE("GPL");
|
73
frontends/stv6110x.h
Normal file
73
frontends/stv6110x.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
STV6110(A) Silicon tuner driver
|
||||
|
||||
Copyright (C) Manu Abraham <abraham.manu@gmail.com>
|
||||
|
||||
Copyright (C) ST Microelectronics
|
||||
|
||||
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; either version 2 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 General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __STV6110x_H
|
||||
#define __STV6110x_H
|
||||
|
||||
struct stv6110x_config {
|
||||
u8 addr;
|
||||
u32 refclk;
|
||||
u8 clk_div; /* divisor value for the output clock */
|
||||
};
|
||||
|
||||
enum tuner_mode {
|
||||
TUNER_SLEEP = 1,
|
||||
TUNER_WAKE,
|
||||
};
|
||||
|
||||
enum tuner_status {
|
||||
TUNER_PHASELOCKED = 1,
|
||||
};
|
||||
|
||||
struct stv6110x_devctl {
|
||||
int (*tuner_init) (struct dvb_frontend *fe);
|
||||
int (*tuner_sleep) (struct dvb_frontend *fe);
|
||||
int (*tuner_set_mode) (struct dvb_frontend *fe, enum tuner_mode mode);
|
||||
int (*tuner_set_frequency) (struct dvb_frontend *fe, u32 frequency);
|
||||
int (*tuner_get_frequency) (struct dvb_frontend *fe, u32 *frequency);
|
||||
int (*tuner_set_bandwidth) (struct dvb_frontend *fe, u32 bandwidth);
|
||||
int (*tuner_get_bandwidth) (struct dvb_frontend *fe, u32 *bandwidth);
|
||||
int (*tuner_set_bbgain) (struct dvb_frontend *fe, u32 gain);
|
||||
int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
|
||||
int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
|
||||
int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
|
||||
};
|
||||
|
||||
|
||||
#if defined(CONFIG_DVB_STV6110x) || (defined(CONFIG_DVB_STV6110x_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
|
||||
const struct stv6110x_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
|
||||
#else
|
||||
static inline struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe,
|
||||
const struct stv6110x_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DVB_STV6110x */
|
||||
|
||||
#endif /* __STV6110x_H */
|
76
frontends/stv6110x_priv.h
Normal file
76
frontends/stv6110x_priv.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
STV6110(A) Silicon tuner driver
|
||||
|
||||
Copyright (C) Manu Abraham <abraham.manu@gmail.com>
|
||||
|
||||
Copyright (C) ST Microelectronics
|
||||
|
||||
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; either version 2 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 General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __STV6110x_PRIV_H
|
||||
#define __STV6110x_PRIV_H
|
||||
|
||||
#define FE_ERROR 0
|
||||
#define FE_NOTICE 1
|
||||
#define FE_INFO 2
|
||||
#define FE_DEBUG 3
|
||||
#define FE_DEBUGREG 4
|
||||
|
||||
#define dprintk(__y, __z, format, arg...) do { \
|
||||
if (__z) { \
|
||||
if ((verbose > FE_ERROR) && (verbose > __y)) \
|
||||
printk(KERN_ERR "%s: " format "\n", __func__ , ##arg); \
|
||||
else if ((verbose > FE_NOTICE) && (verbose > __y)) \
|
||||
printk(KERN_NOTICE "%s: " format "\n", __func__ , ##arg); \
|
||||
else if ((verbose > FE_INFO) && (verbose > __y)) \
|
||||
printk(KERN_INFO "%s: " format "\n", __func__ , ##arg); \
|
||||
else if ((verbose > FE_DEBUG) && (verbose > __y)) \
|
||||
printk(KERN_DEBUG "%s: " format "\n", __func__ , ##arg); \
|
||||
} else { \
|
||||
if (verbose > __y) \
|
||||
printk(format, ##arg); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define STV6110x_SETFIELD(mask, bitf, val) \
|
||||
(mask = (mask & (~(((1 << STV6110x_WIDTH_##bitf) - 1) << \
|
||||
STV6110x_OFFST_##bitf))) | \
|
||||
(val << STV6110x_OFFST_##bitf))
|
||||
|
||||
#define STV6110x_GETFIELD(bitf, val) \
|
||||
((val >> STV6110x_OFFST_##bitf) & \
|
||||
((1 << STV6110x_WIDTH_##bitf) - 1))
|
||||
|
||||
#define MAKEWORD16(a, b) (((a) << 8) | (b))
|
||||
|
||||
#define LSB(x) ((x & 0xff))
|
||||
#define MSB(y) ((y >> 8) & 0xff)
|
||||
|
||||
#define TRIALS 10
|
||||
#define R_DIV(__div) (1 << (__div + 1))
|
||||
#define REFCLOCK_kHz (stv6110x->config->refclk / 1000)
|
||||
#define REFCLOCK_MHz (stv6110x->config->refclk / 1000000)
|
||||
|
||||
struct stv6110x_state {
|
||||
struct i2c_adapter *i2c;
|
||||
const struct stv6110x_config *config;
|
||||
u8 regs[8];
|
||||
|
||||
struct stv6110x_devctl *devctl;
|
||||
};
|
||||
|
||||
#endif /* __STV6110x_PRIV_H */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user