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 *)®_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 *)®_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 *)®_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 *)®_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 *)®_val, sizeof(u32)); 706 if (status) 707 goto err_finish; 708 709 reg_val |= 0x800; 710 711 status = mxl692_memwrite(dev, 0x90000018, (u8 *)®_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 *)®_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 *)®_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 *)®_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 *)®_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 *)®_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 *)®_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 *)®_val1, sizeof(u32)); 774 if (status) 775 goto err_finish; 776 777 /* set XTAL bias value */ 778 status = mxl692_memread(dev, 0x9000002c, (u8 *)®_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 *)®_val, sizeof(u32)); 786 if (status) 787 goto err_finish; 788 } 789 790 /* start XTAL calibration */ 791 status = mxl692_memread(dev, 0x70000010, (u8 *)®_val, sizeof(u32)); 792 if (status) 793 goto err_finish; 794 795 reg_val |= 0x8; 796 797 status = mxl692_memwrite(dev, 0x70000010, (u8 *)®_val, sizeof(u32)); 798 if (status) 799 goto err_finish; 800 801 status = mxl692_memread(dev, 0x70000018, (u8 *)®_val, sizeof(u32)); 802 if (status) 803 goto err_finish; 804 805 reg_val |= 0x10; 806 807 status = mxl692_memwrite(dev, 0x70000018, (u8 *)®_val, sizeof(u32)); 808 if (status) 809 goto err_finish; 810 811 status = mxl692_memread(dev, 0x9001014c, (u8 *)®_val, sizeof(u32)); 812 if (status) 813 goto err_finish; 814 815 reg_val &= 0xFFFFEFFF; 816 817 status = mxl692_memwrite(dev, 0x9001014c, (u8 *)®_val, sizeof(u32)); 818 if (status) 819 goto err_finish; 820 821 reg_val |= 0x1000; 822 823 status = mxl692_memwrite(dev, 0x9001014c, (u8 *)®_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"); 1379