]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/media/dvb/frontends/lgdt330x.c
V4L/DVB (4176): Bug-fix: Fix memory overflow
[linux-2.6-omap-h63xx.git] / drivers / media / dvb / frontends / lgdt330x.c
index 10fc4e7878af2079a2def44c2e262181a2132c96..6e8ad176e1a1468f0bbb3bf197232e850361f0d6 100644 (file)
@@ -27,7 +27,9 @@
  *   DViCO FusionHDTV 3 Gold-T
  *   DViCO FusionHDTV 5 Gold
  *   DViCO FusionHDTV 5 Lite
+ *   DViCO FusionHDTV 5 USB Gold
  *   Air2PC/AirStar 2 ATSC 3rd generation (HD5000)
+ *   pcHDTV HD5500
  *
  * TODO:
  * signal strength always returns 0.
@@ -58,7 +60,6 @@ if (debug) printk(KERN_DEBUG "lgdt330x: " args); \
 struct lgdt330x_state
 {
        struct i2c_adapter* i2c;
-       struct dvb_frontend_ops ops;
 
        /* Configuration settings */
        const struct lgdt330x_config* config;
@@ -301,10 +302,10 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe,
        static u8 lgdt3303_8vsb_44_data[] = {
                0x04, 0x00,
                0x0d, 0x40,
-        0x0e, 0x87,
-        0x0f, 0x8e,
-        0x10, 0x01,
-        0x47, 0x8b };
+       0x0e, 0x87,
+       0x0f, 0x8e,
+       0x10, 0x01,
+       0x47, 0x8b };
 
        /*
         * Array of byte pairs <address, value>
@@ -398,10 +399,14 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe,
        }
 
        /* Tune to the specified frequency */
-       if (state->config->pll_set)
-               state->config->pll_set(fe, param);
+       if (fe->ops.tuner_ops.set_params) {
+               fe->ops.tuner_ops.set_params(fe, param);
+               if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
+       }
 
        /* Keep track of the new frequency */
+       /* FIXME this is the wrong way to do this...           */
+       /* The tuner is shared with the video4linux analog API */
        state->current_frequency = param->frequency;
 
        lgdt330x_SwReset(state);
@@ -669,6 +674,7 @@ static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
 
        if (state->current_modulation == VSB_8) {
 
+               i2c_read_demod_bytes(state, 0x6e, buf, 5);
                /* Phase Tracker Mean-Square Error Register for VSB */
                noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4];
        } else {
@@ -711,24 +717,26 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
        u8 buf[1];
 
        /* Allocate memory for the internal state */
-       state = (struct lgdt330x_state*) kmalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct lgdt330x_state), GFP_KERNEL);
        if (state == NULL)
                goto error;
-       memset(state,0,sizeof(*state));
 
        /* Setup the state */
        state->config = config;
        state->i2c = i2c;
+
+       /* Create dvb_frontend */
        switch (config->demod_chip) {
        case LGDT3302:
-               memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
+               memcpy(&state->frontend.ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops));
                break;
        case LGDT3303:
-               memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
+               memcpy(&state->frontend.ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops));
                break;
        default:
                goto error;
        }
+       state->frontend.demodulator_priv = state;
 
        /* Verify communication with demod chip */
        if (i2c_read_demod_bytes(state, 2, buf, 1))
@@ -737,9 +745,6 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
        state->current_frequency = -1;
        state->current_modulation = -1;
 
-       /* Create dvb_frontend */
-       state->frontend.ops = &state->ops;
-       state->frontend.demodulator_priv = state;
        return &state->frontend;
 
 error:
@@ -755,9 +760,8 @@ static struct dvb_frontend_ops lgdt3302_ops = {
                .frequency_min= 54000000,
                .frequency_max= 858000000,
                .frequency_stepsize= 62500,
-               /* Symbol rate is for all VSB modes need to check QAM */
-               .symbol_rate_min    = 10762000,
-               .symbol_rate_max    = 10762000,
+               .symbol_rate_min    = 5056941,  /* QAM 64 */
+               .symbol_rate_max    = 10762000, /* VSB 8  */
                .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
        },
        .init                 = lgdt330x_init,
@@ -779,9 +783,8 @@ static struct dvb_frontend_ops lgdt3303_ops = {
                .frequency_min= 54000000,
                .frequency_max= 858000000,
                .frequency_stepsize= 62500,
-               /* Symbol rate is for all VSB modes need to check QAM */
-               .symbol_rate_min    = 10762000,
-               .symbol_rate_max    = 10762000,
+               .symbol_rate_min    = 5056941,  /* QAM 64 */
+               .symbol_rate_max    = 10762000, /* VSB 8  */
                .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
        },
        .init                 = lgdt330x_init,