1// SPDX-License-Identifier: GPL-2.0
2/*
3 * cxd2880_tnrdmd.c
4 * Sony CXD2880 DVB-T2/T tuner + demodulator driver
5 * common control functions
6 *
7 * Copyright (C) 2016, 2017, 2018 Sony Semiconductor Solutions Corporation
8 */
9
10#include <media/dvb_frontend.h>
11#include "cxd2880_common.h"
12#include "cxd2880_tnrdmd.h"
13#include "cxd2880_tnrdmd_mon.h"
14#include "cxd2880_tnrdmd_dvbt.h"
15#include "cxd2880_tnrdmd_dvbt2.h"
16
17static const struct cxd2880_reg_value p_init1_seq[] = {
18	{0x11, 0x16}, {0x00, 0x10},
19};
20
21static const struct cxd2880_reg_value rf_init1_seq1[] = {
22	{0x4f, 0x18}, {0x61, 0x00}, {0x71, 0x00}, {0x9d, 0x01},
23	{0x7d, 0x02}, {0x8f, 0x01}, {0x8b, 0xc6}, {0x9a, 0x03},
24	{0x1c, 0x00},
25};
26
27static const struct cxd2880_reg_value rf_init1_seq2[] = {
28	{0xb9, 0x07}, {0x33, 0x01}, {0xc1, 0x01}, {0xc4, 0x1e},
29};
30
31static const struct cxd2880_reg_value rf_init1_seq3[] = {
32	{0x00, 0x10}, {0x51, 0x01}, {0xc5, 0x07}, {0x00, 0x11},
33	{0x70, 0xe9}, {0x76, 0x0a}, {0x78, 0x32}, {0x7a, 0x46},
34	{0x7c, 0x86}, {0x7e, 0xa4}, {0x00, 0x10}, {0xe1, 0x01},
35};
36
37static const struct cxd2880_reg_value rf_init1_seq4[] = {
38	{0x15, 0x00}, {0x00, 0x16}
39};
40
41static const struct cxd2880_reg_value rf_init1_seq5[] = {
42	{0x00, 0x00}, {0x25, 0x00}
43};
44
45static const struct cxd2880_reg_value rf_init1_seq6[] = {
46	{0x02, 0x00}, {0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1},
47	{0x8f, 0x16}, {0x67, 0x60}, {0x6a, 0x0f}, {0x6c, 0x17}
48};
49
50static const struct cxd2880_reg_value rf_init1_seq7[] = {
51	{0x00, 0xe2}, {0x41, 0xa0}, {0x4b, 0x68}, {0x00, 0x00},
52	{0x21, 0x00}, {0x10, 0x01},
53};
54
55static const struct cxd2880_reg_value rf_init1_seq8[] = {
56	{0x00, 0x10}, {0x25, 0x01},
57};
58
59static const struct cxd2880_reg_value rf_init1_seq9[] = {
60	{0x00, 0x10}, {0x14, 0x01}, {0x00, 0x00}, {0x26, 0x00},
61};
62
63static const struct cxd2880_reg_value rf_init2_seq1[] = {
64	{0x00, 0x14}, {0x1b, 0x01},
65};
66
67static const struct cxd2880_reg_value rf_init2_seq2[] = {
68	{0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe1}, {0xd3, 0x00},
69	{0x00, 0x00}, {0x21, 0x00},
70};
71
72static const struct cxd2880_reg_value x_tune1_seq1[] = {
73	{0x00, 0x00}, {0x10, 0x01},
74};
75
76static const struct cxd2880_reg_value x_tune1_seq2[] = {
77	{0x62, 0x00}, {0x00, 0x15},
78};
79
80static const struct cxd2880_reg_value x_tune2_seq1[] = {
81	{0x00, 0x1a}, {0x29, 0x01},
82};
83
84static const struct cxd2880_reg_value x_tune2_seq2[] = {
85	{0x62, 0x01}, {0x00, 0x11}, {0x2d, 0x00}, {0x2f, 0x00},
86};
87
88static const struct cxd2880_reg_value x_tune2_seq3[] = {
89	{0x00, 0x00}, {0x10, 0x00}, {0x21, 0x01},
90};
91
92static const struct cxd2880_reg_value x_tune2_seq4[] = {
93	{0x00, 0xe1}, {0x8a, 0x87},
94};
95
96static const struct cxd2880_reg_value x_tune2_seq5[] = {
97	{0x00, 0x00}, {0x21, 0x00},
98};
99
100static const struct cxd2880_reg_value x_tune3_seq[] = {
101	{0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0xa0},
102	{0x00, 0x00}, {0x21, 0x00}, {0xfe, 0x01},
103};
104
105static const struct cxd2880_reg_value x_tune4_seq[] = {
106	{0x00, 0x00}, {0xfe, 0x01},
107};
108
109static const struct cxd2880_reg_value x_sleep1_seq[] = {
110	{0x00, 0x00}, {0x57, 0x03},
111};
112
113static const struct cxd2880_reg_value x_sleep2_seq1[] = {
114	{0x00, 0x2d}, {0xb1, 0x01},
115};
116
117static const struct cxd2880_reg_value x_sleep2_seq2[] = {
118	{0x00, 0x10}, {0xf4, 0x00}, {0xf3, 0x00}, {0xf2, 0x00},
119	{0xf1, 0x00}, {0xf0, 0x00}, {0xef, 0x00},
120};
121
122static const struct cxd2880_reg_value x_sleep3_seq[] = {
123	{0x00, 0x00}, {0xfd, 0x00},
124};
125
126static const struct cxd2880_reg_value x_sleep4_seq[] = {
127	{0x00, 0x00}, {0x21, 0x01}, {0x00, 0xe2}, {0x41, 0x00},
128	{0x00, 0x00}, {0x21, 0x00},
129};
130
131static const struct cxd2880_reg_value spll_reset_seq1[] = {
132	{0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01},
133	{0x26, 0x01},
134};
135
136static const struct cxd2880_reg_value spll_reset_seq2[] = {
137	{0x00, 0x00}, {0x10, 0x00},
138};
139
140static const struct cxd2880_reg_value spll_reset_seq3[] = {
141	{0x00, 0x00}, {0x27, 0x00}, {0x22, 0x01},
142};
143
144static const struct cxd2880_reg_value spll_reset_seq4[] = {
145	{0x00, 0x00}, {0x27, 0x01},
146};
147
148static const struct cxd2880_reg_value spll_reset_seq5[] = {
149	{0x00, 0x00}, {0x10, 0x01},
150};
151
152static const struct cxd2880_reg_value t_power_x_seq1[] = {
153	{0x00, 0x10}, {0x29, 0x01}, {0x28, 0x01}, {0x27, 0x01},
154};
155
156static const struct cxd2880_reg_value t_power_x_seq2[] = {
157	{0x00, 0x00}, {0x10, 0x00},
158};
159
160static const struct cxd2880_reg_value t_power_x_seq3[] = {
161	{0x00, 0x00}, {0x27, 0x00}, {0x25, 0x01},
162};
163
164static const struct cxd2880_reg_value t_power_x_seq4[] = {
165	{0x00, 0x00}, {0x2a, 0x00},
166};
167
168static const struct cxd2880_reg_value t_power_x_seq5[] = {
169	{0x00, 0x00}, {0x25, 0x00},
170};
171
172static const struct cxd2880_reg_value t_power_x_seq6[] = {
173	{0x00, 0x00}, {0x27, 0x01},
174};
175
176static const struct cxd2880_reg_value t_power_x_seq7[] = {
177	{0x00, 0x00}, {0x10, 0x01},
178};
179
180static const struct cxd2880_reg_value set_ts_pin_seq[] = {
181	{0x50, 0x3f}, {0x52, 0x1f},
182
183};
184
185static const struct cxd2880_reg_value set_ts_output_seq1[] = {
186	{0x00, 0x00}, {0x52, 0x00},
187};
188
189static const struct cxd2880_reg_value set_ts_output_seq2[] = {
190	{0x00, 0x00}, {0xc3, 0x00},
191
192};
193
194static const struct cxd2880_reg_value set_ts_output_seq3[] = {
195	{0x00, 0x00}, {0xc3, 0x01},
196
197};
198
199static const struct cxd2880_reg_value set_ts_output_seq4[] = {
200	{0x00, 0x00}, {0x52, 0x1f},
201
202};
203
204static int p_init1(struct cxd2880_tnrdmd *tnr_dmd)
205{
206	u8 data = 0;
207	int ret;
208
209	if (!tnr_dmd)
210		return -EINVAL;
211
212	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
213				     CXD2880_IO_TGT_SYS,
214				     0x00, 0x00);
215	if (ret)
216		return ret;
217
218	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SINGLE ||
219	    tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
220		switch (tnr_dmd->create_param.ts_output_if) {
221		case CXD2880_TNRDMD_TSOUT_IF_TS:
222			data = 0x00;
223			break;
224		case CXD2880_TNRDMD_TSOUT_IF_SPI:
225			data = 0x01;
226			break;
227		case CXD2880_TNRDMD_TSOUT_IF_SDIO:
228			data = 0x02;
229			break;
230		default:
231			return -EINVAL;
232		}
233		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
234					     CXD2880_IO_TGT_SYS,
235					     0x10, data);
236		if (ret)
237			return ret;
238	}
239
240	ret = cxd2880_io_write_multi_regs(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
313static int p_init2(struct cxd2880_tnrdmd *tnr_dmd)
314{
315	u8 data[6] = { 0 };
316	int ret;
317
318	if (!tnr_dmd)
319		return -EINVAL;
320
321	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
322				     CXD2880_IO_TGT_SYS,
323				     0x00, 0x00);
324	if (ret)
325		return ret;
326	data[0] = tnr_dmd->create_param.xosc_cap;
327	data[1] = tnr_dmd->create_param.xosc_i;
328	switch (tnr_dmd->create_param.xtal_share_type) {
329	case CXD2880_TNRDMD_XTAL_SHARE_NONE:
330		data[2] = 0x01;
331		data[3] = 0x00;
332		break;
333	case CXD2880_TNRDMD_XTAL_SHARE_EXTREF:
334		data[2] = 0x00;
335		data[3] = 0x00;
336		break;
337	case CXD2880_TNRDMD_XTAL_SHARE_MASTER:
338		data[2] = 0x01;
339		data[3] = 0x01;
340		break;
341	case CXD2880_TNRDMD_XTAL_SHARE_SLAVE:
342		data[2] = 0x00;
343		data[3] = 0x01;
344		break;
345	default:
346		return -EINVAL;
347	}
348	data[4] = 0x06;
349	data[5] = 0x00;
350
351	return tnr_dmd->io->write_regs(tnr_dmd->io,
352				       CXD2880_IO_TGT_SYS,
353				       0x13, data, 6);
354}
355
356static int p_init3(struct cxd2880_tnrdmd *tnr_dmd)
357{
358	u8 data[2] = { 0 };
359	int ret;
360
361	if (!tnr_dmd)
362		return -EINVAL;
363
364	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
365				     CXD2880_IO_TGT_SYS,
366				     0x00, 0x00);
367	if (ret)
368		return ret;
369
370	switch (tnr_dmd->diver_mode) {
371	case CXD2880_TNRDMD_DIVERMODE_SINGLE:
372		data[0] = 0x00;
373		break;
374	case CXD2880_TNRDMD_DIVERMODE_MAIN:
375		data[0] = 0x03;
376		break;
377	case CXD2880_TNRDMD_DIVERMODE_SUB:
378		data[0] = 0x02;
379		break;
380	default:
381		return -EINVAL;
382	}
383
384	data[1] = 0x01;
385
386	return tnr_dmd->io->write_regs(tnr_dmd->io,
387				       CXD2880_IO_TGT_SYS,
388				       0x1f, data, 2);
389}
390
391static int rf_init1(struct cxd2880_tnrdmd *tnr_dmd)
392{
393	u8 data[8] = { 0 };
394	static const u8 rf_init1_cdata1[40] = {
395		0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
396		0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x03,
397		0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x02,
398		0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
399		0x02, 0x03, 0x02, 0x01, 0x01, 0x01, 0x02,
400		0x02, 0x03, 0x04, 0x04, 0x04
401	};
402
403	static const u8 rf_init1_cdata2[5] = {0xff, 0x00, 0x00, 0x00, 0x00};
404	static const u8 rf_init1_cdata3[80] = {
405		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
406		0x01, 0x00, 0x02, 0x00, 0x63, 0x00, 0x00,
407		0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00,
408		0x06, 0x00, 0x06, 0x00, 0x08, 0x00, 0x09,
409		0x00, 0x0b, 0x00, 0x0b, 0x00, 0x0d, 0x00,
410		0x0d, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x0f,
411		0x00, 0x10, 0x00, 0x79, 0x00, 0x00, 0x00,
412		0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01,
413		0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
414		0x04, 0x00, 0x04, 0x00, 0x06, 0x00, 0x05,
415		0x00, 0x07, 0x00, 0x07, 0x00, 0x08, 0x00,
416		0x0a, 0x03, 0xe0
417	};
418
419	static const u8 rf_init1_cdata4[8] = {
420		0x20, 0x20, 0x30, 0x41, 0x50, 0x5f, 0x6f, 0x80
421	};
422
423	static const u8 rf_init1_cdata5[50] = {
424		0x00, 0x09, 0x00, 0x08, 0x00, 0x07, 0x00,
425		0x06, 0x00, 0x05, 0x00, 0x03, 0x00, 0x02,
426		0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00,
427		0x06, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0c,
428		0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0f, 0x00,
429		0x0e, 0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f,
430		0x00, 0x0e, 0x00, 0x10, 0x00, 0x0f, 0x00,
431		0x0e
432	};
433
434	u8 addr = 0;
435	int ret;
436
437	if (!tnr_dmd)
438		return -EINVAL;
439
440	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
441				     CXD2880_IO_TGT_SYS,
442				     0x00, 0x00);
443	if (ret)
444		return ret;
445	data[0] = 0x01;
446	data[1] = 0x00;
447	data[2] = 0x01;
448	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
449				      CXD2880_IO_TGT_SYS,
450				      0x21, data, 3);
451	if (ret)
452		return ret;
453
454	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
455				     CXD2880_IO_TGT_SYS,
456				     0x00, 0x10);
457	if (ret)
458		return ret;
459	data[0] = 0x01;
460	data[1] = 0x01;
461	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
462				      CXD2880_IO_TGT_SYS,
463				      0x17, data, 2);
464	if (ret)
465		return ret;
466
467	if (tnr_dmd->create_param.stationary_use) {
468		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
469					     CXD2880_IO_TGT_SYS,
470					     0x1a, 0x06);
471		if (ret)
472			return ret;
473	}
474
475	ret = cxd2880_io_write_multi_regs(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
837static int rf_init2(struct cxd2880_tnrdmd *tnr_dmd)
838{
839	u8 data[5] = { 0 };
840	int ret;
841
842	if (!tnr_dmd)
843		return -EINVAL;
844
845	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
846				     CXD2880_IO_TGT_SYS,
847				     0x00, 0x10);
848	if (ret)
849		return ret;
850	data[0] = 0x40;
851	data[1] = 0x40;
852	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
853				      CXD2880_IO_TGT_SYS,
854				      0xea, data, 2);
855	if (ret)
856		return ret;
857
858	usleep_range(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
886static int x_tune1(struct cxd2880_tnrdmd *tnr_dmd,
887		   enum cxd2880_dtv_sys sys, u32 freq_khz,
888		   enum cxd2880_dtv_bandwidth bandwidth,
889		   u8 is_cable, int shift_frequency_khz)
890{
891	u8 data[11] = { 0 };
892	int ret;
893
894	if (!tnr_dmd)
895		return -EINVAL;
896
897	ret = cxd2880_io_write_multi_regs(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
1014static int x_tune2(struct cxd2880_tnrdmd *tnr_dmd,
1015		   enum cxd2880_dtv_bandwidth bandwidth,
1016		   enum cxd2880_tnrdmd_clockmode clk_mode,
1017		   int shift_frequency_khz)
1018{
1019	u8 data[3] = { 0 };
1020	int ret;
1021
1022	if (!tnr_dmd)
1023		return -EINVAL;
1024
1025	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1026				     CXD2880_IO_TGT_SYS,
1027				     0x00, 0x11);
1028	if (ret)
1029		return ret;
1030
1031	data[0] = 0x01;
1032	data[1] = 0x0e;
1033	data[2] = 0x01;
1034	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
1035				      CXD2880_IO_TGT_SYS,
1036				      0x2d, data, 3);
1037	if (ret)
1038		return ret;
1039
1040	ret = cxd2880_io_write_multi_regs(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
1221static int x_tune3(struct cxd2880_tnrdmd *tnr_dmd,
1222		   enum cxd2880_dtv_sys sys,
1223		   u8 en_fef_intmtnt_ctrl)
1224{
1225	u8 data[6] = { 0 };
1226	int ret;
1227
1228	if (!tnr_dmd)
1229		return -EINVAL;
1230
1231	ret = cxd2880_io_write_multi_regs(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
1270static int x_tune4(struct cxd2880_tnrdmd *tnr_dmd)
1271{
1272	u8 data[2] = { 0 };
1273	int ret;
1274
1275	if (!tnr_dmd)
1276		return -EINVAL;
1277
1278	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
1279		return -EINVAL;
1280
1281	ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
1282						CXD2880_IO_TGT_SYS,
1283						0x00, 0x00);
1284	if (ret)
1285		return ret;
1286	data[0] = 0x14;
1287	data[1] = 0x00;
1288	ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io,
1289						CXD2880_IO_TGT_SYS,
1290						0x55, data, 2);
1291	if (ret)
1292		return ret;
1293
1294	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1295				     CXD2880_IO_TGT_SYS,
1296				     0x00, 0x00);
1297	if (ret)
1298		return ret;
1299	data[0] = 0x0b;
1300	data[1] = 0xff;
1301	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
1302				      CXD2880_IO_TGT_SYS,
1303				      0x53, data, 2);
1304	if (ret)
1305		return ret;
1306	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1307				     CXD2880_IO_TGT_SYS,
1308				     0x57, 0x01);
1309	if (ret)
1310		return ret;
1311	data[0] = 0x0b;
1312	data[1] = 0xff;
1313	ret = tnr_dmd->io->write_regs(tnr_dmd->io,
1314				      CXD2880_IO_TGT_SYS,
1315				      0x55, data, 2);
1316	if (ret)
1317		return ret;
1318
1319	ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
1320						CXD2880_IO_TGT_SYS,
1321						0x00, 0x00);
1322	if (ret)
1323		return ret;
1324	data[0] = 0x14;
1325	data[1] = 0x00;
1326	ret = tnr_dmd->diver_sub->io->write_regs(tnr_dmd->diver_sub->io,
1327						 CXD2880_IO_TGT_SYS,
1328						 0x53, data, 2);
1329	if (ret)
1330		return ret;
1331	ret = tnr_dmd->diver_sub->io->write_reg(tnr_dmd->diver_sub->io,
1332						CXD2880_IO_TGT_SYS,
1333						0x57, 0x02);
1334	if (ret)
1335		return ret;
1336
1337	ret = cxd2880_io_write_multi_regs(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
1350static int x_sleep1(struct cxd2880_tnrdmd *tnr_dmd)
1351{
1352	u8 data[3] = { 0 };
1353	int ret;
1354
1355	if (!tnr_dmd)
1356		return -EINVAL;
1357
1358	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
1359		return -EINVAL;
1360
1361	ret = cxd2880_io_write_multi_regs(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
1410static int x_sleep2(struct cxd2880_tnrdmd *tnr_dmd)
1411{
1412	u8 data = 0;
1413	int ret;
1414
1415	if (!tnr_dmd)
1416		return -EINVAL;
1417
1418	ret = cxd2880_io_write_multi_regs(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
1442static int x_sleep3(struct cxd2880_tnrdmd *tnr_dmd)
1443{
1444	if (!tnr_dmd)
1445		return -EINVAL;
1446
1447	return cxd2880_io_write_multi_regs(tnr_dmd->io,
1448					   CXD2880_IO_TGT_DMD,
1449					   x_sleep3_seq,
1450					   ARRAY_SIZE(x_sleep3_seq));
1451}
1452
1453static int x_sleep4(struct cxd2880_tnrdmd *tnr_dmd)
1454{
1455	if (!tnr_dmd)
1456		return -EINVAL;
1457
1458	return cxd2880_io_write_multi_regs(tnr_dmd->io,
1459					   CXD2880_IO_TGT_DMD,
1460					   x_sleep4_seq,
1461					   ARRAY_SIZE(x_sleep4_seq));
1462}
1463
1464static int spll_reset(struct cxd2880_tnrdmd *tnr_dmd,
1465		      enum cxd2880_tnrdmd_clockmode clockmode)
1466{
1467	u8 data[4] = { 0 };
1468	int ret;
1469
1470	if (!tnr_dmd)
1471		return -EINVAL;
1472
1473	ret = cxd2880_io_write_multi_regs(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
1565static int t_power_x(struct cxd2880_tnrdmd *tnr_dmd, u8 on)
1566{
1567	u8 data[3] = { 0 };
1568	int ret;
1569
1570	if (!tnr_dmd)
1571		return -EINVAL;
1572
1573	ret = cxd2880_io_write_multi_regs(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
1698struct cxd2880_tnrdmd_ts_clk_cfg {
1699	u8 srl_clk_mode;
1700	u8 srl_duty_mode;
1701	u8 ts_clk_period;
1702};
1703
1704static int set_ts_clk_mode_and_freq(struct cxd2880_tnrdmd *tnr_dmd,
1705				    enum cxd2880_dtv_sys sys)
1706{
1707	int ret;
1708	u8 backwards_compatible = 0;
1709	struct cxd2880_tnrdmd_ts_clk_cfg ts_clk_cfg;
1710	u8 ts_rate_ctrl_off = 0;
1711	u8 ts_in_off = 0;
1712	u8 ts_clk_manaul_on = 0;
1713	u8 data = 0;
1714
1715	static const struct cxd2880_tnrdmd_ts_clk_cfg srl_ts_clk_stgs[2][2] = {
1716		{
1717			{3, 1, 8,},
1718			{0, 2, 16,}
1719		}, {
1720			{1, 1, 8,},
1721			{2, 2, 16,}
1722		}
1723	};
1724
1725	if (!tnr_dmd)
1726		return -EINVAL;
1727
1728	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1729				     CXD2880_IO_TGT_DMD,
1730				     0x00, 0x00);
1731	if (ret)
1732		return ret;
1733
1734	if (tnr_dmd->is_ts_backwards_compatible_mode) {
1735		backwards_compatible = 1;
1736		ts_rate_ctrl_off = 1;
1737		ts_in_off = 1;
1738	} else {
1739		backwards_compatible = 0;
1740		ts_rate_ctrl_off = 0;
1741		ts_in_off = 0;
1742	}
1743
1744	if (tnr_dmd->ts_byte_clk_manual_setting) {
1745		ts_clk_manaul_on = 1;
1746		ts_rate_ctrl_off = 0;
1747	}
1748
1749	ret = cxd2880_io_set_reg_bits(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
1809static int pid_ftr_setting(struct cxd2880_tnrdmd *tnr_dmd,
1810			   struct cxd2880_tnrdmd_pid_ftr_cfg
1811			   *pid_ftr_cfg)
1812{
1813	int i;
1814	int ret;
1815	u8 data[65];
1816
1817	if (!tnr_dmd)
1818		return -EINVAL;
1819
1820	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1821				     CXD2880_IO_TGT_DMD,
1822				     0x00, 0x00);
1823	if (ret)
1824		return ret;
1825
1826	if (!pid_ftr_cfg)
1827		return tnr_dmd->io->write_reg(tnr_dmd->io,
1828					      CXD2880_IO_TGT_DMD,
1829					      0x50, 0x02);
1830
1831	data[0] = pid_ftr_cfg->is_negative ? 0x01 : 0x00;
1832
1833	for (i = 0; i < 32; i++) {
1834		if (pid_ftr_cfg->pid_cfg[i].is_en) {
1835			data[1 + (i * 2)] = (pid_ftr_cfg->pid_cfg[i].pid >> 8) | 0x20;
1836			data[2 + (i * 2)] =  pid_ftr_cfg->pid_cfg[i].pid & 0xff;
1837		} else {
1838			data[1 + (i * 2)] = 0x00;
1839			data[2 + (i * 2)] = 0x00;
1840		}
1841	}
1842
1843	return tnr_dmd->io->write_regs(tnr_dmd->io,
1844				       CXD2880_IO_TGT_DMD,
1845				       0x50, data, 65);
1846}
1847
1848static int load_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd)
1849{
1850	int ret;
1851	u8 i;
1852
1853	if (!tnr_dmd)
1854		return -EINVAL;
1855
1856	for (i = 0; i < tnr_dmd->cfg_mem_last_entry; i++) {
1857		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
1858					     tnr_dmd->cfg_mem[i].tgt,
1859					     0x00, tnr_dmd->cfg_mem[i].bank);
1860		if (ret)
1861			return ret;
1862
1863		ret = cxd2880_io_set_reg_bits(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
1875static int set_cfg_mem(struct cxd2880_tnrdmd *tnr_dmd,
1876		       enum cxd2880_io_tgt tgt,
1877		       u8 bank, u8 address, u8 value, u8 bit_mask)
1878{
1879	u8 i;
1880	u8 value_stored = 0;
1881
1882	if (!tnr_dmd)
1883		return -EINVAL;
1884
1885	for (i = 0; i < tnr_dmd->cfg_mem_last_entry; i++) {
1886		if (value_stored == 0 &&
1887		    tnr_dmd->cfg_mem[i].tgt == tgt &&
1888		    tnr_dmd->cfg_mem[i].bank == bank &&
1889		    tnr_dmd->cfg_mem[i].address == address) {
1890			tnr_dmd->cfg_mem[i].value &= ~bit_mask;
1891			tnr_dmd->cfg_mem[i].value |= (value & bit_mask);
1892
1893			tnr_dmd->cfg_mem[i].bit_mask |= bit_mask;
1894
1895			value_stored = 1;
1896		}
1897	}
1898
1899	if (value_stored)
1900		return 0;
1901
1902	if (tnr_dmd->cfg_mem_last_entry < CXD2880_TNRDMD_MAX_CFG_MEM_COUNT) {
1903		tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].tgt = tgt;
1904		tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].bank = bank;
1905		tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].address = address;
1906		tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].value = (value & bit_mask);
1907		tnr_dmd->cfg_mem[tnr_dmd->cfg_mem_last_entry].bit_mask = bit_mask;
1908		tnr_dmd->cfg_mem_last_entry++;
1909	} else {
1910		return -ENOMEM;
1911	}
1912
1913	return 0;
1914}
1915
1916int cxd2880_tnrdmd_create(struct cxd2880_tnrdmd *tnr_dmd,
1917			  struct cxd2880_io *io,
1918			  struct cxd2880_tnrdmd_create_param
1919			  *create_param)
1920{
1921	if (!tnr_dmd || !io || !create_param)
1922		return -EINVAL;
1923
1924	memset(tnr_dmd, 0, sizeof(struct cxd2880_tnrdmd));
1925
1926	tnr_dmd->io = io;
1927	tnr_dmd->create_param = *create_param;
1928
1929	tnr_dmd->diver_mode = CXD2880_TNRDMD_DIVERMODE_SINGLE;
1930	tnr_dmd->diver_sub = NULL;
1931
1932	tnr_dmd->srl_ts_clk_mod_cnts = 1;
1933	tnr_dmd->en_fef_intmtnt_base = 1;
1934	tnr_dmd->en_fef_intmtnt_lite = 1;
1935	tnr_dmd->rf_lvl_cmpstn = NULL;
1936	tnr_dmd->lna_thrs_tbl_air = NULL;
1937	tnr_dmd->lna_thrs_tbl_cable = NULL;
1938	atomic_set(&tnr_dmd->cancel, 0);
1939
1940	return 0;
1941}
1942
1943int cxd2880_tnrdmd_diver_create(struct cxd2880_tnrdmd
1944				*tnr_dmd_main,
1945				struct cxd2880_io *io_main,
1946				struct cxd2880_tnrdmd *tnr_dmd_sub,
1947				struct cxd2880_io *io_sub,
1948				struct
1949				cxd2880_tnrdmd_diver_create_param
1950				*create_param)
1951{
1952	struct cxd2880_tnrdmd_create_param *main_param, *sub_param;
1953
1954	if (!tnr_dmd_main || !io_main || !tnr_dmd_sub || !io_sub ||
1955	    !create_param)
1956		return -EINVAL;
1957
1958	memset(tnr_dmd_main, 0, sizeof(struct cxd2880_tnrdmd));
1959	memset(tnr_dmd_sub, 0, sizeof(struct cxd2880_tnrdmd));
1960
1961	main_param = &tnr_dmd_main->create_param;
1962	sub_param = &tnr_dmd_sub->create_param;
1963
1964	tnr_dmd_main->io = io_main;
1965	tnr_dmd_main->diver_mode = CXD2880_TNRDMD_DIVERMODE_MAIN;
1966	tnr_dmd_main->diver_sub = tnr_dmd_sub;
1967	tnr_dmd_main->create_param.en_internal_ldo =
1968	    create_param->en_internal_ldo;
1969
1970	main_param->ts_output_if = create_param->ts_output_if;
1971	main_param->xtal_share_type = CXD2880_TNRDMD_XTAL_SHARE_MASTER;
1972	main_param->xosc_cap = create_param->xosc_cap_main;
1973	main_param->xosc_i = create_param->xosc_i_main;
1974	main_param->is_cxd2881gg = create_param->is_cxd2881gg;
1975	main_param->stationary_use = create_param->stationary_use;
1976
1977	tnr_dmd_sub->io = io_sub;
1978	tnr_dmd_sub->diver_mode = CXD2880_TNRDMD_DIVERMODE_SUB;
1979	tnr_dmd_sub->diver_sub = NULL;
1980
1981	sub_param->en_internal_ldo = create_param->en_internal_ldo;
1982	sub_param->ts_output_if = create_param->ts_output_if;
1983	sub_param->xtal_share_type = CXD2880_TNRDMD_XTAL_SHARE_SLAVE;
1984	sub_param->xosc_cap = 0;
1985	sub_param->xosc_i = create_param->xosc_i_sub;
1986	sub_param->is_cxd2881gg = create_param->is_cxd2881gg;
1987	sub_param->stationary_use = create_param->stationary_use;
1988
1989	tnr_dmd_main->srl_ts_clk_mod_cnts = 1;
1990	tnr_dmd_main->en_fef_intmtnt_base = 1;
1991	tnr_dmd_main->en_fef_intmtnt_lite = 1;
1992	tnr_dmd_main->rf_lvl_cmpstn = NULL;
1993	tnr_dmd_main->lna_thrs_tbl_air = NULL;
1994	tnr_dmd_main->lna_thrs_tbl_cable = NULL;
1995
1996	tnr_dmd_sub->srl_ts_clk_mod_cnts = 1;
1997	tnr_dmd_sub->en_fef_intmtnt_base = 1;
1998	tnr_dmd_sub->en_fef_intmtnt_lite = 1;
1999	tnr_dmd_sub->rf_lvl_cmpstn = NULL;
2000	tnr_dmd_sub->lna_thrs_tbl_air = NULL;
2001	tnr_dmd_sub->lna_thrs_tbl_cable = NULL;
2002
2003	return 0;
2004}
2005
2006int cxd2880_tnrdmd_init1(struct cxd2880_tnrdmd *tnr_dmd)
2007{
2008	int ret;
2009
2010	if (!tnr_dmd || tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2011		return -EINVAL;
2012
2013	tnr_dmd->chip_id = CXD2880_TNRDMD_CHIP_ID_UNKNOWN;
2014	tnr_dmd->state = CXD2880_TNRDMD_STATE_UNKNOWN;
2015	tnr_dmd->clk_mode = CXD2880_TNRDMD_CLOCKMODE_UNKNOWN;
2016	tnr_dmd->frequency_khz = 0;
2017	tnr_dmd->sys = CXD2880_DTV_SYS_UNKNOWN;
2018	tnr_dmd->bandwidth = CXD2880_DTV_BW_UNKNOWN;
2019	tnr_dmd->scan_mode = 0;
2020	atomic_set(&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
2095int cxd2880_tnrdmd_init2(struct cxd2880_tnrdmd *tnr_dmd)
2096{
2097	u8 cpu_task_completed;
2098	int ret;
2099
2100	if (!tnr_dmd)
2101		return -EINVAL;
2102
2103	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2104		return -EINVAL;
2105
2106	ret = cxd2880_tnrdmd_check_internal_cpu_status(tnr_dmd,
2107						     &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
2142int cxd2880_tnrdmd_check_internal_cpu_status(struct cxd2880_tnrdmd
2143					     *tnr_dmd,
2144					     u8 *task_completed)
2145{
2146	u16 cpu_status = 0;
2147	int ret;
2148
2149	if (!tnr_dmd || !task_completed)
2150		return -EINVAL;
2151
2152	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2153		return -EINVAL;
2154
2155	ret = cxd2880_tnrdmd_mon_internal_cpu_status(tnr_dmd, &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
2184int cxd2880_tnrdmd_common_tune_setting1(struct cxd2880_tnrdmd *tnr_dmd,
2185					enum cxd2880_dtv_sys sys,
2186					u32 frequency_khz,
2187					enum cxd2880_dtv_bandwidth
2188					bandwidth, u8 one_seg_opt,
2189					u8 one_seg_opt_shft_dir)
2190{
2191	u8 data;
2192	enum cxd2880_tnrdmd_clockmode new_clk_mode =
2193				CXD2880_TNRDMD_CLOCKMODE_A;
2194	int shift_frequency_khz;
2195	u8 cpu_task_completed;
2196	int ret;
2197
2198	if (!tnr_dmd)
2199		return -EINVAL;
2200
2201	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2202		return -EINVAL;
2203
2204	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
2205	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
2206		return -EINVAL;
2207
2208	if (frequency_khz < 4000)
2209		return -EINVAL;
2210
2211	ret = cxd2880_tnrdmd_sleep(tnr_dmd);
2212	if (ret)
2213		return ret;
2214
2215	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
2216				     CXD2880_IO_TGT_SYS,
2217				     0x00,
2218				     0x00);
2219	if (ret)
2220		return ret;
2221
2222	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
2223				     CXD2880_IO_TGT_SYS,
2224				     0x2b,
2225				     &data,
2226				     1);
2227	if (ret)
2228		return ret;
2229
2230	switch (sys) {
2231	case CXD2880_DTV_SYS_DVBT:
2232		if (data == 0x00) {
2233			ret = t_power_x(tnr_dmd, 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
2381int cxd2880_tnrdmd_common_tune_setting2(struct cxd2880_tnrdmd
2382					*tnr_dmd,
2383					enum cxd2880_dtv_sys sys,
2384					u8 en_fef_intmtnt_ctrl)
2385{
2386	int ret;
2387
2388	if (!tnr_dmd)
2389		return -EINVAL;
2390
2391	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2392		return -EINVAL;
2393
2394	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
2395	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
2396		return -EINVAL;
2397
2398	ret = x_tune3(tnr_dmd, sys, en_fef_intmtnt_ctrl);
2399	if (ret)
2400		return ret;
2401
2402	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN) {
2403		ret = x_tune3(tnr_dmd->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
2414int cxd2880_tnrdmd_sleep(struct cxd2880_tnrdmd *tnr_dmd)
2415{
2416	int ret;
2417
2418	if (!tnr_dmd)
2419		return -EINVAL;
2420
2421	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
2422		return -EINVAL;
2423
2424	if (tnr_dmd->state == CXD2880_TNRDMD_STATE_SLEEP)
2425		return 0;
2426
2427	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
2428		return -EINVAL;
2429
2430	ret = cxd2880_tnrdmd_set_ts_output(tnr_dmd, 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
2502int cxd2880_tnrdmd_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
2503			   enum cxd2880_tnrdmd_cfg_id id,
2504			   int value)
2505{
2506	int ret = 0;
2507	u8 data[2] = { 0 };
2508	u8 need_sub_setting = 0;
2509
2510	if (!tnr_dmd)
2511		return -EINVAL;
2512
2513	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
2514	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
2515		return -EINVAL;
2516
2517	switch (id) {
2518	case CXD2880_TNRDMD_CFG_OUTPUT_SEL_MSB:
2519		if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
2520			return -EINVAL;
2521
2522		ret =
2523		    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
2524							 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
2988int cxd2880_tnrdmd_gpio_set_cfg(struct cxd2880_tnrdmd *tnr_dmd,
2989				u8 id,
2990				u8 en,
2991				enum cxd2880_tnrdmd_gpio_mode mode,
2992				u8 open_drain, u8 invert)
2993{
2994	int ret;
2995
2996	if (!tnr_dmd)
2997		return -EINVAL;
2998
2999	if (id > 2)
3000		return -EINVAL;
3001
3002	if (mode > CXD2880_TNRDMD_GPIO_MODE_EEW)
3003		return -EINVAL;
3004
3005	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3006	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3007		return -EINVAL;
3008
3009	ret =
3010	    cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd, 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
3039int cxd2880_tnrdmd_gpio_set_cfg_sub(struct cxd2880_tnrdmd *tnr_dmd,
3040				    u8 id,
3041				    u8 en,
3042				    enum cxd2880_tnrdmd_gpio_mode
3043				    mode, u8 open_drain, u8 invert)
3044{
3045	if (!tnr_dmd)
3046		return -EINVAL;
3047
3048	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
3049		return -EINVAL;
3050
3051	return cxd2880_tnrdmd_gpio_set_cfg(tnr_dmd->diver_sub, id, en, mode,
3052					   open_drain, invert);
3053}
3054
3055int cxd2880_tnrdmd_gpio_read(struct cxd2880_tnrdmd *tnr_dmd,
3056			     u8 id, u8 *value)
3057{
3058	u8 data = 0;
3059	int ret;
3060
3061	if (!tnr_dmd || !value)
3062		return -EINVAL;
3063
3064	if (id > 2)
3065		return -EINVAL;
3066
3067	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3068	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3069		return -EINVAL;
3070
3071	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3072				     CXD2880_IO_TGT_SYS,
3073				     0x00, 0x0a);
3074	if (ret)
3075		return ret;
3076	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
3077				     CXD2880_IO_TGT_SYS,
3078				     0x20, &data, 1);
3079	if (ret)
3080		return ret;
3081
3082	*value = (data >> id) & 0x01;
3083
3084	return 0;
3085}
3086
3087int cxd2880_tnrdmd_gpio_read_sub(struct cxd2880_tnrdmd *tnr_dmd,
3088				 u8 id, u8 *value)
3089{
3090	if (!tnr_dmd)
3091		return -EINVAL;
3092
3093	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
3094		return -EINVAL;
3095
3096	return cxd2880_tnrdmd_gpio_read(tnr_dmd->diver_sub, id, value);
3097}
3098
3099int cxd2880_tnrdmd_gpio_write(struct cxd2880_tnrdmd *tnr_dmd,
3100			      u8 id, u8 value)
3101{
3102	if (!tnr_dmd)
3103		return -EINVAL;
3104
3105	if (id > 2)
3106		return -EINVAL;
3107
3108	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3109	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3110		return -EINVAL;
3111
3112	return cxd2880_tnrdmd_set_and_save_reg_bits(tnr_dmd,
3113						    CXD2880_IO_TGT_SYS,
3114						    0x00, 0x46,
3115						    value ? (1 << id) : 0,
3116						    1 << id);
3117}
3118
3119int cxd2880_tnrdmd_gpio_write_sub(struct cxd2880_tnrdmd *tnr_dmd,
3120				  u8 id, u8 value)
3121{
3122	if (!tnr_dmd)
3123		return -EINVAL;
3124
3125	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
3126		return -EINVAL;
3127
3128	return cxd2880_tnrdmd_gpio_write(tnr_dmd->diver_sub, id, value);
3129}
3130
3131int cxd2880_tnrdmd_interrupt_read(struct cxd2880_tnrdmd *tnr_dmd,
3132				  u16 *value)
3133{
3134	int ret;
3135	u8 data[2] = { 0 };
3136
3137	if (!tnr_dmd || !value)
3138		return -EINVAL;
3139
3140	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3141	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3142		return -EINVAL;
3143
3144	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3145				     CXD2880_IO_TGT_SYS,
3146				     0x00, 0x0a);
3147	if (ret)
3148		return ret;
3149	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
3150				     CXD2880_IO_TGT_SYS,
3151				     0x15, data, 2);
3152	if (ret)
3153		return ret;
3154
3155	*value = (data[0] << 8) | data[1];
3156
3157	return 0;
3158}
3159
3160int cxd2880_tnrdmd_interrupt_clear(struct cxd2880_tnrdmd *tnr_dmd,
3161				   u16 value)
3162{
3163	int ret;
3164	u8 data[2] = { 0 };
3165
3166	if (!tnr_dmd)
3167		return -EINVAL;
3168
3169	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3170	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3171		return -EINVAL;
3172
3173	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3174				     CXD2880_IO_TGT_SYS,
3175				     0x00, 0x00);
3176	if (ret)
3177		return ret;
3178
3179	data[0] = (value >> 8) & 0xff;
3180	data[1] = value & 0xff;
3181
3182	return tnr_dmd->io->write_regs(tnr_dmd->io,
3183				       CXD2880_IO_TGT_SYS,
3184				       0x3c, data, 2);
3185}
3186
3187int cxd2880_tnrdmd_ts_buf_clear(struct cxd2880_tnrdmd *tnr_dmd,
3188				u8 clear_overflow_flag,
3189				u8 clear_underflow_flag,
3190				u8 clear_buf)
3191{
3192	int ret;
3193	u8 data[2] = { 0 };
3194
3195	if (!tnr_dmd)
3196		return -EINVAL;
3197
3198	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
3199		return -EINVAL;
3200
3201	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3202	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3203		return -EINVAL;
3204
3205	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3206				     CXD2880_IO_TGT_DMD,
3207				     0x00, 0x00);
3208	if (ret)
3209		return ret;
3210
3211	data[0] = clear_overflow_flag ? 0x02 : 0x00;
3212	data[0] |= clear_underflow_flag ? 0x01 : 0x00;
3213	data[1] = clear_buf ? 0x01 : 0x00;
3214
3215	return tnr_dmd->io->write_regs(tnr_dmd->io,
3216				       CXD2880_IO_TGT_DMD,
3217				       0x9f, data, 2);
3218}
3219
3220int cxd2880_tnrdmd_chip_id(struct cxd2880_tnrdmd *tnr_dmd,
3221			   enum cxd2880_tnrdmd_chip_id *chip_id)
3222{
3223	int ret;
3224	u8 data = 0;
3225
3226	if (!tnr_dmd || !chip_id)
3227		return -EINVAL;
3228
3229	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3230				     CXD2880_IO_TGT_SYS,
3231				     0x00, 0x00);
3232	if (ret)
3233		return ret;
3234	ret = tnr_dmd->io->read_regs(tnr_dmd->io,
3235				     CXD2880_IO_TGT_SYS,
3236				     0xfd, &data, 1);
3237	if (ret)
3238		return ret;
3239
3240	*chip_id = (enum cxd2880_tnrdmd_chip_id)data;
3241
3242	return 0;
3243}
3244
3245int cxd2880_tnrdmd_set_and_save_reg_bits(struct cxd2880_tnrdmd
3246					 *tnr_dmd,
3247					 enum cxd2880_io_tgt tgt,
3248					 u8 bank, u8 address,
3249					 u8 value, u8 bit_mask)
3250{
3251	int ret;
3252
3253	if (!tnr_dmd)
3254		return -EINVAL;
3255
3256	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3257	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3258		return -EINVAL;
3259
3260	ret = tnr_dmd->io->write_reg(tnr_dmd->io, tgt, 0x00, bank);
3261	if (ret)
3262		return ret;
3263
3264	ret = cxd2880_io_set_reg_bits(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
3272int cxd2880_tnrdmd_set_scan_mode(struct cxd2880_tnrdmd *tnr_dmd,
3273				 enum cxd2880_dtv_sys sys,
3274				 u8 scan_mode_end)
3275{
3276	if (!tnr_dmd)
3277		return -EINVAL;
3278
3279	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3280	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3281		return -EINVAL;
3282
3283	tnr_dmd->scan_mode = scan_mode_end;
3284
3285	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_MAIN)
3286		return cxd2880_tnrdmd_set_scan_mode(tnr_dmd->diver_sub, sys,
3287						    scan_mode_end);
3288	else
3289		return 0;
3290}
3291
3292int cxd2880_tnrdmd_set_pid_ftr(struct cxd2880_tnrdmd *tnr_dmd,
3293			       struct cxd2880_tnrdmd_pid_ftr_cfg
3294			       *pid_ftr_cfg)
3295{
3296	if (!tnr_dmd)
3297		return -EINVAL;
3298
3299	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
3300		return -EINVAL;
3301
3302	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3303	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3304		return -EINVAL;
3305
3306	if (tnr_dmd->create_param.ts_output_if == CXD2880_TNRDMD_TSOUT_IF_TS)
3307		return -ENOTTY;
3308
3309	if (pid_ftr_cfg) {
3310		tnr_dmd->pid_ftr_cfg = *pid_ftr_cfg;
3311		tnr_dmd->pid_ftr_cfg_en = 1;
3312	} else {
3313		tnr_dmd->pid_ftr_cfg_en = 0;
3314	}
3315
3316	if (tnr_dmd->state == CXD2880_TNRDMD_STATE_ACTIVE)
3317		return pid_ftr_setting(tnr_dmd, pid_ftr_cfg);
3318	else
3319		return 0;
3320}
3321
3322int cxd2880_tnrdmd_set_rf_lvl_cmpstn(struct cxd2880_tnrdmd
3323				     *tnr_dmd,
3324				     int (*rf_lvl_cmpstn)
3325				     (struct cxd2880_tnrdmd *,
3326				     int *))
3327{
3328	if (!tnr_dmd)
3329		return -EINVAL;
3330
3331	tnr_dmd->rf_lvl_cmpstn = rf_lvl_cmpstn;
3332
3333	return 0;
3334}
3335
3336int cxd2880_tnrdmd_set_rf_lvl_cmpstn_sub(struct cxd2880_tnrdmd
3337					 *tnr_dmd,
3338					 int (*rf_lvl_cmpstn)
3339					 (struct cxd2880_tnrdmd *,
3340					 int *))
3341{
3342	if (!tnr_dmd)
3343		return -EINVAL;
3344
3345	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
3346		return -EINVAL;
3347
3348	return cxd2880_tnrdmd_set_rf_lvl_cmpstn(tnr_dmd->diver_sub,
3349						rf_lvl_cmpstn);
3350}
3351
3352int cxd2880_tnrdmd_set_lna_thrs(struct cxd2880_tnrdmd *tnr_dmd,
3353				struct cxd2880_tnrdmd_lna_thrs_tbl_air
3354				*tbl_air,
3355				struct cxd2880_tnrdmd_lna_thrs_tbl_cable
3356				*tbl_cable)
3357{
3358	if (!tnr_dmd)
3359		return -EINVAL;
3360
3361	tnr_dmd->lna_thrs_tbl_air = tbl_air;
3362	tnr_dmd->lna_thrs_tbl_cable = tbl_cable;
3363
3364	return 0;
3365}
3366
3367int cxd2880_tnrdmd_set_lna_thrs_sub(struct cxd2880_tnrdmd *tnr_dmd,
3368				    struct
3369				    cxd2880_tnrdmd_lna_thrs_tbl_air
3370				    *tbl_air,
3371				    struct cxd2880_tnrdmd_lna_thrs_tbl_cable
3372				    *tbl_cable)
3373{
3374	if (!tnr_dmd)
3375		return -EINVAL;
3376
3377	if (tnr_dmd->diver_mode != CXD2880_TNRDMD_DIVERMODE_MAIN)
3378		return -EINVAL;
3379
3380	return cxd2880_tnrdmd_set_lna_thrs(tnr_dmd->diver_sub,
3381					   tbl_air, tbl_cable);
3382}
3383
3384int cxd2880_tnrdmd_set_ts_pin_high_low(struct cxd2880_tnrdmd
3385				       *tnr_dmd, u8 en, u8 value)
3386{
3387	int ret;
3388
3389	if (!tnr_dmd)
3390		return -EINVAL;
3391
3392	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
3393		return -EINVAL;
3394
3395	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP)
3396		return -EINVAL;
3397
3398	if (tnr_dmd->create_param.ts_output_if != CXD2880_TNRDMD_TSOUT_IF_TS)
3399		return -ENOTTY;
3400
3401	ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3402				     CXD2880_IO_TGT_SYS,
3403				     0x00, 0x00);
3404	if (ret)
3405		return ret;
3406
3407	if (en) {
3408		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3409					     CXD2880_IO_TGT_SYS,
3410					     0x50, ((value & 0x1f) | 0x80));
3411		if (ret)
3412			return ret;
3413
3414		ret = tnr_dmd->io->write_reg(tnr_dmd->io,
3415					     CXD2880_IO_TGT_SYS,
3416					     0x52, (value & 0x1f));
3417	} else {
3418		ret = cxd2880_io_write_multi_regs(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
3431int cxd2880_tnrdmd_set_ts_output(struct cxd2880_tnrdmd *tnr_dmd,
3432				 u8 en)
3433{
3434	int ret;
3435
3436	if (!tnr_dmd)
3437		return -EINVAL;
3438
3439	if (tnr_dmd->diver_mode == CXD2880_TNRDMD_DIVERMODE_SUB)
3440		return -EINVAL;
3441
3442	if (tnr_dmd->state != CXD2880_TNRDMD_STATE_SLEEP &&
3443	    tnr_dmd->state != CXD2880_TNRDMD_STATE_ACTIVE)
3444		return -EINVAL;
3445
3446	switch (tnr_dmd->create_param.ts_output_if) {
3447	case CXD2880_TNRDMD_TSOUT_IF_TS:
3448		if (en) {
3449			ret = cxd2880_io_write_multi_regs(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
3492int slvt_freeze_reg(struct cxd2880_tnrdmd *tnr_dmd)
3493{
3494	u8 data;
3495	int ret;
3496
3497	if (!tnr_dmd)
3498		return -EINVAL;
3499
3500	switch (tnr_dmd->create_param.ts_output_if) {
3501	case CXD2880_TNRDMD_TSOUT_IF_SPI:
3502	case CXD2880_TNRDMD_TSOUT_IF_SDIO:
3503
3504		ret = tnr_dmd->io->read_regs(tnr_dmd->io,
3505					     CXD2880_IO_TGT_DMD,
3506					     0x00, &data, 1);
3507		if (ret)
3508			return ret;
3509
3510		break;
3511	case CXD2880_TNRDMD_TSOUT_IF_TS:
3512	default:
3513		break;
3514	}
3515
3516	return tnr_dmd->io->write_reg(tnr_dmd->io,
3517				      CXD2880_IO_TGT_DMD,
3518				      0x01, 0x01);
3519}
3520