diff options
| author | Manu Abraham <abraham.manu@gmail.com> | 2007-09-24 12:27:06 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-29 14:53:16 -0500 |
| commit | c7d85a2debb07af67c4915c972a352b68cda9022 (patch) | |
| tree | 757e447f0dcd09a250beb81a5b7cb34eb42b083d /drivers | |
| parent | de29eb82595684c937cf0e2578479f4fcb9c9e40 (diff) | |
V4L/DVB (9397): fix some bugs at tda8261
Fix bug obviously, some enhancements as well
* enable i2c_gate before doing any transaction
* read is one single message with 2 words
* reduce sleep from 100mS to 20mS
Signed-off-by: Manu Abraham <manu@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/media/dvb/frontends/tda8261.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/media/dvb/frontends/tda8261.c b/drivers/media/dvb/frontends/tda8261.c index 1b3d491445af..a6cd2b362b6e 100644 --- a/drivers/media/dvb/frontends/tda8261.c +++ b/drivers/media/dvb/frontends/tda8261.c | |||
| @@ -37,14 +37,15 @@ struct tda8261_state { | |||
| 37 | 37 | ||
| 38 | static int tda8261_read(struct tda8261_state *state, u8 *buf) | 38 | static int tda8261_read(struct tda8261_state *state, u8 *buf) |
| 39 | { | 39 | { |
| 40 | struct dvb_frontend *fe = state->fe; | ||
| 40 | const struct tda8261_config *config = state->config; | 41 | const struct tda8261_config *config = state->config; |
| 41 | int err = 0; | 42 | int err = 0; |
| 42 | struct i2c_msg msg[] = { | 43 | struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 2 }; |
| 43 | { .addr = config->addr, .flags = 0, .buf = NULL, .len = 0 }, | ||
| 44 | { .addr = config->addr, .flags = I2C_M_RD,.buf = buf, .len = 1 } | ||
| 45 | }; | ||
| 46 | 44 | ||
| 47 | if ((err = i2c_transfer(state->i2c, msg, 2)) != 2) | 45 | if (fe->ops.i2c_gate_ctrl) |
| 46 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 47 | |||
| 48 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) | ||
| 48 | printk("%s: read error, err=%d\n", __func__, err); | 49 | printk("%s: read error, err=%d\n", __func__, err); |
| 49 | 50 | ||
| 50 | return err; | 51 | return err; |
| @@ -52,12 +53,16 @@ static int tda8261_read(struct tda8261_state *state, u8 *buf) | |||
| 52 | 53 | ||
| 53 | static int tda8261_write(struct tda8261_state *state, u8 *buf) | 54 | static int tda8261_write(struct tda8261_state *state, u8 *buf) |
| 54 | { | 55 | { |
| 56 | struct dvb_frontend *fe = state->fe; | ||
| 55 | const struct tda8261_config *config = state->config; | 57 | const struct tda8261_config *config = state->config; |
| 56 | int err = 0; | 58 | int err = 0; |
| 57 | struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 }; | 59 | struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = 4 }; |
| 58 | 60 | ||
| 61 | if (fe->ops.i2c_gate_ctrl) | ||
| 62 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
| 63 | |||
| 59 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) | 64 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) |
| 60 | printk("%s: read error, err=%d\n", __func__, err); | 65 | printk("%s: write error, err=%d\n", __func__, err); |
| 61 | 66 | ||
| 62 | return err; | 67 | return err; |
| 63 | } | 68 | } |
| @@ -124,20 +129,21 @@ static int tda8261_set_state(struct dvb_frontend *fe, | |||
| 124 | */ | 129 | */ |
| 125 | frequency = tstate->frequency; | 130 | frequency = tstate->frequency; |
| 126 | N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size]; | 131 | N = (frequency + (div_tab[config->step_size] - 1)) / div_tab[config->step_size]; |
| 132 | printk("%s: Step size=%d, Divider=%d, PG=0x%02x (%d)\n", | ||
| 133 | __func__, config->step_size, div_tab[config->step_size], N, N); | ||
| 134 | |||
| 127 | buf[0] = (N >> 8) & 0xff; | 135 | buf[0] = (N >> 8) & 0xff; |
| 128 | buf[1] = N & 0xff; | 136 | buf[1] = N & 0xff; |
| 129 | buf[2] = (0x08 << 4) | ((ref_div[config->step_size] & 0x07) << 1); | 137 | buf[2] = (0x01 << 7) | ((ref_div[config->step_size] & 0x07) << 1); |
| 130 | buf[3] = 0xc0; | 138 | buf[3] = 0xc0; |
| 131 | /* Set params */ | 139 | /* Set params */ |
| 132 | printk("%s: Frequency=%d, Sending[ %02x %02x %02x %02x ]\n", | ||
| 133 | __func__, frequency, buf[0], buf[1], buf[2], buf[3]); | ||
| 134 | |||
| 135 | if ((err = tda8261_write(state, buf)) < 0) { | 140 | if ((err = tda8261_write(state, buf)) < 0) { |
| 136 | printk("%s: I/O Error\n", __func__); | 141 | printk("%s: I/O Error\n", __func__); |
| 137 | return err; | 142 | return err; |
| 138 | } | 143 | } |
| 139 | /* sleep for some time */ | 144 | /* sleep for some time */ |
| 140 | msleep(100); | 145 | printk("%s: Waiting to Phase LOCK\n", __func__); |
| 146 | msleep(20); | ||
| 141 | /* check status */ | 147 | /* check status */ |
| 142 | if ((err = tda8261_get_status(fe, &status)) < 0) { | 148 | if ((err = tda8261_get_status(fe, &status)) < 0) { |
| 143 | printk("%s: I/O Error\n", __func__); | 149 | printk("%s: I/O Error\n", __func__); |
| @@ -145,7 +151,7 @@ static int tda8261_set_state(struct dvb_frontend *fe, | |||
| 145 | } | 151 | } |
| 146 | if (status == 1) { | 152 | if (status == 1) { |
| 147 | printk("%s: Tuner Phase locked: status=%d\n", __func__, status); | 153 | printk("%s: Tuner Phase locked: status=%d\n", __func__, status); |
| 148 | state->frequency = frequency; /* cache last successful */ | 154 | state->frequency = frequency; /* cache successful state */ |
| 149 | } else { | 155 | } else { |
| 150 | printk("%s: No Phase lock: status=%d\n", __func__, status); | 156 | printk("%s: No Phase lock: status=%d\n", __func__, status); |
| 151 | } | 157 | } |
| @@ -203,7 +209,6 @@ struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, | |||
| 203 | // __func__, fe->ops.tuner_ops.tuner_name); | 209 | // __func__, fe->ops.tuner_ops.tuner_name); |
| 204 | printk("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__); | 210 | printk("%s: Attaching TDA8261 8PSK/QPSK tuner\n", __func__); |
| 205 | 211 | ||
| 206 | |||
| 207 | return fe; | 212 | return fe; |
| 208 | 213 | ||
| 209 | exit: | 214 | exit: |
