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

source code of linux/drivers/media/dvb-frontends/cxd2880/cxd2880_tnrdmd.c