mirror of
https://github.com/DigitalDevices/dddvb.git
synced 2023-10-10 13:37:43 +02:00
git push
Merge branch 'internal'
This commit is contained in:
commit
7d8a151127
@ -1,10 +1,11 @@
|
||||
all: ddtest octonet octokey ddflash
|
||||
all: ddtest octonet octokey ddflash ddupdate
|
||||
|
||||
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
|
||||
install -m 0755 ddupdate $(DESTDIR)/usr/bin
|
||||
|
||||
ddflash: ddflash.c flash.h flash.c
|
||||
$(CC) -o ddflash ddflash.c
|
||||
@ -12,6 +13,9 @@ ddflash: ddflash.c flash.h flash.c
|
||||
ddtest: ddtest.c flash.h flash.c
|
||||
$(CC) -o ddtest ddtest.c
|
||||
|
||||
ddupdate: ddupdate.c flash.h flash.c
|
||||
$(CC) -o ddupdate ddupdate.c
|
||||
|
||||
octonet: octonet.c
|
||||
$(CC) -o octonet octonet.c
|
||||
|
||||
|
@ -38,25 +38,6 @@
|
||||
#include "flash.h"
|
||||
#include "flash.c"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static int update_flash(struct ddflash *ddf)
|
||||
{
|
||||
char *fname;
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
|
||||
#include "flash.h"
|
||||
#include "flash.c"
|
||||
|
||||
@ -115,11 +114,11 @@ static int update_flash(struct ddflash *ddf)
|
||||
if (!fname)
|
||||
fname = default_fname;
|
||||
if (name)
|
||||
printf("Card: %s\n", name);
|
||||
printf("Card: %s\n", name);
|
||||
if (ddf->flash_name)
|
||||
printf("Flash: %s\n", ddf->flash_name);
|
||||
printf("Version:%08x\n", ddf->id.hw);
|
||||
//printf("REGMAPa: %08x\n", ddf->id.regmap);
|
||||
printf("Flash: %s\n", ddf->flash_name);
|
||||
printf("Version: %08x\n", ddf->id.hw);
|
||||
printf("REGMAP : %08x\n", ddf->id.regmap);
|
||||
if ((res = update_image(ddf, fname, 0x10000, 0x100000, 1, 0)) == 1)
|
||||
stat |= 1;
|
||||
return stat;
|
||||
@ -142,7 +141,7 @@ static int update_link(struct ddflash *ddf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int update_card(int ddbnum, char *fname)
|
||||
static int update_card(int ddbnum, char *fname, int force)
|
||||
{
|
||||
struct ddflash ddf;
|
||||
char ddbname[80];
|
||||
@ -156,6 +155,7 @@ static int update_card(int ddbnum, char *fname)
|
||||
ddf.fd = ddb;
|
||||
ddf.link = 0;
|
||||
ddf.fname = fname;
|
||||
ddf.force = force;
|
||||
links = 1;
|
||||
|
||||
for (link = 0; link < links; link++) {
|
||||
@ -206,18 +206,20 @@ static int usage()
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ddbnum = -1, all = 0, i, force = 0;
|
||||
int ddbnum = -1, all = 0, i, force = 0, reboot_len = -1;
|
||||
char *fname = 0;
|
||||
int ret;
|
||||
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
int c;
|
||||
static struct option long_options[] = {
|
||||
{"reboot", optional_argument , NULL, 'r'},
|
||||
{"help", no_argument , NULL, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
c = getopt_long(argc, argv,
|
||||
"n:havfb:",
|
||||
"n:havfb:r::",
|
||||
long_options, &option_index);
|
||||
if (c==-1)
|
||||
break;
|
||||
@ -232,9 +234,20 @@ int main(int argc, char **argv)
|
||||
case 'a':
|
||||
all = 1;
|
||||
break;
|
||||
case 'f':
|
||||
force = 1;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
case 'r':
|
||||
if (optarg)
|
||||
reboot_len = strtol(optarg, NULL, 0);
|
||||
else
|
||||
reboot_len = 40;
|
||||
if (!reboot_len)
|
||||
reboot(40);
|
||||
break;
|
||||
case 'h':
|
||||
usage();
|
||||
break;
|
||||
@ -253,17 +266,19 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (!all)
|
||||
return update_card(ddbnum, fname);
|
||||
ret = update_card(ddbnum, fname, force);
|
||||
else
|
||||
for (i = 0; i < 100; i++) {
|
||||
ret = update_card(i, 0, 0);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
int ret = update_card(i, 0);
|
||||
|
||||
if (ret == -3) /* could not open, no more cards! */
|
||||
break;
|
||||
if (ret < 0)
|
||||
return i; /* fatal error */
|
||||
if (verbose >= 1)
|
||||
printf("card %d up to date\n", i);
|
||||
}
|
||||
if (ret == -3) /* could not open, no more cards! */
|
||||
break;
|
||||
if (ret < 0)
|
||||
return i; /* fatal error */
|
||||
if (verbose >= 1)
|
||||
printf("card %d up to date\n", i);
|
||||
}
|
||||
if (reboot_len > 0)
|
||||
reboot(reboot_len);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,7 +1,28 @@
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uint32_t linknr = 0;
|
||||
|
||||
int flashio(int ddb, int link,
|
||||
uint8_t *wbuf, uint32_t wlen, uint8_t *rbuf, uint32_t rlen)
|
||||
uint8_t *wbuf, uint32_t wlen,
|
||||
uint8_t *rbuf, uint32_t rlen)
|
||||
{
|
||||
struct ddb_flashio fio = {
|
||||
.write_buf=wbuf,
|
||||
@ -118,7 +139,7 @@ int flashread(int ddb, int link, uint8_t *buf, uint32_t addr, uint32_t len)
|
||||
uint32_t l;
|
||||
|
||||
while (len) {
|
||||
cmd[0] = 3;
|
||||
cmd[0] = 0x03;
|
||||
cmd[1] = (addr >> 16) & 0xff;
|
||||
cmd[2] = (addr >> 8) & 0xff;
|
||||
cmd[3] = addr & 0xff;
|
||||
@ -137,12 +158,12 @@ int flashread(int ddb, int link, uint8_t *buf, uint32_t addr, uint32_t len)
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int flashread(int ddb, uint8_t *buf, uint32_t addr, uint32_t len)
|
||||
static int flashread(int ddb, int link, uint8_t *buf, uint32_t addr, uint32_t len)
|
||||
{
|
||||
uint8_t cmd[4]= {0x03, (addr >> 16) & 0xff,
|
||||
(addr >> 8) & 0xff, addr & 0xff};
|
||||
uint8_t cmd[5]= {0x0b, (addr >> 16) & 0xff,
|
||||
(addr >> 8) & 0xff, addr & 0xff, 0x00};
|
||||
|
||||
return flashio(ddb, linknr, cmd, 4, buf, len);
|
||||
return flashio(ddb, link, cmd, 5, buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -500,10 +521,10 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset,
|
||||
uint8_t Cmd[260];
|
||||
int i, j;
|
||||
|
||||
if( (BufferSize % 4096) != 0 ) return -1; // Must be multiple of sector size
|
||||
if ((BufferSize % 4096))
|
||||
return -1; // Must be multiple of sector size
|
||||
|
||||
do
|
||||
{
|
||||
do {
|
||||
Cmd[0] = 0x50; // EWSR
|
||||
err = flashio(dev,linknr, Cmd,1,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
@ -513,8 +534,7 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset,
|
||||
err = flashio(dev,linknr, Cmd,2,NULL,0);
|
||||
if( err < 0 ) break;
|
||||
|
||||
for(i = 0; i < BufferSize; i += 4096 )
|
||||
{
|
||||
for(i = 0; i < BufferSize; i += 4096 ) {
|
||||
if( (i & 0xFFFF) == 0 )
|
||||
{
|
||||
printf(" Erase %08x\n",FlashOffset + i);
|
||||
@ -588,124 +608,117 @@ int FlashWritePageMode(int dev, uint32_t FlashOffset,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int flash_wait(int fd, uint32_t link)
|
||||
{
|
||||
while (1) {
|
||||
uint8_t rcmd = 0x05; // RDSR
|
||||
int err = flashio(fd, link, &rcmd, 1, &rcmd, 1);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
if ((rcmd & 0x01) == 0)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int flashwrite_pagemode(struct ddflash *ddf, int dev, uint32_t FlashOffset,
|
||||
uint8_t LockBits, uint32_t fw_off)
|
||||
uint8_t LockBits, uint32_t fw_off, int be)
|
||||
{
|
||||
int err = 0;
|
||||
uint8_t cmd[260];
|
||||
int i, j;
|
||||
uint32_t flen, blen;
|
||||
int blockerase = be && ((FlashOffset & 0xFFFF) == 0 ) && (flen >= 0x10000);
|
||||
|
||||
blen = flen = lseek(dev, 0, SEEK_END) - fw_off;
|
||||
if (blen % 0xff)
|
||||
blen = (blen + 0xff) & 0xffffff00;
|
||||
printf("blen = %u, flen = %u\n", blen, flen);
|
||||
//printf("blen = %u, flen = %u\n", blen, flen);
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
do {
|
||||
cmd[0] = 0x50; // EWSR
|
||||
cmd[0] = 0x50; // EWSR
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = 0x00; // BPx = 0, Unlock all blocks
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 2, NULL, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
for (i = 0; i < flen; ) {
|
||||
printf(" Erase %08x\r", FlashOffset + i);
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = 0x00; // BPx = 0, Unlock all blocks
|
||||
err = flashio(ddf->fd, ddf->link, 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, ddf->link, cmd, 1, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
return err;
|
||||
cmd[1] = ( (( FlashOffset + i ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + i ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
if (blockerase && ((flen - i) >= 0x10000) ) {
|
||||
cmd[0] = 0xd8;
|
||||
i += 0x10000;
|
||||
} else {
|
||||
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, ddf->link, cmd, 4, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
while (1) {
|
||||
cmd[0] = 0x05; // RDSR
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 1, &cmd[0], 1);
|
||||
if (err < 0)
|
||||
break;
|
||||
if ((cmd[0] & 0x01) == 0)
|
||||
break;
|
||||
}
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
i += 0x1000;
|
||||
}
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 4, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
for (j = blen - 256; j >= 0; j -= 256 ) {
|
||||
uint32_t len = 256;
|
||||
ssize_t rlen;
|
||||
|
||||
if (lseek(dev, j + fw_off, SEEK_SET) < 0) {
|
||||
printf("seek error\n");
|
||||
return -1;
|
||||
}
|
||||
if (flen - j < 256) {
|
||||
len = flen - j;
|
||||
memset(ddf->buffer, 0xff, 256);
|
||||
}
|
||||
rlen = read(dev, 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);
|
||||
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(ddf->fd, ddf->link, 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], ddf->buffer, 256);
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 260, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
|
||||
while(1) {
|
||||
cmd[0] = 0x05; // RDRS
|
||||
err = flashio(ddf->fd, ddf->link, cmd,1, &cmd[0], 1);
|
||||
if (err < 0)
|
||||
break;
|
||||
if ((cmd[0] & 0x01) == 0)
|
||||
break;
|
||||
}
|
||||
if (err < 0)
|
||||
break;
|
||||
return err;
|
||||
err = flash_wait(ddf->fd, ddf->link);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
for (j = blen - 256; j >= 0; j -= 256 ) {
|
||||
uint32_t len = 256;
|
||||
ssize_t rlen;
|
||||
|
||||
if (lseek(dev, j + fw_off, SEEK_SET) < 0) {
|
||||
printf("seek error\n");
|
||||
return -1;
|
||||
}
|
||||
if (err < 0)
|
||||
break;
|
||||
if (flen - j < 256) {
|
||||
len = flen - j;
|
||||
memset(ddf->buffer, 0xff, 256);
|
||||
}
|
||||
rlen = read(dev, ddf->buffer, len);
|
||||
if (rlen < 0 || rlen != len) {
|
||||
printf("file read error %d,%d at %u\n", rlen, errno, j);
|
||||
return -1;
|
||||
}
|
||||
printf(" Program %08x\r", FlashOffset + j);
|
||||
|
||||
cmd[0] = 0x50; // EWSR
|
||||
cmd[0] = 0x06; // WREN
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0);
|
||||
if (err < 0)
|
||||
break;
|
||||
goto out;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = LockBits; // BPx = 0, Lock all blocks
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 2, NULL, 0);
|
||||
} while(0);
|
||||
cmd[0] = 0x02; // PP
|
||||
cmd[1] = ( (( FlashOffset + j ) >> 16) & 0xFF );
|
||||
cmd[2] = ( (( FlashOffset + j ) >> 8) & 0xFF );
|
||||
cmd[3] = 0x00;
|
||||
memcpy(&cmd[4], ddf->buffer, 256);
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 260, NULL, 0);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
err = flash_wait(ddf->fd, ddf->link);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
cmd[0] = 0x50; // EWSR
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 1, NULL, 0);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
cmd[0] = 0x01; // WRSR
|
||||
cmd[1] = LockBits; // BPx = 0, Lock all blocks
|
||||
err = flashio(ddf->fd, ddf->link, cmd, 2, NULL, 0);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -845,7 +858,7 @@ static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxle
|
||||
case SSTI_SST25VF032B:
|
||||
return flashwrite_SSTI(ddf, fs, addr, maxlen, fw_off);
|
||||
case SSTI_SST25VF064C:
|
||||
return flashwrite_pagemode(ddf, fs, addr, 0x3c, fw_off);
|
||||
return flashwrite_pagemode(ddf, fs, addr, 0x3c, fw_off, 0);
|
||||
case SPANSION_S25FL116K:
|
||||
case SPANSION_S25FL132K:
|
||||
case SPANSION_S25FL164K:
|
||||
@ -853,7 +866,8 @@ static int flashwrite(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxle
|
||||
case WINBOND_W25Q32JV:
|
||||
case WINBOND_W25Q64JV:
|
||||
case WINBOND_W25Q128JV:
|
||||
return flashwrite_pagemode(ddf, fs, addr, 0x1c, fw_off);
|
||||
default:
|
||||
return flashwrite_pagemode(ddf, fs, addr, 0x1c, fw_off, 1);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -892,97 +906,55 @@ static int get_id(struct ddflash *ddf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct devids {
|
||||
uint16_t id;
|
||||
char *name;
|
||||
char *fname;
|
||||
};
|
||||
|
||||
#define DEV(_id, _name, _fname) { .id = _id, .name = _name, .fname = _fname }
|
||||
|
||||
static const struct devids ids[] = {
|
||||
DEV(0x0002, "Octopus 35", "DVBBridgeV1A_DVBBridgeV1A.bit"),
|
||||
DEV(0x0003, "Octopus", "DVBBridgeV1B_DVBBridgeV1B.fpga"),
|
||||
DEV(0x0005, "Octopus Classic", "DVBBridgeV2A_DD01_0005_STD.fpga"),
|
||||
DEV(0x0006, "CineS2 V7", "DVBBridgeV2A_DD01_0006_STD.fpga"),
|
||||
DEV(0x0007, "Octopus 4/8", "DVBBridgeV2A_DD01_0007_MXL.fpga"),
|
||||
DEV(0x0008, "Octopus 4/8", "DVBBridgeV2A_DD01_0008_CXD.fpga"),
|
||||
DEV(0x0009, "Octopus MAXSX8", "DVBBridgeV2A_DD01_0009_SX8.fpga"),
|
||||
DEV(0x000b, "Octopus MAXSX8 Basic", "DVBBridgeV2A_DD01_000B_SX8.fpga"),
|
||||
DEV(0x000a, "Octopus MAXM4", "DVBBridgeV2A_DD01_000A_M4.fpga"),
|
||||
DEV(0x0011, "Octopus CI", "DVBBridgeV2B_DD01_0011.fpga"),
|
||||
DEV(0x0012, "Octopus CI", "DVBBridgeV2B_DD01_0012_STD.fpga"),
|
||||
DEV(0x0013, "Octopus PRO", "DVBBridgeV2B_DD01_0013_PRO.fpga"),
|
||||
DEV(0x0020, "Octopus GT Mini", "DVBBridgeV2C_DD01_0020.fpga"),
|
||||
DEV(0x0201, "Modulator", "DVBModulatorV1B_DVBModulatorV1B.bit"),
|
||||
DEV(0x0203, "Modulator Test", "DVBModulatorV1B_DD01_0203.fpga"),
|
||||
DEV(0x0210, "Modulator V2", "DVBModulatorV2A_DD01_0210.fpga"),
|
||||
DEV(0x0220, "SDRModulator ATV", "SDRModulatorV1A_DD01_0220.fpga"),
|
||||
DEV(0x0221, "SDRModulator IQ", "SDRModulatorV1A_DD01_0221_IQ.fpga"),
|
||||
DEV(0x0222, "SDRModulator DVBT", "SDRModulatorV1A_DD01_0222_DVBT.fpga"),
|
||||
DEV(0x0223, "SDRModulator IQ2", "SDRModulatorV1A_DD01_0223_IQ2.fpga"),
|
||||
DEV(0x0000, "UNKNOWN", 0),
|
||||
};
|
||||
|
||||
static char *devid2fname(uint16_t devid, char **name)
|
||||
{
|
||||
int i;
|
||||
char *fname = 0;
|
||||
|
||||
switch (devid) {
|
||||
case 0x0002:
|
||||
fname="DVBBridgeV1A_DVBBridgeV1A.bit";
|
||||
*name = "Octopus 35";
|
||||
break;
|
||||
case 0x0003:
|
||||
fname="DVBBridgeV1B_DVBBridgeV1B.fpga";
|
||||
*name = "Octopus";
|
||||
break;
|
||||
case 0x0005:
|
||||
fname="DVBBridgeV2A_DD01_0005_STD.fpga";
|
||||
*name = "Octopus Classic";
|
||||
break;
|
||||
case 0x0006:
|
||||
fname="DVBBridgeV2A_DD01_0006_STD.fpga";
|
||||
*name = "CineS2 V7";
|
||||
break;
|
||||
case 0x0007:
|
||||
fname="DVBBridgeV2A_DD01_0007_MXL.fpga";
|
||||
*name = "Octopus 4/8";
|
||||
break;
|
||||
case 0x0008:
|
||||
fname="DVBBridgeV2A_DD01_0008_CXD.fpga";
|
||||
*name = "Octopus 4/8";
|
||||
break;
|
||||
case 0x0009:
|
||||
fname="DVBBridgeV2A_DD01_0009_SX8.fpga";
|
||||
*name = "Octopus MAXSX8";
|
||||
break;
|
||||
case 0x000b:
|
||||
fname="DVBBridgeV2A_DD01_000B_SX8.fpga";
|
||||
*name = "Octopus MAXSX8 Basic";
|
||||
break;
|
||||
case 0x000a:
|
||||
fname="DVBBridgeV2A_DD01_000A_M4.fpga";
|
||||
*name = "Octopus MAXM4";
|
||||
break;
|
||||
case 0x0011:
|
||||
fname="DVBBridgeV2B_DD01_0011.fpga";
|
||||
*name = "Octopus CI";
|
||||
break;
|
||||
case 0x0012:
|
||||
fname="DVBBridgeV2B_DD01_0012_STD.fpga";
|
||||
*name = "Octopus CI";
|
||||
break;
|
||||
case 0x0013:
|
||||
fname="DVBBridgeV2B_DD01_0013_PRO.fpga";
|
||||
*name = "Octopus PRO";
|
||||
break;
|
||||
case 0x0020:
|
||||
fname="DVBBridgeV2C_DD01_0020.fpga";
|
||||
*name = "Octopus GT Mini";
|
||||
break;
|
||||
case 0x0201:
|
||||
fname="DVBModulatorV1B_DVBModulatorV1B.bit";
|
||||
*name = "Modulator";
|
||||
break;
|
||||
case 0x0203:
|
||||
fname="DVBModulatorV1B_DD01_0203.fpga";
|
||||
*name = "Modulator Test";
|
||||
break;
|
||||
case 0x0210:
|
||||
fname="DVBModulatorV2A_DD01_0210.fpga";
|
||||
*name = "Modulator V2";
|
||||
break;
|
||||
case 0x0220:
|
||||
fname="SDRModulatorV1A_DD01_0220.fpga";
|
||||
*name = "SDRModulator ATV";
|
||||
break;
|
||||
case 0x0221:
|
||||
fname="SDRModulatorV1A_DD01_0221_IQ.fpga";
|
||||
*name = "SDRModulator IQ";
|
||||
break;
|
||||
case 0x0222:
|
||||
fname="SDRModulatorV1A_DD01_0222_DVBT.fpga";
|
||||
*name = "SDRModulator DVBT";
|
||||
break;
|
||||
default:
|
||||
*name = "UNKNOWN";
|
||||
break;
|
||||
for (i = 0; ; i++) {
|
||||
const struct devids *id = &ids[i];
|
||||
|
||||
if (devid == id->id || !id->id) {
|
||||
*name = id->name;
|
||||
fname = id->fname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return fname;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen, uint32_t fw_off)
|
||||
{
|
||||
off_t off;
|
||||
@ -1015,9 +987,9 @@ static int flashcmp(struct ddflash *ddf, int fs, uint32_t addr, uint32_t maxlen,
|
||||
|
||||
if (memcmp(buf, buf2, bl)) {
|
||||
printf("flash differs at %08x (offset %u)\n", addr, j);
|
||||
dump(buf, bl);
|
||||
printf("\n");
|
||||
dump(buf2, bl);
|
||||
//dump(buf, bl);
|
||||
//printf("\n");
|
||||
//dump(buf2, bl);
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
@ -1080,7 +1052,7 @@ static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off)
|
||||
unsigned int devid, version, length;
|
||||
unsigned int cid[8];
|
||||
int cids = 0;
|
||||
uint32_t maxlen = 2 * 1024 * 1024, crc;
|
||||
uint32_t maxlen = 2 * 1024 * 1024, crc, fcrc;
|
||||
|
||||
fd = open(fn, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
@ -1148,11 +1120,17 @@ static int check_fw(struct ddflash *ddf, char *fn, uint32_t *fw_off)
|
||||
}
|
||||
p++;
|
||||
*fw_off = p;
|
||||
printf(" CRC = %08x\n", crc);
|
||||
printf(" devid = %04x\n", devid);
|
||||
printf(" version = %08x (current image = %08x)\n", version, ddf->id.hw);
|
||||
fcrc = crc32(buf + p, length, 0xffffffff);
|
||||
printf(" CRC file = %08x\n", fcrc);
|
||||
printf(" CRC flash = %08x\n", crc);
|
||||
printf(" devid = %04x\n", devid);
|
||||
printf(" version = %08x (current image = %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 (fcrc != crc) {
|
||||
printf("CRC error in file %s!\n", fn);
|
||||
return -4;
|
||||
}
|
||||
if (devid == ddf->id.device) {
|
||||
if (version <= (ddf->id.hw & 0xffffff)) {
|
||||
printf("%s is older or same version as flash\n", fn);
|
||||
@ -1175,7 +1153,7 @@ static int update_image(struct ddflash *ddf, char *fn,
|
||||
int fs, res = 0;
|
||||
uint32_t fw_off = 0;
|
||||
|
||||
printf("File: %s\n", fn);
|
||||
printf("File: %s\n", fn);
|
||||
if (has_header) {
|
||||
int ck;
|
||||
ck = check_fw(ddf, fn, &fw_off);
|
||||
@ -1192,6 +1170,10 @@ static int update_image(struct ddflash *ddf, char *fn,
|
||||
res = flashcmp(ddf, fs, adr, len, fw_off);
|
||||
if (res == -2) {
|
||||
printf("Flash already identical to %s\n", fn);
|
||||
if (ddf->force) {
|
||||
printf("but force enabled!\n");
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
if (res < 0)
|
||||
goto out;
|
||||
@ -1200,6 +1182,9 @@ static int update_image(struct ddflash *ddf, char *fn,
|
||||
res = flashcmp(ddf, fs, adr, len, fw_off);
|
||||
if (res == -2) {
|
||||
res = 1;
|
||||
printf("Flash verify OK!\n");
|
||||
} else {
|
||||
printf("Flash verify ERROR!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,6 +89,7 @@ struct ddflash {
|
||||
int fd;
|
||||
uint32_t link;
|
||||
char *fname;
|
||||
int force;
|
||||
|
||||
struct ddb_id id;
|
||||
uint32_t version;
|
||||
|
@ -33,8 +33,10 @@ void proc_ts(int i, uint8_t *buf)
|
||||
if (ccin & 0x10) {
|
||||
if( cc[pid] != 0 ) {
|
||||
// TODO: 1 repetition allowed
|
||||
if ((((cc[pid] + 1) & 0x0F) != (ccin & 0x0F)) )
|
||||
if ((((cc[pid] + 1) & 0x0F) != (ccin & 0x0F)) ) {
|
||||
cc_errors += 1;
|
||||
printf("%04x: %u != %u\n", pid, (cc[pid] + 1) & 0x0F, ccin & 0x0F);
|
||||
}
|
||||
}
|
||||
cc[pid] = ccin;
|
||||
}
|
||||
|
@ -2507,8 +2507,10 @@ static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr)
|
||||
rm = io_regmap(input, 1);
|
||||
input->regs = DDB_LINK_TAG(port->lnr) |
|
||||
(rm->input->base + rm->input->size * nr);
|
||||
#if 0
|
||||
dev_info(dev->dev, "init link %u, input %u, regs %08x\n",
|
||||
port->lnr, nr, input->regs);
|
||||
#endif
|
||||
if (dev->has_dma) {
|
||||
const struct ddb_regmap *rm0 = io_regmap(input, 0);
|
||||
u32 base = rm0->irq_base_idma;
|
||||
@ -3210,6 +3212,12 @@ struct ddb_i2c_msg {
|
||||
__u32 mlen;
|
||||
};
|
||||
|
||||
struct ddb_mci_msg {
|
||||
__u32 link;
|
||||
struct mci_command cmd;
|
||||
struct mci_result res;
|
||||
};
|
||||
|
||||
#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)
|
||||
@ -3222,6 +3230,7 @@ struct ddb_i2c_msg {
|
||||
#define IOCTL_DDB_WRITE_MDIO _IOR(DDB_MAGIC, 0x09, struct ddb_mdio)
|
||||
#define IOCTL_DDB_READ_I2C _IOWR(DDB_MAGIC, 0x0a, struct ddb_i2c_msg)
|
||||
#define IOCTL_DDB_WRITE_I2C _IOR(DDB_MAGIC, 0x0b, struct ddb_i2c_msg)
|
||||
#define IOCTL_DDB_MCI_CMD _IOWR(DDB_MAGIC, 0x0c, struct ddb_mci_msg)
|
||||
|
||||
#define DDB_NAME "ddbridge"
|
||||
|
||||
@ -3433,6 +3442,24 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
return -EIO;
|
||||
break;
|
||||
}
|
||||
case IOCTL_DDB_MCI_CMD:
|
||||
{
|
||||
struct ddb_mci_msg msg;
|
||||
struct ddb_link *link;
|
||||
int res;
|
||||
|
||||
if (copy_from_user(&msg, parg, sizeof(msg)))
|
||||
return -EFAULT;
|
||||
if (msg.link > 3)
|
||||
return -EFAULT;
|
||||
link = &dev->link[msg.link];
|
||||
if (!link->mci_base)
|
||||
return -EFAULT;
|
||||
res = ddb_mci_cmd_link(link, &msg.cmd, &msg.res);
|
||||
if (copy_to_user(parg, &msg, sizeof(msg)))
|
||||
return -EFAULT;
|
||||
return res;
|
||||
}
|
||||
default:
|
||||
return -ENOTTY;
|
||||
}
|
||||
@ -4414,6 +4441,13 @@ static int ddb_init_boards(struct ddb *dev)
|
||||
usleep_range(2000, 3000);
|
||||
}
|
||||
ddb_init_tempmon(link);
|
||||
|
||||
if (info->regmap->mci) {
|
||||
if (link->info->type == DDB_OCTOPUS_MCI ||
|
||||
((link->info->type == DDB_MOD) &&
|
||||
(link->ids.regmapid & 0xfff0)))
|
||||
mci_init(link);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -124,6 +124,32 @@ static const struct ddb_regset octopus_i2c_buf = {
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static const struct ddb_regset max_mci = {
|
||||
.base = 0x500,
|
||||
.num = 0x01,
|
||||
.size = 0x04,
|
||||
};
|
||||
|
||||
static const struct ddb_regset max_mci_buf = {
|
||||
.base = 0x600,
|
||||
.num = 0x01,
|
||||
.size = 0x100,
|
||||
};
|
||||
|
||||
static const struct ddb_regset sdr_mci = {
|
||||
.base = 0x260,
|
||||
.num = 0x01,
|
||||
.size = 0x04,
|
||||
};
|
||||
|
||||
static const struct ddb_regset sdr_mci_buf = {
|
||||
.base = 0x300,
|
||||
.num = 0x01,
|
||||
.size = 0x100,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static const struct ddb_regset octopro_input = {
|
||||
.base = 0x400,
|
||||
.num = 0x14,
|
||||
@ -224,6 +250,25 @@ static const struct ddb_regmap octopus_map = {
|
||||
.output = &octopus_output,
|
||||
};
|
||||
|
||||
static const struct ddb_regmap octopus_mci_map = {
|
||||
.irq_version = 1,
|
||||
.irq_base_i2c = 0,
|
||||
.irq_base_idma = 8,
|
||||
.irq_base_odma = 16,
|
||||
.irq_base_mci = 0,
|
||||
.i2c = &octopus_i2c,
|
||||
.i2c_buf = &octopus_i2c_buf,
|
||||
.idma = &octopus_idma,
|
||||
.idma_buf = &octopus_idma_buf,
|
||||
.odma = &octopus_odma,
|
||||
.odma_buf = &octopus_odma_buf,
|
||||
.input = &octopus_input,
|
||||
.output = &octopus_output,
|
||||
|
||||
.mci = &max_mci,
|
||||
.mci_buf = &max_mci_buf,
|
||||
};
|
||||
|
||||
static const struct ddb_regmap octopro_map = {
|
||||
.irq_version = 2,
|
||||
.irq_base_i2c = 32,
|
||||
@ -280,10 +325,14 @@ static const struct ddb_regmap octopus_sdr_map = {
|
||||
.irq_version = 2,
|
||||
.irq_base_odma = 64,
|
||||
.irq_base_rate = 32,
|
||||
.irq_base_mci = 10,
|
||||
.output = &octopus_sdr_output,
|
||||
.odma = &octopus_mod_2_odma,
|
||||
.odma_buf = &octopus_mod_2_odma_buf,
|
||||
.channel = &octopus_mod_2_channel,
|
||||
|
||||
.mci = &sdr_mci,
|
||||
.mci_buf = &sdr_mci_buf,
|
||||
};
|
||||
|
||||
static const struct ddb_regmap gtl_mini = {
|
||||
@ -537,6 +586,16 @@ static const struct ddb_info ddb_sdr_iq = {
|
||||
.tempmon_irq = 8,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_sdr_iq2 = {
|
||||
.type = DDB_MOD,
|
||||
.name = "Digital Devices SDR IQ2",
|
||||
.version = 17,
|
||||
.regmap = &octopus_sdr_map,
|
||||
.port_num = 4,
|
||||
.temp_num = 1,
|
||||
.tempmon_irq = 8,
|
||||
};
|
||||
|
||||
static const struct ddb_info ddb_sdr_dvbt = {
|
||||
.type = DDB_MOD,
|
||||
.name = "Digital Devices DVBT",
|
||||
@ -568,7 +627,7 @@ static const struct ddb_info ddb_octopro = {
|
||||
static const struct ddb_info ddb_s2_48 = {
|
||||
.type = DDB_OCTOPUS_MAX,
|
||||
.name = "Digital Devices MAX S8 4/8",
|
||||
.regmap = &octopus_map,
|
||||
.regmap = &octopus_mci_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x01,
|
||||
.board_control = 1,
|
||||
@ -635,10 +694,12 @@ static const struct ddb_info ddb_c2t2i_8 = {
|
||||
.tempmon_irq = 24,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static const struct ddb_info ddb_s2x_48 = {
|
||||
.type = DDB_OCTOPUS_MCI,
|
||||
.name = "Digital Devices MAX SX8",
|
||||
.regmap = &octopus_map,
|
||||
.regmap = &octopus_mci_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x00,
|
||||
.tempmon_irq = 24,
|
||||
@ -650,7 +711,7 @@ static const struct ddb_info ddb_s2x_48 = {
|
||||
static const struct ddb_info ddb_s2x_48_b = {
|
||||
.type = DDB_OCTOPUS_MCI,
|
||||
.name = "Digital Devices MAX SX8 Basic",
|
||||
.regmap = &octopus_map,
|
||||
.regmap = &octopus_mci_map,
|
||||
.port_num = 4,
|
||||
.i2c_mask = 0x00,
|
||||
.tempmon_irq = 24,
|
||||
@ -662,7 +723,7 @@ static const struct ddb_info ddb_s2x_48_b = {
|
||||
static const struct ddb_info ddb_m4 = {
|
||||
.type = DDB_OCTOPUS_MCI,
|
||||
.name = "Digital Devices MAX M4",
|
||||
.regmap = &octopus_map,
|
||||
.regmap = &octopus_mci_map,
|
||||
.port_num = 2,
|
||||
.i2c_mask = 0x00,
|
||||
.tempmon_irq = 24,
|
||||
@ -671,6 +732,8 @@ static const struct ddb_info ddb_m4 = {
|
||||
.temp_num = 1,
|
||||
};
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static const struct ddb_info ddb_gtl_mini = {
|
||||
.type = DDB_OCTOPUS,
|
||||
.name = "Digital Devices Octopus GT Mini",
|
||||
@ -813,6 +876,8 @@ static const struct ddb_device_id ddb_device_ids[] = {
|
||||
DDB_DEVID(0x0220, 0x0001, ddb_sdr_atv),
|
||||
DDB_DEVID(0x0221, 0x0001, ddb_sdr_iq),
|
||||
DDB_DEVID(0x0222, 0x0001, ddb_sdr_dvbt),
|
||||
DDB_DEVID(0x0223, 0x0001, ddb_sdr_iq2),
|
||||
DDB_DEVID(0xffff, 0xffff, ddb_sdr_iq2),
|
||||
|
||||
/* testing on OctopusNet Pro */
|
||||
DDB_DEVID(0x0320, 0xffff, ddb_octopro_hdin),
|
||||
|
@ -139,8 +139,8 @@ void gtlcpyfrom(struct ddb *dev, u8 *buf, u32 adr, long count)
|
||||
u32 a = p & 3;
|
||||
|
||||
if (a) {
|
||||
val = ddbreadl(dev, p) >> (8 * a);
|
||||
while (p & 3 && count) {
|
||||
val = ddbreadl(dev, p & ~3) >> (8 * a);
|
||||
while ((p & 3) && count) {
|
||||
*buf = val & 0xff;
|
||||
val >>= 8;
|
||||
p++;
|
||||
@ -177,7 +177,12 @@ void ddbcpyto(struct ddb *dev, u32 adr, void *src, long count)
|
||||
|
||||
void ddbcpyfrom(struct ddb *dev, void *dst, u32 adr, long count)
|
||||
{
|
||||
return gtlcpyfrom(dev, dst, adr, count);
|
||||
/* The possible 64 bit read in memcpy_fromio produces errors
|
||||
on some platforms, i.e. arm64 rpi4
|
||||
if (unlikely(adr & 0xf0000000))
|
||||
return gtlcpyfrom(dev, dst, adr, count);
|
||||
return memcpy_fromio(dst, dev->regs + adr, count);
|
||||
return memcpy_fromio(dst, dev->regs + adr, count);
|
||||
*/
|
||||
|
||||
}
|
||||
|
@ -402,6 +402,8 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status)
|
||||
ddb_mci_get_strength(fe);
|
||||
if (res.status == MCI_DEMOD_WAIT_SIGNAL)
|
||||
*status = 0x01;
|
||||
if (res.status == M4_DEMOD_WAIT_TS)
|
||||
*status = 0x03;
|
||||
if (res.status == MCI_DEMOD_LOCKED) {
|
||||
*status = 0x1f;
|
||||
ddb_mci_get_snr(fe);
|
||||
|
@ -290,9 +290,11 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64)))
|
||||
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))
|
||||
return -ENODEV;
|
||||
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
|
||||
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
|
||||
} else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
|
||||
pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
|
||||
} else return -ENODEV;
|
||||
|
||||
dev = vzalloc(sizeof(*dev));
|
||||
if (!dev)
|
||||
@ -425,6 +427,7 @@ static const struct pci_device_id ddb_id_table[] __devinitconst = {
|
||||
DDB_DEVICE_ANY(0x0220),
|
||||
DDB_DEVICE_ANY(0x0221),
|
||||
DDB_DEVICE_ANY(0x0222),
|
||||
DDB_DEVICE_ANY(0x0223),
|
||||
DDB_DEVICE_ANY(0x0320),
|
||||
DDB_DEVICE_ANY(0x0321),
|
||||
DDB_DEVICE_ANY(0x0322),
|
||||
|
@ -28,151 +28,178 @@
|
||||
|
||||
static LIST_HEAD(mci_list);
|
||||
|
||||
static int mci_reset(struct mci *state)
|
||||
static int mci_reset(struct ddb_link *link)
|
||||
{
|
||||
struct ddb_link *link = state->base->link;
|
||||
const struct ddb_regmap *regmap = link->info->regmap;
|
||||
u32 control;
|
||||
u32 status = 0;
|
||||
u32 timeout = 40;
|
||||
|
||||
ddblwritel(link, MCI_CONTROL_RESET, MCI_CONTROL);
|
||||
ddblwritel(link, 0, MCI_CONTROL + 4); /* 1= no internal init */
|
||||
msleep(300);
|
||||
ddblwritel(link, 0, MCI_CONTROL);
|
||||
if (!regmap || ! regmap->mci)
|
||||
return -EINVAL;
|
||||
control = regmap->mci->base;
|
||||
|
||||
if ((link->info->type == DDB_OCTOPUS_MCI) &&
|
||||
(ddblreadl(link, control) & MCI_CONTROL_START_COMMAND)) {
|
||||
ddblwritel(link, MCI_CONTROL_RESET, control);
|
||||
ddblwritel(link, 0, control + 4); /* 1= no internal init */
|
||||
msleep(300);
|
||||
}
|
||||
ddblwritel(link, 0, control);
|
||||
while (1) {
|
||||
status = ddblreadl(link, MCI_CONTROL);
|
||||
status = ddblreadl(link, control);
|
||||
if ((status & MCI_CONTROL_READY) == MCI_CONTROL_READY)
|
||||
break;
|
||||
if (--timeout == 0)
|
||||
break;
|
||||
msleep(50);
|
||||
}
|
||||
if ((status & MCI_CONTROL_READY) == 0)
|
||||
dev_info(link->dev->dev, "MCI control port @ %08x\n", control);
|
||||
if ((status & MCI_CONTROL_READY) == 0) {
|
||||
dev_err(link->dev->dev, "MCI init failed!\n");
|
||||
return -1;
|
||||
if (link->ids.device == 0x0009 || link->ids.device == 0x000b)
|
||||
ddblwritel(link, SX8_TSCONFIG_MODE_NORMAL, SX8_TSCONFIG);
|
||||
}
|
||||
dev_info(link->dev->dev, "MCI port OK, init time %u msecs\n", (40-timeout)*50);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ddb_mci_config(struct mci *state, u32 config)
|
||||
{
|
||||
struct ddb_link *link = state->base->link;
|
||||
|
||||
if (link->ids.device != 0x0009 && link->ids.device != 0x000b)
|
||||
return -EINVAL;
|
||||
ddblwritel(link, config, SX8_TSCONFIG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ddb_mci_cmd_raw_unlocked(struct mci *state,
|
||||
static int ddb_mci_cmd_raw_unlocked(struct ddb_link *link,
|
||||
u32 *cmd, u32 cmd_len,
|
||||
u32 *res, u32 res_len)
|
||||
{
|
||||
struct ddb_link *link = state->base->link;
|
||||
const struct ddb_regmap *regmap = link->info->regmap;
|
||||
u32 control, command, result;
|
||||
u32 i, val;
|
||||
unsigned long stat;
|
||||
|
||||
val = ddblreadl(link, MCI_CONTROL);
|
||||
if (!regmap || ! regmap->mci)
|
||||
return -EINVAL;
|
||||
control = regmap->mci->base;
|
||||
command = regmap->mci_buf->base;
|
||||
result = command + MCI_COMMAND_SIZE;
|
||||
val = ddblreadl(link, control);
|
||||
if (val & (MCI_CONTROL_RESET | MCI_CONTROL_START_COMMAND))
|
||||
return -EIO;
|
||||
if (cmd && cmd_len)
|
||||
for (i = 0; i < cmd_len; i++)
|
||||
ddblwritel(link, cmd[i], MCI_COMMAND + i * 4);
|
||||
val |= (MCI_CONTROL_START_COMMAND | MCI_CONTROL_ENABLE_DONE_INTERRUPT);
|
||||
ddblwritel(link, val, MCI_CONTROL);
|
||||
ddblwritel(link, cmd[i], command + i * 4);
|
||||
val |= (MCI_CONTROL_START_COMMAND |
|
||||
MCI_CONTROL_ENABLE_DONE_INTERRUPT);
|
||||
ddblwritel(link, val, control);
|
||||
|
||||
stat = wait_for_completion_timeout(&state->base->completion, HZ);
|
||||
stat = wait_for_completion_timeout(&link->mci_completion, HZ);
|
||||
if (stat == 0) {
|
||||
u32 istat = ddblreadl(link, INTERRUPT_STATUS);
|
||||
|
||||
dev_err(state->base->link->dev->dev, "MCI timeout\n");
|
||||
val = ddblreadl(link, MCI_CONTROL);
|
||||
dev_err(link->dev->dev, "MCI timeout\n");
|
||||
val = ddblreadl(link, control);
|
||||
if (val == 0xffffffff) {
|
||||
dev_err(state->base->link->dev->dev,
|
||||
dev_err(link->dev->dev,
|
||||
"Lost PCIe link!\n");
|
||||
return -EIO;
|
||||
} else {
|
||||
dev_err(state->base->link->dev->dev,
|
||||
"DDBridge IRS %08x link %u\n", istat, link->nr);
|
||||
dev_err(link->dev->dev,
|
||||
"DDBridge IRS %08x link %u\n",
|
||||
istat, link->nr);
|
||||
if (istat & 1)
|
||||
ddblwritel(link, istat, INTERRUPT_ACK);
|
||||
if (link->nr)
|
||||
ddbwritel(link->dev, 0xffffff, INTERRUPT_ACK);
|
||||
ddbwritel(link->dev,
|
||||
0xffffff, INTERRUPT_ACK);
|
||||
}
|
||||
}
|
||||
if (res && res_len)
|
||||
for (i = 0; i < res_len; i++)
|
||||
res[i] = ddblreadl(link, MCI_RESULT + i * 4);
|
||||
res[i] = ddblreadl(link, result + i * 4);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ddb_mci_cmd_unlocked(struct mci *state,
|
||||
struct mci_command *command,
|
||||
struct mci_result *result)
|
||||
int ddb_mci_cmd_link(struct ddb_link *link,
|
||||
struct mci_command *command,
|
||||
struct mci_result *result)
|
||||
{
|
||||
u32 *cmd = (u32 *) command;
|
||||
u32 *res = (u32 *) result;
|
||||
|
||||
return ddb_mci_cmd_raw_unlocked(state, cmd, sizeof(*command)/sizeof(u32),
|
||||
res, sizeof(*result)/sizeof(u32));
|
||||
}
|
||||
|
||||
int ddb_mci_cmd(struct mci *state,
|
||||
struct mci_command *command,
|
||||
struct mci_result *result)
|
||||
{
|
||||
int stat;
|
||||
struct mci_result res;
|
||||
int stat;
|
||||
|
||||
if (!result)
|
||||
result = &res;
|
||||
mutex_lock(&state->base->mci_lock);
|
||||
stat = ddb_mci_cmd_raw_unlocked(state,
|
||||
(u32 *)command, sizeof(*command)/sizeof(u32),
|
||||
(u32 *)result, sizeof(*result)/sizeof(u32));
|
||||
mutex_unlock(&state->base->mci_lock);
|
||||
mutex_lock(&link->mci_lock);
|
||||
stat = ddb_mci_cmd_raw_unlocked(link,
|
||||
(u32 *)command,
|
||||
sizeof(*command)/sizeof(u32),
|
||||
(u32 *)result,
|
||||
sizeof(*result)/sizeof(u32));
|
||||
mutex_unlock(&link->mci_lock);
|
||||
if (command && result && (result->status & 0x80))
|
||||
dev_warn(state->base->link->dev->dev,
|
||||
dev_warn(link->dev->dev,
|
||||
"mci_command 0x%02x, error=0x%02x\n",
|
||||
command->command, result->status);
|
||||
return stat;
|
||||
}
|
||||
|
||||
static void mci_handler(void *priv)
|
||||
{
|
||||
struct ddb_link *link = (struct ddb_link *) priv;
|
||||
|
||||
complete(&link->mci_completion);
|
||||
}
|
||||
|
||||
int mci_init(struct ddb_link *link)
|
||||
{
|
||||
int result;
|
||||
|
||||
mutex_init(&link->mci_lock);
|
||||
init_completion(&link->mci_completion);
|
||||
result = mci_reset(link);
|
||||
if (result < 0)
|
||||
return result;
|
||||
if (link->ids.device == 0x0009 || link->ids.device == 0x000b)
|
||||
ddblwritel(link, SX8_TSCONFIG_MODE_NORMAL, SX8_TSCONFIG);
|
||||
|
||||
ddb_irq_set(link->dev, link->nr,
|
||||
link->info->regmap->irq_base_mci,
|
||||
mci_handler, link);
|
||||
link->mci_ok = 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
int mci_cmd_val(struct ddb_link *link, uint32_t cmd, uint32_t val)
|
||||
{
|
||||
struct mci_result result;
|
||||
struct mci_command command = {
|
||||
.command_word = cmd,
|
||||
.params = { val },
|
||||
};
|
||||
|
||||
return ddb_mci_cmd_link(link, &command, &result);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
int ddb_mci_cmd(struct mci *state,
|
||||
struct mci_command *command,
|
||||
struct mci_result *result)
|
||||
{
|
||||
return ddb_mci_cmd_link(state->base->link, command, result);
|
||||
}
|
||||
|
||||
|
||||
int ddb_mci_cmd_raw(struct mci *state,
|
||||
struct mci_command *command, u32 command_len,
|
||||
struct mci_result *result, u32 result_len)
|
||||
{
|
||||
struct ddb_link *link = state->base->link;
|
||||
int stat;
|
||||
|
||||
mutex_lock(&state->base->mci_lock);
|
||||
stat = ddb_mci_cmd_raw_unlocked(state,
|
||||
mutex_lock(&link->mci_lock);
|
||||
stat = ddb_mci_cmd_raw_unlocked(link,
|
||||
(u32 *)command, command_len,
|
||||
(u32 *)result, result_len);
|
||||
mutex_unlock(&state->base->mci_lock);
|
||||
mutex_unlock(&link->mci_lock);
|
||||
return stat;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int ddb_mci_get_iq(struct mci *mci, u32 demod, s16 *i, s16 *q)
|
||||
{
|
||||
int stat;
|
||||
struct mci_command cmd;
|
||||
struct mci_result res;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
memset(&res, 0, sizeof(res));
|
||||
cmd.command = MCI_CMD_GET_IQSYMBOL;
|
||||
cmd.demod = demod;
|
||||
stat = ddb_mci_cmd(mci, &cmd, &res);
|
||||
if (!stat) {
|
||||
*i = res.iq_symbol.i;
|
||||
*q = res.iq_symbol.q;
|
||||
}
|
||||
return stat;
|
||||
}
|
||||
#endif
|
||||
|
||||
int ddb_mci_get_status(struct mci *mci, struct mci_result *res)
|
||||
{
|
||||
struct mci_command cmd;
|
||||
@ -189,7 +216,8 @@ int ddb_mci_get_snr(struct dvb_frontend *fe)
|
||||
|
||||
p->cnr.len = 1;
|
||||
p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->cnr.stat[0].svalue = (s64) mci->signal_info.dvbs2_signal_info.signal_to_noise * 10;
|
||||
p->cnr.stat[0].svalue =
|
||||
(s64) mci->signal_info.dvbs2_signal_info.signal_to_noise * 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -266,6 +294,8 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
|
||||
p->delivery_system =
|
||||
(mci->signal_info.dvbs2_signal_info.standard == 2) ?
|
||||
SYS_DVBS2 : SYS_DVBS;
|
||||
p->inversion = (mci->signal_info.dvbs2_signal_info.roll_off & 0x80) ?
|
||||
INVERSION_ON : INVERSION_OFF;
|
||||
if (mci->signal_info.dvbs2_signal_info.standard == 2) {
|
||||
u32 modcod;
|
||||
|
||||
@ -306,6 +336,8 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
|
||||
case SYS_ISDBT:
|
||||
break;
|
||||
}
|
||||
/* post is correct, we cannot provide both pre and post at the same time */
|
||||
/* set pre and post the same for now */
|
||||
p->pre_bit_error.len = 1;
|
||||
p->pre_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->pre_bit_error.stat[0].uvalue =
|
||||
@ -316,6 +348,16 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
|
||||
p->pre_bit_count.stat[0].uvalue =
|
||||
mci->signal_info.dvbs2_signal_info.ber_denominator;
|
||||
|
||||
p->post_bit_error.len = 1;
|
||||
p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->post_bit_error.stat[0].uvalue =
|
||||
mci->signal_info.dvbs2_signal_info.ber_numerator;
|
||||
|
||||
p->post_bit_count.len = 1;
|
||||
p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->post_bit_count.stat[0].uvalue =
|
||||
mci->signal_info.dvbs2_signal_info.ber_denominator;
|
||||
|
||||
p->block_error.len = 1;
|
||||
p->block_error.stat[0].scale = FE_SCALE_COUNTER;
|
||||
p->block_error.stat[0].uvalue =
|
||||
@ -329,17 +371,10 @@ void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p)
|
||||
|
||||
p->strength.len = 1;
|
||||
p->strength.stat[0].scale = FE_SCALE_DECIBEL;
|
||||
p->strength.stat[0].svalue =
|
||||
p->strength.stat[0].svalue = (s64)
|
||||
mci->signal_info.dvbs2_signal_info.channel_power * 10;
|
||||
}
|
||||
|
||||
static void mci_handler(void *priv)
|
||||
{
|
||||
struct mci_base *base = (struct mci_base *)priv;
|
||||
|
||||
complete(&base->completion);
|
||||
}
|
||||
|
||||
static struct mci_base *match_base(void *key)
|
||||
{
|
||||
struct mci_base *p;
|
||||
@ -350,13 +385,8 @@ static struct mci_base *match_base(void *key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int probe(struct mci *state)
|
||||
{
|
||||
mci_reset(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, struct mci_cfg *cfg, int nr, int tuner)
|
||||
struct dvb_frontend *ddb_mci_attach(struct ddb_input *input,
|
||||
struct mci_cfg *cfg, int nr, int tuner)
|
||||
{
|
||||
struct ddb_port *port = input->port;
|
||||
struct ddb *dev = port->dev;
|
||||
@ -380,12 +410,11 @@ struct dvb_frontend *ddb_mci_attach(struct ddb_input *input, struct mci_cfg *cfg
|
||||
base->key = key;
|
||||
base->count = 1;
|
||||
base->link = link;
|
||||
mutex_init(&base->mci_lock);
|
||||
link->mci_base = base;
|
||||
mutex_init(&base->tuner_lock);
|
||||
ddb_irq_set(dev, link->nr, 0, mci_handler, base);
|
||||
init_completion(&base->completion);
|
||||
state->base = base;
|
||||
if (probe(state) < 0) {
|
||||
|
||||
if (!link->mci_ok) {
|
||||
kfree(base);
|
||||
goto fail;
|
||||
}
|
||||
|
@ -39,11 +39,6 @@
|
||||
#define MIC_INTERFACE_OUT (0x0680)
|
||||
#define MIC_INTERFACE_VER (0x06F0)
|
||||
|
||||
|
||||
#define MCI_CONTROL (0x500)
|
||||
#define MCI_COMMAND (0x600)
|
||||
#define MCI_RESULT (0x680)
|
||||
|
||||
#define MCI_COMMAND_SIZE (0x80)
|
||||
#define MCI_RESULT_SIZE (0x80)
|
||||
|
||||
@ -686,7 +681,7 @@ struct mci_result {
|
||||
} ISDBS_TMCCInfo;
|
||||
};
|
||||
u32 version[3];
|
||||
u32 version_rsvd;
|
||||
u8 version_rsvd;
|
||||
u8 version_major;
|
||||
u8 version_minor;
|
||||
u8 version_sub;
|
||||
@ -767,9 +762,9 @@ struct mci_base {
|
||||
struct list_head mci_list;
|
||||
void *key;
|
||||
struct ddb_link *link;
|
||||
struct completion completion;
|
||||
// struct completion completion;
|
||||
struct mutex tuner_lock;
|
||||
struct mutex mci_lock;
|
||||
// struct mutex mci_lock;
|
||||
int count;
|
||||
int type;
|
||||
};
|
||||
@ -795,14 +790,14 @@ struct mci_cfg {
|
||||
};
|
||||
|
||||
int ddb_mci_cmd(struct mci *state, struct mci_command *command, struct mci_result *result);
|
||||
int ddb_mci_cmd_raw(struct mci *state, struct mci_command *command, u32 command_len,
|
||||
struct mci_result *result, u32 result_len);
|
||||
int ddb_mci_config(struct mci *state, u32 config);
|
||||
int ddb_mci_cmd_link(struct ddb_link *link, struct mci_command *command, struct mci_result *result);
|
||||
int ddb_mci_get_status(struct mci *mci, struct mci_result *res);
|
||||
int ddb_mci_get_snr(struct dvb_frontend *fe);
|
||||
int ddb_mci_get_info(struct mci *mci);
|
||||
int ddb_mci_get_strength(struct dvb_frontend *fe);
|
||||
void ddb_mci_proc_info(struct mci *mci, struct dtv_frontend_properties *p);
|
||||
int mci_init(struct ddb_link *link);
|
||||
int mci_cmd_val(struct ddb_link *link, uint32_t cmd, uint32_t val);
|
||||
|
||||
extern struct mci_cfg ddb_max_sx8_cfg;
|
||||
extern struct mci_cfg ddb_max_m4_cfg;
|
||||
|
@ -644,6 +644,7 @@ static int mod_set_sdr_attenuator(struct ddb *dev, u32 value)
|
||||
static int mod_set_sdr_gain(struct ddb *dev, u32 gain)
|
||||
{
|
||||
u32 control = ddbreadl(dev, SDR_CONTROL);
|
||||
struct ddb_link *link = &dev->link[0];
|
||||
|
||||
if (control & 0x01000000) {
|
||||
if (gain > 511)
|
||||
@ -658,6 +659,8 @@ static int mod_set_sdr_gain(struct ddb *dev, u32 gain)
|
||||
return -EINVAL;
|
||||
ddbwritel(dev, gain, SDR_GAIN_F);
|
||||
}
|
||||
if (link->mci_ok)
|
||||
mci_cmd_val(link, 0xc0, gain);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1516,6 +1519,7 @@ static int mod3_set_ari(struct ddb_mod *mod, u32 rate)
|
||||
|
||||
static int mod3_set_sample_rate(struct ddb_mod *mod, u32 rate)
|
||||
{
|
||||
struct ddb *dev = mod->port->dev;
|
||||
u32 cic, inc, bypass = 0;
|
||||
|
||||
switch (rate) {
|
||||
@ -1556,19 +1560,52 @@ static int mod3_set_sample_rate(struct ddb_mod *mod, u32 rate)
|
||||
inc = 0x7684BD82; //1988410754;
|
||||
cic = 7;
|
||||
break;
|
||||
case SYS_DVBS2_22:
|
||||
case SYS_DVB_22:
|
||||
inc = 0x72955555; // 1922389333;
|
||||
cic = 5;
|
||||
bypass = 2;
|
||||
break;
|
||||
case SYS_DVBS2_24:
|
||||
case SYS_DVB_24:
|
||||
inc = 0x7d000000;
|
||||
cic = 5;
|
||||
bypass = 2;
|
||||
break;
|
||||
case SYS_DVB_30:
|
||||
inc = 0x7d000000;
|
||||
cic = 4;
|
||||
bypass = 2;
|
||||
break;
|
||||
case SYS_ISDBS_2886:
|
||||
inc = 0x78400000;
|
||||
cic = 4;
|
||||
bypass = 2;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
{
|
||||
u64 a;
|
||||
|
||||
if (rate < 1000000)
|
||||
return -EINVAL;
|
||||
if (rate > 30720000)
|
||||
return -EINVAL;
|
||||
|
||||
bypass = 2;
|
||||
if (rate > 24576000)
|
||||
cic = 4;
|
||||
else if (rate > 20480000)
|
||||
cic = 5;
|
||||
else if (rate > 17554286)
|
||||
cic = 6;
|
||||
else if (rate > 15360000)
|
||||
cic = 7;
|
||||
else
|
||||
cic = 8;
|
||||
a = (1ULL << 31) * rate * 2 * cic;
|
||||
inc = div_s64(a, 245760000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
dev_info(dev->dev, "inc = %08x, cic = %u, bypass = %u\n", inc, cic, bypass);
|
||||
ddbwritel(mod->port->dev, inc, SDR_CHANNEL_ARICW(mod->port->nr));
|
||||
ddbwritel(mod->port->dev, (cic << 8) | (bypass << 4),
|
||||
SDR_CHANNEL_CONFIG(mod->port->nr));
|
||||
@ -1596,6 +1633,7 @@ static int mod3_prop_proc(struct ddb_mod *mod, struct dtv_property *tvp)
|
||||
|
||||
case MODULATOR_GAIN:
|
||||
return mod_set_sdr_gain(mod->port->dev, tvp->u.data);
|
||||
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -114,6 +114,16 @@ static void release(struct dvb_frontend *fe)
|
||||
kfree(state);
|
||||
}
|
||||
|
||||
static int ddb_mci_tsconfig(struct mci *state, u32 config)
|
||||
{
|
||||
struct ddb_link *link = state->base->link;
|
||||
|
||||
if (link->ids.device != 0x0009 && link->ids.device != 0x000b)
|
||||
return -EINVAL;
|
||||
ddblwritel(link, config, SX8_TSCONFIG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_status(struct dvb_frontend *fe, enum fe_status *status)
|
||||
{
|
||||
int stat;
|
||||
@ -172,7 +182,7 @@ static int stop_iq(struct dvb_frontend *fe)
|
||||
cmd.command = SX8_CMD_STOP_IQ;
|
||||
cmd.demod = state->mci.demod;
|
||||
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
ddb_mci_config(&state->mci, SX8_TSCONFIG_MODE_NORMAL);
|
||||
ddb_mci_tsconfig(&state->mci, SX8_TSCONFIG_MODE_NORMAL);
|
||||
|
||||
mutex_lock(&mci_base->tuner_lock);
|
||||
sx8_base->tuner_use_count[input]--;
|
||||
@ -209,7 +219,7 @@ static int stop(struct dvb_frontend *fe)
|
||||
cmd.demod = state->mci.demod;
|
||||
cmd.output = 0;
|
||||
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
ddb_mci_config(&state->mci, SX8_TSCONFIG_MODE_NORMAL);
|
||||
ddb_mci_tsconfig(&state->mci, SX8_TSCONFIG_MODE_NORMAL);
|
||||
}
|
||||
}
|
||||
mutex_lock(&mci_base->tuner_lock);
|
||||
@ -331,7 +341,7 @@ unlock:
|
||||
cmd.demod = state->mci.demod;
|
||||
cmd.output = p->stream_id & 7;
|
||||
ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
ddb_mci_config(&state->mci, ts_config);
|
||||
ddb_mci_tsconfig(&state->mci, ts_config);
|
||||
}
|
||||
if (p->stream_id != NO_STREAM_ID_FILTER && !(p->stream_id & 0xf0000000))
|
||||
flags |= 0x80;
|
||||
@ -411,7 +421,7 @@ static int start_iq(struct dvb_frontend *fe, u32 flags,
|
||||
stat = ddb_mci_cmd(&state->mci, &cmd, NULL);
|
||||
if (stat)
|
||||
stop_iq(fe);
|
||||
ddb_mci_config(&state->mci, ts_config);
|
||||
ddb_mci_tsconfig(&state->mci, ts_config);
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,7 @@ struct ddb_regmap {
|
||||
u32 irq_base_odma;
|
||||
u32 irq_base_gtl;
|
||||
u32 irq_base_rate;
|
||||
u32 irq_base_mci;
|
||||
|
||||
const struct ddb_regset *i2c;
|
||||
const struct ddb_regset *i2c_buf;
|
||||
@ -127,6 +128,9 @@ struct ddb_regmap {
|
||||
|
||||
const struct ddb_regset *channel;
|
||||
const struct ddb_regset *gtl;
|
||||
|
||||
const struct ddb_regset *mci;
|
||||
const struct ddb_regset *mci_buf;
|
||||
};
|
||||
|
||||
struct ddb_ids {
|
||||
@ -427,6 +431,9 @@ struct ddb_link {
|
||||
struct ddb_irq irq[256];
|
||||
|
||||
struct mci_base *mci_base;
|
||||
struct completion mci_completion;
|
||||
struct mutex mci_lock;
|
||||
int mci_ok;
|
||||
};
|
||||
|
||||
struct ddb {
|
||||
|
13
docs/firmware
Normal file
13
docs/firmware
Normal file
@ -0,0 +1,13 @@
|
||||
Firmware update:
|
||||
|
||||
Copy the firmware file to the dddvb/apps/ directory and
|
||||
execute "./flashprog".
|
||||
|
||||
The program will try to identify the card version and
|
||||
check if it finds the corresponding firmware file.
|
||||
It will then prompt you to confirm to proceed
|
||||
with the flashing procedure.
|
||||
|
||||
After the update the system needs a power cycle.
|
||||
|
||||
|
13
docs/iq_samples
Normal file
13
docs/iq_samples
Normal file
@ -0,0 +1,13 @@
|
||||
~The Max SX8 can provide IQ samples in real time.
|
||||
|
||||
They are 8 bit signed values embedded in TS packets with PID 0x200.
|
||||
|
||||
API:
|
||||
|
||||
Currently DTV_STREAM_ID is misused.
|
||||
|
||||
0x10000000 - symbols (locked and tracked) at symbol rate
|
||||
0x20000000 - samples at ADC rate (1550/24=64.583... MHz)
|
||||
0x30000000 - samples at symbol rate
|
||||
|
||||
Max. sample rate is 64.583333 MHz.
|
@ -44,8 +44,10 @@ enum mod_output_rate {
|
||||
SYS_ISDBT_6 = 16,
|
||||
SYS_J83B_64_6 = 24,
|
||||
SYS_J83B_256_6 = 25,
|
||||
SYS_DVBS2_22 = 32,
|
||||
SYS_DVBS2_24 = 33,
|
||||
SYS_DVB_22 = 32,
|
||||
SYS_DVB_24 = 33,
|
||||
SYS_DVB_30 = 34,
|
||||
SYS_ISDBS_2886 = 48,
|
||||
};
|
||||
|
||||
|
||||
|
@ -203,7 +203,7 @@ void proc_ts(int i, uint8_t *buf)
|
||||
if (ccin & 0x10) {
|
||||
if ( cc[pid]) {
|
||||
// TODO: 1 repetition allowed
|
||||
if( ( ccin & 0x10 ) != 0 && (((cc[pid] + 1) & 0x0F) != (ccin & 0x0F)) )
|
||||
if ((((cc[pid] + 1) & 0x0F) != (ccin & 0x0F)))
|
||||
cc_errors += 1;
|
||||
}
|
||||
cc[pid] = ccin;
|
||||
@ -414,6 +414,8 @@ int main(int argc, char **argv)
|
||||
delsys = SYS_ISDBC;
|
||||
if (!strcmp(optarg, "ISDBT"))
|
||||
delsys = SYS_ISDBT;
|
||||
if (!strcmp(optarg, "ISDBS"))
|
||||
delsys = SYS_ISDBS;
|
||||
break;
|
||||
case 'p':
|
||||
if (!strcmp(optarg, "h") || !strcmp(optarg, "H"))
|
||||
|
@ -128,7 +128,7 @@ static int set_fe_input(struct dddvb_fe *fe, uint32_t fr,
|
||||
}
|
||||
if (input != DDDVB_UNDEF)
|
||||
set_property(fd, DTV_INPUT, input);
|
||||
fprintf(stderr, "bw =%u\n", fe->param.param[PARAM_BW_HZ]);
|
||||
//fprintf(stderr, "bw =%u\n", fe->param.param[PARAM_BW_HZ]);
|
||||
if (fe->param.param[PARAM_BW_HZ] != DDDVB_UNDEF)
|
||||
set_property(fd, DTV_BANDWIDTH_HZ, fe->param.param[PARAM_BW_HZ]);
|
||||
if (fe->param.param[PARAM_ISI] != DDDVB_UNDEF)
|
||||
@ -320,11 +320,12 @@ static int tune_sat(struct dddvb_fe *fe)
|
||||
} else {
|
||||
uint32_t input = lnb;
|
||||
|
||||
if (input != DDDVB_UNDEF)
|
||||
input = 3 & (input >> 6);
|
||||
//if (input != DDDVB_UNDEF)
|
||||
// input = 3 & (input >> 6);
|
||||
//set_property(fe->fd, DTV_INPUT, 3 & (lnb >> 6));
|
||||
diseqc(fe->fd, lnb, fe->param.param[PARAM_POL], hi);
|
||||
set_fe_input(fe, freq, fe->param.param[PARAM_SR], ds, input);
|
||||
//set_fe_input(fe, freq, fe->param.param[PARAM_SR], ds, input);
|
||||
set_fe_input(fe, freq, fe->param.param[PARAM_SR], ds, ~(0U));
|
||||
}
|
||||
}
|
||||
|
||||
@ -509,6 +510,32 @@ static int tune_isdbt(struct dddvb_fe *fe)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tune_isdbs(struct dddvb_fe *fe)
|
||||
{
|
||||
struct dtv_property p[] = {
|
||||
{ .cmd = DTV_CLEAR },
|
||||
{ .cmd = DTV_FREQUENCY, .u.data = fe->param.param[PARAM_FREQ]},
|
||||
//{ .cmd = DTV_SYMBOL_RATE, .u.data = fe->param.param[PARAM_SR] },
|
||||
//{ .cmd = DTV_TUNE },
|
||||
};
|
||||
struct dtv_properties c;
|
||||
int ret;
|
||||
|
||||
set_property(fe->fd, DTV_DELIVERY_SYSTEM, SYS_ISDBS);
|
||||
|
||||
c.num = ARRAY_SIZE(p);
|
||||
c.props = p;
|
||||
ret = ioctl(fe->fd, FE_SET_PROPERTY, &c);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "FE_SET_PROPERTY returned %d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
if (fe->param.param[PARAM_ISI] != DDDVB_UNDEF)
|
||||
set_property(fe->fd, DTV_STREAM_ID, fe->param.param[PARAM_ISI]);
|
||||
set_property(fe->fd, DTV_TUNE, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tune(struct dddvb_fe *fe)
|
||||
{
|
||||
int ret;
|
||||
@ -537,6 +564,9 @@ static int tune(struct dddvb_fe *fe)
|
||||
case SYS_ISDBT:
|
||||
ret = tune_isdbt(fe);
|
||||
break;
|
||||
case SYS_ISDBS:
|
||||
ret = tune_isdbs(fe);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -678,7 +708,7 @@ void dddvb_fe_handle(struct dddvb_fe *fe)
|
||||
} else {
|
||||
max = 1;
|
||||
nolock++;
|
||||
if (nolock > 100)
|
||||
if (nolock > 10)
|
||||
fe->tune = 1;
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user