GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / media / dvb-frontends / cxd2880 / cxd2880_tnrdmd.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }