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