Merge tag 'rpmsg-v5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/remoteproc...
[linux-2.6-microblaze.git] / drivers / media / dvb-frontends / mxl692.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Driver for the MaxLinear MxL69x family of combo tuners/demods
4  *
5  * Copyright (C) 2020 Brad Love <brad@nextdimension.cc>
6  *
7  * based on code:
8  * Copyright (c) 2016 MaxLinear, Inc. All rights reserved
9  * which was released under GPL V2
10  */
11
12 #include <linux/mutex.h>
13 #include <linux/i2c-mux.h>
14 #include <linux/string.h>
15 #include <linux/firmware.h>
16
17 #include "mxl692.h"
18 #include "mxl692_defs.h"
19
20 static const struct dvb_frontend_ops mxl692_ops;
21
22 struct mxl692_dev {
23         struct dvb_frontend fe;
24         struct i2c_client *i2c_client;
25         struct mutex i2c_lock;          /* i2c command mutex */
26         enum MXL_EAGLE_DEMOD_TYPE_E demod_type;
27         enum MXL_EAGLE_POWER_MODE_E power_mode;
28         u32 current_frequency;
29         int device_type;
30         int seqnum;
31         int init_done;
32 };
33
34 static int mxl692_i2c_write(struct mxl692_dev *dev, u8 *buffer, u16 buf_len)
35 {
36         int ret = 0;
37         struct i2c_msg msg = {
38                 .addr = dev->i2c_client->addr,
39                 .flags = 0,
40                 .buf = buffer,
41                 .len = buf_len
42         };
43
44         ret = i2c_transfer(dev->i2c_client->adapter, &msg, 1);
45         if (ret != 1)
46                 dev_dbg(&dev->i2c_client->dev, "i2c write error!\n");
47
48         return ret;
49 }
50
51 static int mxl692_i2c_read(struct mxl692_dev *dev, u8 *buffer, u16 buf_len)
52 {
53         int ret = 0;
54         struct i2c_msg msg = {
55                 .addr = dev->i2c_client->addr,
56                 .flags = I2C_M_RD,
57                 .buf = buffer,
58                 .len = buf_len
59         };
60
61         ret = i2c_transfer(dev->i2c_client->adapter, &msg, 1);
62         if (ret != 1)
63                 dev_dbg(&dev->i2c_client->dev, "i2c read error!\n");
64
65         return ret;
66 }
67
68 static int convert_endian(u32 size, u8 *d)
69 {
70         u32 i;
71
72         for (i = 0; i < (size & ~3); i += 4) {
73                 d[i + 0] ^= d[i + 3];
74                 d[i + 3] ^= d[i + 0];
75                 d[i + 0] ^= d[i + 3];
76
77                 d[i + 1] ^= d[i + 2];
78                 d[i + 2] ^= d[i + 1];
79                 d[i + 1] ^= d[i + 2];
80         }
81
82         switch (size & 3) {
83         case 0:
84         case 1:
85                 /* do nothing */
86                 break;
87         case 2:
88                 d[i + 0] ^= d[i + 1];
89                 d[i + 1] ^= d[i + 0];
90                 d[i + 0] ^= d[i + 1];
91                 break;
92
93         case 3:
94                 d[i + 0] ^= d[i + 2];
95                 d[i + 2] ^= d[i + 0];
96                 d[i + 0] ^= d[i + 2];
97                 break;
98         }
99         return size;
100 }
101
102 static int convert_endian_n(int n, u32 size, u8 *d)
103 {
104         int i, count = 0;
105
106         for (i = 0; i < n; i += size)
107                 count += convert_endian(size, d + i);
108         return count;
109 }
110
111 static void mxl692_tx_swap(enum MXL_EAGLE_OPCODE_E opcode, u8 *buffer)
112 {
113 #ifdef __BIG_ENDIAN
114         return;
115 #endif
116         buffer += MXL_EAGLE_HOST_MSG_HEADER_SIZE; /* skip API header */
117
118         switch (opcode) {
119         case MXL_EAGLE_OPCODE_DEVICE_INTR_MASK_SET:
120         case MXL_EAGLE_OPCODE_TUNER_CHANNEL_TUNE_SET:
121         case MXL_EAGLE_OPCODE_SMA_TRANSMIT_SET:
122                 buffer += convert_endian(sizeof(u32), buffer);
123                 break;
124         case MXL_EAGLE_OPCODE_QAM_PARAMS_SET:
125                 buffer += 5;
126                 buffer += convert_endian(2 * sizeof(u32), buffer);
127                 break;
128         default:
129                 /* no swapping - all get opcodes */
130                 /* ATSC/OOB no swapping */
131                 break;
132         }
133 }
134
135 static void mxl692_rx_swap(enum MXL_EAGLE_OPCODE_E opcode, u8 *buffer)
136 {
137 #ifdef __BIG_ENDIAN
138         return;
139 #endif
140         buffer += MXL_EAGLE_HOST_MSG_HEADER_SIZE; /* skip API header */
141
142         switch (opcode) {
143         case MXL_EAGLE_OPCODE_TUNER_AGC_STATUS_GET:
144                 buffer++;
145                 buffer += convert_endian(2 * sizeof(u16), buffer);
146                 break;
147         case MXL_EAGLE_OPCODE_ATSC_STATUS_GET:
148                 buffer += convert_endian_n(2, sizeof(u16), buffer);
149                 buffer += convert_endian(sizeof(u32), buffer);
150                 break;
151         case MXL_EAGLE_OPCODE_ATSC_ERROR_COUNTERS_GET:
152                 buffer += convert_endian(3 * sizeof(u32), buffer);
153                 break;
154         case MXL_EAGLE_OPCODE_ATSC_EQUALIZER_FILTER_FFE_TAPS_GET:
155                 buffer += convert_endian_n(24, sizeof(u16), buffer);
156                 break;
157         case MXL_EAGLE_OPCODE_QAM_STATUS_GET:
158                 buffer += 8;
159                 buffer += convert_endian_n(2, sizeof(u16), buffer);
160                 buffer += convert_endian(sizeof(u32), buffer);
161                 break;
162         case MXL_EAGLE_OPCODE_QAM_ERROR_COUNTERS_GET:
163                 buffer += convert_endian(7 * sizeof(u32), buffer);
164                 break;
165         case MXL_EAGLE_OPCODE_QAM_CONSTELLATION_VALUE_GET:
166         case MXL_EAGLE_OPCODE_QAM_EQUALIZER_FILTER_DFE_START_GET:
167         case MXL_EAGLE_OPCODE_QAM_EQUALIZER_FILTER_DFE_MIDDLE_GET:
168         case MXL_EAGLE_OPCODE_QAM_EQUALIZER_FILTER_DFE_END_GET:
169         case MXL_EAGLE_OPCODE_QAM_EQUALIZER_FILTER_SPUR_START_GET:
170                 buffer += convert_endian_n(24, sizeof(u16), buffer);
171                 break;
172         case MXL_EAGLE_OPCODE_QAM_EQUALIZER_FILTER_SPUR_END_GET:
173                 buffer += convert_endian_n(8, sizeof(u16), buffer);
174                 break;
175         case MXL_EAGLE_OPCODE_QAM_EQUALIZER_FILTER_FFE_GET:
176                 buffer += convert_endian_n(17, sizeof(u16), buffer);
177                 break;
178         case MXL_EAGLE_OPCODE_OOB_ERROR_COUNTERS_GET:
179                 buffer += convert_endian(3 * sizeof(u32), buffer);
180                 break;
181         case MXL_EAGLE_OPCODE_OOB_STATUS_GET:
182                 buffer += convert_endian_n(2, sizeof(u16), buffer);
183                 buffer += convert_endian(sizeof(u32), buffer);
184                 break;
185         case MXL_EAGLE_OPCODE_SMA_RECEIVE_GET:
186                 buffer += convert_endian(sizeof(u32), buffer);
187                 break;
188         default:
189                 /* no swapping - all set opcodes */
190                 break;
191         }
192 }
193
194 static u32 mxl692_checksum(u8 *buffer, u32 size)
195 {
196         u32 ix, div_size;
197         u32 cur_cksum = 0;
198         __be32 *buf;
199
200         div_size = DIV_ROUND_UP(size, 4);
201
202         buf = (__be32 *)buffer;
203         for (ix = 0; ix < div_size; ix++)
204                 cur_cksum += be32_to_cpu(buf[ix]);
205
206         cur_cksum ^= 0xDEADBEEF;
207
208         return cur_cksum;
209 }
210
211 static int mxl692_validate_fw_header(struct mxl692_dev *dev,
212                                      const u8 *buffer, u32 buf_len)
213 {
214         int status = 0;
215         u32 ix, temp;
216         __be32 *local_buf = NULL;
217         u8 temp_cksum = 0;
218         static const u8 fw_hdr[] = {
219                 0x4D, 0x31, 0x10, 0x02, 0x40, 0x00, 0x00, 0x80
220         };
221
222         if (memcmp(buffer, fw_hdr, 8) != 0) {
223                 status = -EINVAL;
224                 goto err_finish;
225         }
226
227         local_buf = (__be32 *)(buffer + 8);
228         temp = be32_to_cpu(*local_buf);
229
230         if ((buf_len - 16) != temp >> 8) {
231                 status = -EINVAL;
232                 goto err_finish;
233         }
234
235         for (ix = 16; ix < buf_len; ix++)
236                 temp_cksum += buffer[ix];
237
238         if (temp_cksum != buffer[11])
239                 status = -EINVAL;
240
241 err_finish:
242         if (status)
243                 dev_dbg(&dev->i2c_client->dev, "failed\n");
244         return status;
245 }
246
247 static int mxl692_write_fw_block(struct mxl692_dev *dev, const u8 *buffer,
248                                  u32 buf_len, u32 *index)
249 {
250         int status = 0;
251         u32 ix = 0, total_len = 0, addr = 0, chunk_len = 0, prevchunk_len = 0;
252         u8 local_buf[MXL_EAGLE_MAX_I2C_PACKET_SIZE] = {}, *plocal_buf = NULL;
253         int payload_max = MXL_EAGLE_MAX_I2C_PACKET_SIZE - MXL_EAGLE_I2C_MHEADER_SIZE;
254
255         ix = *index;
256
257         if (buffer[ix] == 0x53) {
258                 total_len = buffer[ix + 1] << 16 | buffer[ix + 2] << 8 | buffer[ix + 3];
259                 total_len = (total_len + 3) & ~3;
260                 addr      = buffer[ix + 4] << 24 | buffer[ix + 5] << 16 |
261                             buffer[ix + 6] << 8 | buffer[ix + 7];
262                 ix       += MXL_EAGLE_FW_SEGMENT_HEADER_SIZE;
263
264                 while ((total_len > 0) && (status == 0)) {
265                         plocal_buf = local_buf;
266                         chunk_len  = (total_len < payload_max) ? total_len : payload_max;
267
268                         *plocal_buf++ = 0xFC;
269                         *plocal_buf++ = chunk_len + sizeof(u32);
270
271                         *(u32 *)plocal_buf = addr + prevchunk_len;
272 #ifdef __BIG_ENDIAN
273                         convert_endian(sizeof(u32), plocal_buf);
274 #endif
275                         plocal_buf += sizeof(u32);
276
277                         memcpy(plocal_buf, &buffer[ix], chunk_len);
278                         convert_endian(chunk_len, plocal_buf);
279                         if (mxl692_i2c_write(dev, local_buf,
280                                              (chunk_len + MXL_EAGLE_I2C_MHEADER_SIZE)) < 0) {
281                                 status = -EREMOTEIO;
282                                 break;
283                         }
284
285                         prevchunk_len += chunk_len;
286                         total_len -= chunk_len;
287                         ix += chunk_len;
288                 }
289                 *index = ix;
290         } else {
291                 status = -EINVAL;
292         }
293
294         if (status)
295                 dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
296
297         return status;
298 }
299
300 static int mxl692_memwrite(struct mxl692_dev *dev, u32 addr,
301                            u8 *buffer, u32 size)
302 {
303         int status = 0, total_len = 0;
304         u8 local_buf[MXL_EAGLE_MAX_I2C_PACKET_SIZE] = {}, *plocal_buf = NULL;
305
306         total_len = size;
307         total_len = (total_len + 3) & ~3;  /* 4 byte alignment */
308
309         if (total_len > (MXL_EAGLE_MAX_I2C_PACKET_SIZE - MXL_EAGLE_I2C_MHEADER_SIZE))
310                 dev_dbg(&dev->i2c_client->dev, "hrmph?\n");
311
312         plocal_buf = local_buf;
313
314         *plocal_buf++ = 0xFC;
315         *plocal_buf++ = total_len + sizeof(u32);
316
317         *(u32 *)plocal_buf = addr;
318         plocal_buf += sizeof(u32);
319
320         memcpy(plocal_buf, buffer, total_len);
321 #ifdef __BIG_ENDIAN
322         convert_endian(sizeof(u32) + total_len, local_buf + 2);
323 #endif
324         if (mxl692_i2c_write(dev, local_buf,
325                              (total_len + MXL_EAGLE_I2C_MHEADER_SIZE)) < 0) {
326                 status = -EREMOTEIO;
327                 goto err_finish;
328         }
329
330         return status;
331 err_finish:
332         dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
333         return status;
334 }
335
336 static int mxl692_memread(struct mxl692_dev *dev, u32 addr,
337                           u8 *buffer, u32 size)
338 {
339         int status = 0;
340         u8 local_buf[MXL_EAGLE_I2C_MHEADER_SIZE] = {}, *plocal_buf = NULL;
341
342         plocal_buf = local_buf;
343
344         *plocal_buf++ = 0xFB;
345         *plocal_buf++ = sizeof(u32);
346         *(u32 *)plocal_buf = addr;
347 #ifdef __BIG_ENDIAN
348         convert_endian(sizeof(u32), plocal_buf);
349 #endif
350         mutex_lock(&dev->i2c_lock);
351
352         if (mxl692_i2c_write(dev, local_buf, MXL_EAGLE_I2C_MHEADER_SIZE) > 0) {
353                 size = (size + 3) & ~3;  /* 4 byte alignment */
354                 status = mxl692_i2c_read(dev, buffer, (u16)size) < 0 ? -EREMOTEIO : 0;
355 #ifdef __BIG_ENDIAN
356                 if (status == 0)
357                         convert_endian(size, buffer);
358 #endif
359         } else {
360                 status = -EREMOTEIO;
361         }
362
363         mutex_unlock(&dev->i2c_lock);
364
365         if (status)
366                 dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
367
368         return status;
369 }
370
371 static const char *mxl692_opcode_string(u8 opcode)
372 {
373         if (opcode <= MXL_EAGLE_OPCODE_INTERNAL)
374                 return MXL_EAGLE_OPCODE_STRING[opcode];
375
376         return "invalid opcode";
377 }
378
379 static int mxl692_opwrite(struct mxl692_dev *dev, u8 *buffer,
380                           u32 size)
381 {
382         int status = 0, total_len = 0;
383         u8 local_buf[MXL_EAGLE_MAX_I2C_PACKET_SIZE] = {}, *plocal_buf = NULL;
384         struct MXL_EAGLE_HOST_MSG_HEADER_T *tx_hdr = (struct MXL_EAGLE_HOST_MSG_HEADER_T *)buffer;
385
386         total_len = size;
387         total_len = (total_len + 3) & ~3;  /* 4 byte alignment */
388
389         if (total_len > (MXL_EAGLE_MAX_I2C_PACKET_SIZE - MXL_EAGLE_I2C_PHEADER_SIZE))
390                 dev_dbg(&dev->i2c_client->dev, "hrmph?\n");
391
392         plocal_buf = local_buf;
393
394         *plocal_buf++ = 0xFE;
395         *plocal_buf++ = (u8)total_len;
396
397         memcpy(plocal_buf, buffer, total_len);
398         convert_endian(total_len, plocal_buf);
399
400         if (mxl692_i2c_write(dev, local_buf,
401                              (total_len + MXL_EAGLE_I2C_PHEADER_SIZE)) < 0) {
402                 status = -EREMOTEIO;
403                 goto err_finish;
404         }
405 err_finish:
406         if (status)
407                 dev_dbg(&dev->i2c_client->dev, "opcode %s  err %d\n",
408                         mxl692_opcode_string(tx_hdr->opcode), status);
409         return status;
410 }
411
412 static int mxl692_opread(struct mxl692_dev *dev, u8 *buffer,
413                          u32 size)
414 {
415         int status = 0;
416         u32 ix = 0;
417         u8 local_buf[MXL_EAGLE_I2C_PHEADER_SIZE] = {};
418
419         local_buf[0] = 0xFD;
420         local_buf[1] = 0;
421
422         if (mxl692_i2c_write(dev, local_buf, MXL_EAGLE_I2C_PHEADER_SIZE) > 0) {
423                 size = (size + 3) & ~3;  /* 4 byte alignment */
424
425                 /* Read in 4 byte chunks */
426                 for (ix = 0; ix < size; ix += 4) {
427                         if (mxl692_i2c_read(dev, buffer + ix, 4) < 0) {
428                                 dev_dbg(&dev->i2c_client->dev, "ix=%d   size=%d\n", ix, size);
429                                 status = -EREMOTEIO;
430                                 goto err_finish;
431                         }
432                 }
433                 convert_endian(size, buffer);
434         } else {
435                 status = -EREMOTEIO;
436         }
437 err_finish:
438         if (status)
439                 dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
440         return status;
441 }
442
443 static int mxl692_i2c_writeread(struct mxl692_dev *dev,
444                                 u8 opcode,
445                                 u8 *tx_payload,
446                                 u8 tx_payload_size,
447                                 u8 *rx_payload,
448                                 u8 rx_payload_expected)
449 {
450         int status = 0, timeout = 40;
451         u8 tx_buf[MXL_EAGLE_MAX_I2C_PACKET_SIZE] = {};
452         u8 rx_buf[MXL_EAGLE_MAX_I2C_PACKET_SIZE] = {};
453         u32 resp_checksum = 0, resp_checksum_tmp = 0;
454         struct MXL_EAGLE_HOST_MSG_HEADER_T *tx_header;
455         struct MXL_EAGLE_HOST_MSG_HEADER_T *rx_header;
456
457         mutex_lock(&dev->i2c_lock);
458
459         if ((tx_payload_size + MXL_EAGLE_HOST_MSG_HEADER_SIZE) >
460             (MXL_EAGLE_MAX_I2C_PACKET_SIZE - MXL_EAGLE_I2C_PHEADER_SIZE)) {
461                 status = -EINVAL;
462                 goto err_finish;
463         }
464
465         tx_header = (struct MXL_EAGLE_HOST_MSG_HEADER_T *)tx_buf;
466         tx_header->opcode = opcode;
467         tx_header->seqnum = dev->seqnum++;
468         tx_header->payload_size = tx_payload_size;
469         tx_header->checksum = 0;
470
471         if (dev->seqnum == 0)
472                 dev->seqnum = 1;
473
474         if (tx_payload && tx_payload_size > 0)
475                 memcpy(&tx_buf[MXL_EAGLE_HOST_MSG_HEADER_SIZE], tx_payload, tx_payload_size);
476
477         mxl692_tx_swap(opcode, tx_buf);
478
479         tx_header->checksum = 0;
480         tx_header->checksum = mxl692_checksum(tx_buf,
481                                               MXL_EAGLE_HOST_MSG_HEADER_SIZE + tx_payload_size);
482 #ifdef __LITTLE_ENDIAN
483         convert_endian(4, (u8 *)&tx_header->checksum); /* cksum is big endian */
484 #endif
485         /* send Tx message */
486         status = mxl692_opwrite(dev, tx_buf,
487                                 tx_payload_size + MXL_EAGLE_HOST_MSG_HEADER_SIZE);
488         if (status) {
489                 status = -EREMOTEIO;
490                 goto err_finish;
491         }
492
493         /* receive Rx message (polling) */
494         rx_header = (struct MXL_EAGLE_HOST_MSG_HEADER_T *)rx_buf;
495
496         do {
497                 status = mxl692_opread(dev, rx_buf,
498                                        rx_payload_expected + MXL_EAGLE_HOST_MSG_HEADER_SIZE);
499                 usleep_range(1000, 2000);
500                 timeout--;
501         } while ((timeout > 0) && (status == 0) &&
502                  (rx_header->seqnum == 0) &&
503                  (rx_header->checksum == 0));
504
505         if (timeout == 0 || status) {
506                 dev_dbg(&dev->i2c_client->dev, "timeout=%d   status=%d\n",
507                         timeout, status);
508                 status = -ETIMEDOUT;
509                 goto err_finish;
510         }
511
512         if (rx_header->status) {
513                 dev_dbg(&dev->i2c_client->dev, "rx header status code: %d\n", rx_header->status);
514                 status = -EREMOTEIO;
515                 goto err_finish;
516         }
517
518         if (rx_header->seqnum != tx_header->seqnum ||
519             rx_header->opcode != tx_header->opcode ||
520             rx_header->payload_size != rx_payload_expected) {
521                 dev_dbg(&dev->i2c_client->dev, "Something failed seq=%s  opcode=%s  pSize=%s\n",
522                         rx_header->seqnum != tx_header->seqnum ? "X" : "0",
523                         rx_header->opcode != tx_header->opcode ? "X" : "0",
524                         rx_header->payload_size != rx_payload_expected ? "X" : "0");
525                 if (rx_header->payload_size != rx_payload_expected)
526                         dev_dbg(&dev->i2c_client->dev,
527                                 "rx_header->payloadSize=%d   rx_payload_expected=%d\n",
528                                 rx_header->payload_size, rx_payload_expected);
529                 status = -EREMOTEIO;
530                 goto err_finish;
531         }
532
533         resp_checksum = rx_header->checksum;
534         rx_header->checksum = 0;
535
536         resp_checksum_tmp = mxl692_checksum(rx_buf,
537                                             MXL_EAGLE_HOST_MSG_HEADER_SIZE + rx_header->payload_size);
538 #ifdef __LITTLE_ENDIAN
539         convert_endian(4, (u8 *)&resp_checksum_tmp); /* cksum is big endian */
540 #endif
541         if (resp_checksum != resp_checksum_tmp) {
542                 dev_dbg(&dev->i2c_client->dev, "rx checksum failure\n");
543                 status = -EREMOTEIO;
544                 goto err_finish;
545         }
546
547         mxl692_rx_swap(rx_header->opcode, rx_buf);
548
549         if (rx_header->payload_size > 0) {
550                 if (!rx_payload) {
551                         dev_dbg(&dev->i2c_client->dev, "no rx payload?!?\n");
552                         status = -EREMOTEIO;
553                         goto err_finish;
554                 }
555                 memcpy(rx_payload, rx_buf + MXL_EAGLE_HOST_MSG_HEADER_SIZE,
556                        rx_header->payload_size);
557         }
558 err_finish:
559         if (status)
560                 dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
561
562         mutex_unlock(&dev->i2c_lock);
563         return status;
564 }
565
566 static int mxl692_fwdownload(struct mxl692_dev *dev,
567                              const u8 *firmware_buf, u32 buf_len)
568 {
569         int status = 0;
570         u32 ix, reg_val = 0x1;
571         u8 rx_buf[MXL_EAGLE_MAX_I2C_PACKET_SIZE] = {};
572         struct MXL_EAGLE_DEV_STATUS_T *dev_status;
573
574         if (buf_len < MXL_EAGLE_FW_HEADER_SIZE ||
575             buf_len > MXL_EAGLE_FW_MAX_SIZE_IN_KB * 1000)
576                 return -EINVAL;
577
578         mutex_lock(&dev->i2c_lock);
579
580         dev_dbg(&dev->i2c_client->dev, "\n");
581
582         status = mxl692_validate_fw_header(dev, firmware_buf, buf_len);
583         if (status)
584                 goto err_finish;
585
586         ix = 16;
587         status = mxl692_write_fw_block(dev, firmware_buf, buf_len, &ix); /* DRAM */
588         if (status)
589                 goto err_finish;
590
591         status = mxl692_write_fw_block(dev, firmware_buf, buf_len, &ix); /* IRAM */
592         if (status)
593                 goto err_finish;
594
595         /* release CPU from reset */
596         status = mxl692_memwrite(dev, 0x70000018, (u8 *)&reg_val, sizeof(u32));
597         if (status)
598                 goto err_finish;
599
600         mutex_unlock(&dev->i2c_lock);
601
602         if (status == 0) {
603                 /* verify FW is alive */
604                 usleep_range(MXL_EAGLE_FW_LOAD_TIME * 1000, (MXL_EAGLE_FW_LOAD_TIME + 5) * 1000);
605                 dev_status = (struct MXL_EAGLE_DEV_STATUS_T *)&rx_buf;
606                 status = mxl692_i2c_writeread(dev,
607                                               MXL_EAGLE_OPCODE_DEVICE_STATUS_GET,
608                                               NULL,
609                                               0,
610                                               (u8 *)dev_status,
611                                               sizeof(struct MXL_EAGLE_DEV_STATUS_T));
612         }
613
614         return status;
615 err_finish:
616         mutex_unlock(&dev->i2c_lock);
617         if (status)
618                 dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
619         return status;
620 }
621
622 static int mxl692_get_versions(struct mxl692_dev *dev)
623 {
624         int status = 0;
625         struct MXL_EAGLE_DEV_VER_T dev_ver = {};
626         static const char * const chip_id[] = {"N/A", "691", "248", "692"};
627
628         status = mxl692_i2c_writeread(dev, MXL_EAGLE_OPCODE_DEVICE_VERSION_GET,
629                                       NULL,
630                                       0,
631                                       (u8 *)&dev_ver,
632                                       sizeof(struct MXL_EAGLE_DEV_VER_T));
633         if (status)
634                 return status;
635
636         dev_info(&dev->i2c_client->dev, "MxL692_DEMOD Chip ID: %s\n",
637                  chip_id[dev_ver.chip_id]);
638
639         dev_info(&dev->i2c_client->dev,
640                  "MxL692_DEMOD FW Version: %d.%d.%d.%d_RC%d\n",
641                  dev_ver.firmware_ver[0],
642                  dev_ver.firmware_ver[1],
643                  dev_ver.firmware_ver[2],
644                  dev_ver.firmware_ver[3],
645                  dev_ver.firmware_ver[4]);
646
647         return status;
648 }
649
650 static int mxl692_reset(struct mxl692_dev *dev)
651 {
652         int status = 0;
653         u32 dev_type = MXL_EAGLE_DEVICE_MAX, reg_val = 0x2;
654
655         dev_dbg(&dev->i2c_client->dev, "\n");
656
657         /* legacy i2c override */
658         status = mxl692_memwrite(dev, 0x80000100, (u8 *)&reg_val, sizeof(u32));
659         if (status)
660                 goto err_finish;
661
662         /* verify sku */
663         status = mxl692_memread(dev, 0x70000188, (u8 *)&dev_type, sizeof(u32));
664         if (status)
665                 goto err_finish;
666
667         if (dev_type != dev->device_type)
668                 goto err_finish;
669
670 err_finish:
671         if (status)
672                 dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
673         return status;
674 }
675
676 static int mxl692_config_regulators(struct mxl692_dev *dev,
677                                     enum MXL_EAGLE_POWER_SUPPLY_SOURCE_E power_supply)
678 {
679         int status = 0;
680         u32 reg_val;
681
682         dev_dbg(&dev->i2c_client->dev, "\n");
683
684         /* configure main regulator according to the power supply source */
685         status = mxl692_memread(dev, 0x90000000, (u8 *)&reg_val, sizeof(u32));
686         if (status)
687                 goto err_finish;
688
689         reg_val &= 0x00FFFFFF;
690         reg_val |= (power_supply == MXL_EAGLE_POWER_SUPPLY_SOURCE_SINGLE) ?
691                                         0x14000000 : 0x10000000;
692
693         status = mxl692_memwrite(dev, 0x90000000, (u8 *)&reg_val, sizeof(u32));
694         if (status)
695                 goto err_finish;
696
697         /* configure digital regulator to high current mode */
698         status = mxl692_memread(dev, 0x90000018, (u8 *)&reg_val, sizeof(u32));
699         if (status)
700                 goto err_finish;
701
702         reg_val |= 0x800;
703
704         status = mxl692_memwrite(dev, 0x90000018, (u8 *)&reg_val, sizeof(u32));
705
706 err_finish:
707         if (status)
708                 dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
709         return status;
710 }
711
712 static int mxl692_config_xtal(struct mxl692_dev *dev,
713                               struct MXL_EAGLE_DEV_XTAL_T *dev_xtal)
714 {
715         int status = 0;
716         u32 reg_val, reg_val1;
717
718         dev_dbg(&dev->i2c_client->dev, "\n");
719
720         status = mxl692_memread(dev, 0x90000000, (u8 *)&reg_val, sizeof(u32));
721         if (status)
722                 goto err_finish;
723
724         /* set XTAL capacitance */
725         reg_val &= 0xFFFFFFE0;
726         reg_val |= dev_xtal->xtal_cap;
727
728         /* set CLK OUT */
729         reg_val = dev_xtal->clk_out_enable ? (reg_val | 0x0100) : (reg_val & 0xFFFFFEFF);
730
731         status = mxl692_memwrite(dev, 0x90000000, (u8 *)&reg_val, sizeof(u32));
732         if (status)
733                 goto err_finish;
734
735         /* set CLK OUT divider */
736         reg_val = dev_xtal->clk_out_div_enable ? (reg_val | 0x0200) : (reg_val & 0xFFFFFDFF);
737
738         status = mxl692_memwrite(dev, 0x90000000, (u8 *)&reg_val, sizeof(u32));
739         if (status)
740                 goto err_finish;
741
742         /* set XTAL sharing */
743         reg_val = dev_xtal->xtal_sharing_enable ? (reg_val | 0x010400) : (reg_val & 0xFFFEFBFF);
744
745         status = mxl692_memwrite(dev, 0x90000000, (u8 *)&reg_val, sizeof(u32));
746         if (status)
747                 goto err_finish;
748
749         /* enable/disable XTAL calibration, based on master/slave device */
750         status = mxl692_memread(dev, 0x90000030, (u8 *)&reg_val1, sizeof(u32));
751         if (status)
752                 goto err_finish;
753
754         if (dev_xtal->xtal_calibration_enable) {
755                 /* enable XTAL calibration and set XTAL amplitude to a higher value */
756                 reg_val1 &= 0xFFFFFFFD;
757                 reg_val1 |= 0x30;
758
759                 status = mxl692_memwrite(dev, 0x90000030, (u8 *)&reg_val1, sizeof(u32));
760                 if (status)
761                         goto err_finish;
762         } else {
763                 /* disable XTAL calibration */
764                 reg_val1 |= 0x2;
765
766                 status = mxl692_memwrite(dev, 0x90000030, (u8 *)&reg_val1, sizeof(u32));
767                 if (status)
768                         goto err_finish;
769
770                 /* set XTAL bias value */
771                 status = mxl692_memread(dev, 0x9000002c, (u8 *)&reg_val, sizeof(u32));
772                 if (status)
773                         goto err_finish;
774
775                 reg_val &= 0xC0FFFFFF;
776                 reg_val |= 0xA000000;
777
778                 status = mxl692_memwrite(dev, 0x9000002c, (u8 *)&reg_val, sizeof(u32));
779                 if (status)
780                         goto err_finish;
781         }
782
783         /* start XTAL calibration */
784         status = mxl692_memread(dev, 0x70000010, (u8 *)&reg_val, sizeof(u32));
785         if (status)
786                 goto err_finish;
787
788         reg_val |= 0x8;
789
790         status = mxl692_memwrite(dev, 0x70000010, (u8 *)&reg_val, sizeof(u32));
791         if (status)
792                 goto err_finish;
793
794         status = mxl692_memread(dev, 0x70000018, (u8 *)&reg_val, sizeof(u32));
795         if (status)
796                 goto err_finish;
797
798         reg_val |= 0x10;
799
800         status = mxl692_memwrite(dev, 0x70000018, (u8 *)&reg_val, sizeof(u32));
801         if (status)
802                 goto err_finish;
803
804         status = mxl692_memread(dev, 0x9001014c, (u8 *)&reg_val, sizeof(u32));
805         if (status)
806                 goto err_finish;
807
808         reg_val &= 0xFFFFEFFF;
809
810         status = mxl692_memwrite(dev, 0x9001014c, (u8 *)&reg_val, sizeof(u32));
811         if (status)
812                 goto err_finish;
813
814         reg_val |= 0x1000;
815
816         status = mxl692_memwrite(dev, 0x9001014c, (u8 *)&reg_val, sizeof(u32));
817         if (status)
818                 goto err_finish;
819
820         usleep_range(45000, 55000);
821
822 err_finish:
823         if (status)
824                 dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
825         return status;
826 }
827
828 static int mxl692_powermode(struct mxl692_dev *dev,
829                             enum MXL_EAGLE_POWER_MODE_E power_mode)
830 {
831         int status = 0;
832         u8 mode = power_mode;
833
834         dev_dbg(&dev->i2c_client->dev, "%s\n",
835                 power_mode == MXL_EAGLE_POWER_MODE_SLEEP ? "sleep" : "active");
836
837         status = mxl692_i2c_writeread(dev,
838                                       MXL_EAGLE_OPCODE_DEVICE_POWERMODE_SET,
839                                       &mode,
840                                       sizeof(u8),
841                                       NULL,
842                                       0);
843         if (status) {
844                 dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
845                 return status;
846         }
847
848         dev->power_mode = power_mode;
849
850         return status;
851 }
852
853 static int mxl692_init(struct dvb_frontend *fe)
854 {
855         struct mxl692_dev *dev = fe->demodulator_priv;
856         struct i2c_client *client = dev->i2c_client;
857         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
858         int status = 0;
859         const struct firmware *firmware;
860         struct MXL_EAGLE_DEV_XTAL_T xtal_config = {};
861
862         dev_dbg(&dev->i2c_client->dev, "\n");
863
864         if (dev->init_done)
865                 goto warm;
866
867         dev->seqnum = 1;
868
869         status = mxl692_reset(dev);
870         if (status)
871                 goto err;
872
873         usleep_range(50 * 1000, 60 * 1000); /* was 1000! */
874
875         status = mxl692_config_regulators(dev, MXL_EAGLE_POWER_SUPPLY_SOURCE_DUAL);
876         if (status)
877                 goto err;
878
879         xtal_config.xtal_cap = 26;
880         xtal_config.clk_out_div_enable = 0;
881         xtal_config.clk_out_enable = 0;
882         xtal_config.xtal_calibration_enable = 0;
883         xtal_config.xtal_sharing_enable = 1;
884         status = mxl692_config_xtal(dev, &xtal_config);
885         if (status)
886                 goto err;
887
888         status = request_firmware(&firmware, MXL692_FIRMWARE, &client->dev);
889         if (status) {
890                 dev_dbg(&dev->i2c_client->dev, "firmware missing? %s\n",
891                         MXL692_FIRMWARE);
892                 goto err;
893         }
894
895         status = mxl692_fwdownload(dev, firmware->data, firmware->size);
896         if (status)
897                 goto err_release_firmware;
898
899         release_firmware(firmware);
900
901         status = mxl692_get_versions(dev);
902         if (status)
903                 goto err;
904
905         dev->power_mode = MXL_EAGLE_POWER_MODE_SLEEP;
906 warm:
907         /* Config Device Power Mode */
908         if (dev->power_mode != MXL_EAGLE_POWER_MODE_ACTIVE) {
909                 status = mxl692_powermode(dev, MXL_EAGLE_POWER_MODE_ACTIVE);
910                 if (status)
911                         goto err;
912
913                 usleep_range(50 * 1000, 60 * 1000); /* was 500! */
914         }
915
916         /* Init stats here to indicate which stats are supported */
917         c->cnr.len = 1;
918         c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
919         c->post_bit_error.len = 1;
920         c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
921         c->post_bit_count.len = 1;
922         c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
923         c->block_error.len = 1;
924         c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
925
926         dev->init_done = 1;
927         return 0;
928 err_release_firmware:
929         release_firmware(firmware);
930 err:
931         dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
932         return status;
933 }
934
935 static int mxl692_sleep(struct dvb_frontend *fe)
936 {
937         struct mxl692_dev *dev = fe->demodulator_priv;
938
939         if (dev->power_mode != MXL_EAGLE_POWER_MODE_SLEEP)
940                 mxl692_powermode(dev, MXL_EAGLE_POWER_MODE_SLEEP);
941
942         return 0;
943 }
944
945 static int mxl692_set_frontend(struct dvb_frontend *fe)
946 {
947         struct dtv_frontend_properties *p = &fe->dtv_property_cache;
948         struct mxl692_dev *dev = fe->demodulator_priv;
949
950         int status = 0;
951         enum MXL_EAGLE_DEMOD_TYPE_E demod_type;
952         struct MXL_EAGLE_MPEGOUT_PARAMS_T mpeg_params = {};
953         enum MXL_EAGLE_QAM_DEMOD_ANNEX_TYPE_E qam_annex = MXL_EAGLE_QAM_DEMOD_ANNEX_B;
954         struct MXL_EAGLE_QAM_DEMOD_PARAMS_T qam_params = {};
955         struct MXL_EAGLE_TUNER_CHANNEL_PARAMS_T tuner_params = {};
956         u8 op_param = 0;
957
958         dev_dbg(&dev->i2c_client->dev, "\n");
959
960         switch (p->modulation) {
961         case VSB_8:
962                 demod_type = MXL_EAGLE_DEMOD_TYPE_ATSC;
963                 break;
964         case QAM_AUTO:
965         case QAM_64:
966         case QAM_128:
967         case QAM_256:
968                 demod_type = MXL_EAGLE_DEMOD_TYPE_QAM;
969                 break;
970         default:
971                 return -EINVAL;
972         }
973
974         if (dev->current_frequency == p->frequency && dev->demod_type == demod_type) {
975                 dev_dbg(&dev->i2c_client->dev, "already set up\n");
976                 return 0;
977         }
978
979         dev->current_frequency = -1;
980         dev->demod_type = -1;
981
982         op_param = demod_type;
983         status = mxl692_i2c_writeread(dev,
984                                       MXL_EAGLE_OPCODE_DEVICE_DEMODULATOR_TYPE_SET,
985                                       &op_param,
986                                       sizeof(u8),
987                                       NULL,
988                                       0);
989         if (status) {
990                 dev_dbg(&dev->i2c_client->dev,
991                         "DEVICE_DEMODULATOR_TYPE_SET...FAIL  err 0x%x\n", status);
992                 goto err;
993         }
994
995         usleep_range(20 * 1000, 30 * 1000); /* was 500! */
996
997         mpeg_params.mpeg_parallel = 0;
998         mpeg_params.msb_first = MXL_EAGLE_DATA_SERIAL_MSB_1ST;
999         mpeg_params.mpeg_sync_pulse_width = MXL_EAGLE_DATA_SYNC_WIDTH_BIT;
1000         mpeg_params.mpeg_valid_pol = MXL_EAGLE_CLOCK_POSITIVE;
1001         mpeg_params.mpeg_sync_pol = MXL_EAGLE_CLOCK_POSITIVE;
1002         mpeg_params.mpeg_clk_pol = MXL_EAGLE_CLOCK_NEGATIVE;
1003         mpeg_params.mpeg3wire_mode_enable = 0;
1004         mpeg_params.mpeg_clk_freq = MXL_EAGLE_MPEG_CLOCK_27MHZ;
1005
1006         switch (demod_type) {
1007         case MXL_EAGLE_DEMOD_TYPE_ATSC:
1008                 status = mxl692_i2c_writeread(dev,
1009                                               MXL_EAGLE_OPCODE_DEVICE_MPEG_OUT_PARAMS_SET,
1010                                               (u8 *)&mpeg_params,
1011                                               sizeof(struct MXL_EAGLE_MPEGOUT_PARAMS_T),
1012                                               NULL,
1013                                               0);
1014                 if (status)
1015                         goto err;
1016                 break;
1017         case MXL_EAGLE_DEMOD_TYPE_QAM:
1018                 if (qam_annex == MXL_EAGLE_QAM_DEMOD_ANNEX_A)
1019                         mpeg_params.msb_first = MXL_EAGLE_DATA_SERIAL_LSB_1ST;
1020                 status = mxl692_i2c_writeread(dev,
1021                                               MXL_EAGLE_OPCODE_DEVICE_MPEG_OUT_PARAMS_SET,
1022                                               (u8 *)&mpeg_params,
1023                                               sizeof(struct MXL_EAGLE_MPEGOUT_PARAMS_T),
1024                                               NULL,
1025                                               0);
1026                 if (status)
1027                         goto err;
1028
1029                 qam_params.annex_type = qam_annex;
1030                 qam_params.qam_type = MXL_EAGLE_QAM_DEMOD_AUTO;
1031                 qam_params.iq_flip = MXL_EAGLE_DEMOD_IQ_AUTO;
1032                 if (p->modulation == QAM_64)
1033                         qam_params.symbol_rate_hz = 5057000;
1034                 else
1035                         qam_params.symbol_rate_hz = 5361000;
1036
1037                 qam_params.symbol_rate_256qam_hz = 5361000;
1038
1039                 status = mxl692_i2c_writeread(dev,
1040                                               MXL_EAGLE_OPCODE_QAM_PARAMS_SET,
1041                                               (u8 *)&qam_params,
1042                                               sizeof(struct MXL_EAGLE_QAM_DEMOD_PARAMS_T),
1043                                               NULL, 0);
1044                 if (status)
1045                         goto err;
1046
1047                 break;
1048         default:
1049                 break;
1050         }
1051
1052         usleep_range(20 * 1000, 30 * 1000); /* was 500! */
1053
1054         tuner_params.freq_hz = p->frequency;
1055         tuner_params.bandwidth = MXL_EAGLE_TUNER_BW_6MHZ;
1056         tuner_params.tune_mode = MXL_EAGLE_TUNER_CHANNEL_TUNE_MODE_VIEW;
1057
1058         dev_dbg(&dev->i2c_client->dev, " Tuning Freq: %d %s\n", tuner_params.freq_hz,
1059                 demod_type == MXL_EAGLE_DEMOD_TYPE_ATSC ? "ATSC" : "QAM");
1060
1061         status = mxl692_i2c_writeread(dev,
1062                                       MXL_EAGLE_OPCODE_TUNER_CHANNEL_TUNE_SET,
1063                                       (u8 *)&tuner_params,
1064                                       sizeof(struct MXL_EAGLE_TUNER_CHANNEL_PARAMS_T),
1065                                       NULL,
1066                                       0);
1067         if (status)
1068                 goto err;
1069
1070         usleep_range(20 * 1000, 30 * 1000); /* was 500! */
1071
1072         switch (demod_type) {
1073         case MXL_EAGLE_DEMOD_TYPE_ATSC:
1074                 status = mxl692_i2c_writeread(dev,
1075                                               MXL_EAGLE_OPCODE_ATSC_INIT_SET,
1076                                               NULL, 0, NULL, 0);
1077                 if (status)
1078                         goto err;
1079                 break;
1080         case MXL_EAGLE_DEMOD_TYPE_QAM:
1081                 status = mxl692_i2c_writeread(dev,
1082                                               MXL_EAGLE_OPCODE_QAM_RESTART_SET,
1083                                               NULL, 0, NULL, 0);
1084                 if (status)
1085                         goto err;
1086                 break;
1087         default:
1088                 break;
1089         }
1090
1091         dev->demod_type = demod_type;
1092         dev->current_frequency = p->frequency;
1093
1094         return 0;
1095 err:
1096         dev_dbg(&dev->i2c_client->dev, "err %d\n", status);
1097         return status;
1098 }
1099
1100 static int mxl692_get_frontend(struct dvb_frontend *fe,
1101                                struct dtv_frontend_properties *p)
1102 {
1103         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1104
1105         p->modulation = c->modulation;
1106         p->frequency = c->frequency;
1107
1108         return 0;
1109 }
1110
1111 static int mxl692_read_snr(struct dvb_frontend *fe, u16 *snr)
1112 {
1113         struct mxl692_dev *dev = fe->demodulator_priv;
1114         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1115         u8 rx_buf[MXL_EAGLE_MAX_I2C_PACKET_SIZE] = {};
1116         struct MXL_EAGLE_ATSC_DEMOD_STATUS_T *atsc_status;
1117         struct MXL_EAGLE_QAM_DEMOD_STATUS_T *qam_status;
1118         enum MXL_EAGLE_DEMOD_TYPE_E demod_type = dev->demod_type;
1119         int mxl_status = 0;
1120
1121         *snr = 0;
1122
1123         dev_dbg(&dev->i2c_client->dev, "\n");
1124
1125         atsc_status = (struct MXL_EAGLE_ATSC_DEMOD_STATUS_T *)&rx_buf;
1126         qam_status = (struct MXL_EAGLE_QAM_DEMOD_STATUS_T *)&rx_buf;
1127
1128         switch (demod_type) {
1129         case MXL_EAGLE_DEMOD_TYPE_ATSC:
1130                 mxl_status = mxl692_i2c_writeread(dev,
1131                                                   MXL_EAGLE_OPCODE_ATSC_STATUS_GET,
1132                                                   NULL,
1133                                                   0,
1134                                                   rx_buf,
1135                                                   sizeof(struct MXL_EAGLE_ATSC_DEMOD_STATUS_T));
1136                 if (!mxl_status) {
1137                         *snr = (u16)(atsc_status->snr_db_tenths / 10);
1138                         c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
1139                         c->cnr.stat[0].svalue = *snr;
1140                 }
1141                 break;
1142         case MXL_EAGLE_DEMOD_TYPE_QAM:
1143                 mxl_status = mxl692_i2c_writeread(dev,
1144                                                   MXL_EAGLE_OPCODE_QAM_STATUS_GET,
1145                                                   NULL,
1146                                                   0,
1147                                                   rx_buf,
1148                                                   sizeof(struct MXL_EAGLE_QAM_DEMOD_STATUS_T));
1149                 if (!mxl_status)
1150                         *snr = (u16)(qam_status->snr_db_tenths / 10);
1151                 break;
1152         case MXL_EAGLE_DEMOD_TYPE_OOB:
1153         default:
1154                 break;
1155         }
1156
1157         if (mxl_status)
1158                 dev_dbg(&dev->i2c_client->dev, "err %d\n", mxl_status);
1159         return mxl_status;
1160 }
1161
1162 static int mxl692_read_ber_ucb(struct dvb_frontend *fe)
1163 {
1164         struct mxl692_dev *dev = fe->demodulator_priv;
1165         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1166         u8 rx_buf[MXL_EAGLE_MAX_I2C_PACKET_SIZE] = {};
1167         struct MXL_EAGLE_ATSC_DEMOD_ERROR_COUNTERS_T *atsc_errors;
1168         enum MXL_EAGLE_DEMOD_TYPE_E demod_type = dev->demod_type;
1169         int mxl_status = 0;
1170         u32 utmp;
1171
1172         dev_dbg(&dev->i2c_client->dev, "\n");
1173
1174         atsc_errors = (struct MXL_EAGLE_ATSC_DEMOD_ERROR_COUNTERS_T *)&rx_buf;
1175
1176         switch (demod_type) {
1177         case MXL_EAGLE_DEMOD_TYPE_ATSC:
1178                 mxl_status = mxl692_i2c_writeread(dev,
1179                                                   MXL_EAGLE_OPCODE_ATSC_ERROR_COUNTERS_GET,
1180                                                   NULL,
1181                                                   0,
1182                                                   rx_buf,
1183                                                   sizeof(struct MXL_EAGLE_ATSC_DEMOD_ERROR_COUNTERS_T));
1184                 if (!mxl_status) {
1185                         if (atsc_errors->error_packets == 0)
1186                                 utmp = 0;
1187                         else
1188                                 utmp = ((atsc_errors->error_bytes / atsc_errors->error_packets) *
1189                                         atsc_errors->total_packets);
1190                         /* ber */
1191                         c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
1192                         c->post_bit_error.stat[0].uvalue += atsc_errors->error_bytes;
1193                         c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
1194                         c->post_bit_count.stat[0].uvalue += utmp;
1195                         /* ucb */
1196                         c->block_error.stat[0].scale = FE_SCALE_COUNTER;
1197                         c->block_error.stat[0].uvalue += atsc_errors->error_packets;
1198
1199                         dev_dbg(&dev->i2c_client->dev, "%llu   %llu\n",
1200                                 c->post_bit_count.stat[0].uvalue, c->block_error.stat[0].uvalue);
1201                 }
1202                 break;
1203         case MXL_EAGLE_DEMOD_TYPE_QAM:
1204         case MXL_EAGLE_DEMOD_TYPE_OOB:
1205         default:
1206                 break;
1207         }
1208
1209         if (mxl_status)
1210                 dev_dbg(&dev->i2c_client->dev, "err %d\n", mxl_status);
1211
1212         return mxl_status;
1213 }
1214
1215 static int mxl692_read_status(struct dvb_frontend *fe,
1216                               enum fe_status *status)
1217 {
1218         struct mxl692_dev *dev = fe->demodulator_priv;
1219         struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1220         u8 rx_buf[MXL_EAGLE_MAX_I2C_PACKET_SIZE] = {};
1221         struct MXL_EAGLE_ATSC_DEMOD_STATUS_T *atsc_status;
1222         struct MXL_EAGLE_QAM_DEMOD_STATUS_T *qam_status;
1223         enum MXL_EAGLE_DEMOD_TYPE_E demod_type = dev->demod_type;
1224         int mxl_status = 0;
1225         *status = 0;
1226
1227         dev_dbg(&dev->i2c_client->dev, "\n");
1228
1229         atsc_status = (struct MXL_EAGLE_ATSC_DEMOD_STATUS_T *)&rx_buf;
1230         qam_status = (struct MXL_EAGLE_QAM_DEMOD_STATUS_T *)&rx_buf;
1231
1232         switch (demod_type) {
1233         case MXL_EAGLE_DEMOD_TYPE_ATSC:
1234                 mxl_status = mxl692_i2c_writeread(dev,
1235                                                   MXL_EAGLE_OPCODE_ATSC_STATUS_GET,
1236                                                   NULL,
1237                                                   0,
1238                                                   rx_buf,
1239                                                   sizeof(struct MXL_EAGLE_ATSC_DEMOD_STATUS_T));
1240                 if (!mxl_status && atsc_status->atsc_lock) {
1241                         *status |= FE_HAS_SIGNAL;
1242                         *status |= FE_HAS_CARRIER;
1243                         *status |= FE_HAS_VITERBI;
1244                         *status |= FE_HAS_SYNC;
1245                         *status |= FE_HAS_LOCK;
1246
1247                         c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
1248                         c->cnr.stat[0].svalue = atsc_status->snr_db_tenths / 10;
1249                 }
1250                 break;
1251         case MXL_EAGLE_DEMOD_TYPE_QAM:
1252                 mxl_status = mxl692_i2c_writeread(dev,
1253                                                   MXL_EAGLE_OPCODE_QAM_STATUS_GET,
1254                                                   NULL,
1255                                                   0,
1256                                                   rx_buf,
1257                                                   sizeof(struct MXL_EAGLE_QAM_DEMOD_STATUS_T));
1258                 if (!mxl_status && qam_status->qam_locked) {
1259                         *status |= FE_HAS_SIGNAL;
1260                         *status |= FE_HAS_CARRIER;
1261                         *status |= FE_HAS_VITERBI;
1262                         *status |= FE_HAS_SYNC;
1263                         *status |= FE_HAS_LOCK;
1264
1265                         c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
1266                         c->cnr.stat[0].svalue = qam_status->snr_db_tenths / 10;
1267                 }
1268                 break;
1269         case MXL_EAGLE_DEMOD_TYPE_OOB:
1270         default:
1271                 break;
1272         }
1273
1274         if ((*status & FE_HAS_LOCK) == 0) {
1275                 /* No lock, reset all statistics */
1276                 c->cnr.len = 1;
1277                 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1278                 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1279                 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1280                 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1281                 return 0;
1282         }
1283
1284         if (mxl_status)
1285                 dev_dbg(&dev->i2c_client->dev, "err %d\n", mxl_status);
1286         else
1287                 mxl_status = mxl692_read_ber_ucb(fe);
1288
1289         return mxl_status;
1290 }
1291
1292 static const struct dvb_frontend_ops mxl692_ops = {
1293         .delsys = { SYS_ATSC },
1294         .info = {
1295                 .name = "MaxLinear MxL692 VSB tuner-demodulator",
1296                 .frequency_min_hz      = 54000000,
1297                 .frequency_max_hz      = 858000000,
1298                 .frequency_stepsize_hz = 62500,
1299                 .caps = FE_CAN_8VSB
1300         },
1301
1302         .init         = mxl692_init,
1303         .sleep        = mxl692_sleep,
1304         .set_frontend = mxl692_set_frontend,
1305         .get_frontend = mxl692_get_frontend,
1306
1307         .read_status          = mxl692_read_status,
1308         .read_snr             = mxl692_read_snr,
1309 };
1310
1311 static int mxl692_probe(struct i2c_client *client,
1312                         const struct i2c_device_id *id)
1313 {
1314         struct mxl692_config *config = client->dev.platform_data;
1315         struct mxl692_dev *dev;
1316         int ret = 0;
1317
1318         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1319         if (!dev) {
1320                 ret = -ENOMEM;
1321                 dev_dbg(&client->dev, "kzalloc() failed\n");
1322                 goto err;
1323         }
1324
1325         memcpy(&dev->fe.ops, &mxl692_ops, sizeof(struct dvb_frontend_ops));
1326         dev->fe.demodulator_priv = dev;
1327         dev->i2c_client = client;
1328         *config->fe = &dev->fe;
1329         mutex_init(&dev->i2c_lock);
1330         i2c_set_clientdata(client, dev);
1331
1332         dev_info(&client->dev, "MaxLinear mxl692 successfully attached\n");
1333
1334         return 0;
1335 err:
1336         dev_dbg(&client->dev, "failed %d\n", ret);
1337         return -ENODEV;
1338 }
1339
1340 static int mxl692_remove(struct i2c_client *client)
1341 {
1342         struct mxl692_dev *dev = i2c_get_clientdata(client);
1343
1344         dev->fe.demodulator_priv = NULL;
1345         i2c_set_clientdata(client, NULL);
1346         kfree(dev);
1347
1348         return 0;
1349 }
1350
1351 static const struct i2c_device_id mxl692_id_table[] = {
1352         {"mxl692", 0},
1353         {}
1354 };
1355 MODULE_DEVICE_TABLE(i2c, mxl692_id_table);
1356
1357 static struct i2c_driver mxl692_driver = {
1358         .driver = {
1359                 .name   = "mxl692",
1360         },
1361         .probe          = mxl692_probe,
1362         .remove         = mxl692_remove,
1363         .id_table       = mxl692_id_table,
1364 };
1365
1366 module_i2c_driver(mxl692_driver);
1367
1368 MODULE_AUTHOR("Brad Love <brad@nextdimension.cc>");
1369 MODULE_DESCRIPTION("MaxLinear MxL692 demodulator/tuner driver");
1370 MODULE_FIRMWARE(MXL692_FIRMWARE);
1371 MODULE_LICENSE("GPL");