blob: addffc33993a9dc234e479ac0f55d91d536eeed1 [file] [log] [blame]
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001/*
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03002 Montage Technology DS3000 - DVBS/S2 Demodulator driver
3 Copyright (C) 2009-2012 Konstantin Dimitrov <kosio.dimitrov@gmail.com>
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03004
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03005 Copyright (C) 2009-2012 TurboSight.com
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/slab.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/firmware.h>
28
29#include "dvb_frontend.h"
Konstantin Dimitrov73f0af42012-12-23 19:25:38 -030030#include "ts2020.h"
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -030031#include "ds3000.h"
32
33static int debug;
34
35#define dprintk(args...) \
36 do { \
37 if (debug) \
38 printk(args); \
39 } while (0)
40
41/* as of March 2009 current DS3000 firmware version is 1.78 */
42/* DS3000 FW v1.78 MD5: a32d17910c4f370073f9346e71d34b80 */
43#define DS3000_DEFAULT_FIRMWARE "dvb-fe-ds3000.fw"
44
45#define DS3000_SAMPLE_RATE 96000 /* in kHz */
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -030046
47/* Register values to initialise the demod in DVB-S mode */
48static u8 ds3000_dvbs_init_tab[] = {
49 0x23, 0x05,
50 0x08, 0x03,
51 0x0c, 0x00,
52 0x21, 0x54,
53 0x25, 0x82,
54 0x27, 0x31,
55 0x30, 0x08,
56 0x31, 0x40,
57 0x32, 0x32,
58 0x33, 0x35,
59 0x35, 0xff,
60 0x3a, 0x00,
61 0x37, 0x10,
62 0x38, 0x10,
63 0x39, 0x02,
64 0x42, 0x60,
65 0x4a, 0x40,
66 0x4b, 0x04,
67 0x4d, 0x91,
68 0x5d, 0xc8,
69 0x50, 0x77,
70 0x51, 0x77,
71 0x52, 0x36,
72 0x53, 0x36,
73 0x56, 0x01,
74 0x63, 0x43,
75 0x64, 0x30,
76 0x65, 0x40,
77 0x68, 0x26,
78 0x69, 0x4c,
79 0x70, 0x20,
80 0x71, 0x70,
81 0x72, 0x04,
82 0x73, 0x00,
83 0x70, 0x40,
84 0x71, 0x70,
85 0x72, 0x04,
86 0x73, 0x00,
87 0x70, 0x60,
88 0x71, 0x70,
89 0x72, 0x04,
90 0x73, 0x00,
91 0x70, 0x80,
92 0x71, 0x70,
93 0x72, 0x04,
94 0x73, 0x00,
95 0x70, 0xa0,
96 0x71, 0x70,
97 0x72, 0x04,
98 0x73, 0x00,
99 0x70, 0x1f,
100 0x76, 0x00,
101 0x77, 0xd1,
102 0x78, 0x0c,
103 0x79, 0x80,
104 0x7f, 0x04,
105 0x7c, 0x00,
106 0x80, 0x86,
107 0x81, 0xa6,
108 0x85, 0x04,
109 0xcd, 0xf4,
110 0x90, 0x33,
111 0xa0, 0x44,
112 0xc0, 0x18,
113 0xc3, 0x10,
114 0xc4, 0x08,
115 0xc5, 0x80,
116 0xc6, 0x80,
117 0xc7, 0x0a,
118 0xc8, 0x1a,
119 0xc9, 0x80,
120 0xfe, 0x92,
121 0xe0, 0xf8,
122 0xe6, 0x8b,
123 0xd0, 0x40,
124 0xf8, 0x20,
125 0xfa, 0x0f,
126 0xfd, 0x20,
127 0xad, 0x20,
128 0xae, 0x07,
129 0xb8, 0x00,
130};
131
132/* Register values to initialise the demod in DVB-S2 mode */
133static u8 ds3000_dvbs2_init_tab[] = {
134 0x23, 0x0f,
135 0x08, 0x07,
136 0x0c, 0x00,
137 0x21, 0x54,
138 0x25, 0x82,
139 0x27, 0x31,
140 0x30, 0x08,
141 0x31, 0x32,
142 0x32, 0x32,
143 0x33, 0x35,
144 0x35, 0xff,
145 0x3a, 0x00,
146 0x37, 0x10,
147 0x38, 0x10,
148 0x39, 0x02,
149 0x42, 0x60,
150 0x4a, 0x80,
151 0x4b, 0x04,
152 0x4d, 0x81,
153 0x5d, 0x88,
154 0x50, 0x36,
155 0x51, 0x36,
156 0x52, 0x36,
157 0x53, 0x36,
158 0x63, 0x60,
159 0x64, 0x10,
160 0x65, 0x10,
161 0x68, 0x04,
162 0x69, 0x29,
163 0x70, 0x20,
164 0x71, 0x70,
165 0x72, 0x04,
166 0x73, 0x00,
167 0x70, 0x40,
168 0x71, 0x70,
169 0x72, 0x04,
170 0x73, 0x00,
171 0x70, 0x60,
172 0x71, 0x70,
173 0x72, 0x04,
174 0x73, 0x00,
175 0x70, 0x80,
176 0x71, 0x70,
177 0x72, 0x04,
178 0x73, 0x00,
179 0x70, 0xa0,
180 0x71, 0x70,
181 0x72, 0x04,
182 0x73, 0x00,
183 0x70, 0x1f,
184 0xa0, 0x44,
185 0xc0, 0x08,
186 0xc1, 0x10,
187 0xc2, 0x08,
188 0xc3, 0x10,
189 0xc4, 0x08,
190 0xc5, 0xf0,
191 0xc6, 0xf0,
192 0xc7, 0x0a,
193 0xc8, 0x1a,
194 0xc9, 0x80,
195 0xca, 0x23,
196 0xcb, 0x24,
197 0xce, 0x74,
198 0x90, 0x03,
199 0x76, 0x80,
200 0x77, 0x42,
201 0x78, 0x0a,
202 0x79, 0x80,
203 0xad, 0x40,
204 0xae, 0x07,
205 0x7f, 0xd4,
206 0x7c, 0x00,
207 0x80, 0xa8,
208 0x81, 0xda,
209 0x7c, 0x01,
210 0x80, 0xda,
211 0x81, 0xec,
212 0x7c, 0x02,
213 0x80, 0xca,
214 0x81, 0xeb,
215 0x7c, 0x03,
216 0x80, 0xba,
217 0x81, 0xdb,
218 0x85, 0x08,
219 0x86, 0x00,
220 0x87, 0x02,
221 0x89, 0x80,
222 0x8b, 0x44,
223 0x8c, 0xaa,
224 0x8a, 0x10,
225 0xba, 0x00,
226 0xf5, 0x04,
227 0xfe, 0x44,
228 0xd2, 0x32,
229 0xb8, 0x00,
230};
231
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300232struct ds3000_state {
233 struct i2c_adapter *i2c;
234 const struct ds3000_config *config;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300235 struct dvb_frontend frontend;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300236 /* previous uncorrected block counter for DVB-S2 */
237 u16 prevUCBS2;
238};
239
240static int ds3000_writereg(struct ds3000_state *state, int reg, int data)
241{
242 u8 buf[] = { reg, data };
243 struct i2c_msg msg = { .addr = state->config->demod_address,
244 .flags = 0, .buf = buf, .len = 2 };
245 int err;
246
247 dprintk("%s: write reg 0x%02x, value 0x%02x\n", __func__, reg, data);
248
249 err = i2c_transfer(state->i2c, &msg, 1);
250 if (err != 1) {
251 printk(KERN_ERR "%s: writereg error(err == %i, reg == 0x%02x,"
252 " value == 0x%02x)\n", __func__, err, reg, data);
253 return -EREMOTEIO;
254 }
255
256 return 0;
257}
258
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -0300259static int ds3000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300260{
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -0300261 struct ds3000_state *state = fe->demodulator_priv;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300262
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -0300263 if (enable)
264 ds3000_writereg(state, 0x03, 0x12);
265 else
266 ds3000_writereg(state, 0x03, 0x02);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300267
268 return 0;
269}
270
271/* I2C write for 8k firmware load */
272static int ds3000_writeFW(struct ds3000_state *state, int reg,
273 const u8 *data, u16 len)
274{
RĂ©mi Cardonad58f4f22012-09-28 08:59:29 -0300275 int i, ret = 0;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300276 struct i2c_msg msg;
277 u8 *buf;
278
Igor M. Liplianincaa687c2011-02-01 19:40:25 -0300279 buf = kmalloc(33, GFP_KERNEL);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300280 if (buf == NULL) {
281 printk(KERN_ERR "Unable to kmalloc\n");
RĂ©mi Cardonad58f4f22012-09-28 08:59:29 -0300282 return -ENOMEM;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300283 }
284
285 *(buf) = reg;
286
287 msg.addr = state->config->demod_address;
288 msg.flags = 0;
289 msg.buf = buf;
Igor M. Liplianincaa687c2011-02-01 19:40:25 -0300290 msg.len = 33;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300291
Igor M. Liplianincaa687c2011-02-01 19:40:25 -0300292 for (i = 0; i < len; i += 32) {
293 memcpy(buf + 1, data + i, 32);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300294
295 dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
296
297 ret = i2c_transfer(state->i2c, &msg, 1);
298 if (ret != 1) {
299 printk(KERN_ERR "%s: write error(err == %i, "
300 "reg == 0x%02x\n", __func__, ret, reg);
301 ret = -EREMOTEIO;
RĂ©mi Cardonad58f4f22012-09-28 08:59:29 -0300302 goto error;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300303 }
304 }
RĂ©mi Cardonad58f4f22012-09-28 08:59:29 -0300305 ret = 0;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300306
307error:
308 kfree(buf);
309
310 return ret;
311}
312
313static int ds3000_readreg(struct ds3000_state *state, u8 reg)
314{
315 int ret;
316 u8 b0[] = { reg };
317 u8 b1[] = { 0 };
318 struct i2c_msg msg[] = {
319 {
320 .addr = state->config->demod_address,
321 .flags = 0,
322 .buf = b0,
323 .len = 1
324 }, {
325 .addr = state->config->demod_address,
326 .flags = I2C_M_RD,
327 .buf = b1,
328 .len = 1
329 }
330 };
331
332 ret = i2c_transfer(state->i2c, msg, 2);
333
334 if (ret != 2) {
335 printk(KERN_ERR "%s: reg=0x%x(error=%d)\n", __func__, reg, ret);
336 return ret;
337 }
338
339 dprintk("%s: read reg 0x%02x, value 0x%02x\n", __func__, reg, b1[0]);
340
341 return b1[0];
342}
343
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300344static int ds3000_load_firmware(struct dvb_frontend *fe,
345 const struct firmware *fw);
346
347static int ds3000_firmware_ondemand(struct dvb_frontend *fe)
348{
349 struct ds3000_state *state = fe->demodulator_priv;
350 const struct firmware *fw;
351 int ret = 0;
352
353 dprintk("%s()\n", __func__);
354
RĂ©mi Cardona034351f2012-09-28 08:59:31 -0300355 ret = ds3000_readreg(state, 0xb2);
356 if (ret < 0)
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300357 return ret;
358
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300359 /* Load firmware */
360 /* request the firmware, this will block until someone uploads it */
361 printk(KERN_INFO "%s: Waiting for firmware upload (%s)...\n", __func__,
362 DS3000_DEFAULT_FIRMWARE);
363 ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE,
364 state->i2c->dev.parent);
365 printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__);
366 if (ret) {
367 printk(KERN_ERR "%s: No firmware uploaded (timeout or file not "
368 "found?)\n", __func__);
369 return ret;
370 }
371
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300372 ret = ds3000_load_firmware(fe, fw);
373 if (ret)
374 printk("%s: Writing firmware to device failed\n", __func__);
375
376 release_firmware(fw);
377
378 dprintk("%s: Firmware upload %s\n", __func__,
379 ret == 0 ? "complete" : "failed");
380
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300381 return ret;
382}
383
384static int ds3000_load_firmware(struct dvb_frontend *fe,
385 const struct firmware *fw)
386{
387 struct ds3000_state *state = fe->demodulator_priv;
RĂ©mi Cardonad58f4f22012-09-28 08:59:29 -0300388 int ret = 0;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300389
390 dprintk("%s\n", __func__);
391 dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n",
392 fw->size,
393 fw->data[0],
394 fw->data[1],
395 fw->data[fw->size - 2],
396 fw->data[fw->size - 1]);
397
398 /* Begin the firmware load process */
399 ds3000_writereg(state, 0xb2, 0x01);
400 /* write the entire firmware */
RĂ©mi Cardonad58f4f22012-09-28 08:59:29 -0300401 ret = ds3000_writeFW(state, 0xb0, fw->data, fw->size);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300402 ds3000_writereg(state, 0xb2, 0x00);
403
RĂ©mi Cardonad58f4f22012-09-28 08:59:29 -0300404 return ret;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300405}
406
Mauro Carvalho Chehab0df289a2015-06-07 14:53:52 -0300407static int ds3000_set_voltage(struct dvb_frontend *fe,
408 enum fe_sec_voltage voltage)
Igor M. Liplianind2ffc442011-02-25 18:41:22 -0300409{
410 struct ds3000_state *state = fe->demodulator_priv;
411 u8 data;
412
413 dprintk("%s(%d)\n", __func__, voltage);
414
415 data = ds3000_readreg(state, 0xa2);
416 data |= 0x03; /* bit0 V/H, bit1 off/on */
417
418 switch (voltage) {
419 case SEC_VOLTAGE_18:
420 data &= ~0x03;
421 break;
422 case SEC_VOLTAGE_13:
423 data &= ~0x03;
424 data |= 0x01;
425 break;
426 case SEC_VOLTAGE_OFF:
427 break;
428 }
429
430 ds3000_writereg(state, 0xa2, data);
431
432 return 0;
433}
434
Mauro Carvalho Chehab0df289a2015-06-07 14:53:52 -0300435static int ds3000_read_status(struct dvb_frontend *fe, enum fe_status *status)
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300436{
437 struct ds3000_state *state = fe->demodulator_priv;
438 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
439 int lock;
440
441 *status = 0;
442
443 switch (c->delivery_system) {
444 case SYS_DVBS:
445 lock = ds3000_readreg(state, 0xd1);
446 if ((lock & 0x07) == 0x07)
447 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
448 FE_HAS_VITERBI | FE_HAS_SYNC |
449 FE_HAS_LOCK;
450
451 break;
452 case SYS_DVBS2:
453 lock = ds3000_readreg(state, 0x0d);
454 if ((lock & 0x8f) == 0x8f)
455 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
456 FE_HAS_VITERBI | FE_HAS_SYNC |
457 FE_HAS_LOCK;
458
459 break;
460 default:
Olli Salonen27924dc2016-03-16 08:04:50 -0300461 return -EINVAL;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300462 }
463
Igor M. Liplianin43385c82012-12-28 19:40:24 -0300464 if (state->config->set_lock_led)
465 state->config->set_lock_led(fe, *status == 0 ? 0 : 1);
466
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300467 dprintk("%s: status = 0x%02x\n", __func__, lock);
468
469 return 0;
470}
471
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300472/* read DS3000 BER value */
473static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
474{
475 struct ds3000_state *state = fe->demodulator_priv;
476 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
477 u8 data;
478 u32 ber_reading, lpdc_frames;
479
480 dprintk("%s()\n", __func__);
481
482 switch (c->delivery_system) {
483 case SYS_DVBS:
484 /* set the number of bytes checked during
485 BER estimation */
486 ds3000_writereg(state, 0xf9, 0x04);
487 /* read BER estimation status */
488 data = ds3000_readreg(state, 0xf8);
489 /* check if BER estimation is ready */
490 if ((data & 0x10) == 0) {
491 /* this is the number of error bits,
492 to calculate the bit error rate
493 divide to 8388608 */
494 *ber = (ds3000_readreg(state, 0xf7) << 8) |
495 ds3000_readreg(state, 0xf6);
496 /* start counting error bits */
497 /* need to be set twice
498 otherwise it fails sometimes */
499 data |= 0x10;
500 ds3000_writereg(state, 0xf8, data);
501 ds3000_writereg(state, 0xf8, data);
502 } else
503 /* used to indicate that BER estimation
504 is not ready, i.e. BER is unknown */
505 *ber = 0xffffffff;
506 break;
507 case SYS_DVBS2:
508 /* read the number of LPDC decoded frames */
509 lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) |
510 (ds3000_readreg(state, 0xd6) << 8) |
511 ds3000_readreg(state, 0xd5);
512 /* read the number of packets with bad CRC */
513 ber_reading = (ds3000_readreg(state, 0xf8) << 8) |
514 ds3000_readreg(state, 0xf7);
515 if (lpdc_frames > 750) {
516 /* clear LPDC frame counters */
517 ds3000_writereg(state, 0xd1, 0x01);
518 /* clear bad packets counter */
519 ds3000_writereg(state, 0xf9, 0x01);
520 /* enable bad packets counter */
521 ds3000_writereg(state, 0xf9, 0x00);
522 /* enable LPDC frame counters */
523 ds3000_writereg(state, 0xd1, 0x00);
524 *ber = ber_reading;
525 } else
526 /* used to indicate that BER estimation is not ready,
527 i.e. BER is unknown */
528 *ber = 0xffffffff;
529 break;
530 default:
Olli Salonen27924dc2016-03-16 08:04:50 -0300531 return -EINVAL;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300532 }
533
534 return 0;
535}
536
Malcolm Priestleya0a030b2013-01-06 08:40:42 -0300537static int ds3000_read_signal_strength(struct dvb_frontend *fe,
538 u16 *signal_strength)
539{
540 if (fe->ops.tuner_ops.get_rf_strength)
541 fe->ops.tuner_ops.get_rf_strength(fe, signal_strength);
542
543 return 0;
544}
545
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300546/* calculate DS3000 snr value in dB */
547static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
548{
549 struct ds3000_state *state = fe->demodulator_priv;
550 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
551 u8 snr_reading, snr_value;
552 u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp;
553 static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */
554 0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03,
555 0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717,
556 0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505
557 };
558 static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */
559 0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103,
560 0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5,
561 0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6,
562 0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888,
563 0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51,
564 0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68,
565 0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206,
566 0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a,
567 0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649,
568 0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813,
569 0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1,
570 0x49e9, 0x4a20, 0x4a57
571 };
572
573 dprintk("%s()\n", __func__);
574
575 switch (c->delivery_system) {
576 case SYS_DVBS:
577 snr_reading = ds3000_readreg(state, 0xff);
578 snr_reading /= 8;
579 if (snr_reading == 0)
580 *snr = 0x0000;
581 else {
582 if (snr_reading > 20)
583 snr_reading = 20;
584 snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026;
585 /* cook the value to be suitable for szap-s2
586 human readable output */
587 *snr = snr_value * 8 * 655;
588 }
589 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
590 snr_reading, *snr);
591 break;
592 case SYS_DVBS2:
593 dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) +
594 (ds3000_readreg(state, 0x8d) << 4);
595 dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
596 tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
Nicolas Noirbent450df222010-03-22 14:54:43 -0300597 if (tmp == 0) {
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300598 *snr = 0x0000;
599 return 0;
600 }
601 if (dvbs2_noise_reading == 0) {
602 snr_value = 0x0013;
603 /* cook the value to be suitable for szap-s2
604 human readable output */
605 *snr = 0xffff;
606 return 0;
607 }
608 if (tmp > dvbs2_noise_reading) {
609 snr_reading = tmp / dvbs2_noise_reading;
610 if (snr_reading > 80)
611 snr_reading = 80;
612 snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000;
613 /* cook the value to be suitable for szap-s2
614 human readable output */
615 *snr = snr_value * 5 * 655;
616 } else {
617 snr_reading = dvbs2_noise_reading / tmp;
618 if (snr_reading > 80)
619 snr_reading = 80;
Heinrich Schuchardtb59de952014-02-27 23:04:08 -0300620 *snr = -(dvbs2_snr_tab[snr_reading - 1] / 1000);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300621 }
622 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
623 snr_reading, *snr);
624 break;
625 default:
Olli Salonen27924dc2016-03-16 08:04:50 -0300626 return -EINVAL;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300627 }
628
629 return 0;
630}
631
632/* read DS3000 uncorrected blocks */
633static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
634{
635 struct ds3000_state *state = fe->demodulator_priv;
636 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
637 u8 data;
638 u16 _ucblocks;
639
640 dprintk("%s()\n", __func__);
641
642 switch (c->delivery_system) {
643 case SYS_DVBS:
644 *ucblocks = (ds3000_readreg(state, 0xf5) << 8) |
645 ds3000_readreg(state, 0xf4);
646 data = ds3000_readreg(state, 0xf8);
647 /* clear packet counters */
648 data &= ~0x20;
649 ds3000_writereg(state, 0xf8, data);
650 /* enable packet counters */
651 data |= 0x20;
652 ds3000_writereg(state, 0xf8, data);
653 break;
654 case SYS_DVBS2:
655 _ucblocks = (ds3000_readreg(state, 0xe2) << 8) |
656 ds3000_readreg(state, 0xe1);
657 if (_ucblocks > state->prevUCBS2)
658 *ucblocks = _ucblocks - state->prevUCBS2;
659 else
660 *ucblocks = state->prevUCBS2 - _ucblocks;
661 state->prevUCBS2 = _ucblocks;
662 break;
663 default:
Olli Salonen27924dc2016-03-16 08:04:50 -0300664 return -EINVAL;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300665 }
666
667 return 0;
668}
669
Mauro Carvalho Chehab0df289a2015-06-07 14:53:52 -0300670static int ds3000_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300671{
672 struct ds3000_state *state = fe->demodulator_priv;
673 u8 data;
674
675 dprintk("%s(%d)\n", __func__, tone);
676 if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
677 printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
678 return -EINVAL;
679 }
680
681 data = ds3000_readreg(state, 0xa2);
682 data &= ~0xc0;
683 ds3000_writereg(state, 0xa2, data);
684
685 switch (tone) {
686 case SEC_TONE_ON:
687 dprintk("%s: setting tone on\n", __func__);
688 data = ds3000_readreg(state, 0xa1);
689 data &= ~0x43;
690 data |= 0x04;
691 ds3000_writereg(state, 0xa1, data);
692 break;
693 case SEC_TONE_OFF:
694 dprintk("%s: setting tone off\n", __func__);
695 data = ds3000_readreg(state, 0xa2);
696 data |= 0x80;
697 ds3000_writereg(state, 0xa2, data);
698 break;
699 }
700
701 return 0;
702}
703
704static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
705 struct dvb_diseqc_master_cmd *d)
706{
707 struct ds3000_state *state = fe->demodulator_priv;
708 int i;
709 u8 data;
710
711 /* Dump DiSEqC message */
712 dprintk("%s(", __func__);
713 for (i = 0 ; i < d->msg_len;) {
714 dprintk("0x%02x", d->msg[i]);
715 if (++i < d->msg_len)
716 dprintk(", ");
717 }
718
719 /* enable DiSEqC message send pin */
720 data = ds3000_readreg(state, 0xa2);
721 data &= ~0xc0;
722 ds3000_writereg(state, 0xa2, data);
723
724 /* DiSEqC message */
725 for (i = 0; i < d->msg_len; i++)
726 ds3000_writereg(state, 0xa3 + i, d->msg[i]);
727
728 data = ds3000_readreg(state, 0xa1);
729 /* clear DiSEqC message length and status,
730 enable DiSEqC message send */
731 data &= ~0xf8;
732 /* set DiSEqC mode, modulation active during 33 pulses,
733 set DiSEqC message length */
734 data |= ((d->msg_len - 1) << 3) | 0x07;
735 ds3000_writereg(state, 0xa1, data);
736
737 /* wait up to 150ms for DiSEqC transmission to complete */
738 for (i = 0; i < 15; i++) {
739 data = ds3000_readreg(state, 0xa1);
740 if ((data & 0x40) == 0)
741 break;
742 msleep(10);
743 }
744
745 /* DiSEqC timeout after 150ms */
746 if (i == 15) {
747 data = ds3000_readreg(state, 0xa1);
748 data &= ~0x80;
749 data |= 0x40;
750 ds3000_writereg(state, 0xa1, data);
751
752 data = ds3000_readreg(state, 0xa2);
753 data &= ~0xc0;
754 data |= 0x80;
755 ds3000_writereg(state, 0xa2, data);
756
Olli Salonen27924dc2016-03-16 08:04:50 -0300757 return -ETIMEDOUT;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300758 }
759
760 data = ds3000_readreg(state, 0xa2);
761 data &= ~0xc0;
762 data |= 0x80;
763 ds3000_writereg(state, 0xa2, data);
764
765 return 0;
766}
767
768/* Send DiSEqC burst */
769static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
Mauro Carvalho Chehab0df289a2015-06-07 14:53:52 -0300770 enum fe_sec_mini_cmd burst)
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300771{
772 struct ds3000_state *state = fe->demodulator_priv;
773 int i;
774 u8 data;
775
776 dprintk("%s()\n", __func__);
777
778 data = ds3000_readreg(state, 0xa2);
779 data &= ~0xc0;
780 ds3000_writereg(state, 0xa2, data);
781
782 /* DiSEqC burst */
783 if (burst == SEC_MINI_A)
784 /* Unmodulated tone burst */
785 ds3000_writereg(state, 0xa1, 0x02);
786 else if (burst == SEC_MINI_B)
787 /* Modulated tone burst */
788 ds3000_writereg(state, 0xa1, 0x01);
789 else
790 return -EINVAL;
791
792 msleep(13);
793 for (i = 0; i < 5; i++) {
794 data = ds3000_readreg(state, 0xa1);
795 if ((data & 0x40) == 0)
796 break;
797 msleep(1);
798 }
799
800 if (i == 5) {
801 data = ds3000_readreg(state, 0xa1);
802 data &= ~0x80;
803 data |= 0x40;
804 ds3000_writereg(state, 0xa1, data);
805
806 data = ds3000_readreg(state, 0xa2);
807 data &= ~0xc0;
808 data |= 0x80;
809 ds3000_writereg(state, 0xa2, data);
810
Olli Salonen27924dc2016-03-16 08:04:50 -0300811 return -ETIMEDOUT;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300812 }
813
814 data = ds3000_readreg(state, 0xa2);
815 data &= ~0xc0;
816 data |= 0x80;
817 ds3000_writereg(state, 0xa2, data);
818
819 return 0;
820}
821
822static void ds3000_release(struct dvb_frontend *fe)
823{
824 struct ds3000_state *state = fe->demodulator_priv;
Igor M. Liplianin43385c82012-12-28 19:40:24 -0300825
826 if (state->config->set_lock_led)
827 state->config->set_lock_led(fe, 0);
828
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300829 dprintk("%s\n", __func__);
830 kfree(state);
831}
832
833static struct dvb_frontend_ops ds3000_ops;
834
835struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
836 struct i2c_adapter *i2c)
837{
838 struct ds3000_state *state = NULL;
839 int ret;
840
841 dprintk("%s\n", __func__);
842
843 /* allocate memory for the internal state */
Julia Lawall2ef17c92010-05-13 16:59:15 -0300844 state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300845 if (state == NULL) {
846 printk(KERN_ERR "Unable to kmalloc\n");
847 goto error2;
848 }
849
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300850 state->config = config;
851 state->i2c = i2c;
852 state->prevUCBS2 = 0;
853
854 /* check if the demod is present */
855 ret = ds3000_readreg(state, 0x00) & 0xfe;
856 if (ret != 0xe0) {
857 printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
858 goto error3;
859 }
860
861 printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
862 ds3000_readreg(state, 0x02),
863 ds3000_readreg(state, 0x01));
864
865 memcpy(&state->frontend.ops, &ds3000_ops,
866 sizeof(struct dvb_frontend_ops));
867 state->frontend.demodulator_priv = state;
Ulrich Eckhardt8c5bcde2014-10-10 14:19:12 -0300868
869 /*
870 * Some devices like T480 starts with voltage on. Be sure
871 * to turn voltage off during init, as this can otherwise
872 * interfere with Unicable SCR systems.
873 */
874 ds3000_set_voltage(&state->frontend, SEC_VOLTAGE_OFF);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300875 return &state->frontend;
876
877error3:
878 kfree(state);
879error2:
880 return NULL;
881}
882EXPORT_SYMBOL(ds3000_attach);
883
Igor M. Liplianina5bf8342011-02-25 18:41:24 -0300884static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
885 s32 carrier_offset_khz)
886{
887 struct ds3000_state *state = fe->demodulator_priv;
888 s32 tmp;
889
890 tmp = carrier_offset_khz;
891 tmp *= 65536;
892 tmp = (2 * tmp + DS3000_SAMPLE_RATE) / (2 * DS3000_SAMPLE_RATE);
893
894 if (tmp < 0)
895 tmp += 65536;
896
897 ds3000_writereg(state, 0x5f, tmp >> 8);
898 ds3000_writereg(state, 0x5e, tmp & 0xff);
899
900 return 0;
901}
902
Mauro Carvalho Chehab9fe33012011-12-26 10:03:29 -0300903static int ds3000_set_frontend(struct dvb_frontend *fe)
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300904{
905 struct ds3000_state *state = fe->demodulator_priv;
906 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
907
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300908 int i;
Mauro Carvalho Chehab0df289a2015-06-07 14:53:52 -0300909 enum fe_status status;
Igor M. Liplianina5bf8342011-02-25 18:41:24 -0300910 s32 offset_khz;
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -0300911 u32 frequency;
912 u16 value;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300913
914 dprintk("%s() ", __func__);
915
Igor M. Liplianin0cb73632011-02-25 18:41:24 -0300916 if (state->config->set_ts_params)
917 state->config->set_ts_params(fe, 0);
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300918 /* Tune */
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -0300919 if (fe->ops.tuner_ops.set_params)
920 fe->ops.tuner_ops.set_params(fe);
Igor M. Liplianina5bf8342011-02-25 18:41:24 -0300921
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300922 /* ds3000 global reset */
923 ds3000_writereg(state, 0x07, 0x80);
924 ds3000_writereg(state, 0x07, 0x00);
925 /* ds3000 build-in uC reset */
926 ds3000_writereg(state, 0xb2, 0x01);
927 /* ds3000 software reset */
928 ds3000_writereg(state, 0x00, 0x01);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300929
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300930 switch (c->delivery_system) {
931 case SYS_DVBS:
932 /* initialise the demod in DVB-S mode */
933 for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
934 ds3000_writereg(state,
935 ds3000_dvbs_init_tab[i],
936 ds3000_dvbs_init_tab[i + 1]);
937 value = ds3000_readreg(state, 0xfe);
938 value &= 0xc0;
939 value |= 0x1b;
940 ds3000_writereg(state, 0xfe, value);
941 break;
942 case SYS_DVBS2:
943 /* initialise the demod in DVB-S2 mode */
944 for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
945 ds3000_writereg(state,
946 ds3000_dvbs2_init_tab[i],
947 ds3000_dvbs2_init_tab[i + 1]);
Igor M. Liplianin7b134e82012-05-11 11:45:42 -0300948 if (c->symbol_rate >= 30000000)
949 ds3000_writereg(state, 0xfe, 0x54);
950 else
951 ds3000_writereg(state, 0xfe, 0x98);
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300952 break;
953 default:
Olli Salonen27924dc2016-03-16 08:04:50 -0300954 return -EINVAL;
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300955 }
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300956
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300957 /* enable 27MHz clock output */
958 ds3000_writereg(state, 0x29, 0x80);
959 /* enable ac coupling */
960 ds3000_writereg(state, 0x25, 0x8a);
961
962 /* enhance symbol rate performance */
Igor M. Liplianincb8f74d2011-02-25 18:41:24 -0300963 if ((c->symbol_rate / 1000) <= 5000) {
964 value = 29777 / (c->symbol_rate / 1000) + 1;
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300965 if (value % 2 != 0)
966 value++;
967 ds3000_writereg(state, 0xc3, 0x0d);
968 ds3000_writereg(state, 0xc8, value);
969 ds3000_writereg(state, 0xc4, 0x10);
970 ds3000_writereg(state, 0xc7, 0x0e);
Igor M. Liplianincb8f74d2011-02-25 18:41:24 -0300971 } else if ((c->symbol_rate / 1000) <= 10000) {
972 value = 92166 / (c->symbol_rate / 1000) + 1;
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300973 if (value % 2 != 0)
974 value++;
975 ds3000_writereg(state, 0xc3, 0x07);
976 ds3000_writereg(state, 0xc8, value);
977 ds3000_writereg(state, 0xc4, 0x09);
978 ds3000_writereg(state, 0xc7, 0x12);
Igor M. Liplianincb8f74d2011-02-25 18:41:24 -0300979 } else if ((c->symbol_rate / 1000) <= 20000) {
980 value = 64516 / (c->symbol_rate / 1000) + 1;
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300981 ds3000_writereg(state, 0xc3, value);
982 ds3000_writereg(state, 0xc8, 0x0e);
983 ds3000_writereg(state, 0xc4, 0x07);
984 ds3000_writereg(state, 0xc7, 0x18);
985 } else {
Igor M. Liplianincb8f74d2011-02-25 18:41:24 -0300986 value = 129032 / (c->symbol_rate / 1000) + 1;
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300987 ds3000_writereg(state, 0xc3, value);
988 ds3000_writereg(state, 0xc8, 0x0a);
989 ds3000_writereg(state, 0xc4, 0x05);
990 ds3000_writereg(state, 0xc7, 0x24);
991 }
992
993 /* normalized symbol rate rounded to the closest integer */
Igor M. Liplianincb8f74d2011-02-25 18:41:24 -0300994 value = (((c->symbol_rate / 1000) << 16) +
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300995 (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
996 ds3000_writereg(state, 0x61, value & 0x00ff);
997 ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
998
999 /* co-channel interference cancellation disabled */
1000 ds3000_writereg(state, 0x56, 0x00);
1001
1002 /* equalizer disabled */
1003 ds3000_writereg(state, 0x76, 0x00);
1004
1005 /*ds3000_writereg(state, 0x08, 0x03);
1006 ds3000_writereg(state, 0xfd, 0x22);
1007 ds3000_writereg(state, 0x08, 0x07);
1008 ds3000_writereg(state, 0xfd, 0x42);
1009 ds3000_writereg(state, 0x08, 0x07);*/
1010
1011 if (state->config->ci_mode) {
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001012 switch (c->delivery_system) {
1013 case SYS_DVBS:
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001014 default:
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001015 ds3000_writereg(state, 0xfd, 0x80);
1016 break;
1017 case SYS_DVBS2:
1018 ds3000_writereg(state, 0xfd, 0x01);
Igor M. Liplianind2ffc442011-02-25 18:41:22 -03001019 break;
Igor M. Liplianind2ffc442011-02-25 18:41:22 -03001020 }
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001021 }
Igor M. Liplianind2ffc442011-02-25 18:41:22 -03001022
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001023 /* ds3000 out of software reset */
1024 ds3000_writereg(state, 0x00, 0x00);
1025 /* start ds3000 build-in uC */
1026 ds3000_writereg(state, 0xb2, 0x00);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001027
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03001028 if (fe->ops.tuner_ops.get_frequency) {
1029 fe->ops.tuner_ops.get_frequency(fe, &frequency);
1030 offset_khz = frequency - c->frequency;
1031 ds3000_set_carrier_offset(fe, offset_khz);
1032 }
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001033
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001034 for (i = 0; i < 30 ; i++) {
1035 ds3000_read_status(fe, &status);
Dan Carpenter3a9888f2012-01-17 03:28:51 -03001036 if (status & FE_HAS_LOCK)
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001037 break;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001038
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001039 msleep(10);
1040 }
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001041
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001042 return 0;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001043}
1044
Igor M. Liplianindcc8a122011-02-25 18:41:24 -03001045static int ds3000_tune(struct dvb_frontend *fe,
Mauro Carvalho Chehab7e072222011-12-26 17:48:33 -03001046 bool re_tune,
Igor M. Liplianin738e8ff2011-02-27 17:29:55 -03001047 unsigned int mode_flags,
1048 unsigned int *delay,
Mauro Carvalho Chehab0df289a2015-06-07 14:53:52 -03001049 enum fe_status *status)
Igor M. Liplianindcc8a122011-02-25 18:41:24 -03001050{
Mauro Carvalho Chehab7e072222011-12-26 17:48:33 -03001051 if (re_tune) {
Mauro Carvalho Chehab9fe33012011-12-26 10:03:29 -03001052 int ret = ds3000_set_frontend(fe);
Igor M. Liplianin738e8ff2011-02-27 17:29:55 -03001053 if (ret)
1054 return ret;
1055 }
1056
1057 *delay = HZ / 5;
1058
1059 return ds3000_read_status(fe, status);
Igor M. Liplianindcc8a122011-02-25 18:41:24 -03001060}
1061
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001062static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
1063{
Igor M. Liplianin43385c82012-12-28 19:40:24 -03001064 struct ds3000_state *state = fe->demodulator_priv;
1065
1066 if (state->config->set_lock_led)
1067 state->config->set_lock_led(fe, 0);
1068
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001069 dprintk("%s()\n", __func__);
Igor M. Liplianindcc8a122011-02-25 18:41:24 -03001070 return DVBFE_ALGO_HW;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001071}
1072
1073/*
1074 * Initialise or wake up device
1075 *
1076 * Power config will reset and load initial firmware if required
1077 */
1078static int ds3000_initfe(struct dvb_frontend *fe)
1079{
Igor M. Liplianina0ea298d52011-02-01 19:40:03 -03001080 struct ds3000_state *state = fe->demodulator_priv;
1081 int ret;
1082
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001083 dprintk("%s()\n", __func__);
Igor M. Liplianina0ea298d52011-02-01 19:40:03 -03001084 /* hard reset */
1085 ds3000_writereg(state, 0x08, 0x01 | ds3000_readreg(state, 0x08));
1086 msleep(1);
1087
Igor M. Liplianinb9bf2ea2011-02-01 19:40:36 -03001088 /* Load the firmware if required */
1089 ret = ds3000_firmware_ondemand(fe);
1090 if (ret != 0) {
1091 printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
1092 return ret;
1093 }
Igor M. Liplianina0ea298d52011-02-01 19:40:03 -03001094
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001095 return 0;
1096}
1097
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001098static struct dvb_frontend_ops ds3000_ops = {
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03001099 .delsys = { SYS_DVBS, SYS_DVBS2 },
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001100 .info = {
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03001101 .name = "Montage Technology DS3000",
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001102 .frequency_min = 950000,
1103 .frequency_max = 2150000,
1104 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1105 .frequency_tolerance = 5000,
1106 .symbol_rate_min = 1000000,
1107 .symbol_rate_max = 45000000,
1108 .caps = FE_CAN_INVERSION_AUTO |
1109 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1110 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1111 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1112 FE_CAN_2G_MODULATION |
1113 FE_CAN_QPSK | FE_CAN_RECOVER
1114 },
1115
1116 .release = ds3000_release,
1117
1118 .init = ds3000_initfe,
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03001119 .i2c_gate_ctrl = ds3000_i2c_gate_ctrl,
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001120 .read_status = ds3000_read_status,
1121 .read_ber = ds3000_read_ber,
Malcolm Priestleya0a030b2013-01-06 08:40:42 -03001122 .read_signal_strength = ds3000_read_signal_strength,
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001123 .read_snr = ds3000_read_snr,
1124 .read_ucblocks = ds3000_read_ucblocks,
Igor M. Liplianind2ffc442011-02-25 18:41:22 -03001125 .set_voltage = ds3000_set_voltage,
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001126 .set_tone = ds3000_set_tone,
1127 .diseqc_send_master_cmd = ds3000_send_diseqc_msg,
1128 .diseqc_send_burst = ds3000_diseqc_send_burst,
1129 .get_frontend_algo = ds3000_get_algo,
1130
Mauro Carvalho Chehab9fe33012011-12-26 10:03:29 -03001131 .set_frontend = ds3000_set_frontend,
Igor M. Liplianindcc8a122011-02-25 18:41:24 -03001132 .tune = ds3000_tune,
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001133};
1134
1135module_param(debug, int, 0644);
1136MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
1137
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001138MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03001139 "DS3000 hardware");
1140MODULE_AUTHOR("Konstantin Dimitrov <kosio.dimitrov@gmail.com>");
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001141MODULE_LICENSE("GPL");
RĂ©mi Cardonafeadd7d2012-09-28 08:59:26 -03001142MODULE_FIRMWARE(DS3000_DEFAULT_FIRMWARE);