diff --git a/apps/ddinfo.c b/apps/ddinfo.c index 22f08c1..f37c0cb 100644 --- a/apps/ddinfo.c +++ b/apps/ddinfo.c @@ -285,7 +285,6 @@ void print_info(int dev, uint32_t link, uint8_t demod, struct mci_result *res) else printf("Demod Locked: DVB-S2\n"); printf("PLS-Code: %u\n", res->dvbs2_signal_info.pls_code); - mci_bb(dev, link, demod); if (pls >= 250) { pilots = 1; modcod = S2Xrsvd[pls - 250]; @@ -298,6 +297,8 @@ void print_info(int dev, uint32_t link, uint8_t demod, struct mci_result *res) short_frame = pls & 2; modcod = S2ModCods[pls / 4]; } + printf("ModCod: %s\n", modcod); + mci_bb(dev, link, demod); printf("Roll-Off: %s\n", Rolloff[res->dvbs2_signal_info.roll_off & 7]); printf("Pilots: %s\n", pilots ? "On" : "Off"); printf("Frame: %s\n", short_frame ? "Short" : "Normal"); @@ -423,6 +424,8 @@ static char *id2name(uint16_t id) return "MAX SX8 Basic"; case 0x000a: return "MAX M4"; + case 0x0014: + return "MAX CI M2"; default: return " "; } @@ -432,7 +435,7 @@ static int card_info(int ddbnum, int demod) { char ddbname[80]; struct ddb_id ddbid; - int ddb, ret, link, links = 1, i; + int ddb, ret, link, links = 1, i, num=8; struct ddb_id id; sprintf(ddbname, "/dev/ddbridge/card%d", ddbnum); @@ -465,21 +468,19 @@ static int card_info(int ddbnum, int demod) id.hw, id.regmap, (id.hw & 0xff0000) >> 16, (id.hw & 0xffff)); switch (id.device) { case 0x0009: - mci_firmware(ddb, link); - if (demod >= 0) - mci_info(ddb, link, demod); - else { - for (i = 0; i < 8; i++) - mci_info(ddb, link, i); - } + case 0x000b: temp_info(ddb, link); - break; case 0x000a: + case 0x0014: + if (id.device == 0x000a) + num = 4; + if (id.device == 0x0014) + num = 2; mci_firmware(ddb, link); if (demod >= 0) mci_info(ddb, link, demod); else { - for (i = 0; i < 4; i++) + for (i = 0; i < num; i++) mci_info(ddb, link, i); } break; diff --git a/apps/modulator-c.conf b/apps/modulator-c.conf new file mode 100644 index 0000000..eda485c --- /dev/null +++ b/apps/modulator-c.conf @@ -0,0 +1,58 @@ +[output] +# connector = OFF, SMA or F +connector = F +# number of total channels to be used at the same time +# use lower number to have fewer channels but stronger signal per channel +channels = 16 +# unit of power in DBUV or DBM +unit = DBUV +# power output in units of above unit +power = 70.0 + +# define channels: +# channels are frequency slots to which a stream (mod0, mod1 ...) can be assigned +[channels] +# frequency of channel 0, following channels are spaced according to set standard +frequency = 474.0 +# numbers of channels to allocate, starting from frequency below +# this defines 16 channels at 474, 474+8, 474+16, etc. Mhz +channels = 16 +# standard: 0 = generic, 1 = DVB-T 8MHz, 2 = DVB-T 7 MHz, 3 = DVB-T 6 MHz +standard = DVBC_8 + +[streams] +# number of streams depends on the card hardware +# streams correspond to devices mod0, mod1, ... +# channels are defined above in channels section + +standard = DVBC_8 +stream_format = TS +symbol_rate = 6.9 +modulation = qam_dvbc_256 +rolloff = 13 + +channel = 0 +stream = 0 + +channel = 1 +stream = 1 + +channel = 2 +stream = 2 + +channel = 3 +stream = 3 + +channel = 4 +stream = 4 + +channel = 5 +stream = 5 + +channel = 6 +stream = 6 + +symbol_rate = 6.5 +modulation = qam_dvbc_64 +channel = 7 +stream = 7 diff --git a/ddbridge/ddbridge-core.c b/ddbridge/ddbridge-core.c index 0bbaa56..f38ccff 100644 --- a/ddbridge/ddbridge-core.c +++ b/ddbridge/ddbridge-core.c @@ -61,7 +61,7 @@ static int raw_stream; module_param(raw_stream, int, 0444); MODULE_PARM_DESC(raw_stream, "send data as raw stream to DVB layer"); -#ifdef __arm__ +#if defined(__arm__) || defined(__aarch64__) static int alt_dma = 1; #else static int alt_dma; @@ -69,6 +69,14 @@ static int alt_dma; module_param(alt_dma, int, 0444); MODULE_PARM_DESC(alt_dma, "use alternative DMA buffer handling"); +#if defined(__arm__) || defined(__aarch64__) +static int use_workqueue = 1; +#else +static int use_workqueue; +#endif +module_param(use_workqueue, int, 0444); +MODULE_PARM_DESC(use_workqueue, "use workqueue instead of tasklet"); + static int no_init; module_param(no_init, int, 0444); MODULE_PARM_DESC(no_init, "do not initialize most devices"); @@ -325,7 +333,7 @@ static void dma_free(struct pci_dev *pdev, struct ddb_dma *dma, int dir) dma_unmap_single(&pdev->dev, dma->pbuf[i], dma->size, dir ? DMA_TO_DEVICE : - DMA_FROM_DEVICE); + DMA_BIDIRECTIONAL); kfree(dma->vbuf[i]); } else { dma_free_coherent(&pdev->dev, dma->size, @@ -356,7 +364,7 @@ static int dma_alloc(struct pci_dev *pdev, struct ddb_dma *dma, int dir) dma->vbuf[i], dma->size, dir ? DMA_TO_DEVICE : - DMA_FROM_DEVICE); + DMA_BIDIRECTIONAL); if (dma_mapping_error(&pdev->dev, dma->pbuf[i])) { kfree(dma->vbuf[i]); dma->vbuf[i] = 0; @@ -641,9 +649,9 @@ static void ddb_input_stop_unlocked(struct ddb_input *input) static void ddb_input_stop(struct ddb_input *input) { if (input->dma) { - spin_lock_irq(&input->dma->lock); + spin_lock_bh(&input->dma->lock); ddb_input_stop_unlocked(input); - spin_unlock_irq(&input->dma->lock); + spin_unlock_bh(&input->dma->lock); } else { ddb_input_stop_unlocked(input); } @@ -672,14 +680,10 @@ static void ddb_input_start_unlocked(struct ddb_input *input) ddbwritel(dev, 1, DMA_BASE_WRITE); ddbwritel(dev, 3, DMA_BUFFER_CONTROL(input->dma)); } - if (dev->link[0].info->type == DDB_OCTONET) - ddbwritel(dev, 0x01, TS_CONTROL(input)); - else { - if (raw_stream) - ddbwritel(dev, 0x01 | ((raw_stream & 3) << 8), TS_CONTROL(input)); - else - ddbwritel(dev, 0x01 | input->con, TS_CONTROL(input)); - } + if (raw_stream) + ddbwritel(dev, 0x01 | (raw_stream & 0x300), TS_CONTROL(input)); + else + ddbwritel(dev, 0x01 | input->con, TS_CONTROL(input)); if (input->port->type == DDB_TUNER_DUMMY) ddbwritel(dev, 0x000fff01, TS_CONTROL2(input)); if (input->dma) @@ -689,9 +693,9 @@ static void ddb_input_start_unlocked(struct ddb_input *input) static void ddb_input_start(struct ddb_input *input) { if (input->dma) { - spin_lock_irq(&input->dma->lock); + spin_lock_bh(&input->dma->lock); ddb_input_start_unlocked(input); - spin_unlock_irq(&input->dma->lock); + spin_unlock_bh(&input->dma->lock); } else { ddb_input_start_unlocked(input); } @@ -799,6 +803,12 @@ static ssize_t ddb_output_write(struct ddb_output *output, } if (len > left) len = left; + if (alt_dma) + dma_sync_single_for_cpu(dev->dev, + output->dma->pbuf[ + output->dma->cbuf], + output->dma->size, + DMA_TO_DEVICE); if (copy_from_user(output->dma->vbuf[output->dma->cbuf] + output->dma->coff, buf, len)) @@ -869,6 +879,12 @@ static size_t ddb_input_read(struct ddb_input *input, DMA_FROM_DEVICE); ret = copy_to_user(buf, input->dma->vbuf[input->dma->cbuf] + input->dma->coff, free); + if (alt_dma) + dma_sync_single_for_device(dev->dev, + input->dma->pbuf[ + input->dma->cbuf], + input->dma->size, + DMA_FROM_DEVICE); if (ret) return -EFAULT; input->dma->coff += free; @@ -958,12 +974,16 @@ static unsigned int ts_poll(struct file *file, poll_table *wait) unsigned int mask = 0; - poll_wait(file, &input->dma->wq, wait); - poll_wait(file, &output->dma->wq, wait); - if (ddb_input_avail(input) >= 188) - mask |= POLLIN | POLLRDNORM; - if (ddb_output_free(output) >= 188) - mask |= POLLOUT | POLLWRNORM; + if (input && input->dma) { + poll_wait(file, &input->dma->wq, wait); + if (ddb_input_avail(input) >= 188) + mask |= POLLIN | POLLRDNORM; + } + if (output && output->dma) { + poll_wait(file, &output->dma->wq, wait); + if (ddb_output_free(output) >= 188) + mask |= POLLOUT | POLLWRNORM; + } return mask; } @@ -990,8 +1010,11 @@ static int ts_open(struct inode *inode, struct file *file) int err; struct dvb_device *dvbdev = file->private_data; struct ddb_output *output = dvbdev->priv; - struct ddb_input *input = output->port->input[0]; + struct ddb_input *input; + if (!output) + return -EINVAL; + input = output->port->input[0]; if ((file->f_flags & O_ACCMODE) == O_RDONLY) { if (!input) return -EINVAL; @@ -1159,11 +1182,8 @@ static struct dvb_frontend_ops dummy_ops = { static struct dvb_frontend *dummy_attach(void) { -#if (KERNEL_VERSION(4, 13, 0) > LINUX_VERSION_CODE) - struct dvb_frontend *fe = kmalloc(sizeof(*fe), __GFP_REPEAT); -#else - struct dvb_frontend *fe = kmalloc(sizeof(*fe), __GFP_RETRY_MAYFAIL); -#endif + struct dvb_frontend *fe = kzalloc(sizeof(*fe), GFP_KERNEL); + if (fe) fe->ops = dummy_ops; return fe; @@ -2419,7 +2439,9 @@ static void input_write_dvb(struct ddb_input *input, dma2->vbuf[dma->cbuf], dma2->size / 188); } - + //if (alt_dma) + // dma_sync_single_for_device(dev->dev, dma2->pbuf[dma->cbuf], + // dma2->size, DMA_FROM_DEVICE); dma->cbuf = (dma->cbuf + 1) % dma2->num; if (ack) ddbwritel(dev, (dma->cbuf << 11), @@ -2429,18 +2451,13 @@ static void input_write_dvb(struct ddb_input *input, } } -static void input_tasklet(unsigned long data) +static void input_proc(struct ddb_dma *dma) { - struct ddb_dma *dma = (struct ddb_dma *)data; struct ddb_input *input = (struct ddb_input *)dma->io; struct ddb *dev = input->port->dev; - unsigned long flags; - spin_lock_irqsave(&dma->lock, flags); - if (!dma->running) { - spin_unlock_irqrestore(&dma->lock, flags); + if (!dma->running) return; - } dma->stat = ddbreadl(dev, DMA_BUFFER_CURRENT(dma)); dma->ctrl = ddbreadl(dev, DMA_BUFFER_CONTROL(dma)); update_loss(dma); @@ -2451,83 +2468,63 @@ static void input_tasklet(unsigned long data) if (input->redo) input_write_output(input, input->redo); wake_up(&dma->wq); - spin_unlock_irqrestore(&dma->lock, flags); } -#ifdef OPTIMIZE_TASKLETS -static void input_handler(unsigned long data) +static void input_work(struct work_struct *work) { - struct ddb_input *input = (struct ddb_input *)data; + struct ddb_dma *dma = container_of(work, struct ddb_dma, work); + + spin_lock(&dma->lock); + input_proc(dma); + spin_unlock(&dma->lock); +} + +static void input_tasklet(unsigned long data) +{ + struct ddb_dma *dma = (struct ddb_dma *)data; + + spin_lock_bh(&dma->lock); + input_proc(dma); + spin_unlock_bh(&dma->lock); +} + +static void input_handler(void *data) +{ + struct ddb_input *input = (struct ddb_input *) data; struct ddb_dma *dma = input->dma; /* If there is no input connected, input_tasklet() will * just copy pointers and ACK. So, there is no need to go * through the tasklet scheduler. */ - if (input->redi) - tasklet_schedule(&dma->tasklet); - else - input_tasklet(data); + if (!input->redi) { + input_work(&dma->work); + } else { + if (use_workqueue) + queue_work(ddb_wq, &dma->work); + else + tasklet_schedule(&dma->tasklet); + } } -#else -static void input_handler(void *data) +static void output_handler(void *data) { - struct ddb_input *input = (struct ddb_input *)data; - struct ddb_dma *dma = input->dma; - - input_tasklet((unsigned long)dma); -} -#endif - -static void output_tasklet(unsigned long data) -{ - struct ddb_dma *dma = (struct ddb_dma *)data; - struct ddb_output *output = (struct ddb_output *)dma->io; + struct ddb_output *output = (struct ddb_output *)data; + struct ddb_dma *dma = output->dma; struct ddb *dev = output->port->dev; unsigned long flags; spin_lock_irqsave(&dma->lock, flags); - if (!dma->running) - goto unlock_exit; - 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); -unlock_exit: + if (dma->running) { + 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); + } spin_unlock_irqrestore(&dma->lock, flags); } -#ifdef OPTIMIZE_TASKLETS -static void output_handler(void *data) -{ - struct ddb_output *output = (struct ddb_output *)data; - struct ddb_dma *dma = output->dma; - struct ddb *dev = output->port->dev; - - spin_lock(&dma->lock); - if (!dma->running) { - spin_unlock(&dma->lock); - return; - } - 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); - spin_unlock(&dma->lock); -} -#else -static void output_handler(void *data) -{ - struct ddb_output *output = (struct ddb_output *)data; - struct ddb_dma *dma = output->dma; - - tasklet_schedule(&dma->tasklet); -} -#endif - /****************************************************************************/ /****************************************************************************/ @@ -2555,7 +2552,6 @@ static void ddb_dma_init(struct ddb_io *io, int nr, int out, int irq_nr) spin_lock_init(&dma->lock); init_waitqueue_head(&dma->wq); if (out) { - tasklet_init(&dma->tasklet, output_tasklet, (unsigned long)dma); dma->regs = rm->odma->base + rm->odma->size * nr; dma->bufregs = rm->odma_buf->base + rm->odma_buf->size * nr; if (io->port->dev->link[0].info->type == DDB_MOD && @@ -2569,7 +2565,10 @@ static void ddb_dma_init(struct ddb_io *io, int nr, int out, int irq_nr) dma->div = 1; } } else { - tasklet_init(&dma->tasklet, input_tasklet, (unsigned long)dma); + if (use_workqueue) + INIT_WORK(&dma->work, input_work); + else + tasklet_init(&dma->tasklet, input_tasklet, (unsigned long)dma); dma->regs = rm->idma->base + rm->idma->size * nr; dma->bufregs = rm->idma_buf->base + rm->idma_buf->size * nr; dma->num = dma_buf_num; @@ -2767,12 +2766,21 @@ void ddb_ports_release(struct ddb *dev) for (i = 0; i < dev->port_num; i++) { port = &dev->port[i]; - if (port->input[0] && port->input[0]->dma) - tasklet_kill(&port->input[0]->dma->tasklet); - if (port->input[1] && port->input[1]->dma) - tasklet_kill(&port->input[1]->dma->tasklet); - if (port->output && port->output->dma) - tasklet_kill(&port->output->dma->tasklet); + if (use_workqueue) { + if (port->input[0] && port->input[0]->dma) + cancel_work_sync(&port->input[0]->dma->work); + if (port->input[1] && port->input[1]->dma) + cancel_work_sync(&port->input[1]->dma->work); + //if (port->output && port->output->dma) + // cancel_work_sync(&port->output->dma->work); + } else { + if (port->input[0] && port->input[0]->dma) + tasklet_kill(&port->input[0]->dma->tasklet); + if (port->input[1] && port->input[1]->dma) + tasklet_kill(&port->input[1]->dma->tasklet); + //if (port->output && port->output->dma) + // tasklet_kill(&port->output->dma->tasklet); + } } } @@ -2874,9 +2882,8 @@ irqreturn_t ddb_irq_handler(int irq, void *dev_id) if (s & 0x0000000f) irq_handle_msg(dev, s); - if (s & 0x0fffff00) { + if (s & 0x0fffff00) irq_handle_io(dev, s); - } } while ((s = ddbreadl(dev, INTERRUPT_STATUS))); return ret; @@ -4613,7 +4620,7 @@ int ddb_init_ddbridge(void) if (ddb_class_create() < 0) return -1; - ddb_wq = alloc_workqueue("ddbridge", 0, 0); + ddb_wq = alloc_workqueue("ddbridge", WQ_UNBOUND, 0); if (!ddb_wq) return ddb_exit_ddbridge(1, -1); return 0; diff --git a/ddbridge/ddbridge-main.c b/ddbridge/ddbridge-main.c index a03b58a..7f1bd5a 100644 --- a/ddbridge/ddbridge-main.c +++ b/ddbridge/ddbridge-main.c @@ -388,7 +388,7 @@ fail: ddb_unmap(dev); pci_set_drvdata(pdev, NULL); pci_disable_device(pdev); - return -1; + return stat; } /****************************************************************************/ diff --git a/ddbridge/ddbridge-max.c b/ddbridge/ddbridge-max.c index e804f07..8557f18 100644 --- a/ddbridge/ddbridge-max.c +++ b/ddbridge/ddbridge-max.c @@ -65,8 +65,8 @@ static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd) } if (c == 10) dev_info(dev->dev, - "%s lnb = %08x cmd = %08x\n", - __func__, lnb, cmd); + "%s lnb = %08x cmd = %08x timed out\n", + __func__, lnb, cmd | v); return 0; } @@ -480,8 +480,12 @@ int ddb_fe_attach_mxl5xx(struct ddb_input *input) tuner = demod & 3; if (fmode >= 3) tuner = 0; +#ifdef CONFIG_MEDIA_ATTACH dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg, demod, tuner, &dvb->set_input); +#else + dvb->fe = mxl5xx_attach(i2c, &cfg, demod, tuner, &dvb->set_input); +#endif if (!dvb->fe) { dev_err(dev->dev, "No MXL5XX found!\n"); return -ENODEV; diff --git a/ddbridge/ddbridge-sx8.c b/ddbridge/ddbridge-sx8.c index 630f541..45a0991 100644 --- a/ddbridge/ddbridge-sx8.c +++ b/ddbridge/ddbridge-sx8.c @@ -152,6 +152,7 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) if (stat) goto unlock; if (res.status == MCI_DEMOD_LOCKED || res.status == SX8_DEMOD_IQ_MODE) { + //if (res.status == MCI_DEMOD_LOCKED || sx8_base->iq_mode) { *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; if (res.status == MCI_DEMOD_LOCKED) { @@ -171,8 +172,12 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) } } else if (res.status == MCI_DEMOD_TIMEOUT) *status = FE_TIMEDOUT; - else if (res.status >= SX8_DEMOD_WAIT_MATYPE) + else if (res.status >= SX8_DEMOD_WAIT_MATYPE) { *status = FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; + if (sx8_base->iq_mode) + *status |= FE_HAS_LOCK; + } + unlock: mutex_unlock(&state->lock); return stat; @@ -385,6 +390,8 @@ unlock: cmd.dvbs2_search.s2_modulation_mask = modmask; cmd.dvbs2_search.rsvd1 = ro_lut[p->rolloff & 7]; cmd.dvbs2_search.retry = 2; + if (sx8_base->iq_mode) + cmd.dvbs2_search.retry = 255; cmd.dvbs2_search.frequency = p->frequency * 1000; cmd.dvbs2_search.symbol_rate = p->symbol_rate; cmd.dvbs2_search.scrambling_sequence_index = diff --git a/ddbridge/ddbridge.h b/ddbridge/ddbridge.h index e9d24ba..f36573a 100644 --- a/ddbridge/ddbridge.h +++ b/ddbridge/ddbridge.h @@ -202,6 +202,7 @@ struct ddb_dma { u32 div; u32 bufval; + struct work_struct work; struct tasklet_struct tasklet; spinlock_t lock; /* DMA lock */ wait_queue_head_t wq; diff --git a/dvb-core/dvbdev.c b/dvb-core/dvbdev.c index 913e434..fd0de1f 100644 --- a/dvb-core/dvbdev.c +++ b/dvb-core/dvbdev.c @@ -134,25 +134,35 @@ static struct cdev dvb_device_cdev; int dvb_generic_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev = file->private_data; + int ret = 0; if (!dvbdev) return -ENODEV; - if (!dvbdev->users) - return -EBUSY; + mutex_lock(&dvbdev->lock); + if (!dvbdev->users) { + ret = -EBUSY; + goto unlock; + } if ((file->f_flags & O_ACCMODE) == O_RDONLY) { - if (!dvbdev->readers) - return -EBUSY; + if (!dvbdev->readers) { + ret = -EBUSY; + goto unlock; + } dvbdev->readers--; } else { - if (!dvbdev->writers) - return -EBUSY; + if (!dvbdev->writers) { + ret = -EBUSY; + goto unlock; + } dvbdev->writers--; } dvbdev->users--; - return 0; +unlock: + mutex_unlock(&dvbdev->lock); + return ret; } EXPORT_SYMBOL(dvb_generic_open); @@ -163,12 +173,14 @@ int dvb_generic_release(struct inode *inode, struct file *file) if (!dvbdev) return -ENODEV; + mutex_lock(&dvbdev->lock); if ((file->f_flags & O_ACCMODE) == O_RDONLY) dvbdev->readers++; else dvbdev->writers++; dvbdev->users++; + mutex_unlock(&dvbdev->lock); dvb_device_put(dvbdev); @@ -524,6 +536,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, dvbdev->adapter = adap; dvbdev->priv = priv; dvbdev->fops = dvbdevfops; + mutex_init(&dvbdev->lock); init_waitqueue_head(&dvbdev->wait_queue); dvbdevfops->owner = adap->module; list_add_tail(&dvbdev->list_head, &adap->device_list); diff --git a/include/linux/media/dvbdev.h b/include/linux/media/dvbdev.h index 91fcab8..14c8b7d 100644 --- a/include/linux/media/dvbdev.h +++ b/include/linux/media/dvbdev.h @@ -182,6 +182,7 @@ struct dvb_device { int readers; int writers; int users; + struct mutex lock; wait_queue_head_t wait_queue; /* don't really need those !? -- FIXME: use video_usercopy */ diff --git a/lib/config/dddvb.conf b/lib/config/dddvb.conf index cb27303..ecb7b9b 100644 --- a/lib/config/dddvb.conf +++ b/lib/config/dddvb.conf @@ -17,7 +17,19 @@ Tuner5=5,984 Tuner6=6,1020 Tuner7=7,1056 Tuner8=8,1092 -Tuner9=1,1210 -Tuner10=2,1420 -Tuner11=3,1680 -Tuner12=4,2040 +Tuner9=9,1128 +Tuner10=10,1164 +Tuner11=11,1256 +Tuner12=12,1292 +Tuner13=13,1328 +Tuner14=14,1364 +Tuner15=15,1458 +Tuner16=16,1494 +Tuner17=17,1530 +Tuner18=18,1566 +Tuner19=19,1602 +Tuner20=20,1638 +Tuner21=21,1716 +Tuner22=22,1752 +Tuner23=23,1788 +Tuner24=24,1824 diff --git a/lib/src/dddvb.h b/lib/src/dddvb.h index a478bb2..c09781a 100644 --- a/lib/src/dddvb.h +++ b/lib/src/dddvb.h @@ -76,6 +76,8 @@ struct dddvb_fe { uint32_t lock; uint32_t quality; uint32_t pls_code; + uint32_t inversion; + uint32_t rolloff; int64_t strength; int64_t cnr; int64_t ber; diff --git a/lib/src/dvb.c b/lib/src/dvb.c index 9a1f840..a1afcf0 100644 --- a/lib/src/dvb.c +++ b/lib/src/dvb.c @@ -244,7 +244,7 @@ static int set_en50607(struct dddvb_fe *fe, uint32_t freq_khz, uint32_t sr, uint32_t t = freq - 100; uint32_t input = 3 & (sat >> 6); int fd = fe->fd; - + dbgprintf(DEBUG_DVB, "input = %u, sat = %u\n", input, sat&0x3f); hor &= 1; cmd.msg[1] = slot << 3; @@ -732,7 +732,7 @@ void dddvb_fe_handle(struct dddvb_fe *fe) } else { max = 1; nolock++; - if (nolock > 10) + if (nolock > 20) fe->tune = 1; } break; @@ -809,8 +809,10 @@ static int dddvb_fe_init(struct dddvb *dd, int a, int f, int fd) dps.props = dp; dp[0].cmd = DTV_ENUM_DELSYS; r = ioctl(fd, FE_GET_PROPERTY, &dps); - if (r < 0) + if (r < 0) { + dbgprintf(DEBUG_DVB, "Could not get delsys, error=%d\n", errno); return -1; + } for (i = 0; i < dp[0].u.buffer.len; i++) { ds = dp[0].u.buffer.data[i]; dbgprintf(DEBUG_DVB, "delivery system %d\n", ds); diff --git a/lib/src/dvb_quality.c b/lib/src/dvb_quality.c index 53d8a17..6e463a5 100644 --- a/lib/src/dvb_quality.c +++ b/lib/src/dvb_quality.c @@ -331,8 +331,6 @@ static void calc_lq(struct dddvb_fe *fe) int64_t str, snr; uint32_t mod, fec, ber_num, ber_den, trans, pilot = 0, quality = 0, freq, rate; - get_property(fe->fd, DTV_TRANSMISSION_MODE, &fe->pls_code); - dbgprintf(DEBUG_DVB, "fe%d: pls=0x%02x\n", fe->nr, fe->pls_code); get_stat(fe->fd, DTV_STAT_SIGNAL_STRENGTH, &st); str = st.stat[0].svalue; @@ -368,9 +366,17 @@ static void calc_lq(struct dddvb_fe *fe) dbgprintf(DEBUG_DVB, "fe%d: actual symbol rate=%u\n", fe->nr, rate); switch (fe->n_param.param[PARAM_MSYS]) { case SYS_DVBS: + get_property(fe->fd, DTV_INVERSION, &fe->inversion); + get_property(fe->fd, DTV_ROLLOFF, &fe->rolloff); + dbgprintf(DEBUG_DVB, "fe%d: inversion=%u rolloff=%u\n", fe->nr, fe->inversion, fe->rolloff); quality = dvbsq(snr, fec, ber_num, ber_den); break; case SYS_DVBS2: + get_property(fe->fd, DTV_TRANSMISSION_MODE, &fe->pls_code); + dbgprintf(DEBUG_DVB, "fe%d: pls=0x%02x\n", fe->nr, fe->pls_code); + get_property(fe->fd, DTV_INVERSION, &fe->inversion); + get_property(fe->fd, DTV_ROLLOFF, &fe->rolloff); + dbgprintf(DEBUG_DVB, "fe%d: inversion=%u rolloff=%u\n", fe->nr, fe->inversion, fe->rolloff); quality = dvbs2q(snr, fec, mod, ber_num, ber_den); break; case SYS_DVBC_ANNEX_A: