Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[pandora-kernel.git] / drivers / media / dvb / frontends / mt352.c
index d32dc4d..5de7376 100644 (file)
@@ -35,6 +35,8 @@
 #include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/slab.h>
 
 #include "dvb_frontend.h"
 #include "mt352_priv.h"
@@ -43,7 +45,6 @@
 struct mt352_state {
        struct i2c_adapter* i2c;
        struct dvb_frontend frontend;
-       struct dvb_frontend_ops ops;
 
        /* configuration settings */
        struct mt352_config config;
@@ -284,16 +285,25 @@ static int mt352_set_parameters(struct dvb_frontend* fe,
 
        mt352_calc_nominal_rate(state, op->bandwidth, buf+4);
        mt352_calc_input_freq(state, buf+6);
-       state->config.pll_set(fe, param, buf+8);
 
-       mt352_write(fe, buf, sizeof(buf));
        if (state->config.no_tuner) {
-               /* start decoding */
+               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);
+               }
+
+               mt352_write(fe, buf, 8);
                mt352_write(fe, fsm_go, 2);
        } else {
-               /* start tuning */
-               mt352_write(fe, tuner_go, 2);
+               if (fe->ops.tuner_ops.calc_regs) {
+                       fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5);
+                       buf[8] <<= 1;
+                       mt352_write(fe, buf, sizeof(buf));
+                       mt352_write(fe, tuner_go, 2);
+               }
        }
+
        return 0;
 }
 
@@ -462,9 +472,11 @@ static int mt352_read_signal_strength(struct dvb_frontend* fe, u16* strength)
 {
        struct mt352_state* state = fe->demodulator_priv;
 
-       u16 signal = ((mt352_read_register(state, AGC_GAIN_1) << 8) & 0x0f) |
-                     (mt352_read_register(state, AGC_GAIN_0));
+       /* align the 12 bit AGC gain with the most significant bits */
+       u16 signal = ((mt352_read_register(state, AGC_GAIN_1) & 0x0f) << 12) |
+               (mt352_read_register(state, AGC_GAIN_0) << 4);
 
+       /* inverse of gain is signal strength */
        *strength = ~signal;
        return 0;
 }
@@ -531,20 +543,18 @@ struct dvb_frontend* mt352_attach(const struct mt352_config* config,
        struct mt352_state* state = NULL;
 
        /* allocate memory for the internal state */
-       state = kmalloc(sizeof(struct mt352_state), GFP_KERNEL);
+       state = kzalloc(sizeof(struct mt352_state), GFP_KERNEL);
        if (state == NULL) goto error;
-       memset(state,0,sizeof(*state));
 
        /* setup the state */
        state->i2c = i2c;
        memcpy(&state->config,config,sizeof(struct mt352_config));
-       memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
 
        /* check if the demod is there */
        if (mt352_read_register(state, CHIP_ID) != ID_MT352) goto error;
 
        /* create dvb_frontend */
-       state->frontend.ops = &state->ops;
+       memcpy(&state->frontend.ops, &mt352_ops, sizeof(struct dvb_frontend_ops));
        state->frontend.demodulator_priv = state;
        return &state->frontend;