octopro fixes

This commit is contained in:
Ralph Metzler 2016-05-02 16:27:32 +02:00
parent 5633c2f79d
commit 1b0df5fcfa
10 changed files with 523 additions and 442 deletions

View File

@ -1,7 +1,7 @@
/*
* ddbridge-core.c: Digital Devices bridge core functions
*
* Copyright (C) 2010-2015 Digital Devices GmbH
* Copyright (C) 2010-2016 Digital Devices GmbH
* Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de>
*
@ -54,7 +54,7 @@ static int xo2_speed = 2;
module_param(xo2_speed, int, 0444);
MODULE_PARM_DESC(xo2_speed, "default transfer speed for xo2 based duoflex, 0=55,1=75,2=90,3=104 MBit/s, default=2, use attribute to change for individual cards");
#ifdef MACH_OCTOPRO
#ifdef __arm__
static int alt_dma = 1;
#else
static int alt_dma;
@ -76,18 +76,220 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
#include "ddbridge-ns.c"
static void ddb_set_dma_table(struct ddb *dev, struct ddb_dma *dma)
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static struct ddb_regset octopus_mod_odma = {
.base = 0x300,
.num = 0x0a,
.size = 0x10,
};
static struct ddb_regset octopus_mod_odma_buf = {
.base = 0x2000,
.num = 0x0a,
.size = 0x100,
};
/****************************************************************************/
static struct ddb_regset octopus_input = {
.base = 0x200,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_output = {
.base = 0x280,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_idma = {
.base = 0x300,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_idma_buf = {
.base = 0x2000,
.num = 0x08,
.size = 0x100,
};
static struct ddb_regset octopus_odma = {
.base = 0x380,
.num = 0x04,
.size = 0x10,
};
static struct ddb_regset octopus_odma_buf = {
.base = 0x2800,
.num = 0x04,
.size = 0x100,
};
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_regset octopro_input = {
.base = 0x400,
.num = 0x14,
.size = 0x10,
};
static struct ddb_regset octopro_output = {
.base = 0x600,
.num = 0x0a,
.size = 0x10,
};
static struct ddb_regset octopro_idma = {
.base = 0x800,
.num = 0x40,
.size = 0x10,
};
static struct ddb_regset octopro_idma_buf = {
.base = 0x4000,
.num = 0x40,
.size = 0x100,
};
static struct ddb_regset octopro_odma = {
.base = 0xc00,
.num = 0x20,
.size = 0x10,
};
static struct ddb_regset octopro_odma_buf = {
.base = 0x8000,
.num = 0x20,
.size = 0x100,
};
static struct ddb_regset octopro_i2c = {
.base = 0x200,
.num = 0x0a,
.size = 0x20,
};
static struct ddb_regset octopro_i2c_buf = {
.base = 0x2000,
.num = 0x0a,
.size = 0x200,
};
static struct ddb_regset octopro_gtl = {
.base = 0xe00,
.num = 0x03,
.size = 0x40,
};
/****************************************************************************/
/****************************************************************************/
static struct ddb_regmap octopus_map = {
.irq_version = 1,
.irq_base_i2c = 0,
.irq_base_idma = 8,
.irq_base_odma = 16,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.idma = &octopus_idma,
.idma_buf = &octopus_idma_buf,
.odma = &octopus_odma,
.odma_buf = &octopus_odma_buf,
.input = &octopus_input,
.output = &octopus_output,
};
static struct ddb_regmap octopro_map = {
.irq_version = 2,
.irq_base_i2c = 32,
.irq_base_idma = 64,
.irq_base_odma = 128,
.irq_base_gtl = 8,
.i2c = &octopro_i2c,
.i2c_buf = &octopro_i2c_buf,
.idma = &octopro_idma,
.idma_buf = &octopro_idma_buf,
.odma = &octopro_odma,
.odma_buf = &octopro_odma_buf,
.input = &octopro_input,
.output = &octopro_output,
.gtl = &octopro_gtl,
};
static struct ddb_regset octopus_mod_channel = {
.base = 0x400,
.num = 0x0c,
.size = 0x40,
};
static struct ddb_regmap octopus_mod_map = {
.irq_version = 1,
.irq_base_odma = 8,
.output = &octopus_output,
.odma = &octopus_mod_odma,
.odma_buf = &octopus_mod_odma_buf,
.channel = &octopus_mod_channel,
};
/****************************************************************************/
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_ct_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX CT8",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
};
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/
static void ddb_set_dma_table(struct ddb_io *io)
{
u32 i, base;
struct ddb *dev = io->port->dev;
struct ddb_dma *dma = io->dma;
u32 i;
u64 mem;
if (!dma)
return;
base = DMA_BASE_ADDRESS_TABLE + dma->nr * 0x100;
for (i = 0; i < dma->num; i++) {
mem = dma->pbuf[i];
ddbwritel(dev, mem & 0xffffffff, base + i * 8);
ddbwritel(dev, mem >> 32, base + i * 8 + 4);
ddbwritel(dev, mem & 0xffffffff, dma->bufregs + i * 8);
ddbwritel(dev, mem >> 32, dma->bufregs + i * 8 + 4);
}
dma->bufval = (dma->div << 16) |
((dma->num & 0x1f) << 11) |
@ -97,11 +299,15 @@ static void ddb_set_dma_table(struct ddb *dev, struct ddb_dma *dma)
static void ddb_set_dma_tables(struct ddb *dev)
{
u32 i;
for (i = 0; i < dev->link[0].info->port_num * 2; i++)
ddb_set_dma_table(dev, dev->input[i].dma);
for (i = 0; i < dev->link[0].info->port_num; i++)
ddb_set_dma_table(dev, dev->output[i].dma);
for (i = 0; i < DDB_MAX_PORT; i++) {
if (dev->port[i].input[0])
ddb_set_dma_table(dev->port[i].input[0]);
if (dev->port[i].input[1])
ddb_set_dma_table(dev->port[i].input[1]);
if (dev->port[i].output)
ddb_set_dma_table(dev->port[i].output);
}
}
@ -117,7 +323,7 @@ static void ddb_redirect_dma(struct ddb *dev,
u64 mem;
sdma->bufval = ddma->bufval;
base = DMA_BASE_ADDRESS_TABLE + sdma->nr * 0x100;
base = sdma->bufregs;
for (i = 0; i < ddma->num; i++) {
mem = ddma->pbuf[i];
ddbwritel(dev, mem & 0xffffffff, base + i * 8);
@ -151,7 +357,7 @@ static int ddb_unredirect(struct ddb_port *port)
oredi->dma, iredo->dma);
}
port->input[0]->redo = 0;
ddb_set_dma_table(port->dev, port->input[0]->dma);
ddb_set_dma_table(port->input[0]);
}
oredi->redi = iredi;
port->input[0]->redi = 0;
@ -159,7 +365,7 @@ static int ddb_unredirect(struct ddb_port *port)
oredi->redo = 0;
port->output->redi = 0;
ddb_set_dma_table(oredi->port->dev, oredi->dma);
ddb_set_dma_table(oredi);
done:
mutex_unlock(&redirect_lock);
return 0;
@ -339,33 +545,33 @@ static void ddb_output_start(struct ddb_output *output)
output->dma->cbuf = 0;
output->dma->coff = 0;
output->dma->stat = 0;
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma->nr));
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma));
}
if (output->port->class == DDB_PORT_MOD)
ddbridge_mod_output_start(output);
else {
ddbwritel(dev, 0, TS_OUTPUT_CONTROL(output->nr));
ddbwritel(dev, 2, TS_OUTPUT_CONTROL(output->nr));
ddbwritel(dev, 0, TS_OUTPUT_CONTROL(output->nr));
ddbwritel(dev, 0x3c, TS_OUTPUT_CONTROL(output->nr));
ddbwritel(dev, con2, TS_OUTPUT_CONTROL2(output->nr));
ddbwritel(dev, 0, TS_CONTROL(output));
ddbwritel(dev, 2, TS_CONTROL(output));
ddbwritel(dev, 0, TS_CONTROL(output));
ddbwritel(dev, 0x3c, TS_CONTROL(output));
ddbwritel(dev, con2, TS_CONTROL2(output));
}
if (output->dma) {
ddbwritel(dev, output->dma->bufval,
DMA_BUFFER_SIZE(output->dma->nr));
ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma->nr));
DMA_BUFFER_SIZE(output->dma));
ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma));
ddbwritel(dev, 1, DMA_BASE_READ);
ddbwritel(dev, 3, DMA_BUFFER_CONTROL(output->dma->nr));
ddbwritel(dev, 3, DMA_BUFFER_CONTROL(output->dma));
}
if (output->port->class != DDB_PORT_MOD) {
if (output->port->input[0]->port->class == DDB_PORT_LOOP)
/*ddbwritel(dev, 0x15, TS_OUTPUT_CONTROL(output->nr));
/*ddbwritel(dev, 0x15, TS_CONTROL(output));
ddbwritel(dev, 0x45,
TS_OUTPUT_CONTROL(output->nr));*/
TS_CONTROL(output));*/
ddbwritel(dev, (1 << 13) | 0x15,
TS_OUTPUT_CONTROL(output->nr));
TS_CONTROL(output));
else
ddbwritel(dev, 0x11d, TS_OUTPUT_CONTROL(output->nr));
ddbwritel(dev, 0x11d, TS_CONTROL(output));
}
if (output->dma) {
output->dma->running = 1;
@ -382,9 +588,9 @@ static void ddb_output_stop(struct ddb_output *output)
if (output->port->class == DDB_PORT_MOD)
ddbridge_mod_output_stop(output);
else
ddbwritel(dev, 0, TS_OUTPUT_CONTROL(output->nr));
ddbwritel(dev, 0, TS_CONTROL(output));
if (output->dma) {
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma->nr));
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(output->dma));
output->dma->running = 0;
spin_unlock_irq(&output->dma->lock);
}
@ -397,9 +603,9 @@ static void ddb_input_stop(struct ddb_input *input)
if (input->dma)
spin_lock_irq(&input->dma->lock);
ddbwritel(dev, 0, tag | TS_INPUT_CONTROL(input->nr));
ddbwritel(dev, 0, tag | TS_CONTROL(input));
if (input->dma) {
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma->nr));
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma));
input->dma->running = 0;
spin_unlock_irq(&input->dma->lock);
}
@ -410,39 +616,36 @@ static void ddb_input_stop(struct ddb_input *input)
static void ddb_input_start(struct ddb_input *input)
{
struct ddb *dev = input->port->dev;
u32 tsctrl = TS_INPUT_BASE + input->nr * 0x10;
u32 tsctrl2 = tsctrl + 4;
u32 tag = DDB_LINK_TAG(input->port->lnr);
if (input->dma) {
spin_lock_irq(&input->dma->lock);
input->dma->cbuf = 0;
input->dma->coff = 0;
input->dma->stat = 0;
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma->nr));
ddbwritel(dev, 0, DMA_BUFFER_CONTROL(input->dma));
}
//ddbwritel(dev, 0, tag | TS_INPUT_CONTROL2(input->nr));
ddbwritel(dev, 0, tag | TS_INPUT_CONTROL(input->nr));
ddbwritel(dev, 2, tag | TS_INPUT_CONTROL(input->nr));
ddbwritel(dev, 0, tag | TS_INPUT_CONTROL(input->nr));
ddbwritel(dev, 0, TS_CONTROL(input));
ddbwritel(dev, 2, TS_CONTROL(input));
ddbwritel(dev, 0, TS_CONTROL(input));
if (input->dma) {
ddbwritel(dev, input->dma->bufval,
DMA_BUFFER_SIZE(input->dma->nr));
ddbwritel(dev, 0, DMA_BUFFER_ACK(input->dma->nr));
DMA_BUFFER_SIZE(input->dma));
ddbwritel(dev, 0, DMA_BUFFER_ACK(input->dma));
ddbwritel(dev, 1, DMA_BASE_WRITE);
ddbwritel(dev, 3, DMA_BUFFER_CONTROL(input->dma->nr));
ddbwritel(dev, 3, DMA_BUFFER_CONTROL(input->dma));
}
if (dev->link[0].info->type == DDB_OCTONET)
ddbwritel(dev, 0x01, tag | TS_INPUT_CONTROL(input->nr));
ddbwritel(dev, 0x01, TS_CONTROL(input));
else
ddbwritel(dev, 0x09, tag | TS_INPUT_CONTROL(input->nr));
ddbwritel(dev, 0x09, TS_CONTROL(input));
if (input->dma) {
input->dma->running = 1;
spin_unlock_irq(&input->dma->lock);
}
/*printk("input_start %u.%u.%u\n",
dev->nr, input->port->lnr, input->nr); */
pr_info("input_start %u.%u.%u\n",
dev->nr, input->port->lnr, input->nr);
pr_info("dmaregs = %08x\n", input->dma->regs);
}
@ -587,7 +790,7 @@ static ssize_t ddb_output_write(struct ddb_output *output,
ddbwritel(dev,
(output->dma->cbuf << 11) |
(output->dma->coff >> 7),
DMA_BUFFER_ACK(output->dma->nr));
DMA_BUFFER_ACK(output->dma));
}
return count - left;
}
@ -597,7 +800,7 @@ static u32 ddb_input_free_bytes(struct ddb_input *input)
{
struct ddb *dev = input->port->dev;
u32 idx, off, stat = input->dma->stat;
u32 ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(input->dma->nr));
u32 ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(input->dma));
idx = (stat >> 11) & 0x1f;
off = (stat & 0x7ff) << 7;
@ -671,14 +874,14 @@ static u32 ddb_input_avail(struct ddb_input *input)
{
struct ddb *dev = input->port->dev;
u32 idx, off, stat = input->dma->stat;
u32 ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(input->dma->nr));
u32 ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(input->dma));
idx = (stat >> 11) & 0x1f;
off = (stat & 0x7ff) << 7;
if (ctrl & 4) {
pr_err("IA %d %d %08x\n", idx, off, ctrl);
ddbwritel(dev, stat, DMA_BUFFER_ACK(input->dma->nr));
ddbwritel(dev, stat, DMA_BUFFER_ACK(input->dma));
return 0;
}
if (input->dma->cbuf != idx)
@ -720,7 +923,7 @@ static size_t ddb_input_read(struct ddb_input *input,
left -= free;
ddbwritel(dev,
(input->dma->cbuf << 11) | (input->dma->coff >> 7),
DMA_BUFFER_ACK(input->dma->nr));
DMA_BUFFER_ACK(input->dma));
}
return count;
}
@ -926,20 +1129,6 @@ static struct dvb_device dvbdev_mod = {
.fops = &mod_fops,
};
#if 0
static struct ddb_input *fe2input(struct ddb *dev, struct dvb_frontend *fe)
{
int i;
for (i = 0; i < dev->link[0].info->port_num * 2; i++) {
if (dev->input[i].fe == fe)
return &dev->input[i];
}
return NULL;
}
#endif
static int locked_gate_ctrl(struct dvb_frontend *fe, int enable)
{
struct ddb_input *input = fe->sec_priv;
@ -2797,7 +2986,7 @@ static void input_write_output(struct ddb_input *input,
struct ddb_output *output)
{
ddbwritel(output->port->dev,
input->dma->stat, DMA_BUFFER_ACK(output->dma->nr));
input->dma->stat, DMA_BUFFER_ACK(output->dma));
output->dma->cbuf = (input->dma->stat >> 11) & 0x1f;
output->dma->coff = (input->dma->stat & 0x7ff) << 7;
}
@ -2806,7 +2995,7 @@ static void output_ack_input(struct ddb_output *output,
struct ddb_input *input)
{
ddbwritel(input->port->dev,
output->dma->stat, DMA_BUFFER_ACK(input->dma->nr));
output->dma->stat, DMA_BUFFER_ACK(input->dma));
}
static void input_write_dvb(struct ddb_input *input,
@ -2833,15 +3022,20 @@ static void input_write_dvb(struct ddb_input *input,
if (alt_dma)
dma_sync_single_for_cpu(dev->dev, dma2->pbuf[dma->cbuf],
dma2->size, DMA_FROM_DEVICE);
#if 0
pr_info("%02x %02x %02x %02x \n",
dma2->vbuf[dma->cbuf][0], dma2->vbuf[dma->cbuf][1],
dma2->vbuf[dma->cbuf][2], dma2->vbuf[dma->cbuf][3]);
#endif
dvb_dmx_swfilter_packets(&dvb->demux,
dma2->vbuf[dma->cbuf],
dma2->size / 188);
dma->cbuf = (dma->cbuf + 1) % dma2->num;
if (ack)
ddbwritel(dev, (dma->cbuf << 11),
DMA_BUFFER_ACK(dma->nr));
dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma->nr));
dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma->nr));
DMA_BUFFER_ACK(dma));
dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma));
dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma));
}
}
@ -2864,8 +3058,8 @@ static void input_tasklet(unsigned long data)
spin_unlock_irqrestore(&dma->lock, flags);
return;
}
dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma->nr));
dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma->nr));
dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma));
dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma));
#if 0
if (4 & dma->ctrl)
@ -2912,8 +3106,8 @@ static void output_handler(unsigned long data)
spin_unlock(&dma->lock);
return;
}
dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma->nr));
dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma->nr));
dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma));
dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma));
if (output->redi)
output_ack_input(output, output->redi);
wake_up(&dma->wq);
@ -2925,17 +3119,32 @@ static void output_handler(unsigned long data)
/****************************************************************************/
static void ddb_dma_init(struct ddb_dma *dma, int nr, void *io, int out)
static struct ddb_regmap *io_regmap(struct ddb_io *io, int link)
{
#ifndef DDB_USE_WORK
unsigned long priv = (unsigned long) io;
#endif
struct ddb_info *info;
if (link)
info = io->port->dev->link[io->port->lnr].info;
else
info = io->port->dev->link[0].info;
if (!info)
return NULL;
return info->regmap;
}
static void ddb_dma_init(struct ddb_io *io, int nr, int out)
{
struct ddb_dma *dma;
struct ddb_regmap *rm = io_regmap(io, 0);
dma = out ? &io->port->dev->odma[nr] : &io->port->dev->idma[nr];
io->dma = dma;
dma->io = io;
dma->nr = nr;
spin_lock_init(&dma->lock);
init_waitqueue_head(&dma->wq);
if (out) {
dma->regs = rm->odma->base + rm->odma->size * nr;
dma->bufregs = rm->odma_buf->base + rm->odma_buf->size * nr;
dma->num = OUTPUT_DMA_BUFS;
dma->size = OUTPUT_DMA_SIZE;
dma->div = OUTPUT_DMA_IRQ_DIV;
@ -2943,63 +3152,66 @@ static void ddb_dma_init(struct ddb_dma *dma, int nr, void *io, int out)
#ifdef DDB_USE_WORK
INIT_WORK(&dma->work, input_work);
#else
tasklet_init(&dma->tasklet, input_tasklet, priv);
tasklet_init(&dma->tasklet, input_tasklet, (unsigned long) io);
#endif
dma->regs = rm->idma->base + rm->idma->size * nr;
dma->bufregs = rm->idma_buf->base + rm->idma_buf->size * nr;
dma->num = INPUT_DMA_BUFS;
dma->size = INPUT_DMA_SIZE;
dma->div = INPUT_DMA_IRQ_DIV;
}
ddbwritel(io->port->dev, 0, DMA_BUFFER_ACK(dma));
pr_info("init link %u, io %u, dma %u, dmaregs %08x bufregs %08x\n",
io->port->lnr, io->nr, nr, dma->regs, dma->bufregs);
}
static void ddb_input_init(struct ddb_port *port, int nr, int pnr,
int dma_nr, int anr)
static void ddb_input_init(struct ddb_port *port, int nr, int pnr, int anr)
{
struct ddb *dev = port->dev;
struct ddb_input *input = &dev->input[anr];
struct ddb_regmap *rm;
if (dev->has_dma) {
dev->handler[0][dma_nr + 8] = input_handler;
dev->handler_data[0][dma_nr + 8] = (unsigned long) input;
}
port->input[pnr] = input;
input->nr = nr;
input->port = port;
rm = io_regmap(input, 1);
input->regs = DDB_LINK_TAG(port->lnr) |
(rm->input->base + rm->input->size * nr);
pr_info("init link %u, input %u, regs %08x\n", port->lnr, nr, input->regs);
if (dev->has_dma) {
input->dma = &dev->dma[dma_nr];
ddb_dma_init(input->dma, dma_nr, (void *) input, 0);
u32 base = rm->irq_base_idma;
u32 dma_nr = nr;
if (port->lnr)
dma_nr += 32 + (port->lnr - 1) * 8;
pr_info("init link %u, input %u, handler %u\n", port->lnr, nr, dma_nr + base);
dev->handler[0][dma_nr + base] = input_handler;
dev->handler_data[0][dma_nr + base] = (unsigned long) input;
ddb_dma_init(input, dma_nr, 0);
}
ddbwritel(dev, 0, TS_INPUT_CONTROL(nr));
ddbwritel(dev, 2, TS_INPUT_CONTROL(nr));
ddbwritel(dev, 0, TS_INPUT_CONTROL(nr));
if (input->dma)
ddbwritel(dev, 0, DMA_BUFFER_ACK(input->dma->nr));
}
static void ddb_output_init(struct ddb_port *port, int nr, int dma_nr)
static void ddb_output_init(struct ddb_port *port, int nr)
{
struct ddb *dev = port->dev;
struct ddb_output *output = &dev->output[nr];
struct ddb_regmap *rm;
if (dev->has_dma) {
dev->handler[0][dma_nr + 8] = output_handler;
dev->handler_data[0][dma_nr + 8] = (unsigned long) output;
}
port->output = output;
output->nr = nr;
output->port = port;
rm = io_regmap(output, 1);
output->regs = DDB_LINK_TAG(port->lnr) |
(rm->output->base + rm->output->size * nr);
pr_info("init link %u, output %u, regs %08x\n", port->lnr, nr, output->regs);
if (dev->has_dma) {
output->dma = &dev->dma[dma_nr];
ddb_dma_init(output->dma, dma_nr, (void *) output, 1);
u32 base = rm->irq_base_odma;
dev->handler[0][nr + base] = output_handler;
dev->handler_data[0][nr + base] = (unsigned long) output;
ddb_dma_init(output, nr, 1);
}
if (output->port->class == DDB_PORT_MOD) {
/*ddbwritel(dev, 0, CHANNEL_CONTROL(output->nr));*/
} else {
ddbwritel(dev, 0, TS_OUTPUT_CONTROL(nr));
ddbwritel(dev, 2, TS_OUTPUT_CONTROL(nr));
ddbwritel(dev, 0, TS_OUTPUT_CONTROL(nr));
}
if (output->dma)
ddbwritel(dev, 0, DMA_BUFFER_ACK(output->dma->nr));
}
static int ddb_port_match_i2c(struct ddb_port *port)
@ -3017,9 +3229,23 @@ static int ddb_port_match_i2c(struct ddb_port *port)
return 0;
}
static int ddb_port_match_link_i2c(struct ddb_port *port)
{
struct ddb *dev = port->dev;
u32 i;
for (i = 0; i < dev->i2c_num; i++) {
if (dev->i2c[i].link == port->lnr) {
port->i2c = &dev->i2c[i];
return 1;
}
}
return 0;
}
static void ddb_ports_init(struct ddb *dev)
{
u32 i, l, p, li2c;
u32 i, l, p;
struct ddb_port *port;
struct ddb_info *info;
struct ddb_regmap *rm;
@ -3031,9 +3257,6 @@ static void ddb_ports_init(struct ddb *dev)
rm = info->regmap;
if (!rm)
continue;
for (li2c = 0; li2c < dev->i2c_num; li2c++)
if (dev->i2c[li2c].link == l)
break;
for (i = 0; i < info->port_num; i++, p++) {
port = &dev->port[p];
port->dev = dev;
@ -3043,12 +3266,9 @@ static void ddb_ports_init(struct ddb *dev)
port->gap = 4;
port->obr = ci_bitrate;
mutex_init(&port->i2c_gate_lock);
if (!ddb_port_match_i2c(port)) {
if (!ddb_port_match_i2c(port))
if (info->type == DDB_OCTOPUS_MAX)
port->i2c = &dev->i2c[li2c];
}
ddb_port_match_link_i2c(port);
ddb_port_probe(port);
port->dvb[0].adap = &dev->adap[2 * p];
@ -3061,52 +3281,48 @@ static void ddb_ports_init(struct ddb *dev)
port->name = "DuoFlex CI_B";
port->i2c = dev->port[p - 1].i2c;
}
pr_info("Port %u: Link %u, Link Port %u (TAB %u): %s\n",
port->pnr, port->lnr, port->nr,
port->nr + 1, port->name);
if (port->class == DDB_PORT_CI &&
port->type == DDB_CI_EXTERNAL_XO2) {
ddb_input_init(port, 2 * i, 0, 2 * i, 2 * i);
ddb_output_init(port, i, i + 8);
ddb_input_init(port, 2 * i, 0, 2 * i);
ddb_output_init(port, i);
continue;
}
if (port->class == DDB_PORT_CI &&
port->type == DDB_CI_EXTERNAL_XO2_B) {
ddb_input_init(port, 2 * i - 1, 0,
2 * i - 1, 2 * i - 1);
ddb_output_init(port, i, i + 8);
ddb_input_init(port, 2 * i - 1, 0, 2 * i - 1);
ddb_output_init(port, i);
continue;
}
if (port->class == DDB_PORT_NONE)
continue;
switch (dev->link[l].info->type) {
case DDB_OCTOPUS_CI:
if (i >= 2) {
ddb_input_init(port, 2 + i, 0,
2 + i, 2 + i);
ddb_input_init(port, 4 + i, 1,
4 + i, 4 + i);
ddb_output_init(port, i, i + 8);
ddb_input_init(port, 2 + i, 0, 2 + i);
ddb_input_init(port, 4 + i, 1, 4 + i);
ddb_output_init(port, i);
break;
} /* fallthrough */
case DDB_OCTONET:
case DDB_OCTOPUS:
case DDB_OCTOPRO:
ddb_input_init(port, 2 * i, 0, 2 * i, 2 * i);
ddb_input_init(port, 2 * i + 1, 1,
2 * i + 1, 2 * i + 1);
ddb_output_init(port, i, i + 8);
ddb_input_init(port, 2 * i, 0, 2 * i);
ddb_input_init(port, 2 * i + 1, 1, 2 * i + 1);
ddb_output_init(port, i);
break;
case DDB_OCTOPUS_MAX:
case DDB_OCTOPUS_MAX_CT:
ddb_input_init(port, 2 * i, 0, 2 * i, 2 * p);
ddb_input_init(port, 2 * i + 1,
1, 2 * i + 1, 2 * p + 1);
ddb_input_init(port, 2 * i, 0, 2 * p);
ddb_input_init(port, 2 * i + 1, 1, 2 * p + 1);
break;
case DDB_MOD:
ddb_output_init(port, i, i);
ddb_output_init(port, i);
dev->handler[0][i + 18] =
ddbridge_mod_rate_handler;
dev->handler_data[0][i + 18] =
@ -3279,24 +3495,53 @@ static irqreturn_t irq_handler(int irq, void *dev_id)
static irqreturn_t irq_handle_v2_n(struct ddb *dev, u32 n)
{
u32 reg = INTERRUPT_V2_STATUS_1 + 4 * n;
u32 reg = INTERRUPT_V2_STATUS + 4 * n;
u32 s = ddbreadl(dev, reg);
u32 off = n * 32;
//pr_info("irq_handle_v2_%u s=%08x\n", n, s);
if (!s)
return IRQ_NONE;
ddbwritel(dev, s, reg);
if ((s & 0x000000ff)) {
IRQ_HANDLE(0 + off);
IRQ_HANDLE(1 + off);
IRQ_HANDLE(2 + off);
IRQ_HANDLE(3 + off);
IRQ_HANDLE(4 + off);
IRQ_HANDLE(5 + off);
IRQ_HANDLE(6 + off);
IRQ_HANDLE(7 + off);
IRQ_HANDLE( 0 + off);
IRQ_HANDLE( 1 + off);
IRQ_HANDLE( 2 + off);
IRQ_HANDLE( 3 + off);
IRQ_HANDLE( 4 + off);
IRQ_HANDLE( 5 + off);
IRQ_HANDLE( 6 + off);
IRQ_HANDLE( 7 + off);
}
if ((s & 0x0000ff00)) {
IRQ_HANDLE( 8 + off);
IRQ_HANDLE( 9 + off);
IRQ_HANDLE(10 + off);
IRQ_HANDLE(11 + off);
IRQ_HANDLE(12 + off);
IRQ_HANDLE(13 + off);
IRQ_HANDLE(14 + off);
IRQ_HANDLE(15 + off);
}
if ((s & 0x00ff0000)) {
IRQ_HANDLE(16 + off);
IRQ_HANDLE(17 + off);
IRQ_HANDLE(18 + off);
IRQ_HANDLE(19 + off);
IRQ_HANDLE(20 + off);
IRQ_HANDLE(21 + off);
IRQ_HANDLE(22 + off);
IRQ_HANDLE(23 + off);
}
if ((s & 0xff000000)) {
IRQ_HANDLE(24 + off);
IRQ_HANDLE(25 + off);
IRQ_HANDLE(26 + off);
IRQ_HANDLE(27 + off);
IRQ_HANDLE(28 + off);
IRQ_HANDLE(29 + off);
IRQ_HANDLE(30 + off);
IRQ_HANDLE(31 + off);
}
return IRQ_HANDLED;
}
@ -3310,11 +3555,21 @@ static irqreturn_t irq_handler_v2(int irq, void *dev_id)
if (!s)
return IRQ_NONE;
do {
if (s & 0x80000000)
if (s & 0x80)
return IRQ_NONE;
//pr_info("irq_handler_v2 s=%08x\n", s);
ddbwritel(dev, s, INTERRUPT_V2_STATUS);
if (s & 0x00000001)
irq_handle_v2_n(dev, 0);
irq_handle_v2_n(dev, 1);
if (s & 0x00000002) {
//pr_info("irq_handler_v2 s=%08x\n", s);
irq_handle_v2_n(dev, 2);
}
if (s & 0x00000004)
irq_handle_v2_n(dev, 3);
IRQ_HANDLE(8);
IRQ_HANDLE(9);
IRQ_HANDLE(10);
IRQ_HANDLE(11);
} while ((s = 0xffff & ddbreadl(dev, INTERRUPT_V2_STATUS)));
return ret;
@ -4592,68 +4847,12 @@ static void gtl_irq_handler(unsigned long priv)
#endif
}
static struct ddb_regset octopus_max_gtl_i2c = {
.base = 0x80,
.num = 0x01,
.size = 0x20,
};
static struct ddb_regset octopus_max_gtl_i2c_buf = {
.base = 0x1000,
.num = 0x01,
.size = 0x200,
};
static struct ddb_regmap octopus_max_gtl_map = {
.i2c = &octopus_max_gtl_i2c,
.i2c_buf = &octopus_max_gtl_i2c_buf,
};
static struct ddb_info octopus_max_gtl = {
.type = DDB_OCTOPUS_MAX,
.name = "Digital Devices Octopus MAX GTL",
.regmap = &octopus_max_gtl_map,
.port_num = 4,
.i2c_mask = 0x01,
.board_control = 1,
};
static struct ddb_regset octopus_maxct_gtl_i2c = {
.base = 0x80,
.num = 0x04,
.size = 0x20,
};
static struct ddb_regset octopus_maxct_gtl_i2c_buf = {
.base = 0x1000,
.num = 0x04,
.size = 0x200,
};
static struct ddb_regmap octopus_maxct_gtl_map = {
.i2c = &octopus_maxct_gtl_i2c,
.i2c_buf = &octopus_maxct_gtl_i2c_buf,
};
static struct ddb_info octopus_ct_gtl = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices Octopus MAX CT GTL",
.regmap = &octopus_maxct_gtl_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0xff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
};
static int ddb_gtl_init_link(struct ddb *dev, u32 l)
{
struct ddb_link *link = &dev->link[l];
u32 regs = dev->link[0].info->regmap->gtl->base +
(l - 1) * dev->link[0].info->regmap->gtl->size;
u32 id;
u32 id, base = dev->link[0].info->regmap->irq_base_gtl;
pr_info("Checking GT link %u: regs = %08x\n", l, regs);
@ -4683,10 +4882,10 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l)
id = ddbreadl(dev, DDB_LINK_TAG(l) | 8);
switch (id) {
case 0x0007dd01:
link->info = &octopus_max_gtl;
link->info = &ddb_s2_48;
break;
case 0x0008dd01:
link->info = &octopus_ct_gtl;
link->info = &ddb_ct_8;
break;
default:
pr_info("DDBridge: Detected GT link but found invalid ID %08x. You might have to update (flash) the add-on card first.",
@ -4697,8 +4896,8 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l)
ddbwritel(dev, 1, 0x1a0);
dev->handler_data[0][11] = (unsigned long) link;
dev->handler[0][11] = gtl_irq_handler;
dev->handler_data[0][base + l] = (unsigned long) link;
dev->handler[0][base + l] = gtl_irq_handler;
pr_info("GTL %s\n", dev->link[l].info->name);
pr_info("GTL HW %08x REGMAP %08x\n",
@ -4716,11 +4915,10 @@ static int ddb_gtl_init_link(struct ddb *dev, u32 l)
static int ddb_gtl_init(struct ddb *dev)
{
u32 l;
dev->handler_data[0][10] = (unsigned long) dev;
dev->handler[0][10] = gtl_link_handler;
u32 l, base = dev->link[0].info->regmap->irq_base_gtl;
dev->handler_data[0][base] = (unsigned long) dev;
dev->handler[0][base] = gtl_link_handler;
for (l = 1; l < dev->link[0].info->regmap->gtl->num + 1; l++)
ddb_gtl_init_link(dev, l);
return 0;
@ -4806,3 +5004,24 @@ fail:
pr_err("fail1\n");
return -1;
}
static void ddb_reset_io(struct ddb *dev, u32 reg)
{
ddbwritel(dev, 0x00, reg);
ddbwritel(dev, 0x02, reg);
ddbwritel(dev, 0x00, reg);
}
static void ddb_reset_ios(struct ddb *dev)
{
u32 i;
struct ddb_regmap *rm = dev->link[0].info->regmap;
if (rm->input)
for (i = 0; i < rm->input->num; i++)
ddb_reset_io(dev, rm->input->base + i * rm->input->size);
if (rm->output)
for (i = 0; i < rm->output->num; i++)
ddb_reset_io(dev, rm->output->base + i * rm->output->size);
usleep_range(5000, 6000);
}

View File

@ -257,7 +257,7 @@ static int ddb_i2c_add(struct ddb *dev, struct ddb_i2c *i2c,
static int ddb_i2c_init(struct ddb *dev)
{
int stat = 0;
u32 i, j, num = 0, l;
u32 i, j, num = 0, l, base;
struct ddb_i2c *i2c;
struct i2c_adapter *adap;
struct ddb_regmap *regmap;
@ -268,12 +268,13 @@ static int ddb_i2c_init(struct ddb *dev)
regmap = dev->link[l].info->regmap;
if (!regmap || !regmap->i2c)
continue;
base = regmap->irq_base_i2c;
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[l][i] = (unsigned long) i2c;
dev->handler[l][i] = i2c_handler;
dev->handler_data[l][i + base] = (unsigned long) i2c;
dev->handler[l][i + base] = i2c_handler;
stat = ddb_i2c_add(dev, i2c, regmap, l, i, num);
if (stat)
break;

View File

@ -201,10 +201,10 @@ static int ns_set_ci(struct dvbnss *nss, u8 ci)
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));
TS_CONTROL(dev->port[ciport].output));
usleep_range(1, 5);
ddbwritel(dev, (input->port->lnr << 21) | (input->nr << 16) | 0x1d,
TS_OUTPUT_CONTROL(ciport));
TS_CONTROL(dev->port[ciport].output));
dns->fe = dev->port[ciport].input[0];
return 0;
}

View File

@ -1,7 +1,7 @@
/*
* ddbridge-regs.h: Digital Devices PCIe bridge driver
*
* Copyright (C) 2010-2015 Digital Devices GmbH
* Copyright (C) 2010-2016 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
@ -156,15 +156,12 @@
/* ------------------------------------------------------------------------- */
/* I2C Master Controller */
/*#define I2C_BASE (0x80) */
#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)
@ -193,26 +190,17 @@
#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_CONTROL(_io) (_io->regs + 0x00)
#define TS_CONTROL2(_io) (_io->regs + 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 DMA_BUFFER_CONTROL(_dma) (_dma->regs + 0x00)
#define DMA_BUFFER_ACK(_dma) (_dma->regs + 0x04)
#define DMA_BUFFER_CURRENT(_dma) (_dma->regs + 0x08)
#define DMA_BUFFER_SIZE(_dma) (_dma->regs + 0x0c)
/* ------------------------------------------------------------------------- */

View File

@ -59,7 +59,7 @@ static void ddb_unmap(struct ddb *dev)
static void __devexit ddb_irq_disable(struct ddb *dev)
{
if ((dev->link[0].ids.regmapid & 0xffff0000) == 0x00020000) {
if (dev->link[0].info->regmap->irq_version == 2) {
//ddbwritel(dev, 0x00000000, INTERRUPT_V2_CONTROL);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_1);
ddbwritel(dev, 0x00000000, INTERRUPT_V2_ENABLE_2);
@ -131,14 +131,12 @@ static int __devinit ddb_irq_msi(struct ddb *dev, int nr)
if (stat == 0) {
dev->msi = nr;
pr_info("DDBridge: using %d MSI interrupts\n", nr);
}
if (stat == 1)
} else if (stat == 1) {
stat = pci_enable_msi(dev->pdev);
if (stat < 0) {
pr_info("DDBridge: MSI not available.\n");
} else {
dev->msi++;
dev->msi = 1;
}
if (stat < 0)
pr_info("DDBridge: MSI not available.\n");
#endif
}
return stat;
@ -185,7 +183,7 @@ static int __devinit ddb_irq_init(struct ddb *dev)
int stat;
int irq_flag = IRQF_SHARED;
if ((dev->link[0].ids.regmapid & 0xffff0000) == 0x00020000)
if (dev->link[0].info->regmap->irq_version == 2)
return ddb_irq_init2(dev);
ddbwritel(dev, 0x00000000, INTERRUPT_ENABLE);
@ -294,12 +292,8 @@ static int __devinit ddb_probe(struct pci_dev *pdev,
dev->link[0].ids.hwid, dev->link[0].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);
ddb_reset_ios(dev);
}
ddbwritel(dev, 0, DMA_BASE_READ);
if (dev->link[0].info->type != DDB_MOD)
@ -335,134 +329,6 @@ fail:
/****************************************************************************/
/****************************************************************************/
static struct ddb_regset octopus_input = {
.base = 0x200,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_output = {
.base = 0x280,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_idma = {
.base = 0x300,
.num = 0x08,
.size = 0x10,
};
static struct ddb_regset octopus_idma_buf = {
.base = 0x2000,
.num = 0x08,
.size = 0x100,
};
static struct ddb_regset octopus_odma = {
.base = 0x380,
.num = 0x04,
.size = 0x10,
};
static struct ddb_regset octopus_odma_buf = {
.base = 0x2800,
.num = 0x04,
.size = 0x100,
};
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_regset octopro_input = {
.base = 0x400,
.num = 0x14,
.size = 0x10,
};
static struct ddb_regset octopro_output = {
.base = 0x600,
.num = 0x0a,
.size = 0x10,
};
static struct ddb_regset octopro_idma = {
.base = 0x800,
.num = 0x14,
.size = 0x10,
};
static struct ddb_regset octopro_idma_buf = {
.base = 0x4000,
.num = 0x14,
.size = 0x100,
};
static struct ddb_regset octopro_odma = {
.base = 0xa00,
.num = 0x0a,
.size = 0x10,
};
static struct ddb_regset octopro_odma_buf = {
.base = 0x6000,
.num = 0x0a,
.size = 0x100,
};
static struct ddb_regset octopro_i2c = {
.base = 0x200,
.num = 0x0a,
.size = 0x20,
};
static struct ddb_regset octopro_i2c_buf = {
.base = 0x2000,
.num = 0x0a,
.size = 0x200,
};
/****************************************************************************/
/****************************************************************************/
static struct ddb_regmap octopus_map = {
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.idma[0] = &octopus_idma,
.idma_buf[0] = &octopus_idma_buf,
.odma = &octopus_odma,
.odma_buf = &octopus_odma_buf,
};
static struct ddb_regmap octopro_map = {
.i2c = &octopro_i2c,
.i2c_buf = &octopro_i2c_buf,
.idma[0] = &octopro_idma,
.idma_buf[0] = &octopro_idma_buf,
.odma = &octopro_odma,
.odma_buf = &octopro_odma_buf,
};
static struct ddb_regmap octopus_mod_map = {
.odma = &octopus_odma,
.odma_buf = &octopus_odma_buf,
};
/****************************************************************************/
static struct ddb_info ddb_none = {
.type = DDB_NONE,
.name = "unknown Digital Devices PCIe card, install newer driver",
@ -594,26 +460,6 @@ static struct ddb_info ddb_dvbct = {
/****************************************************************************/
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_ct_8 = {
.type = DDB_OCTOPUS_MAX_CT,
.name = "Digital Devices MAX CT8",
.regmap = &octopus_map,
.port_num = 4,
.i2c_mask = 0x0f,
.board_control = 0x0ff,
.board_control_2 = 0xf00,
.ts_quirks = TS_QUIRK_SERIAL,
};
static struct ddb_info ddb_mod = {
.type = DDB_MOD,
.name = "Digital Devices DVB-C modulator",
@ -711,7 +557,7 @@ static __init int module_init_ddbridge(void)
pr_info("Digital Devices PCIE bridge driver "
DDBRIDGE_VERSION
", Copyright (C) 2010-15 Digital Devices GmbH\n");
", Copyright (C) 2010-16 Digital Devices GmbH\n");
if (ddb_class_create() < 0)
return -1;
ddb_wq = create_workqueue("ddbridge");

View File

@ -91,10 +91,10 @@
#include "lnbh25.h"
#include "mxl5xx.h"
#define DDB_MAX_I2C 16
#define DDB_MAX_PORT 22
#define DDB_MAX_INPUT 44
#define DDB_MAX_OUTPUT 24
#define DDB_MAX_I2C 32
#define DDB_MAX_PORT 32
#define DDB_MAX_INPUT 64
#define DDB_MAX_OUTPUT 32
#define DDB_MAX_LINK 4
#define DDB_LINK_SHIFT 28
@ -106,18 +106,17 @@ struct ddb_regset {
u32 size;
};
struct ddb_ports {
u32 base;
u32 num;
u32 size;
};
struct ddb_regmap {
struct ddb_ports *bc;
u32 irq_version;
u32 irq_base_i2c;
u32 irq_base_idma;
u32 irq_base_odma;
u32 irq_base_gtl;
struct ddb_regset *i2c;
struct ddb_regset *i2c_buf;
struct ddb_regset *idma[4];
struct ddb_regset *idma_buf[4];
struct ddb_regset *idma;
struct ddb_regset *idma_buf;
struct ddb_regset *odma;
struct ddb_regset *odma_buf;
@ -125,11 +124,11 @@ struct ddb_regmap {
struct ddb_regset *output;
struct ddb_regset *channel;
struct ddb_regset *ci;
struct ddb_regset *pid_filter;
struct ddb_regset *ns;
//struct ddb_regset *ci;
//struct ddb_regset *pid_filter;
//struct ddb_regset *ns;
struct ddb_regset *gtl;
struct ddb_regset *mdio;
//struct ddb_regset *mdio;
};
struct ddb_ids {
@ -191,7 +190,6 @@ struct ddb_port;
struct ddb_dma {
void *io;
u32 nr;
u32 regs;
u32 bufregs;
@ -424,7 +422,8 @@ struct ddb {
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];
struct ddb_dma idma[DDB_MAX_INPUT];
struct ddb_dma odma[DDB_MAX_OUTPUT];
void (*handler[4][128])(unsigned long);
unsigned long handler_data[4][128];

View File

@ -1,7 +1,7 @@
/*
* octonet.c: Digital Devices network tuner driver
*
* Copyright (C) 2012-15 Digital Devices GmbH
* Copyright (C) 2012-16 Digital Devices GmbH
* Marcus Metzler <mocm@metzlerbros.de>
* Ralph Metzler <rjkm@metzlerbros.de>
*
@ -34,21 +34,16 @@ MODULE_PARM_DESC(adapter_alloc,
#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 = {
.irq_version = 1,
.irq_base_i2c = 0,
.irq_base_idma = 8,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.input = &octopus_input,
.output = &octopus_output,
};
static struct ddb_regset octopus_gtl = {
@ -58,8 +53,16 @@ static struct ddb_regset octopus_gtl = {
};
static struct ddb_regmap octopus_net_gtl = {
.irq_version = 1,
.irq_base_i2c = 0,
.irq_base_idma = 8,
.irq_base_gtl = 10,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.i2c = &octopus_i2c,
.i2c_buf = &octopus_i2c_buf,
.input = &octopus_input,
.output = &octopus_output,
.gtl = &octopus_gtl,
};
@ -185,9 +188,7 @@ static int __init octonet_probe(struct platform_device *pdev)
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);
ddb_reset_ios(dev);
irq = platform_get_irq(dev->pfdev, 0);
if (irq < 0)
@ -236,7 +237,7 @@ static __init int init_octonet(void)
int res;
pr_info("Digital Devices OctopusNet driver " DDBRIDGE_VERSION
", Copyright (C) 2010-15 Digital Devices GmbH\n");
", Copyright (C) 2010-16 Digital Devices GmbH\n");
res = ddb_class_create();
if (res)
return res;

View File

@ -1054,12 +1054,31 @@ static int set_parameters(struct dvb_frontend *fe)
return stat;
}
static int get_frequency_offset(struct stv *state, s32 *off)
{
u8 cfr0, cfr1, cfr2;
s32 derot;
read_reg(state, RSTV0910_P2_CFR2 + state->regoff, &cfr2);
read_reg(state, RSTV0910_P2_CFR2 + state->regoff, &cfr1);
read_reg(state, RSTV0910_P2_CFR2 + state->regoff, &cfr0);
derot = ((u32) cfr2 << 16) | ((u32)cfr1 << 8) | cfr0;
if (derot & (1<<23))
derot |= 0xFF000000;
*off = - (s32) (((s64) derot * (s64) state->base->mclk) >> 24);
pr_info("foff = %d\n", *off);
return 0;
}
static int get_frontend(struct dvb_frontend *fe)
{
struct stv *state = fe->demodulator_priv;
struct dtv_frontend_properties *p = &fe->dtv_property_cache;
u8 tmp;
if (state->ReceiveMode == Mode_DVBS2) {
u32 mc;
enum fe_modulation modcod2mod[0x20] = {
@ -1132,6 +1151,9 @@ static int read_status(struct dvb_frontend *fe, fe_status_t *status)
u32 FECLock = 0;
u16 val;
u32 ber;
s32 foff;
get_frequency_offset(state, &foff);
read_signal_strength(fe, &val);
@ -1446,8 +1468,6 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
int i;
read_regs(state, RSTV0910_P2_AGCIQIN1 + state->regoff, Reg, 2);
//KdPrintEx((MSG_INFO "_%d " __FUNCTION__ " AGCIQIN1 = %02x%02x\n",m_Instance,Reg[0],Reg[1]));
*strength = (((u32) Reg[0]) << 8) | Reg[1];
for (i = 0; i < 5; i += 1) {
@ -1456,7 +1476,6 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
msleep(3);
}
Power /= 5;
bbgain = (465 - Log10x100(Power)) * 10;
if (fe->ops.tuner_ops.get_rf_strength)
@ -1464,7 +1483,7 @@ static int read_signal_strength(struct dvb_frontend *fe, u16 *strength)
else
*strength = 0;
printk("pwr = %d bb = %d str = %u\n", Power, bbgain, *strength);
//printk("pwr = %d bb = %d str = %u\n", Power, bbgain, *strength);
if (bbgain < (s32) *strength)
*strength -= bbgain;
else

View File

@ -26,6 +26,10 @@
#include <linux/compiler.h>
#ifndef __user
#define __user
#endif
typedef enum {
// All functions return -2 on "not open"
OSD_Close=1, // ()

View File

@ -30,6 +30,10 @@
#include <time.h>
#endif
#ifndef __user
#define __user
#endif
typedef enum {
VIDEO_FORMAT_4_3, /* Select 4:3 format */
VIDEO_FORMAT_16_9, /* Select 16:9 format. */