2 * cxd2880_tnrdmd_dvbt.c
3 * Sony CXD2880 DVB-T2/T tuner + demodulator driver
4 * control functions for DVB-T
6 * Copyright (C) 2016, 2017 Sony Semiconductor Solutions Corporation
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; version 2 of the License.
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
15 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
16 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
17 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
18 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, see <http://www.gnu.org/licenses/>.
27 #include "cxd2880_tnrdmd_dvbt.h"
28 #include "cxd2880_tnrdmd_dvbt_mon.h"
30 static enum cxd2880_ret
x_tune_dvbt_demod_setting(struct cxd2880_tnrdmd
32 enum cxd2880_dtv_bandwidth
34 enum cxd2880_tnrdmd_clockmode
38 return CXD2880_RESULT_ERROR_ARG
;
40 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
41 CXD2880_IO_TGT_SYS
, 0x00,
42 0x00) != CXD2880_RESULT_OK
)
43 return CXD2880_RESULT_ERROR_IO
;
45 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
46 CXD2880_IO_TGT_SYS
, 0x31,
47 0x01) != CXD2880_RESULT_OK
)
48 return CXD2880_RESULT_ERROR_IO
;
51 u8 data_a
[2] = { 0x52, 0x49 };
52 u8 data_b
[2] = { 0x5D, 0x55 };
53 u8 data_c
[2] = { 0x60, 0x00 };
56 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
57 CXD2880_IO_TGT_DMD
, 0x00,
58 0x04) != CXD2880_RESULT_OK
)
59 return CXD2880_RESULT_ERROR_IO
;
62 case CXD2880_TNRDMD_CLOCKMODE_A
:
65 case CXD2880_TNRDMD_CLOCKMODE_B
:
68 case CXD2880_TNRDMD_CLOCKMODE_C
:
72 return CXD2880_RESULT_ERROR_SW_STATE
;
75 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
76 CXD2880_IO_TGT_DMD
, 0x65, data
,
77 2) != CXD2880_RESULT_OK
)
78 return CXD2880_RESULT_ERROR_IO
;
81 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
82 CXD2880_IO_TGT_DMD
, 0x5D,
83 0x07) != CXD2880_RESULT_OK
)
84 return CXD2880_RESULT_ERROR_IO
;
86 if (tnr_dmd
->diver_mode
!= CXD2880_TNRDMD_DIVERMODE_SUB
) {
87 u8 data
[2] = { 0x01, 0x01 };
89 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
90 CXD2880_IO_TGT_DMD
, 0x00,
91 0x00) != CXD2880_RESULT_OK
)
92 return CXD2880_RESULT_ERROR_IO
;
94 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
95 CXD2880_IO_TGT_DMD
, 0xCE, data
,
96 2) != CXD2880_RESULT_OK
)
97 return CXD2880_RESULT_ERROR_IO
;
100 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
101 CXD2880_IO_TGT_DMD
, 0x00,
102 0x04) != CXD2880_RESULT_OK
)
103 return CXD2880_RESULT_ERROR_IO
;
105 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
106 CXD2880_IO_TGT_DMD
, 0x5C,
107 0xFB) != CXD2880_RESULT_OK
)
108 return CXD2880_RESULT_ERROR_IO
;
110 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
111 CXD2880_IO_TGT_DMD
, 0x00,
112 0x10) != CXD2880_RESULT_OK
)
113 return CXD2880_RESULT_ERROR_IO
;
115 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
116 CXD2880_IO_TGT_DMD
, 0xA4,
117 0x03) != CXD2880_RESULT_OK
)
118 return CXD2880_RESULT_ERROR_IO
;
120 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
121 CXD2880_IO_TGT_DMD
, 0x00,
122 0x14) != CXD2880_RESULT_OK
)
123 return CXD2880_RESULT_ERROR_IO
;
125 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
126 CXD2880_IO_TGT_DMD
, 0xB0,
127 0x00) != CXD2880_RESULT_OK
)
128 return CXD2880_RESULT_ERROR_IO
;
130 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
131 CXD2880_IO_TGT_DMD
, 0x00,
132 0x25) != CXD2880_RESULT_OK
)
133 return CXD2880_RESULT_ERROR_IO
;
136 u8 data
[2] = { 0x01, 0xF0 };
138 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
139 CXD2880_IO_TGT_DMD
, 0xF0, data
,
140 2) != CXD2880_RESULT_OK
)
141 return CXD2880_RESULT_ERROR_IO
;
144 if ((tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_MAIN
) ||
145 (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_SUB
)) {
146 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
147 CXD2880_IO_TGT_DMD
, 0x00,
148 0x12) != CXD2880_RESULT_OK
)
149 return CXD2880_RESULT_ERROR_IO
;
151 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
152 CXD2880_IO_TGT_DMD
, 0x44,
153 0x00) != CXD2880_RESULT_OK
)
154 return CXD2880_RESULT_ERROR_IO
;
157 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_SUB
) {
158 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
159 CXD2880_IO_TGT_DMD
, 0x00,
160 0x11) != CXD2880_RESULT_OK
)
161 return CXD2880_RESULT_ERROR_IO
;
163 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
164 CXD2880_IO_TGT_DMD
, 0x87,
165 0xD2) != CXD2880_RESULT_OK
)
166 return CXD2880_RESULT_ERROR_IO
;
169 if (tnr_dmd
->diver_mode
!= CXD2880_TNRDMD_DIVERMODE_SUB
) {
170 u8 data_a
[3] = { 0x73, 0xCA, 0x49 };
171 u8 data_b
[3] = { 0xC8, 0x13, 0xAA };
172 u8 data_c
[3] = { 0xDC, 0x6C, 0x00 };
175 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
176 CXD2880_IO_TGT_DMD
, 0x00,
177 0x04) != CXD2880_RESULT_OK
)
178 return CXD2880_RESULT_ERROR_IO
;
181 case CXD2880_TNRDMD_CLOCKMODE_A
:
184 case CXD2880_TNRDMD_CLOCKMODE_B
:
187 case CXD2880_TNRDMD_CLOCKMODE_C
:
191 return CXD2880_RESULT_ERROR_SW_STATE
;
194 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
195 CXD2880_IO_TGT_DMD
, 0x68, data
,
196 3) != CXD2880_RESULT_OK
)
197 return CXD2880_RESULT_ERROR_IO
;
200 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
201 CXD2880_IO_TGT_DMD
, 0x00,
202 0x04) != CXD2880_RESULT_OK
)
203 return CXD2880_RESULT_ERROR_IO
;
206 case CXD2880_DTV_BW_8_MHZ
:
209 u8 data_ac
[5] = { 0x15, 0x00, 0x00, 0x00,
212 u8 data_b
[5] = { 0x14, 0x6A, 0xAA, 0xAA,
218 case CXD2880_TNRDMD_CLOCKMODE_A
:
219 case CXD2880_TNRDMD_CLOCKMODE_C
:
222 case CXD2880_TNRDMD_CLOCKMODE_B
:
226 return CXD2880_RESULT_ERROR_SW_STATE
;
229 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
230 CXD2880_IO_TGT_DMD
, 0x60,
232 5) != CXD2880_RESULT_OK
)
233 return CXD2880_RESULT_ERROR_IO
;
236 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
237 CXD2880_IO_TGT_DMD
, 0x4A,
238 0x00) != CXD2880_RESULT_OK
)
239 return CXD2880_RESULT_ERROR_IO
;
242 u8 data_a
[2] = { 0x01, 0x28 };
243 u8 data_b
[2] = { 0x11, 0x44 };
244 u8 data_c
[2] = { 0x15, 0x28 };
248 case CXD2880_TNRDMD_CLOCKMODE_A
:
251 case CXD2880_TNRDMD_CLOCKMODE_B
:
254 case CXD2880_TNRDMD_CLOCKMODE_C
:
258 return CXD2880_RESULT_ERROR_SW_STATE
;
261 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
262 CXD2880_IO_TGT_DMD
, 0x7D,
264 2) != CXD2880_RESULT_OK
)
265 return CXD2880_RESULT_ERROR_IO
;
272 case CXD2880_TNRDMD_CLOCKMODE_A
:
273 case CXD2880_TNRDMD_CLOCKMODE_B
:
276 case CXD2880_TNRDMD_CLOCKMODE_C
:
280 return CXD2880_RESULT_ERROR_SW_STATE
;
283 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
284 CXD2880_IO_TGT_DMD
, 0x71,
285 data
) != CXD2880_RESULT_OK
)
286 return CXD2880_RESULT_ERROR_IO
;
289 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_MAIN
) {
290 u8 data_a
[5] = { 0x30, 0x00, 0x00, 0x90,
293 u8 data_b
[5] = { 0x36, 0x71, 0x00, 0xA3,
296 u8 data_c
[5] = { 0x38, 0x00, 0x00, 0xA8,
302 case CXD2880_TNRDMD_CLOCKMODE_A
:
305 case CXD2880_TNRDMD_CLOCKMODE_B
:
308 case CXD2880_TNRDMD_CLOCKMODE_C
:
312 return CXD2880_RESULT_ERROR_SW_STATE
;
315 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
316 CXD2880_IO_TGT_DMD
, 0x4B,
318 2) != CXD2880_RESULT_OK
)
319 return CXD2880_RESULT_ERROR_IO
;
321 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
322 CXD2880_IO_TGT_DMD
, 0x51,
324 3) != CXD2880_RESULT_OK
)
325 return CXD2880_RESULT_ERROR_IO
;
329 u8 data
[4] = { 0xB3, 0x00, 0x01, 0x02 };
331 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
332 CXD2880_IO_TGT_DMD
, 0x72,
334 2) != CXD2880_RESULT_OK
)
335 return CXD2880_RESULT_ERROR_IO
;
337 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
338 CXD2880_IO_TGT_DMD
, 0x6B,
340 2) != CXD2880_RESULT_OK
)
341 return CXD2880_RESULT_ERROR_IO
;
345 case CXD2880_DTV_BW_7_MHZ
:
348 u8 data_ac
[5] = { 0x18, 0x00, 0x00, 0x00,
351 u8 data_b
[5] = { 0x17, 0x55, 0x55, 0x55,
357 case CXD2880_TNRDMD_CLOCKMODE_A
:
358 case CXD2880_TNRDMD_CLOCKMODE_C
:
361 case CXD2880_TNRDMD_CLOCKMODE_B
:
365 return CXD2880_RESULT_ERROR_SW_STATE
;
368 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
369 CXD2880_IO_TGT_DMD
, 0x60,
371 5) != CXD2880_RESULT_OK
)
372 return CXD2880_RESULT_ERROR_IO
;
375 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
376 CXD2880_IO_TGT_DMD
, 0x4A,
377 0x02) != CXD2880_RESULT_OK
)
378 return CXD2880_RESULT_ERROR_IO
;
381 u8 data_a
[2] = { 0x12, 0x4C };
382 u8 data_b
[2] = { 0x1F, 0x15 };
383 u8 data_c
[2] = { 0x1F, 0xF8 };
387 case CXD2880_TNRDMD_CLOCKMODE_A
:
390 case CXD2880_TNRDMD_CLOCKMODE_B
:
393 case CXD2880_TNRDMD_CLOCKMODE_C
:
397 return CXD2880_RESULT_ERROR_SW_STATE
;
400 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
401 CXD2880_IO_TGT_DMD
, 0x7D,
403 2) != CXD2880_RESULT_OK
)
404 return CXD2880_RESULT_ERROR_IO
;
411 case CXD2880_TNRDMD_CLOCKMODE_A
:
412 case CXD2880_TNRDMD_CLOCKMODE_B
:
415 case CXD2880_TNRDMD_CLOCKMODE_C
:
419 return CXD2880_RESULT_ERROR_SW_STATE
;
422 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
423 CXD2880_IO_TGT_DMD
, 0x71,
424 data
) != CXD2880_RESULT_OK
)
425 return CXD2880_RESULT_ERROR_IO
;
428 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_MAIN
) {
429 u8 data_a
[5] = { 0x36, 0xDB, 0x00, 0xA4,
432 u8 data_b
[5] = { 0x3E, 0x38, 0x00, 0xBA,
435 u8 data_c
[5] = { 0x40, 0x00, 0x00, 0xC0,
441 case CXD2880_TNRDMD_CLOCKMODE_A
:
444 case CXD2880_TNRDMD_CLOCKMODE_B
:
447 case CXD2880_TNRDMD_CLOCKMODE_C
:
451 return CXD2880_RESULT_ERROR_SW_STATE
;
454 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
455 CXD2880_IO_TGT_DMD
, 0x4B,
457 2) != CXD2880_RESULT_OK
)
458 return CXD2880_RESULT_ERROR_IO
;
460 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
461 CXD2880_IO_TGT_DMD
, 0x51,
463 3) != CXD2880_RESULT_OK
)
464 return CXD2880_RESULT_ERROR_IO
;
468 u8 data
[4] = { 0xB8, 0x00, 0x00, 0x03 };
470 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
471 CXD2880_IO_TGT_DMD
, 0x72,
473 2) != CXD2880_RESULT_OK
)
474 return CXD2880_RESULT_ERROR_IO
;
476 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
477 CXD2880_IO_TGT_DMD
, 0x6B,
479 2) != CXD2880_RESULT_OK
)
480 return CXD2880_RESULT_ERROR_IO
;
484 case CXD2880_DTV_BW_6_MHZ
:
487 u8 data_ac
[5] = { 0x1C, 0x00, 0x00, 0x00,
490 u8 data_b
[5] = { 0x1B, 0x38, 0xE3, 0x8E,
496 case CXD2880_TNRDMD_CLOCKMODE_A
:
497 case CXD2880_TNRDMD_CLOCKMODE_C
:
500 case CXD2880_TNRDMD_CLOCKMODE_B
:
504 return CXD2880_RESULT_ERROR_SW_STATE
;
507 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
508 CXD2880_IO_TGT_DMD
, 0x60,
510 5) != CXD2880_RESULT_OK
)
511 return CXD2880_RESULT_ERROR_IO
;
514 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
515 CXD2880_IO_TGT_DMD
, 0x4A,
516 0x04) != CXD2880_RESULT_OK
)
517 return CXD2880_RESULT_ERROR_IO
;
520 u8 data_a
[2] = { 0x1F, 0xF8 };
521 u8 data_b
[2] = { 0x24, 0x43 };
522 u8 data_c
[2] = { 0x25, 0x4C };
526 case CXD2880_TNRDMD_CLOCKMODE_A
:
529 case CXD2880_TNRDMD_CLOCKMODE_B
:
532 case CXD2880_TNRDMD_CLOCKMODE_C
:
536 return CXD2880_RESULT_ERROR_SW_STATE
;
539 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
540 CXD2880_IO_TGT_DMD
, 0x7D,
542 2) != CXD2880_RESULT_OK
)
543 return CXD2880_RESULT_ERROR_IO
;
550 case CXD2880_TNRDMD_CLOCKMODE_A
:
551 case CXD2880_TNRDMD_CLOCKMODE_C
:
554 case CXD2880_TNRDMD_CLOCKMODE_B
:
558 return CXD2880_RESULT_ERROR_SW_STATE
;
561 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
562 CXD2880_IO_TGT_DMD
, 0x71,
563 data
) != CXD2880_RESULT_OK
)
564 return CXD2880_RESULT_ERROR_IO
;
567 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_MAIN
) {
568 u8 data_a
[5] = { 0x40, 0x00, 0x00, 0xC0,
571 u8 data_b
[5] = { 0x48, 0x97, 0x00, 0xD9,
574 u8 data_c
[5] = { 0x4A, 0xAA, 0x00, 0xDF,
580 case CXD2880_TNRDMD_CLOCKMODE_A
:
583 case CXD2880_TNRDMD_CLOCKMODE_B
:
586 case CXD2880_TNRDMD_CLOCKMODE_C
:
590 return CXD2880_RESULT_ERROR_SW_STATE
;
593 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
594 CXD2880_IO_TGT_DMD
, 0x4B,
596 2) != CXD2880_RESULT_OK
)
597 return CXD2880_RESULT_ERROR_IO
;
599 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
600 CXD2880_IO_TGT_DMD
, 0x51,
602 3) != CXD2880_RESULT_OK
)
603 return CXD2880_RESULT_ERROR_IO
;
607 u8 data
[4] = { 0xBE, 0xAB, 0x00, 0x03 };
609 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
610 CXD2880_IO_TGT_DMD
, 0x72,
612 2) != CXD2880_RESULT_OK
)
613 return CXD2880_RESULT_ERROR_IO
;
615 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
616 CXD2880_IO_TGT_DMD
, 0x6B,
618 2) != CXD2880_RESULT_OK
)
619 return CXD2880_RESULT_ERROR_IO
;
623 case CXD2880_DTV_BW_5_MHZ
:
626 u8 data_ac
[5] = { 0x21, 0x99, 0x99, 0x99,
629 u8 data_b
[5] = { 0x20, 0xAA, 0xAA, 0xAA,
635 case CXD2880_TNRDMD_CLOCKMODE_A
:
636 case CXD2880_TNRDMD_CLOCKMODE_C
:
639 case CXD2880_TNRDMD_CLOCKMODE_B
:
643 return CXD2880_RESULT_ERROR_SW_STATE
;
646 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
647 CXD2880_IO_TGT_DMD
, 0x60,
649 5) != CXD2880_RESULT_OK
)
650 return CXD2880_RESULT_ERROR_IO
;
653 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
654 CXD2880_IO_TGT_DMD
, 0x4A,
655 0x06) != CXD2880_RESULT_OK
)
656 return CXD2880_RESULT_ERROR_IO
;
659 u8 data_a
[2] = { 0x26, 0x5D };
660 u8 data_b
[2] = { 0x2B, 0x84 };
661 u8 data_c
[2] = { 0x2C, 0xC2 };
665 case CXD2880_TNRDMD_CLOCKMODE_A
:
668 case CXD2880_TNRDMD_CLOCKMODE_B
:
671 case CXD2880_TNRDMD_CLOCKMODE_C
:
675 return CXD2880_RESULT_ERROR_SW_STATE
;
678 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
679 CXD2880_IO_TGT_DMD
, 0x7D,
681 2) != CXD2880_RESULT_OK
)
682 return CXD2880_RESULT_ERROR_IO
;
689 case CXD2880_TNRDMD_CLOCKMODE_A
:
690 case CXD2880_TNRDMD_CLOCKMODE_B
:
693 case CXD2880_TNRDMD_CLOCKMODE_C
:
697 return CXD2880_RESULT_ERROR_SW_STATE
;
700 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
701 CXD2880_IO_TGT_DMD
, 0x71,
702 data
) != CXD2880_RESULT_OK
)
703 return CXD2880_RESULT_ERROR_IO
;
706 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_MAIN
) {
707 u8 data_a
[5] = { 0x4C, 0xCC, 0x00, 0xE6,
710 u8 data_b
[5] = { 0x57, 0x1C, 0x01, 0x05,
713 u8 data_c
[5] = { 0x59, 0x99, 0x01, 0x0C,
719 case CXD2880_TNRDMD_CLOCKMODE_A
:
722 case CXD2880_TNRDMD_CLOCKMODE_B
:
725 case CXD2880_TNRDMD_CLOCKMODE_C
:
729 return CXD2880_RESULT_ERROR_SW_STATE
;
732 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
733 CXD2880_IO_TGT_DMD
, 0x4B,
735 2) != CXD2880_RESULT_OK
)
736 return CXD2880_RESULT_ERROR_IO
;
738 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
739 CXD2880_IO_TGT_DMD
, 0x51,
741 3) != CXD2880_RESULT_OK
)
742 return CXD2880_RESULT_ERROR_IO
;
746 u8 data
[4] = { 0xC8, 0x01, 0x00, 0x03 };
748 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
749 CXD2880_IO_TGT_DMD
, 0x72,
751 2) != CXD2880_RESULT_OK
)
752 return CXD2880_RESULT_ERROR_IO
;
754 if (tnr_dmd
->io
->write_regs(tnr_dmd
->io
,
755 CXD2880_IO_TGT_DMD
, 0x6B,
757 2) != CXD2880_RESULT_OK
)
758 return CXD2880_RESULT_ERROR_IO
;
763 return CXD2880_RESULT_ERROR_SW_STATE
;
766 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
767 CXD2880_IO_TGT_DMD
, 0x00,
768 0x00) != CXD2880_RESULT_OK
)
769 return CXD2880_RESULT_ERROR_IO
;
771 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
772 CXD2880_IO_TGT_DMD
, 0xFD,
773 0x01) != CXD2880_RESULT_OK
)
774 return CXD2880_RESULT_ERROR_IO
;
776 return CXD2880_RESULT_OK
;
779 static enum cxd2880_ret
x_sleep_dvbt_demod_setting(struct cxd2880_tnrdmd
783 return CXD2880_RESULT_ERROR_ARG
;
785 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
786 CXD2880_IO_TGT_DMD
, 0x00,
787 0x04) != CXD2880_RESULT_OK
)
788 return CXD2880_RESULT_ERROR_IO
;
790 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
791 CXD2880_IO_TGT_DMD
, 0x5C,
792 0xD8) != CXD2880_RESULT_OK
)
793 return CXD2880_RESULT_ERROR_IO
;
795 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
796 CXD2880_IO_TGT_DMD
, 0x00,
797 0x10) != CXD2880_RESULT_OK
)
798 return CXD2880_RESULT_ERROR_IO
;
800 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
801 CXD2880_IO_TGT_DMD
, 0xA4,
802 0x00) != CXD2880_RESULT_OK
)
803 return CXD2880_RESULT_ERROR_IO
;
805 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_SUB
) {
806 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
807 CXD2880_IO_TGT_DMD
, 0x00,
808 0x11) != CXD2880_RESULT_OK
)
809 return CXD2880_RESULT_ERROR_IO
;
811 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
812 CXD2880_IO_TGT_DMD
, 0x87,
813 0x04) != CXD2880_RESULT_OK
)
814 return CXD2880_RESULT_ERROR_IO
;
817 return CXD2880_RESULT_OK
;
820 static enum cxd2880_ret
dvbt_set_profile(struct cxd2880_tnrdmd
*tnr_dmd
,
821 enum cxd2880_dvbt_profile profile
)
823 enum cxd2880_ret ret
= CXD2880_RESULT_OK
;
826 return CXD2880_RESULT_ERROR_ARG
;
828 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
829 CXD2880_IO_TGT_DMD
, 0x00,
830 0x10) != CXD2880_RESULT_OK
)
831 return CXD2880_RESULT_ERROR_IO
;
833 if (tnr_dmd
->io
->write_reg(tnr_dmd
->io
,
834 CXD2880_IO_TGT_DMD
, 0x67,
836 CXD2880_DVBT_PROFILE_HP
) ? 0x00 : 0x01) !=
838 return CXD2880_RESULT_ERROR_IO
;
843 enum cxd2880_ret
cxd2880_tnrdmd_dvbt_tune1(struct cxd2880_tnrdmd
*tnr_dmd
,
844 struct cxd2880_dvbt_tune_param
847 enum cxd2880_ret ret
= CXD2880_RESULT_OK
;
849 if ((!tnr_dmd
) || (!tune_param
))
850 return CXD2880_RESULT_ERROR_ARG
;
852 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_SUB
)
853 return CXD2880_RESULT_ERROR_ARG
;
855 if ((tnr_dmd
->state
!= CXD2880_TNRDMD_STATE_SLEEP
) &&
856 (tnr_dmd
->state
!= CXD2880_TNRDMD_STATE_ACTIVE
))
857 return CXD2880_RESULT_ERROR_SW_STATE
;
860 cxd2880_tnrdmd_common_tune_setting1(tnr_dmd
, CXD2880_DTV_SYS_DVBT
,
861 tune_param
->center_freq_khz
,
862 tune_param
->bandwidth
, 0, 0);
863 if (ret
!= CXD2880_RESULT_OK
)
867 x_tune_dvbt_demod_setting(tnr_dmd
, tune_param
->bandwidth
,
869 if (ret
!= CXD2880_RESULT_OK
)
872 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_MAIN
) {
874 x_tune_dvbt_demod_setting(tnr_dmd
->diver_sub
,
875 tune_param
->bandwidth
,
876 tnr_dmd
->diver_sub
->clk_mode
);
877 if (ret
!= CXD2880_RESULT_OK
)
881 ret
= dvbt_set_profile(tnr_dmd
, tune_param
->profile
);
882 if (ret
!= CXD2880_RESULT_OK
)
885 return CXD2880_RESULT_OK
;
888 enum cxd2880_ret
cxd2880_tnrdmd_dvbt_tune2(struct cxd2880_tnrdmd
*tnr_dmd
,
889 struct cxd2880_dvbt_tune_param
892 enum cxd2880_ret ret
= CXD2880_RESULT_OK
;
894 if ((!tnr_dmd
) || (!tune_param
))
895 return CXD2880_RESULT_ERROR_ARG
;
897 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_SUB
)
898 return CXD2880_RESULT_ERROR_ARG
;
900 if ((tnr_dmd
->state
!= CXD2880_TNRDMD_STATE_SLEEP
) &&
901 (tnr_dmd
->state
!= CXD2880_TNRDMD_STATE_ACTIVE
))
902 return CXD2880_RESULT_ERROR_SW_STATE
;
905 cxd2880_tnrdmd_common_tune_setting2(tnr_dmd
, CXD2880_DTV_SYS_DVBT
,
907 if (ret
!= CXD2880_RESULT_OK
)
910 tnr_dmd
->state
= CXD2880_TNRDMD_STATE_ACTIVE
;
911 tnr_dmd
->frequency_khz
= tune_param
->center_freq_khz
;
912 tnr_dmd
->sys
= CXD2880_DTV_SYS_DVBT
;
913 tnr_dmd
->bandwidth
= tune_param
->bandwidth
;
915 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_MAIN
) {
916 tnr_dmd
->diver_sub
->state
= CXD2880_TNRDMD_STATE_ACTIVE
;
917 tnr_dmd
->diver_sub
->frequency_khz
= tune_param
->center_freq_khz
;
918 tnr_dmd
->diver_sub
->sys
= CXD2880_DTV_SYS_DVBT
;
919 tnr_dmd
->diver_sub
->bandwidth
= tune_param
->bandwidth
;
922 return CXD2880_RESULT_OK
;
925 enum cxd2880_ret
cxd2880_tnrdmd_dvbt_sleep_setting(struct cxd2880_tnrdmd
928 enum cxd2880_ret ret
= CXD2880_RESULT_OK
;
931 return CXD2880_RESULT_ERROR_ARG
;
933 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_SUB
)
934 return CXD2880_RESULT_ERROR_ARG
;
936 if ((tnr_dmd
->state
!= CXD2880_TNRDMD_STATE_SLEEP
) &&
937 (tnr_dmd
->state
!= CXD2880_TNRDMD_STATE_ACTIVE
))
938 return CXD2880_RESULT_ERROR_SW_STATE
;
940 ret
= x_sleep_dvbt_demod_setting(tnr_dmd
);
941 if (ret
!= CXD2880_RESULT_OK
)
944 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_MAIN
) {
945 ret
= x_sleep_dvbt_demod_setting(tnr_dmd
->diver_sub
);
946 if (ret
!= CXD2880_RESULT_OK
)
950 return CXD2880_RESULT_OK
;
953 enum cxd2880_ret
cxd2880_tnrdmd_dvbt_check_demod_lock(struct cxd2880_tnrdmd
956 cxd2880_tnrdmd_lock_result
959 enum cxd2880_ret ret
= CXD2880_RESULT_OK
;
963 u8 unlock_detected
= 0;
964 u8 unlock_detected_sub
= 0;
966 if ((!tnr_dmd
) || (!lock
))
967 return CXD2880_RESULT_ERROR_ARG
;
969 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_SUB
)
970 return CXD2880_RESULT_ERROR_ARG
;
972 if (tnr_dmd
->state
!= CXD2880_TNRDMD_STATE_ACTIVE
)
973 return CXD2880_RESULT_ERROR_SW_STATE
;
976 cxd2880_tnrdmd_dvbt_mon_sync_stat(tnr_dmd
, &sync_stat
, &ts_lock
,
978 if (ret
!= CXD2880_RESULT_OK
)
981 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_SINGLE
) {
983 *lock
= CXD2880_TNRDMD_LOCK_RESULT_LOCKED
;
984 else if (unlock_detected
)
985 *lock
= CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED
;
987 *lock
= CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT
;
992 if (sync_stat
== 6) {
993 *lock
= CXD2880_TNRDMD_LOCK_RESULT_LOCKED
;
998 cxd2880_tnrdmd_dvbt_mon_sync_stat_sub(tnr_dmd
, &sync_stat
,
999 &unlock_detected_sub
);
1000 if (ret
!= CXD2880_RESULT_OK
)
1004 *lock
= CXD2880_TNRDMD_LOCK_RESULT_LOCKED
;
1005 else if (unlock_detected
&& unlock_detected_sub
)
1006 *lock
= CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED
;
1008 *lock
= CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT
;
1013 enum cxd2880_ret
cxd2880_tnrdmd_dvbt_check_ts_lock(struct cxd2880_tnrdmd
1016 cxd2880_tnrdmd_lock_result
1019 enum cxd2880_ret ret
= CXD2880_RESULT_OK
;
1023 u8 unlock_detected
= 0;
1024 u8 unlock_detected_sub
= 0;
1026 if ((!tnr_dmd
) || (!lock
))
1027 return CXD2880_RESULT_ERROR_ARG
;
1029 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_SUB
)
1030 return CXD2880_RESULT_ERROR_ARG
;
1032 if (tnr_dmd
->state
!= CXD2880_TNRDMD_STATE_ACTIVE
)
1033 return CXD2880_RESULT_ERROR_SW_STATE
;
1036 cxd2880_tnrdmd_dvbt_mon_sync_stat(tnr_dmd
, &sync_stat
, &ts_lock
,
1038 if (ret
!= CXD2880_RESULT_OK
)
1041 if (tnr_dmd
->diver_mode
== CXD2880_TNRDMD_DIVERMODE_SINGLE
) {
1043 *lock
= CXD2880_TNRDMD_LOCK_RESULT_LOCKED
;
1044 else if (unlock_detected
)
1045 *lock
= CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED
;
1047 *lock
= CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT
;
1053 *lock
= CXD2880_TNRDMD_LOCK_RESULT_LOCKED
;
1055 } else if (!unlock_detected
) {
1056 *lock
= CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT
;
1061 cxd2880_tnrdmd_dvbt_mon_sync_stat_sub(tnr_dmd
, &sync_stat
,
1062 &unlock_detected_sub
);
1063 if (ret
!= CXD2880_RESULT_OK
)
1066 if (unlock_detected
&& unlock_detected_sub
)
1067 *lock
= CXD2880_TNRDMD_LOCK_RESULT_UNLOCKED
;
1069 *lock
= CXD2880_TNRDMD_LOCK_RESULT_NOTDETECT
;