[linux-dvb] [PATCH] HD5000 Support
Mac Michaels
wmichaels1 at earthlink.net
Tue Sep 27 21:05:26 CEST 2005
I suggest a few changes to this patch. I inserted it a a
quote so that I can work my comments into it.
> Index: linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
>
===================================================================
> RCS
file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c,v
> retrieving revision 1.10
> diff -u -r1.10 flexcop-fe-tuner.c
> --- linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c 10 Sep
2005 12:43:48 -0000 1.10
> +++ linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c 25 Sep
2005 16:52:08 -0000
> @@ -13,6 +13,8 @@
> #include "bcm3510.h"
> #include "stv0297_cs2.h"
> #include "mt312.h"
> +#include "lgdt330x.h"
> +#include "dvb-pll.h"
>
> /* lnb control */
>
> @@ -296,6 +298,51 @@
> return request_firmware(fw, name, fc->dev);
> }
>
> +static int lgdt3303_pll_set(struct dvb_frontend* fe,
> + struct
dvb_frontend_parameters* params)
> +{
> + struct flexcop_device *fc = fe->dvb->priv;
> + u8 buf[4];
> + struct i2c_msg msg =
> + { .addr = 0x61, .flags = 0, .buf = buf, .len = 4 };
> + int err;
> +
> + dvb_pll_configure(&dvb_pll_tdvs_tua6034,buf,
params->frequency, 0);
> + dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x
0x%02x 0x%02x\n",
> + __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
> + if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
> + printk(KERN_WARNING "lgdt3303: %s error "
> + "(addr %02x <- %02x, err = %i)\n",
> + __FUNCTION__, buf[0], buf[1], err);
> + if (err < 0)
> + return err;
> + else
> + return -EREMOTEIO;
> + }
> +
> + buf[0] = 0x86 | 0x18;
> + buf[1] = 0x50;
> + msg.len = 2;
> + if ((err = i2c_transfer(&fc->i2c_adap, &msg, 1)) != 1) {
> + printk(KERN_WARNING "lgdt3303: %s error "
> + "(addr %02x <- %02x, err = %i)\n",
> + __FUNCTION__, buf[0], buf[1], err);
> + if (err < 0)
> + return err;
> + else
> + return -EREMOTEIO;
> + }
> +
> + return 0;
> +}
> +
> +static struct lgdt330x_config air2pc_atsc_hd5000_config =
{
> + .demod_address = 0x59,
> + .demod_chip = LGDT3303,
> + .serial_mpeg = 0x04,
I assume you are using parallel mode data transfer here.
+ .serial_mpeg = 0x00, /* Select parallel mode */
> + .pll_set = lgdt3303_pll_set,
> +};
> +
> static struct nxt2002_config samsung_tbmv_config = {
> .demod_address = 0x0a,
> .request_firmware = flexcop_fe_request_firmware,
> @@ -407,6 +454,11 @@
> fc->dev_type = FC_AIR_ATSC2;
> info("found the nxt2002 at i2c address:
0x%02x",samsung_tbmv_config.demod_address);
> } else
> + /* try the air atsc 3nd generation (lgdt3303) */
> + if ((fc->fe =
lgdt330x_attach(&air2pc_atsc_hd5000_config,
&fc->i2c_adap)) != NULL) {
> + fc->dev_type = FC_AIR_ATSC3;
> + info("found the lgdt3303 at i2c address:
0x%02x",air2pc_atsc_hd5000_config.demod_address);
> + } else
> /* try the air atsc 1nd generation (bcm3510)/panasonic
ct10s */
> if ((fc->fe =
bcm3510_attach(&air2pc_atsc_first_gen_config,
&fc->i2c_adap)) != NULL) {
> fc->dev_type = FC_AIR_ATSC1;
> Index: linux/drivers/media/dvb/b2c2/flexcop-misc.c
>
===================================================================
> RCS
file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/b2c2/flexcop-misc.c,v
> retrieving revision 1.4
> diff -u -r1.4 flexcop-misc.c
> --- linux/drivers/media/dvb/b2c2/flexcop-misc.c 22 Jun
2005 18:53:25 -0000 1.4
> +++ linux/drivers/media/dvb/b2c2/flexcop-misc.c 25 Sep
2005 16:52:08 -0000
> @@ -51,6 +51,7 @@
> "Sky2PC/SkyStar 2 DVB-S",
> "Sky2PC/SkyStar 2 DVB-S (old version)",
> "Cable2PC/CableStar 2 DVB-C",
> + "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)",
> };
>
> const char *flexcop_bus_names[] = {
> Index: linux/drivers/media/dvb/b2c2/flexcop-reg.h
>
===================================================================
> RCS
file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/b2c2/flexcop-reg.h,v
> retrieving revision 1.5
> diff -u -r1.5 flexcop-reg.h
> --- linux/drivers/media/dvb/b2c2/flexcop-reg.h 12 Jun 2005
09:36:19 -0000 1.5
> +++ linux/drivers/media/dvb/b2c2/flexcop-reg.h 25 Sep 2005
16:52:08 -0000
> @@ -26,6 +26,7 @@
> FC_SKY,
> FC_SKY_OLD,
> FC_CABLE,
> + FC_AIR_ATSC3,
> } flexcop_device_type_t;
>
> typedef enum {
> Index: linux/drivers/media/dvb/b2c2/flexcop.c
>
===================================================================
> RCS
file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/b2c2/flexcop.c,v
> retrieving revision 1.7
> diff -u -r1.7 flexcop.c
> --- linux/drivers/media/dvb/b2c2/flexcop.c 22 Jun 2005
18:53:25 -0000 1.7
> +++ linux/drivers/media/dvb/b2c2/flexcop.c 25 Sep 2005
16:52:09 -0000
> @@ -193,6 +193,7 @@
> v204 = fc->read_ibi_reg(fc,misc_204);
> v204.misc_204.Per_reset_sig = 0;
> fc->write_ibi_reg(fc,misc_204,v204);
> + msleep(1);
> v204.misc_204.Per_reset_sig = 1;
> fc->write_ibi_reg(fc,misc_204,v204);
> }
> Index: linux/drivers/media/dvb/frontends/lgdt330x.c
>
===================================================================
> RCS
file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/lgdt330x.c,v
> retrieving revision 1.10
> diff -u -r1.10 lgdt330x.c
> --- linux/drivers/media/dvb/frontends/lgdt330x.c 10 Sep
2005 08:12:36 -0000 1.10
> +++ linux/drivers/media/dvb/frontends/lgdt330x.c 25 Sep
2005 16:52:09 -0000
> @@ -27,6 +27,7 @@
> * DViCO FusionHDTV 3 Gold-T
> * DViCO FusionHDTV 5 Gold
> * DViCO FusionHDTV 5 Lite
> + * Air2PC HD5000
> *
> * TODO:
> * signal strength always returns 0.
> @@ -218,7 +219,8 @@
> };
>
> static u8 lgdt3303_init_data[] = {
> - 0x4c, 0x14
> + 0x4c, 0x14,
> + 0x87, 0xF3
This may be a problem. This change flips the polarity of the
clock for the mpeg data transfer clock. The best I can tell
the CX2388x requires the default high clock. This change
flips that and may cause problems. It should be
conditionalized.
> };
>
> struct lgdt330x_state* state = fe->demodulator_priv;
> @@ -535,12 +537,28 @@
>
> static int lgdt330x_read_signal_strength(struct
dvb_frontend* fe, u16* strength)
> {
> - /* not directly available. */
> - *strength = 0;
> +
> + struct lgdt330x_state* state = fe->demodulator_priv;
> + u8 buf[3];
> +
> + switch (state->config->demod_chip) {
> + case LGDT3302:
> + i2c_read_demod_bytes(state, LGDT3302_AGC_RFIF_ACC0,
buf, sizeof(buf));
> + break;
> + case LGDT3303:
> + i2c_read_demod_bytes(state, LGDT3303_AGC_RFIF_ACC0,
buf, sizeof(buf));
> + break;
> + default:
> + return -ENODEV;
> + }
> +
> + /* This math was given from example from the windows
bbti driver */
> + *strength = (1700 - ((buf[0] & 0x07) << 8 | buf[2])) *
(0xFFFF/1700);
Why did you pick the IF AGC instead of the RF AGC?
I do not understand this math. The value returned is a 12
bit signed value. The sign is ignored. This is not good.
The calculation will always be meaningless because a small
negative number will look like a large positive number and
a large negative number will look like a small positive
number. It totally renders that data useless.
Next this useless number with a range of 0 to 2047 is
subtracted from 1700. Since 1700 is less than 2047 we may
have a signed number as the result. The result range is
-1700 to 347.
Now multiply this by 38 and we get a number that has a range
of -64600 to 13186. This is returned as a unsigned 16 bit
number with a range of 0 to 65535.
I just do not understand this math. It takes some
assumptions to get this to make any sense at all:
1) The sign of the number read from the chip never changes.
2) The value range of the least significant 11 bits read
from the chip is 0 to1700.
3) The intent is to return a value with no units that is
linear with the value from the chip such that a chip value
of 0 to 1700 results in a returned value of 65535 to 0.
> +
> return 0;
> }
>
The changes from here to the end of the file modified by
this patch optimize out some subtile differences between
the lgdt3302 and lgdt3303 in the snr calculations. The two
data sheets are different in this area.
I do not think this should be changed in this manner. I
think the SNR_IN_DB section needs to be reworked to be
available as an insmod option. I can make it available to
both lgdt3302 and lgdt3303 chips then. I will do this work
if there is interest.
> -static int lgdt3302_read_snr(struct dvb_frontend* fe,
u16* snr)
> +static int lgdt330x_read_snr(struct dvb_frontend* fe,
u16* snr)
> {
> #ifdef SNR_IN_DB
> /*
> @@ -598,7 +616,17 @@
> struct lgdt330x_state* state = (struct lgdt330x_state*)
fe->demodulator_priv;
>
> /* read both equalizer and phase tracker noise data */
> - i2c_read_demod_bytes(state, EQPH_ERR0, buf,
sizeof(buf));
> + switch (state->config->demod_chip) {
> + case LGDT3302:
> + i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf,
sizeof(buf));
> + break;
> + case LGDT3303:
> + i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf,
sizeof(buf));
> + break;
> + default:
> + return -ENODEV;
> + }
> +
>
> if (state->current_modulation == VSB_8) {
> /* Equalizer Mean-Square Error Register for VSB */
> @@ -634,7 +662,16 @@
> struct lgdt330x_state* state = (struct lgdt330x_state*)
fe->demodulator_priv;
>
> /* read both equalizer and pase tracker noise data */
> - i2c_read_demod_bytes(state, EQPH_ERR0, buf,
sizeof(buf));
> + switch (state->config->demod_chip) {
> + case LGDT3302:
> + i2c_read_demod_bytes(state, LGDT3302_EQPH_ERR0, buf,
sizeof(buf));
> + break;
> + case LGDT3303:
> + i2c_read_demod_bytes(state, LGDT3303_EQPH_ERR0, buf,
sizeof(buf));
> + break;
> + default:
> + return -ENODEV;
> + }
>
> if (state->current_modulation == VSB_8) {
> #if 0
> @@ -660,37 +697,6 @@
> return 0;
> }
>
> -static int lgdt3303_read_snr(struct dvb_frontend* fe,
u16* snr)
> -{
> - /* Return the raw noise value */
> - static u8 buf[5];/* read data buffer */
> - static u32 noise; /* noise value */
> - struct lgdt330x_state* state = (struct lgdt330x_state*)
fe->demodulator_priv;
> -
> - if (state->current_modulation == VSB_8) {
> -
> -#if 0
> - /* Equalizer Mean-Square Error Register for VSB */
> - noise = ((buf[0] & 0x78) << 13) | (buf[1] << 8) |
buf[2];
> -#else
> - /* Phase Tracker Mean-Square Error Register for VSB */
> - noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
> -#endif
> - } else {
> -
> - /* Carrier Recovery Mean-Square Error for QAM */
> - i2c_read_demod_bytes(state, 0x1a, buf, 2);
> - noise = (buf[0] << 8) | buf[1];
> - }
> -
> - /* Small values for noise mean signal is better so
invert noise */
> - *snr = ~noise;
> -
> - dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__,
noise, *snr);
> -
> - return 0;
> -}
> -
> static int lgdt330x_get_tune_settings(struct
dvb_frontend* fe, struct dvb_frontend_tune_settings*
fe_tune_settings)
> {
> /* I have no idea about this - it may not be needed */
> @@ -773,7 +779,7 @@
> .read_status = lgdt3302_read_status,
> .read_ber = lgdt330x_read_ber,
> .read_signal_strength = lgdt330x_read_signal_strength,
> - .read_snr = lgdt3302_read_snr,
> + .read_snr = lgdt330x_read_snr,
> .read_ucblocks = lgdt330x_read_ucblocks,
> .release = lgdt330x_release,
> };
> @@ -797,7 +803,7 @@
> .read_status = lgdt3303_read_status,
> .read_ber = lgdt330x_read_ber,
> .read_signal_strength = lgdt330x_read_signal_strength,
> - .read_snr = lgdt3303_read_snr,
> + .read_snr = lgdt330x_read_snr,
> .read_ucblocks = lgdt330x_read_ucblocks,
> .release = lgdt330x_release,
> };
> Index: linux/drivers/media/dvb/frontends/lgdt330x_priv.h
>
===================================================================
> RCS
file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/frontends/lgdt330x_priv.h,v
> retrieving revision 1.2
> diff -u -r1.2 lgdt330x_priv.h
> --- linux/drivers/media/dvb/frontends/lgdt330x_priv.h 26
Jul 2005 06:02:19 -0000 1.2
> +++ linux/drivers/media/dvb/frontends/lgdt330x_priv.h 25
Sep 2005 16:52:09 -0000
> @@ -46,19 +46,27 @@
> AGC_FUNC_CTRL1= 0x32,
> AGC_FUNC_CTRL2= 0x33,
> AGC_FUNC_CTRL3= 0x34,
> - AGC_RFIF_ACC0= 0x39,
> - AGC_RFIF_ACC1= 0x3a,
> - AGC_RFIF_ACC2= 0x3b,
> + LGDT3302_AGC_RFIF_ACC0= 0x39,
> + LGDT3302_AGC_RFIF_ACC1= 0x3a,
> + LGDT3302_AGC_RFIF_ACC2= 0x3b,
> AGC_STATUS= 0x3f,
> SYNC_STATUS_VSB= 0x43,
> - EQPH_ERR0= 0x47,
> - EQ_ERR1= 0x48,
> - EQ_ERR2= 0x49,
> - PH_ERR1= 0x4a,
> - PH_ERR2= 0x4b,
> + LGDT3302_EQPH_ERR0= 0x47,
> + LGDT3302_EQ_ERR1= 0x48,
> + LGDT3302_EQ_ERR2= 0x49,
> + LGDT3302_PH_ERR1= 0x4a,
> + LGDT3302_PH_ERR2= 0x4b,
> + LGDT3303_AGC_RFIF_ACC0= 0x52,
> + LGDT3303_AGC_RFIF_ACC1= 0x53,
> + LGDT3303_AGC_RFIF_ACC2= 0x54,
> DEMUX_CONTROL= 0x66,
> LGDT3302_PACKET_ERR_COUNTER1= 0x6a,
> LGDT3302_PACKET_ERR_COUNTER2= 0x6b,
> + LGDT3303_EQPH_ERR0= 0x6e,
> + LGDT3303_EQ_ERR1= 0x6f,
> + LGDT3303_EQ_ERR2= 0x70,
> + LGDT3303_PH_ERR1= 0x71,
> + LGDT3303_PH_ERR2= 0x72,
> LGDT3303_PACKET_ERR_COUNTER1= 0x8b,
> LGDT3303_PACKET_ERR_COUNTER2= 0x8c,
> };
>
On Monday 26 September 2005 03:23 pm, Taylor Jacob wrote:
> I have been very busy with work today, and would have
> posted this earlier.. Sorry.
>
> Here is the "cleaned up" patch for adding support for the
> Air2PC/Airstar2 HD5000 (LGDT3303 Frontend).
>
> http://www.digitalregime.com/patches/hd5000-cleanup.patch
>
> Changes to note from the last one I submitted are:
>
> - I have tried to impliment the SNR for the LGDT3303
> since it appears to be the same formula for the 3302 and
> 3303..
>
> - I have also tried to impliment the signal level based
> on information I was provided by BBTI.. I am not sure if
> this is correct for the 3302, and it is a unitless
> measure since I have no idea how it was calcualted.. I
> would need to spend some time digging it spec sheets for
> both and see if I can come up with something, but I only
> have the 3303 right now..
>
> - The serial_mpeg value needed to be set to 0x04 for the
> demux to return data.. I am not sure as to why but the
> suggested value of 0x40 didn't return any data from teh
> demux. (Could this have something to do with the wiring
> of the frontend to the demux?)
>
> - The frontend reset delay added to flexcop.c was reduced
> from 100 or 200ms to a reasonable 1ms which gives
> adequate time for the 3303 to reset..
>
> Also to note:
>
> I have also put together a few liner patch to make the
> older version of the DVICO FusionHDTV Gold3 work.. I have
> one that has a LGDT3302 and has a card id of 18ac:d800
> instead of 18ac:d820
> (CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T), but appears to be
> the same.. I will validate this and post this
> seperately..
>
> Taylor
>
>
>
>
> _______________________________________________
> linux-dvb mailing list
> linux-dvb at linuxtv.org
> http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb
More information about the linux-dvb
mailing list