diff options
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/m920x.c | 69 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/m920x.h | 32 |
2 files changed, 51 insertions, 50 deletions
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c index d48b24d9abf4..92f76c918c79 100644 --- a/drivers/media/dvb/dvb-usb/m920x.c +++ b/drivers/media/dvb/dvb-usb/m920x.c | |||
@@ -137,52 +137,45 @@ static int m9206_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
137 | int num) | 137 | int num) |
138 | { | 138 | { |
139 | struct dvb_usb_device *d = i2c_get_adapdata(adap); | 139 | struct dvb_usb_device *d = i2c_get_adapdata(adap); |
140 | struct m9206_state *m = d->priv; | 140 | int i, j; |
141 | int i; | ||
142 | int ret = 0; | 141 | int ret = 0; |
143 | 142 | ||
144 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | 143 | if (mutex_lock_interruptible(&d->i2c_mutex) < 0) |
145 | return -EAGAIN; | 144 | return -EAGAIN; |
146 | 145 | ||
147 | if (num > 2) | ||
148 | return -EINVAL; | ||
149 | |||
150 | for (i = 0; i < num; i++) { | 146 | for (i = 0; i < num; i++) { |
151 | if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].addr, 0x80)) != 0) | 147 | if (msg[i].flags & I2C_M_RD) { |
152 | goto unlock; | ||
153 | |||
154 | if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[0], 0x0)) != 0) | ||
155 | goto unlock; | ||
156 | |||
157 | if (i + 1 < num && msg[i + 1].flags & I2C_M_RD) { | ||
158 | int i2c_i; | ||
159 | |||
160 | for (i2c_i = 0; i2c_i < M9206_I2C_MAX; i2c_i++) | ||
161 | if (msg[i].addr == m->i2c_r[i2c_i].addr) | ||
162 | break; | ||
163 | 148 | ||
164 | if (i2c_i >= M9206_I2C_MAX) { | 149 | if ((ret = m9206_write(d->udev, M9206_I2C, (msg[i].addr << 1) | 0x01, 0x80)) != 0) |
165 | deb_rc("No magic for i2c addr!\n"); | ||
166 | ret = -EINVAL; | ||
167 | goto unlock; | 150 | goto unlock; |
151 | |||
152 | for(j = 0; j < msg[i].len; j++) { | ||
153 | if (j + 1 == msg[i].len && i + 1== num) { | ||
154 | if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x60, &msg[i].buf[j], msg[i].len)) != 0) | ||
155 | goto unlock; | ||
156 | } else { | ||
157 | if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x21, &msg[i].buf[j], msg[i].len)) != 0) | ||
158 | goto unlock; | ||
159 | } | ||
168 | } | 160 | } |
169 | 161 | ||
170 | if ((ret = m9206_write(d->udev, M9206_I2C, m->i2c_r[i2c_i].magic, 0x80)) != 0) | 162 | } else { |
163 | if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].addr << 1, 0x80)) != 0) | ||
171 | goto unlock; | 164 | goto unlock; |
172 | 165 | ||
173 | if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x60, msg[i + 1].buf, msg[i + 1].len)) != 0) | 166 | for(j = 0; j < msg[i].len; j++) { |
174 | goto unlock; | 167 | if (j + 1 == msg[i].len && i + 1== num) { |
168 | if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[j], 0x40)) != 0) | ||
169 | goto unlock; | ||
175 | 170 | ||
176 | i++; | 171 | } else { |
177 | } else { | 172 | if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[j], 0x0)) != 0) |
178 | if (msg[i].len != 2) | 173 | goto unlock; |
179 | return -EINVAL; | 174 | } |
180 | 175 | } | |
181 | if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[1], 0x40)) != 0) | ||
182 | goto unlock; | ||
183 | } | 176 | } |
184 | } | 177 | } |
185 | ret = i; | 178 | ret = num; |
186 | unlock: | 179 | unlock: |
187 | mutex_unlock(&d->i2c_mutex); | 180 | mutex_unlock(&d->i2c_mutex); |
188 | 181 | ||
@@ -381,20 +374,15 @@ static int megasky_mt352_demod_init(struct dvb_frontend *fe) | |||
381 | } | 374 | } |
382 | 375 | ||
383 | static struct mt352_config megasky_mt352_config = { | 376 | static struct mt352_config megasky_mt352_config = { |
384 | .demod_address = 0x1e, | 377 | .demod_address = 0x0f, |
385 | .no_tuner = 1, | 378 | .no_tuner = 1, |
386 | .demod_init = megasky_mt352_demod_init, | 379 | .demod_init = megasky_mt352_demod_init, |
387 | }; | 380 | }; |
388 | 381 | ||
389 | static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap) | 382 | static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap) |
390 | { | 383 | { |
391 | struct m9206_state *m = adap->dev->priv; | ||
392 | |||
393 | deb_rc("megasky_frontend_attach!\n"); | 384 | deb_rc("megasky_frontend_attach!\n"); |
394 | 385 | ||
395 | m->i2c_r[M9206_I2C_DEMOD].addr = megasky_mt352_config.demod_address; | ||
396 | m->i2c_r[M9206_I2C_DEMOD].magic = 0x1f; | ||
397 | |||
398 | if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL) | 386 | if ((adap->fe = dvb_attach(mt352_attach, &megasky_mt352_config, &adap->dev->i2c_adap)) == NULL) |
399 | return -EIO; | 387 | return -EIO; |
400 | 388 | ||
@@ -402,16 +390,11 @@ static int megasky_mt352_frontend_attach(struct dvb_usb_adapter *adap) | |||
402 | } | 390 | } |
403 | 391 | ||
404 | static struct qt1010_config megasky_qt1010_config = { | 392 | static struct qt1010_config megasky_qt1010_config = { |
405 | .i2c_address = 0xc4 | 393 | .i2c_address = 0x62 |
406 | }; | 394 | }; |
407 | 395 | ||
408 | static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap) | 396 | static int megasky_qt1010_tuner_attach(struct dvb_usb_adapter *adap) |
409 | { | 397 | { |
410 | struct m9206_state *m = adap->dev->priv; | ||
411 | |||
412 | m->i2c_r[M9206_I2C_TUNER].addr = megasky_qt1010_config.i2c_address; | ||
413 | m->i2c_r[M9206_I2C_TUNER].magic = 0xc5; | ||
414 | |||
415 | if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, | 398 | if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, |
416 | &megasky_qt1010_config) == NULL) | 399 | &megasky_qt1010_config) == NULL) |
417 | return -ENODEV; | 400 | return -ENODEV; |
diff --git a/drivers/media/dvb/dvb-usb/m920x.h b/drivers/media/dvb/dvb-usb/m920x.h index c354196ffe5d..c5ef592cbfee 100644 --- a/drivers/media/dvb/dvb-usb/m920x.h +++ b/drivers/media/dvb/dvb-usb/m920x.h | |||
@@ -19,17 +19,35 @@ | |||
19 | 19 | ||
20 | #define M9206_MAX_FILTERS 8 | 20 | #define M9206_MAX_FILTERS 8 |
21 | 21 | ||
22 | #define M9206_I2C_TUNER 0 | 22 | /* |
23 | #define M9206_I2C_DEMOD 1 | 23 | sequences found in logs: |
24 | #define M9206_I2C_MAX 2 | 24 | [index value] |
25 | 0x80 write addr | ||
26 | (0x00 out byte)* | ||
27 | 0x40 out byte | ||
28 | |||
29 | 0x80 write addr | ||
30 | (0x00 out byte)* | ||
31 | 0x80 read addr | ||
32 | (0x21 in byte)* | ||
33 | 0x60 in byte | ||
34 | |||
35 | this sequence works: | ||
36 | 0x80 read addr | ||
37 | (0x21 in byte)* | ||
38 | 0x60 in byte | ||
39 | |||
40 | _my guess_: | ||
41 | 0x80: begin i2c transfer using address. value=address<<1|(reading?1:0) | ||
42 | 0x00: write byte | ||
43 | 0x21: read byte, more to follow | ||
44 | 0x40: write last byte of message sequence | ||
45 | 0x60: read last byte of message sequence | ||
46 | */ | ||
25 | 47 | ||
26 | struct m9206_state { | 48 | struct m9206_state { |
27 | u16 filters[M9206_MAX_FILTERS]; | 49 | u16 filters[M9206_MAX_FILTERS]; |
28 | int filtering_enabled; | 50 | int filtering_enabled; |
29 | int rep_count; | 51 | int rep_count; |
30 | struct { | ||
31 | unsigned char addr; | ||
32 | unsigned char magic; | ||
33 | }i2c_r[M9206_I2C_MAX]; | ||
34 | }; | 52 | }; |
35 | #endif | 53 | #endif |