blob: fded9b67456c83a2677df612b49d2e60c00134e4 [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
Igor M. Liplianind2ffc442011-02-25 18:41:22 -0300407static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
408{
409 struct ds3000_state *state = fe->demodulator_priv;
410 u8 data;
411
412 dprintk("%s(%d)\n", __func__, voltage);
413
414 data = ds3000_readreg(state, 0xa2);
415 data |= 0x03; /* bit0 V/H, bit1 off/on */
416
417 switch (voltage) {
418 case SEC_VOLTAGE_18:
419 data &= ~0x03;
420 break;
421 case SEC_VOLTAGE_13:
422 data &= ~0x03;
423 data |= 0x01;
424 break;
425 case SEC_VOLTAGE_OFF:
426 break;
427 }
428
429 ds3000_writereg(state, 0xa2, data);
430
431 return 0;
432}
433
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300434static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
435{
436 struct ds3000_state *state = fe->demodulator_priv;
437 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
438 int lock;
439
440 *status = 0;
441
442 switch (c->delivery_system) {
443 case SYS_DVBS:
444 lock = ds3000_readreg(state, 0xd1);
445 if ((lock & 0x07) == 0x07)
446 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
447 FE_HAS_VITERBI | FE_HAS_SYNC |
448 FE_HAS_LOCK;
449
450 break;
451 case SYS_DVBS2:
452 lock = ds3000_readreg(state, 0x0d);
453 if ((lock & 0x8f) == 0x8f)
454 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
455 FE_HAS_VITERBI | FE_HAS_SYNC |
456 FE_HAS_LOCK;
457
458 break;
459 default:
460 return 1;
461 }
462
463 dprintk("%s: status = 0x%02x\n", __func__, lock);
464
465 return 0;
466}
467
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300468/* read DS3000 BER value */
469static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
470{
471 struct ds3000_state *state = fe->demodulator_priv;
472 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
473 u8 data;
474 u32 ber_reading, lpdc_frames;
475
476 dprintk("%s()\n", __func__);
477
478 switch (c->delivery_system) {
479 case SYS_DVBS:
480 /* set the number of bytes checked during
481 BER estimation */
482 ds3000_writereg(state, 0xf9, 0x04);
483 /* read BER estimation status */
484 data = ds3000_readreg(state, 0xf8);
485 /* check if BER estimation is ready */
486 if ((data & 0x10) == 0) {
487 /* this is the number of error bits,
488 to calculate the bit error rate
489 divide to 8388608 */
490 *ber = (ds3000_readreg(state, 0xf7) << 8) |
491 ds3000_readreg(state, 0xf6);
492 /* start counting error bits */
493 /* need to be set twice
494 otherwise it fails sometimes */
495 data |= 0x10;
496 ds3000_writereg(state, 0xf8, data);
497 ds3000_writereg(state, 0xf8, data);
498 } else
499 /* used to indicate that BER estimation
500 is not ready, i.e. BER is unknown */
501 *ber = 0xffffffff;
502 break;
503 case SYS_DVBS2:
504 /* read the number of LPDC decoded frames */
505 lpdc_frames = (ds3000_readreg(state, 0xd7) << 16) |
506 (ds3000_readreg(state, 0xd6) << 8) |
507 ds3000_readreg(state, 0xd5);
508 /* read the number of packets with bad CRC */
509 ber_reading = (ds3000_readreg(state, 0xf8) << 8) |
510 ds3000_readreg(state, 0xf7);
511 if (lpdc_frames > 750) {
512 /* clear LPDC frame counters */
513 ds3000_writereg(state, 0xd1, 0x01);
514 /* clear bad packets counter */
515 ds3000_writereg(state, 0xf9, 0x01);
516 /* enable bad packets counter */
517 ds3000_writereg(state, 0xf9, 0x00);
518 /* enable LPDC frame counters */
519 ds3000_writereg(state, 0xd1, 0x00);
520 *ber = ber_reading;
521 } else
522 /* used to indicate that BER estimation is not ready,
523 i.e. BER is unknown */
524 *ber = 0xffffffff;
525 break;
526 default:
527 return 1;
528 }
529
530 return 0;
531}
532
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300533/* calculate DS3000 snr value in dB */
534static int ds3000_read_snr(struct dvb_frontend *fe, u16 *snr)
535{
536 struct ds3000_state *state = fe->demodulator_priv;
537 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
538 u8 snr_reading, snr_value;
539 u32 dvbs2_signal_reading, dvbs2_noise_reading, tmp;
540 static const u16 dvbs_snr_tab[] = { /* 20 x Table (rounded up) */
541 0x0000, 0x1b13, 0x2aea, 0x3627, 0x3ede, 0x45fe, 0x4c03,
542 0x513a, 0x55d4, 0x59f2, 0x5dab, 0x6111, 0x6431, 0x6717,
543 0x69c9, 0x6c4e, 0x6eac, 0x70e8, 0x7304, 0x7505
544 };
545 static const u16 dvbs2_snr_tab[] = { /* 80 x Table (rounded up) */
546 0x0000, 0x0bc2, 0x12a3, 0x1785, 0x1b4e, 0x1e65, 0x2103,
547 0x2347, 0x2546, 0x2710, 0x28ae, 0x2a28, 0x2b83, 0x2cc5,
548 0x2df1, 0x2f09, 0x3010, 0x3109, 0x31f4, 0x32d2, 0x33a6,
549 0x3470, 0x3531, 0x35ea, 0x369b, 0x3746, 0x37ea, 0x3888,
550 0x3920, 0x39b3, 0x3a42, 0x3acc, 0x3b51, 0x3bd3, 0x3c51,
551 0x3ccb, 0x3d42, 0x3db6, 0x3e27, 0x3e95, 0x3f00, 0x3f68,
552 0x3fcf, 0x4033, 0x4094, 0x40f4, 0x4151, 0x41ac, 0x4206,
553 0x425e, 0x42b4, 0x4308, 0x435b, 0x43ac, 0x43fc, 0x444a,
554 0x4497, 0x44e2, 0x452d, 0x4576, 0x45bd, 0x4604, 0x4649,
555 0x468e, 0x46d1, 0x4713, 0x4755, 0x4795, 0x47d4, 0x4813,
556 0x4851, 0x488d, 0x48c9, 0x4904, 0x493f, 0x4978, 0x49b1,
557 0x49e9, 0x4a20, 0x4a57
558 };
559
560 dprintk("%s()\n", __func__);
561
562 switch (c->delivery_system) {
563 case SYS_DVBS:
564 snr_reading = ds3000_readreg(state, 0xff);
565 snr_reading /= 8;
566 if (snr_reading == 0)
567 *snr = 0x0000;
568 else {
569 if (snr_reading > 20)
570 snr_reading = 20;
571 snr_value = dvbs_snr_tab[snr_reading - 1] * 10 / 23026;
572 /* cook the value to be suitable for szap-s2
573 human readable output */
574 *snr = snr_value * 8 * 655;
575 }
576 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
577 snr_reading, *snr);
578 break;
579 case SYS_DVBS2:
580 dvbs2_noise_reading = (ds3000_readreg(state, 0x8c) & 0x3f) +
581 (ds3000_readreg(state, 0x8d) << 4);
582 dvbs2_signal_reading = ds3000_readreg(state, 0x8e);
583 tmp = dvbs2_signal_reading * dvbs2_signal_reading >> 1;
Nicolas Noirbent450df222010-03-22 14:54:43 -0300584 if (tmp == 0) {
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300585 *snr = 0x0000;
586 return 0;
587 }
588 if (dvbs2_noise_reading == 0) {
589 snr_value = 0x0013;
590 /* cook the value to be suitable for szap-s2
591 human readable output */
592 *snr = 0xffff;
593 return 0;
594 }
595 if (tmp > dvbs2_noise_reading) {
596 snr_reading = tmp / dvbs2_noise_reading;
597 if (snr_reading > 80)
598 snr_reading = 80;
599 snr_value = dvbs2_snr_tab[snr_reading - 1] / 1000;
600 /* cook the value to be suitable for szap-s2
601 human readable output */
602 *snr = snr_value * 5 * 655;
603 } else {
604 snr_reading = dvbs2_noise_reading / tmp;
605 if (snr_reading > 80)
606 snr_reading = 80;
607 *snr = -(dvbs2_snr_tab[snr_reading] / 1000);
608 }
609 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
610 snr_reading, *snr);
611 break;
612 default:
613 return 1;
614 }
615
616 return 0;
617}
618
619/* read DS3000 uncorrected blocks */
620static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
621{
622 struct ds3000_state *state = fe->demodulator_priv;
623 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
624 u8 data;
625 u16 _ucblocks;
626
627 dprintk("%s()\n", __func__);
628
629 switch (c->delivery_system) {
630 case SYS_DVBS:
631 *ucblocks = (ds3000_readreg(state, 0xf5) << 8) |
632 ds3000_readreg(state, 0xf4);
633 data = ds3000_readreg(state, 0xf8);
634 /* clear packet counters */
635 data &= ~0x20;
636 ds3000_writereg(state, 0xf8, data);
637 /* enable packet counters */
638 data |= 0x20;
639 ds3000_writereg(state, 0xf8, data);
640 break;
641 case SYS_DVBS2:
642 _ucblocks = (ds3000_readreg(state, 0xe2) << 8) |
643 ds3000_readreg(state, 0xe1);
644 if (_ucblocks > state->prevUCBS2)
645 *ucblocks = _ucblocks - state->prevUCBS2;
646 else
647 *ucblocks = state->prevUCBS2 - _ucblocks;
648 state->prevUCBS2 = _ucblocks;
649 break;
650 default:
651 return 1;
652 }
653
654 return 0;
655}
656
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300657static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
658{
659 struct ds3000_state *state = fe->demodulator_priv;
660 u8 data;
661
662 dprintk("%s(%d)\n", __func__, tone);
663 if ((tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF)) {
664 printk(KERN_ERR "%s: Invalid, tone=%d\n", __func__, tone);
665 return -EINVAL;
666 }
667
668 data = ds3000_readreg(state, 0xa2);
669 data &= ~0xc0;
670 ds3000_writereg(state, 0xa2, data);
671
672 switch (tone) {
673 case SEC_TONE_ON:
674 dprintk("%s: setting tone on\n", __func__);
675 data = ds3000_readreg(state, 0xa1);
676 data &= ~0x43;
677 data |= 0x04;
678 ds3000_writereg(state, 0xa1, data);
679 break;
680 case SEC_TONE_OFF:
681 dprintk("%s: setting tone off\n", __func__);
682 data = ds3000_readreg(state, 0xa2);
683 data |= 0x80;
684 ds3000_writereg(state, 0xa2, data);
685 break;
686 }
687
688 return 0;
689}
690
691static int ds3000_send_diseqc_msg(struct dvb_frontend *fe,
692 struct dvb_diseqc_master_cmd *d)
693{
694 struct ds3000_state *state = fe->demodulator_priv;
695 int i;
696 u8 data;
697
698 /* Dump DiSEqC message */
699 dprintk("%s(", __func__);
700 for (i = 0 ; i < d->msg_len;) {
701 dprintk("0x%02x", d->msg[i]);
702 if (++i < d->msg_len)
703 dprintk(", ");
704 }
705
706 /* enable DiSEqC message send pin */
707 data = ds3000_readreg(state, 0xa2);
708 data &= ~0xc0;
709 ds3000_writereg(state, 0xa2, data);
710
711 /* DiSEqC message */
712 for (i = 0; i < d->msg_len; i++)
713 ds3000_writereg(state, 0xa3 + i, d->msg[i]);
714
715 data = ds3000_readreg(state, 0xa1);
716 /* clear DiSEqC message length and status,
717 enable DiSEqC message send */
718 data &= ~0xf8;
719 /* set DiSEqC mode, modulation active during 33 pulses,
720 set DiSEqC message length */
721 data |= ((d->msg_len - 1) << 3) | 0x07;
722 ds3000_writereg(state, 0xa1, data);
723
724 /* wait up to 150ms for DiSEqC transmission to complete */
725 for (i = 0; i < 15; i++) {
726 data = ds3000_readreg(state, 0xa1);
727 if ((data & 0x40) == 0)
728 break;
729 msleep(10);
730 }
731
732 /* DiSEqC timeout after 150ms */
733 if (i == 15) {
734 data = ds3000_readreg(state, 0xa1);
735 data &= ~0x80;
736 data |= 0x40;
737 ds3000_writereg(state, 0xa1, data);
738
739 data = ds3000_readreg(state, 0xa2);
740 data &= ~0xc0;
741 data |= 0x80;
742 ds3000_writereg(state, 0xa2, data);
743
744 return 1;
745 }
746
747 data = ds3000_readreg(state, 0xa2);
748 data &= ~0xc0;
749 data |= 0x80;
750 ds3000_writereg(state, 0xa2, data);
751
752 return 0;
753}
754
755/* Send DiSEqC burst */
756static int ds3000_diseqc_send_burst(struct dvb_frontend *fe,
757 fe_sec_mini_cmd_t burst)
758{
759 struct ds3000_state *state = fe->demodulator_priv;
760 int i;
761 u8 data;
762
763 dprintk("%s()\n", __func__);
764
765 data = ds3000_readreg(state, 0xa2);
766 data &= ~0xc0;
767 ds3000_writereg(state, 0xa2, data);
768
769 /* DiSEqC burst */
770 if (burst == SEC_MINI_A)
771 /* Unmodulated tone burst */
772 ds3000_writereg(state, 0xa1, 0x02);
773 else if (burst == SEC_MINI_B)
774 /* Modulated tone burst */
775 ds3000_writereg(state, 0xa1, 0x01);
776 else
777 return -EINVAL;
778
779 msleep(13);
780 for (i = 0; i < 5; i++) {
781 data = ds3000_readreg(state, 0xa1);
782 if ((data & 0x40) == 0)
783 break;
784 msleep(1);
785 }
786
787 if (i == 5) {
788 data = ds3000_readreg(state, 0xa1);
789 data &= ~0x80;
790 data |= 0x40;
791 ds3000_writereg(state, 0xa1, data);
792
793 data = ds3000_readreg(state, 0xa2);
794 data &= ~0xc0;
795 data |= 0x80;
796 ds3000_writereg(state, 0xa2, data);
797
798 return 1;
799 }
800
801 data = ds3000_readreg(state, 0xa2);
802 data &= ~0xc0;
803 data |= 0x80;
804 ds3000_writereg(state, 0xa2, data);
805
806 return 0;
807}
808
809static void ds3000_release(struct dvb_frontend *fe)
810{
811 struct ds3000_state *state = fe->demodulator_priv;
812 dprintk("%s\n", __func__);
813 kfree(state);
814}
815
816static struct dvb_frontend_ops ds3000_ops;
817
818struct dvb_frontend *ds3000_attach(const struct ds3000_config *config,
819 struct i2c_adapter *i2c)
820{
821 struct ds3000_state *state = NULL;
822 int ret;
823
824 dprintk("%s\n", __func__);
825
826 /* allocate memory for the internal state */
Julia Lawall2ef17c92010-05-13 16:59:15 -0300827 state = kzalloc(sizeof(struct ds3000_state), GFP_KERNEL);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300828 if (state == NULL) {
829 printk(KERN_ERR "Unable to kmalloc\n");
830 goto error2;
831 }
832
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300833 state->config = config;
834 state->i2c = i2c;
835 state->prevUCBS2 = 0;
836
837 /* check if the demod is present */
838 ret = ds3000_readreg(state, 0x00) & 0xfe;
839 if (ret != 0xe0) {
840 printk(KERN_ERR "Invalid probe, probably not a DS3000\n");
841 goto error3;
842 }
843
844 printk(KERN_INFO "DS3000 chip version: %d.%d attached.\n",
845 ds3000_readreg(state, 0x02),
846 ds3000_readreg(state, 0x01));
847
848 memcpy(&state->frontend.ops, &ds3000_ops,
849 sizeof(struct dvb_frontend_ops));
850 state->frontend.demodulator_priv = state;
851 return &state->frontend;
852
853error3:
854 kfree(state);
855error2:
856 return NULL;
857}
858EXPORT_SYMBOL(ds3000_attach);
859
Igor M. Liplianina5bf8342011-02-25 18:41:24 -0300860static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
861 s32 carrier_offset_khz)
862{
863 struct ds3000_state *state = fe->demodulator_priv;
864 s32 tmp;
865
866 tmp = carrier_offset_khz;
867 tmp *= 65536;
868 tmp = (2 * tmp + DS3000_SAMPLE_RATE) / (2 * DS3000_SAMPLE_RATE);
869
870 if (tmp < 0)
871 tmp += 65536;
872
873 ds3000_writereg(state, 0x5f, tmp >> 8);
874 ds3000_writereg(state, 0x5e, tmp & 0xff);
875
876 return 0;
877}
878
Mauro Carvalho Chehab9fe33012011-12-26 10:03:29 -0300879static int ds3000_set_frontend(struct dvb_frontend *fe)
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300880{
881 struct ds3000_state *state = fe->demodulator_priv;
882 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
883
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300884 int i;
Igor M. Liplianindcc8a122011-02-25 18:41:24 -0300885 fe_status_t status;
Igor M. Liplianina5bf8342011-02-25 18:41:24 -0300886 s32 offset_khz;
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -0300887 u32 frequency;
888 u16 value;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300889
890 dprintk("%s() ", __func__);
891
Igor M. Liplianin0cb73632011-02-25 18:41:24 -0300892 if (state->config->set_ts_params)
893 state->config->set_ts_params(fe, 0);
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300894 /* Tune */
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -0300895 if (fe->ops.tuner_ops.set_params)
896 fe->ops.tuner_ops.set_params(fe);
Igor M. Liplianina5bf8342011-02-25 18:41:24 -0300897
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300898 /* ds3000 global reset */
899 ds3000_writereg(state, 0x07, 0x80);
900 ds3000_writereg(state, 0x07, 0x00);
901 /* ds3000 build-in uC reset */
902 ds3000_writereg(state, 0xb2, 0x01);
903 /* ds3000 software reset */
904 ds3000_writereg(state, 0x00, 0x01);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300905
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300906 switch (c->delivery_system) {
907 case SYS_DVBS:
908 /* initialise the demod in DVB-S mode */
909 for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
910 ds3000_writereg(state,
911 ds3000_dvbs_init_tab[i],
912 ds3000_dvbs_init_tab[i + 1]);
913 value = ds3000_readreg(state, 0xfe);
914 value &= 0xc0;
915 value |= 0x1b;
916 ds3000_writereg(state, 0xfe, value);
917 break;
918 case SYS_DVBS2:
919 /* initialise the demod in DVB-S2 mode */
920 for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
921 ds3000_writereg(state,
922 ds3000_dvbs2_init_tab[i],
923 ds3000_dvbs2_init_tab[i + 1]);
Igor M. Liplianin7b134e82012-05-11 11:45:42 -0300924 if (c->symbol_rate >= 30000000)
925 ds3000_writereg(state, 0xfe, 0x54);
926 else
927 ds3000_writereg(state, 0xfe, 0x98);
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300928 break;
929 default:
930 return 1;
931 }
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300932
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300933 /* enable 27MHz clock output */
934 ds3000_writereg(state, 0x29, 0x80);
935 /* enable ac coupling */
936 ds3000_writereg(state, 0x25, 0x8a);
937
938 /* enhance symbol rate performance */
Igor M. Liplianincb8f74d2011-02-25 18:41:24 -0300939 if ((c->symbol_rate / 1000) <= 5000) {
940 value = 29777 / (c->symbol_rate / 1000) + 1;
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300941 if (value % 2 != 0)
942 value++;
943 ds3000_writereg(state, 0xc3, 0x0d);
944 ds3000_writereg(state, 0xc8, value);
945 ds3000_writereg(state, 0xc4, 0x10);
946 ds3000_writereg(state, 0xc7, 0x0e);
Igor M. Liplianincb8f74d2011-02-25 18:41:24 -0300947 } else if ((c->symbol_rate / 1000) <= 10000) {
948 value = 92166 / (c->symbol_rate / 1000) + 1;
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300949 if (value % 2 != 0)
950 value++;
951 ds3000_writereg(state, 0xc3, 0x07);
952 ds3000_writereg(state, 0xc8, value);
953 ds3000_writereg(state, 0xc4, 0x09);
954 ds3000_writereg(state, 0xc7, 0x12);
Igor M. Liplianincb8f74d2011-02-25 18:41:24 -0300955 } else if ((c->symbol_rate / 1000) <= 20000) {
956 value = 64516 / (c->symbol_rate / 1000) + 1;
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300957 ds3000_writereg(state, 0xc3, value);
958 ds3000_writereg(state, 0xc8, 0x0e);
959 ds3000_writereg(state, 0xc4, 0x07);
960 ds3000_writereg(state, 0xc7, 0x18);
961 } else {
Igor M. Liplianincb8f74d2011-02-25 18:41:24 -0300962 value = 129032 / (c->symbol_rate / 1000) + 1;
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300963 ds3000_writereg(state, 0xc3, value);
964 ds3000_writereg(state, 0xc8, 0x0a);
965 ds3000_writereg(state, 0xc4, 0x05);
966 ds3000_writereg(state, 0xc7, 0x24);
967 }
968
969 /* normalized symbol rate rounded to the closest integer */
Igor M. Liplianincb8f74d2011-02-25 18:41:24 -0300970 value = (((c->symbol_rate / 1000) << 16) +
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300971 (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
972 ds3000_writereg(state, 0x61, value & 0x00ff);
973 ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
974
975 /* co-channel interference cancellation disabled */
976 ds3000_writereg(state, 0x56, 0x00);
977
978 /* equalizer disabled */
979 ds3000_writereg(state, 0x76, 0x00);
980
981 /*ds3000_writereg(state, 0x08, 0x03);
982 ds3000_writereg(state, 0xfd, 0x22);
983 ds3000_writereg(state, 0x08, 0x07);
984 ds3000_writereg(state, 0xfd, 0x42);
985 ds3000_writereg(state, 0x08, 0x07);*/
986
987 if (state->config->ci_mode) {
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300988 switch (c->delivery_system) {
989 case SYS_DVBS:
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -0300990 default:
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300991 ds3000_writereg(state, 0xfd, 0x80);
992 break;
993 case SYS_DVBS2:
994 ds3000_writereg(state, 0xfd, 0x01);
Igor M. Liplianind2ffc442011-02-25 18:41:22 -0300995 break;
Igor M. Liplianind2ffc442011-02-25 18:41:22 -0300996 }
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300997 }
Igor M. Liplianind2ffc442011-02-25 18:41:22 -0300998
Igor M. Liplianin18a73f32011-02-25 18:41:23 -0300999 /* ds3000 out of software reset */
1000 ds3000_writereg(state, 0x00, 0x00);
1001 /* start ds3000 build-in uC */
1002 ds3000_writereg(state, 0xb2, 0x00);
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001003
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03001004 if (fe->ops.tuner_ops.get_frequency) {
1005 fe->ops.tuner_ops.get_frequency(fe, &frequency);
1006 offset_khz = frequency - c->frequency;
1007 ds3000_set_carrier_offset(fe, offset_khz);
1008 }
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001009
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001010 for (i = 0; i < 30 ; i++) {
1011 ds3000_read_status(fe, &status);
Dan Carpenter3a9888f2012-01-17 03:28:51 -03001012 if (status & FE_HAS_LOCK)
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001013 break;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001014
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001015 msleep(10);
1016 }
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001017
Igor M. Liplianin18a73f32011-02-25 18:41:23 -03001018 return 0;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001019}
1020
Igor M. Liplianindcc8a122011-02-25 18:41:24 -03001021static int ds3000_tune(struct dvb_frontend *fe,
Mauro Carvalho Chehab7e072222011-12-26 17:48:33 -03001022 bool re_tune,
Igor M. Liplianin738e8ff2011-02-27 17:29:55 -03001023 unsigned int mode_flags,
1024 unsigned int *delay,
1025 fe_status_t *status)
Igor M. Liplianindcc8a122011-02-25 18:41:24 -03001026{
Mauro Carvalho Chehab7e072222011-12-26 17:48:33 -03001027 if (re_tune) {
Mauro Carvalho Chehab9fe33012011-12-26 10:03:29 -03001028 int ret = ds3000_set_frontend(fe);
Igor M. Liplianin738e8ff2011-02-27 17:29:55 -03001029 if (ret)
1030 return ret;
1031 }
1032
1033 *delay = HZ / 5;
1034
1035 return ds3000_read_status(fe, status);
Igor M. Liplianindcc8a122011-02-25 18:41:24 -03001036}
1037
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001038static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
1039{
1040 dprintk("%s()\n", __func__);
Igor M. Liplianindcc8a122011-02-25 18:41:24 -03001041 return DVBFE_ALGO_HW;
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001042}
1043
1044/*
1045 * Initialise or wake up device
1046 *
1047 * Power config will reset and load initial firmware if required
1048 */
1049static int ds3000_initfe(struct dvb_frontend *fe)
1050{
Igor M. Liplianina0ea298d52011-02-01 19:40:03 -03001051 struct ds3000_state *state = fe->demodulator_priv;
1052 int ret;
1053
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001054 dprintk("%s()\n", __func__);
Igor M. Liplianina0ea298d52011-02-01 19:40:03 -03001055 /* hard reset */
1056 ds3000_writereg(state, 0x08, 0x01 | ds3000_readreg(state, 0x08));
1057 msleep(1);
1058
Igor M. Liplianinb9bf2ea2011-02-01 19:40:36 -03001059 /* Load the firmware if required */
1060 ret = ds3000_firmware_ondemand(fe);
1061 if (ret != 0) {
1062 printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
1063 return ret;
1064 }
Igor M. Liplianina0ea298d52011-02-01 19:40:03 -03001065
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001066 return 0;
1067}
1068
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001069static struct dvb_frontend_ops ds3000_ops = {
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03001070 .delsys = { SYS_DVBS, SYS_DVBS2 },
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001071 .info = {
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03001072 .name = "Montage Technology DS3000",
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001073 .frequency_min = 950000,
1074 .frequency_max = 2150000,
1075 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1076 .frequency_tolerance = 5000,
1077 .symbol_rate_min = 1000000,
1078 .symbol_rate_max = 45000000,
1079 .caps = FE_CAN_INVERSION_AUTO |
1080 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1081 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1082 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1083 FE_CAN_2G_MODULATION |
1084 FE_CAN_QPSK | FE_CAN_RECOVER
1085 },
1086
1087 .release = ds3000_release,
1088
1089 .init = ds3000_initfe,
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03001090 .i2c_gate_ctrl = ds3000_i2c_gate_ctrl,
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001091 .read_status = ds3000_read_status,
1092 .read_ber = ds3000_read_ber,
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001093 .read_snr = ds3000_read_snr,
1094 .read_ucblocks = ds3000_read_ucblocks,
Igor M. Liplianind2ffc442011-02-25 18:41:22 -03001095 .set_voltage = ds3000_set_voltage,
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001096 .set_tone = ds3000_set_tone,
1097 .diseqc_send_master_cmd = ds3000_send_diseqc_msg,
1098 .diseqc_send_burst = ds3000_diseqc_send_burst,
1099 .get_frontend_algo = ds3000_get_algo,
1100
Mauro Carvalho Chehab9fe33012011-12-26 10:03:29 -03001101 .set_frontend = ds3000_set_frontend,
Igor M. Liplianindcc8a122011-02-25 18:41:24 -03001102 .tune = ds3000_tune,
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001103};
1104
1105module_param(debug, int, 0644);
1106MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
1107
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001108MODULE_DESCRIPTION("DVB Frontend module for Montage Technology "
Konstantin Dimitrovc1965ea2012-12-23 19:25:09 -03001109 "DS3000 hardware");
1110MODULE_AUTHOR("Konstantin Dimitrov <kosio.dimitrov@gmail.com>");
Igor M. Liplianin09ea33e2009-11-24 20:16:04 -03001111MODULE_LICENSE("GPL");
Rémi Cardonafeadd7d2012-09-28 08:59:26 -03001112MODULE_FIRMWARE(DS3000_DEFAULT_FIRMWARE);