xref: /linux/drivers/media/dvb-frontends/mxl692.c (revision cbdb1f163af2bb90d01be1f0263df1d8d5c9d9d3)
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 {
1313 	struct mxl692_config *config = client->dev.platform_data;
1314 	struct mxl692_dev *dev;
1315 	int ret = 0;
1316 
1317 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1318 	if (!dev) {
1319 		ret = -ENOMEM;
1320 		dev_dbg(&client->dev, "kzalloc() failed\n");
1321 		goto err;
1322 	}
1323 
1324 	memcpy(&dev->fe.ops, &mxl692_ops, sizeof(struct dvb_frontend_ops));
1325 	dev->fe.demodulator_priv = dev;
1326 	dev->i2c_client = client;
1327 	*config->fe = &dev->fe;
1328 	mutex_init(&dev->i2c_lock);
1329 	i2c_set_clientdata(client, dev);
1330 
1331 	dev_info(&client->dev, "MaxLinear mxl692 successfully attached\n");
1332 
1333 	return 0;
1334 err:
1335 	dev_dbg(&client->dev, "failed %d\n", ret);
1336 	return -ENODEV;
1337 }
1338 
1339 static void mxl692_remove(struct i2c_client *client)
1340 {
1341 	struct mxl692_dev *dev = i2c_get_clientdata(client);
1342 
1343 	dev->fe.demodulator_priv = NULL;
1344 	i2c_set_clientdata(client, NULL);
1345 	kfree(dev);
1346 }
1347 
1348 static const struct i2c_device_id mxl692_id_table[] = {
1349 	{"mxl692", 0},
1350 	{}
1351 };
1352 MODULE_DEVICE_TABLE(i2c, mxl692_id_table);
1353 
1354 static struct i2c_driver mxl692_driver = {
1355 	.driver = {
1356 		.name	= "mxl692",
1357 	},
1358 	.probe_new	= mxl692_probe,
1359 	.remove		= mxl692_remove,
1360 	.id_table	= mxl692_id_table,
1361 };
1362 
1363 module_i2c_driver(mxl692_driver);
1364 
1365 MODULE_AUTHOR("Brad Love <brad@nextdimension.cc>");
1366 MODULE_DESCRIPTION("MaxLinear MxL692 demodulator/tuner driver");
1367 MODULE_FIRMWARE(MXL692_FIRMWARE);
1368 MODULE_LICENSE("GPL");
1369