WIP FPC-III support
[linux/fpc-iii.git] / drivers / media / dvb-frontends / cxd2880 / cxd2880_tnrdmd.c
blob4cf2d7cfd3f5893f40740f8c9c3c626aee1193d6
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
7 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
8 */
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"
17 static const struct cxd2880_reg_value p_init1_seq[] = {
18 {0x11, 0x16}, {0x00, 0x10},
21 static 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},
27 static const struct cxd2880_reg_value rf_init1_seq2[] = {
28 {0xb9, 0x07}, {0x33, 0x01}, {0xc1, 0x01}, {0xc4, 0x1e},
31 static 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},
37 static const struct cxd2880_reg_value rf_init1_seq4[] = {
38 {0x15, 0x00}, {0x00, 0x16}
41 static const struct cxd2880_reg_value rf_init1_seq5[] = {
42 {0x00, 0x00}, {0x25, 0x00}
45 static 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}
50 static const struct cxd2880_reg_value rf_init1_seq7[] = {
51 {0x00, 0xe2}, {0x41, 0xa0}, {0x4b, 0x68}, {0x00, 0x00},
52 {0x21, 0x00}, {0x10, 0x01},
55 static const struct cxd2880_reg_value rf_init1_seq8[] = {
56 {0x00, 0x10}, {0x25, 0x01},
59 static const struct cxd2880_reg_value rf_init1_seq9[] = {
60 {0x00, 0x10}, {0x14, 0x01}, {0x00, 0x00}, {0x26, 0x00},
63 static const struct cxd2880_reg_value rf_init2_seq1[] = {
64 {0x00, 0x14}, {0x1b, 0x01},
67 static const struct cxd2880_reg_value rf_init2_seq2[] = {
68 {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1}, {0xd3, 0x00},
69 {0x00, 0x00}, {0x21, 0x00},
72 static const struct cxd2880_reg_value x_tune1_seq1[] = {
73 {0x00, 0x00}, {0x10, 0x01},
76 static const struct cxd2880_reg_value x_tune1_seq2[] = {
77 {0x62, 0x00}, {0x00, 0x15},
80 static const struct cxd2880_reg_value x_tune2_seq1[] = {
81 {0x00, 0x1a}, {0x29, 0x01},
84 static const struct cxd2880_reg_value x_tune2_seq2[] = {
85 {0x62, 0x01}, {0x00, 0x11}, {0x2d, 0x00}, {0x2f, 0x00},
88 static const struct cxd2880_reg_value x_tune2_seq3[] = {
89 {0x00, 0x00}, {0x10, 0x00}, {0x21, 0x01},
92 static const struct cxd2880_reg_value x_tune2_seq4[] = {
93 {0x00, 0xe1}, {0x8a, 0x87},
96 static const struct cxd2880_reg_value x_tune2_seq5[] = {
97 {0x00, 0x00}, {0x21, 0x00},
100 static const struct cxd2880_reg_value x_tune3_seq[] = {
101 {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0xa0},
102 {0x00, 0x00}, {0x21, 0x00}, {0xfe, 0x01},
105 static const struct cxd2880_reg_value x_tune4_seq[] = {
106 {0x00, 0x00}, {0xfe, 0x01},
109 static const struct cxd2880_reg_value x_sleep1_seq[] = {
110 {0x00, 0x00}, {0x57, 0x03},
113 static const struct cxd2880_reg_value x_sleep2_seq1[] = {
114 {0x00, 0x2d}, {0xb1, 0x01},
117 static const struct cxd2880_reg_value x_sleep2_seq2[] = {
118 {0x00, 0x10}, {0xf4, 0x00}, {0xf3, 0x00}, {0xf2, 0x00},
119 {0xf1, 0x00}, {0xf0, 0x00}, {0xef, 0x00},
122 static const struct cxd2880_reg_value x_sleep3_seq[] = {
123 {0x00, 0x00}, {0xfd, 0x00},
126 static const struct cxd2880_reg_value x_sleep4_seq[] = {
127 {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0x00},
128 {0x00, 0x00}, {0x21, 0x00},
131 static const struct cxd2880_reg_value spll_reset_seq1[] = {
132 {0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01},
133 {0x26, 0x01},
136 static const struct cxd2880_reg_value spll_reset_seq2[] = {
137 {0x00, 0x00}, {0x10, 0x00},
140 static const struct cxd2880_reg_value spll_reset_seq3[] = {
141 {0x00, 0x00}, {0x27, 0x00}, {0x22, 0x01},
144 static const struct cxd2880_reg_value spll_reset_seq4[] = {
145 {0x00, 0x00}, {0x27, 0x01},
148 static const struct cxd2880_reg_value spll_reset_seq5[] = {
149 {0x00, 0x00}, {0x10, 0x01},
152 static const struct cxd2880_reg_value t_power_x_seq1[] = {
153 {0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01},
156 static const struct cxd2880_reg_value t_power_x_seq2[] = {
157 {0x00, 0x00}, {0x10, 0x00},
160 static const struct cxd2880_reg_value t_power_x_seq3[] = {
161 {0x00, 0x00}, {0x27, 0x00}, {0x25, 0x01},
164 static const struct cxd2880_reg_value t_power_x_seq4[] = {
165 {0x00, 0x00}, {0x2a, 0x00},
168 static const struct cxd2880_reg_value t_power_x_seq5[] = {
169 {0x00, 0x00}, {0x25, 0x00},
172 static const struct cxd2880_reg_value t_power_x_seq6[] = {
173 {0x00, 0x00}, {0x27, 0x01},
176 static const struct cxd2880_reg_value t_power_x_seq7[] = {
177 {0x00, 0x00}, {0x10, 0x01},
180 static const struct cxd2880_reg_value set_ts_pin_seq[] = {
181 {0x50, 0x3f}, {0x52, 0x1f},
185 static const struct cxd2880_reg_value set_ts_output_seq1[] = {
186 {0x00, 0x00}, {0x52, 0x00},
189 static const struct cxd2880_reg_value set_ts_output_seq2[] = {
190 {0x00, 0x00}, {0xc3, 0x00},
194 static const struct cxd2880_reg_value set_ts_output_seq3[] = {
195 {0x00, 0x00}, {0xc3, 0x01},
199 static const struct cxd2880_reg_value set_ts_output_seq4[] = {
200 {0x00, 0x00}, {0x52, 0x1f},
204 static int p_init1(struct cxd2880_tnrdmd *tnr_dmd)
206 u8 data = 0;
207 int ret;
209 if (!tnr_dmd)
210 return -EINVAL;
212 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
213 CXD2880_IO_TGT_SYS,
214 0x00, 0x00);
215 if (ret)
216 return ret;
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;
233 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
234 CXD2880_IO_TGT_SYS,
235 0x10, data);
236 if (ret)
237 return ret;
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;
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;
258 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
259 CXD2880_IO_TGT_SYS,
260 0x10, data);
261 if (ret)
262 return ret;
264 if (tnr_dmd->create_param.en_internal_ldo)
265 data = 0x01;
266 else
267 data = 0x00;
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;
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;
291 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
292 CXD2880_IO_TGT_SYS,
293 0x00, 0x10);
294 if (ret)
295 return ret;
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;
308 return tnr_dmd->io->write_reg(tnr_dmd->io,
309 CXD2880_IO_TGT_SYS,
310 0x69, data);
313 static int p_init2(struct cxd2880_tnrdmd *tnr_dmd)
315 u8 data[6] = { 0 };
316 int ret;
318 if (!tnr_dmd)
319 return -EINVAL;
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;
348 data[4] = 0x06;
349 data[5] = 0x00;
351 return tnr_dmd->io->write_regs(tnr_dmd->io,
352 CXD2880_IO_TGT_SYS,
353 0x13, data, 6);
356 static int p_init3(struct cxd2880_tnrdmd *tnr_dmd)
358 u8 data[2] = { 0 };
359 int ret;
361 if (!tnr_dmd)
362 return -EINVAL;
364 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
365 CXD2880_IO_TGT_SYS,
366 0x00, 0x00);
367 if (ret)
368 return ret;
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;
384 data[1] = 0x01;
386 return tnr_dmd->io->write_regs(tnr_dmd->io,
387 CXD2880_IO_TGT_SYS,
388 0x1f, data, 2);
391 static int rf_init1(struct cxd2880_tnrdmd *tnr_dmd)
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
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
419 static const u8 rf_init1_cdata4[8] = {
420 0x20, 0x20, 0x30, 0x41, 0x50, 0x5f, 0x6f, 0x80
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
434 u8 addr = 0;
435 int ret;
437 if (!tnr_dmd)
438 return -EINVAL;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
616 data[3] = 0x0e;
617 data[4] = 0x09;
618 data[5] = 0x0e;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
727 usleep_range(1000, 2000);
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;
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;
749 usleep_range(1000, 2000);
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;
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;
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;
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;
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;
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;
816 usleep_range(1000, 2000);
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;
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));
837 static int rf_init2(struct cxd2880_tnrdmd *tnr_dmd)
839 u8 data[5] = { 0 };
840 int ret;
842 if (!tnr_dmd)
843 return -EINVAL;
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;
858 usleep_range(1000, 2000);
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;
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;
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));
886 static 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)
891 u8 data[11] = { 0 };
892 int ret;
894 if (!tnr_dmd)
895 return -EINVAL;
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;
904 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
905 CXD2880_IO_TGT_SYS,
906 0x00, 0x10);
907 if (ret)
908 return ret;
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;
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;
929 usleep_range(1000, 2000);
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;
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;
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;
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;
970 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
971 CXD2880_IO_TGT_SYS,
972 0x00, 0x10);
973 if (ret)
974 return ret;
976 data[0] = is_cable ? 0x01 : 0x00;
977 data[1] = 0x00;
978 data[2] = 0x6b;
979 data[3] = 0x4d;
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;
999 data[5] = 0x00;
1001 freq_khz += shift_frequency_khz;
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;
1009 return tnr_dmd->io->write_regs(tnr_dmd->io,
1010 CXD2880_IO_TGT_SYS,
1011 0x52, data, 11);
1014 static 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)
1019 u8 data[3] = { 0 };
1020 int ret;
1022 if (!tnr_dmd)
1023 return -EINVAL;
1025 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1026 CXD2880_IO_TGT_SYS,
1027 0x00, 0x11);
1028 if (ret)
1029 return ret;
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;
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;
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;
1053 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1054 CXD2880_IO_TGT_SYS,
1055 0x00, 0x10);
1056 if (ret)
1057 return ret;
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;
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;
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;
1079 if (shift_frequency_khz != 0) {
1080 int shift_freq = 0;
1082 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1083 CXD2880_IO_TGT_DMD,
1084 0x00, 0xe1);
1085 if (ret)
1086 return ret;
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;
1094 shift_freq = shift_frequency_khz * 1000;
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;
1113 shift_freq +=
1114 cxd2880_convert2s_complement((data[0] << 8) | data[1], 16);
1116 if (shift_freq > 32767)
1117 shift_freq = 32767;
1118 else if (shift_freq < -32768)
1119 shift_freq = -32768;
1121 data[0] = (shift_freq >> 8) & 0xff;
1122 data[1] = shift_freq & 0xff;
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;
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;
1136 shift_freq = -shift_frequency_khz;
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;
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;
1190 shift_freq += cxd2880_convert2s_complement(data[0], 8);
1192 if (shift_freq > 127)
1193 shift_freq = 127;
1194 else if (shift_freq < -128)
1195 shift_freq = -128;
1197 data[0] = shift_freq & 0xff;
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;
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;
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));
1221 static int x_tune3(struct cxd2880_tnrdmd *tnr_dmd,
1222 enum cxd2880_dtv_sys sys,
1223 u8 en_fef_intmtnt_ctrl)
1225 u8 data[6] = { 0 };
1226 int ret;
1228 if (!tnr_dmd)
1229 return -EINVAL;
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;
1238 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1239 CXD2880_IO_TGT_SYS,
1240 0x00, 0x10);
1241 if (ret)
1242 return ret;
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));
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;
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;
1265 return tnr_dmd->io->write_reg(tnr_dmd->io,
1266 CXD2880_IO_TGT_DMD,
1267 0xb1, data[0]);
1270 static int x_tune4(struct cxd2880_tnrdmd *tnr_dmd)
1272 u8 data[2] = { 0 };
1273 int ret;
1275 if (!tnr_dmd)
1276 return -EINVAL;
1278 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
1279 return -EINVAL;
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;
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;
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;
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;
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));
1350 static int x_sleep1(struct cxd2880_tnrdmd *tnr_dmd)
1352 u8 data[3] = { 0 };
1353 int ret;
1355 if (!tnr_dmd)
1356 return -EINVAL;
1358 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
1359 return -EINVAL;
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;
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;
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;
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;
1405 return tnr_dmd->io->write_regs(tnr_dmd->io,
1406 CXD2880_IO_TGT_SYS,
1407 0x55, data, 2);
1410 static int x_sleep2(struct cxd2880_tnrdmd *tnr_dmd)
1412 u8 data = 0;
1413 int ret;
1415 if (!tnr_dmd)
1416 return -EINVAL;
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;
1425 usleep_range(1000, 2000);
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;
1433 if ((data & 0x01) == 0x00)
1434 return -EINVAL;
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));
1442 static int x_sleep3(struct cxd2880_tnrdmd *tnr_dmd)
1444 if (!tnr_dmd)
1445 return -EINVAL;
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));
1453 static int x_sleep4(struct cxd2880_tnrdmd *tnr_dmd)
1455 if (!tnr_dmd)
1456 return -EINVAL;
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));
1464 static int spll_reset(struct cxd2880_tnrdmd *tnr_dmd,
1465 enum cxd2880_tnrdmd_clockmode clockmode)
1467 u8 data[4] = { 0 };
1468 int ret;
1470 if (!tnr_dmd)
1471 return -EINVAL;
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;
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;
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;
1494 switch (clockmode) {
1495 case CXD2880_TNRDMD_CLOCKMODE_A:
1496 data[0] = 0x00;
1497 break;
1499 case CXD2880_TNRDMD_CLOCKMODE_B:
1500 data[0] = 0x01;
1501 break;
1503 case CXD2880_TNRDMD_CLOCKMODE_C:
1504 data[0] = 0x02;
1505 break;
1507 default:
1508 return -EINVAL;
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;
1521 usleep_range(2000, 3000);
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;
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;
1543 usleep_range(1000, 2000);
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;
1552 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1553 CXD2880_IO_TGT_SYS,
1554 0x00, 0x10);
1555 if (ret)
1556 return ret;
1558 memset(data, 0x00, sizeof(data));
1560 return tnr_dmd->io->write_regs(tnr_dmd->io,
1561 CXD2880_IO_TGT_SYS,
1562 0x26, data, 4);
1565 static int t_power_x(struct cxd2880_tnrdmd *tnr_dmd, u8 on)
1567 u8 data[3] = { 0 };
1568 int ret;
1570 if (!tnr_dmd)
1571 return -EINVAL;
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;
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;
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;
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;
1601 usleep_range(1000, 2000);
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;
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;
1631 usleep_range(1000, 2000);
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;
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;
1654 usleep_range(1000, 2000);
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;
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;
1676 usleep_range(1000, 2000);
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;
1685 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1686 CXD2880_IO_TGT_SYS,
1687 0x00, 0x10);
1688 if (ret)
1689 return ret;
1691 memset(data, 0x00, sizeof(data));
1693 return tnr_dmd->io->write_regs(tnr_dmd->io,
1694 CXD2880_IO_TGT_SYS,
1695 0x27, data, 3);
1698 struct cxd2880_tnrdmd_ts_clk_cfg {
1699 u8 srl_clk_mode;
1700 u8 srl_duty_mode;
1701 u8 ts_clk_period;
1704 static int set_ts_clk_mode_and_freq(struct cxd2880_tnrdmd *tnr_dmd,
1705 enum cxd2880_dtv_sys sys)
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;
1715 static const struct cxd2880_tnrdmd_ts_clk_cfg srl_ts_clk_stgs[2][2] = {
1717 {3, 1, 8,},
1718 {0, 2, 16,}
1719 }, {
1720 {1, 1, 8,},
1721 {2, 2, 16,}
1725 if (!tnr_dmd)
1726 return -EINVAL;
1728 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1729 CXD2880_IO_TGT_DMD,
1730 0x00, 0x00);
1731 if (ret)
1732 return ret;
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;
1744 if (tnr_dmd->ts_byte_clk_manual_setting) {
1745 ts_clk_manaul_on = 1;
1746 ts_rate_ctrl_off = 0;
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;
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;
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;
1767 ts_clk_cfg = srl_ts_clk_stgs[tnr_dmd->srl_ts_clk_mod_cnts]
1768 [tnr_dmd->srl_ts_clk_frq];
1770 if (tnr_dmd->ts_byte_clk_manual_setting)
1771 ts_clk_cfg.ts_clk_period = tnr_dmd->ts_byte_clk_manual_setting;
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;
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;
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;
1791 data = backwards_compatible ? 0x00 : 0x01;
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;
1800 ret =
1801 cxd2880_io_set_reg_bits(tnr_dmd->io,
1802 CXD2880_IO_TGT_DMD,
1803 0x66, data, 0x01);
1806 return ret;
1809 static int pid_ftr_setting(struct cxd2880_tnrdmd *tnr_dmd,
1810 struct cxd2880_tnrdmd_pid_ftr_cfg
1811 *pid_ftr_cfg)
1813 int i;
1814 int ret;
1815 u8 data[65];
1817 if (!tnr_dmd)
1818 return -EINVAL;
1820 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1821 CXD2880_IO_TGT_DMD,
1822 0x00, 0x00);
1823 if (ret)
1824 return ret;
1826 if (!pid_ftr_cfg)
1827 return tnr_dmd->io->write_reg(tnr_dmd->io,
1828 CXD2880_IO_TGT_DMD,
1829 0x50, 0x02);
1831 data[0] = pid_ftr_cfg->is_negative ? 0x01 : 0x00;
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;
1843 return tnr_dmd->io->write_regs(tnr_dmd->io,
1844 CXD2880_IO_TGT_DMD,
1845 0x50, data, 65);
1848 static int load_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd)
1850 int ret;
1851 u8 i;
1853 if (!tnr_dmd)
1854 return -EINVAL;
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;
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;
1872 return 0;
1875 static 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)
1879 u8 i;
1880 u8 value_stored = 0;
1882 if (!tnr_dmd)
1883 return -EINVAL;
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);
1893 tnr_dmd->cfg_mem[i].bit_mask |= bit_mask;
1895 value_stored = 1;
1899 if (value_stored)
1900 return 0;
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;
1913 return 0;
1916 int cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd,
1917 struct cxd2880_io *io,
1918 struct cxd2880_tnrdmd_create_param
1919 *create_param)
1921 if (!tnr_dmd || !io || !create_param)
1922 return -EINVAL;
1924 memset(tnr_dmd, 0, sizeof(struct cxd2880_tnrdmd));
1926 tnr_dmd->io = io;
1927 tnr_dmd->create_param = *create_param;
1929 tnr_dmd->diver_mode = CXD2880_TNRDMD_DIVERMODE_SINGLE;
1930 tnr_dmd->diver_sub = NULL;
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);
1940 return 0;
1943 int 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)
1952 struct cxd2880_tnrdmd_create_param *main_param, *sub_param;
1954 if (!tnr_dmd_main || !io_main || !tnr_dmd_sub || !io_sub ||
1955 !create_param)
1956 return -EINVAL;
1958 memset(tnr_dmd_main, 0, sizeof(struct cxd2880_tnrdmd));
1959 memset(tnr_dmd_sub, 0, sizeof(struct cxd2880_tnrdmd));
1961 main_param = &tnr_dmd_main->create_param;
1962 sub_param = &tnr_dmd_sub->create_param;
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;
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;
1977 tnr_dmd_sub->io = io_sub;
1978 tnr_dmd_sub->diver_mode = CXD2880_TNRDMD_DIVERMODE_SUB;
1979 tnr_dmd_sub->diver_sub = NULL;
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;
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;
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;
2003 return 0;
2006 int cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd)
2008 int ret;
2010 if (!tnr_dmd || tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2011 return -EINVAL;
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);
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);
2033 ret = cxd2880_tnrdmd_chip_id(tnr_dmd, &tnr_dmd->chip_id);
2034 if (ret)
2035 return ret;
2037 if (!CXD2880_TNRDMD_CHIP_ID_VALID(tnr_dmd->chip_id))
2038 return -ENOTTY;
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;
2047 if (!CXD2880_TNRDMD_CHIP_ID_VALID(tnr_dmd->diver_sub->chip_id))
2048 return -ENOTTY;
2051 ret = p_init1(tnr_dmd);
2052 if (ret)
2053 return ret;
2055 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
2056 ret = p_init1(tnr_dmd->diver_sub);
2057 if (ret)
2058 return ret;
2061 usleep_range(1000, 2000);
2063 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
2064 ret = p_init2(tnr_dmd->diver_sub);
2065 if (ret)
2066 return ret;
2069 ret = p_init2(tnr_dmd);
2070 if (ret)
2071 return ret;
2073 usleep_range(5000, 6000);
2075 ret = p_init3(tnr_dmd);
2076 if (ret)
2077 return ret;
2079 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
2080 ret = p_init3(tnr_dmd->diver_sub);
2081 if (ret)
2082 return ret;
2085 ret = rf_init1(tnr_dmd);
2086 if (ret)
2087 return ret;
2089 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
2090 ret = rf_init1(tnr_dmd->diver_sub);
2092 return ret;
2095 int cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd)
2097 u8 cpu_task_completed;
2098 int ret;
2100 if (!tnr_dmd)
2101 return -EINVAL;
2103 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2104 return -EINVAL;
2106 ret = cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
2107 &cpu_task_completed);
2108 if (ret)
2109 return ret;
2111 if (!cpu_task_completed)
2112 return -EINVAL;
2114 ret = rf_init2(tnr_dmd);
2115 if (ret)
2116 return ret;
2118 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
2119 ret = rf_init2(tnr_dmd->diver_sub);
2120 if (ret)
2121 return ret;
2124 ret = load_cfg_mem(tnr_dmd);
2125 if (ret)
2126 return ret;
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;
2134 tnr_dmd->state = CXD2880_TNRDMD_STATE_SLEEP;
2136 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
2137 tnr_dmd->diver_sub->state = CXD2880_TNRDMD_STATE_SLEEP;
2139 return ret;
2142 int cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd
2143 *tnr_dmd,
2144 u8 *task_completed)
2146 u16 cpu_status = 0;
2147 int ret;
2149 if (!tnr_dmd || !task_completed)
2150 return -EINVAL;
2152 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2153 return -EINVAL;
2155 ret = cxd2880_tnrdmd_mon_internal_cpu_status(tnr_dmd, &cpu_status);
2156 if (ret)
2157 return ret;
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;
2165 return ret;
2167 if (cpu_status != 0) {
2168 *task_completed = 0;
2169 return ret;
2172 ret = cxd2880_tnrdmd_mon_internal_cpu_status_sub(tnr_dmd, &cpu_status);
2173 if (ret)
2174 return ret;
2176 if (cpu_status == 0)
2177 *task_completed = 1;
2178 else
2179 *task_completed = 0;
2181 return ret;
2184 int 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)
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;
2198 if (!tnr_dmd)
2199 return -EINVAL;
2201 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2202 return -EINVAL;
2204 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
2205 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
2206 return -EINVAL;
2208 if (frequency_khz < 4000)
2209 return -EINVAL;
2211 ret = cxd2880_tnrdmd_sleep(tnr_dmd);
2212 if (ret)
2213 return ret;
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;
2222 ret = tnr_dmd->io->read_regs(tnr_dmd->io,
2223 CXD2880_IO_TGT_SYS,
2224 0x2b,
2225 &data,
2227 if (ret)
2228 return ret;
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;
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;
2244 break;
2246 case CXD2880_DTV_SYS_DVBT2:
2247 if (data == 0x01) {
2248 ret = t_power_x(tnr_dmd, 0);
2249 if (ret)
2250 return ret;
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;
2259 break;
2261 default:
2262 return -EINVAL;
2265 ret = spll_reset(tnr_dmd, new_clk_mode);
2266 if (ret)
2267 return ret;
2269 tnr_dmd->clk_mode = new_clk_mode;
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;
2276 tnr_dmd->diver_sub->clk_mode = new_clk_mode;
2279 ret = load_cfg_mem(tnr_dmd);
2280 if (ret)
2281 return ret;
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;
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;
2299 if (tnr_dmd->create_param.xtal_share_type ==
2300 CXD2880_TNRDMD_XTAL_SHARE_SLAVE)
2301 shift_frequency_khz *= -1;
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;
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;
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;
2339 usleep_range(10000, 11000);
2341 ret =
2342 cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
2343 &cpu_task_completed);
2344 if (ret)
2345 return ret;
2347 if (!cpu_task_completed)
2348 return -EINVAL;
2350 ret =
2351 x_tune2(tnr_dmd, bandwidth, tnr_dmd->clk_mode,
2352 shift_frequency_khz);
2353 if (ret)
2354 return ret;
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;
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;
2370 if (tnr_dmd->pid_ftr_cfg_en)
2371 pid_ftr_cfg = &tnr_dmd->pid_ftr_cfg;
2372 else
2373 pid_ftr_cfg = NULL;
2375 ret = pid_ftr_setting(tnr_dmd, pid_ftr_cfg);
2378 return ret;
2381 int cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd
2382 *tnr_dmd,
2383 enum cxd2880_dtv_sys sys,
2384 u8 en_fef_intmtnt_ctrl)
2386 int ret;
2388 if (!tnr_dmd)
2389 return -EINVAL;
2391 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2392 return -EINVAL;
2394 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
2395 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
2396 return -EINVAL;
2398 ret = x_tune3(tnr_dmd, sys, en_fef_intmtnt_ctrl);
2399 if (ret)
2400 return ret;
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;
2411 return cxd2880_tnrdmd_set_ts_output(tnr_dmd, 1);
2414 int cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd)
2416 int ret;
2418 if (!tnr_dmd)
2419 return -EINVAL;
2421 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2422 return -EINVAL;
2424 if (tnr_dmd->state == CXD2880_TNRDMD_STATE_SLEEP)
2425 return 0;
2427 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
2428 return -EINVAL;
2430 ret = cxd2880_tnrdmd_set_ts_output(tnr_dmd, 0);
2431 if (ret)
2432 return ret;
2434 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
2435 ret = x_sleep1(tnr_dmd);
2436 if (ret)
2437 return ret;
2440 ret = x_sleep2(tnr_dmd);
2441 if (ret)
2442 return ret;
2444 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
2445 ret = x_sleep2(tnr_dmd->diver_sub);
2446 if (ret)
2447 return ret;
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;
2457 case CXD2880_DTV_SYS_DVBT2:
2458 ret = cxd2880_tnrdmd_dvbt2_sleep_setting(tnr_dmd);
2459 if (ret)
2460 return ret;
2461 break;
2463 default:
2464 return -EINVAL;
2467 ret = x_sleep3(tnr_dmd);
2468 if (ret)
2469 return ret;
2471 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
2472 ret = x_sleep3(tnr_dmd->diver_sub);
2473 if (ret)
2474 return ret;
2477 ret = x_sleep4(tnr_dmd);
2478 if (ret)
2479 return ret;
2481 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
2482 ret = x_sleep4(tnr_dmd->diver_sub);
2483 if (ret)
2484 return ret;
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;
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;
2499 return 0;
2502 int cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
2503 enum cxd2880_tnrdmd_cfg_id id,
2504 int value)
2506 int ret = 0;
2507 u8 data[2] = { 0 };
2508 u8 need_sub_setting = 0;
2510 if (!tnr_dmd)
2511 return -EINVAL;
2513 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
2514 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
2515 return -EINVAL;
2517 switch (id) {
2518 case CXD2880_TNRDMD_CFG_OUTPUT_SEL_MSB:
2519 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2520 return -EINVAL;
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;
2532 case CXD2880_TNRDMD_CFG_TSVALID_ACTIVE_HI:
2533 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2534 return -EINVAL;
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;
2546 case CXD2880_TNRDMD_CFG_TSSYNC_ACTIVE_HI:
2547 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2548 return -EINVAL;
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;
2560 case CXD2880_TNRDMD_CFG_TSERR_ACTIVE_HI:
2561 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2562 return -EINVAL;
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;
2574 case CXD2880_TNRDMD_CFG_LATCH_ON_POSEDGE:
2575 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2576 return -EINVAL;
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;
2588 case CXD2880_TNRDMD_CFG_TSCLK_CONT:
2589 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2590 return -EINVAL;
2592 tnr_dmd->srl_ts_clk_mod_cnts = value ? 0x01 : 0x00;
2593 break;
2595 case CXD2880_TNRDMD_CFG_TSCLK_MASK:
2596 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2597 return -EINVAL;
2599 if (value < 0 || value > 0x1f)
2600 return -EINVAL;
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;
2611 case CXD2880_TNRDMD_CFG_TSVALID_MASK:
2612 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2613 return -EINVAL;
2615 if (value < 0 || value > 0x1f)
2616 return -EINVAL;
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;
2627 case CXD2880_TNRDMD_CFG_TSERR_MASK:
2628 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2629 return -EINVAL;
2631 if (value < 0 || value > 0x1f)
2632 return -EINVAL;
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;
2643 case CXD2880_TNRDMD_CFG_TSERR_VALID_DIS:
2644 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2645 return -EINVAL;
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;
2657 case CXD2880_TNRDMD_CFG_TSPIN_CURRENT:
2658 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2659 return -EINVAL;
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;
2670 case CXD2880_TNRDMD_CFG_TSPIN_PULLUP_MANUAL:
2671 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2672 return -EINVAL;
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;
2684 case CXD2880_TNRDMD_CFG_TSPIN_PULLUP:
2685 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2686 return -EINVAL;
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;
2697 case CXD2880_TNRDMD_CFG_TSCLK_FREQ:
2698 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2699 return -EINVAL;
2701 if (value < 0 || value > 1)
2702 return -EINVAL;
2704 tnr_dmd->srl_ts_clk_frq =
2705 (enum cxd2880_tnrdmd_serial_ts_clk)value;
2706 break;
2708 case CXD2880_TNRDMD_CFG_TSBYTECLK_MANUAL:
2709 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2710 return -EINVAL;
2712 if (value < 0 || value > 0xff)
2713 return -EINVAL;
2715 tnr_dmd->ts_byte_clk_manual_setting = value;
2717 break;
2719 case CXD2880_TNRDMD_CFG_TS_PACKET_GAP:
2720 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2721 return -EINVAL;
2723 if (value < 0 || value > 7)
2724 return -EINVAL;
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;
2734 break;
2736 case CXD2880_TNRDMD_CFG_TS_BACKWARDS_COMPATIBLE:
2737 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2738 return -EINVAL;
2740 tnr_dmd->is_ts_backwards_compatible_mode = value ? 1 : 0;
2742 break;
2744 case CXD2880_TNRDMD_CFG_PWM_VALUE:
2745 if (value < 0 || value > 0x1000)
2746 return -EINVAL;
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;
2757 data[0] = (value >> 8) & 0x1f;
2758 data[1] = value & 0xff;
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;
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;
2776 break;
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;
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;
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;
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;
2826 case CXD2880_TNRDMD_CFG_CABLE_INPUT:
2827 tnr_dmd->is_cable_input = value ? 1 : 0;
2828 break;
2830 case CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_BASE:
2831 tnr_dmd->en_fef_intmtnt_base = value ? 1 : 0;
2832 break;
2834 case CXD2880_TNRDMD_CFG_DVBT2_FEF_INTERMITTENT_LITE:
2835 tnr_dmd->en_fef_intmtnt_lite = value ? 1 : 0;
2836 break;
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;
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;
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;
2895 case CXD2880_TNRDMD_CFG_BLINDTUNE_DVBT2_FIRST:
2896 tnr_dmd->blind_tune_dvbt2_first = value ? 1 : 0;
2897 break;
2899 case CXD2880_TNRDMD_CFG_DVBT_BERN_PERIOD:
2900 if (value < 0 || value > 31)
2901 return -EINVAL;
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;
2912 case CXD2880_TNRDMD_CFG_DVBT_VBER_PERIOD:
2913 if (value < 0 || value > 7)
2914 return -EINVAL;
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;
2925 case CXD2880_TNRDMD_CFG_DVBT2_BBER_MES:
2926 if (value < 0 || value > 15)
2927 return -EINVAL;
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;
2938 case CXD2880_TNRDMD_CFG_DVBT2_LBER_MES:
2939 if (value < 0 || value > 15)
2940 return -EINVAL;
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;
2951 case CXD2880_TNRDMD_CFG_DVBT_PER_MES:
2952 if (value < 0 || value > 15)
2953 return -EINVAL;
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;
2964 case CXD2880_TNRDMD_CFG_DVBT2_PER_MES:
2965 if (value < 0 || value > 15)
2966 return -EINVAL;
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;
2977 default:
2978 return -EINVAL;
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);
2985 return ret;
2988 int 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)
2994 int ret;
2996 if (!tnr_dmd)
2997 return -EINVAL;
2999 if (id > 2)
3000 return -EINVAL;
3002 if (mode > CXD2880_TNRDMD_GPIO_MODE_EEW)
3003 return -EINVAL;
3005 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3006 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3007 return -EINVAL;
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;
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;
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;
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);
3039 int 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)
3045 if (!tnr_dmd)
3046 return -EINVAL;
3048 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
3049 return -EINVAL;
3051 return cxd2880_tnrdmd_gpio_set_cfg(tnr_dmd->diver_sub, id, en, mode,
3052 open_drain, invert);
3055 int cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd,
3056 u8 id, u8 *value)
3058 u8 data = 0;
3059 int ret;
3061 if (!tnr_dmd || !value)
3062 return -EINVAL;
3064 if (id > 2)
3065 return -EINVAL;
3067 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3068 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3069 return -EINVAL;
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;
3082 *value = (data >> id) & 0x01;
3084 return 0;
3087 int cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd,
3088 u8 id, u8 *value)
3090 if (!tnr_dmd)
3091 return -EINVAL;
3093 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
3094 return -EINVAL;
3096 return cxd2880_tnrdmd_gpio_read(tnr_dmd->diver_sub, id, value);
3099 int cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd,
3100 u8 id, u8 value)
3102 if (!tnr_dmd)
3103 return -EINVAL;
3105 if (id > 2)
3106 return -EINVAL;
3108 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3109 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3110 return -EINVAL;
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);
3119 int cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd,
3120 u8 id, u8 value)
3122 if (!tnr_dmd)
3123 return -EINVAL;
3125 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
3126 return -EINVAL;
3128 return cxd2880_tnrdmd_gpio_write(tnr_dmd->diver_sub, id, value);
3131 int cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd,
3132 u16 *value)
3134 int ret;
3135 u8 data[2] = { 0 };
3137 if (!tnr_dmd || !value)
3138 return -EINVAL;
3140 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3141 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3142 return -EINVAL;
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;
3155 *value = (data[0] << 8) | data[1];
3157 return 0;
3160 int cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd,
3161 u16 value)
3163 int ret;
3164 u8 data[2] = { 0 };
3166 if (!tnr_dmd)
3167 return -EINVAL;
3169 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3170 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3171 return -EINVAL;
3173 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3174 CXD2880_IO_TGT_SYS,
3175 0x00, 0x00);
3176 if (ret)
3177 return ret;
3179 data[0] = (value >> 8) & 0xff;
3180 data[1] = value & 0xff;
3182 return tnr_dmd->io->write_regs(tnr_dmd->io,
3183 CXD2880_IO_TGT_SYS,
3184 0x3c, data, 2);
3187 int cxd2880_tnrdmd_ts_buf_clear(struct cxd2880_tnrdmd *tnr_dmd,
3188 u8 clear_overflow_flag,
3189 u8 clear_underflow_flag,
3190 u8 clear_buf)
3192 int ret;
3193 u8 data[2] = { 0 };
3195 if (!tnr_dmd)
3196 return -EINVAL;
3198 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
3199 return -EINVAL;
3201 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3202 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3203 return -EINVAL;
3205 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3206 CXD2880_IO_TGT_DMD,
3207 0x00, 0x00);
3208 if (ret)
3209 return ret;
3211 data[0] = clear_overflow_flag ? 0x02 : 0x00;
3212 data[0] |= clear_underflow_flag ? 0x01 : 0x00;
3213 data[1] = clear_buf ? 0x01 : 0x00;
3215 return tnr_dmd->io->write_regs(tnr_dmd->io,
3216 CXD2880_IO_TGT_DMD,
3217 0x9f, data, 2);
3220 int cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd,
3221 enum cxd2880_tnrdmd_chip_id *chip_id)
3223 int ret;
3224 u8 data = 0;
3226 if (!tnr_dmd || !chip_id)
3227 return -EINVAL;
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;
3240 *chip_id = (enum cxd2880_tnrdmd_chip_id)data;
3242 return 0;
3245 int 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)
3251 int ret;
3253 if (!tnr_dmd)
3254 return -EINVAL;
3256 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3257 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3258 return -EINVAL;
3260 ret = tnr_dmd->io->write_reg(tnr_dmd->io, tgt, 0x00, bank);
3261 if (ret)
3262 return ret;
3264 ret = cxd2880_io_set_reg_bits(tnr_dmd->io,
3265 tgt, address, value, bit_mask);
3266 if (ret)
3267 return ret;
3269 return set_cfg_mem(tnr_dmd, tgt, bank, address, value, bit_mask);
3272 int cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd,
3273 enum cxd2880_dtv_sys sys,
3274 u8 scan_mode_end)
3276 if (!tnr_dmd)
3277 return -EINVAL;
3279 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3280 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3281 return -EINVAL;
3283 tnr_dmd->scan_mode = scan_mode_end;
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;
3292 int cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd,
3293 struct cxd2880_tnrdmd_pid_ftr_cfg
3294 *pid_ftr_cfg)
3296 if (!tnr_dmd)
3297 return -EINVAL;
3299 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
3300 return -EINVAL;
3302 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3303 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3304 return -EINVAL;
3306 if (tnr_dmd->create_param.ts_output_if == CXD2880_TNRDMD_TSOUT_IF_TS)
3307 return -ENOTTY;
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;
3316 if (tnr_dmd->state == CXD2880_TNRDMD_STATE_ACTIVE)
3317 return pid_ftr_setting(tnr_dmd, pid_ftr_cfg);
3318 else
3319 return 0;
3322 int cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd
3323 *tnr_dmd,
3324 int (*rf_lvl_cmpstn)
3325 (struct cxd2880_tnrdmd *,
3326 int *))
3328 if (!tnr_dmd)
3329 return -EINVAL;
3331 tnr_dmd->rf_lvl_cmpstn = rf_lvl_cmpstn;
3333 return 0;
3336 int cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd
3337 *tnr_dmd,
3338 int (*rf_lvl_cmpstn)
3339 (struct cxd2880_tnrdmd *,
3340 int *))
3342 if (!tnr_dmd)
3343 return -EINVAL;
3345 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
3346 return -EINVAL;
3348 return cxd2880_tnrdmd_set_rf_lvl_cmpstn(tnr_dmd->diver_sub,
3349 rf_lvl_cmpstn);
3352 int 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)
3358 if (!tnr_dmd)
3359 return -EINVAL;
3361 tnr_dmd->lna_thrs_tbl_air = tbl_air;
3362 tnr_dmd->lna_thrs_tbl_cable = tbl_cable;
3364 return 0;
3367 int 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)
3374 if (!tnr_dmd)
3375 return -EINVAL;
3377 if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
3378 return -EINVAL;
3380 return cxd2880_tnrdmd_set_lna_thrs(tnr_dmd->diver_sub,
3381 tbl_air, tbl_cable);
3384 int cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd
3385 *tnr_dmd, u8 en, u8 value)
3387 int ret;
3389 if (!tnr_dmd)
3390 return -EINVAL;
3392 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
3393 return -EINVAL;
3395 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
3396 return -EINVAL;
3398 if (tnr_dmd->create_param.ts_output_if != CXD2880_TNRDMD_TSOUT_IF_TS)
3399 return -ENOTTY;
3401 ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3402 CXD2880_IO_TGT_SYS,
3403 0x00, 0x00);
3404 if (ret)
3405 return ret;
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;
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;
3425 ret = load_cfg_mem(tnr_dmd);
3428 return ret;
3431 int cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd,
3432 u8 en)
3434 int ret;
3436 if (!tnr_dmd)
3437 return -EINVAL;
3439 if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
3440 return -EINVAL;
3442 if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3443 tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3444 return -EINVAL;
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;
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;
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;
3477 break;
3479 case CXD2880_TNRDMD_TSOUT_IF_SPI:
3480 break;
3482 case CXD2880_TNRDMD_TSOUT_IF_SDIO:
3483 break;
3485 default:
3486 return -EINVAL;
3489 return 0;
3492 int slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd)
3494 u8 data;
3495 int ret;
3497 if (!tnr_dmd)
3498 return -EINVAL;
3500 switch (tnr_dmd->create_param.ts_output_if) {
3501 case CXD2880_TNRDMD_TSOUT_IF_SPI:
3502 case CXD2880_TNRDMD_TSOUT_IF_SDIO:
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;
3510 break;
3511 case CXD2880_TNRDMD_TSOUT_IF_TS:
3512 default:
3513 break;
3516 return tnr_dmd->io->write_reg(tnr_dmd->io,
3517 CXD2880_IO_TGT_DMD,
3518 0x01, 0x01);