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