You're welcome, Manu
Its great that these patches are useful.
Here they are.
Once again about my license for these changes:
I accept the following license for my cu1216.c and mantis_dma.c and dvb_net.c
changes,
because those files have the same license now:
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Pauli Borodulin found originally the MANTIS_GPIF_ADDR problem spot.
I developed the attached solution for the problem.
dvb_net.c fix isn't my idea originally.
The advice for the trivial solution occurred
somewhere in this list, although not as a patch.
Other fixes are fully my own
writings or modifications of the specified code in question.
Best regards,
Marko Ristola
Manu Abraham wrote:
Marko Ristola wrote:
Hi Manu and others,
On my DVB Mantis chip, there is
K61468.2A-2
041213
With the attached patch, I am able to see Finnish HTV cable TV,
unencrypted channels,
with my Mantis VP-2033. It uses the cu1216 kernel module.
The patch can be applied to the Mantis Alpha version that Manu released
(this thread
began with the release note and a reference to the source code).
cd mantis-25021de30f36
patch -p1 < /tmp/mantis-alpha-changes.diff
Here are the changed files:
linux/drivers/media/dvb/dvb-core/dvb_net.c (just to make it compilable,
not my fix initially, for completeness only).
linux/drivers/media/dvb/frontends/cu1216.c (dvb-core is able to do a
lock into the given frequency).
patching file linux/drivers/media/dvb/mantis/mantis_dma.c (demuxer fix,
lock status reading fix).
Here are answers for You, Manu:
Manu Abraham wrote:
DMA should be started only after a LOCK, but it is not the driver that
which starts the DMA but it is in the dvb-core. Need to see why DMA is
initiated much earlier, causing garbage in the buffers.
I will check it out in the coming few days.
The patch that I have attached, has function cu1216_get_tune_settings()
It sets a 50ms time delay. I'm able to get a lock with that delay
without any hacks
in cu1216_set_parameters() function.
I removed the interlace selection in cu1216_set_parameters().
cu1216_set_parameters() will also return 0 on success.
MANTIS_GPIF_ADDR changes are needed to enable dvb-core to read the lock
status after DMA start. So this is the 0x3000 case.
Quite helpful indeed that you were able to dig into this.
Garbage in the buffers is fixed for me (scratch screen becomes working
video and audio),
when I use dvb_dmx_swfilter() instead of dvb_dmx_swfilter_204(). This is
in file mantis_dma.c.
"scan" binary is able to find channels after a fresh reboot.
After using DVB applications, "scan" won't work anymore.
I never use rmmod. I suspect memory corruption then.
If you like, you can attach some of my fixes with the following GPL v2
licence.
I accept this license for my cu1216.c and mantis_dma.c changes,
because you have selected that license for those files:
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
Regards,
Marko Ristola
------------------------------------------------------------------------
diff -r -c mantis.old/linux/drivers/media/dvb/dvb-core/dvb_net.c
mantis/linux/drivers/media/dvb/dvb-core/dvb_net.c
*** mantis.old/linux/drivers/media/dvb/dvb-core/dvb_net.c 2006-10-19
17:24:03.000000000 +0300
--- mantis/linux/drivers/media/dvb/dvb-core/dvb_net.c 2006-10-19
17:46:41.000000000 +0300
***************
can you please create a diff in the unified format ? , ie, diff -up
options ? Please do send the core diff also as a separate patch.
Thanks,
Manu
--- mantis.alpha/linux/drivers/media/dvb/dvb-core/dvb_net.c 2006-10-19 17:24:03.000000000 +0300
+++ mantis/linux/drivers/media/dvb/dvb-core/dvb_net.c 2006-10-19 17:46:41.000000000 +0300
@@ -1138,7 +1138,7 @@ static void wq_set_multicast_list (void
dvb_net_feed_stop(dev);
priv->rx_mode = RX_MODE_UNI;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
- spin_lock_bh(&dev->xmit_lock);
+ spin_lock_bh(&dev->_xmit_lock);
#else
netif_tx_lock_bh(dev);
#endif
@@ -1167,7 +1167,7 @@ static void wq_set_multicast_list (void
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
- spin_unlock_bh(&dev->xmit_lock);
+ spin_unlock_bh(&dev->_xmit_lock);
#else
netif_tx_unlock_bh(dev);
#endif
diff -up -r mantis.alpha/linux/drivers/media/dvb/frontends/cu1216.c mantis/linux/drivers/media/dvb/frontends/cu1216.c
--- mantis.alpha/linux/drivers/media/dvb/frontends/cu1216.c 2006-10-19 17:24:03.000000000 +0300
+++ mantis/linux/drivers/media/dvb/frontends/cu1216.c 2006-10-21 14:53:05.000000000 +0300
@@ -68,7 +68,6 @@ typedef struct AC_TypeQAM_TAG {
static u32 AC_uSysClk;
-static u8 li_Iq, li_oldIq = 0, uc_Gain, uc_oldGain = 0;
static void cu1216_set_symbolRate(struct dvb_frontend *fe, u16 uFreqSymb);
static void cu1216_set_QAM(struct dvb_frontend *fe, u8 bQAM);
@@ -785,14 +784,12 @@ static int cu1216_init(struct dvb_fronte
static void delay_ms_interruptible(u32 ms)
{
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ * ms / 100);
+ schedule_timeout_interruptible( msecs_to_jiffies( ms ) );
}
static void delay_us_interruptible(u32 us)
{
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ * us / 10000);
+ schedule_timeout_interruptible( usecs_to_jiffies ( us ) );
}
@@ -800,16 +797,12 @@ static int cu1216_set_parameters(struct
{
struct cu1216_state *state = fe->demodulator_priv;
- u8 i;
u8 QamSize = 0;
- u32 ErrRate[3];
+ u32 uc_Gain;
+ u32 errRate[3];
fe_status_t value;
int status = -EINVAL;
-
- printk("[%s]:frequency = %d , symbol = %d , qam = %d .\n",
- __func__,
- params->frequency , params->u.qam.symbol_rate,
- params->u.qam.modulation);
+ int theGain = 0;
switch (params->u.qam.modulation) {
case QPSK :
@@ -835,9 +828,6 @@ static int cu1216_set_parameters(struct
break;
}
- if (li_oldIq >= 2)
- li_oldIq = 0;
-
// cu1216_reset(fe);
// FIXME ! need to do a Bridge RESET from here
// state->config->fe_reset(fe);
@@ -862,65 +852,48 @@ static int cu1216_set_parameters(struct
//Write QAM
cu1216_set_QAM(fe, QamSize);
- for (i = li_oldIq; i < li_oldIq + 2; i++) {
- li_Iq = i % 2;
-
- for (uc_Gain = 1; uc_Gain < 4; uc_Gain++) {
- cu1216_set_IQ(fe, li_Iq);
+ cu1216_set_IQ(fe, (params->inversion == INVERSION_ON)? 1:0);
- cu1216_set_gain(fe, uc_Gain);
+ for (uc_Gain = 1; uc_Gain < 4; uc_Gain++)
+ errRate[uc_Gain-1] = 0;
- //udelay(50);
- delay_us_interruptible(5);
+ for (uc_Gain = 1; uc_Gain < 4; uc_Gain++) {
- if (cu1216_read_status(fe, &value) == 0) {
+ cu1216_set_gain(fe, uc_Gain);
+ delay_us_interruptible(5);
- li_oldIq = li_Iq;
- uc_oldGain = uc_Gain;
- ErrRate[0] = cu1216_read_errRate(fe);
-
- if (uc_Gain < 3) {
- cu1216_set_gain(fe, uc_Gain+1);
- //udelay(50);
- delay_us_interruptible(5);
- ErrRate[1] = cu1216_read_errRate(fe);
-
- if (ErrRate[0] > ErrRate[1]) {
- cu1216_set_gain(fe , uc_Gain);
- //udelay(50);
- delay_us_interruptible(5);
-
- } else {
- uc_oldGain = uc_Gain + 1;
- uc_Gain = uc_Gain + 1;
-
- if (uc_Gain < 3) {
- cu1216_set_gain(fe, uc_Gain + 1);
-
- //udelay(50);
- delay_us_interruptible(5);
- ErrRate[2] = cu1216_read_errRate(fe);
-
- if (ErrRate[1] > ErrRate[2]) {
- cu1216_set_gain(fe , uc_oldGain);
-
- //udelay(50);
- delay_us_interruptible(5);
- } else {
- uc_oldGain = uc_Gain + 1;
- }
- }
- }
- }
- goto ret;
- }
+ if (uc_Gain == 1) {
+ if ( cu1216_read_status(fe, &value) != 0 )
+ break;
}
- }
- status = -1;
+ errRate[uc_Gain-1] = cu1216_read_errRate(fe);
+
+ if ( uc_Gain == 1 )
+ continue;
-ret:
+ // Accept the previous gain if it is has smaller or equal error rate.
+ if ( errRate[uc_Gain - 2] <= errRate[uc_Gain - 1] ) {
+ theGain = uc_Gain - 1;
+ cu1216_set_gain(fe, uc_Gain - 1);
+ delay_us_interruptible(5);
+ status = 0;
+ break;
+ }
+
+ // Accept this gain. The previous has been discarded already.
+ if ( uc_Gain == 3 ) {
+ theGain = uc_Gain;
+ status = 0;
+ break;
+ }
+ }
+ printk("[%s]:frequency = %d , symbol = %d , qam = %d, inversion = %d err={%04x %04x %04x max=%d}.\n",
+ __func__,
+ params->frequency , params->u.qam.symbol_rate,
+ params->u.qam.modulation, params->inversion,errRate[0],errRate[1],errRate[2],theGain);
+
state->params = *params;
return status ;
@@ -954,6 +927,14 @@ static int cu1216_get_frontend(struct dv
return 0;
}
+static int cu1216_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* settings)
+{
+ settings->min_delay_ms = 50;
+ settings->step_size = 0; /* FE_QAM: zero */
+ settings->max_drift = 0; /* FE_QAM: zero */
+
+ return 0;
+}
static int cu1216_sleep(struct dvb_frontend *fe)
{
@@ -1031,6 +1012,7 @@ static struct dvb_frontend_ops cu1216_op
.init = cu1216_init_none,
.sleep = cu1216_sleep,
.set_frontend = cu1216_set_parameters,
+ .get_tune_settings = cu1216_get_tune_settings,
.get_frontend = cu1216_get_frontend,
.read_status = cu1216_read_status,
.read_ber = cu1216_read_ber,
diff -up -r mantis.alpha/linux/drivers/media/dvb/mantis/mantis_dma.c mantis/linux/drivers/media/dvb/mantis/mantis_dma.c
--- mantis.alpha/linux/drivers/media/dvb/mantis/mantis_dma.c 2006-10-19 17:24:03.000000000 +0300
+++ mantis/linux/drivers/media/dvb/mantis/mantis_dma.c 2006-10-19 17:44:31.000000000 +0300
@@ -192,7 +192,7 @@ void mantis_dma_start(struct mantis_pci
mantis_risc_program(mantis);
mmwrite(cpu_to_le32(mantis->risc_dma), MANTIS_RISC_START);
- mmwrite(MANTIS_GPIF_RDWRN, MANTIS_GPIF_ADDR);
+ mmwrite( mmread( MANTIS_GPIF_ADDR ) | MANTIS_GPIF_RDWRN, MANTIS_GPIF_ADDR);
mmwrite(0, MANTIS_DMA_CTL);
mantis->last_block = mantis->finished_block = 0;
@@ -208,6 +208,7 @@ void mantis_dma_stop(struct mantis_pci *
{
u32 stat = 0, mask = 0;
+ mmwrite( (mmread(MANTIS_GPIF_ADDR) & ( ~(MANTIS_GPIF_RDWRN) ) ), MANTIS_GPIF_ADDR);
stat = mmread(MANTIS_INT_STAT);
mask = mmread(MANTIS_INT_MASK);
dprintk(verbose, MANTIS_DEBUG, 1, "Mantis Stop DMA engine");
@@ -231,7 +232,7 @@ void mantis_dma_xfer(unsigned long data)
dprintk(verbose, MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]",
mantis->last_block, mantis->finished_block);
- (mantis->ts_size ? dvb_dmx_swfilter_204: dvb_dmx_swfilter)
+ (mantis->ts_size ? dvb_dmx_swfilter: dvb_dmx_swfilter_204)
(&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES);
mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT;
}
_______________________________________________
linux-dvb mailing list
linux-dvb@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb