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.
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
***************
*** 1138,1144 ****
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);
#else
netif_tx_lock_bh(dev);
#endif
--- 1138,1144 ----
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);
#else
netif_tx_lock_bh(dev);
#endif
***************
*** 1167,1173 ****
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
! spin_unlock_bh(&dev->xmit_lock);
#else
netif_tx_unlock_bh(dev);
#endif
--- 1167,1173 ----
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
! spin_unlock_bh(&dev->_xmit_lock);
#else
netif_tx_unlock_bh(dev);
#endif
diff -r -c mantis.old/linux/drivers/media/dvb/frontends/cu1216.c mantis/linux/drivers/media/dvb/frontends/cu1216.c
*** mantis.old/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,74 ****
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);
--- 68,73 ----
***************
*** 785,798 ****
static void delay_ms_interruptible(u32 ms)
{
! set_current_state(TASK_INTERRUPTIBLE);
! schedule_timeout(HZ * ms / 100);
}
static void delay_us_interruptible(u32 us)
{
! set_current_state(TASK_INTERRUPTIBLE);
! schedule_timeout(HZ * us / 10000);
}
--- 784,795 ----
static void delay_ms_interruptible(u32 ms)
{
! schedule_timeout_interruptible( msecs_to_jiffies( ms ) );
}
static void delay_us_interruptible(u32 us)
{
! schedule_timeout_interruptible( usecs_to_jiffies ( us ) );
}
***************
*** 800,815 ****
{
struct cu1216_state *state = fe->demodulator_priv;
- u8 i;
u8 QamSize = 0;
! 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);
switch (params->u.qam.modulation) {
case QPSK :
--- 797,808 ----
{
struct cu1216_state *state = fe->demodulator_priv;
u8 QamSize = 0;
! u32 uc_Gain;
! u32 errRate[3];
fe_status_t value;
int status = -EINVAL;
! int theGain = 0;
switch (params->u.qam.modulation) {
case QPSK :
***************
*** 835,843 ****
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);
--- 828,833 ----
***************
*** 862,926 ****
//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_gain(fe, uc_Gain);
! //udelay(50);
! delay_us_interruptible(5);
! if (cu1216_read_status(fe, &value) == 0) {
! 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;
! }
}
- }
! status = -1;
! ret:
state->params = *params;
return status ;
--- 852,899 ----
//Write QAM
cu1216_set_QAM(fe, QamSize);
! cu1216_set_IQ(fe, (params->inversion == INVERSION_ON)? 1:0);
! for (uc_Gain = 1; uc_Gain < 4; uc_Gain++)
! errRate[uc_Gain-1] = 0;
! for (uc_Gain = 1; uc_Gain < 4; uc_Gain++) {
! cu1216_set_gain(fe, uc_Gain);
! delay_us_interruptible(5);
! if (uc_Gain == 1) {
! if ( cu1216_read_status(fe, &value) != 0 )
! break;
}
! errRate[uc_Gain-1] = cu1216_read_errRate(fe);
!
! if ( uc_Gain == 1 )
! continue;
! // 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,959 ****
--- 927,940 ----
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,1036 ****
--- 1012,1018 ----
.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 -r -c mantis.old/linux/drivers/media/dvb/mantis/mantis_dma.c mantis/linux/drivers/media/dvb/mantis/mantis_dma.c
*** mantis.old/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,198 ****
mantis_risc_program(mantis);
mmwrite(cpu_to_le32(mantis->risc_dma), MANTIS_RISC_START);
! mmwrite(MANTIS_GPIF_RDWRN, MANTIS_GPIF_ADDR);
mmwrite(0, MANTIS_DMA_CTL);
mantis->last_block = mantis->finished_block = 0;
--- 192,198 ----
mantis_risc_program(mantis);
mmwrite(cpu_to_le32(mantis->risc_dma), MANTIS_RISC_START);
! mmwrite( mmread( MANTIS_GPIF_ADDR ) | MANTIS_GPIF_RDWRN, MANTIS_GPIF_ADDR);
mmwrite(0, MANTIS_DMA_CTL);
mantis->last_block = mantis->finished_block = 0;
***************
*** 208,213 ****
--- 208,214 ----
{
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,237 ****
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->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES);
mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT;
}
--- 232,238 ----
dprintk(verbose, MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]",
mantis->last_block, mantis->finished_block);
! (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@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb