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