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