cxd2880_tnrdmd.c (77019B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * cxd2880_tnrdmd.c 4 * Sony CXD2880 DVB-T2/T tuner + demodulator driver 5 * common control functions 6 * 7 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation 8 */ 9 10#include <media/dvb_frontend.h> 11#include "cxd2880_common.h" 12#include "cxd2880_tnrdmd.h" 13#include "cxd2880_tnrdmd_mon.h" 14#include "cxd2880_tnrdmd_dvbt.h" 15#include "cxd2880_tnrdmd_dvbt2.h" 16 17static const struct cxd2880_reg_value p_init1_seq[] = { 18 {0x11, 0x16}, {0x00, 0x10}, 19}; 20 21static const struct cxd2880_reg_value rf_init1_seq1[] = { 22 {0x4f, 0x18}, {0x61, 0x00}, {0x71, 0x00}, {0x9d, 0x01}, 23 {0x7d, 0x02}, {0x8f, 0x01}, {0x8b, 0xc6}, {0x9a, 0x03}, 24 {0x1c, 0x00}, 25}; 26 27static const struct cxd2880_reg_value rf_init1_seq2[] = { 28 {0xb9, 0x07}, {0x33, 0x01}, {0xc1, 0x01}, {0xc4, 0x1e}, 29}; 30 31static const struct cxd2880_reg_value rf_init1_seq3[] = { 32 {0x00, 0x10}, {0x51, 0x01}, {0xc5, 0x07}, {0x00, 0x11}, 33 {0x70, 0xe9}, {0x76, 0x0a}, {0x78, 0x32}, {0x7a, 0x46}, 34 {0x7c, 0x86}, {0x7e, 0xa4}, {0x00, 0x10}, {0xe1, 0x01}, 35}; 36 37static const struct cxd2880_reg_value rf_init1_seq4[] = { 38 {0x15, 0x00}, {0x00, 0x16} 39}; 40 41static const struct cxd2880_reg_value rf_init1_seq5[] = { 42 {0x00, 0x00}, {0x25, 0x00} 43}; 44 45static const struct cxd2880_reg_value rf_init1_seq6[] = { 46 {0x02, 0x00}, {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1}, 47 {0x8f, 0x16}, {0x67, 0x60}, {0x6a, 0x0f}, {0x6c, 0x17} 48}; 49 50static const struct cxd2880_reg_value rf_init1_seq7[] = { 51 {0x00, 0xe2}, {0x41, 0xa0}, {0x4b, 0x68}, {0x00, 0x00}, 52 {0x21, 0x00}, {0x10, 0x01}, 53}; 54 55static const struct cxd2880_reg_value rf_init1_seq8[] = { 56 {0x00, 0x10}, {0x25, 0x01}, 57}; 58 59static const struct cxd2880_reg_value rf_init1_seq9[] = { 60 {0x00, 0x10}, {0x14, 0x01}, {0x00, 0x00}, {0x26, 0x00}, 61}; 62 63static const struct cxd2880_reg_value rf_init2_seq1[] = { 64 {0x00, 0x14}, {0x1b, 0x01}, 65}; 66 67static const struct cxd2880_reg_value rf_init2_seq2[] = { 68 {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1}, {0xd3, 0x00}, 69 {0x00, 0x00}, {0x21, 0x00}, 70}; 71 72static const struct cxd2880_reg_value x_tune1_seq1[] = { 73 {0x00, 0x00}, {0x10, 0x01}, 74}; 75 76static const struct cxd2880_reg_value x_tune1_seq2[] = { 77 {0x62, 0x00}, {0x00, 0x15}, 78}; 79 80static const struct cxd2880_reg_value x_tune2_seq1[] = { 81 {0x00, 0x1a}, {0x29, 0x01}, 82}; 83 84static const struct cxd2880_reg_value x_tune2_seq2[] = { 85 {0x62, 0x01}, {0x00, 0x11}, {0x2d, 0x00}, {0x2f, 0x00}, 86}; 87 88static const struct cxd2880_reg_value x_tune2_seq3[] = { 89 {0x00, 0x00}, {0x10, 0x00}, {0x21, 0x01}, 90}; 91 92static const struct cxd2880_reg_value x_tune2_seq4[] = { 93 {0x00, 0xe1}, {0x8a, 0x87}, 94}; 95 96static const struct cxd2880_reg_value x_tune2_seq5[] = { 97 {0x00, 0x00}, {0x21, 0x00}, 98}; 99 100static const struct cxd2880_reg_value x_tune3_seq[] = { 101 {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0xa0}, 102 {0x00, 0x00}, {0x21, 0x00}, {0xfe, 0x01}, 103}; 104 105static const struct cxd2880_reg_value x_tune4_seq[] = { 106 {0x00, 0x00}, {0xfe, 0x01}, 107}; 108 109static const struct cxd2880_reg_value x_sleep1_seq[] = { 110 {0x00, 0x00}, {0x57, 0x03}, 111}; 112 113static const struct cxd2880_reg_value x_sleep2_seq1[] = { 114 {0x00, 0x2d}, {0xb1, 0x01}, 115}; 116 117static const struct cxd2880_reg_value x_sleep2_seq2[] = { 118 {0x00, 0x10}, {0xf4, 0x00}, {0xf3, 0x00}, {0xf2, 0x00}, 119 {0xf1, 0x00}, {0xf0, 0x00}, {0xef, 0x00}, 120}; 121 122static const struct cxd2880_reg_value x_sleep3_seq[] = { 123 {0x00, 0x00}, {0xfd, 0x00}, 124}; 125 126static const struct cxd2880_reg_value x_sleep4_seq[] = { 127 {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0x00}, 128 {0x00, 0x00}, {0x21, 0x00}, 129}; 130 131static const struct cxd2880_reg_value spll_reset_seq1[] = { 132 {0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01}, 133 {0x26, 0x01}, 134}; 135 136static const struct cxd2880_reg_value spll_reset_seq2[] = { 137 {0x00, 0x00}, {0x10, 0x00}, 138}; 139 140static const struct cxd2880_reg_value spll_reset_seq3[] = { 141 {0x00, 0x00}, {0x27, 0x00}, {0x22, 0x01}, 142}; 143 144static const struct cxd2880_reg_value spll_reset_seq4[] = { 145 {0x00, 0x00}, {0x27, 0x01}, 146}; 147 148static const struct cxd2880_reg_value spll_reset_seq5[] = { 149 {0x00, 0x00}, {0x10, 0x01}, 150}; 151 152static const struct cxd2880_reg_value t_power_x_seq1[] = { 153 {0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01}, 154}; 155 156static const struct cxd2880_reg_value t_power_x_seq2[] = { 157 {0x00, 0x00}, {0x10, 0x00}, 158}; 159 160static const struct cxd2880_reg_value t_power_x_seq3[] = { 161 {0x00, 0x00}, {0x27, 0x00}, {0x25, 0x01}, 162}; 163 164static const struct cxd2880_reg_value t_power_x_seq4[] = { 165 {0x00, 0x00}, {0x2a, 0x00}, 166}; 167 168static const struct cxd2880_reg_value t_power_x_seq5[] = { 169 {0x00, 0x00}, {0x25, 0x00}, 170}; 171 172static const struct cxd2880_reg_value t_power_x_seq6[] = { 173 {0x00, 0x00}, {0x27, 0x01}, 174}; 175 176static const struct cxd2880_reg_value t_power_x_seq7[] = { 177 {0x00, 0x00}, {0x10, 0x01}, 178}; 179 180static const struct cxd2880_reg_value set_ts_pin_seq[] = { 181 {0x50, 0x3f}, {0x52, 0x1f}, 182 183}; 184 185static const struct cxd2880_reg_value set_ts_output_seq1[] = { 186 {0x00, 0x00}, {0x52, 0x00}, 187}; 188 189static const struct cxd2880_reg_value set_ts_output_seq2[] = { 190 {0x00, 0x00}, {0xc3, 0x00}, 191 192}; 193 194static const struct cxd2880_reg_value set_ts_output_seq3[] = { 195 {0x00, 0x00}, {0xc3, 0x01}, 196 197}; 198 199static const struct cxd2880_reg_value set_ts_output_seq4[] = { 200 {0x00, 0x00}, {0x52, 0x1f}, 201 202}; 203 204static int p_init1(struct cxd2880_tnrdmd *tnr_dmd) 205{ 206 u8 data = 0; 207 int ret; 208 209 if (!tnr_dmd) 210 return -EINVAL; 211 212 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 213 CXD2880_IO_TGT_SYS, 214 0x00, 0x00); 215 if (ret) 216 return ret; 217 218 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE || 219 tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 220 switch (tnr_dmd->create_param.ts_output_if) { 221 case CXD2880_TNRDMD_TSOUT_IF_TS: 222 data = 0x00; 223 break; 224 case CXD2880_TNRDMD_TSOUT_IF_SPI: 225 data = 0x01; 226 break; 227 case CXD2880_TNRDMD_TSOUT_IF_SDIO: 228 data = 0x02; 229 break; 230 default: 231 return -EINVAL; 232 } 233 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 234 CXD2880_IO_TGT_SYS, 235 0x10, data); 236 if (ret) 237 return ret; 238 } 239 240 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 241 CXD2880_IO_TGT_SYS, 242 p_init1_seq, 243 ARRAY_SIZE(p_init1_seq)); 244 if (ret) 245 return ret; 246 247 switch (tnr_dmd->chip_id) { 248 case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X: 249 data = 0x1a; 250 break; 251 case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11: 252 data = 0x16; 253 break; 254 default: 255 return -ENOTTY; 256 } 257 258 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 259 CXD2880_IO_TGT_SYS, 260 0x10, data); 261 if (ret) 262 return ret; 263 264 if (tnr_dmd->create_param.en_internal_ldo) 265 data = 0x01; 266 else 267 data = 0x00; 268 269 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 270 CXD2880_IO_TGT_SYS, 271 0x11, data); 272 if (ret) 273 return ret; 274 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 275 CXD2880_IO_TGT_SYS, 276 0x13, data); 277 if (ret) 278 return ret; 279 280 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 281 CXD2880_IO_TGT_SYS, 282 0x00, 0x00); 283 if (ret) 284 return ret; 285 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 286 CXD2880_IO_TGT_SYS, 287 0x12, data); 288 if (ret) 289 return ret; 290 291 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 292 CXD2880_IO_TGT_SYS, 293 0x00, 0x10); 294 if (ret) 295 return ret; 296 297 switch (tnr_dmd->chip_id) { 298 case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X: 299 data = 0x01; 300 break; 301 case CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_11: 302 data = 0x00; 303 break; 304 default: 305 return -ENOTTY; 306 } 307 308 return tnr_dmd->io->write_reg(tnr_dmd->io, 309 CXD2880_IO_TGT_SYS, 310 0x69, data); 311} 312 313static int p_init2(struct cxd2880_tnrdmd *tnr_dmd) 314{ 315 u8 data[6] = { 0 }; 316 int ret; 317 318 if (!tnr_dmd) 319 return -EINVAL; 320 321 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 322 CXD2880_IO_TGT_SYS, 323 0x00, 0x00); 324 if (ret) 325 return ret; 326 data[0] = tnr_dmd->create_param.xosc_cap; 327 data[1] = tnr_dmd->create_param.xosc_i; 328 switch (tnr_dmd->create_param.xtal_share_type) { 329 case CXD2880_TNRDMD_XTAL_SHARE_NONE: 330 data[2] = 0x01; 331 data[3] = 0x00; 332 break; 333 case CXD2880_TNRDMD_XTAL_SHARE_EXTREF: 334 data[2] = 0x00; 335 data[3] = 0x00; 336 break; 337 case CXD2880_TNRDMD_XTAL_SHARE_MASTER: 338 data[2] = 0x01; 339 data[3] = 0x01; 340 break; 341 case CXD2880_TNRDMD_XTAL_SHARE_SLAVE: 342 data[2] = 0x00; 343 data[3] = 0x01; 344 break; 345 default: 346 return -EINVAL; 347 } 348 data[4] = 0x06; 349 data[5] = 0x00; 350 351 return tnr_dmd->io->write_regs(tnr_dmd->io, 352 CXD2880_IO_TGT_SYS, 353 0x13, data, 6); 354} 355 356static int p_init3(struct cxd2880_tnrdmd *tnr_dmd) 357{ 358 u8 data[2] = { 0 }; 359 int ret; 360 361 if (!tnr_dmd) 362 return -EINVAL; 363 364 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 365 CXD2880_IO_TGT_SYS, 366 0x00, 0x00); 367 if (ret) 368 return ret; 369 370 switch (tnr_dmd->diver_mode) { 371 case CXD2880_TNRDMD_DIVERMODE_SINGLE: 372 data[0] = 0x00; 373 break; 374 case CXD2880_TNRDMD_DIVERMODE_MAIN: 375 data[0] = 0x03; 376 break; 377 case CXD2880_TNRDMD_DIVERMODE_SUB: 378 data[0] = 0x02; 379 break; 380 default: 381 return -EINVAL; 382 } 383 384 data[1] = 0x01; 385 386 return tnr_dmd->io->write_regs(tnr_dmd->io, 387 CXD2880_IO_TGT_SYS, 388 0x1f, data, 2); 389} 390 391static int rf_init1(struct cxd2880_tnrdmd *tnr_dmd) 392{ 393 u8 data[8] = { 0 }; 394 static const u8 rf_init1_cdata1[40] = { 395 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 396 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x03, 397 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x02, 398 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 399 0x02, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02, 400 0x02, 0x03, 0x04, 0x04, 0x04 401 }; 402 403 static const u8 rf_init1_cdata2[5] = {0xff, 0x00, 0x00, 0x00, 0x00}; 404 static const u8 rf_init1_cdata3[80] = { 405 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 406 0x01, 0x00, 0x02, 0x00, 0x63, 0x00, 0x00, 407 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 408 0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x09, 409 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0d, 0x00, 410 0x0d, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f, 411 0x00, 0x10, 0x00, 0x79, 0x00, 0x00, 0x00, 412 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 413 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 414 0x04, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05, 415 0x00, 0x07, 0x00, 0x07, 0x00, 0x08, 0x00, 416 0x0a, 0x03, 0xe0 417 }; 418 419 static const u8 rf_init1_cdata4[8] = { 420 0x20, 0x20, 0x30, 0x41, 0x50, 0x5f, 0x6f, 0x80 421 }; 422 423 static const u8 rf_init1_cdata5[50] = { 424 0x00, 0x09, 0x00, 0x08, 0x00, 0x07, 0x00, 425 0x06, 0x00, 0x05, 0x00, 0x03, 0x00, 0x02, 426 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 427 0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0c, 428 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0f, 0x00, 429 0x0e, 0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f, 430 0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f, 0x00, 431 0x0e 432 }; 433 434 u8 addr = 0; 435 int ret; 436 437 if (!tnr_dmd) 438 return -EINVAL; 439 440 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 441 CXD2880_IO_TGT_SYS, 442 0x00, 0x00); 443 if (ret) 444 return ret; 445 data[0] = 0x01; 446 data[1] = 0x00; 447 data[2] = 0x01; 448 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 449 CXD2880_IO_TGT_SYS, 450 0x21, data, 3); 451 if (ret) 452 return ret; 453 454 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 455 CXD2880_IO_TGT_SYS, 456 0x00, 0x10); 457 if (ret) 458 return ret; 459 data[0] = 0x01; 460 data[1] = 0x01; 461 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 462 CXD2880_IO_TGT_SYS, 463 0x17, data, 2); 464 if (ret) 465 return ret; 466 467 if (tnr_dmd->create_param.stationary_use) { 468 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 469 CXD2880_IO_TGT_SYS, 470 0x1a, 0x06); 471 if (ret) 472 return ret; 473 } 474 475 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 476 CXD2880_IO_TGT_SYS, 477 rf_init1_seq1, 478 ARRAY_SIZE(rf_init1_seq1)); 479 if (ret) 480 return ret; 481 482 data[0] = 0x00; 483 if (tnr_dmd->create_param.is_cxd2881gg && 484 tnr_dmd->create_param.xtal_share_type == 485 CXD2880_TNRDMD_XTAL_SHARE_SLAVE) 486 data[1] = 0x00; 487 else 488 data[1] = 0x1f; 489 data[2] = 0x0a; 490 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 491 CXD2880_IO_TGT_SYS, 492 0xb5, data, 3); 493 if (ret) 494 return ret; 495 496 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 497 CXD2880_IO_TGT_SYS, 498 rf_init1_seq2, 499 ARRAY_SIZE(rf_init1_seq2)); 500 if (ret) 501 return ret; 502 503 if (tnr_dmd->chip_id == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) { 504 data[0] = 0x34; 505 data[1] = 0x2c; 506 } else { 507 data[0] = 0x2f; 508 data[1] = 0x25; 509 } 510 data[2] = 0x15; 511 data[3] = 0x19; 512 data[4] = 0x1b; 513 data[5] = 0x15; 514 data[6] = 0x19; 515 data[7] = 0x1b; 516 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 517 CXD2880_IO_TGT_SYS, 518 0xd9, data, 8); 519 if (ret) 520 return ret; 521 522 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 523 CXD2880_IO_TGT_SYS, 524 0x00, 0x11); 525 if (ret) 526 return ret; 527 data[0] = 0x6c; 528 data[1] = 0x10; 529 data[2] = 0xa6; 530 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 531 CXD2880_IO_TGT_SYS, 532 0x44, data, 3); 533 if (ret) 534 return ret; 535 data[0] = 0x16; 536 data[1] = 0xa8; 537 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 538 CXD2880_IO_TGT_SYS, 539 0x50, data, 2); 540 if (ret) 541 return ret; 542 data[0] = 0x00; 543 data[1] = 0x22; 544 data[2] = 0x00; 545 data[3] = 0x88; 546 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 547 CXD2880_IO_TGT_SYS, 548 0x62, data, 4); 549 if (ret) 550 return ret; 551 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 552 CXD2880_IO_TGT_SYS, 553 0x74, 0x75); 554 if (ret) 555 return ret; 556 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 557 CXD2880_IO_TGT_SYS, 558 0x7f, rf_init1_cdata1, 40); 559 if (ret) 560 return ret; 561 562 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 563 CXD2880_IO_TGT_SYS, 564 0x00, 0x16); 565 if (ret) 566 return ret; 567 data[0] = 0x00; 568 data[1] = 0x71; 569 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 570 CXD2880_IO_TGT_SYS, 571 0x10, data, 2); 572 if (ret) 573 return ret; 574 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 575 CXD2880_IO_TGT_SYS, 576 0x23, 0x89); 577 if (ret) 578 return ret; 579 580 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 581 CXD2880_IO_TGT_SYS, 582 0x27, rf_init1_cdata2, 5); 583 if (ret) 584 return ret; 585 586 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 587 CXD2880_IO_TGT_SYS, 588 0x3a, rf_init1_cdata3, 80); 589 if (ret) 590 return ret; 591 592 data[0] = 0x03; 593 data[1] = 0xe0; 594 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 595 CXD2880_IO_TGT_SYS, 596 0xbc, data, 2); 597 if (ret) 598 return ret; 599 600 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 601 CXD2880_IO_TGT_SYS, 602 rf_init1_seq3, 603 ARRAY_SIZE(rf_init1_seq3)); 604 if (ret) 605 return ret; 606 607 if (tnr_dmd->create_param.stationary_use) { 608 data[0] = 0x06; 609 data[1] = 0x07; 610 data[2] = 0x1a; 611 } else { 612 data[0] = 0x00; 613 data[1] = 0x08; 614 data[2] = 0x19; 615 } 616 data[3] = 0x0e; 617 data[4] = 0x09; 618 data[5] = 0x0e; 619 620 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 621 CXD2880_IO_TGT_SYS, 622 0x00, 0x12); 623 if (ret) 624 return ret; 625 for (addr = 0x10; addr < 0x9f; addr += 6) { 626 if (tnr_dmd->lna_thrs_tbl_air) { 627 u8 idx = 0; 628 629 idx = (addr - 0x10) / 6; 630 data[0] = 631 tnr_dmd->lna_thrs_tbl_air->thrs[idx].off_on; 632 data[1] = 633 tnr_dmd->lna_thrs_tbl_air->thrs[idx].on_off; 634 } 635 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 636 CXD2880_IO_TGT_SYS, 637 addr, data, 6); 638 if (ret) 639 return ret; 640 } 641 642 data[0] = 0x00; 643 data[1] = 0x08; 644 if (tnr_dmd->create_param.stationary_use) 645 data[2] = 0x1a; 646 else 647 data[2] = 0x19; 648 data[3] = 0x0e; 649 data[4] = 0x09; 650 data[5] = 0x0e; 651 652 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 653 CXD2880_IO_TGT_SYS, 654 0x00, 0x13); 655 if (ret) 656 return ret; 657 for (addr = 0x10; addr < 0xcf; addr += 6) { 658 if (tnr_dmd->lna_thrs_tbl_cable) { 659 u8 idx = 0; 660 661 idx = (addr - 0x10) / 6; 662 data[0] = 663 tnr_dmd->lna_thrs_tbl_cable->thrs[idx].off_on; 664 data[1] = 665 tnr_dmd->lna_thrs_tbl_cable->thrs[idx].on_off; 666 } 667 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 668 CXD2880_IO_TGT_SYS, 669 addr, data, 6); 670 if (ret) 671 return ret; 672 } 673 674 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 675 CXD2880_IO_TGT_SYS, 676 0x00, 0x11); 677 if (ret) 678 return ret; 679 data[0] = 0x08; 680 data[1] = 0x09; 681 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 682 CXD2880_IO_TGT_SYS, 683 0xbd, data, 2); 684 if (ret) 685 return ret; 686 data[0] = 0x08; 687 data[1] = 0x09; 688 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 689 CXD2880_IO_TGT_SYS, 690 0xc4, data, 2); 691 if (ret) 692 return ret; 693 694 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 695 CXD2880_IO_TGT_SYS, 696 0xc9, rf_init1_cdata4, 8); 697 if (ret) 698 return ret; 699 700 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 701 CXD2880_IO_TGT_SYS, 702 0x00, 0x14); 703 if (ret) 704 return ret; 705 data[0] = 0x15; 706 data[1] = 0x18; 707 data[2] = 0x00; 708 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 709 CXD2880_IO_TGT_SYS, 710 0x10, data, 3); 711 if (ret) 712 return ret; 713 714 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 715 CXD2880_IO_TGT_SYS, 716 rf_init1_seq4, 717 ARRAY_SIZE(rf_init1_seq4)); 718 if (ret) 719 return ret; 720 721 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 722 CXD2880_IO_TGT_SYS, 723 0x12, rf_init1_cdata5, 50); 724 if (ret) 725 return ret; 726 727 usleep_range(1000, 2000); 728 729 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 730 CXD2880_IO_TGT_SYS, 731 0x00, 0x0a); 732 if (ret) 733 return ret; 734 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 735 CXD2880_IO_TGT_SYS, 736 0x10, data, 1); 737 if (ret) 738 return ret; 739 if ((data[0] & 0x01) == 0x00) 740 return -EINVAL; 741 742 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 743 CXD2880_IO_TGT_SYS, 744 rf_init1_seq5, 745 ARRAY_SIZE(rf_init1_seq5)); 746 if (ret) 747 return ret; 748 749 usleep_range(1000, 2000); 750 751 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 752 CXD2880_IO_TGT_SYS, 753 0x00, 0x0a); 754 if (ret) 755 return ret; 756 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 757 CXD2880_IO_TGT_SYS, 758 0x11, data, 1); 759 if (ret) 760 return ret; 761 if ((data[0] & 0x01) == 0x00) 762 return -EINVAL; 763 764 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 765 CXD2880_IO_TGT_DMD, 766 rf_init1_seq6, 767 ARRAY_SIZE(rf_init1_seq6)); 768 if (ret) 769 return ret; 770 771 data[0] = 0x00; 772 data[1] = 0xfe; 773 data[2] = 0xee; 774 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 775 CXD2880_IO_TGT_DMD, 776 0x6e, data, 3); 777 if (ret) 778 return ret; 779 data[0] = 0xa1; 780 data[1] = 0x8b; 781 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 782 CXD2880_IO_TGT_DMD, 783 0x8d, data, 2); 784 if (ret) 785 return ret; 786 data[0] = 0x08; 787 data[1] = 0x09; 788 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 789 CXD2880_IO_TGT_DMD, 790 0x77, data, 2); 791 if (ret) 792 return ret; 793 794 if (tnr_dmd->create_param.stationary_use) { 795 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 796 CXD2880_IO_TGT_DMD, 797 0x80, 0xaa); 798 if (ret) 799 return ret; 800 } 801 802 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 803 CXD2880_IO_TGT_DMD, 804 rf_init1_seq7, 805 ARRAY_SIZE(rf_init1_seq7)); 806 if (ret) 807 return ret; 808 809 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 810 CXD2880_IO_TGT_SYS, 811 rf_init1_seq8, 812 ARRAY_SIZE(rf_init1_seq8)); 813 if (ret) 814 return ret; 815 816 usleep_range(1000, 2000); 817 818 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 819 CXD2880_IO_TGT_SYS, 820 0x00, 0x1a); 821 if (ret) 822 return ret; 823 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 824 CXD2880_IO_TGT_SYS, 825 0x10, data, 1); 826 if (ret) 827 return ret; 828 if ((data[0] & 0x01) == 0x00) 829 return -EINVAL; 830 831 return cxd2880_io_write_multi_regs(tnr_dmd->io, 832 CXD2880_IO_TGT_SYS, 833 rf_init1_seq9, 834 ARRAY_SIZE(rf_init1_seq9)); 835} 836 837static int rf_init2(struct cxd2880_tnrdmd *tnr_dmd) 838{ 839 u8 data[5] = { 0 }; 840 int ret; 841 842 if (!tnr_dmd) 843 return -EINVAL; 844 845 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 846 CXD2880_IO_TGT_SYS, 847 0x00, 0x10); 848 if (ret) 849 return ret; 850 data[0] = 0x40; 851 data[1] = 0x40; 852 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 853 CXD2880_IO_TGT_SYS, 854 0xea, data, 2); 855 if (ret) 856 return ret; 857 858 usleep_range(1000, 2000); 859 860 data[0] = 0x00; 861 if (tnr_dmd->chip_id == CXD2880_TNRDMD_CHIP_ID_CXD2880_ES1_0X) 862 data[1] = 0x00; 863 else 864 data[1] = 0x01; 865 data[2] = 0x01; 866 data[3] = 0x03; 867 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 868 CXD2880_IO_TGT_SYS, 869 0x30, data, 4); 870 if (ret) 871 return ret; 872 873 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 874 CXD2880_IO_TGT_SYS, 875 rf_init2_seq1, 876 ARRAY_SIZE(rf_init2_seq1)); 877 if (ret) 878 return ret; 879 880 return cxd2880_io_write_multi_regs(tnr_dmd->io, 881 CXD2880_IO_TGT_DMD, 882 rf_init2_seq2, 883 ARRAY_SIZE(rf_init2_seq2)); 884} 885 886static int x_tune1(struct cxd2880_tnrdmd *tnr_dmd, 887 enum cxd2880_dtv_sys sys, u32 freq_khz, 888 enum cxd2880_dtv_bandwidth bandwidth, 889 u8 is_cable, int shift_frequency_khz) 890{ 891 u8 data[11] = { 0 }; 892 int ret; 893 894 if (!tnr_dmd) 895 return -EINVAL; 896 897 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 898 CXD2880_IO_TGT_DMD, 899 x_tune1_seq1, 900 ARRAY_SIZE(x_tune1_seq1)); 901 if (ret) 902 return ret; 903 904 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 905 CXD2880_IO_TGT_SYS, 906 0x00, 0x10); 907 if (ret) 908 return ret; 909 910 data[2] = 0x0e; 911 data[4] = 0x03; 912 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 913 CXD2880_IO_TGT_SYS, 914 0xe7, data, 5); 915 if (ret) 916 return ret; 917 918 data[0] = 0x1f; 919 data[1] = 0x80; 920 data[2] = 0x18; 921 data[3] = 0x00; 922 data[4] = 0x07; 923 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 924 CXD2880_IO_TGT_SYS, 925 0xe7, data, 5); 926 if (ret) 927 return ret; 928 929 usleep_range(1000, 2000); 930 931 data[0] = 0x72; 932 data[1] = 0x81; 933 data[3] = 0x1d; 934 data[4] = 0x6f; 935 data[5] = 0x7e; 936 data[7] = 0x1c; 937 switch (sys) { 938 case CXD2880_DTV_SYS_DVBT: 939 data[2] = 0x94; 940 data[6] = 0x91; 941 break; 942 case CXD2880_DTV_SYS_DVBT2: 943 data[2] = 0x96; 944 data[6] = 0x93; 945 break; 946 default: 947 return -EINVAL; 948 } 949 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 950 CXD2880_IO_TGT_SYS, 951 0x44, data, 8); 952 if (ret) 953 return ret; 954 955 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 956 CXD2880_IO_TGT_SYS, 957 x_tune1_seq2, 958 ARRAY_SIZE(x_tune1_seq2)); 959 if (ret) 960 return ret; 961 962 data[0] = 0x03; 963 data[1] = 0xe2; 964 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 965 CXD2880_IO_TGT_SYS, 966 0x1e, data, 2); 967 if (ret) 968 return ret; 969 970 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 971 CXD2880_IO_TGT_SYS, 972 0x00, 0x10); 973 if (ret) 974 return ret; 975 976 data[0] = is_cable ? 0x01 : 0x00; 977 data[1] = 0x00; 978 data[2] = 0x6b; 979 data[3] = 0x4d; 980 981 switch (bandwidth) { 982 case CXD2880_DTV_BW_1_7_MHZ: 983 data[4] = 0x03; 984 break; 985 case CXD2880_DTV_BW_5_MHZ: 986 case CXD2880_DTV_BW_6_MHZ: 987 data[4] = 0x00; 988 break; 989 case CXD2880_DTV_BW_7_MHZ: 990 data[4] = 0x01; 991 break; 992 case CXD2880_DTV_BW_8_MHZ: 993 data[4] = 0x02; 994 break; 995 default: 996 return -EINVAL; 997 } 998 999 data[5] = 0x00; 1000 1001 freq_khz += shift_frequency_khz; 1002 1003 data[6] = (freq_khz >> 16) & 0x0f; 1004 data[7] = (freq_khz >> 8) & 0xff; 1005 data[8] = freq_khz & 0xff; 1006 data[9] = 0xff; 1007 data[10] = 0xfe; 1008 1009 return tnr_dmd->io->write_regs(tnr_dmd->io, 1010 CXD2880_IO_TGT_SYS, 1011 0x52, data, 11); 1012} 1013 1014static int x_tune2(struct cxd2880_tnrdmd *tnr_dmd, 1015 enum cxd2880_dtv_bandwidth bandwidth, 1016 enum cxd2880_tnrdmd_clockmode clk_mode, 1017 int shift_frequency_khz) 1018{ 1019 u8 data[3] = { 0 }; 1020 int ret; 1021 1022 if (!tnr_dmd) 1023 return -EINVAL; 1024 1025 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1026 CXD2880_IO_TGT_SYS, 1027 0x00, 0x11); 1028 if (ret) 1029 return ret; 1030 1031 data[0] = 0x01; 1032 data[1] = 0x0e; 1033 data[2] = 0x01; 1034 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 1035 CXD2880_IO_TGT_SYS, 1036 0x2d, data, 3); 1037 if (ret) 1038 return ret; 1039 1040 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1041 CXD2880_IO_TGT_SYS, 1042 x_tune2_seq1, 1043 ARRAY_SIZE(x_tune2_seq1)); 1044 if (ret) 1045 return ret; 1046 1047 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 1048 CXD2880_IO_TGT_SYS, 1049 0x2c, data, 1); 1050 if (ret) 1051 return ret; 1052 1053 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1054 CXD2880_IO_TGT_SYS, 1055 0x00, 0x10); 1056 if (ret) 1057 return ret; 1058 1059 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1060 CXD2880_IO_TGT_SYS, 1061 0x60, data[0]); 1062 if (ret) 1063 return ret; 1064 1065 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1066 CXD2880_IO_TGT_SYS, 1067 x_tune2_seq2, 1068 ARRAY_SIZE(x_tune2_seq2)); 1069 if (ret) 1070 return ret; 1071 1072 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1073 CXD2880_IO_TGT_DMD, 1074 x_tune2_seq3, 1075 ARRAY_SIZE(x_tune2_seq3)); 1076 if (ret) 1077 return ret; 1078 1079 if (shift_frequency_khz != 0) { 1080 int shift_freq = 0; 1081 1082 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1083 CXD2880_IO_TGT_DMD, 1084 0x00, 0xe1); 1085 if (ret) 1086 return ret; 1087 1088 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 1089 CXD2880_IO_TGT_DMD, 1090 0x60, data, 2); 1091 if (ret) 1092 return ret; 1093 1094 shift_freq = shift_frequency_khz * 1000; 1095 1096 switch (clk_mode) { 1097 case CXD2880_TNRDMD_CLOCKMODE_A: 1098 case CXD2880_TNRDMD_CLOCKMODE_C: 1099 default: 1100 if (shift_freq >= 0) 1101 shift_freq = (shift_freq + 183 / 2) / 183; 1102 else 1103 shift_freq = (shift_freq - 183 / 2) / 183; 1104 break; 1105 case CXD2880_TNRDMD_CLOCKMODE_B: 1106 if (shift_freq >= 0) 1107 shift_freq = (shift_freq + 178 / 2) / 178; 1108 else 1109 shift_freq = (shift_freq - 178 / 2) / 178; 1110 break; 1111 } 1112 1113 shift_freq += 1114 cxd2880_convert2s_complement((data[0] << 8) | data[1], 16); 1115 1116 if (shift_freq > 32767) 1117 shift_freq = 32767; 1118 else if (shift_freq < -32768) 1119 shift_freq = -32768; 1120 1121 data[0] = (shift_freq >> 8) & 0xff; 1122 data[1] = shift_freq & 0xff; 1123 1124 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 1125 CXD2880_IO_TGT_DMD, 1126 0x60, data, 2); 1127 if (ret) 1128 return ret; 1129 1130 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 1131 CXD2880_IO_TGT_DMD, 1132 0x69, data, 1); 1133 if (ret) 1134 return ret; 1135 1136 shift_freq = -shift_frequency_khz; 1137 1138 if (bandwidth == CXD2880_DTV_BW_1_7_MHZ) { 1139 switch (clk_mode) { 1140 case CXD2880_TNRDMD_CLOCKMODE_A: 1141 case CXD2880_TNRDMD_CLOCKMODE_C: 1142 default: 1143 if (shift_freq >= 0) 1144 shift_freq = 1145 (shift_freq * 1000 + 1146 17578 / 2) / 17578; 1147 else 1148 shift_freq = 1149 (shift_freq * 1000 - 1150 17578 / 2) / 17578; 1151 break; 1152 case CXD2880_TNRDMD_CLOCKMODE_B: 1153 if (shift_freq >= 0) 1154 shift_freq = 1155 (shift_freq * 1000 + 1156 17090 / 2) / 17090; 1157 else 1158 shift_freq = 1159 (shift_freq * 1000 - 1160 17090 / 2) / 17090; 1161 break; 1162 } 1163 } else { 1164 switch (clk_mode) { 1165 case CXD2880_TNRDMD_CLOCKMODE_A: 1166 case CXD2880_TNRDMD_CLOCKMODE_C: 1167 default: 1168 if (shift_freq >= 0) 1169 shift_freq = 1170 (shift_freq * 1000 + 1171 35156 / 2) / 35156; 1172 else 1173 shift_freq = 1174 (shift_freq * 1000 - 1175 35156 / 2) / 35156; 1176 break; 1177 case CXD2880_TNRDMD_CLOCKMODE_B: 1178 if (shift_freq >= 0) 1179 shift_freq = 1180 (shift_freq * 1000 + 1181 34180 / 2) / 34180; 1182 else 1183 shift_freq = 1184 (shift_freq * 1000 - 1185 34180 / 2) / 34180; 1186 break; 1187 } 1188 } 1189 1190 shift_freq += cxd2880_convert2s_complement(data[0], 8); 1191 1192 if (shift_freq > 127) 1193 shift_freq = 127; 1194 else if (shift_freq < -128) 1195 shift_freq = -128; 1196 1197 data[0] = shift_freq & 0xff; 1198 1199 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1200 CXD2880_IO_TGT_DMD, 1201 0x69, data[0]); 1202 if (ret) 1203 return ret; 1204 } 1205 1206 if (tnr_dmd->create_param.stationary_use) { 1207 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1208 CXD2880_IO_TGT_DMD, 1209 x_tune2_seq4, 1210 ARRAY_SIZE(x_tune2_seq4)); 1211 if (ret) 1212 return ret; 1213 } 1214 1215 return cxd2880_io_write_multi_regs(tnr_dmd->io, 1216 CXD2880_IO_TGT_DMD, 1217 x_tune2_seq5, 1218 ARRAY_SIZE(x_tune2_seq5)); 1219} 1220 1221static int x_tune3(struct cxd2880_tnrdmd *tnr_dmd, 1222 enum cxd2880_dtv_sys sys, 1223 u8 en_fef_intmtnt_ctrl) 1224{ 1225 u8 data[6] = { 0 }; 1226 int ret; 1227 1228 if (!tnr_dmd) 1229 return -EINVAL; 1230 1231 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1232 CXD2880_IO_TGT_DMD, 1233 x_tune3_seq, 1234 ARRAY_SIZE(x_tune3_seq)); 1235 if (ret) 1236 return ret; 1237 1238 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1239 CXD2880_IO_TGT_SYS, 1240 0x00, 0x10); 1241 if (ret) 1242 return ret; 1243 1244 if (sys == CXD2880_DTV_SYS_DVBT2 && en_fef_intmtnt_ctrl) 1245 memset(data, 0x01, sizeof(data)); 1246 else 1247 memset(data, 0x00, sizeof(data)); 1248 1249 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 1250 CXD2880_IO_TGT_SYS, 1251 0xef, data, 6); 1252 if (ret) 1253 return ret; 1254 1255 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1256 CXD2880_IO_TGT_DMD, 1257 0x00, 0x2d); 1258 if (ret) 1259 return ret; 1260 if (sys == CXD2880_DTV_SYS_DVBT2 && en_fef_intmtnt_ctrl) 1261 data[0] = 0x00; 1262 else 1263 data[0] = 0x01; 1264 1265 return tnr_dmd->io->write_reg(tnr_dmd->io, 1266 CXD2880_IO_TGT_DMD, 1267 0xb1, data[0]); 1268} 1269 1270static int x_tune4(struct cxd2880_tnrdmd *tnr_dmd) 1271{ 1272 u8 data[2] = { 0 }; 1273 int ret; 1274 1275 if (!tnr_dmd) 1276 return -EINVAL; 1277 1278 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) 1279 return -EINVAL; 1280 1281 ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io, 1282 CXD2880_IO_TGT_SYS, 1283 0x00, 0x00); 1284 if (ret) 1285 return ret; 1286 data[0] = 0x14; 1287 data[1] = 0x00; 1288 ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io, 1289 CXD2880_IO_TGT_SYS, 1290 0x55, data, 2); 1291 if (ret) 1292 return ret; 1293 1294 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1295 CXD2880_IO_TGT_SYS, 1296 0x00, 0x00); 1297 if (ret) 1298 return ret; 1299 data[0] = 0x0b; 1300 data[1] = 0xff; 1301 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 1302 CXD2880_IO_TGT_SYS, 1303 0x53, data, 2); 1304 if (ret) 1305 return ret; 1306 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1307 CXD2880_IO_TGT_SYS, 1308 0x57, 0x01); 1309 if (ret) 1310 return ret; 1311 data[0] = 0x0b; 1312 data[1] = 0xff; 1313 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 1314 CXD2880_IO_TGT_SYS, 1315 0x55, data, 2); 1316 if (ret) 1317 return ret; 1318 1319 ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io, 1320 CXD2880_IO_TGT_SYS, 1321 0x00, 0x00); 1322 if (ret) 1323 return ret; 1324 data[0] = 0x14; 1325 data[1] = 0x00; 1326 ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io, 1327 CXD2880_IO_TGT_SYS, 1328 0x53, data, 2); 1329 if (ret) 1330 return ret; 1331 ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io, 1332 CXD2880_IO_TGT_SYS, 1333 0x57, 0x02); 1334 if (ret) 1335 return ret; 1336 1337 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1338 CXD2880_IO_TGT_DMD, 1339 x_tune4_seq, 1340 ARRAY_SIZE(x_tune4_seq)); 1341 if (ret) 1342 return ret; 1343 1344 return cxd2880_io_write_multi_regs(tnr_dmd->diver_sub->io, 1345 CXD2880_IO_TGT_DMD, 1346 x_tune4_seq, 1347 ARRAY_SIZE(x_tune4_seq)); 1348} 1349 1350static int x_sleep1(struct cxd2880_tnrdmd *tnr_dmd) 1351{ 1352 u8 data[3] = { 0 }; 1353 int ret; 1354 1355 if (!tnr_dmd) 1356 return -EINVAL; 1357 1358 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) 1359 return -EINVAL; 1360 1361 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1362 CXD2880_IO_TGT_SYS, 1363 x_sleep1_seq, 1364 ARRAY_SIZE(x_sleep1_seq)); 1365 if (ret) 1366 return ret; 1367 1368 data[0] = 0x00; 1369 data[1] = 0x00; 1370 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 1371 CXD2880_IO_TGT_SYS, 1372 0x53, data, 2); 1373 if (ret) 1374 return ret; 1375 1376 ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io, 1377 CXD2880_IO_TGT_SYS, 1378 0x00, 0x00); 1379 if (ret) 1380 return ret; 1381 data[0] = 0x1f; 1382 data[1] = 0xff; 1383 data[2] = 0x03; 1384 ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io, 1385 CXD2880_IO_TGT_SYS, 1386 0x55, data, 3); 1387 if (ret) 1388 return ret; 1389 data[0] = 0x00; 1390 data[1] = 0x00; 1391 ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io, 1392 CXD2880_IO_TGT_SYS, 1393 0x53, data, 2); 1394 if (ret) 1395 return ret; 1396 1397 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1398 CXD2880_IO_TGT_SYS, 1399 0x00, 0x00); 1400 if (ret) 1401 return ret; 1402 data[0] = 0x1f; 1403 data[1] = 0xff; 1404 1405 return tnr_dmd->io->write_regs(tnr_dmd->io, 1406 CXD2880_IO_TGT_SYS, 1407 0x55, data, 2); 1408} 1409 1410static int x_sleep2(struct cxd2880_tnrdmd *tnr_dmd) 1411{ 1412 u8 data = 0; 1413 int ret; 1414 1415 if (!tnr_dmd) 1416 return -EINVAL; 1417 1418 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1419 CXD2880_IO_TGT_DMD, 1420 x_sleep2_seq1, 1421 ARRAY_SIZE(x_sleep2_seq1)); 1422 if (ret) 1423 return ret; 1424 1425 usleep_range(1000, 2000); 1426 1427 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 1428 CXD2880_IO_TGT_DMD, 1429 0xb2, &data, 1); 1430 if (ret) 1431 return ret; 1432 1433 if ((data & 0x01) == 0x00) 1434 return -EINVAL; 1435 1436 return cxd2880_io_write_multi_regs(tnr_dmd->io, 1437 CXD2880_IO_TGT_SYS, 1438 x_sleep2_seq2, 1439 ARRAY_SIZE(x_sleep2_seq2)); 1440} 1441 1442static int x_sleep3(struct cxd2880_tnrdmd *tnr_dmd) 1443{ 1444 if (!tnr_dmd) 1445 return -EINVAL; 1446 1447 return cxd2880_io_write_multi_regs(tnr_dmd->io, 1448 CXD2880_IO_TGT_DMD, 1449 x_sleep3_seq, 1450 ARRAY_SIZE(x_sleep3_seq)); 1451} 1452 1453static int x_sleep4(struct cxd2880_tnrdmd *tnr_dmd) 1454{ 1455 if (!tnr_dmd) 1456 return -EINVAL; 1457 1458 return cxd2880_io_write_multi_regs(tnr_dmd->io, 1459 CXD2880_IO_TGT_DMD, 1460 x_sleep4_seq, 1461 ARRAY_SIZE(x_sleep4_seq)); 1462} 1463 1464static int spll_reset(struct cxd2880_tnrdmd *tnr_dmd, 1465 enum cxd2880_tnrdmd_clockmode clockmode) 1466{ 1467 u8 data[4] = { 0 }; 1468 int ret; 1469 1470 if (!tnr_dmd) 1471 return -EINVAL; 1472 1473 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1474 CXD2880_IO_TGT_SYS, 1475 spll_reset_seq1, 1476 ARRAY_SIZE(spll_reset_seq1)); 1477 if (ret) 1478 return ret; 1479 1480 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1481 CXD2880_IO_TGT_DMD, 1482 spll_reset_seq2, 1483 ARRAY_SIZE(spll_reset_seq2)); 1484 if (ret) 1485 return ret; 1486 1487 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1488 CXD2880_IO_TGT_SYS, 1489 spll_reset_seq3, 1490 ARRAY_SIZE(spll_reset_seq3)); 1491 if (ret) 1492 return ret; 1493 1494 switch (clockmode) { 1495 case CXD2880_TNRDMD_CLOCKMODE_A: 1496 data[0] = 0x00; 1497 break; 1498 1499 case CXD2880_TNRDMD_CLOCKMODE_B: 1500 data[0] = 0x01; 1501 break; 1502 1503 case CXD2880_TNRDMD_CLOCKMODE_C: 1504 data[0] = 0x02; 1505 break; 1506 1507 default: 1508 return -EINVAL; 1509 } 1510 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1511 CXD2880_IO_TGT_SYS, 1512 0x30, data[0]); 1513 if (ret) 1514 return ret; 1515 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1516 CXD2880_IO_TGT_SYS, 1517 0x22, 0x00); 1518 if (ret) 1519 return ret; 1520 1521 usleep_range(2000, 3000); 1522 1523 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1524 CXD2880_IO_TGT_SYS, 1525 0x00, 0x0a); 1526 if (ret) 1527 return ret; 1528 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 1529 CXD2880_IO_TGT_SYS, 1530 0x10, data, 1); 1531 if (ret) 1532 return ret; 1533 if ((data[0] & 0x01) == 0x00) 1534 return -EINVAL; 1535 1536 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1537 CXD2880_IO_TGT_SYS, 1538 spll_reset_seq4, 1539 ARRAY_SIZE(spll_reset_seq4)); 1540 if (ret) 1541 return ret; 1542 1543 usleep_range(1000, 2000); 1544 1545 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1546 CXD2880_IO_TGT_DMD, 1547 spll_reset_seq5, 1548 ARRAY_SIZE(spll_reset_seq5)); 1549 if (ret) 1550 return ret; 1551 1552 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1553 CXD2880_IO_TGT_SYS, 1554 0x00, 0x10); 1555 if (ret) 1556 return ret; 1557 1558 memset(data, 0x00, sizeof(data)); 1559 1560 return tnr_dmd->io->write_regs(tnr_dmd->io, 1561 CXD2880_IO_TGT_SYS, 1562 0x26, data, 4); 1563} 1564 1565static int t_power_x(struct cxd2880_tnrdmd *tnr_dmd, u8 on) 1566{ 1567 u8 data[3] = { 0 }; 1568 int ret; 1569 1570 if (!tnr_dmd) 1571 return -EINVAL; 1572 1573 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1574 CXD2880_IO_TGT_SYS, 1575 t_power_x_seq1, 1576 ARRAY_SIZE(t_power_x_seq1)); 1577 if (ret) 1578 return ret; 1579 1580 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1581 CXD2880_IO_TGT_DMD, 1582 t_power_x_seq2, 1583 ARRAY_SIZE(t_power_x_seq2)); 1584 if (ret) 1585 return ret; 1586 1587 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1588 CXD2880_IO_TGT_SYS, 1589 t_power_x_seq3, 1590 ARRAY_SIZE(t_power_x_seq3)); 1591 if (ret) 1592 return ret; 1593 1594 if (on) { 1595 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1596 CXD2880_IO_TGT_SYS, 1597 0x2b, 0x01); 1598 if (ret) 1599 return ret; 1600 1601 usleep_range(1000, 2000); 1602 1603 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1604 CXD2880_IO_TGT_SYS, 1605 0x00, 0x0a); 1606 if (ret) 1607 return ret; 1608 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 1609 CXD2880_IO_TGT_SYS, 1610 0x12, data, 1); 1611 if (ret) 1612 return ret; 1613 if ((data[0] & 0x01) == 0) 1614 return -EINVAL; 1615 1616 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1617 CXD2880_IO_TGT_SYS, 1618 t_power_x_seq4, 1619 ARRAY_SIZE(t_power_x_seq4)); 1620 if (ret) 1621 return ret; 1622 } else { 1623 data[0] = 0x03; 1624 data[1] = 0x00; 1625 ret = tnr_dmd->io->write_regs(tnr_dmd->io, 1626 CXD2880_IO_TGT_SYS, 1627 0x2a, data, 2); 1628 if (ret) 1629 return ret; 1630 1631 usleep_range(1000, 2000); 1632 1633 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1634 CXD2880_IO_TGT_SYS, 1635 0x00, 0x0a); 1636 if (ret) 1637 return ret; 1638 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 1639 CXD2880_IO_TGT_SYS, 1640 0x13, data, 1); 1641 if (ret) 1642 return ret; 1643 if ((data[0] & 0x01) == 0) 1644 return -EINVAL; 1645 } 1646 1647 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1648 CXD2880_IO_TGT_SYS, 1649 t_power_x_seq5, 1650 ARRAY_SIZE(t_power_x_seq5)); 1651 if (ret) 1652 return ret; 1653 1654 usleep_range(1000, 2000); 1655 1656 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1657 CXD2880_IO_TGT_SYS, 1658 0x00, 0x0a); 1659 if (ret) 1660 return ret; 1661 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 1662 CXD2880_IO_TGT_SYS, 1663 0x11, data, 1); 1664 if (ret) 1665 return ret; 1666 if ((data[0] & 0x01) == 0) 1667 return -EINVAL; 1668 1669 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1670 CXD2880_IO_TGT_SYS, 1671 t_power_x_seq6, 1672 ARRAY_SIZE(t_power_x_seq6)); 1673 if (ret) 1674 return ret; 1675 1676 usleep_range(1000, 2000); 1677 1678 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 1679 CXD2880_IO_TGT_DMD, 1680 t_power_x_seq7, 1681 ARRAY_SIZE(t_power_x_seq7)); 1682 if (ret) 1683 return ret; 1684 1685 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1686 CXD2880_IO_TGT_SYS, 1687 0x00, 0x10); 1688 if (ret) 1689 return ret; 1690 1691 memset(data, 0x00, sizeof(data)); 1692 1693 return tnr_dmd->io->write_regs(tnr_dmd->io, 1694 CXD2880_IO_TGT_SYS, 1695 0x27, data, 3); 1696} 1697 1698struct cxd2880_tnrdmd_ts_clk_cfg { 1699 u8 srl_clk_mode; 1700 u8 srl_duty_mode; 1701 u8 ts_clk_period; 1702}; 1703 1704static int set_ts_clk_mode_and_freq(struct cxd2880_tnrdmd *tnr_dmd, 1705 enum cxd2880_dtv_sys sys) 1706{ 1707 int ret; 1708 u8 backwards_compatible = 0; 1709 struct cxd2880_tnrdmd_ts_clk_cfg ts_clk_cfg; 1710 u8 ts_rate_ctrl_off = 0; 1711 u8 ts_in_off = 0; 1712 u8 ts_clk_manaul_on = 0; 1713 u8 data = 0; 1714 1715 static const struct cxd2880_tnrdmd_ts_clk_cfg srl_ts_clk_stgs[2][2] = { 1716 { 1717 {3, 1, 8,}, 1718 {0, 2, 16,} 1719 }, { 1720 {1, 1, 8,}, 1721 {2, 2, 16,} 1722 } 1723 }; 1724 1725 if (!tnr_dmd) 1726 return -EINVAL; 1727 1728 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1729 CXD2880_IO_TGT_DMD, 1730 0x00, 0x00); 1731 if (ret) 1732 return ret; 1733 1734 if (tnr_dmd->is_ts_backwards_compatible_mode) { 1735 backwards_compatible = 1; 1736 ts_rate_ctrl_off = 1; 1737 ts_in_off = 1; 1738 } else { 1739 backwards_compatible = 0; 1740 ts_rate_ctrl_off = 0; 1741 ts_in_off = 0; 1742 } 1743 1744 if (tnr_dmd->ts_byte_clk_manual_setting) { 1745 ts_clk_manaul_on = 1; 1746 ts_rate_ctrl_off = 0; 1747 } 1748 1749 ret = cxd2880_io_set_reg_bits(tnr_dmd->io, 1750 CXD2880_IO_TGT_DMD, 1751 0xd3, ts_rate_ctrl_off, 0x01); 1752 if (ret) 1753 return ret; 1754 1755 ret = cxd2880_io_set_reg_bits(tnr_dmd->io, 1756 CXD2880_IO_TGT_DMD, 1757 0xde, ts_in_off, 0x01); 1758 if (ret) 1759 return ret; 1760 1761 ret = cxd2880_io_set_reg_bits(tnr_dmd->io, 1762 CXD2880_IO_TGT_DMD, 1763 0xda, ts_clk_manaul_on, 0x01); 1764 if (ret) 1765 return ret; 1766 1767 ts_clk_cfg = srl_ts_clk_stgs[tnr_dmd->srl_ts_clk_mod_cnts] 1768 [tnr_dmd->srl_ts_clk_frq]; 1769 1770 if (tnr_dmd->ts_byte_clk_manual_setting) 1771 ts_clk_cfg.ts_clk_period = tnr_dmd->ts_byte_clk_manual_setting; 1772 1773 ret = cxd2880_io_set_reg_bits(tnr_dmd->io, 1774 CXD2880_IO_TGT_DMD, 1775 0xc4, ts_clk_cfg.srl_clk_mode, 0x03); 1776 if (ret) 1777 return ret; 1778 1779 ret = cxd2880_io_set_reg_bits(tnr_dmd->io, 1780 CXD2880_IO_TGT_DMD, 1781 0xd1, ts_clk_cfg.srl_duty_mode, 0x03); 1782 if (ret) 1783 return ret; 1784 1785 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1786 CXD2880_IO_TGT_DMD, 0xd9, 1787 ts_clk_cfg.ts_clk_period); 1788 if (ret) 1789 return ret; 1790 1791 data = backwards_compatible ? 0x00 : 0x01; 1792 1793 if (sys == CXD2880_DTV_SYS_DVBT) { 1794 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1795 CXD2880_IO_TGT_DMD, 1796 0x00, 0x10); 1797 if (ret) 1798 return ret; 1799 1800 ret = 1801 cxd2880_io_set_reg_bits(tnr_dmd->io, 1802 CXD2880_IO_TGT_DMD, 1803 0x66, data, 0x01); 1804 } 1805 1806 return ret; 1807} 1808 1809static int pid_ftr_setting(struct cxd2880_tnrdmd *tnr_dmd, 1810 struct cxd2880_tnrdmd_pid_ftr_cfg 1811 *pid_ftr_cfg) 1812{ 1813 int i; 1814 int ret; 1815 u8 data[65]; 1816 1817 if (!tnr_dmd) 1818 return -EINVAL; 1819 1820 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1821 CXD2880_IO_TGT_DMD, 1822 0x00, 0x00); 1823 if (ret) 1824 return ret; 1825 1826 if (!pid_ftr_cfg) 1827 return tnr_dmd->io->write_reg(tnr_dmd->io, 1828 CXD2880_IO_TGT_DMD, 1829 0x50, 0x02); 1830 1831 data[0] = pid_ftr_cfg->is_negative ? 0x01 : 0x00; 1832 1833 for (i = 0; i < 32; i++) { 1834 if (pid_ftr_cfg->pid_cfg[i].is_en) { 1835 data[1 + (i * 2)] = (pid_ftr_cfg->pid_cfg[i].pid >> 8) | 0x20; 1836 data[2 + (i * 2)] = pid_ftr_cfg->pid_cfg[i].pid & 0xff; 1837 } else { 1838 data[1 + (i * 2)] = 0x00; 1839 data[2 + (i * 2)] = 0x00; 1840 } 1841 } 1842 1843 return tnr_dmd->io->write_regs(tnr_dmd->io, 1844 CXD2880_IO_TGT_DMD, 1845 0x50, data, 65); 1846} 1847 1848static int load_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd) 1849{ 1850 int ret; 1851 u8 i; 1852 1853 if (!tnr_dmd) 1854 return -EINVAL; 1855 1856 for (i = 0; i < tnr_dmd->cfg_mem_last_entry; i++) { 1857 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 1858 tnr_dmd->cfg_mem[i].tgt, 1859 0x00, tnr_dmd->cfg_mem[i].bank); 1860 if (ret) 1861 return ret; 1862 1863 ret = cxd2880_io_set_reg_bits(tnr_dmd->io, 1864 tnr_dmd->cfg_mem[i].tgt, 1865 tnr_dmd->cfg_mem[i].address, 1866 tnr_dmd->cfg_mem[i].value, 1867 tnr_dmd->cfg_mem[i].bit_mask); 1868 if (ret) 1869 return ret; 1870 } 1871 1872 return 0; 1873} 1874 1875static int set_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd, 1876 enum cxd2880_io_tgt tgt, 1877 u8 bank, u8 address, u8 value, u8 bit_mask) 1878{ 1879 u8 i; 1880 u8 value_stored = 0; 1881 1882 if (!tnr_dmd) 1883 return -EINVAL; 1884 1885 for (i = 0; i < tnr_dmd->cfg_mem_last_entry; i++) { 1886 if (value_stored == 0 && 1887 tnr_dmd->cfg_mem[i].tgt == tgt && 1888 tnr_dmd->cfg_mem[i].bank == bank && 1889 tnr_dmd->cfg_mem[i].address == address) { 1890 tnr_dmd->cfg_mem[i].value &= ~bit_mask; 1891 tnr_dmd->cfg_mem[i].value |= (value & bit_mask); 1892 1893 tnr_dmd->cfg_mem[i].bit_mask |= bit_mask; 1894 1895 value_stored = 1; 1896 } 1897 } 1898 1899 if (value_stored) 1900 return 0; 1901 1902 if (tnr_dmd->cfg_mem_last_entry < CXD2880_TNRDMD_MAX_CFG_MEM_COUNT) { 1903 tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].tgt = tgt; 1904 tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].bank = bank; 1905 tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].address = address; 1906 tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].value = (value & bit_mask); 1907 tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].bit_mask = bit_mask; 1908 tnr_dmd->cfg_mem_last_entry++; 1909 } else { 1910 return -ENOMEM; 1911 } 1912 1913 return 0; 1914} 1915 1916int cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd, 1917 struct cxd2880_io *io, 1918 struct cxd2880_tnrdmd_create_param 1919 *create_param) 1920{ 1921 if (!tnr_dmd || !io || !create_param) 1922 return -EINVAL; 1923 1924 memset(tnr_dmd, 0, sizeof(struct cxd2880_tnrdmd)); 1925 1926 tnr_dmd->io = io; 1927 tnr_dmd->create_param = *create_param; 1928 1929 tnr_dmd->diver_mode = CXD2880_TNRDMD_DIVERMODE_SINGLE; 1930 tnr_dmd->diver_sub = NULL; 1931 1932 tnr_dmd->srl_ts_clk_mod_cnts = 1; 1933 tnr_dmd->en_fef_intmtnt_base = 1; 1934 tnr_dmd->en_fef_intmtnt_lite = 1; 1935 tnr_dmd->rf_lvl_cmpstn = NULL; 1936 tnr_dmd->lna_thrs_tbl_air = NULL; 1937 tnr_dmd->lna_thrs_tbl_cable = NULL; 1938 atomic_set(&tnr_dmd->cancel, 0); 1939 1940 return 0; 1941} 1942 1943int cxd2880_tnrdmd_diver_create(struct cxd2880_tnrdmd 1944 *tnr_dmd_main, 1945 struct cxd2880_io *io_main, 1946 struct cxd2880_tnrdmd *tnr_dmd_sub, 1947 struct cxd2880_io *io_sub, 1948 struct 1949 cxd2880_tnrdmd_diver_create_param 1950 *create_param) 1951{ 1952 struct cxd2880_tnrdmd_create_param *main_param, *sub_param; 1953 1954 if (!tnr_dmd_main || !io_main || !tnr_dmd_sub || !io_sub || 1955 !create_param) 1956 return -EINVAL; 1957 1958 memset(tnr_dmd_main, 0, sizeof(struct cxd2880_tnrdmd)); 1959 memset(tnr_dmd_sub, 0, sizeof(struct cxd2880_tnrdmd)); 1960 1961 main_param = &tnr_dmd_main->create_param; 1962 sub_param = &tnr_dmd_sub->create_param; 1963 1964 tnr_dmd_main->io = io_main; 1965 tnr_dmd_main->diver_mode = CXD2880_TNRDMD_DIVERMODE_MAIN; 1966 tnr_dmd_main->diver_sub = tnr_dmd_sub; 1967 tnr_dmd_main->create_param.en_internal_ldo = 1968 create_param->en_internal_ldo; 1969 1970 main_param->ts_output_if = create_param->ts_output_if; 1971 main_param->xtal_share_type = CXD2880_TNRDMD_XTAL_SHARE_MASTER; 1972 main_param->xosc_cap = create_param->xosc_cap_main; 1973 main_param->xosc_i = create_param->xosc_i_main; 1974 main_param->is_cxd2881gg = create_param->is_cxd2881gg; 1975 main_param->stationary_use = create_param->stationary_use; 1976 1977 tnr_dmd_sub->io = io_sub; 1978 tnr_dmd_sub->diver_mode = CXD2880_TNRDMD_DIVERMODE_SUB; 1979 tnr_dmd_sub->diver_sub = NULL; 1980 1981 sub_param->en_internal_ldo = create_param->en_internal_ldo; 1982 sub_param->ts_output_if = create_param->ts_output_if; 1983 sub_param->xtal_share_type = CXD2880_TNRDMD_XTAL_SHARE_SLAVE; 1984 sub_param->xosc_cap = 0; 1985 sub_param->xosc_i = create_param->xosc_i_sub; 1986 sub_param->is_cxd2881gg = create_param->is_cxd2881gg; 1987 sub_param->stationary_use = create_param->stationary_use; 1988 1989 tnr_dmd_main->srl_ts_clk_mod_cnts = 1; 1990 tnr_dmd_main->en_fef_intmtnt_base = 1; 1991 tnr_dmd_main->en_fef_intmtnt_lite = 1; 1992 tnr_dmd_main->rf_lvl_cmpstn = NULL; 1993 tnr_dmd_main->lna_thrs_tbl_air = NULL; 1994 tnr_dmd_main->lna_thrs_tbl_cable = NULL; 1995 1996 tnr_dmd_sub->srl_ts_clk_mod_cnts = 1; 1997 tnr_dmd_sub->en_fef_intmtnt_base = 1; 1998 tnr_dmd_sub->en_fef_intmtnt_lite = 1; 1999 tnr_dmd_sub->rf_lvl_cmpstn = NULL; 2000 tnr_dmd_sub->lna_thrs_tbl_air = NULL; 2001 tnr_dmd_sub->lna_thrs_tbl_cable = NULL; 2002 2003 return 0; 2004} 2005 2006int cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd) 2007{ 2008 int ret; 2009 2010 if (!tnr_dmd || tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 2011 return -EINVAL; 2012 2013 tnr_dmd->chip_id = CXD2880_TNRDMD_CHIP_ID_UNKNOWN; 2014 tnr_dmd->state = CXD2880_TNRDMD_STATE_UNKNOWN; 2015 tnr_dmd->clk_mode = CXD2880_TNRDMD_CLOCKMODE_UNKNOWN; 2016 tnr_dmd->frequency_khz = 0; 2017 tnr_dmd->sys = CXD2880_DTV_SYS_UNKNOWN; 2018 tnr_dmd->bandwidth = CXD2880_DTV_BW_UNKNOWN; 2019 tnr_dmd->scan_mode = 0; 2020 atomic_set(&tnr_dmd->cancel, 0); 2021 2022 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2023 tnr_dmd->diver_sub->chip_id = CXD2880_TNRDMD_CHIP_ID_UNKNOWN; 2024 tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_UNKNOWN; 2025 tnr_dmd->diver_sub->clk_mode = CXD2880_TNRDMD_CLOCKMODE_UNKNOWN; 2026 tnr_dmd->diver_sub->frequency_khz = 0; 2027 tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_UNKNOWN; 2028 tnr_dmd->diver_sub->bandwidth = CXD2880_DTV_BW_UNKNOWN; 2029 tnr_dmd->diver_sub->scan_mode = 0; 2030 atomic_set(&tnr_dmd->diver_sub->cancel, 0); 2031 } 2032 2033 ret = cxd2880_tnrdmd_chip_id(tnr_dmd, &tnr_dmd->chip_id); 2034 if (ret) 2035 return ret; 2036 2037 if (!CXD2880_TNRDMD_CHIP_ID_VALID(tnr_dmd->chip_id)) 2038 return -ENOTTY; 2039 2040 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2041 ret = 2042 cxd2880_tnrdmd_chip_id(tnr_dmd->diver_sub, 2043 &tnr_dmd->diver_sub->chip_id); 2044 if (ret) 2045 return ret; 2046 2047 if (!CXD2880_TNRDMD_CHIP_ID_VALID(tnr_dmd->diver_sub->chip_id)) 2048 return -ENOTTY; 2049 } 2050 2051 ret = p_init1(tnr_dmd); 2052 if (ret) 2053 return ret; 2054 2055 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2056 ret = p_init1(tnr_dmd->diver_sub); 2057 if (ret) 2058 return ret; 2059 } 2060 2061 usleep_range(1000, 2000); 2062 2063 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2064 ret = p_init2(tnr_dmd->diver_sub); 2065 if (ret) 2066 return ret; 2067 } 2068 2069 ret = p_init2(tnr_dmd); 2070 if (ret) 2071 return ret; 2072 2073 usleep_range(5000, 6000); 2074 2075 ret = p_init3(tnr_dmd); 2076 if (ret) 2077 return ret; 2078 2079 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2080 ret = p_init3(tnr_dmd->diver_sub); 2081 if (ret) 2082 return ret; 2083 } 2084 2085 ret = rf_init1(tnr_dmd); 2086 if (ret) 2087 return ret; 2088 2089 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) 2090 ret = rf_init1(tnr_dmd->diver_sub); 2091 2092 return ret; 2093} 2094 2095int cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd) 2096{ 2097 u8 cpu_task_completed; 2098 int ret; 2099 2100 if (!tnr_dmd) 2101 return -EINVAL; 2102 2103 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 2104 return -EINVAL; 2105 2106 ret = cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd, 2107 &cpu_task_completed); 2108 if (ret) 2109 return ret; 2110 2111 if (!cpu_task_completed) 2112 return -EINVAL; 2113 2114 ret = rf_init2(tnr_dmd); 2115 if (ret) 2116 return ret; 2117 2118 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2119 ret = rf_init2(tnr_dmd->diver_sub); 2120 if (ret) 2121 return ret; 2122 } 2123 2124 ret = load_cfg_mem(tnr_dmd); 2125 if (ret) 2126 return ret; 2127 2128 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2129 ret = load_cfg_mem(tnr_dmd->diver_sub); 2130 if (ret) 2131 return ret; 2132 } 2133 2134 tnr_dmd->state = CXD2880_TNRDMD_STATE_SLEEP; 2135 2136 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) 2137 tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_SLEEP; 2138 2139 return ret; 2140} 2141 2142int cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd 2143 *tnr_dmd, 2144 u8 *task_completed) 2145{ 2146 u16 cpu_status = 0; 2147 int ret; 2148 2149 if (!tnr_dmd || !task_completed) 2150 return -EINVAL; 2151 2152 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 2153 return -EINVAL; 2154 2155 ret = cxd2880_tnrdmd_mon_internal_cpu_status(tnr_dmd, &cpu_status); 2156 if (ret) 2157 return ret; 2158 2159 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE) { 2160 if (cpu_status == 0) 2161 *task_completed = 1; 2162 else 2163 *task_completed = 0; 2164 2165 return ret; 2166 } 2167 if (cpu_status != 0) { 2168 *task_completed = 0; 2169 return ret; 2170 } 2171 2172 ret = cxd2880_tnrdmd_mon_internal_cpu_status_sub(tnr_dmd, &cpu_status); 2173 if (ret) 2174 return ret; 2175 2176 if (cpu_status == 0) 2177 *task_completed = 1; 2178 else 2179 *task_completed = 0; 2180 2181 return ret; 2182} 2183 2184int cxd2880_tnrdmd_common_tune_setting1(struct cxd2880_tnrdmd *tnr_dmd, 2185 enum cxd2880_dtv_sys sys, 2186 u32 frequency_khz, 2187 enum cxd2880_dtv_bandwidth 2188 bandwidth, u8 one_seg_opt, 2189 u8 one_seg_opt_shft_dir) 2190{ 2191 u8 data; 2192 enum cxd2880_tnrdmd_clockmode new_clk_mode = 2193 CXD2880_TNRDMD_CLOCKMODE_A; 2194 int shift_frequency_khz; 2195 u8 cpu_task_completed; 2196 int ret; 2197 2198 if (!tnr_dmd) 2199 return -EINVAL; 2200 2201 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 2202 return -EINVAL; 2203 2204 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 2205 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 2206 return -EINVAL; 2207 2208 if (frequency_khz < 4000) 2209 return -EINVAL; 2210 2211 ret = cxd2880_tnrdmd_sleep(tnr_dmd); 2212 if (ret) 2213 return ret; 2214 2215 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 2216 CXD2880_IO_TGT_SYS, 2217 0x00, 2218 0x00); 2219 if (ret) 2220 return ret; 2221 2222 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 2223 CXD2880_IO_TGT_SYS, 2224 0x2b, 2225 &data, 2226 1); 2227 if (ret) 2228 return ret; 2229 2230 switch (sys) { 2231 case CXD2880_DTV_SYS_DVBT: 2232 if (data == 0x00) { 2233 ret = t_power_x(tnr_dmd, 1); 2234 if (ret) 2235 return ret; 2236 2237 if (tnr_dmd->diver_mode == 2238 CXD2880_TNRDMD_DIVERMODE_MAIN) { 2239 ret = t_power_x(tnr_dmd->diver_sub, 1); 2240 if (ret) 2241 return ret; 2242 } 2243 } 2244 break; 2245 2246 case CXD2880_DTV_SYS_DVBT2: 2247 if (data == 0x01) { 2248 ret = t_power_x(tnr_dmd, 0); 2249 if (ret) 2250 return ret; 2251 2252 if (tnr_dmd->diver_mode == 2253 CXD2880_TNRDMD_DIVERMODE_MAIN) { 2254 ret = t_power_x(tnr_dmd->diver_sub, 0); 2255 if (ret) 2256 return ret; 2257 } 2258 } 2259 break; 2260 2261 default: 2262 return -EINVAL; 2263 } 2264 2265 ret = spll_reset(tnr_dmd, new_clk_mode); 2266 if (ret) 2267 return ret; 2268 2269 tnr_dmd->clk_mode = new_clk_mode; 2270 2271 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2272 ret = spll_reset(tnr_dmd->diver_sub, new_clk_mode); 2273 if (ret) 2274 return ret; 2275 2276 tnr_dmd->diver_sub->clk_mode = new_clk_mode; 2277 } 2278 2279 ret = load_cfg_mem(tnr_dmd); 2280 if (ret) 2281 return ret; 2282 2283 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2284 ret = load_cfg_mem(tnr_dmd->diver_sub); 2285 if (ret) 2286 return ret; 2287 } 2288 2289 if (one_seg_opt) { 2290 if (tnr_dmd->diver_mode == 2291 CXD2880_TNRDMD_DIVERMODE_MAIN) { 2292 shift_frequency_khz = 350; 2293 } else { 2294 if (one_seg_opt_shft_dir) 2295 shift_frequency_khz = 350; 2296 else 2297 shift_frequency_khz = -350; 2298 2299 if (tnr_dmd->create_param.xtal_share_type == 2300 CXD2880_TNRDMD_XTAL_SHARE_SLAVE) 2301 shift_frequency_khz *= -1; 2302 } 2303 } else { 2304 if (tnr_dmd->diver_mode == 2305 CXD2880_TNRDMD_DIVERMODE_MAIN) { 2306 shift_frequency_khz = 150; 2307 } else { 2308 switch (tnr_dmd->create_param.xtal_share_type) { 2309 case CXD2880_TNRDMD_XTAL_SHARE_NONE: 2310 case CXD2880_TNRDMD_XTAL_SHARE_EXTREF: 2311 default: 2312 shift_frequency_khz = 0; 2313 break; 2314 case CXD2880_TNRDMD_XTAL_SHARE_MASTER: 2315 shift_frequency_khz = 150; 2316 break; 2317 case CXD2880_TNRDMD_XTAL_SHARE_SLAVE: 2318 shift_frequency_khz = -150; 2319 break; 2320 } 2321 } 2322 } 2323 2324 ret = 2325 x_tune1(tnr_dmd, sys, frequency_khz, bandwidth, 2326 tnr_dmd->is_cable_input, shift_frequency_khz); 2327 if (ret) 2328 return ret; 2329 2330 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2331 ret = 2332 x_tune1(tnr_dmd->diver_sub, sys, frequency_khz, 2333 bandwidth, tnr_dmd->is_cable_input, 2334 -shift_frequency_khz); 2335 if (ret) 2336 return ret; 2337 } 2338 2339 usleep_range(10000, 11000); 2340 2341 ret = 2342 cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd, 2343 &cpu_task_completed); 2344 if (ret) 2345 return ret; 2346 2347 if (!cpu_task_completed) 2348 return -EINVAL; 2349 2350 ret = 2351 x_tune2(tnr_dmd, bandwidth, tnr_dmd->clk_mode, 2352 shift_frequency_khz); 2353 if (ret) 2354 return ret; 2355 2356 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2357 ret = 2358 x_tune2(tnr_dmd->diver_sub, bandwidth, 2359 tnr_dmd->diver_sub->clk_mode, 2360 -shift_frequency_khz); 2361 if (ret) 2362 return ret; 2363 } 2364 2365 if (tnr_dmd->create_param.ts_output_if == CXD2880_TNRDMD_TSOUT_IF_TS) { 2366 ret = set_ts_clk_mode_and_freq(tnr_dmd, sys); 2367 } else { 2368 struct cxd2880_tnrdmd_pid_ftr_cfg *pid_ftr_cfg; 2369 2370 if (tnr_dmd->pid_ftr_cfg_en) 2371 pid_ftr_cfg = &tnr_dmd->pid_ftr_cfg; 2372 else 2373 pid_ftr_cfg = NULL; 2374 2375 ret = pid_ftr_setting(tnr_dmd, pid_ftr_cfg); 2376 } 2377 2378 return ret; 2379} 2380 2381int cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd 2382 *tnr_dmd, 2383 enum cxd2880_dtv_sys sys, 2384 u8 en_fef_intmtnt_ctrl) 2385{ 2386 int ret; 2387 2388 if (!tnr_dmd) 2389 return -EINVAL; 2390 2391 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 2392 return -EINVAL; 2393 2394 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 2395 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 2396 return -EINVAL; 2397 2398 ret = x_tune3(tnr_dmd, sys, en_fef_intmtnt_ctrl); 2399 if (ret) 2400 return ret; 2401 2402 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2403 ret = x_tune3(tnr_dmd->diver_sub, sys, en_fef_intmtnt_ctrl); 2404 if (ret) 2405 return ret; 2406 ret = x_tune4(tnr_dmd); 2407 if (ret) 2408 return ret; 2409 } 2410 2411 return cxd2880_tnrdmd_set_ts_output(tnr_dmd, 1); 2412} 2413 2414int cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd) 2415{ 2416 int ret; 2417 2418 if (!tnr_dmd) 2419 return -EINVAL; 2420 2421 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 2422 return -EINVAL; 2423 2424 if (tnr_dmd->state == CXD2880_TNRDMD_STATE_SLEEP) 2425 return 0; 2426 2427 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 2428 return -EINVAL; 2429 2430 ret = cxd2880_tnrdmd_set_ts_output(tnr_dmd, 0); 2431 if (ret) 2432 return ret; 2433 2434 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2435 ret = x_sleep1(tnr_dmd); 2436 if (ret) 2437 return ret; 2438 } 2439 2440 ret = x_sleep2(tnr_dmd); 2441 if (ret) 2442 return ret; 2443 2444 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2445 ret = x_sleep2(tnr_dmd->diver_sub); 2446 if (ret) 2447 return ret; 2448 } 2449 2450 switch (tnr_dmd->sys) { 2451 case CXD2880_DTV_SYS_DVBT: 2452 ret = cxd2880_tnrdmd_dvbt_sleep_setting(tnr_dmd); 2453 if (ret) 2454 return ret; 2455 break; 2456 2457 case CXD2880_DTV_SYS_DVBT2: 2458 ret = cxd2880_tnrdmd_dvbt2_sleep_setting(tnr_dmd); 2459 if (ret) 2460 return ret; 2461 break; 2462 2463 default: 2464 return -EINVAL; 2465 } 2466 2467 ret = x_sleep3(tnr_dmd); 2468 if (ret) 2469 return ret; 2470 2471 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2472 ret = x_sleep3(tnr_dmd->diver_sub); 2473 if (ret) 2474 return ret; 2475 } 2476 2477 ret = x_sleep4(tnr_dmd); 2478 if (ret) 2479 return ret; 2480 2481 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2482 ret = x_sleep4(tnr_dmd->diver_sub); 2483 if (ret) 2484 return ret; 2485 } 2486 2487 tnr_dmd->state = CXD2880_TNRDMD_STATE_SLEEP; 2488 tnr_dmd->frequency_khz = 0; 2489 tnr_dmd->sys = CXD2880_DTV_SYS_UNKNOWN; 2490 tnr_dmd->bandwidth = CXD2880_DTV_BW_UNKNOWN; 2491 2492 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) { 2493 tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_SLEEP; 2494 tnr_dmd->diver_sub->frequency_khz = 0; 2495 tnr_dmd->diver_sub->sys = CXD2880_DTV_SYS_UNKNOWN; 2496 tnr_dmd->diver_sub->bandwidth = CXD2880_DTV_BW_UNKNOWN; 2497 } 2498 2499 return 0; 2500} 2501 2502int cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd, 2503 enum cxd2880_tnrdmd_cfg_id id, 2504 int value) 2505{ 2506 int ret = 0; 2507 u8 data[2] = { 0 }; 2508 u8 need_sub_setting = 0; 2509 2510 if (!tnr_dmd) 2511 return -EINVAL; 2512 2513 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 2514 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 2515 return -EINVAL; 2516 2517 switch (id) { 2518 case CXD2880_TNRDMD_CFG_OUTPUT_SEL_MSB: 2519 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2520 return -EINVAL; 2521 2522 ret = 2523 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2524 CXD2880_IO_TGT_DMD, 2525 0x00, 0xc4, 2526 value ? 0x00 : 0x10, 2527 0x10); 2528 if (ret) 2529 return ret; 2530 break; 2531 2532 case CXD2880_TNRDMD_CFG_TSVALID_ACTIVE_HI: 2533 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2534 return -EINVAL; 2535 2536 ret = 2537 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2538 CXD2880_IO_TGT_DMD, 2539 0x00, 0xc5, 2540 value ? 0x00 : 0x02, 2541 0x02); 2542 if (ret) 2543 return ret; 2544 break; 2545 2546 case CXD2880_TNRDMD_CFG_TSSYNC_ACTIVE_HI: 2547 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2548 return -EINVAL; 2549 2550 ret = 2551 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2552 CXD2880_IO_TGT_DMD, 2553 0x00, 0xc5, 2554 value ? 0x00 : 0x04, 2555 0x04); 2556 if (ret) 2557 return ret; 2558 break; 2559 2560 case CXD2880_TNRDMD_CFG_TSERR_ACTIVE_HI: 2561 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2562 return -EINVAL; 2563 2564 ret = 2565 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2566 CXD2880_IO_TGT_DMD, 2567 0x00, 0xcb, 2568 value ? 0x00 : 0x01, 2569 0x01); 2570 if (ret) 2571 return ret; 2572 break; 2573 2574 case CXD2880_TNRDMD_CFG_LATCH_ON_POSEDGE: 2575 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2576 return -EINVAL; 2577 2578 ret = 2579 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2580 CXD2880_IO_TGT_DMD, 2581 0x00, 0xc5, 2582 value ? 0x01 : 0x00, 2583 0x01); 2584 if (ret) 2585 return ret; 2586 break; 2587 2588 case CXD2880_TNRDMD_CFG_TSCLK_CONT: 2589 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2590 return -EINVAL; 2591 2592 tnr_dmd->srl_ts_clk_mod_cnts = value ? 0x01 : 0x00; 2593 break; 2594 2595 case CXD2880_TNRDMD_CFG_TSCLK_MASK: 2596 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2597 return -EINVAL; 2598 2599 if (value < 0 || value > 0x1f) 2600 return -EINVAL; 2601 2602 ret = 2603 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2604 CXD2880_IO_TGT_DMD, 2605 0x00, 0xc6, value, 2606 0x1f); 2607 if (ret) 2608 return ret; 2609 break; 2610 2611 case CXD2880_TNRDMD_CFG_TSVALID_MASK: 2612 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2613 return -EINVAL; 2614 2615 if (value < 0 || value > 0x1f) 2616 return -EINVAL; 2617 2618 ret = 2619 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2620 CXD2880_IO_TGT_DMD, 2621 0x00, 0xc8, value, 2622 0x1f); 2623 if (ret) 2624 return ret; 2625 break; 2626 2627 case CXD2880_TNRDMD_CFG_TSERR_MASK: 2628 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2629 return -EINVAL; 2630 2631 if (value < 0 || value > 0x1f) 2632 return -EINVAL; 2633 2634 ret = 2635 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2636 CXD2880_IO_TGT_DMD, 2637 0x00, 0xc9, value, 2638 0x1f); 2639 if (ret) 2640 return ret; 2641 break; 2642 2643 case CXD2880_TNRDMD_CFG_TSERR_VALID_DIS: 2644 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2645 return -EINVAL; 2646 2647 ret = 2648 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2649 CXD2880_IO_TGT_DMD, 2650 0x00, 0x91, 2651 value ? 0x01 : 0x00, 2652 0x01); 2653 if (ret) 2654 return ret; 2655 break; 2656 2657 case CXD2880_TNRDMD_CFG_TSPIN_CURRENT: 2658 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2659 return -EINVAL; 2660 2661 ret = 2662 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2663 CXD2880_IO_TGT_SYS, 2664 0x00, 0x51, value, 2665 0x3f); 2666 if (ret) 2667 return ret; 2668 break; 2669 2670 case CXD2880_TNRDMD_CFG_TSPIN_PULLUP_MANUAL: 2671 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2672 return -EINVAL; 2673 2674 ret = 2675 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2676 CXD2880_IO_TGT_SYS, 2677 0x00, 0x50, 2678 value ? 0x80 : 0x00, 2679 0x80); 2680 if (ret) 2681 return ret; 2682 break; 2683 2684 case CXD2880_TNRDMD_CFG_TSPIN_PULLUP: 2685 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2686 return -EINVAL; 2687 2688 ret = 2689 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2690 CXD2880_IO_TGT_SYS, 2691 0x00, 0x50, value, 2692 0x3f); 2693 if (ret) 2694 return ret; 2695 break; 2696 2697 case CXD2880_TNRDMD_CFG_TSCLK_FREQ: 2698 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2699 return -EINVAL; 2700 2701 if (value < 0 || value > 1) 2702 return -EINVAL; 2703 2704 tnr_dmd->srl_ts_clk_frq = 2705 (enum cxd2880_tnrdmd_serial_ts_clk)value; 2706 break; 2707 2708 case CXD2880_TNRDMD_CFG_TSBYTECLK_MANUAL: 2709 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2710 return -EINVAL; 2711 2712 if (value < 0 || value > 0xff) 2713 return -EINVAL; 2714 2715 tnr_dmd->ts_byte_clk_manual_setting = value; 2716 2717 break; 2718 2719 case CXD2880_TNRDMD_CFG_TS_PACKET_GAP: 2720 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2721 return -EINVAL; 2722 2723 if (value < 0 || value > 7) 2724 return -EINVAL; 2725 2726 ret = 2727 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2728 CXD2880_IO_TGT_DMD, 2729 0x00, 0xd6, value, 2730 0x07); 2731 if (ret) 2732 return ret; 2733 2734 break; 2735 2736 case CXD2880_TNRDMD_CFG_TS_BACKWARDS_COMPATIBLE: 2737 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 2738 return -EINVAL; 2739 2740 tnr_dmd->is_ts_backwards_compatible_mode = value ? 1 : 0; 2741 2742 break; 2743 2744 case CXD2880_TNRDMD_CFG_PWM_VALUE: 2745 if (value < 0 || value > 0x1000) 2746 return -EINVAL; 2747 2748 ret = 2749 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2750 CXD2880_IO_TGT_DMD, 2751 0x00, 0x22, 2752 value ? 0x01 : 0x00, 2753 0x01); 2754 if (ret) 2755 return ret; 2756 2757 data[0] = (value >> 8) & 0x1f; 2758 data[1] = value & 0xff; 2759 2760 ret = 2761 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2762 CXD2880_IO_TGT_DMD, 2763 0x00, 0x23, 2764 data[0], 0x1f); 2765 if (ret) 2766 return ret; 2767 2768 ret = 2769 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2770 CXD2880_IO_TGT_DMD, 2771 0x00, 0x24, 2772 data[1], 0xff); 2773 if (ret) 2774 return ret; 2775 2776 break; 2777 2778 case CXD2880_TNRDMD_CFG_INTERRUPT: 2779 data[0] = (value >> 8) & 0xff; 2780 data[1] = value & 0xff; 2781 ret = 2782 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2783 CXD2880_IO_TGT_SYS, 2784 0x00, 0x48, data[0], 2785 0xff); 2786 if (ret) 2787 return ret; 2788 ret = 2789 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2790 CXD2880_IO_TGT_SYS, 2791 0x00, 0x49, data[1], 2792 0xff); 2793 if (ret) 2794 return ret; 2795 break; 2796 2797 case CXD2880_TNRDMD_CFG_INTERRUPT_LOCK_SEL: 2798 data[0] = value & 0x07; 2799 ret = 2800 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2801 CXD2880_IO_TGT_SYS, 2802 0x00, 0x4a, data[0], 2803 0x07); 2804 if (ret) 2805 return ret; 2806 break; 2807 2808 case CXD2880_TNRDMD_CFG_INTERRUPT_INV_LOCK_SEL: 2809 data[0] = (value & 0x07) << 3; 2810 ret = 2811 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2812 CXD2880_IO_TGT_SYS, 2813 0x00, 0x4a, data[0], 2814 0x38); 2815 if (ret) 2816 return ret; 2817 break; 2818 2819 case CXD2880_TNRDMD_CFG_FIXED_CLOCKMODE: 2820 if (value < CXD2880_TNRDMD_CLOCKMODE_UNKNOWN || 2821 value > CXD2880_TNRDMD_CLOCKMODE_C) 2822 return -EINVAL; 2823 tnr_dmd->fixed_clk_mode = (enum cxd2880_tnrdmd_clockmode)value; 2824 break; 2825 2826 case CXD2880_TNRDMD_CFG_CABLE_INPUT: 2827 tnr_dmd->is_cable_input = value ? 1 : 0; 2828 break; 2829 2830 case CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_BASE: 2831 tnr_dmd->en_fef_intmtnt_base = value ? 1 : 0; 2832 break; 2833 2834 case CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_LITE: 2835 tnr_dmd->en_fef_intmtnt_lite = value ? 1 : 0; 2836 break; 2837 2838 case CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_EMPTY_THRS: 2839 data[0] = (value >> 8) & 0x07; 2840 data[1] = value & 0xff; 2841 ret = 2842 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2843 CXD2880_IO_TGT_DMD, 2844 0x00, 0x99, data[0], 2845 0x07); 2846 if (ret) 2847 return ret; 2848 ret = 2849 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2850 CXD2880_IO_TGT_DMD, 2851 0x00, 0x9a, data[1], 2852 0xff); 2853 if (ret) 2854 return ret; 2855 break; 2856 2857 case CXD2880_TNRDMD_CFG_TS_BUF_ALMOST_FULL_THRS: 2858 data[0] = (value >> 8) & 0x07; 2859 data[1] = value & 0xff; 2860 ret = 2861 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2862 CXD2880_IO_TGT_DMD, 2863 0x00, 0x9b, data[0], 2864 0x07); 2865 if (ret) 2866 return ret; 2867 ret = 2868 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2869 CXD2880_IO_TGT_DMD, 2870 0x00, 0x9c, data[1], 2871 0xff); 2872 if (ret) 2873 return ret; 2874 break; 2875 2876 case CXD2880_TNRDMD_CFG_TS_BUF_RRDY_THRS: 2877 data[0] = (value >> 8) & 0x07; 2878 data[1] = value & 0xff; 2879 ret = 2880 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2881 CXD2880_IO_TGT_DMD, 2882 0x00, 0x9d, data[0], 2883 0x07); 2884 if (ret) 2885 return ret; 2886 ret = 2887 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2888 CXD2880_IO_TGT_DMD, 2889 0x00, 0x9e, data[1], 2890 0xff); 2891 if (ret) 2892 return ret; 2893 break; 2894 2895 case CXD2880_TNRDMD_CFG_BLINDTUNE_DVBT2_FIRST: 2896 tnr_dmd->blind_tune_dvbt2_first = value ? 1 : 0; 2897 break; 2898 2899 case CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD: 2900 if (value < 0 || value > 31) 2901 return -EINVAL; 2902 2903 ret = 2904 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2905 CXD2880_IO_TGT_DMD, 2906 0x10, 0x60, 2907 value & 0x1f, 0x1f); 2908 if (ret) 2909 return ret; 2910 break; 2911 2912 case CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD: 2913 if (value < 0 || value > 7) 2914 return -EINVAL; 2915 2916 ret = 2917 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2918 CXD2880_IO_TGT_DMD, 2919 0x10, 0x6f, 2920 value & 0x07, 0x07); 2921 if (ret) 2922 return ret; 2923 break; 2924 2925 case CXD2880_TNRDMD_CFG_DVBT2_BBER_MES: 2926 if (value < 0 || value > 15) 2927 return -EINVAL; 2928 2929 ret = 2930 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2931 CXD2880_IO_TGT_DMD, 2932 0x20, 0x72, 2933 value & 0x0f, 0x0f); 2934 if (ret) 2935 return ret; 2936 break; 2937 2938 case CXD2880_TNRDMD_CFG_DVBT2_LBER_MES: 2939 if (value < 0 || value > 15) 2940 return -EINVAL; 2941 2942 ret = 2943 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2944 CXD2880_IO_TGT_DMD, 2945 0x20, 0x6f, 2946 value & 0x0f, 0x0f); 2947 if (ret) 2948 return ret; 2949 break; 2950 2951 case CXD2880_TNRDMD_CFG_DVBT_PER_MES: 2952 if (value < 0 || value > 15) 2953 return -EINVAL; 2954 2955 ret = 2956 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2957 CXD2880_IO_TGT_DMD, 2958 0x10, 0x5c, 2959 value & 0x0f, 0x0f); 2960 if (ret) 2961 return ret; 2962 break; 2963 2964 case CXD2880_TNRDMD_CFG_DVBT2_PER_MES: 2965 if (value < 0 || value > 15) 2966 return -EINVAL; 2967 2968 ret = 2969 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 2970 CXD2880_IO_TGT_DMD, 2971 0x24, 0xdc, 2972 value & 0x0f, 0x0f); 2973 if (ret) 2974 return ret; 2975 break; 2976 2977 default: 2978 return -EINVAL; 2979 } 2980 2981 if (need_sub_setting && 2982 tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) 2983 ret = cxd2880_tnrdmd_set_cfg(tnr_dmd->diver_sub, id, value); 2984 2985 return ret; 2986} 2987 2988int cxd2880_tnrdmd_gpio_set_cfg(struct cxd2880_tnrdmd *tnr_dmd, 2989 u8 id, 2990 u8 en, 2991 enum cxd2880_tnrdmd_gpio_mode mode, 2992 u8 open_drain, u8 invert) 2993{ 2994 int ret; 2995 2996 if (!tnr_dmd) 2997 return -EINVAL; 2998 2999 if (id > 2) 3000 return -EINVAL; 3001 3002 if (mode > CXD2880_TNRDMD_GPIO_MODE_EEW) 3003 return -EINVAL; 3004 3005 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 3006 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 3007 return -EINVAL; 3008 3009 ret = 3010 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS, 3011 0x00, 0x40 + id, mode, 3012 0x0f); 3013 if (ret) 3014 return ret; 3015 3016 ret = 3017 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS, 3018 0x00, 0x43, 3019 open_drain ? (1 << id) : 0, 3020 1 << id); 3021 if (ret) 3022 return ret; 3023 3024 ret = 3025 cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, CXD2880_IO_TGT_SYS, 3026 0x00, 0x44, 3027 invert ? (1 << id) : 0, 3028 1 << id); 3029 if (ret) 3030 return ret; 3031 3032 return cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 3033 CXD2880_IO_TGT_SYS, 3034 0x00, 0x45, 3035 en ? 0 : (1 << id), 3036 1 << id); 3037} 3038 3039int cxd2880_tnrdmd_gpio_set_cfg_sub(struct cxd2880_tnrdmd *tnr_dmd, 3040 u8 id, 3041 u8 en, 3042 enum cxd2880_tnrdmd_gpio_mode 3043 mode, u8 open_drain, u8 invert) 3044{ 3045 if (!tnr_dmd) 3046 return -EINVAL; 3047 3048 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) 3049 return -EINVAL; 3050 3051 return cxd2880_tnrdmd_gpio_set_cfg(tnr_dmd->diver_sub, id, en, mode, 3052 open_drain, invert); 3053} 3054 3055int cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd, 3056 u8 id, u8 *value) 3057{ 3058 u8 data = 0; 3059 int ret; 3060 3061 if (!tnr_dmd || !value) 3062 return -EINVAL; 3063 3064 if (id > 2) 3065 return -EINVAL; 3066 3067 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 3068 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 3069 return -EINVAL; 3070 3071 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3072 CXD2880_IO_TGT_SYS, 3073 0x00, 0x0a); 3074 if (ret) 3075 return ret; 3076 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 3077 CXD2880_IO_TGT_SYS, 3078 0x20, &data, 1); 3079 if (ret) 3080 return ret; 3081 3082 *value = (data >> id) & 0x01; 3083 3084 return 0; 3085} 3086 3087int cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd, 3088 u8 id, u8 *value) 3089{ 3090 if (!tnr_dmd) 3091 return -EINVAL; 3092 3093 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) 3094 return -EINVAL; 3095 3096 return cxd2880_tnrdmd_gpio_read(tnr_dmd->diver_sub, id, value); 3097} 3098 3099int cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd, 3100 u8 id, u8 value) 3101{ 3102 if (!tnr_dmd) 3103 return -EINVAL; 3104 3105 if (id > 2) 3106 return -EINVAL; 3107 3108 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 3109 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 3110 return -EINVAL; 3111 3112 return cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 3113 CXD2880_IO_TGT_SYS, 3114 0x00, 0x46, 3115 value ? (1 << id) : 0, 3116 1 << id); 3117} 3118 3119int cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd, 3120 u8 id, u8 value) 3121{ 3122 if (!tnr_dmd) 3123 return -EINVAL; 3124 3125 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) 3126 return -EINVAL; 3127 3128 return cxd2880_tnrdmd_gpio_write(tnr_dmd->diver_sub, id, value); 3129} 3130 3131int cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd, 3132 u16 *value) 3133{ 3134 int ret; 3135 u8 data[2] = { 0 }; 3136 3137 if (!tnr_dmd || !value) 3138 return -EINVAL; 3139 3140 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 3141 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 3142 return -EINVAL; 3143 3144 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3145 CXD2880_IO_TGT_SYS, 3146 0x00, 0x0a); 3147 if (ret) 3148 return ret; 3149 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 3150 CXD2880_IO_TGT_SYS, 3151 0x15, data, 2); 3152 if (ret) 3153 return ret; 3154 3155 *value = (data[0] << 8) | data[1]; 3156 3157 return 0; 3158} 3159 3160int cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd, 3161 u16 value) 3162{ 3163 int ret; 3164 u8 data[2] = { 0 }; 3165 3166 if (!tnr_dmd) 3167 return -EINVAL; 3168 3169 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 3170 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 3171 return -EINVAL; 3172 3173 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3174 CXD2880_IO_TGT_SYS, 3175 0x00, 0x00); 3176 if (ret) 3177 return ret; 3178 3179 data[0] = (value >> 8) & 0xff; 3180 data[1] = value & 0xff; 3181 3182 return tnr_dmd->io->write_regs(tnr_dmd->io, 3183 CXD2880_IO_TGT_SYS, 3184 0x3c, data, 2); 3185} 3186 3187int cxd2880_tnrdmd_ts_buf_clear(struct cxd2880_tnrdmd *tnr_dmd, 3188 u8 clear_overflow_flag, 3189 u8 clear_underflow_flag, 3190 u8 clear_buf) 3191{ 3192 int ret; 3193 u8 data[2] = { 0 }; 3194 3195 if (!tnr_dmd) 3196 return -EINVAL; 3197 3198 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 3199 return -EINVAL; 3200 3201 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 3202 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 3203 return -EINVAL; 3204 3205 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3206 CXD2880_IO_TGT_DMD, 3207 0x00, 0x00); 3208 if (ret) 3209 return ret; 3210 3211 data[0] = clear_overflow_flag ? 0x02 : 0x00; 3212 data[0] |= clear_underflow_flag ? 0x01 : 0x00; 3213 data[1] = clear_buf ? 0x01 : 0x00; 3214 3215 return tnr_dmd->io->write_regs(tnr_dmd->io, 3216 CXD2880_IO_TGT_DMD, 3217 0x9f, data, 2); 3218} 3219 3220int cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd, 3221 enum cxd2880_tnrdmd_chip_id *chip_id) 3222{ 3223 int ret; 3224 u8 data = 0; 3225 3226 if (!tnr_dmd || !chip_id) 3227 return -EINVAL; 3228 3229 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3230 CXD2880_IO_TGT_SYS, 3231 0x00, 0x00); 3232 if (ret) 3233 return ret; 3234 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 3235 CXD2880_IO_TGT_SYS, 3236 0xfd, &data, 1); 3237 if (ret) 3238 return ret; 3239 3240 *chip_id = (enum cxd2880_tnrdmd_chip_id)data; 3241 3242 return 0; 3243} 3244 3245int cxd2880_tnrdmd_set_and_save_reg_bits(struct cxd2880_tnrdmd 3246 *tnr_dmd, 3247 enum cxd2880_io_tgt tgt, 3248 u8 bank, u8 address, 3249 u8 value, u8 bit_mask) 3250{ 3251 int ret; 3252 3253 if (!tnr_dmd) 3254 return -EINVAL; 3255 3256 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 3257 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 3258 return -EINVAL; 3259 3260 ret = tnr_dmd->io->write_reg(tnr_dmd->io, tgt, 0x00, bank); 3261 if (ret) 3262 return ret; 3263 3264 ret = cxd2880_io_set_reg_bits(tnr_dmd->io, 3265 tgt, address, value, bit_mask); 3266 if (ret) 3267 return ret; 3268 3269 return set_cfg_mem(tnr_dmd, tgt, bank, address, value, bit_mask); 3270} 3271 3272int cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd, 3273 enum cxd2880_dtv_sys sys, 3274 u8 scan_mode_end) 3275{ 3276 if (!tnr_dmd) 3277 return -EINVAL; 3278 3279 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 3280 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 3281 return -EINVAL; 3282 3283 tnr_dmd->scan_mode = scan_mode_end; 3284 3285 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) 3286 return cxd2880_tnrdmd_set_scan_mode(tnr_dmd->diver_sub, sys, 3287 scan_mode_end); 3288 else 3289 return 0; 3290} 3291 3292int cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd, 3293 struct cxd2880_tnrdmd_pid_ftr_cfg 3294 *pid_ftr_cfg) 3295{ 3296 if (!tnr_dmd) 3297 return -EINVAL; 3298 3299 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 3300 return -EINVAL; 3301 3302 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 3303 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 3304 return -EINVAL; 3305 3306 if (tnr_dmd->create_param.ts_output_if == CXD2880_TNRDMD_TSOUT_IF_TS) 3307 return -ENOTTY; 3308 3309 if (pid_ftr_cfg) { 3310 tnr_dmd->pid_ftr_cfg = *pid_ftr_cfg; 3311 tnr_dmd->pid_ftr_cfg_en = 1; 3312 } else { 3313 tnr_dmd->pid_ftr_cfg_en = 0; 3314 } 3315 3316 if (tnr_dmd->state == CXD2880_TNRDMD_STATE_ACTIVE) 3317 return pid_ftr_setting(tnr_dmd, pid_ftr_cfg); 3318 else 3319 return 0; 3320} 3321 3322int cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd 3323 *tnr_dmd, 3324 int (*rf_lvl_cmpstn) 3325 (struct cxd2880_tnrdmd *, 3326 int *)) 3327{ 3328 if (!tnr_dmd) 3329 return -EINVAL; 3330 3331 tnr_dmd->rf_lvl_cmpstn = rf_lvl_cmpstn; 3332 3333 return 0; 3334} 3335 3336int cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd 3337 *tnr_dmd, 3338 int (*rf_lvl_cmpstn) 3339 (struct cxd2880_tnrdmd *, 3340 int *)) 3341{ 3342 if (!tnr_dmd) 3343 return -EINVAL; 3344 3345 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) 3346 return -EINVAL; 3347 3348 return cxd2880_tnrdmd_set_rf_lvl_cmpstn(tnr_dmd->diver_sub, 3349 rf_lvl_cmpstn); 3350} 3351 3352int cxd2880_tnrdmd_set_lna_thrs(struct cxd2880_tnrdmd *tnr_dmd, 3353 struct cxd2880_tnrdmd_lna_thrs_tbl_air 3354 *tbl_air, 3355 struct cxd2880_tnrdmd_lna_thrs_tbl_cable 3356 *tbl_cable) 3357{ 3358 if (!tnr_dmd) 3359 return -EINVAL; 3360 3361 tnr_dmd->lna_thrs_tbl_air = tbl_air; 3362 tnr_dmd->lna_thrs_tbl_cable = tbl_cable; 3363 3364 return 0; 3365} 3366 3367int cxd2880_tnrdmd_set_lna_thrs_sub(struct cxd2880_tnrdmd *tnr_dmd, 3368 struct 3369 cxd2880_tnrdmd_lna_thrs_tbl_air 3370 *tbl_air, 3371 struct cxd2880_tnrdmd_lna_thrs_tbl_cable 3372 *tbl_cable) 3373{ 3374 if (!tnr_dmd) 3375 return -EINVAL; 3376 3377 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN) 3378 return -EINVAL; 3379 3380 return cxd2880_tnrdmd_set_lna_thrs(tnr_dmd->diver_sub, 3381 tbl_air, tbl_cable); 3382} 3383 3384int cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd 3385 *tnr_dmd, u8 en, u8 value) 3386{ 3387 int ret; 3388 3389 if (!tnr_dmd) 3390 return -EINVAL; 3391 3392 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 3393 return -EINVAL; 3394 3395 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP) 3396 return -EINVAL; 3397 3398 if (tnr_dmd->create_param.ts_output_if != CXD2880_TNRDMD_TSOUT_IF_TS) 3399 return -ENOTTY; 3400 3401 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3402 CXD2880_IO_TGT_SYS, 3403 0x00, 0x00); 3404 if (ret) 3405 return ret; 3406 3407 if (en) { 3408 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3409 CXD2880_IO_TGT_SYS, 3410 0x50, ((value & 0x1f) | 0x80)); 3411 if (ret) 3412 return ret; 3413 3414 ret = tnr_dmd->io->write_reg(tnr_dmd->io, 3415 CXD2880_IO_TGT_SYS, 3416 0x52, (value & 0x1f)); 3417 } else { 3418 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 3419 CXD2880_IO_TGT_SYS, 3420 set_ts_pin_seq, 3421 ARRAY_SIZE(set_ts_pin_seq)); 3422 if (ret) 3423 return ret; 3424 3425 ret = load_cfg_mem(tnr_dmd); 3426 } 3427 3428 return ret; 3429} 3430 3431int cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd, 3432 u8 en) 3433{ 3434 int ret; 3435 3436 if (!tnr_dmd) 3437 return -EINVAL; 3438 3439 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB) 3440 return -EINVAL; 3441 3442 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP && 3443 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE) 3444 return -EINVAL; 3445 3446 switch (tnr_dmd->create_param.ts_output_if) { 3447 case CXD2880_TNRDMD_TSOUT_IF_TS: 3448 if (en) { 3449 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 3450 CXD2880_IO_TGT_SYS, 3451 set_ts_output_seq1, 3452 ARRAY_SIZE(set_ts_output_seq1)); 3453 if (ret) 3454 return ret; 3455 3456 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 3457 CXD2880_IO_TGT_DMD, 3458 set_ts_output_seq2, 3459 ARRAY_SIZE(set_ts_output_seq2)); 3460 if (ret) 3461 return ret; 3462 } else { 3463 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 3464 CXD2880_IO_TGT_DMD, 3465 set_ts_output_seq3, 3466 ARRAY_SIZE(set_ts_output_seq3)); 3467 if (ret) 3468 return ret; 3469 3470 ret = cxd2880_io_write_multi_regs(tnr_dmd->io, 3471 CXD2880_IO_TGT_SYS, 3472 set_ts_output_seq4, 3473 ARRAY_SIZE(set_ts_output_seq4)); 3474 if (ret) 3475 return ret; 3476 } 3477 break; 3478 3479 case CXD2880_TNRDMD_TSOUT_IF_SPI: 3480 break; 3481 3482 case CXD2880_TNRDMD_TSOUT_IF_SDIO: 3483 break; 3484 3485 default: 3486 return -EINVAL; 3487 } 3488 3489 return 0; 3490} 3491 3492int slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd) 3493{ 3494 u8 data; 3495 int ret; 3496 3497 if (!tnr_dmd) 3498 return -EINVAL; 3499 3500 switch (tnr_dmd->create_param.ts_output_if) { 3501 case CXD2880_TNRDMD_TSOUT_IF_SPI: 3502 case CXD2880_TNRDMD_TSOUT_IF_SDIO: 3503 3504 ret = tnr_dmd->io->read_regs(tnr_dmd->io, 3505 CXD2880_IO_TGT_DMD, 3506 0x00, &data, 1); 3507 if (ret) 3508 return ret; 3509 3510 break; 3511 case CXD2880_TNRDMD_TSOUT_IF_TS: 3512 default: 3513 break; 3514 } 3515 3516 return tnr_dmd->io->write_reg(tnr_dmd->io, 3517 CXD2880_IO_TGT_DMD, 3518 0x01, 0x01); 3519}