1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * cxd2841er.c
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Sony digital demodulator driver for
6*4882a593Smuzhiyun * CXD2841ER - DVB-S/S2/T/T2/C/C2
7*4882a593Smuzhiyun * CXD2854ER - DVB-S/S2/T/T2/C/C2, ISDB-T/S
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * Copyright 2012 Sony Corporation
10*4882a593Smuzhiyun * Copyright (C) 2014 NetUP Inc.
11*4882a593Smuzhiyun * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
12*4882a593Smuzhiyun * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
13*4882a593Smuzhiyun */
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #include <linux/module.h>
16*4882a593Smuzhiyun #include <linux/init.h>
17*4882a593Smuzhiyun #include <linux/string.h>
18*4882a593Smuzhiyun #include <linux/slab.h>
19*4882a593Smuzhiyun #include <linux/bitops.h>
20*4882a593Smuzhiyun #include <linux/math64.h>
21*4882a593Smuzhiyun #include <linux/log2.h>
22*4882a593Smuzhiyun #include <linux/dynamic_debug.h>
23*4882a593Smuzhiyun #include <linux/kernel.h>
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun #include <media/dvb_math.h>
26*4882a593Smuzhiyun #include <media/dvb_frontend.h>
27*4882a593Smuzhiyun #include "cxd2841er.h"
28*4882a593Smuzhiyun #include "cxd2841er_priv.h"
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define MAX_WRITE_REGSIZE 16
31*4882a593Smuzhiyun #define LOG2_E_100X 144
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #define INTLOG10X100(x) ((u32) (((u64) intlog10(x) * 100) >> 24))
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun /* DVB-C constellation */
36*4882a593Smuzhiyun enum sony_dvbc_constellation_t {
37*4882a593Smuzhiyun SONY_DVBC_CONSTELLATION_16QAM,
38*4882a593Smuzhiyun SONY_DVBC_CONSTELLATION_32QAM,
39*4882a593Smuzhiyun SONY_DVBC_CONSTELLATION_64QAM,
40*4882a593Smuzhiyun SONY_DVBC_CONSTELLATION_128QAM,
41*4882a593Smuzhiyun SONY_DVBC_CONSTELLATION_256QAM
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun enum cxd2841er_state {
45*4882a593Smuzhiyun STATE_SHUTDOWN = 0,
46*4882a593Smuzhiyun STATE_SLEEP_S,
47*4882a593Smuzhiyun STATE_ACTIVE_S,
48*4882a593Smuzhiyun STATE_SLEEP_TC,
49*4882a593Smuzhiyun STATE_ACTIVE_TC
50*4882a593Smuzhiyun };
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun struct cxd2841er_priv {
53*4882a593Smuzhiyun struct dvb_frontend frontend;
54*4882a593Smuzhiyun struct i2c_adapter *i2c;
55*4882a593Smuzhiyun u8 i2c_addr_slvx;
56*4882a593Smuzhiyun u8 i2c_addr_slvt;
57*4882a593Smuzhiyun const struct cxd2841er_config *config;
58*4882a593Smuzhiyun enum cxd2841er_state state;
59*4882a593Smuzhiyun u8 system;
60*4882a593Smuzhiyun enum cxd2841er_xtal xtal;
61*4882a593Smuzhiyun enum fe_caps caps;
62*4882a593Smuzhiyun u32 flags;
63*4882a593Smuzhiyun unsigned long stats_time;
64*4882a593Smuzhiyun };
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun static const struct cxd2841er_cnr_data s_cn_data[] = {
67*4882a593Smuzhiyun { 0x033e, 0 }, { 0x0339, 100 }, { 0x0333, 200 },
68*4882a593Smuzhiyun { 0x032e, 300 }, { 0x0329, 400 }, { 0x0324, 500 },
69*4882a593Smuzhiyun { 0x031e, 600 }, { 0x0319, 700 }, { 0x0314, 800 },
70*4882a593Smuzhiyun { 0x030f, 900 }, { 0x030a, 1000 }, { 0x02ff, 1100 },
71*4882a593Smuzhiyun { 0x02f4, 1200 }, { 0x02e9, 1300 }, { 0x02de, 1400 },
72*4882a593Smuzhiyun { 0x02d4, 1500 }, { 0x02c9, 1600 }, { 0x02bf, 1700 },
73*4882a593Smuzhiyun { 0x02b5, 1800 }, { 0x02ab, 1900 }, { 0x02a1, 2000 },
74*4882a593Smuzhiyun { 0x029b, 2100 }, { 0x0295, 2200 }, { 0x0290, 2300 },
75*4882a593Smuzhiyun { 0x028a, 2400 }, { 0x0284, 2500 }, { 0x027f, 2600 },
76*4882a593Smuzhiyun { 0x0279, 2700 }, { 0x0274, 2800 }, { 0x026e, 2900 },
77*4882a593Smuzhiyun { 0x0269, 3000 }, { 0x0262, 3100 }, { 0x025c, 3200 },
78*4882a593Smuzhiyun { 0x0255, 3300 }, { 0x024f, 3400 }, { 0x0249, 3500 },
79*4882a593Smuzhiyun { 0x0242, 3600 }, { 0x023c, 3700 }, { 0x0236, 3800 },
80*4882a593Smuzhiyun { 0x0230, 3900 }, { 0x022a, 4000 }, { 0x0223, 4100 },
81*4882a593Smuzhiyun { 0x021c, 4200 }, { 0x0215, 4300 }, { 0x020e, 4400 },
82*4882a593Smuzhiyun { 0x0207, 4500 }, { 0x0201, 4600 }, { 0x01fa, 4700 },
83*4882a593Smuzhiyun { 0x01f4, 4800 }, { 0x01ed, 4900 }, { 0x01e7, 5000 },
84*4882a593Smuzhiyun { 0x01e0, 5100 }, { 0x01d9, 5200 }, { 0x01d2, 5300 },
85*4882a593Smuzhiyun { 0x01cb, 5400 }, { 0x01c4, 5500 }, { 0x01be, 5600 },
86*4882a593Smuzhiyun { 0x01b7, 5700 }, { 0x01b1, 5800 }, { 0x01aa, 5900 },
87*4882a593Smuzhiyun { 0x01a4, 6000 }, { 0x019d, 6100 }, { 0x0196, 6200 },
88*4882a593Smuzhiyun { 0x018f, 6300 }, { 0x0189, 6400 }, { 0x0182, 6500 },
89*4882a593Smuzhiyun { 0x017c, 6600 }, { 0x0175, 6700 }, { 0x016f, 6800 },
90*4882a593Smuzhiyun { 0x0169, 6900 }, { 0x0163, 7000 }, { 0x015c, 7100 },
91*4882a593Smuzhiyun { 0x0156, 7200 }, { 0x0150, 7300 }, { 0x014a, 7400 },
92*4882a593Smuzhiyun { 0x0144, 7500 }, { 0x013e, 7600 }, { 0x0138, 7700 },
93*4882a593Smuzhiyun { 0x0132, 7800 }, { 0x012d, 7900 }, { 0x0127, 8000 },
94*4882a593Smuzhiyun { 0x0121, 8100 }, { 0x011c, 8200 }, { 0x0116, 8300 },
95*4882a593Smuzhiyun { 0x0111, 8400 }, { 0x010b, 8500 }, { 0x0106, 8600 },
96*4882a593Smuzhiyun { 0x0101, 8700 }, { 0x00fc, 8800 }, { 0x00f7, 8900 },
97*4882a593Smuzhiyun { 0x00f2, 9000 }, { 0x00ee, 9100 }, { 0x00ea, 9200 },
98*4882a593Smuzhiyun { 0x00e6, 9300 }, { 0x00e2, 9400 }, { 0x00de, 9500 },
99*4882a593Smuzhiyun { 0x00da, 9600 }, { 0x00d7, 9700 }, { 0x00d3, 9800 },
100*4882a593Smuzhiyun { 0x00d0, 9900 }, { 0x00cc, 10000 }, { 0x00c7, 10100 },
101*4882a593Smuzhiyun { 0x00c3, 10200 }, { 0x00bf, 10300 }, { 0x00ba, 10400 },
102*4882a593Smuzhiyun { 0x00b6, 10500 }, { 0x00b2, 10600 }, { 0x00ae, 10700 },
103*4882a593Smuzhiyun { 0x00aa, 10800 }, { 0x00a7, 10900 }, { 0x00a3, 11000 },
104*4882a593Smuzhiyun { 0x009f, 11100 }, { 0x009c, 11200 }, { 0x0098, 11300 },
105*4882a593Smuzhiyun { 0x0094, 11400 }, { 0x0091, 11500 }, { 0x008e, 11600 },
106*4882a593Smuzhiyun { 0x008a, 11700 }, { 0x0087, 11800 }, { 0x0084, 11900 },
107*4882a593Smuzhiyun { 0x0081, 12000 }, { 0x007e, 12100 }, { 0x007b, 12200 },
108*4882a593Smuzhiyun { 0x0079, 12300 }, { 0x0076, 12400 }, { 0x0073, 12500 },
109*4882a593Smuzhiyun { 0x0071, 12600 }, { 0x006e, 12700 }, { 0x006c, 12800 },
110*4882a593Smuzhiyun { 0x0069, 12900 }, { 0x0067, 13000 }, { 0x0065, 13100 },
111*4882a593Smuzhiyun { 0x0062, 13200 }, { 0x0060, 13300 }, { 0x005e, 13400 },
112*4882a593Smuzhiyun { 0x005c, 13500 }, { 0x005a, 13600 }, { 0x0058, 13700 },
113*4882a593Smuzhiyun { 0x0056, 13800 }, { 0x0054, 13900 }, { 0x0052, 14000 },
114*4882a593Smuzhiyun { 0x0050, 14100 }, { 0x004e, 14200 }, { 0x004c, 14300 },
115*4882a593Smuzhiyun { 0x004b, 14400 }, { 0x0049, 14500 }, { 0x0047, 14600 },
116*4882a593Smuzhiyun { 0x0046, 14700 }, { 0x0044, 14800 }, { 0x0043, 14900 },
117*4882a593Smuzhiyun { 0x0041, 15000 }, { 0x003f, 15100 }, { 0x003e, 15200 },
118*4882a593Smuzhiyun { 0x003c, 15300 }, { 0x003b, 15400 }, { 0x003a, 15500 },
119*4882a593Smuzhiyun { 0x0037, 15700 }, { 0x0036, 15800 }, { 0x0034, 15900 },
120*4882a593Smuzhiyun { 0x0033, 16000 }, { 0x0032, 16100 }, { 0x0031, 16200 },
121*4882a593Smuzhiyun { 0x0030, 16300 }, { 0x002f, 16400 }, { 0x002e, 16500 },
122*4882a593Smuzhiyun { 0x002d, 16600 }, { 0x002c, 16700 }, { 0x002b, 16800 },
123*4882a593Smuzhiyun { 0x002a, 16900 }, { 0x0029, 17000 }, { 0x0028, 17100 },
124*4882a593Smuzhiyun { 0x0027, 17200 }, { 0x0026, 17300 }, { 0x0025, 17400 },
125*4882a593Smuzhiyun { 0x0024, 17500 }, { 0x0023, 17600 }, { 0x0022, 17800 },
126*4882a593Smuzhiyun { 0x0021, 17900 }, { 0x0020, 18000 }, { 0x001f, 18200 },
127*4882a593Smuzhiyun { 0x001e, 18300 }, { 0x001d, 18500 }, { 0x001c, 18700 },
128*4882a593Smuzhiyun { 0x001b, 18900 }, { 0x001a, 19000 }, { 0x0019, 19200 },
129*4882a593Smuzhiyun { 0x0018, 19300 }, { 0x0017, 19500 }, { 0x0016, 19700 },
130*4882a593Smuzhiyun { 0x0015, 19900 }, { 0x0014, 20000 },
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun static const struct cxd2841er_cnr_data s2_cn_data[] = {
134*4882a593Smuzhiyun { 0x05af, 0 }, { 0x0597, 100 }, { 0x057e, 200 },
135*4882a593Smuzhiyun { 0x0567, 300 }, { 0x0550, 400 }, { 0x0539, 500 },
136*4882a593Smuzhiyun { 0x0522, 600 }, { 0x050c, 700 }, { 0x04f6, 800 },
137*4882a593Smuzhiyun { 0x04e1, 900 }, { 0x04cc, 1000 }, { 0x04b6, 1100 },
138*4882a593Smuzhiyun { 0x04a1, 1200 }, { 0x048c, 1300 }, { 0x0477, 1400 },
139*4882a593Smuzhiyun { 0x0463, 1500 }, { 0x044f, 1600 }, { 0x043c, 1700 },
140*4882a593Smuzhiyun { 0x0428, 1800 }, { 0x0416, 1900 }, { 0x0403, 2000 },
141*4882a593Smuzhiyun { 0x03ef, 2100 }, { 0x03dc, 2200 }, { 0x03c9, 2300 },
142*4882a593Smuzhiyun { 0x03b6, 2400 }, { 0x03a4, 2500 }, { 0x0392, 2600 },
143*4882a593Smuzhiyun { 0x0381, 2700 }, { 0x036f, 2800 }, { 0x035f, 2900 },
144*4882a593Smuzhiyun { 0x034e, 3000 }, { 0x033d, 3100 }, { 0x032d, 3200 },
145*4882a593Smuzhiyun { 0x031d, 3300 }, { 0x030d, 3400 }, { 0x02fd, 3500 },
146*4882a593Smuzhiyun { 0x02ee, 3600 }, { 0x02df, 3700 }, { 0x02d0, 3800 },
147*4882a593Smuzhiyun { 0x02c2, 3900 }, { 0x02b4, 4000 }, { 0x02a6, 4100 },
148*4882a593Smuzhiyun { 0x0299, 4200 }, { 0x028c, 4300 }, { 0x027f, 4400 },
149*4882a593Smuzhiyun { 0x0272, 4500 }, { 0x0265, 4600 }, { 0x0259, 4700 },
150*4882a593Smuzhiyun { 0x024d, 4800 }, { 0x0241, 4900 }, { 0x0236, 5000 },
151*4882a593Smuzhiyun { 0x022b, 5100 }, { 0x0220, 5200 }, { 0x0215, 5300 },
152*4882a593Smuzhiyun { 0x020a, 5400 }, { 0x0200, 5500 }, { 0x01f6, 5600 },
153*4882a593Smuzhiyun { 0x01ec, 5700 }, { 0x01e2, 5800 }, { 0x01d8, 5900 },
154*4882a593Smuzhiyun { 0x01cf, 6000 }, { 0x01c6, 6100 }, { 0x01bc, 6200 },
155*4882a593Smuzhiyun { 0x01b3, 6300 }, { 0x01aa, 6400 }, { 0x01a2, 6500 },
156*4882a593Smuzhiyun { 0x0199, 6600 }, { 0x0191, 6700 }, { 0x0189, 6800 },
157*4882a593Smuzhiyun { 0x0181, 6900 }, { 0x0179, 7000 }, { 0x0171, 7100 },
158*4882a593Smuzhiyun { 0x0169, 7200 }, { 0x0161, 7300 }, { 0x015a, 7400 },
159*4882a593Smuzhiyun { 0x0153, 7500 }, { 0x014b, 7600 }, { 0x0144, 7700 },
160*4882a593Smuzhiyun { 0x013d, 7800 }, { 0x0137, 7900 }, { 0x0130, 8000 },
161*4882a593Smuzhiyun { 0x012a, 8100 }, { 0x0124, 8200 }, { 0x011e, 8300 },
162*4882a593Smuzhiyun { 0x0118, 8400 }, { 0x0112, 8500 }, { 0x010c, 8600 },
163*4882a593Smuzhiyun { 0x0107, 8700 }, { 0x0101, 8800 }, { 0x00fc, 8900 },
164*4882a593Smuzhiyun { 0x00f7, 9000 }, { 0x00f2, 9100 }, { 0x00ec, 9200 },
165*4882a593Smuzhiyun { 0x00e7, 9300 }, { 0x00e2, 9400 }, { 0x00dd, 9500 },
166*4882a593Smuzhiyun { 0x00d8, 9600 }, { 0x00d4, 9700 }, { 0x00cf, 9800 },
167*4882a593Smuzhiyun { 0x00ca, 9900 }, { 0x00c6, 10000 }, { 0x00c2, 10100 },
168*4882a593Smuzhiyun { 0x00be, 10200 }, { 0x00b9, 10300 }, { 0x00b5, 10400 },
169*4882a593Smuzhiyun { 0x00b1, 10500 }, { 0x00ae, 10600 }, { 0x00aa, 10700 },
170*4882a593Smuzhiyun { 0x00a6, 10800 }, { 0x00a3, 10900 }, { 0x009f, 11000 },
171*4882a593Smuzhiyun { 0x009b, 11100 }, { 0x0098, 11200 }, { 0x0095, 11300 },
172*4882a593Smuzhiyun { 0x0091, 11400 }, { 0x008e, 11500 }, { 0x008b, 11600 },
173*4882a593Smuzhiyun { 0x0088, 11700 }, { 0x0085, 11800 }, { 0x0082, 11900 },
174*4882a593Smuzhiyun { 0x007f, 12000 }, { 0x007c, 12100 }, { 0x007a, 12200 },
175*4882a593Smuzhiyun { 0x0077, 12300 }, { 0x0074, 12400 }, { 0x0072, 12500 },
176*4882a593Smuzhiyun { 0x006f, 12600 }, { 0x006d, 12700 }, { 0x006b, 12800 },
177*4882a593Smuzhiyun { 0x0068, 12900 }, { 0x0066, 13000 }, { 0x0064, 13100 },
178*4882a593Smuzhiyun { 0x0061, 13200 }, { 0x005f, 13300 }, { 0x005d, 13400 },
179*4882a593Smuzhiyun { 0x005b, 13500 }, { 0x0059, 13600 }, { 0x0057, 13700 },
180*4882a593Smuzhiyun { 0x0055, 13800 }, { 0x0053, 13900 }, { 0x0051, 14000 },
181*4882a593Smuzhiyun { 0x004f, 14100 }, { 0x004e, 14200 }, { 0x004c, 14300 },
182*4882a593Smuzhiyun { 0x004a, 14400 }, { 0x0049, 14500 }, { 0x0047, 14600 },
183*4882a593Smuzhiyun { 0x0045, 14700 }, { 0x0044, 14800 }, { 0x0042, 14900 },
184*4882a593Smuzhiyun { 0x0041, 15000 }, { 0x003f, 15100 }, { 0x003e, 15200 },
185*4882a593Smuzhiyun { 0x003c, 15300 }, { 0x003b, 15400 }, { 0x003a, 15500 },
186*4882a593Smuzhiyun { 0x0038, 15600 }, { 0x0037, 15700 }, { 0x0036, 15800 },
187*4882a593Smuzhiyun { 0x0034, 15900 }, { 0x0033, 16000 }, { 0x0032, 16100 },
188*4882a593Smuzhiyun { 0x0031, 16200 }, { 0x0030, 16300 }, { 0x002f, 16400 },
189*4882a593Smuzhiyun { 0x002e, 16500 }, { 0x002d, 16600 }, { 0x002c, 16700 },
190*4882a593Smuzhiyun { 0x002b, 16800 }, { 0x002a, 16900 }, { 0x0029, 17000 },
191*4882a593Smuzhiyun { 0x0028, 17100 }, { 0x0027, 17200 }, { 0x0026, 17300 },
192*4882a593Smuzhiyun { 0x0025, 17400 }, { 0x0024, 17500 }, { 0x0023, 17600 },
193*4882a593Smuzhiyun { 0x0022, 17800 }, { 0x0021, 17900 }, { 0x0020, 18000 },
194*4882a593Smuzhiyun { 0x001f, 18200 }, { 0x001e, 18300 }, { 0x001d, 18500 },
195*4882a593Smuzhiyun { 0x001c, 18700 }, { 0x001b, 18900 }, { 0x001a, 19000 },
196*4882a593Smuzhiyun { 0x0019, 19200 }, { 0x0018, 19300 }, { 0x0017, 19500 },
197*4882a593Smuzhiyun { 0x0016, 19700 }, { 0x0015, 19900 }, { 0x0014, 20000 },
198*4882a593Smuzhiyun };
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv);
201*4882a593Smuzhiyun static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv);
202*4882a593Smuzhiyun
cxd2841er_i2c_debug(struct cxd2841er_priv * priv,u8 addr,u8 reg,u8 write,const u8 * data,u32 len)203*4882a593Smuzhiyun static void cxd2841er_i2c_debug(struct cxd2841er_priv *priv,
204*4882a593Smuzhiyun u8 addr, u8 reg, u8 write,
205*4882a593Smuzhiyun const u8 *data, u32 len)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
208*4882a593Smuzhiyun "cxd2841er: I2C %s addr %02x reg 0x%02x size %d data %*ph\n",
209*4882a593Smuzhiyun (write == 0 ? "read" : "write"), addr, reg, len, len, data);
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun
cxd2841er_write_regs(struct cxd2841er_priv * priv,u8 addr,u8 reg,const u8 * data,u32 len)212*4882a593Smuzhiyun static int cxd2841er_write_regs(struct cxd2841er_priv *priv,
213*4882a593Smuzhiyun u8 addr, u8 reg, const u8 *data, u32 len)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun int ret;
216*4882a593Smuzhiyun u8 buf[MAX_WRITE_REGSIZE + 1];
217*4882a593Smuzhiyun u8 i2c_addr = (addr == I2C_SLVX ?
218*4882a593Smuzhiyun priv->i2c_addr_slvx : priv->i2c_addr_slvt);
219*4882a593Smuzhiyun struct i2c_msg msg[1] = {
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun .addr = i2c_addr,
222*4882a593Smuzhiyun .flags = 0,
223*4882a593Smuzhiyun .len = len + 1,
224*4882a593Smuzhiyun .buf = buf,
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun };
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun if (len + 1 >= sizeof(buf)) {
229*4882a593Smuzhiyun dev_warn(&priv->i2c->dev, "wr reg=%04x: len=%d is too big!\n",
230*4882a593Smuzhiyun reg, len + 1);
231*4882a593Smuzhiyun return -E2BIG;
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun cxd2841er_i2c_debug(priv, i2c_addr, reg, 1, data, len);
235*4882a593Smuzhiyun buf[0] = reg;
236*4882a593Smuzhiyun memcpy(&buf[1], data, len);
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun ret = i2c_transfer(priv->i2c, msg, 1);
239*4882a593Smuzhiyun if (ret >= 0 && ret != 1)
240*4882a593Smuzhiyun ret = -EIO;
241*4882a593Smuzhiyun if (ret < 0) {
242*4882a593Smuzhiyun dev_warn(&priv->i2c->dev,
243*4882a593Smuzhiyun "%s: i2c wr failed=%d addr=%02x reg=%02x len=%d\n",
244*4882a593Smuzhiyun KBUILD_MODNAME, ret, i2c_addr, reg, len);
245*4882a593Smuzhiyun return ret;
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun return 0;
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
cxd2841er_write_reg(struct cxd2841er_priv * priv,u8 addr,u8 reg,u8 val)250*4882a593Smuzhiyun static int cxd2841er_write_reg(struct cxd2841er_priv *priv,
251*4882a593Smuzhiyun u8 addr, u8 reg, u8 val)
252*4882a593Smuzhiyun {
253*4882a593Smuzhiyun u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun return cxd2841er_write_regs(priv, addr, reg, &tmp, 1);
256*4882a593Smuzhiyun }
257*4882a593Smuzhiyun
cxd2841er_read_regs(struct cxd2841er_priv * priv,u8 addr,u8 reg,u8 * val,u32 len)258*4882a593Smuzhiyun static int cxd2841er_read_regs(struct cxd2841er_priv *priv,
259*4882a593Smuzhiyun u8 addr, u8 reg, u8 *val, u32 len)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun int ret;
262*4882a593Smuzhiyun u8 i2c_addr = (addr == I2C_SLVX ?
263*4882a593Smuzhiyun priv->i2c_addr_slvx : priv->i2c_addr_slvt);
264*4882a593Smuzhiyun struct i2c_msg msg[2] = {
265*4882a593Smuzhiyun {
266*4882a593Smuzhiyun .addr = i2c_addr,
267*4882a593Smuzhiyun .flags = 0,
268*4882a593Smuzhiyun .len = 1,
269*4882a593Smuzhiyun .buf = ®,
270*4882a593Smuzhiyun }, {
271*4882a593Smuzhiyun .addr = i2c_addr,
272*4882a593Smuzhiyun .flags = I2C_M_RD,
273*4882a593Smuzhiyun .len = len,
274*4882a593Smuzhiyun .buf = val,
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun };
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun ret = i2c_transfer(priv->i2c, msg, 2);
279*4882a593Smuzhiyun if (ret >= 0 && ret != 2)
280*4882a593Smuzhiyun ret = -EIO;
281*4882a593Smuzhiyun if (ret < 0) {
282*4882a593Smuzhiyun dev_warn(&priv->i2c->dev,
283*4882a593Smuzhiyun "%s: i2c rd failed=%d addr=%02x reg=%02x\n",
284*4882a593Smuzhiyun KBUILD_MODNAME, ret, i2c_addr, reg);
285*4882a593Smuzhiyun return ret;
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun cxd2841er_i2c_debug(priv, i2c_addr, reg, 0, val, len);
288*4882a593Smuzhiyun return 0;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
cxd2841er_read_reg(struct cxd2841er_priv * priv,u8 addr,u8 reg,u8 * val)291*4882a593Smuzhiyun static int cxd2841er_read_reg(struct cxd2841er_priv *priv,
292*4882a593Smuzhiyun u8 addr, u8 reg, u8 *val)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun return cxd2841er_read_regs(priv, addr, reg, val, 1);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
cxd2841er_set_reg_bits(struct cxd2841er_priv * priv,u8 addr,u8 reg,u8 data,u8 mask)297*4882a593Smuzhiyun static int cxd2841er_set_reg_bits(struct cxd2841er_priv *priv,
298*4882a593Smuzhiyun u8 addr, u8 reg, u8 data, u8 mask)
299*4882a593Smuzhiyun {
300*4882a593Smuzhiyun int res;
301*4882a593Smuzhiyun u8 rdata;
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun if (mask != 0xff) {
304*4882a593Smuzhiyun res = cxd2841er_read_reg(priv, addr, reg, &rdata);
305*4882a593Smuzhiyun if (res)
306*4882a593Smuzhiyun return res;
307*4882a593Smuzhiyun data = ((data & mask) | (rdata & (mask ^ 0xFF)));
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun return cxd2841er_write_reg(priv, addr, reg, data);
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun
cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal,u32 ifhz)312*4882a593Smuzhiyun static u32 cxd2841er_calc_iffreq_xtal(enum cxd2841er_xtal xtal, u32 ifhz)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun u64 tmp;
315*4882a593Smuzhiyun
316*4882a593Smuzhiyun tmp = (u64) ifhz * 16777216;
317*4882a593Smuzhiyun do_div(tmp, ((xtal == SONY_XTAL_24000) ? 48000000 : 41000000));
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun return (u32) tmp;
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun
cxd2841er_calc_iffreq(u32 ifhz)322*4882a593Smuzhiyun static u32 cxd2841er_calc_iffreq(u32 ifhz)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun return cxd2841er_calc_iffreq_xtal(SONY_XTAL_20500, ifhz);
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun
cxd2841er_get_if_hz(struct cxd2841er_priv * priv,u32 def_hz)327*4882a593Smuzhiyun static int cxd2841er_get_if_hz(struct cxd2841er_priv *priv, u32 def_hz)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun u32 hz;
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun if (priv->frontend.ops.tuner_ops.get_if_frequency
332*4882a593Smuzhiyun && (priv->flags & CXD2841ER_AUTO_IFHZ))
333*4882a593Smuzhiyun priv->frontend.ops.tuner_ops.get_if_frequency(
334*4882a593Smuzhiyun &priv->frontend, &hz);
335*4882a593Smuzhiyun else
336*4882a593Smuzhiyun hz = def_hz;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun return hz;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun
cxd2841er_tuner_set(struct dvb_frontend * fe)341*4882a593Smuzhiyun static int cxd2841er_tuner_set(struct dvb_frontend *fe)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl)
346*4882a593Smuzhiyun fe->ops.i2c_gate_ctrl(fe, 1);
347*4882a593Smuzhiyun if (fe->ops.tuner_ops.set_params)
348*4882a593Smuzhiyun fe->ops.tuner_ops.set_params(fe);
349*4882a593Smuzhiyun if ((priv->flags & CXD2841ER_USE_GATECTRL) && fe->ops.i2c_gate_ctrl)
350*4882a593Smuzhiyun fe->ops.i2c_gate_ctrl(fe, 0);
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun return 0;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
cxd2841er_dvbs2_set_symbol_rate(struct cxd2841er_priv * priv,u32 symbol_rate)355*4882a593Smuzhiyun static int cxd2841er_dvbs2_set_symbol_rate(struct cxd2841er_priv *priv,
356*4882a593Smuzhiyun u32 symbol_rate)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun u32 reg_value = 0;
359*4882a593Smuzhiyun u8 data[3] = {0, 0, 0};
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
362*4882a593Smuzhiyun /*
363*4882a593Smuzhiyun * regValue = (symbolRateKSps * 2^14 / 1000) + 0.5
364*4882a593Smuzhiyun * = ((symbolRateKSps * 2^14) + 500) / 1000
365*4882a593Smuzhiyun * = ((symbolRateKSps * 16384) + 500) / 1000
366*4882a593Smuzhiyun */
367*4882a593Smuzhiyun reg_value = DIV_ROUND_CLOSEST(symbol_rate * 16384, 1000);
368*4882a593Smuzhiyun if ((reg_value == 0) || (reg_value > 0xFFFFF)) {
369*4882a593Smuzhiyun dev_err(&priv->i2c->dev,
370*4882a593Smuzhiyun "%s(): reg_value is out of range\n", __func__);
371*4882a593Smuzhiyun return -EINVAL;
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun data[0] = (u8)((reg_value >> 16) & 0x0F);
374*4882a593Smuzhiyun data[1] = (u8)((reg_value >> 8) & 0xFF);
375*4882a593Smuzhiyun data[2] = (u8)(reg_value & 0xFF);
376*4882a593Smuzhiyun /* Set SLV-T Bank : 0xAE */
377*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xae);
378*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x20, data, 3);
379*4882a593Smuzhiyun return 0;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
383*4882a593Smuzhiyun u8 system);
384*4882a593Smuzhiyun
cxd2841er_sleep_s_to_active_s(struct cxd2841er_priv * priv,u8 system,u32 symbol_rate)385*4882a593Smuzhiyun static int cxd2841er_sleep_s_to_active_s(struct cxd2841er_priv *priv,
386*4882a593Smuzhiyun u8 system, u32 symbol_rate)
387*4882a593Smuzhiyun {
388*4882a593Smuzhiyun int ret;
389*4882a593Smuzhiyun u8 data[4] = { 0, 0, 0, 0 };
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun if (priv->state != STATE_SLEEP_S) {
392*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
393*4882a593Smuzhiyun __func__, (int)priv->state);
394*4882a593Smuzhiyun return -EINVAL;
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
397*4882a593Smuzhiyun cxd2841er_set_ts_clock_mode(priv, SYS_DVBS);
398*4882a593Smuzhiyun /* Set demod mode */
399*4882a593Smuzhiyun if (system == SYS_DVBS) {
400*4882a593Smuzhiyun data[0] = 0x0A;
401*4882a593Smuzhiyun } else if (system == SYS_DVBS2) {
402*4882a593Smuzhiyun data[0] = 0x0B;
403*4882a593Smuzhiyun } else {
404*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid delsys %d\n",
405*4882a593Smuzhiyun __func__, system);
406*4882a593Smuzhiyun return -EINVAL;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
409*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
410*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x17, data[0]);
411*4882a593Smuzhiyun /* DVB-S/S2 */
412*4882a593Smuzhiyun data[0] = 0x00;
413*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
414*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
415*4882a593Smuzhiyun /* Enable S/S2 auto detection 1 */
416*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2d, data[0]);
417*4882a593Smuzhiyun /* Set SLV-T Bank : 0xAE */
418*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xae);
419*4882a593Smuzhiyun /* Enable S/S2 auto detection 2 */
420*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x30, data[0]);
421*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
422*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
423*4882a593Smuzhiyun /* Enable demod clock */
424*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01);
425*4882a593Smuzhiyun /* Enable ADC clock */
426*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x31, 0x01);
427*4882a593Smuzhiyun /* Enable ADC 1 */
428*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16);
429*4882a593Smuzhiyun /* Enable ADC 2 */
430*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x3f);
431*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
432*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
433*4882a593Smuzhiyun /* Enable ADC 3 */
434*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
435*4882a593Smuzhiyun /* Set SLV-T Bank : 0xA3 */
436*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa3);
437*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xac, 0x00);
438*4882a593Smuzhiyun data[0] = 0x07;
439*4882a593Smuzhiyun data[1] = 0x3B;
440*4882a593Smuzhiyun data[2] = 0x08;
441*4882a593Smuzhiyun data[3] = 0xC5;
442*4882a593Smuzhiyun /* Set SLV-T Bank : 0xAB */
443*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xab);
444*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x98, data, 4);
445*4882a593Smuzhiyun data[0] = 0x05;
446*4882a593Smuzhiyun data[1] = 0x80;
447*4882a593Smuzhiyun data[2] = 0x0A;
448*4882a593Smuzhiyun data[3] = 0x80;
449*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xa8, data, 4);
450*4882a593Smuzhiyun data[0] = 0x0C;
451*4882a593Smuzhiyun data[1] = 0xCC;
452*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xc3, data, 2);
453*4882a593Smuzhiyun /* Set demod parameter */
454*4882a593Smuzhiyun ret = cxd2841er_dvbs2_set_symbol_rate(priv, symbol_rate);
455*4882a593Smuzhiyun if (ret != 0)
456*4882a593Smuzhiyun return ret;
457*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
458*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
459*4882a593Smuzhiyun /* disable Hi-Z setting 1 */
460*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x10);
461*4882a593Smuzhiyun /* disable Hi-Z setting 2 */
462*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00);
463*4882a593Smuzhiyun priv->state = STATE_ACTIVE_S;
464*4882a593Smuzhiyun return 0;
465*4882a593Smuzhiyun }
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_t_band(struct cxd2841er_priv *priv,
468*4882a593Smuzhiyun u32 bandwidth);
469*4882a593Smuzhiyun
470*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
471*4882a593Smuzhiyun u32 bandwidth);
472*4882a593Smuzhiyun
473*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
474*4882a593Smuzhiyun u32 bandwidth);
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv,
477*4882a593Smuzhiyun u32 bandwidth);
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun static int cxd2841er_active_i_to_sleep_tc(struct cxd2841er_priv *priv);
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_shutdown(struct cxd2841er_priv *priv);
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv);
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun static int cxd2841er_sleep_tc(struct dvb_frontend *fe);
486*4882a593Smuzhiyun
cxd2841er_retune_active(struct cxd2841er_priv * priv,struct dtv_frontend_properties * p)487*4882a593Smuzhiyun static int cxd2841er_retune_active(struct cxd2841er_priv *priv,
488*4882a593Smuzhiyun struct dtv_frontend_properties *p)
489*4882a593Smuzhiyun {
490*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
491*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_S &&
492*4882a593Smuzhiyun priv->state != STATE_ACTIVE_TC) {
493*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
494*4882a593Smuzhiyun __func__, priv->state);
495*4882a593Smuzhiyun return -EINVAL;
496*4882a593Smuzhiyun }
497*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
498*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
499*4882a593Smuzhiyun /* disable TS output */
500*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
501*4882a593Smuzhiyun if (priv->state == STATE_ACTIVE_S)
502*4882a593Smuzhiyun return cxd2841er_dvbs2_set_symbol_rate(
503*4882a593Smuzhiyun priv, p->symbol_rate / 1000);
504*4882a593Smuzhiyun else if (priv->state == STATE_ACTIVE_TC) {
505*4882a593Smuzhiyun switch (priv->system) {
506*4882a593Smuzhiyun case SYS_DVBT:
507*4882a593Smuzhiyun return cxd2841er_sleep_tc_to_active_t_band(
508*4882a593Smuzhiyun priv, p->bandwidth_hz);
509*4882a593Smuzhiyun case SYS_DVBT2:
510*4882a593Smuzhiyun return cxd2841er_sleep_tc_to_active_t2_band(
511*4882a593Smuzhiyun priv, p->bandwidth_hz);
512*4882a593Smuzhiyun case SYS_DVBC_ANNEX_A:
513*4882a593Smuzhiyun return cxd2841er_sleep_tc_to_active_c_band(
514*4882a593Smuzhiyun priv, p->bandwidth_hz);
515*4882a593Smuzhiyun case SYS_ISDBT:
516*4882a593Smuzhiyun cxd2841er_active_i_to_sleep_tc(priv);
517*4882a593Smuzhiyun cxd2841er_sleep_tc_to_shutdown(priv);
518*4882a593Smuzhiyun cxd2841er_shutdown_to_sleep_tc(priv);
519*4882a593Smuzhiyun return cxd2841er_sleep_tc_to_active_i(
520*4882a593Smuzhiyun priv, p->bandwidth_hz);
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
524*4882a593Smuzhiyun __func__, priv->system);
525*4882a593Smuzhiyun return -EINVAL;
526*4882a593Smuzhiyun }
527*4882a593Smuzhiyun
cxd2841er_active_s_to_sleep_s(struct cxd2841er_priv * priv)528*4882a593Smuzhiyun static int cxd2841er_active_s_to_sleep_s(struct cxd2841er_priv *priv)
529*4882a593Smuzhiyun {
530*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
531*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_S) {
532*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
533*4882a593Smuzhiyun __func__, priv->state);
534*4882a593Smuzhiyun return -EINVAL;
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
537*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
538*4882a593Smuzhiyun /* disable TS output */
539*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
540*4882a593Smuzhiyun /* enable Hi-Z setting 1 */
541*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x1f);
542*4882a593Smuzhiyun /* enable Hi-Z setting 2 */
543*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);
544*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
545*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
546*4882a593Smuzhiyun /* disable ADC 1 */
547*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
548*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
549*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
550*4882a593Smuzhiyun /* disable ADC clock */
551*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x31, 0x00);
552*4882a593Smuzhiyun /* disable ADC 2 */
553*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16);
554*4882a593Smuzhiyun /* disable ADC 3 */
555*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x27);
556*4882a593Smuzhiyun /* SADC Bias ON */
557*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x69, 0x06);
558*4882a593Smuzhiyun /* disable demod clock */
559*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
560*4882a593Smuzhiyun /* Set SLV-T Bank : 0xAE */
561*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xae);
562*4882a593Smuzhiyun /* disable S/S2 auto detection1 */
563*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
564*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
565*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
566*4882a593Smuzhiyun /* disable S/S2 auto detection2 */
567*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2d, 0x00);
568*4882a593Smuzhiyun priv->state = STATE_SLEEP_S;
569*4882a593Smuzhiyun return 0;
570*4882a593Smuzhiyun }
571*4882a593Smuzhiyun
cxd2841er_sleep_s_to_shutdown(struct cxd2841er_priv * priv)572*4882a593Smuzhiyun static int cxd2841er_sleep_s_to_shutdown(struct cxd2841er_priv *priv)
573*4882a593Smuzhiyun {
574*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
575*4882a593Smuzhiyun if (priv->state != STATE_SLEEP_S) {
576*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n",
577*4882a593Smuzhiyun __func__, priv->state);
578*4882a593Smuzhiyun return -EINVAL;
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
581*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
582*4882a593Smuzhiyun /* Disable DSQOUT */
583*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
584*4882a593Smuzhiyun /* Disable DSQIN */
585*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x9c, 0x00);
586*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
587*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
588*4882a593Smuzhiyun /* Disable oscillator */
589*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x15, 0x01);
590*4882a593Smuzhiyun /* Set demod mode */
591*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x01);
592*4882a593Smuzhiyun priv->state = STATE_SHUTDOWN;
593*4882a593Smuzhiyun return 0;
594*4882a593Smuzhiyun }
595*4882a593Smuzhiyun
cxd2841er_sleep_tc_to_shutdown(struct cxd2841er_priv * priv)596*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_shutdown(struct cxd2841er_priv *priv)
597*4882a593Smuzhiyun {
598*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
599*4882a593Smuzhiyun if (priv->state != STATE_SLEEP_TC) {
600*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n",
601*4882a593Smuzhiyun __func__, priv->state);
602*4882a593Smuzhiyun return -EINVAL;
603*4882a593Smuzhiyun }
604*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
605*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
606*4882a593Smuzhiyun /* Disable oscillator */
607*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x15, 0x01);
608*4882a593Smuzhiyun /* Set demod mode */
609*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x01);
610*4882a593Smuzhiyun priv->state = STATE_SHUTDOWN;
611*4882a593Smuzhiyun return 0;
612*4882a593Smuzhiyun }
613*4882a593Smuzhiyun
cxd2841er_active_t_to_sleep_tc(struct cxd2841er_priv * priv)614*4882a593Smuzhiyun static int cxd2841er_active_t_to_sleep_tc(struct cxd2841er_priv *priv)
615*4882a593Smuzhiyun {
616*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
617*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
618*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
619*4882a593Smuzhiyun __func__, priv->state);
620*4882a593Smuzhiyun return -EINVAL;
621*4882a593Smuzhiyun }
622*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
623*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
624*4882a593Smuzhiyun /* disable TS output */
625*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
626*4882a593Smuzhiyun /* enable Hi-Z setting 1 */
627*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
628*4882a593Smuzhiyun /* enable Hi-Z setting 2 */
629*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);
630*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
631*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
632*4882a593Smuzhiyun /* disable ADC 1 */
633*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
634*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
635*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
636*4882a593Smuzhiyun /* Disable ADC 2 */
637*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
638*4882a593Smuzhiyun /* Disable ADC 3 */
639*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
640*4882a593Smuzhiyun /* Disable ADC clock */
641*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
642*4882a593Smuzhiyun /* Disable RF level monitor */
643*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
644*4882a593Smuzhiyun /* Disable demod clock */
645*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
646*4882a593Smuzhiyun priv->state = STATE_SLEEP_TC;
647*4882a593Smuzhiyun return 0;
648*4882a593Smuzhiyun }
649*4882a593Smuzhiyun
cxd2841er_active_t2_to_sleep_tc(struct cxd2841er_priv * priv)650*4882a593Smuzhiyun static int cxd2841er_active_t2_to_sleep_tc(struct cxd2841er_priv *priv)
651*4882a593Smuzhiyun {
652*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
653*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
654*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
655*4882a593Smuzhiyun __func__, priv->state);
656*4882a593Smuzhiyun return -EINVAL;
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
659*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
660*4882a593Smuzhiyun /* disable TS output */
661*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
662*4882a593Smuzhiyun /* enable Hi-Z setting 1 */
663*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
664*4882a593Smuzhiyun /* enable Hi-Z setting 2 */
665*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);
666*4882a593Smuzhiyun /* Cancel DVB-T2 setting */
667*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13);
668*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x83, 0x40);
669*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x86, 0x21);
670*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x9e, 0x09, 0x0f);
671*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x9f, 0xfb);
672*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2a);
673*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x38, 0x00, 0x0f);
674*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b);
675*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x11, 0x00, 0x3f);
676*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
677*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
678*4882a593Smuzhiyun /* disable ADC 1 */
679*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
680*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
681*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
682*4882a593Smuzhiyun /* Disable ADC 2 */
683*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
684*4882a593Smuzhiyun /* Disable ADC 3 */
685*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
686*4882a593Smuzhiyun /* Disable ADC clock */
687*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
688*4882a593Smuzhiyun /* Disable RF level monitor */
689*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
690*4882a593Smuzhiyun /* Disable demod clock */
691*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
692*4882a593Smuzhiyun priv->state = STATE_SLEEP_TC;
693*4882a593Smuzhiyun return 0;
694*4882a593Smuzhiyun }
695*4882a593Smuzhiyun
cxd2841er_active_c_to_sleep_tc(struct cxd2841er_priv * priv)696*4882a593Smuzhiyun static int cxd2841er_active_c_to_sleep_tc(struct cxd2841er_priv *priv)
697*4882a593Smuzhiyun {
698*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
699*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
700*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
701*4882a593Smuzhiyun __func__, priv->state);
702*4882a593Smuzhiyun return -EINVAL;
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
705*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
706*4882a593Smuzhiyun /* disable TS output */
707*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
708*4882a593Smuzhiyun /* enable Hi-Z setting 1 */
709*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
710*4882a593Smuzhiyun /* enable Hi-Z setting 2 */
711*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);
712*4882a593Smuzhiyun /* Cancel DVB-C setting */
713*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11);
714*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa3, 0x00, 0x1f);
715*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
716*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
717*4882a593Smuzhiyun /* disable ADC 1 */
718*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
719*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
720*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
721*4882a593Smuzhiyun /* Disable ADC 2 */
722*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
723*4882a593Smuzhiyun /* Disable ADC 3 */
724*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
725*4882a593Smuzhiyun /* Disable ADC clock */
726*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
727*4882a593Smuzhiyun /* Disable RF level monitor */
728*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
729*4882a593Smuzhiyun /* Disable demod clock */
730*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
731*4882a593Smuzhiyun priv->state = STATE_SLEEP_TC;
732*4882a593Smuzhiyun return 0;
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun
cxd2841er_active_i_to_sleep_tc(struct cxd2841er_priv * priv)735*4882a593Smuzhiyun static int cxd2841er_active_i_to_sleep_tc(struct cxd2841er_priv *priv)
736*4882a593Smuzhiyun {
737*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
738*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
739*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
740*4882a593Smuzhiyun __func__, priv->state);
741*4882a593Smuzhiyun return -EINVAL;
742*4882a593Smuzhiyun }
743*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
744*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
745*4882a593Smuzhiyun /* disable TS output */
746*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x01);
747*4882a593Smuzhiyun /* enable Hi-Z setting 1 */
748*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x3f);
749*4882a593Smuzhiyun /* enable Hi-Z setting 2 */
750*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0xff);
751*4882a593Smuzhiyun
752*4882a593Smuzhiyun /* TODO: Cancel demod parameter */
753*4882a593Smuzhiyun
754*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
755*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
756*4882a593Smuzhiyun /* disable ADC 1 */
757*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x01);
758*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
759*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
760*4882a593Smuzhiyun /* Disable ADC 2 */
761*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
762*4882a593Smuzhiyun /* Disable ADC 3 */
763*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
764*4882a593Smuzhiyun /* Disable ADC clock */
765*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
766*4882a593Smuzhiyun /* Disable RF level monitor */
767*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
768*4882a593Smuzhiyun /* Disable demod clock */
769*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x00);
770*4882a593Smuzhiyun priv->state = STATE_SLEEP_TC;
771*4882a593Smuzhiyun return 0;
772*4882a593Smuzhiyun }
773*4882a593Smuzhiyun
cxd2841er_shutdown_to_sleep_s(struct cxd2841er_priv * priv)774*4882a593Smuzhiyun static int cxd2841er_shutdown_to_sleep_s(struct cxd2841er_priv *priv)
775*4882a593Smuzhiyun {
776*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
777*4882a593Smuzhiyun if (priv->state != STATE_SHUTDOWN) {
778*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n",
779*4882a593Smuzhiyun __func__, priv->state);
780*4882a593Smuzhiyun return -EINVAL;
781*4882a593Smuzhiyun }
782*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
783*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
784*4882a593Smuzhiyun /* Clear all demodulator registers */
785*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x02, 0x00);
786*4882a593Smuzhiyun usleep_range(3000, 5000);
787*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
788*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
789*4882a593Smuzhiyun /* Set demod SW reset */
790*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x01);
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun switch (priv->xtal) {
793*4882a593Smuzhiyun case SONY_XTAL_20500:
794*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x00);
795*4882a593Smuzhiyun break;
796*4882a593Smuzhiyun case SONY_XTAL_24000:
797*4882a593Smuzhiyun /* Select demod frequency */
798*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00);
799*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x03);
800*4882a593Smuzhiyun break;
801*4882a593Smuzhiyun case SONY_XTAL_41000:
802*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x14, 0x01);
803*4882a593Smuzhiyun break;
804*4882a593Smuzhiyun default:
805*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid demod xtal %d\n",
806*4882a593Smuzhiyun __func__, priv->xtal);
807*4882a593Smuzhiyun return -EINVAL;
808*4882a593Smuzhiyun }
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun /* Set demod mode */
811*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x0a);
812*4882a593Smuzhiyun /* Clear demod SW reset */
813*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x00);
814*4882a593Smuzhiyun usleep_range(1000, 2000);
815*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
816*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
817*4882a593Smuzhiyun /* enable DSQOUT */
818*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x1F);
819*4882a593Smuzhiyun /* enable DSQIN */
820*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x9C, 0x40);
821*4882a593Smuzhiyun /* TADC Bias On */
822*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
823*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
824*4882a593Smuzhiyun /* SADC Bias On */
825*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16);
826*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x27);
827*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x69, 0x06);
828*4882a593Smuzhiyun priv->state = STATE_SLEEP_S;
829*4882a593Smuzhiyun return 0;
830*4882a593Smuzhiyun }
831*4882a593Smuzhiyun
cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv * priv)832*4882a593Smuzhiyun static int cxd2841er_shutdown_to_sleep_tc(struct cxd2841er_priv *priv)
833*4882a593Smuzhiyun {
834*4882a593Smuzhiyun u8 data = 0;
835*4882a593Smuzhiyun
836*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
837*4882a593Smuzhiyun if (priv->state != STATE_SHUTDOWN) {
838*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid demod state %d\n",
839*4882a593Smuzhiyun __func__, priv->state);
840*4882a593Smuzhiyun return -EINVAL;
841*4882a593Smuzhiyun }
842*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
843*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
844*4882a593Smuzhiyun /* Clear all demodulator registers */
845*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x02, 0x00);
846*4882a593Smuzhiyun usleep_range(3000, 5000);
847*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
848*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
849*4882a593Smuzhiyun /* Set demod SW reset */
850*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x01);
851*4882a593Smuzhiyun /* Select ADC clock mode */
852*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x13, 0x00);
853*4882a593Smuzhiyun
854*4882a593Smuzhiyun switch (priv->xtal) {
855*4882a593Smuzhiyun case SONY_XTAL_20500:
856*4882a593Smuzhiyun data = 0x0;
857*4882a593Smuzhiyun break;
858*4882a593Smuzhiyun case SONY_XTAL_24000:
859*4882a593Smuzhiyun /* Select demod frequency */
860*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00);
861*4882a593Smuzhiyun data = 0x3;
862*4882a593Smuzhiyun break;
863*4882a593Smuzhiyun case SONY_XTAL_41000:
864*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x12, 0x00);
865*4882a593Smuzhiyun data = 0x1;
866*4882a593Smuzhiyun break;
867*4882a593Smuzhiyun }
868*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x14, data);
869*4882a593Smuzhiyun /* Clear demod SW reset */
870*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x10, 0x00);
871*4882a593Smuzhiyun usleep_range(1000, 2000);
872*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
873*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
874*4882a593Smuzhiyun /* TADC Bias On */
875*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x43, 0x0a);
876*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x0a);
877*4882a593Smuzhiyun /* SADC Bias On */
878*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x63, 0x16);
879*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x65, 0x27);
880*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x69, 0x06);
881*4882a593Smuzhiyun priv->state = STATE_SLEEP_TC;
882*4882a593Smuzhiyun return 0;
883*4882a593Smuzhiyun }
884*4882a593Smuzhiyun
cxd2841er_tune_done(struct cxd2841er_priv * priv)885*4882a593Smuzhiyun static int cxd2841er_tune_done(struct cxd2841er_priv *priv)
886*4882a593Smuzhiyun {
887*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
888*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
889*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0, 0);
890*4882a593Smuzhiyun /* SW Reset */
891*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xfe, 0x01);
892*4882a593Smuzhiyun /* Enable TS output */
893*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xc3, 0x00);
894*4882a593Smuzhiyun return 0;
895*4882a593Smuzhiyun }
896*4882a593Smuzhiyun
897*4882a593Smuzhiyun /* Set TS parallel mode */
cxd2841er_set_ts_clock_mode(struct cxd2841er_priv * priv,u8 system)898*4882a593Smuzhiyun static void cxd2841er_set_ts_clock_mode(struct cxd2841er_priv *priv,
899*4882a593Smuzhiyun u8 system)
900*4882a593Smuzhiyun {
901*4882a593Smuzhiyun u8 serial_ts, ts_rate_ctrl_off, ts_in_off;
902*4882a593Smuzhiyun
903*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
904*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
905*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
906*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0xc4, &serial_ts);
907*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0xd3, &ts_rate_ctrl_off);
908*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0xde, &ts_in_off);
909*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): ser_ts=0x%02x rate_ctrl_off=0x%02x in_off=0x%02x\n",
910*4882a593Smuzhiyun __func__, serial_ts, ts_rate_ctrl_off, ts_in_off);
911*4882a593Smuzhiyun
912*4882a593Smuzhiyun /*
913*4882a593Smuzhiyun * slave Bank Addr Bit default Name
914*4882a593Smuzhiyun * <SLV-T> 00h C4h [1:0] 2'b?? OSERCKMODE
915*4882a593Smuzhiyun */
916*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
917*4882a593Smuzhiyun ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
918*4882a593Smuzhiyun /*
919*4882a593Smuzhiyun * slave Bank Addr Bit default Name
920*4882a593Smuzhiyun * <SLV-T> 00h D1h [1:0] 2'b?? OSERDUTYMODE
921*4882a593Smuzhiyun */
922*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd1,
923*4882a593Smuzhiyun ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
924*4882a593Smuzhiyun /*
925*4882a593Smuzhiyun * slave Bank Addr Bit default Name
926*4882a593Smuzhiyun * <SLV-T> 00h D9h [7:0] 8'h08 OTSCKPERIOD
927*4882a593Smuzhiyun */
928*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xd9, 0x08);
929*4882a593Smuzhiyun /*
930*4882a593Smuzhiyun * Disable TS IF Clock
931*4882a593Smuzhiyun * slave Bank Addr Bit default Name
932*4882a593Smuzhiyun * <SLV-T> 00h 32h [0] 1'b1 OREG_CK_TSIF_EN
933*4882a593Smuzhiyun */
934*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x32, 0x00, 0x01);
935*4882a593Smuzhiyun /*
936*4882a593Smuzhiyun * slave Bank Addr Bit default Name
937*4882a593Smuzhiyun * <SLV-T> 00h 33h [1:0] 2'b01 OREG_CKSEL_TSIF
938*4882a593Smuzhiyun */
939*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x33,
940*4882a593Smuzhiyun ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x01 : 0x00), 0x03);
941*4882a593Smuzhiyun /*
942*4882a593Smuzhiyun * Enable TS IF Clock
943*4882a593Smuzhiyun * slave Bank Addr Bit default Name
944*4882a593Smuzhiyun * <SLV-T> 00h 32h [0] 1'b1 OREG_CK_TSIF_EN
945*4882a593Smuzhiyun */
946*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x32, 0x01, 0x01);
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun if (system == SYS_DVBT) {
949*4882a593Smuzhiyun /* Enable parity period for DVB-T */
950*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
951*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x66, 0x01, 0x01);
952*4882a593Smuzhiyun } else if (system == SYS_DVBC_ANNEX_A) {
953*4882a593Smuzhiyun /* Enable parity period for DVB-C */
954*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
955*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x66, 0x01, 0x01);
956*4882a593Smuzhiyun }
957*4882a593Smuzhiyun }
958*4882a593Smuzhiyun
cxd2841er_chip_id(struct cxd2841er_priv * priv)959*4882a593Smuzhiyun static u8 cxd2841er_chip_id(struct cxd2841er_priv *priv)
960*4882a593Smuzhiyun {
961*4882a593Smuzhiyun u8 chip_id = 0;
962*4882a593Smuzhiyun
963*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
964*4882a593Smuzhiyun if (cxd2841er_write_reg(priv, I2C_SLVT, 0, 0) == 0)
965*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0xfd, &chip_id);
966*4882a593Smuzhiyun else if (cxd2841er_write_reg(priv, I2C_SLVX, 0, 0) == 0)
967*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVX, 0xfd, &chip_id);
968*4882a593Smuzhiyun
969*4882a593Smuzhiyun return chip_id;
970*4882a593Smuzhiyun }
971*4882a593Smuzhiyun
cxd2841er_read_status_s(struct dvb_frontend * fe,enum fe_status * status)972*4882a593Smuzhiyun static int cxd2841er_read_status_s(struct dvb_frontend *fe,
973*4882a593Smuzhiyun enum fe_status *status)
974*4882a593Smuzhiyun {
975*4882a593Smuzhiyun u8 reg = 0;
976*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
977*4882a593Smuzhiyun
978*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
979*4882a593Smuzhiyun *status = 0;
980*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_S) {
981*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
982*4882a593Smuzhiyun __func__, priv->state);
983*4882a593Smuzhiyun return -EINVAL;
984*4882a593Smuzhiyun }
985*4882a593Smuzhiyun /* Set SLV-T Bank : 0xA0 */
986*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
987*4882a593Smuzhiyun /*
988*4882a593Smuzhiyun * slave Bank Addr Bit Signal name
989*4882a593Smuzhiyun * <SLV-T> A0h 11h [2] ITSLOCK
990*4882a593Smuzhiyun */
991*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x11, ®);
992*4882a593Smuzhiyun if (reg & 0x04) {
993*4882a593Smuzhiyun *status = FE_HAS_SIGNAL
994*4882a593Smuzhiyun | FE_HAS_CARRIER
995*4882a593Smuzhiyun | FE_HAS_VITERBI
996*4882a593Smuzhiyun | FE_HAS_SYNC
997*4882a593Smuzhiyun | FE_HAS_LOCK;
998*4882a593Smuzhiyun }
999*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): result 0x%x\n", __func__, *status);
1000*4882a593Smuzhiyun return 0;
1001*4882a593Smuzhiyun }
1002*4882a593Smuzhiyun
cxd2841er_read_status_t_t2(struct cxd2841er_priv * priv,u8 * sync,u8 * tslock,u8 * unlock)1003*4882a593Smuzhiyun static int cxd2841er_read_status_t_t2(struct cxd2841er_priv *priv,
1004*4882a593Smuzhiyun u8 *sync, u8 *tslock, u8 *unlock)
1005*4882a593Smuzhiyun {
1006*4882a593Smuzhiyun u8 data = 0;
1007*4882a593Smuzhiyun
1008*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1009*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC)
1010*4882a593Smuzhiyun return -EINVAL;
1011*4882a593Smuzhiyun if (priv->system == SYS_DVBT) {
1012*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
1013*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1014*4882a593Smuzhiyun } else {
1015*4882a593Smuzhiyun /* Set SLV-T Bank : 0x20 */
1016*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
1017*4882a593Smuzhiyun }
1018*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data);
1019*4882a593Smuzhiyun if ((data & 0x07) == 0x07) {
1020*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1021*4882a593Smuzhiyun "%s(): invalid hardware state detected\n", __func__);
1022*4882a593Smuzhiyun *sync = 0;
1023*4882a593Smuzhiyun *tslock = 0;
1024*4882a593Smuzhiyun *unlock = 0;
1025*4882a593Smuzhiyun } else {
1026*4882a593Smuzhiyun *sync = ((data & 0x07) == 0x6 ? 1 : 0);
1027*4882a593Smuzhiyun *tslock = ((data & 0x20) ? 1 : 0);
1028*4882a593Smuzhiyun *unlock = ((data & 0x10) ? 1 : 0);
1029*4882a593Smuzhiyun }
1030*4882a593Smuzhiyun return 0;
1031*4882a593Smuzhiyun }
1032*4882a593Smuzhiyun
cxd2841er_read_status_c(struct cxd2841er_priv * priv,u8 * tslock)1033*4882a593Smuzhiyun static int cxd2841er_read_status_c(struct cxd2841er_priv *priv, u8 *tslock)
1034*4882a593Smuzhiyun {
1035*4882a593Smuzhiyun u8 data;
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1038*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC)
1039*4882a593Smuzhiyun return -EINVAL;
1040*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
1041*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x88, &data);
1042*4882a593Smuzhiyun if ((data & 0x01) == 0) {
1043*4882a593Smuzhiyun *tslock = 0;
1044*4882a593Smuzhiyun } else {
1045*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data);
1046*4882a593Smuzhiyun *tslock = ((data & 0x20) ? 1 : 0);
1047*4882a593Smuzhiyun }
1048*4882a593Smuzhiyun return 0;
1049*4882a593Smuzhiyun }
1050*4882a593Smuzhiyun
cxd2841er_read_status_i(struct cxd2841er_priv * priv,u8 * sync,u8 * tslock,u8 * unlock)1051*4882a593Smuzhiyun static int cxd2841er_read_status_i(struct cxd2841er_priv *priv,
1052*4882a593Smuzhiyun u8 *sync, u8 *tslock, u8 *unlock)
1053*4882a593Smuzhiyun {
1054*4882a593Smuzhiyun u8 data = 0;
1055*4882a593Smuzhiyun
1056*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1057*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC)
1058*4882a593Smuzhiyun return -EINVAL;
1059*4882a593Smuzhiyun /* Set SLV-T Bank : 0x60 */
1060*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
1061*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data);
1062*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1063*4882a593Smuzhiyun "%s(): lock=0x%x\n", __func__, data);
1064*4882a593Smuzhiyun *sync = ((data & 0x02) ? 1 : 0);
1065*4882a593Smuzhiyun *tslock = ((data & 0x01) ? 1 : 0);
1066*4882a593Smuzhiyun *unlock = ((data & 0x10) ? 1 : 0);
1067*4882a593Smuzhiyun return 0;
1068*4882a593Smuzhiyun }
1069*4882a593Smuzhiyun
cxd2841er_read_status_tc(struct dvb_frontend * fe,enum fe_status * status)1070*4882a593Smuzhiyun static int cxd2841er_read_status_tc(struct dvb_frontend *fe,
1071*4882a593Smuzhiyun enum fe_status *status)
1072*4882a593Smuzhiyun {
1073*4882a593Smuzhiyun int ret = 0;
1074*4882a593Smuzhiyun u8 sync = 0;
1075*4882a593Smuzhiyun u8 tslock = 0;
1076*4882a593Smuzhiyun u8 unlock = 0;
1077*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
1078*4882a593Smuzhiyun
1079*4882a593Smuzhiyun *status = 0;
1080*4882a593Smuzhiyun if (priv->state == STATE_ACTIVE_TC) {
1081*4882a593Smuzhiyun if (priv->system == SYS_DVBT || priv->system == SYS_DVBT2) {
1082*4882a593Smuzhiyun ret = cxd2841er_read_status_t_t2(
1083*4882a593Smuzhiyun priv, &sync, &tslock, &unlock);
1084*4882a593Smuzhiyun if (ret)
1085*4882a593Smuzhiyun goto done;
1086*4882a593Smuzhiyun if (unlock)
1087*4882a593Smuzhiyun goto done;
1088*4882a593Smuzhiyun if (sync)
1089*4882a593Smuzhiyun *status = FE_HAS_SIGNAL |
1090*4882a593Smuzhiyun FE_HAS_CARRIER |
1091*4882a593Smuzhiyun FE_HAS_VITERBI |
1092*4882a593Smuzhiyun FE_HAS_SYNC;
1093*4882a593Smuzhiyun if (tslock)
1094*4882a593Smuzhiyun *status |= FE_HAS_LOCK;
1095*4882a593Smuzhiyun } else if (priv->system == SYS_ISDBT) {
1096*4882a593Smuzhiyun ret = cxd2841er_read_status_i(
1097*4882a593Smuzhiyun priv, &sync, &tslock, &unlock);
1098*4882a593Smuzhiyun if (ret)
1099*4882a593Smuzhiyun goto done;
1100*4882a593Smuzhiyun if (unlock)
1101*4882a593Smuzhiyun goto done;
1102*4882a593Smuzhiyun if (sync)
1103*4882a593Smuzhiyun *status = FE_HAS_SIGNAL |
1104*4882a593Smuzhiyun FE_HAS_CARRIER |
1105*4882a593Smuzhiyun FE_HAS_VITERBI |
1106*4882a593Smuzhiyun FE_HAS_SYNC;
1107*4882a593Smuzhiyun if (tslock)
1108*4882a593Smuzhiyun *status |= FE_HAS_LOCK;
1109*4882a593Smuzhiyun } else if (priv->system == SYS_DVBC_ANNEX_A) {
1110*4882a593Smuzhiyun ret = cxd2841er_read_status_c(priv, &tslock);
1111*4882a593Smuzhiyun if (ret)
1112*4882a593Smuzhiyun goto done;
1113*4882a593Smuzhiyun if (tslock)
1114*4882a593Smuzhiyun *status = FE_HAS_SIGNAL |
1115*4882a593Smuzhiyun FE_HAS_CARRIER |
1116*4882a593Smuzhiyun FE_HAS_VITERBI |
1117*4882a593Smuzhiyun FE_HAS_SYNC |
1118*4882a593Smuzhiyun FE_HAS_LOCK;
1119*4882a593Smuzhiyun }
1120*4882a593Smuzhiyun }
1121*4882a593Smuzhiyun done:
1122*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): status 0x%x\n", __func__, *status);
1123*4882a593Smuzhiyun return ret;
1124*4882a593Smuzhiyun }
1125*4882a593Smuzhiyun
cxd2841er_get_carrier_offset_s_s2(struct cxd2841er_priv * priv,int * offset)1126*4882a593Smuzhiyun static int cxd2841er_get_carrier_offset_s_s2(struct cxd2841er_priv *priv,
1127*4882a593Smuzhiyun int *offset)
1128*4882a593Smuzhiyun {
1129*4882a593Smuzhiyun u8 data[3];
1130*4882a593Smuzhiyun u8 is_hs_mode;
1131*4882a593Smuzhiyun s32 cfrl_ctrlval;
1132*4882a593Smuzhiyun s32 temp_div, temp_q, temp_r;
1133*4882a593Smuzhiyun
1134*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_S) {
1135*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1136*4882a593Smuzhiyun __func__, priv->state);
1137*4882a593Smuzhiyun return -EINVAL;
1138*4882a593Smuzhiyun }
1139*4882a593Smuzhiyun /*
1140*4882a593Smuzhiyun * Get High Sampling Rate mode
1141*4882a593Smuzhiyun * slave Bank Addr Bit Signal name
1142*4882a593Smuzhiyun * <SLV-T> A0h 10h [0] ITRL_LOCK
1143*4882a593Smuzhiyun */
1144*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
1145*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x10, &data[0]);
1146*4882a593Smuzhiyun if (data[0] & 0x01) {
1147*4882a593Smuzhiyun /*
1148*4882a593Smuzhiyun * slave Bank Addr Bit Signal name
1149*4882a593Smuzhiyun * <SLV-T> A0h 50h [4] IHSMODE
1150*4882a593Smuzhiyun */
1151*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x50, &data[0]);
1152*4882a593Smuzhiyun is_hs_mode = (data[0] & 0x10 ? 1 : 0);
1153*4882a593Smuzhiyun } else {
1154*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1155*4882a593Smuzhiyun "%s(): unable to detect sampling rate mode\n",
1156*4882a593Smuzhiyun __func__);
1157*4882a593Smuzhiyun return -EINVAL;
1158*4882a593Smuzhiyun }
1159*4882a593Smuzhiyun /*
1160*4882a593Smuzhiyun * slave Bank Addr Bit Signal name
1161*4882a593Smuzhiyun * <SLV-T> A0h 45h [4:0] ICFRL_CTRLVAL[20:16]
1162*4882a593Smuzhiyun * <SLV-T> A0h 46h [7:0] ICFRL_CTRLVAL[15:8]
1163*4882a593Smuzhiyun * <SLV-T> A0h 47h [7:0] ICFRL_CTRLVAL[7:0]
1164*4882a593Smuzhiyun */
1165*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x45, data, 3);
1166*4882a593Smuzhiyun cfrl_ctrlval = sign_extend32((((u32)data[0] & 0x1F) << 16) |
1167*4882a593Smuzhiyun (((u32)data[1] & 0xFF) << 8) |
1168*4882a593Smuzhiyun ((u32)data[2] & 0xFF), 20);
1169*4882a593Smuzhiyun temp_div = (is_hs_mode ? 1048576 : 1572864);
1170*4882a593Smuzhiyun if (cfrl_ctrlval > 0) {
1171*4882a593Smuzhiyun temp_q = div_s64_rem(97375LL * cfrl_ctrlval,
1172*4882a593Smuzhiyun temp_div, &temp_r);
1173*4882a593Smuzhiyun } else {
1174*4882a593Smuzhiyun temp_q = div_s64_rem(-97375LL * cfrl_ctrlval,
1175*4882a593Smuzhiyun temp_div, &temp_r);
1176*4882a593Smuzhiyun }
1177*4882a593Smuzhiyun if (temp_r >= temp_div / 2)
1178*4882a593Smuzhiyun temp_q++;
1179*4882a593Smuzhiyun if (cfrl_ctrlval > 0)
1180*4882a593Smuzhiyun temp_q *= -1;
1181*4882a593Smuzhiyun *offset = temp_q;
1182*4882a593Smuzhiyun return 0;
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun
cxd2841er_get_carrier_offset_i(struct cxd2841er_priv * priv,u32 bandwidth,int * offset)1185*4882a593Smuzhiyun static int cxd2841er_get_carrier_offset_i(struct cxd2841er_priv *priv,
1186*4882a593Smuzhiyun u32 bandwidth, int *offset)
1187*4882a593Smuzhiyun {
1188*4882a593Smuzhiyun u8 data[4];
1189*4882a593Smuzhiyun
1190*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1191*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1192*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1193*4882a593Smuzhiyun __func__, priv->state);
1194*4882a593Smuzhiyun return -EINVAL;
1195*4882a593Smuzhiyun }
1196*4882a593Smuzhiyun if (priv->system != SYS_ISDBT) {
1197*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
1198*4882a593Smuzhiyun __func__, priv->system);
1199*4882a593Smuzhiyun return -EINVAL;
1200*4882a593Smuzhiyun }
1201*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
1202*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data));
1203*4882a593Smuzhiyun *offset = -1 * sign_extend32(
1204*4882a593Smuzhiyun ((u32)(data[0] & 0x1F) << 24) | ((u32)data[1] << 16) |
1205*4882a593Smuzhiyun ((u32)data[2] << 8) | (u32)data[3], 29);
1206*4882a593Smuzhiyun
1207*4882a593Smuzhiyun switch (bandwidth) {
1208*4882a593Smuzhiyun case 6000000:
1209*4882a593Smuzhiyun *offset = -1 * ((*offset) * 8/264);
1210*4882a593Smuzhiyun break;
1211*4882a593Smuzhiyun case 7000000:
1212*4882a593Smuzhiyun *offset = -1 * ((*offset) * 8/231);
1213*4882a593Smuzhiyun break;
1214*4882a593Smuzhiyun case 8000000:
1215*4882a593Smuzhiyun *offset = -1 * ((*offset) * 8/198);
1216*4882a593Smuzhiyun break;
1217*4882a593Smuzhiyun default:
1218*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n",
1219*4882a593Smuzhiyun __func__, bandwidth);
1220*4882a593Smuzhiyun return -EINVAL;
1221*4882a593Smuzhiyun }
1222*4882a593Smuzhiyun
1223*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): bandwidth %d offset %d\n",
1224*4882a593Smuzhiyun __func__, bandwidth, *offset);
1225*4882a593Smuzhiyun
1226*4882a593Smuzhiyun return 0;
1227*4882a593Smuzhiyun }
1228*4882a593Smuzhiyun
cxd2841er_get_carrier_offset_t(struct cxd2841er_priv * priv,u32 bandwidth,int * offset)1229*4882a593Smuzhiyun static int cxd2841er_get_carrier_offset_t(struct cxd2841er_priv *priv,
1230*4882a593Smuzhiyun u32 bandwidth, int *offset)
1231*4882a593Smuzhiyun {
1232*4882a593Smuzhiyun u8 data[4];
1233*4882a593Smuzhiyun
1234*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1235*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1236*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1237*4882a593Smuzhiyun __func__, priv->state);
1238*4882a593Smuzhiyun return -EINVAL;
1239*4882a593Smuzhiyun }
1240*4882a593Smuzhiyun if (priv->system != SYS_DVBT) {
1241*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
1242*4882a593Smuzhiyun __func__, priv->system);
1243*4882a593Smuzhiyun return -EINVAL;
1244*4882a593Smuzhiyun }
1245*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1246*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data));
1247*4882a593Smuzhiyun *offset = -1 * sign_extend32(
1248*4882a593Smuzhiyun ((u32)(data[0] & 0x1F) << 24) | ((u32)data[1] << 16) |
1249*4882a593Smuzhiyun ((u32)data[2] << 8) | (u32)data[3], 29);
1250*4882a593Smuzhiyun *offset *= (bandwidth / 1000000);
1251*4882a593Smuzhiyun *offset /= 235;
1252*4882a593Smuzhiyun return 0;
1253*4882a593Smuzhiyun }
1254*4882a593Smuzhiyun
cxd2841er_get_carrier_offset_t2(struct cxd2841er_priv * priv,u32 bandwidth,int * offset)1255*4882a593Smuzhiyun static int cxd2841er_get_carrier_offset_t2(struct cxd2841er_priv *priv,
1256*4882a593Smuzhiyun u32 bandwidth, int *offset)
1257*4882a593Smuzhiyun {
1258*4882a593Smuzhiyun u8 data[4];
1259*4882a593Smuzhiyun
1260*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1261*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1262*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1263*4882a593Smuzhiyun __func__, priv->state);
1264*4882a593Smuzhiyun return -EINVAL;
1265*4882a593Smuzhiyun }
1266*4882a593Smuzhiyun if (priv->system != SYS_DVBT2) {
1267*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
1268*4882a593Smuzhiyun __func__, priv->system);
1269*4882a593Smuzhiyun return -EINVAL;
1270*4882a593Smuzhiyun }
1271*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
1272*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x4c, data, sizeof(data));
1273*4882a593Smuzhiyun *offset = -1 * sign_extend32(
1274*4882a593Smuzhiyun ((u32)(data[0] & 0x0F) << 24) | ((u32)data[1] << 16) |
1275*4882a593Smuzhiyun ((u32)data[2] << 8) | (u32)data[3], 27);
1276*4882a593Smuzhiyun switch (bandwidth) {
1277*4882a593Smuzhiyun case 1712000:
1278*4882a593Smuzhiyun *offset /= 582;
1279*4882a593Smuzhiyun break;
1280*4882a593Smuzhiyun case 5000000:
1281*4882a593Smuzhiyun case 6000000:
1282*4882a593Smuzhiyun case 7000000:
1283*4882a593Smuzhiyun case 8000000:
1284*4882a593Smuzhiyun *offset *= (bandwidth / 1000000);
1285*4882a593Smuzhiyun *offset /= 940;
1286*4882a593Smuzhiyun break;
1287*4882a593Smuzhiyun default:
1288*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n",
1289*4882a593Smuzhiyun __func__, bandwidth);
1290*4882a593Smuzhiyun return -EINVAL;
1291*4882a593Smuzhiyun }
1292*4882a593Smuzhiyun return 0;
1293*4882a593Smuzhiyun }
1294*4882a593Smuzhiyun
cxd2841er_get_carrier_offset_c(struct cxd2841er_priv * priv,int * offset)1295*4882a593Smuzhiyun static int cxd2841er_get_carrier_offset_c(struct cxd2841er_priv *priv,
1296*4882a593Smuzhiyun int *offset)
1297*4882a593Smuzhiyun {
1298*4882a593Smuzhiyun u8 data[2];
1299*4882a593Smuzhiyun
1300*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1301*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1302*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1303*4882a593Smuzhiyun __func__, priv->state);
1304*4882a593Smuzhiyun return -EINVAL;
1305*4882a593Smuzhiyun }
1306*4882a593Smuzhiyun if (priv->system != SYS_DVBC_ANNEX_A) {
1307*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid delivery system %d\n",
1308*4882a593Smuzhiyun __func__, priv->system);
1309*4882a593Smuzhiyun return -EINVAL;
1310*4882a593Smuzhiyun }
1311*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
1312*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x15, data, sizeof(data));
1313*4882a593Smuzhiyun *offset = div_s64(41000LL * sign_extend32((((u32)data[0] & 0x3f) << 8)
1314*4882a593Smuzhiyun | (u32)data[1], 13), 16384);
1315*4882a593Smuzhiyun return 0;
1316*4882a593Smuzhiyun }
1317*4882a593Smuzhiyun
cxd2841er_read_packet_errors_c(struct cxd2841er_priv * priv,u32 * penum)1318*4882a593Smuzhiyun static int cxd2841er_read_packet_errors_c(
1319*4882a593Smuzhiyun struct cxd2841er_priv *priv, u32 *penum)
1320*4882a593Smuzhiyun {
1321*4882a593Smuzhiyun u8 data[3];
1322*4882a593Smuzhiyun
1323*4882a593Smuzhiyun *penum = 0;
1324*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1325*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1326*4882a593Smuzhiyun __func__, priv->state);
1327*4882a593Smuzhiyun return -EINVAL;
1328*4882a593Smuzhiyun }
1329*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
1330*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0xea, data, sizeof(data));
1331*4882a593Smuzhiyun if (data[2] & 0x01)
1332*4882a593Smuzhiyun *penum = ((u32)data[0] << 8) | (u32)data[1];
1333*4882a593Smuzhiyun return 0;
1334*4882a593Smuzhiyun }
1335*4882a593Smuzhiyun
cxd2841er_read_packet_errors_t(struct cxd2841er_priv * priv,u32 * penum)1336*4882a593Smuzhiyun static int cxd2841er_read_packet_errors_t(
1337*4882a593Smuzhiyun struct cxd2841er_priv *priv, u32 *penum)
1338*4882a593Smuzhiyun {
1339*4882a593Smuzhiyun u8 data[3];
1340*4882a593Smuzhiyun
1341*4882a593Smuzhiyun *penum = 0;
1342*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1343*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1344*4882a593Smuzhiyun __func__, priv->state);
1345*4882a593Smuzhiyun return -EINVAL;
1346*4882a593Smuzhiyun }
1347*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1348*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0xea, data, sizeof(data));
1349*4882a593Smuzhiyun if (data[2] & 0x01)
1350*4882a593Smuzhiyun *penum = ((u32)data[0] << 8) | (u32)data[1];
1351*4882a593Smuzhiyun return 0;
1352*4882a593Smuzhiyun }
1353*4882a593Smuzhiyun
cxd2841er_read_packet_errors_t2(struct cxd2841er_priv * priv,u32 * penum)1354*4882a593Smuzhiyun static int cxd2841er_read_packet_errors_t2(
1355*4882a593Smuzhiyun struct cxd2841er_priv *priv, u32 *penum)
1356*4882a593Smuzhiyun {
1357*4882a593Smuzhiyun u8 data[3];
1358*4882a593Smuzhiyun
1359*4882a593Smuzhiyun *penum = 0;
1360*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1361*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1362*4882a593Smuzhiyun __func__, priv->state);
1363*4882a593Smuzhiyun return -EINVAL;
1364*4882a593Smuzhiyun }
1365*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x24);
1366*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0xfd, data, sizeof(data));
1367*4882a593Smuzhiyun if (data[0] & 0x01)
1368*4882a593Smuzhiyun *penum = ((u32)data[1] << 8) | (u32)data[2];
1369*4882a593Smuzhiyun return 0;
1370*4882a593Smuzhiyun }
1371*4882a593Smuzhiyun
cxd2841er_read_packet_errors_i(struct cxd2841er_priv * priv,u32 * penum)1372*4882a593Smuzhiyun static int cxd2841er_read_packet_errors_i(
1373*4882a593Smuzhiyun struct cxd2841er_priv *priv, u32 *penum)
1374*4882a593Smuzhiyun {
1375*4882a593Smuzhiyun u8 data[2];
1376*4882a593Smuzhiyun
1377*4882a593Smuzhiyun *penum = 0;
1378*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1379*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1380*4882a593Smuzhiyun __func__, priv->state);
1381*4882a593Smuzhiyun return -EINVAL;
1382*4882a593Smuzhiyun }
1383*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
1384*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0xA1, data, 1);
1385*4882a593Smuzhiyun
1386*4882a593Smuzhiyun if (!(data[0] & 0x01))
1387*4882a593Smuzhiyun return 0;
1388*4882a593Smuzhiyun
1389*4882a593Smuzhiyun /* Layer A */
1390*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0xA2, data, sizeof(data));
1391*4882a593Smuzhiyun *penum = ((u32)data[0] << 8) | (u32)data[1];
1392*4882a593Smuzhiyun
1393*4882a593Smuzhiyun /* Layer B */
1394*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0xA4, data, sizeof(data));
1395*4882a593Smuzhiyun *penum += ((u32)data[0] << 8) | (u32)data[1];
1396*4882a593Smuzhiyun
1397*4882a593Smuzhiyun /* Layer C */
1398*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0xA6, data, sizeof(data));
1399*4882a593Smuzhiyun *penum += ((u32)data[0] << 8) | (u32)data[1];
1400*4882a593Smuzhiyun
1401*4882a593Smuzhiyun return 0;
1402*4882a593Smuzhiyun }
1403*4882a593Smuzhiyun
cxd2841er_read_ber_c(struct cxd2841er_priv * priv,u32 * bit_error,u32 * bit_count)1404*4882a593Smuzhiyun static int cxd2841er_read_ber_c(struct cxd2841er_priv *priv,
1405*4882a593Smuzhiyun u32 *bit_error, u32 *bit_count)
1406*4882a593Smuzhiyun {
1407*4882a593Smuzhiyun u8 data[3];
1408*4882a593Smuzhiyun u32 bit_err, period_exp;
1409*4882a593Smuzhiyun
1410*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1411*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1412*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1413*4882a593Smuzhiyun __func__, priv->state);
1414*4882a593Smuzhiyun return -EINVAL;
1415*4882a593Smuzhiyun }
1416*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
1417*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x62, data, sizeof(data));
1418*4882a593Smuzhiyun if (!(data[0] & 0x80)) {
1419*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1420*4882a593Smuzhiyun "%s(): no valid BER data\n", __func__);
1421*4882a593Smuzhiyun return -EINVAL;
1422*4882a593Smuzhiyun }
1423*4882a593Smuzhiyun bit_err = ((u32)(data[0] & 0x3f) << 16) |
1424*4882a593Smuzhiyun ((u32)data[1] << 8) |
1425*4882a593Smuzhiyun (u32)data[2];
1426*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x60, data);
1427*4882a593Smuzhiyun period_exp = data[0] & 0x1f;
1428*4882a593Smuzhiyun
1429*4882a593Smuzhiyun if ((period_exp <= 11) && (bit_err > (1 << period_exp) * 204 * 8)) {
1430*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1431*4882a593Smuzhiyun "%s(): period_exp(%u) or bit_err(%u) not in range. no valid BER data\n",
1432*4882a593Smuzhiyun __func__, period_exp, bit_err);
1433*4882a593Smuzhiyun return -EINVAL;
1434*4882a593Smuzhiyun }
1435*4882a593Smuzhiyun
1436*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1437*4882a593Smuzhiyun "%s(): period_exp(%u) or bit_err(%u) count=%d\n",
1438*4882a593Smuzhiyun __func__, period_exp, bit_err,
1439*4882a593Smuzhiyun ((1 << period_exp) * 204 * 8));
1440*4882a593Smuzhiyun
1441*4882a593Smuzhiyun *bit_error = bit_err;
1442*4882a593Smuzhiyun *bit_count = ((1 << period_exp) * 204 * 8);
1443*4882a593Smuzhiyun
1444*4882a593Smuzhiyun return 0;
1445*4882a593Smuzhiyun }
1446*4882a593Smuzhiyun
cxd2841er_read_ber_i(struct cxd2841er_priv * priv,u32 * bit_error,u32 * bit_count)1447*4882a593Smuzhiyun static int cxd2841er_read_ber_i(struct cxd2841er_priv *priv,
1448*4882a593Smuzhiyun u32 *bit_error, u32 *bit_count)
1449*4882a593Smuzhiyun {
1450*4882a593Smuzhiyun u8 data[3];
1451*4882a593Smuzhiyun u8 pktnum[2];
1452*4882a593Smuzhiyun
1453*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1454*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1455*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
1456*4882a593Smuzhiyun __func__, priv->state);
1457*4882a593Smuzhiyun return -EINVAL;
1458*4882a593Smuzhiyun }
1459*4882a593Smuzhiyun
1460*4882a593Smuzhiyun cxd2841er_freeze_regs(priv);
1461*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
1462*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x5B, pktnum, sizeof(pktnum));
1463*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x16, data, sizeof(data));
1464*4882a593Smuzhiyun cxd2841er_unfreeze_regs(priv);
1465*4882a593Smuzhiyun
1466*4882a593Smuzhiyun if (!pktnum[0] && !pktnum[1]) {
1467*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1468*4882a593Smuzhiyun "%s(): no valid BER data\n", __func__);
1469*4882a593Smuzhiyun return -EINVAL;
1470*4882a593Smuzhiyun }
1471*4882a593Smuzhiyun
1472*4882a593Smuzhiyun *bit_error = ((u32)(data[0] & 0x7F) << 16) |
1473*4882a593Smuzhiyun ((u32)data[1] << 8) | data[2];
1474*4882a593Smuzhiyun *bit_count = ((((u32)pktnum[0] << 8) | pktnum[1]) * 204 * 8);
1475*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): bit_error=%u bit_count=%u\n",
1476*4882a593Smuzhiyun __func__, *bit_error, *bit_count);
1477*4882a593Smuzhiyun
1478*4882a593Smuzhiyun return 0;
1479*4882a593Smuzhiyun }
1480*4882a593Smuzhiyun
cxd2841er_mon_read_ber_s(struct cxd2841er_priv * priv,u32 * bit_error,u32 * bit_count)1481*4882a593Smuzhiyun static int cxd2841er_mon_read_ber_s(struct cxd2841er_priv *priv,
1482*4882a593Smuzhiyun u32 *bit_error, u32 *bit_count)
1483*4882a593Smuzhiyun {
1484*4882a593Smuzhiyun u8 data[11];
1485*4882a593Smuzhiyun
1486*4882a593Smuzhiyun /* Set SLV-T Bank : 0xA0 */
1487*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
1488*4882a593Smuzhiyun /*
1489*4882a593Smuzhiyun * slave Bank Addr Bit Signal name
1490*4882a593Smuzhiyun * <SLV-T> A0h 35h [0] IFVBER_VALID
1491*4882a593Smuzhiyun * <SLV-T> A0h 36h [5:0] IFVBER_BITERR[21:16]
1492*4882a593Smuzhiyun * <SLV-T> A0h 37h [7:0] IFVBER_BITERR[15:8]
1493*4882a593Smuzhiyun * <SLV-T> A0h 38h [7:0] IFVBER_BITERR[7:0]
1494*4882a593Smuzhiyun * <SLV-T> A0h 3Dh [5:0] IFVBER_BITNUM[21:16]
1495*4882a593Smuzhiyun * <SLV-T> A0h 3Eh [7:0] IFVBER_BITNUM[15:8]
1496*4882a593Smuzhiyun * <SLV-T> A0h 3Fh [7:0] IFVBER_BITNUM[7:0]
1497*4882a593Smuzhiyun */
1498*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x35, data, 11);
1499*4882a593Smuzhiyun if (data[0] & 0x01) {
1500*4882a593Smuzhiyun *bit_error = ((u32)(data[1] & 0x3F) << 16) |
1501*4882a593Smuzhiyun ((u32)(data[2] & 0xFF) << 8) |
1502*4882a593Smuzhiyun (u32)(data[3] & 0xFF);
1503*4882a593Smuzhiyun *bit_count = ((u32)(data[8] & 0x3F) << 16) |
1504*4882a593Smuzhiyun ((u32)(data[9] & 0xFF) << 8) |
1505*4882a593Smuzhiyun (u32)(data[10] & 0xFF);
1506*4882a593Smuzhiyun if ((*bit_count == 0) || (*bit_error > *bit_count)) {
1507*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1508*4882a593Smuzhiyun "%s(): invalid bit_error %d, bit_count %d\n",
1509*4882a593Smuzhiyun __func__, *bit_error, *bit_count);
1510*4882a593Smuzhiyun return -EINVAL;
1511*4882a593Smuzhiyun }
1512*4882a593Smuzhiyun return 0;
1513*4882a593Smuzhiyun }
1514*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): no data available\n", __func__);
1515*4882a593Smuzhiyun return -EINVAL;
1516*4882a593Smuzhiyun }
1517*4882a593Smuzhiyun
1518*4882a593Smuzhiyun
cxd2841er_mon_read_ber_s2(struct cxd2841er_priv * priv,u32 * bit_error,u32 * bit_count)1519*4882a593Smuzhiyun static int cxd2841er_mon_read_ber_s2(struct cxd2841er_priv *priv,
1520*4882a593Smuzhiyun u32 *bit_error, u32 *bit_count)
1521*4882a593Smuzhiyun {
1522*4882a593Smuzhiyun u8 data[5];
1523*4882a593Smuzhiyun u32 period;
1524*4882a593Smuzhiyun
1525*4882a593Smuzhiyun /* Set SLV-T Bank : 0xB2 */
1526*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xb2);
1527*4882a593Smuzhiyun /*
1528*4882a593Smuzhiyun * slave Bank Addr Bit Signal name
1529*4882a593Smuzhiyun * <SLV-T> B2h 30h [0] IFLBER_VALID
1530*4882a593Smuzhiyun * <SLV-T> B2h 31h [3:0] IFLBER_BITERR[27:24]
1531*4882a593Smuzhiyun * <SLV-T> B2h 32h [7:0] IFLBER_BITERR[23:16]
1532*4882a593Smuzhiyun * <SLV-T> B2h 33h [7:0] IFLBER_BITERR[15:8]
1533*4882a593Smuzhiyun * <SLV-T> B2h 34h [7:0] IFLBER_BITERR[7:0]
1534*4882a593Smuzhiyun */
1535*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x30, data, 5);
1536*4882a593Smuzhiyun if (data[0] & 0x01) {
1537*4882a593Smuzhiyun /* Bit error count */
1538*4882a593Smuzhiyun *bit_error = ((u32)(data[1] & 0x0F) << 24) |
1539*4882a593Smuzhiyun ((u32)(data[2] & 0xFF) << 16) |
1540*4882a593Smuzhiyun ((u32)(data[3] & 0xFF) << 8) |
1541*4882a593Smuzhiyun (u32)(data[4] & 0xFF);
1542*4882a593Smuzhiyun
1543*4882a593Smuzhiyun /* Set SLV-T Bank : 0xA0 */
1544*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
1545*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x7a, data);
1546*4882a593Smuzhiyun /* Measurement period */
1547*4882a593Smuzhiyun period = (u32)(1 << (data[0] & 0x0F));
1548*4882a593Smuzhiyun if (period == 0) {
1549*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1550*4882a593Smuzhiyun "%s(): period is 0\n", __func__);
1551*4882a593Smuzhiyun return -EINVAL;
1552*4882a593Smuzhiyun }
1553*4882a593Smuzhiyun if (*bit_error > (period * 64800)) {
1554*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1555*4882a593Smuzhiyun "%s(): invalid bit_err 0x%x period 0x%x\n",
1556*4882a593Smuzhiyun __func__, *bit_error, period);
1557*4882a593Smuzhiyun return -EINVAL;
1558*4882a593Smuzhiyun }
1559*4882a593Smuzhiyun *bit_count = period * 64800;
1560*4882a593Smuzhiyun
1561*4882a593Smuzhiyun return 0;
1562*4882a593Smuzhiyun } else {
1563*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1564*4882a593Smuzhiyun "%s(): no data available\n", __func__);
1565*4882a593Smuzhiyun }
1566*4882a593Smuzhiyun return -EINVAL;
1567*4882a593Smuzhiyun }
1568*4882a593Smuzhiyun
cxd2841er_read_ber_t2(struct cxd2841er_priv * priv,u32 * bit_error,u32 * bit_count)1569*4882a593Smuzhiyun static int cxd2841er_read_ber_t2(struct cxd2841er_priv *priv,
1570*4882a593Smuzhiyun u32 *bit_error, u32 *bit_count)
1571*4882a593Smuzhiyun {
1572*4882a593Smuzhiyun u8 data[4];
1573*4882a593Smuzhiyun u32 period_exp, n_ldpc;
1574*4882a593Smuzhiyun
1575*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1576*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1577*4882a593Smuzhiyun "%s(): invalid state %d\n", __func__, priv->state);
1578*4882a593Smuzhiyun return -EINVAL;
1579*4882a593Smuzhiyun }
1580*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
1581*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x39, data, sizeof(data));
1582*4882a593Smuzhiyun if (!(data[0] & 0x10)) {
1583*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1584*4882a593Smuzhiyun "%s(): no valid BER data\n", __func__);
1585*4882a593Smuzhiyun return -EINVAL;
1586*4882a593Smuzhiyun }
1587*4882a593Smuzhiyun *bit_error = ((u32)(data[0] & 0x0f) << 24) |
1588*4882a593Smuzhiyun ((u32)data[1] << 16) |
1589*4882a593Smuzhiyun ((u32)data[2] << 8) |
1590*4882a593Smuzhiyun (u32)data[3];
1591*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x6f, data);
1592*4882a593Smuzhiyun period_exp = data[0] & 0x0f;
1593*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x22);
1594*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x5e, data);
1595*4882a593Smuzhiyun n_ldpc = ((data[0] & 0x03) == 0 ? 16200 : 64800);
1596*4882a593Smuzhiyun if (*bit_error > ((1U << period_exp) * n_ldpc)) {
1597*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1598*4882a593Smuzhiyun "%s(): invalid BER value\n", __func__);
1599*4882a593Smuzhiyun return -EINVAL;
1600*4882a593Smuzhiyun }
1601*4882a593Smuzhiyun
1602*4882a593Smuzhiyun /*
1603*4882a593Smuzhiyun * FIXME: the right thing would be to return bit_error untouched,
1604*4882a593Smuzhiyun * but, as we don't know the scale returned by the counters, let's
1605*4882a593Smuzhiyun * at least preserver BER = bit_error/bit_count.
1606*4882a593Smuzhiyun */
1607*4882a593Smuzhiyun if (period_exp >= 4) {
1608*4882a593Smuzhiyun *bit_count = (1U << (period_exp - 4)) * (n_ldpc / 200);
1609*4882a593Smuzhiyun *bit_error *= 3125ULL;
1610*4882a593Smuzhiyun } else {
1611*4882a593Smuzhiyun *bit_count = (1U << period_exp) * (n_ldpc / 200);
1612*4882a593Smuzhiyun *bit_error *= 50000ULL;
1613*4882a593Smuzhiyun }
1614*4882a593Smuzhiyun return 0;
1615*4882a593Smuzhiyun }
1616*4882a593Smuzhiyun
cxd2841er_read_ber_t(struct cxd2841er_priv * priv,u32 * bit_error,u32 * bit_count)1617*4882a593Smuzhiyun static int cxd2841er_read_ber_t(struct cxd2841er_priv *priv,
1618*4882a593Smuzhiyun u32 *bit_error, u32 *bit_count)
1619*4882a593Smuzhiyun {
1620*4882a593Smuzhiyun u8 data[2];
1621*4882a593Smuzhiyun u32 period;
1622*4882a593Smuzhiyun
1623*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1624*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1625*4882a593Smuzhiyun "%s(): invalid state %d\n", __func__, priv->state);
1626*4882a593Smuzhiyun return -EINVAL;
1627*4882a593Smuzhiyun }
1628*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1629*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x39, data);
1630*4882a593Smuzhiyun if (!(data[0] & 0x01)) {
1631*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1632*4882a593Smuzhiyun "%s(): no valid BER data\n", __func__);
1633*4882a593Smuzhiyun return 0;
1634*4882a593Smuzhiyun }
1635*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x22, data, sizeof(data));
1636*4882a593Smuzhiyun *bit_error = ((u32)data[0] << 8) | (u32)data[1];
1637*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x6f, data);
1638*4882a593Smuzhiyun period = ((data[0] & 0x07) == 0) ? 256 : (4096 << (data[0] & 0x07));
1639*4882a593Smuzhiyun
1640*4882a593Smuzhiyun /*
1641*4882a593Smuzhiyun * FIXME: the right thing would be to return bit_error untouched,
1642*4882a593Smuzhiyun * but, as we don't know the scale returned by the counters, let's
1643*4882a593Smuzhiyun * at least preserver BER = bit_error/bit_count.
1644*4882a593Smuzhiyun */
1645*4882a593Smuzhiyun *bit_count = period / 128;
1646*4882a593Smuzhiyun *bit_error *= 78125ULL;
1647*4882a593Smuzhiyun return 0;
1648*4882a593Smuzhiyun }
1649*4882a593Smuzhiyun
cxd2841er_freeze_regs(struct cxd2841er_priv * priv)1650*4882a593Smuzhiyun static int cxd2841er_freeze_regs(struct cxd2841er_priv *priv)
1651*4882a593Smuzhiyun {
1652*4882a593Smuzhiyun /*
1653*4882a593Smuzhiyun * Freeze registers: ensure multiple separate register reads
1654*4882a593Smuzhiyun * are from the same snapshot
1655*4882a593Smuzhiyun */
1656*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x01);
1657*4882a593Smuzhiyun return 0;
1658*4882a593Smuzhiyun }
1659*4882a593Smuzhiyun
cxd2841er_unfreeze_regs(struct cxd2841er_priv * priv)1660*4882a593Smuzhiyun static int cxd2841er_unfreeze_regs(struct cxd2841er_priv *priv)
1661*4882a593Smuzhiyun {
1662*4882a593Smuzhiyun /*
1663*4882a593Smuzhiyun * un-freeze registers
1664*4882a593Smuzhiyun */
1665*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x01, 0x00);
1666*4882a593Smuzhiyun return 0;
1667*4882a593Smuzhiyun }
1668*4882a593Smuzhiyun
cxd2841er_dvbs_read_snr(struct cxd2841er_priv * priv,u8 delsys,u32 * snr)1669*4882a593Smuzhiyun static u32 cxd2841er_dvbs_read_snr(struct cxd2841er_priv *priv,
1670*4882a593Smuzhiyun u8 delsys, u32 *snr)
1671*4882a593Smuzhiyun {
1672*4882a593Smuzhiyun u8 data[3];
1673*4882a593Smuzhiyun u32 res = 0, value;
1674*4882a593Smuzhiyun int min_index, max_index, index;
1675*4882a593Smuzhiyun static const struct cxd2841er_cnr_data *cn_data;
1676*4882a593Smuzhiyun
1677*4882a593Smuzhiyun cxd2841er_freeze_regs(priv);
1678*4882a593Smuzhiyun /* Set SLV-T Bank : 0xA1 */
1679*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa1);
1680*4882a593Smuzhiyun /*
1681*4882a593Smuzhiyun * slave Bank Addr Bit Signal name
1682*4882a593Smuzhiyun * <SLV-T> A1h 10h [0] ICPM_QUICKRDY
1683*4882a593Smuzhiyun * <SLV-T> A1h 11h [4:0] ICPM_QUICKCNDT[12:8]
1684*4882a593Smuzhiyun * <SLV-T> A1h 12h [7:0] ICPM_QUICKCNDT[7:0]
1685*4882a593Smuzhiyun */
1686*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x10, data, 3);
1687*4882a593Smuzhiyun cxd2841er_unfreeze_regs(priv);
1688*4882a593Smuzhiyun
1689*4882a593Smuzhiyun if (data[0] & 0x01) {
1690*4882a593Smuzhiyun value = ((u32)(data[1] & 0x1F) << 8) | (u32)(data[2] & 0xFF);
1691*4882a593Smuzhiyun min_index = 0;
1692*4882a593Smuzhiyun if (delsys == SYS_DVBS) {
1693*4882a593Smuzhiyun cn_data = s_cn_data;
1694*4882a593Smuzhiyun max_index = ARRAY_SIZE(s_cn_data) - 1;
1695*4882a593Smuzhiyun } else {
1696*4882a593Smuzhiyun cn_data = s2_cn_data;
1697*4882a593Smuzhiyun max_index = ARRAY_SIZE(s2_cn_data) - 1;
1698*4882a593Smuzhiyun }
1699*4882a593Smuzhiyun if (value >= cn_data[min_index].value) {
1700*4882a593Smuzhiyun res = cn_data[min_index].cnr_x1000;
1701*4882a593Smuzhiyun goto done;
1702*4882a593Smuzhiyun }
1703*4882a593Smuzhiyun if (value <= cn_data[max_index].value) {
1704*4882a593Smuzhiyun res = cn_data[max_index].cnr_x1000;
1705*4882a593Smuzhiyun goto done;
1706*4882a593Smuzhiyun }
1707*4882a593Smuzhiyun while ((max_index - min_index) > 1) {
1708*4882a593Smuzhiyun index = (max_index + min_index) / 2;
1709*4882a593Smuzhiyun if (value == cn_data[index].value) {
1710*4882a593Smuzhiyun res = cn_data[index].cnr_x1000;
1711*4882a593Smuzhiyun goto done;
1712*4882a593Smuzhiyun } else if (value > cn_data[index].value)
1713*4882a593Smuzhiyun max_index = index;
1714*4882a593Smuzhiyun else
1715*4882a593Smuzhiyun min_index = index;
1716*4882a593Smuzhiyun if ((max_index - min_index) <= 1) {
1717*4882a593Smuzhiyun if (value == cn_data[max_index].value) {
1718*4882a593Smuzhiyun res = cn_data[max_index].cnr_x1000;
1719*4882a593Smuzhiyun goto done;
1720*4882a593Smuzhiyun } else {
1721*4882a593Smuzhiyun res = cn_data[min_index].cnr_x1000;
1722*4882a593Smuzhiyun goto done;
1723*4882a593Smuzhiyun }
1724*4882a593Smuzhiyun }
1725*4882a593Smuzhiyun }
1726*4882a593Smuzhiyun } else {
1727*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1728*4882a593Smuzhiyun "%s(): no data available\n", __func__);
1729*4882a593Smuzhiyun return -EINVAL;
1730*4882a593Smuzhiyun }
1731*4882a593Smuzhiyun done:
1732*4882a593Smuzhiyun *snr = res;
1733*4882a593Smuzhiyun return 0;
1734*4882a593Smuzhiyun }
1735*4882a593Smuzhiyun
sony_log(uint32_t x)1736*4882a593Smuzhiyun static uint32_t sony_log(uint32_t x)
1737*4882a593Smuzhiyun {
1738*4882a593Smuzhiyun return (((10000>>8)*(intlog2(x)>>16) + LOG2_E_100X/2)/LOG2_E_100X);
1739*4882a593Smuzhiyun }
1740*4882a593Smuzhiyun
cxd2841er_read_snr_c(struct cxd2841er_priv * priv,u32 * snr)1741*4882a593Smuzhiyun static int cxd2841er_read_snr_c(struct cxd2841er_priv *priv, u32 *snr)
1742*4882a593Smuzhiyun {
1743*4882a593Smuzhiyun u32 reg;
1744*4882a593Smuzhiyun u8 data[2];
1745*4882a593Smuzhiyun enum sony_dvbc_constellation_t qam = SONY_DVBC_CONSTELLATION_16QAM;
1746*4882a593Smuzhiyun
1747*4882a593Smuzhiyun *snr = 0;
1748*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1749*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1750*4882a593Smuzhiyun "%s(): invalid state %d\n",
1751*4882a593Smuzhiyun __func__, priv->state);
1752*4882a593Smuzhiyun return -EINVAL;
1753*4882a593Smuzhiyun }
1754*4882a593Smuzhiyun
1755*4882a593Smuzhiyun cxd2841er_freeze_regs(priv);
1756*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
1757*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x19, data, 1);
1758*4882a593Smuzhiyun qam = (enum sony_dvbc_constellation_t) (data[0] & 0x07);
1759*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x4C, data, 2);
1760*4882a593Smuzhiyun cxd2841er_unfreeze_regs(priv);
1761*4882a593Smuzhiyun
1762*4882a593Smuzhiyun reg = ((u32)(data[0]&0x1f) << 8) | (u32)data[1];
1763*4882a593Smuzhiyun if (reg == 0) {
1764*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1765*4882a593Smuzhiyun "%s(): reg value out of range\n", __func__);
1766*4882a593Smuzhiyun return 0;
1767*4882a593Smuzhiyun }
1768*4882a593Smuzhiyun
1769*4882a593Smuzhiyun switch (qam) {
1770*4882a593Smuzhiyun case SONY_DVBC_CONSTELLATION_16QAM:
1771*4882a593Smuzhiyun case SONY_DVBC_CONSTELLATION_64QAM:
1772*4882a593Smuzhiyun case SONY_DVBC_CONSTELLATION_256QAM:
1773*4882a593Smuzhiyun /* SNR(dB) = -9.50 * ln(IREG_SNR_ESTIMATE / (24320)) */
1774*4882a593Smuzhiyun if (reg < 126)
1775*4882a593Smuzhiyun reg = 126;
1776*4882a593Smuzhiyun *snr = -95 * (int32_t)sony_log(reg) + 95941;
1777*4882a593Smuzhiyun break;
1778*4882a593Smuzhiyun case SONY_DVBC_CONSTELLATION_32QAM:
1779*4882a593Smuzhiyun case SONY_DVBC_CONSTELLATION_128QAM:
1780*4882a593Smuzhiyun /* SNR(dB) = -8.75 * ln(IREG_SNR_ESTIMATE / (20800)) */
1781*4882a593Smuzhiyun if (reg < 69)
1782*4882a593Smuzhiyun reg = 69;
1783*4882a593Smuzhiyun *snr = -88 * (int32_t)sony_log(reg) + 86999;
1784*4882a593Smuzhiyun break;
1785*4882a593Smuzhiyun default:
1786*4882a593Smuzhiyun return -EINVAL;
1787*4882a593Smuzhiyun }
1788*4882a593Smuzhiyun
1789*4882a593Smuzhiyun return 0;
1790*4882a593Smuzhiyun }
1791*4882a593Smuzhiyun
cxd2841er_read_snr_t(struct cxd2841er_priv * priv,u32 * snr)1792*4882a593Smuzhiyun static int cxd2841er_read_snr_t(struct cxd2841er_priv *priv, u32 *snr)
1793*4882a593Smuzhiyun {
1794*4882a593Smuzhiyun u32 reg;
1795*4882a593Smuzhiyun u8 data[2];
1796*4882a593Smuzhiyun
1797*4882a593Smuzhiyun *snr = 0;
1798*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1799*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1800*4882a593Smuzhiyun "%s(): invalid state %d\n", __func__, priv->state);
1801*4882a593Smuzhiyun return -EINVAL;
1802*4882a593Smuzhiyun }
1803*4882a593Smuzhiyun
1804*4882a593Smuzhiyun cxd2841er_freeze_regs(priv);
1805*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
1806*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
1807*4882a593Smuzhiyun cxd2841er_unfreeze_regs(priv);
1808*4882a593Smuzhiyun
1809*4882a593Smuzhiyun reg = ((u32)data[0] << 8) | (u32)data[1];
1810*4882a593Smuzhiyun if (reg == 0) {
1811*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1812*4882a593Smuzhiyun "%s(): reg value out of range\n", __func__);
1813*4882a593Smuzhiyun return 0;
1814*4882a593Smuzhiyun }
1815*4882a593Smuzhiyun if (reg > 4996)
1816*4882a593Smuzhiyun reg = 4996;
1817*4882a593Smuzhiyun *snr = 100 * ((INTLOG10X100(reg) - INTLOG10X100(5350 - reg)) + 285);
1818*4882a593Smuzhiyun return 0;
1819*4882a593Smuzhiyun }
1820*4882a593Smuzhiyun
cxd2841er_read_snr_t2(struct cxd2841er_priv * priv,u32 * snr)1821*4882a593Smuzhiyun static int cxd2841er_read_snr_t2(struct cxd2841er_priv *priv, u32 *snr)
1822*4882a593Smuzhiyun {
1823*4882a593Smuzhiyun u32 reg;
1824*4882a593Smuzhiyun u8 data[2];
1825*4882a593Smuzhiyun
1826*4882a593Smuzhiyun *snr = 0;
1827*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1828*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1829*4882a593Smuzhiyun "%s(): invalid state %d\n", __func__, priv->state);
1830*4882a593Smuzhiyun return -EINVAL;
1831*4882a593Smuzhiyun }
1832*4882a593Smuzhiyun
1833*4882a593Smuzhiyun cxd2841er_freeze_regs(priv);
1834*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
1835*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
1836*4882a593Smuzhiyun cxd2841er_unfreeze_regs(priv);
1837*4882a593Smuzhiyun
1838*4882a593Smuzhiyun reg = ((u32)data[0] << 8) | (u32)data[1];
1839*4882a593Smuzhiyun if (reg == 0) {
1840*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1841*4882a593Smuzhiyun "%s(): reg value out of range\n", __func__);
1842*4882a593Smuzhiyun return 0;
1843*4882a593Smuzhiyun }
1844*4882a593Smuzhiyun if (reg > 10876)
1845*4882a593Smuzhiyun reg = 10876;
1846*4882a593Smuzhiyun *snr = 100 * ((INTLOG10X100(reg) - INTLOG10X100(12600 - reg)) + 320);
1847*4882a593Smuzhiyun return 0;
1848*4882a593Smuzhiyun }
1849*4882a593Smuzhiyun
cxd2841er_read_snr_i(struct cxd2841er_priv * priv,u32 * snr)1850*4882a593Smuzhiyun static int cxd2841er_read_snr_i(struct cxd2841er_priv *priv, u32 *snr)
1851*4882a593Smuzhiyun {
1852*4882a593Smuzhiyun u32 reg;
1853*4882a593Smuzhiyun u8 data[2];
1854*4882a593Smuzhiyun
1855*4882a593Smuzhiyun *snr = 0;
1856*4882a593Smuzhiyun if (priv->state != STATE_ACTIVE_TC) {
1857*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1858*4882a593Smuzhiyun "%s(): invalid state %d\n", __func__,
1859*4882a593Smuzhiyun priv->state);
1860*4882a593Smuzhiyun return -EINVAL;
1861*4882a593Smuzhiyun }
1862*4882a593Smuzhiyun
1863*4882a593Smuzhiyun cxd2841er_freeze_regs(priv);
1864*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
1865*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x28, data, sizeof(data));
1866*4882a593Smuzhiyun cxd2841er_unfreeze_regs(priv);
1867*4882a593Smuzhiyun
1868*4882a593Smuzhiyun reg = ((u32)data[0] << 8) | (u32)data[1];
1869*4882a593Smuzhiyun if (reg == 0) {
1870*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1871*4882a593Smuzhiyun "%s(): reg value out of range\n", __func__);
1872*4882a593Smuzhiyun return 0;
1873*4882a593Smuzhiyun }
1874*4882a593Smuzhiyun *snr = 10000 * (intlog10(reg) >> 24) - 9031;
1875*4882a593Smuzhiyun return 0;
1876*4882a593Smuzhiyun }
1877*4882a593Smuzhiyun
cxd2841er_read_agc_gain_c(struct cxd2841er_priv * priv,u8 delsys)1878*4882a593Smuzhiyun static u16 cxd2841er_read_agc_gain_c(struct cxd2841er_priv *priv,
1879*4882a593Smuzhiyun u8 delsys)
1880*4882a593Smuzhiyun {
1881*4882a593Smuzhiyun u8 data[2];
1882*4882a593Smuzhiyun
1883*4882a593Smuzhiyun cxd2841er_write_reg(
1884*4882a593Smuzhiyun priv, I2C_SLVT, 0x00, 0x40);
1885*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x49, data, 2);
1886*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1887*4882a593Smuzhiyun "%s(): AGC value=%u\n",
1888*4882a593Smuzhiyun __func__, (((u16)data[0] & 0x0F) << 8) |
1889*4882a593Smuzhiyun (u16)(data[1] & 0xFF));
1890*4882a593Smuzhiyun return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4;
1891*4882a593Smuzhiyun }
1892*4882a593Smuzhiyun
cxd2841er_read_agc_gain_t_t2(struct cxd2841er_priv * priv,u8 delsys)1893*4882a593Smuzhiyun static u16 cxd2841er_read_agc_gain_t_t2(struct cxd2841er_priv *priv,
1894*4882a593Smuzhiyun u8 delsys)
1895*4882a593Smuzhiyun {
1896*4882a593Smuzhiyun u8 data[2];
1897*4882a593Smuzhiyun
1898*4882a593Smuzhiyun cxd2841er_write_reg(
1899*4882a593Smuzhiyun priv, I2C_SLVT, 0x00, (delsys == SYS_DVBT ? 0x10 : 0x20));
1900*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x26, data, 2);
1901*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1902*4882a593Smuzhiyun "%s(): AGC value=%u\n",
1903*4882a593Smuzhiyun __func__, (((u16)data[0] & 0x0F) << 8) |
1904*4882a593Smuzhiyun (u16)(data[1] & 0xFF));
1905*4882a593Smuzhiyun return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4;
1906*4882a593Smuzhiyun }
1907*4882a593Smuzhiyun
cxd2841er_read_agc_gain_i(struct cxd2841er_priv * priv,u8 delsys)1908*4882a593Smuzhiyun static u16 cxd2841er_read_agc_gain_i(struct cxd2841er_priv *priv,
1909*4882a593Smuzhiyun u8 delsys)
1910*4882a593Smuzhiyun {
1911*4882a593Smuzhiyun u8 data[2];
1912*4882a593Smuzhiyun
1913*4882a593Smuzhiyun cxd2841er_write_reg(
1914*4882a593Smuzhiyun priv, I2C_SLVT, 0x00, 0x60);
1915*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x26, data, 2);
1916*4882a593Smuzhiyun
1917*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
1918*4882a593Smuzhiyun "%s(): AGC value=%u\n",
1919*4882a593Smuzhiyun __func__, (((u16)data[0] & 0x0F) << 8) |
1920*4882a593Smuzhiyun (u16)(data[1] & 0xFF));
1921*4882a593Smuzhiyun return ((((u16)data[0] & 0x0F) << 8) | (u16)(data[1] & 0xFF)) << 4;
1922*4882a593Smuzhiyun }
1923*4882a593Smuzhiyun
cxd2841er_read_agc_gain_s(struct cxd2841er_priv * priv)1924*4882a593Smuzhiyun static u16 cxd2841er_read_agc_gain_s(struct cxd2841er_priv *priv)
1925*4882a593Smuzhiyun {
1926*4882a593Smuzhiyun u8 data[2];
1927*4882a593Smuzhiyun
1928*4882a593Smuzhiyun /* Set SLV-T Bank : 0xA0 */
1929*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
1930*4882a593Smuzhiyun /*
1931*4882a593Smuzhiyun * slave Bank Addr Bit Signal name
1932*4882a593Smuzhiyun * <SLV-T> A0h 1Fh [4:0] IRFAGC_GAIN[12:8]
1933*4882a593Smuzhiyun * <SLV-T> A0h 20h [7:0] IRFAGC_GAIN[7:0]
1934*4882a593Smuzhiyun */
1935*4882a593Smuzhiyun cxd2841er_read_regs(priv, I2C_SLVT, 0x1f, data, 2);
1936*4882a593Smuzhiyun return ((((u16)data[0] & 0x1F) << 8) | (u16)(data[1] & 0xFF)) << 3;
1937*4882a593Smuzhiyun }
1938*4882a593Smuzhiyun
cxd2841er_read_ber(struct dvb_frontend * fe)1939*4882a593Smuzhiyun static void cxd2841er_read_ber(struct dvb_frontend *fe)
1940*4882a593Smuzhiyun {
1941*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1942*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
1943*4882a593Smuzhiyun u32 ret, bit_error = 0, bit_count = 0;
1944*4882a593Smuzhiyun
1945*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1946*4882a593Smuzhiyun switch (p->delivery_system) {
1947*4882a593Smuzhiyun case SYS_DVBC_ANNEX_A:
1948*4882a593Smuzhiyun case SYS_DVBC_ANNEX_B:
1949*4882a593Smuzhiyun case SYS_DVBC_ANNEX_C:
1950*4882a593Smuzhiyun ret = cxd2841er_read_ber_c(priv, &bit_error, &bit_count);
1951*4882a593Smuzhiyun break;
1952*4882a593Smuzhiyun case SYS_ISDBT:
1953*4882a593Smuzhiyun ret = cxd2841er_read_ber_i(priv, &bit_error, &bit_count);
1954*4882a593Smuzhiyun break;
1955*4882a593Smuzhiyun case SYS_DVBS:
1956*4882a593Smuzhiyun ret = cxd2841er_mon_read_ber_s(priv, &bit_error, &bit_count);
1957*4882a593Smuzhiyun break;
1958*4882a593Smuzhiyun case SYS_DVBS2:
1959*4882a593Smuzhiyun ret = cxd2841er_mon_read_ber_s2(priv, &bit_error, &bit_count);
1960*4882a593Smuzhiyun break;
1961*4882a593Smuzhiyun case SYS_DVBT:
1962*4882a593Smuzhiyun ret = cxd2841er_read_ber_t(priv, &bit_error, &bit_count);
1963*4882a593Smuzhiyun break;
1964*4882a593Smuzhiyun case SYS_DVBT2:
1965*4882a593Smuzhiyun ret = cxd2841er_read_ber_t2(priv, &bit_error, &bit_count);
1966*4882a593Smuzhiyun break;
1967*4882a593Smuzhiyun default:
1968*4882a593Smuzhiyun p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1969*4882a593Smuzhiyun p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1970*4882a593Smuzhiyun return;
1971*4882a593Smuzhiyun }
1972*4882a593Smuzhiyun
1973*4882a593Smuzhiyun if (!ret) {
1974*4882a593Smuzhiyun p->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
1975*4882a593Smuzhiyun p->post_bit_error.stat[0].uvalue += bit_error;
1976*4882a593Smuzhiyun p->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
1977*4882a593Smuzhiyun p->post_bit_count.stat[0].uvalue += bit_count;
1978*4882a593Smuzhiyun } else {
1979*4882a593Smuzhiyun p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1980*4882a593Smuzhiyun p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1981*4882a593Smuzhiyun }
1982*4882a593Smuzhiyun }
1983*4882a593Smuzhiyun
cxd2841er_read_signal_strength(struct dvb_frontend * fe)1984*4882a593Smuzhiyun static void cxd2841er_read_signal_strength(struct dvb_frontend *fe)
1985*4882a593Smuzhiyun {
1986*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1987*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
1988*4882a593Smuzhiyun s32 strength;
1989*4882a593Smuzhiyun
1990*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
1991*4882a593Smuzhiyun switch (p->delivery_system) {
1992*4882a593Smuzhiyun case SYS_DVBT:
1993*4882a593Smuzhiyun case SYS_DVBT2:
1994*4882a593Smuzhiyun strength = cxd2841er_read_agc_gain_t_t2(priv,
1995*4882a593Smuzhiyun p->delivery_system);
1996*4882a593Smuzhiyun p->strength.stat[0].scale = FE_SCALE_DECIBEL;
1997*4882a593Smuzhiyun /* Formula was empirically determinated @ 410 MHz */
1998*4882a593Smuzhiyun p->strength.stat[0].uvalue = strength * 366 / 100 - 89520;
1999*4882a593Smuzhiyun break; /* Code moved out of the function */
2000*4882a593Smuzhiyun case SYS_DVBC_ANNEX_A:
2001*4882a593Smuzhiyun case SYS_DVBC_ANNEX_B:
2002*4882a593Smuzhiyun case SYS_DVBC_ANNEX_C:
2003*4882a593Smuzhiyun strength = cxd2841er_read_agc_gain_c(priv,
2004*4882a593Smuzhiyun p->delivery_system);
2005*4882a593Smuzhiyun p->strength.stat[0].scale = FE_SCALE_DECIBEL;
2006*4882a593Smuzhiyun /*
2007*4882a593Smuzhiyun * Formula was empirically determinated via linear regression,
2008*4882a593Smuzhiyun * using frequencies: 175 MHz, 410 MHz and 800 MHz, and a
2009*4882a593Smuzhiyun * stream modulated with QAM64
2010*4882a593Smuzhiyun */
2011*4882a593Smuzhiyun p->strength.stat[0].uvalue = strength * 4045 / 1000 - 85224;
2012*4882a593Smuzhiyun break;
2013*4882a593Smuzhiyun case SYS_ISDBT:
2014*4882a593Smuzhiyun strength = cxd2841er_read_agc_gain_i(priv, p->delivery_system);
2015*4882a593Smuzhiyun p->strength.stat[0].scale = FE_SCALE_DECIBEL;
2016*4882a593Smuzhiyun /*
2017*4882a593Smuzhiyun * Formula was empirically determinated via linear regression,
2018*4882a593Smuzhiyun * using frequencies: 175 MHz, 410 MHz and 800 MHz.
2019*4882a593Smuzhiyun */
2020*4882a593Smuzhiyun p->strength.stat[0].uvalue = strength * 3775 / 1000 - 90185;
2021*4882a593Smuzhiyun break;
2022*4882a593Smuzhiyun case SYS_DVBS:
2023*4882a593Smuzhiyun case SYS_DVBS2:
2024*4882a593Smuzhiyun strength = 65535 - cxd2841er_read_agc_gain_s(priv);
2025*4882a593Smuzhiyun p->strength.stat[0].scale = FE_SCALE_RELATIVE;
2026*4882a593Smuzhiyun p->strength.stat[0].uvalue = strength;
2027*4882a593Smuzhiyun break;
2028*4882a593Smuzhiyun default:
2029*4882a593Smuzhiyun p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
2030*4882a593Smuzhiyun break;
2031*4882a593Smuzhiyun }
2032*4882a593Smuzhiyun }
2033*4882a593Smuzhiyun
cxd2841er_read_snr(struct dvb_frontend * fe)2034*4882a593Smuzhiyun static void cxd2841er_read_snr(struct dvb_frontend *fe)
2035*4882a593Smuzhiyun {
2036*4882a593Smuzhiyun u32 tmp = 0;
2037*4882a593Smuzhiyun int ret = 0;
2038*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
2039*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
2040*4882a593Smuzhiyun
2041*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
2042*4882a593Smuzhiyun switch (p->delivery_system) {
2043*4882a593Smuzhiyun case SYS_DVBC_ANNEX_A:
2044*4882a593Smuzhiyun case SYS_DVBC_ANNEX_B:
2045*4882a593Smuzhiyun case SYS_DVBC_ANNEX_C:
2046*4882a593Smuzhiyun ret = cxd2841er_read_snr_c(priv, &tmp);
2047*4882a593Smuzhiyun break;
2048*4882a593Smuzhiyun case SYS_DVBT:
2049*4882a593Smuzhiyun ret = cxd2841er_read_snr_t(priv, &tmp);
2050*4882a593Smuzhiyun break;
2051*4882a593Smuzhiyun case SYS_DVBT2:
2052*4882a593Smuzhiyun ret = cxd2841er_read_snr_t2(priv, &tmp);
2053*4882a593Smuzhiyun break;
2054*4882a593Smuzhiyun case SYS_ISDBT:
2055*4882a593Smuzhiyun ret = cxd2841er_read_snr_i(priv, &tmp);
2056*4882a593Smuzhiyun break;
2057*4882a593Smuzhiyun case SYS_DVBS:
2058*4882a593Smuzhiyun case SYS_DVBS2:
2059*4882a593Smuzhiyun ret = cxd2841er_dvbs_read_snr(priv, p->delivery_system, &tmp);
2060*4882a593Smuzhiyun break;
2061*4882a593Smuzhiyun default:
2062*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): unknown delivery system %d\n",
2063*4882a593Smuzhiyun __func__, p->delivery_system);
2064*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
2065*4882a593Smuzhiyun return;
2066*4882a593Smuzhiyun }
2067*4882a593Smuzhiyun
2068*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): snr=%d\n",
2069*4882a593Smuzhiyun __func__, (int32_t)tmp);
2070*4882a593Smuzhiyun
2071*4882a593Smuzhiyun if (!ret) {
2072*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_DECIBEL;
2073*4882a593Smuzhiyun p->cnr.stat[0].svalue = tmp;
2074*4882a593Smuzhiyun } else {
2075*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
2076*4882a593Smuzhiyun }
2077*4882a593Smuzhiyun }
2078*4882a593Smuzhiyun
cxd2841er_read_ucblocks(struct dvb_frontend * fe)2079*4882a593Smuzhiyun static void cxd2841er_read_ucblocks(struct dvb_frontend *fe)
2080*4882a593Smuzhiyun {
2081*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
2082*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
2083*4882a593Smuzhiyun u32 ucblocks = 0;
2084*4882a593Smuzhiyun
2085*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
2086*4882a593Smuzhiyun switch (p->delivery_system) {
2087*4882a593Smuzhiyun case SYS_DVBC_ANNEX_A:
2088*4882a593Smuzhiyun case SYS_DVBC_ANNEX_B:
2089*4882a593Smuzhiyun case SYS_DVBC_ANNEX_C:
2090*4882a593Smuzhiyun cxd2841er_read_packet_errors_c(priv, &ucblocks);
2091*4882a593Smuzhiyun break;
2092*4882a593Smuzhiyun case SYS_DVBT:
2093*4882a593Smuzhiyun cxd2841er_read_packet_errors_t(priv, &ucblocks);
2094*4882a593Smuzhiyun break;
2095*4882a593Smuzhiyun case SYS_DVBT2:
2096*4882a593Smuzhiyun cxd2841er_read_packet_errors_t2(priv, &ucblocks);
2097*4882a593Smuzhiyun break;
2098*4882a593Smuzhiyun case SYS_ISDBT:
2099*4882a593Smuzhiyun cxd2841er_read_packet_errors_i(priv, &ucblocks);
2100*4882a593Smuzhiyun break;
2101*4882a593Smuzhiyun default:
2102*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
2103*4882a593Smuzhiyun return;
2104*4882a593Smuzhiyun }
2105*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s() ucblocks=%u\n", __func__, ucblocks);
2106*4882a593Smuzhiyun
2107*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_COUNTER;
2108*4882a593Smuzhiyun p->block_error.stat[0].uvalue = ucblocks;
2109*4882a593Smuzhiyun }
2110*4882a593Smuzhiyun
cxd2841er_dvbt2_set_profile(struct cxd2841er_priv * priv,enum cxd2841er_dvbt2_profile_t profile)2111*4882a593Smuzhiyun static int cxd2841er_dvbt2_set_profile(
2112*4882a593Smuzhiyun struct cxd2841er_priv *priv, enum cxd2841er_dvbt2_profile_t profile)
2113*4882a593Smuzhiyun {
2114*4882a593Smuzhiyun u8 tune_mode;
2115*4882a593Smuzhiyun u8 seq_not2d_time;
2116*4882a593Smuzhiyun
2117*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
2118*4882a593Smuzhiyun switch (profile) {
2119*4882a593Smuzhiyun case DVBT2_PROFILE_BASE:
2120*4882a593Smuzhiyun tune_mode = 0x01;
2121*4882a593Smuzhiyun /* Set early unlock time */
2122*4882a593Smuzhiyun seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x0E:0x0C;
2123*4882a593Smuzhiyun break;
2124*4882a593Smuzhiyun case DVBT2_PROFILE_LITE:
2125*4882a593Smuzhiyun tune_mode = 0x05;
2126*4882a593Smuzhiyun /* Set early unlock time */
2127*4882a593Smuzhiyun seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x2E:0x28;
2128*4882a593Smuzhiyun break;
2129*4882a593Smuzhiyun case DVBT2_PROFILE_ANY:
2130*4882a593Smuzhiyun tune_mode = 0x00;
2131*4882a593Smuzhiyun /* Set early unlock time */
2132*4882a593Smuzhiyun seq_not2d_time = (priv->xtal == SONY_XTAL_24000)?0x2E:0x28;
2133*4882a593Smuzhiyun break;
2134*4882a593Smuzhiyun default:
2135*4882a593Smuzhiyun return -EINVAL;
2136*4882a593Smuzhiyun }
2137*4882a593Smuzhiyun /* Set SLV-T Bank : 0x2E */
2138*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2e);
2139*4882a593Smuzhiyun /* Set profile and tune mode */
2140*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x10, tune_mode, 0x07);
2141*4882a593Smuzhiyun /* Set SLV-T Bank : 0x2B */
2142*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b);
2143*4882a593Smuzhiyun /* Set early unlock detection time */
2144*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x9d, seq_not2d_time);
2145*4882a593Smuzhiyun return 0;
2146*4882a593Smuzhiyun }
2147*4882a593Smuzhiyun
cxd2841er_dvbt2_set_plp_config(struct cxd2841er_priv * priv,u8 is_auto,u8 plp_id)2148*4882a593Smuzhiyun static int cxd2841er_dvbt2_set_plp_config(struct cxd2841er_priv *priv,
2149*4882a593Smuzhiyun u8 is_auto, u8 plp_id)
2150*4882a593Smuzhiyun {
2151*4882a593Smuzhiyun if (is_auto) {
2152*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
2153*4882a593Smuzhiyun "%s() using auto PLP selection\n", __func__);
2154*4882a593Smuzhiyun } else {
2155*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
2156*4882a593Smuzhiyun "%s() using manual PLP selection, ID %d\n",
2157*4882a593Smuzhiyun __func__, plp_id);
2158*4882a593Smuzhiyun }
2159*4882a593Smuzhiyun /* Set SLV-T Bank : 0x23 */
2160*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x23);
2161*4882a593Smuzhiyun if (!is_auto) {
2162*4882a593Smuzhiyun /* Manual PLP selection mode. Set the data PLP Id. */
2163*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xaf, plp_id);
2164*4882a593Smuzhiyun }
2165*4882a593Smuzhiyun /* Auto PLP select (Scanning mode = 0x00). Data PLP select = 0x01. */
2166*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xad, (is_auto ? 0x00 : 0x01));
2167*4882a593Smuzhiyun return 0;
2168*4882a593Smuzhiyun }
2169*4882a593Smuzhiyun
cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv * priv,u32 bandwidth)2170*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_t2_band(struct cxd2841er_priv *priv,
2171*4882a593Smuzhiyun u32 bandwidth)
2172*4882a593Smuzhiyun {
2173*4882a593Smuzhiyun u32 iffreq, ifhz;
2174*4882a593Smuzhiyun u8 data[MAX_WRITE_REGSIZE];
2175*4882a593Smuzhiyun
2176*4882a593Smuzhiyun static const uint8_t nominalRate8bw[3][5] = {
2177*4882a593Smuzhiyun /* TRCG Nominal Rate [37:0] */
2178*4882a593Smuzhiyun {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2179*4882a593Smuzhiyun {0x15, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2180*4882a593Smuzhiyun {0x11, 0xF0, 0x00, 0x00, 0x00} /* 41MHz XTal */
2181*4882a593Smuzhiyun };
2182*4882a593Smuzhiyun
2183*4882a593Smuzhiyun static const uint8_t nominalRate7bw[3][5] = {
2184*4882a593Smuzhiyun /* TRCG Nominal Rate [37:0] */
2185*4882a593Smuzhiyun {0x14, 0x80, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2186*4882a593Smuzhiyun {0x18, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2187*4882a593Smuzhiyun {0x14, 0x80, 0x00, 0x00, 0x00} /* 41MHz XTal */
2188*4882a593Smuzhiyun };
2189*4882a593Smuzhiyun
2190*4882a593Smuzhiyun static const uint8_t nominalRate6bw[3][5] = {
2191*4882a593Smuzhiyun /* TRCG Nominal Rate [37:0] */
2192*4882a593Smuzhiyun {0x17, 0xEA, 0xAA, 0xAA, 0xAA}, /* 20.5MHz XTal */
2193*4882a593Smuzhiyun {0x1C, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2194*4882a593Smuzhiyun {0x17, 0xEA, 0xAA, 0xAA, 0xAA} /* 41MHz XTal */
2195*4882a593Smuzhiyun };
2196*4882a593Smuzhiyun
2197*4882a593Smuzhiyun static const uint8_t nominalRate5bw[3][5] = {
2198*4882a593Smuzhiyun /* TRCG Nominal Rate [37:0] */
2199*4882a593Smuzhiyun {0x1C, 0xB3, 0x33, 0x33, 0x33}, /* 20.5MHz XTal */
2200*4882a593Smuzhiyun {0x21, 0x99, 0x99, 0x99, 0x99}, /* 24MHz XTal */
2201*4882a593Smuzhiyun {0x1C, 0xB3, 0x33, 0x33, 0x33} /* 41MHz XTal */
2202*4882a593Smuzhiyun };
2203*4882a593Smuzhiyun
2204*4882a593Smuzhiyun static const uint8_t nominalRate17bw[3][5] = {
2205*4882a593Smuzhiyun /* TRCG Nominal Rate [37:0] */
2206*4882a593Smuzhiyun {0x58, 0xE2, 0xAF, 0xE0, 0xBC}, /* 20.5MHz XTal */
2207*4882a593Smuzhiyun {0x68, 0x0F, 0xA2, 0x32, 0xD0}, /* 24MHz XTal */
2208*4882a593Smuzhiyun {0x58, 0xE2, 0xAF, 0xE0, 0xBC} /* 41MHz XTal */
2209*4882a593Smuzhiyun };
2210*4882a593Smuzhiyun
2211*4882a593Smuzhiyun static const uint8_t itbCoef8bw[3][14] = {
2212*4882a593Smuzhiyun {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA,
2213*4882a593Smuzhiyun 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8}, /* 20.5MHz XTal */
2214*4882a593Smuzhiyun {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1,
2215*4882a593Smuzhiyun 0x29, 0xA5, 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz XTal */
2216*4882a593Smuzhiyun {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA,
2217*4882a593Smuzhiyun 0x23, 0xA9, 0x1F, 0xA8, 0x2C, 0xC8} /* 41MHz XTal */
2218*4882a593Smuzhiyun };
2219*4882a593Smuzhiyun
2220*4882a593Smuzhiyun static const uint8_t itbCoef7bw[3][14] = {
2221*4882a593Smuzhiyun {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6,
2222*4882a593Smuzhiyun 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5}, /* 20.5MHz XTal */
2223*4882a593Smuzhiyun {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0,
2224*4882a593Smuzhiyun 0x29, 0xA2, 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz XTal */
2225*4882a593Smuzhiyun {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6,
2226*4882a593Smuzhiyun 0x29, 0xB0, 0x26, 0xA9, 0x21, 0xA5} /* 41MHz XTal */
2227*4882a593Smuzhiyun };
2228*4882a593Smuzhiyun
2229*4882a593Smuzhiyun static const uint8_t itbCoef6bw[3][14] = {
2230*4882a593Smuzhiyun {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
2231*4882a593Smuzhiyun 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */
2232*4882a593Smuzhiyun {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E,
2233*4882a593Smuzhiyun 0x29, 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */
2234*4882a593Smuzhiyun {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
2235*4882a593Smuzhiyun 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */
2236*4882a593Smuzhiyun };
2237*4882a593Smuzhiyun
2238*4882a593Smuzhiyun static const uint8_t itbCoef5bw[3][14] = {
2239*4882a593Smuzhiyun {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
2240*4882a593Smuzhiyun 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */
2241*4882a593Smuzhiyun {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E,
2242*4882a593Smuzhiyun 0x29, 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */
2243*4882a593Smuzhiyun {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
2244*4882a593Smuzhiyun 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */
2245*4882a593Smuzhiyun };
2246*4882a593Smuzhiyun
2247*4882a593Smuzhiyun static const uint8_t itbCoef17bw[3][14] = {
2248*4882a593Smuzhiyun {0x25, 0xA0, 0x36, 0x8D, 0x2E, 0x94, 0x28, 0x9B,
2249*4882a593Smuzhiyun 0x32, 0x90, 0x2C, 0x9D, 0x29, 0x99}, /* 20.5MHz XTal */
2250*4882a593Smuzhiyun {0x33, 0x8E, 0x2B, 0x97, 0x2D, 0x95, 0x37, 0x8B,
2251*4882a593Smuzhiyun 0x30, 0x97, 0x2D, 0x9A, 0x21, 0xA4}, /* 24MHz XTal */
2252*4882a593Smuzhiyun {0x25, 0xA0, 0x36, 0x8D, 0x2E, 0x94, 0x28, 0x9B,
2253*4882a593Smuzhiyun 0x32, 0x90, 0x2C, 0x9D, 0x29, 0x99} /* 41MHz XTal */
2254*4882a593Smuzhiyun };
2255*4882a593Smuzhiyun
2256*4882a593Smuzhiyun /* Set SLV-T Bank : 0x20 */
2257*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
2258*4882a593Smuzhiyun
2259*4882a593Smuzhiyun switch (bandwidth) {
2260*4882a593Smuzhiyun case 8000000:
2261*4882a593Smuzhiyun /* <Timing Recovery setting> */
2262*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2263*4882a593Smuzhiyun 0x9F, nominalRate8bw[priv->xtal], 5);
2264*4882a593Smuzhiyun
2265*4882a593Smuzhiyun /* Set SLV-T Bank : 0x27 */
2266*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
2267*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT,
2268*4882a593Smuzhiyun 0x7a, 0x00, 0x0f);
2269*4882a593Smuzhiyun
2270*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
2271*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2272*4882a593Smuzhiyun
2273*4882a593Smuzhiyun /* Group delay equaliser settings for
2274*4882a593Smuzhiyun * ASCOT2D, ASCOT2E and ASCOT3 tuners
2275*4882a593Smuzhiyun */
2276*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2277*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2278*4882a593Smuzhiyun 0xA6, itbCoef8bw[priv->xtal], 14);
2279*4882a593Smuzhiyun /* <IF freq setting> */
2280*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 4800000);
2281*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2282*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2283*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2284*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2285*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2286*4882a593Smuzhiyun /* System bandwidth setting */
2287*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2288*4882a593Smuzhiyun priv, I2C_SLVT, 0xD7, 0x00, 0x07);
2289*4882a593Smuzhiyun break;
2290*4882a593Smuzhiyun case 7000000:
2291*4882a593Smuzhiyun /* <Timing Recovery setting> */
2292*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2293*4882a593Smuzhiyun 0x9F, nominalRate7bw[priv->xtal], 5);
2294*4882a593Smuzhiyun
2295*4882a593Smuzhiyun /* Set SLV-T Bank : 0x27 */
2296*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
2297*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT,
2298*4882a593Smuzhiyun 0x7a, 0x00, 0x0f);
2299*4882a593Smuzhiyun
2300*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
2301*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2302*4882a593Smuzhiyun
2303*4882a593Smuzhiyun /* Group delay equaliser settings for
2304*4882a593Smuzhiyun * ASCOT2D, ASCOT2E and ASCOT3 tuners
2305*4882a593Smuzhiyun */
2306*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2307*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2308*4882a593Smuzhiyun 0xA6, itbCoef7bw[priv->xtal], 14);
2309*4882a593Smuzhiyun /* <IF freq setting> */
2310*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 4200000);
2311*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2312*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2313*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2314*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2315*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2316*4882a593Smuzhiyun /* System bandwidth setting */
2317*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2318*4882a593Smuzhiyun priv, I2C_SLVT, 0xD7, 0x02, 0x07);
2319*4882a593Smuzhiyun break;
2320*4882a593Smuzhiyun case 6000000:
2321*4882a593Smuzhiyun /* <Timing Recovery setting> */
2322*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2323*4882a593Smuzhiyun 0x9F, nominalRate6bw[priv->xtal], 5);
2324*4882a593Smuzhiyun
2325*4882a593Smuzhiyun /* Set SLV-T Bank : 0x27 */
2326*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
2327*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT,
2328*4882a593Smuzhiyun 0x7a, 0x00, 0x0f);
2329*4882a593Smuzhiyun
2330*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
2331*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2332*4882a593Smuzhiyun
2333*4882a593Smuzhiyun /* Group delay equaliser settings for
2334*4882a593Smuzhiyun * ASCOT2D, ASCOT2E and ASCOT3 tuners
2335*4882a593Smuzhiyun */
2336*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2337*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2338*4882a593Smuzhiyun 0xA6, itbCoef6bw[priv->xtal], 14);
2339*4882a593Smuzhiyun /* <IF freq setting> */
2340*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 3600000);
2341*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2342*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2343*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2344*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2345*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2346*4882a593Smuzhiyun /* System bandwidth setting */
2347*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2348*4882a593Smuzhiyun priv, I2C_SLVT, 0xD7, 0x04, 0x07);
2349*4882a593Smuzhiyun break;
2350*4882a593Smuzhiyun case 5000000:
2351*4882a593Smuzhiyun /* <Timing Recovery setting> */
2352*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2353*4882a593Smuzhiyun 0x9F, nominalRate5bw[priv->xtal], 5);
2354*4882a593Smuzhiyun
2355*4882a593Smuzhiyun /* Set SLV-T Bank : 0x27 */
2356*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
2357*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT,
2358*4882a593Smuzhiyun 0x7a, 0x00, 0x0f);
2359*4882a593Smuzhiyun
2360*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
2361*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2362*4882a593Smuzhiyun
2363*4882a593Smuzhiyun /* Group delay equaliser settings for
2364*4882a593Smuzhiyun * ASCOT2D, ASCOT2E and ASCOT3 tuners
2365*4882a593Smuzhiyun */
2366*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2367*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2368*4882a593Smuzhiyun 0xA6, itbCoef5bw[priv->xtal], 14);
2369*4882a593Smuzhiyun /* <IF freq setting> */
2370*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 3600000);
2371*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2372*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2373*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2374*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2375*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2376*4882a593Smuzhiyun /* System bandwidth setting */
2377*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2378*4882a593Smuzhiyun priv, I2C_SLVT, 0xD7, 0x06, 0x07);
2379*4882a593Smuzhiyun break;
2380*4882a593Smuzhiyun case 1712000:
2381*4882a593Smuzhiyun /* <Timing Recovery setting> */
2382*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2383*4882a593Smuzhiyun 0x9F, nominalRate17bw[priv->xtal], 5);
2384*4882a593Smuzhiyun
2385*4882a593Smuzhiyun /* Set SLV-T Bank : 0x27 */
2386*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
2387*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT,
2388*4882a593Smuzhiyun 0x7a, 0x03, 0x0f);
2389*4882a593Smuzhiyun
2390*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
2391*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2392*4882a593Smuzhiyun
2393*4882a593Smuzhiyun /* Group delay equaliser settings for
2394*4882a593Smuzhiyun * ASCOT2D, ASCOT2E and ASCOT3 tuners
2395*4882a593Smuzhiyun */
2396*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2397*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2398*4882a593Smuzhiyun 0xA6, itbCoef17bw[priv->xtal], 14);
2399*4882a593Smuzhiyun /* <IF freq setting> */
2400*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 3500000);
2401*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2402*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2403*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2404*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2405*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2406*4882a593Smuzhiyun /* System bandwidth setting */
2407*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2408*4882a593Smuzhiyun priv, I2C_SLVT, 0xD7, 0x03, 0x07);
2409*4882a593Smuzhiyun break;
2410*4882a593Smuzhiyun default:
2411*4882a593Smuzhiyun return -EINVAL;
2412*4882a593Smuzhiyun }
2413*4882a593Smuzhiyun return 0;
2414*4882a593Smuzhiyun }
2415*4882a593Smuzhiyun
cxd2841er_sleep_tc_to_active_t_band(struct cxd2841er_priv * priv,u32 bandwidth)2416*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_t_band(
2417*4882a593Smuzhiyun struct cxd2841er_priv *priv, u32 bandwidth)
2418*4882a593Smuzhiyun {
2419*4882a593Smuzhiyun u8 data[MAX_WRITE_REGSIZE];
2420*4882a593Smuzhiyun u32 iffreq, ifhz;
2421*4882a593Smuzhiyun static const u8 nominalRate8bw[3][5] = {
2422*4882a593Smuzhiyun /* TRCG Nominal Rate [37:0] */
2423*4882a593Smuzhiyun {0x11, 0xF0, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2424*4882a593Smuzhiyun {0x15, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2425*4882a593Smuzhiyun {0x11, 0xF0, 0x00, 0x00, 0x00} /* 41MHz XTal */
2426*4882a593Smuzhiyun };
2427*4882a593Smuzhiyun static const u8 nominalRate7bw[3][5] = {
2428*4882a593Smuzhiyun /* TRCG Nominal Rate [37:0] */
2429*4882a593Smuzhiyun {0x14, 0x80, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2430*4882a593Smuzhiyun {0x18, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2431*4882a593Smuzhiyun {0x14, 0x80, 0x00, 0x00, 0x00} /* 41MHz XTal */
2432*4882a593Smuzhiyun };
2433*4882a593Smuzhiyun static const u8 nominalRate6bw[3][5] = {
2434*4882a593Smuzhiyun /* TRCG Nominal Rate [37:0] */
2435*4882a593Smuzhiyun {0x17, 0xEA, 0xAA, 0xAA, 0xAA}, /* 20.5MHz XTal */
2436*4882a593Smuzhiyun {0x1C, 0x00, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2437*4882a593Smuzhiyun {0x17, 0xEA, 0xAA, 0xAA, 0xAA} /* 41MHz XTal */
2438*4882a593Smuzhiyun };
2439*4882a593Smuzhiyun static const u8 nominalRate5bw[3][5] = {
2440*4882a593Smuzhiyun /* TRCG Nominal Rate [37:0] */
2441*4882a593Smuzhiyun {0x1C, 0xB3, 0x33, 0x33, 0x33}, /* 20.5MHz XTal */
2442*4882a593Smuzhiyun {0x21, 0x99, 0x99, 0x99, 0x99}, /* 24MHz XTal */
2443*4882a593Smuzhiyun {0x1C, 0xB3, 0x33, 0x33, 0x33} /* 41MHz XTal */
2444*4882a593Smuzhiyun };
2445*4882a593Smuzhiyun
2446*4882a593Smuzhiyun static const u8 itbCoef8bw[3][14] = {
2447*4882a593Smuzhiyun {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9,
2448*4882a593Smuzhiyun 0x1F, 0xA8, 0x2C, 0xC8}, /* 20.5MHz XTal */
2449*4882a593Smuzhiyun {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 0x29, 0xA5,
2450*4882a593Smuzhiyun 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz XTal */
2451*4882a593Smuzhiyun {0x26, 0xAF, 0x06, 0xCD, 0x13, 0xBB, 0x28, 0xBA, 0x23, 0xA9,
2452*4882a593Smuzhiyun 0x1F, 0xA8, 0x2C, 0xC8} /* 41MHz XTal */
2453*4882a593Smuzhiyun };
2454*4882a593Smuzhiyun static const u8 itbCoef7bw[3][14] = {
2455*4882a593Smuzhiyun {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0,
2456*4882a593Smuzhiyun 0x26, 0xA9, 0x21, 0xA5}, /* 20.5MHz XTal */
2457*4882a593Smuzhiyun {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 0x29, 0xA2,
2458*4882a593Smuzhiyun 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz XTal */
2459*4882a593Smuzhiyun {0x2C, 0xBD, 0x02, 0xCF, 0x04, 0xF8, 0x23, 0xA6, 0x29, 0xB0,
2460*4882a593Smuzhiyun 0x26, 0xA9, 0x21, 0xA5} /* 41MHz XTal */
2461*4882a593Smuzhiyun };
2462*4882a593Smuzhiyun static const u8 itbCoef6bw[3][14] = {
2463*4882a593Smuzhiyun {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF,
2464*4882a593Smuzhiyun 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */
2465*4882a593Smuzhiyun {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 0xA4,
2466*4882a593Smuzhiyun 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */
2467*4882a593Smuzhiyun {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF,
2468*4882a593Smuzhiyun 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */
2469*4882a593Smuzhiyun };
2470*4882a593Smuzhiyun static const u8 itbCoef5bw[3][14] = {
2471*4882a593Smuzhiyun {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF,
2472*4882a593Smuzhiyun 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */
2473*4882a593Smuzhiyun {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29, 0xA4,
2474*4882a593Smuzhiyun 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz XTal */
2475*4882a593Smuzhiyun {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00, 0xCF,
2476*4882a593Smuzhiyun 0x00, 0xE6, 0x23, 0xA4} /* 41MHz XTal */
2477*4882a593Smuzhiyun };
2478*4882a593Smuzhiyun
2479*4882a593Smuzhiyun /* Set SLV-T Bank : 0x13 */
2480*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13);
2481*4882a593Smuzhiyun /* Echo performance optimization setting */
2482*4882a593Smuzhiyun data[0] = 0x01;
2483*4882a593Smuzhiyun data[1] = 0x14;
2484*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x9C, data, 2);
2485*4882a593Smuzhiyun
2486*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
2487*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2488*4882a593Smuzhiyun
2489*4882a593Smuzhiyun switch (bandwidth) {
2490*4882a593Smuzhiyun case 8000000:
2491*4882a593Smuzhiyun /* <Timing Recovery setting> */
2492*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2493*4882a593Smuzhiyun 0x9F, nominalRate8bw[priv->xtal], 5);
2494*4882a593Smuzhiyun /* Group delay equaliser settings for
2495*4882a593Smuzhiyun * ASCOT2D, ASCOT2E and ASCOT3 tuners
2496*4882a593Smuzhiyun */
2497*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2498*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2499*4882a593Smuzhiyun 0xA6, itbCoef8bw[priv->xtal], 14);
2500*4882a593Smuzhiyun /* <IF freq setting> */
2501*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 4800000);
2502*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2503*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2504*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2505*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2506*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2507*4882a593Smuzhiyun /* System bandwidth setting */
2508*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2509*4882a593Smuzhiyun priv, I2C_SLVT, 0xD7, 0x00, 0x07);
2510*4882a593Smuzhiyun
2511*4882a593Smuzhiyun /* Demod core latency setting */
2512*4882a593Smuzhiyun if (priv->xtal == SONY_XTAL_24000) {
2513*4882a593Smuzhiyun data[0] = 0x15;
2514*4882a593Smuzhiyun data[1] = 0x28;
2515*4882a593Smuzhiyun } else {
2516*4882a593Smuzhiyun data[0] = 0x01;
2517*4882a593Smuzhiyun data[1] = 0xE0;
2518*4882a593Smuzhiyun }
2519*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2520*4882a593Smuzhiyun
2521*4882a593Smuzhiyun /* Notch filter setting */
2522*4882a593Smuzhiyun data[0] = 0x01;
2523*4882a593Smuzhiyun data[1] = 0x02;
2524*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17);
2525*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2);
2526*4882a593Smuzhiyun break;
2527*4882a593Smuzhiyun case 7000000:
2528*4882a593Smuzhiyun /* <Timing Recovery setting> */
2529*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2530*4882a593Smuzhiyun 0x9F, nominalRate7bw[priv->xtal], 5);
2531*4882a593Smuzhiyun /* Group delay equaliser settings for
2532*4882a593Smuzhiyun * ASCOT2D, ASCOT2E and ASCOT3 tuners
2533*4882a593Smuzhiyun */
2534*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2535*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2536*4882a593Smuzhiyun 0xA6, itbCoef7bw[priv->xtal], 14);
2537*4882a593Smuzhiyun /* <IF freq setting> */
2538*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 4200000);
2539*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2540*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2541*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2542*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2543*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2544*4882a593Smuzhiyun /* System bandwidth setting */
2545*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2546*4882a593Smuzhiyun priv, I2C_SLVT, 0xD7, 0x02, 0x07);
2547*4882a593Smuzhiyun
2548*4882a593Smuzhiyun /* Demod core latency setting */
2549*4882a593Smuzhiyun if (priv->xtal == SONY_XTAL_24000) {
2550*4882a593Smuzhiyun data[0] = 0x1F;
2551*4882a593Smuzhiyun data[1] = 0xF8;
2552*4882a593Smuzhiyun } else {
2553*4882a593Smuzhiyun data[0] = 0x12;
2554*4882a593Smuzhiyun data[1] = 0xF8;
2555*4882a593Smuzhiyun }
2556*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2557*4882a593Smuzhiyun
2558*4882a593Smuzhiyun /* Notch filter setting */
2559*4882a593Smuzhiyun data[0] = 0x00;
2560*4882a593Smuzhiyun data[1] = 0x03;
2561*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17);
2562*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2);
2563*4882a593Smuzhiyun break;
2564*4882a593Smuzhiyun case 6000000:
2565*4882a593Smuzhiyun /* <Timing Recovery setting> */
2566*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2567*4882a593Smuzhiyun 0x9F, nominalRate6bw[priv->xtal], 5);
2568*4882a593Smuzhiyun /* Group delay equaliser settings for
2569*4882a593Smuzhiyun * ASCOT2D, ASCOT2E and ASCOT3 tuners
2570*4882a593Smuzhiyun */
2571*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2572*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2573*4882a593Smuzhiyun 0xA6, itbCoef6bw[priv->xtal], 14);
2574*4882a593Smuzhiyun /* <IF freq setting> */
2575*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 3600000);
2576*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2577*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2578*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2579*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2580*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2581*4882a593Smuzhiyun /* System bandwidth setting */
2582*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2583*4882a593Smuzhiyun priv, I2C_SLVT, 0xD7, 0x04, 0x07);
2584*4882a593Smuzhiyun
2585*4882a593Smuzhiyun /* Demod core latency setting */
2586*4882a593Smuzhiyun if (priv->xtal == SONY_XTAL_24000) {
2587*4882a593Smuzhiyun data[0] = 0x25;
2588*4882a593Smuzhiyun data[1] = 0x4C;
2589*4882a593Smuzhiyun } else {
2590*4882a593Smuzhiyun data[0] = 0x1F;
2591*4882a593Smuzhiyun data[1] = 0xDC;
2592*4882a593Smuzhiyun }
2593*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2594*4882a593Smuzhiyun
2595*4882a593Smuzhiyun /* Notch filter setting */
2596*4882a593Smuzhiyun data[0] = 0x00;
2597*4882a593Smuzhiyun data[1] = 0x03;
2598*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17);
2599*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2);
2600*4882a593Smuzhiyun break;
2601*4882a593Smuzhiyun case 5000000:
2602*4882a593Smuzhiyun /* <Timing Recovery setting> */
2603*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2604*4882a593Smuzhiyun 0x9F, nominalRate5bw[priv->xtal], 5);
2605*4882a593Smuzhiyun /* Group delay equaliser settings for
2606*4882a593Smuzhiyun * ASCOT2D, ASCOT2E and ASCOT3 tuners
2607*4882a593Smuzhiyun */
2608*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2609*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2610*4882a593Smuzhiyun 0xA6, itbCoef5bw[priv->xtal], 14);
2611*4882a593Smuzhiyun /* <IF freq setting> */
2612*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 3600000);
2613*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2614*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2615*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2616*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2617*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2618*4882a593Smuzhiyun /* System bandwidth setting */
2619*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2620*4882a593Smuzhiyun priv, I2C_SLVT, 0xD7, 0x06, 0x07);
2621*4882a593Smuzhiyun
2622*4882a593Smuzhiyun /* Demod core latency setting */
2623*4882a593Smuzhiyun if (priv->xtal == SONY_XTAL_24000) {
2624*4882a593Smuzhiyun data[0] = 0x2C;
2625*4882a593Smuzhiyun data[1] = 0xC2;
2626*4882a593Smuzhiyun } else {
2627*4882a593Smuzhiyun data[0] = 0x26;
2628*4882a593Smuzhiyun data[1] = 0x3C;
2629*4882a593Smuzhiyun }
2630*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2631*4882a593Smuzhiyun
2632*4882a593Smuzhiyun /* Notch filter setting */
2633*4882a593Smuzhiyun data[0] = 0x00;
2634*4882a593Smuzhiyun data[1] = 0x03;
2635*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x17);
2636*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x38, data, 2);
2637*4882a593Smuzhiyun break;
2638*4882a593Smuzhiyun }
2639*4882a593Smuzhiyun
2640*4882a593Smuzhiyun return 0;
2641*4882a593Smuzhiyun }
2642*4882a593Smuzhiyun
cxd2841er_sleep_tc_to_active_i_band(struct cxd2841er_priv * priv,u32 bandwidth)2643*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_i_band(
2644*4882a593Smuzhiyun struct cxd2841er_priv *priv, u32 bandwidth)
2645*4882a593Smuzhiyun {
2646*4882a593Smuzhiyun u32 iffreq, ifhz;
2647*4882a593Smuzhiyun u8 data[3];
2648*4882a593Smuzhiyun
2649*4882a593Smuzhiyun /* TRCG Nominal Rate */
2650*4882a593Smuzhiyun static const u8 nominalRate8bw[3][5] = {
2651*4882a593Smuzhiyun {0x00, 0x00, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2652*4882a593Smuzhiyun {0x11, 0xB8, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2653*4882a593Smuzhiyun {0x00, 0x00, 0x00, 0x00, 0x00} /* 41MHz XTal */
2654*4882a593Smuzhiyun };
2655*4882a593Smuzhiyun
2656*4882a593Smuzhiyun static const u8 nominalRate7bw[3][5] = {
2657*4882a593Smuzhiyun {0x00, 0x00, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2658*4882a593Smuzhiyun {0x14, 0x40, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2659*4882a593Smuzhiyun {0x00, 0x00, 0x00, 0x00, 0x00} /* 41MHz XTal */
2660*4882a593Smuzhiyun };
2661*4882a593Smuzhiyun
2662*4882a593Smuzhiyun static const u8 nominalRate6bw[3][5] = {
2663*4882a593Smuzhiyun {0x14, 0x2E, 0x00, 0x00, 0x00}, /* 20.5MHz XTal */
2664*4882a593Smuzhiyun {0x17, 0xA0, 0x00, 0x00, 0x00}, /* 24MHz XTal */
2665*4882a593Smuzhiyun {0x14, 0x2E, 0x00, 0x00, 0x00} /* 41MHz XTal */
2666*4882a593Smuzhiyun };
2667*4882a593Smuzhiyun
2668*4882a593Smuzhiyun static const u8 itbCoef8bw[3][14] = {
2669*4882a593Smuzhiyun {0x00}, /* 20.5MHz XTal */
2670*4882a593Smuzhiyun {0x2F, 0xBA, 0x28, 0x9B, 0x28, 0x9D, 0x28, 0xA1, 0x29,
2671*4882a593Smuzhiyun 0xA5, 0x2A, 0xAC, 0x29, 0xB5}, /* 24MHz Xtal */
2672*4882a593Smuzhiyun {0x0}, /* 41MHz XTal */
2673*4882a593Smuzhiyun };
2674*4882a593Smuzhiyun
2675*4882a593Smuzhiyun static const u8 itbCoef7bw[3][14] = {
2676*4882a593Smuzhiyun {0x00}, /* 20.5MHz XTal */
2677*4882a593Smuzhiyun {0x30, 0xB1, 0x29, 0x9A, 0x28, 0x9C, 0x28, 0xA0, 0x29,
2678*4882a593Smuzhiyun 0xA2, 0x2B, 0xA6, 0x2B, 0xAD}, /* 24MHz Xtal */
2679*4882a593Smuzhiyun {0x00}, /* 41MHz XTal */
2680*4882a593Smuzhiyun };
2681*4882a593Smuzhiyun
2682*4882a593Smuzhiyun static const u8 itbCoef6bw[3][14] = {
2683*4882a593Smuzhiyun {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00,
2684*4882a593Smuzhiyun 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 20.5MHz XTal */
2685*4882a593Smuzhiyun {0x31, 0xA8, 0x29, 0x9B, 0x27, 0x9C, 0x28, 0x9E, 0x29,
2686*4882a593Smuzhiyun 0xA4, 0x29, 0xA2, 0x29, 0xA8}, /* 24MHz Xtal */
2687*4882a593Smuzhiyun {0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8, 0x00,
2688*4882a593Smuzhiyun 0xCF, 0x00, 0xE6, 0x23, 0xA4}, /* 41MHz XTal */
2689*4882a593Smuzhiyun };
2690*4882a593Smuzhiyun
2691*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s() bandwidth=%u\n", __func__, bandwidth);
2692*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
2693*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2694*4882a593Smuzhiyun
2695*4882a593Smuzhiyun /* 20.5/41MHz Xtal support is not available
2696*4882a593Smuzhiyun * on ISDB-T 7MHzBW and 8MHzBW
2697*4882a593Smuzhiyun */
2698*4882a593Smuzhiyun if (priv->xtal != SONY_XTAL_24000 && bandwidth > 6000000) {
2699*4882a593Smuzhiyun dev_err(&priv->i2c->dev,
2700*4882a593Smuzhiyun "%s(): bandwidth %d supported only for 24MHz xtal\n",
2701*4882a593Smuzhiyun __func__, bandwidth);
2702*4882a593Smuzhiyun return -EINVAL;
2703*4882a593Smuzhiyun }
2704*4882a593Smuzhiyun
2705*4882a593Smuzhiyun switch (bandwidth) {
2706*4882a593Smuzhiyun case 8000000:
2707*4882a593Smuzhiyun /* TRCG Nominal Rate */
2708*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2709*4882a593Smuzhiyun 0x9F, nominalRate8bw[priv->xtal], 5);
2710*4882a593Smuzhiyun /* Group delay equaliser settings for ASCOT tuners optimized */
2711*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2712*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2713*4882a593Smuzhiyun 0xA6, itbCoef8bw[priv->xtal], 14);
2714*4882a593Smuzhiyun
2715*4882a593Smuzhiyun /* IF freq setting */
2716*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 4750000);
2717*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2718*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2719*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2720*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2721*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2722*4882a593Smuzhiyun
2723*4882a593Smuzhiyun /* System bandwidth setting */
2724*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x0, 0x7);
2725*4882a593Smuzhiyun
2726*4882a593Smuzhiyun /* Demod core latency setting */
2727*4882a593Smuzhiyun data[0] = 0x13;
2728*4882a593Smuzhiyun data[1] = 0xFC;
2729*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2730*4882a593Smuzhiyun
2731*4882a593Smuzhiyun /* Acquisition optimization setting */
2732*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12);
2733*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x03, 0x07);
2734*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15);
2735*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x03);
2736*4882a593Smuzhiyun break;
2737*4882a593Smuzhiyun case 7000000:
2738*4882a593Smuzhiyun /* TRCG Nominal Rate */
2739*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2740*4882a593Smuzhiyun 0x9F, nominalRate7bw[priv->xtal], 5);
2741*4882a593Smuzhiyun /* Group delay equaliser settings for ASCOT tuners optimized */
2742*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2743*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2744*4882a593Smuzhiyun 0xA6, itbCoef7bw[priv->xtal], 14);
2745*4882a593Smuzhiyun
2746*4882a593Smuzhiyun /* IF freq setting */
2747*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 4150000);
2748*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2749*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2750*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2751*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2752*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2753*4882a593Smuzhiyun
2754*4882a593Smuzhiyun /* System bandwidth setting */
2755*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x02, 0x7);
2756*4882a593Smuzhiyun
2757*4882a593Smuzhiyun /* Demod core latency setting */
2758*4882a593Smuzhiyun data[0] = 0x1A;
2759*4882a593Smuzhiyun data[1] = 0xFA;
2760*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2761*4882a593Smuzhiyun
2762*4882a593Smuzhiyun /* Acquisition optimization setting */
2763*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12);
2764*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x03, 0x07);
2765*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15);
2766*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x02);
2767*4882a593Smuzhiyun break;
2768*4882a593Smuzhiyun case 6000000:
2769*4882a593Smuzhiyun /* TRCG Nominal Rate */
2770*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2771*4882a593Smuzhiyun 0x9F, nominalRate6bw[priv->xtal], 5);
2772*4882a593Smuzhiyun /* Group delay equaliser settings for ASCOT tuners optimized */
2773*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2774*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT,
2775*4882a593Smuzhiyun 0xA6, itbCoef6bw[priv->xtal], 14);
2776*4882a593Smuzhiyun
2777*4882a593Smuzhiyun /* IF freq setting */
2778*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 3550000);
2779*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq_xtal(priv->xtal, ifhz);
2780*4882a593Smuzhiyun data[0] = (u8) ((iffreq >> 16) & 0xff);
2781*4882a593Smuzhiyun data[1] = (u8)((iffreq >> 8) & 0xff);
2782*4882a593Smuzhiyun data[2] = (u8)(iffreq & 0xff);
2783*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xB6, data, 3);
2784*4882a593Smuzhiyun
2785*4882a593Smuzhiyun /* System bandwidth setting */
2786*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd7, 0x04, 0x7);
2787*4882a593Smuzhiyun
2788*4882a593Smuzhiyun /* Demod core latency setting */
2789*4882a593Smuzhiyun if (priv->xtal == SONY_XTAL_24000) {
2790*4882a593Smuzhiyun data[0] = 0x1F;
2791*4882a593Smuzhiyun data[1] = 0x79;
2792*4882a593Smuzhiyun } else {
2793*4882a593Smuzhiyun data[0] = 0x1A;
2794*4882a593Smuzhiyun data[1] = 0xE2;
2795*4882a593Smuzhiyun }
2796*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
2797*4882a593Smuzhiyun
2798*4882a593Smuzhiyun /* Acquisition optimization setting */
2799*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x12);
2800*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x71, 0x07, 0x07);
2801*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15);
2802*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xBE, 0x02);
2803*4882a593Smuzhiyun break;
2804*4882a593Smuzhiyun default:
2805*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid bandwidth %d\n",
2806*4882a593Smuzhiyun __func__, bandwidth);
2807*4882a593Smuzhiyun return -EINVAL;
2808*4882a593Smuzhiyun }
2809*4882a593Smuzhiyun return 0;
2810*4882a593Smuzhiyun }
2811*4882a593Smuzhiyun
cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv * priv,u32 bandwidth)2812*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_c_band(struct cxd2841er_priv *priv,
2813*4882a593Smuzhiyun u32 bandwidth)
2814*4882a593Smuzhiyun {
2815*4882a593Smuzhiyun u8 bw7_8mhz_b10_a6[] = {
2816*4882a593Smuzhiyun 0x2D, 0xC7, 0x04, 0xF4, 0x07, 0xC5, 0x2A, 0xB8,
2817*4882a593Smuzhiyun 0x27, 0x9E, 0x27, 0xA4, 0x29, 0xAB };
2818*4882a593Smuzhiyun u8 bw6mhz_b10_a6[] = {
2819*4882a593Smuzhiyun 0x27, 0xA7, 0x28, 0xB3, 0x02, 0xF0, 0x01, 0xE8,
2820*4882a593Smuzhiyun 0x00, 0xCF, 0x00, 0xE6, 0x23, 0xA4 };
2821*4882a593Smuzhiyun u8 b10_b6[3];
2822*4882a593Smuzhiyun u32 iffreq, ifhz;
2823*4882a593Smuzhiyun
2824*4882a593Smuzhiyun if (bandwidth != 6000000 &&
2825*4882a593Smuzhiyun bandwidth != 7000000 &&
2826*4882a593Smuzhiyun bandwidth != 8000000) {
2827*4882a593Smuzhiyun dev_info(&priv->i2c->dev, "%s(): unsupported bandwidth %d. Forcing 8Mhz!\n",
2828*4882a593Smuzhiyun __func__, bandwidth);
2829*4882a593Smuzhiyun bandwidth = 8000000;
2830*4882a593Smuzhiyun }
2831*4882a593Smuzhiyun
2832*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s() bw=%d\n", __func__, bandwidth);
2833*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2834*4882a593Smuzhiyun switch (bandwidth) {
2835*4882a593Smuzhiyun case 8000000:
2836*4882a593Smuzhiyun case 7000000:
2837*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2838*4882a593Smuzhiyun cxd2841er_write_regs(
2839*4882a593Smuzhiyun priv, I2C_SLVT, 0xa6,
2840*4882a593Smuzhiyun bw7_8mhz_b10_a6, sizeof(bw7_8mhz_b10_a6));
2841*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 4900000);
2842*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq(ifhz);
2843*4882a593Smuzhiyun break;
2844*4882a593Smuzhiyun case 6000000:
2845*4882a593Smuzhiyun if (priv->flags & CXD2841ER_ASCOT)
2846*4882a593Smuzhiyun cxd2841er_write_regs(
2847*4882a593Smuzhiyun priv, I2C_SLVT, 0xa6,
2848*4882a593Smuzhiyun bw6mhz_b10_a6, sizeof(bw6mhz_b10_a6));
2849*4882a593Smuzhiyun ifhz = cxd2841er_get_if_hz(priv, 3700000);
2850*4882a593Smuzhiyun iffreq = cxd2841er_calc_iffreq(ifhz);
2851*4882a593Smuzhiyun break;
2852*4882a593Smuzhiyun default:
2853*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): unsupported bandwidth %d\n",
2854*4882a593Smuzhiyun __func__, bandwidth);
2855*4882a593Smuzhiyun return -EINVAL;
2856*4882a593Smuzhiyun }
2857*4882a593Smuzhiyun /* <IF freq setting> */
2858*4882a593Smuzhiyun b10_b6[0] = (u8) ((iffreq >> 16) & 0xff);
2859*4882a593Smuzhiyun b10_b6[1] = (u8)((iffreq >> 8) & 0xff);
2860*4882a593Smuzhiyun b10_b6[2] = (u8)(iffreq & 0xff);
2861*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xb6, b10_b6, sizeof(b10_b6));
2862*4882a593Smuzhiyun /* Set SLV-T Bank : 0x11 */
2863*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11);
2864*4882a593Smuzhiyun switch (bandwidth) {
2865*4882a593Smuzhiyun case 8000000:
2866*4882a593Smuzhiyun case 7000000:
2867*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2868*4882a593Smuzhiyun priv, I2C_SLVT, 0xa3, 0x00, 0x1f);
2869*4882a593Smuzhiyun break;
2870*4882a593Smuzhiyun case 6000000:
2871*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2872*4882a593Smuzhiyun priv, I2C_SLVT, 0xa3, 0x14, 0x1f);
2873*4882a593Smuzhiyun break;
2874*4882a593Smuzhiyun }
2875*4882a593Smuzhiyun /* Set SLV-T Bank : 0x40 */
2876*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
2877*4882a593Smuzhiyun switch (bandwidth) {
2878*4882a593Smuzhiyun case 8000000:
2879*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2880*4882a593Smuzhiyun priv, I2C_SLVT, 0x26, 0x0b, 0x0f);
2881*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x27, 0x3e);
2882*4882a593Smuzhiyun break;
2883*4882a593Smuzhiyun case 7000000:
2884*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2885*4882a593Smuzhiyun priv, I2C_SLVT, 0x26, 0x09, 0x0f);
2886*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x27, 0xd6);
2887*4882a593Smuzhiyun break;
2888*4882a593Smuzhiyun case 6000000:
2889*4882a593Smuzhiyun cxd2841er_set_reg_bits(
2890*4882a593Smuzhiyun priv, I2C_SLVT, 0x26, 0x08, 0x0f);
2891*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x27, 0x6e);
2892*4882a593Smuzhiyun break;
2893*4882a593Smuzhiyun }
2894*4882a593Smuzhiyun return 0;
2895*4882a593Smuzhiyun }
2896*4882a593Smuzhiyun
cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv * priv,u32 bandwidth)2897*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_t(struct cxd2841er_priv *priv,
2898*4882a593Smuzhiyun u32 bandwidth)
2899*4882a593Smuzhiyun {
2900*4882a593Smuzhiyun u8 data[2] = { 0x09, 0x54 };
2901*4882a593Smuzhiyun u8 data24m[3] = {0xDC, 0x6C, 0x00};
2902*4882a593Smuzhiyun
2903*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
2904*4882a593Smuzhiyun cxd2841er_set_ts_clock_mode(priv, SYS_DVBT);
2905*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
2906*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
2907*4882a593Smuzhiyun /* Set demod mode */
2908*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x01);
2909*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
2910*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
2911*4882a593Smuzhiyun /* Enable demod clock */
2912*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01);
2913*4882a593Smuzhiyun /* Disable RF level monitor */
2914*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
2915*4882a593Smuzhiyun /* Enable ADC clock */
2916*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
2917*4882a593Smuzhiyun /* Enable ADC 1 */
2918*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a);
2919*4882a593Smuzhiyun /* Enable ADC 2 & 3 */
2920*4882a593Smuzhiyun if (priv->xtal == SONY_XTAL_41000) {
2921*4882a593Smuzhiyun data[0] = 0x0A;
2922*4882a593Smuzhiyun data[1] = 0xD4;
2923*4882a593Smuzhiyun }
2924*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2);
2925*4882a593Smuzhiyun /* Enable ADC 4 */
2926*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
2927*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
2928*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2929*4882a593Smuzhiyun /* IFAGC gain settings */
2930*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x0c, 0x1f);
2931*4882a593Smuzhiyun /* Set SLV-T Bank : 0x11 */
2932*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11);
2933*4882a593Smuzhiyun /* BBAGC TARGET level setting */
2934*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50);
2935*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
2936*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2937*4882a593Smuzhiyun /* ASCOT setting */
2938*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
2939*4882a593Smuzhiyun ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
2940*4882a593Smuzhiyun /* Set SLV-T Bank : 0x18 */
2941*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x18);
2942*4882a593Smuzhiyun /* Pre-RS BER monitor setting */
2943*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x36, 0x40, 0x07);
2944*4882a593Smuzhiyun /* FEC Auto Recovery setting */
2945*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01);
2946*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x01, 0x01);
2947*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
2948*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
2949*4882a593Smuzhiyun /* TSIF setting */
2950*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01);
2951*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01);
2952*4882a593Smuzhiyun
2953*4882a593Smuzhiyun if (priv->xtal == SONY_XTAL_24000) {
2954*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
2955*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
2956*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xBF, 0x60);
2957*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x18);
2958*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x24, data24m, 3);
2959*4882a593Smuzhiyun }
2960*4882a593Smuzhiyun
2961*4882a593Smuzhiyun cxd2841er_sleep_tc_to_active_t_band(priv, bandwidth);
2962*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
2963*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
2964*4882a593Smuzhiyun /* Disable HiZ Setting 1 */
2965*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28);
2966*4882a593Smuzhiyun /* Disable HiZ Setting 2 */
2967*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00);
2968*4882a593Smuzhiyun priv->state = STATE_ACTIVE_TC;
2969*4882a593Smuzhiyun return 0;
2970*4882a593Smuzhiyun }
2971*4882a593Smuzhiyun
cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv * priv,u32 bandwidth)2972*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_t2(struct cxd2841er_priv *priv,
2973*4882a593Smuzhiyun u32 bandwidth)
2974*4882a593Smuzhiyun {
2975*4882a593Smuzhiyun u8 data[MAX_WRITE_REGSIZE];
2976*4882a593Smuzhiyun
2977*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
2978*4882a593Smuzhiyun cxd2841er_set_ts_clock_mode(priv, SYS_DVBT2);
2979*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
2980*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
2981*4882a593Smuzhiyun /* Set demod mode */
2982*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x02);
2983*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
2984*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
2985*4882a593Smuzhiyun /* Enable demod clock */
2986*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01);
2987*4882a593Smuzhiyun /* Disable RF level monitor */
2988*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x00);
2989*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
2990*4882a593Smuzhiyun /* Enable ADC clock */
2991*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
2992*4882a593Smuzhiyun /* Enable ADC 1 */
2993*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a);
2994*4882a593Smuzhiyun
2995*4882a593Smuzhiyun if (priv->xtal == SONY_XTAL_41000) {
2996*4882a593Smuzhiyun data[0] = 0x0A;
2997*4882a593Smuzhiyun data[1] = 0xD4;
2998*4882a593Smuzhiyun } else {
2999*4882a593Smuzhiyun data[0] = 0x09;
3000*4882a593Smuzhiyun data[1] = 0x54;
3001*4882a593Smuzhiyun }
3002*4882a593Smuzhiyun
3003*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2);
3004*4882a593Smuzhiyun /* Enable ADC 4 */
3005*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
3006*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
3007*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
3008*4882a593Smuzhiyun /* IFAGC gain settings */
3009*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x0c, 0x1f);
3010*4882a593Smuzhiyun /* Set SLV-T Bank : 0x11 */
3011*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11);
3012*4882a593Smuzhiyun /* BBAGC TARGET level setting */
3013*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x50);
3014*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
3015*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
3016*4882a593Smuzhiyun /* ASCOT setting */
3017*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
3018*4882a593Smuzhiyun ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
3019*4882a593Smuzhiyun /* Set SLV-T Bank : 0x20 */
3020*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
3021*4882a593Smuzhiyun /* Acquisition optimization setting */
3022*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x8b, 0x3c);
3023*4882a593Smuzhiyun /* Set SLV-T Bank : 0x2b */
3024*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b);
3025*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x76, 0x20, 0x70);
3026*4882a593Smuzhiyun /* Set SLV-T Bank : 0x23 */
3027*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x23);
3028*4882a593Smuzhiyun /* L1 Control setting */
3029*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xE6, 0x00, 0x03);
3030*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
3031*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
3032*4882a593Smuzhiyun /* TSIF setting */
3033*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01);
3034*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01);
3035*4882a593Smuzhiyun /* DVB-T2 initial setting */
3036*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x13);
3037*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x83, 0x10);
3038*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x86, 0x34);
3039*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x9e, 0x09, 0x0f);
3040*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x9f, 0xd8);
3041*4882a593Smuzhiyun /* Set SLV-T Bank : 0x2a */
3042*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2a);
3043*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x38, 0x04, 0x0f);
3044*4882a593Smuzhiyun /* Set SLV-T Bank : 0x2b */
3045*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2b);
3046*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x11, 0x20, 0x3f);
3047*4882a593Smuzhiyun
3048*4882a593Smuzhiyun /* 24MHz Xtal setting */
3049*4882a593Smuzhiyun if (priv->xtal == SONY_XTAL_24000) {
3050*4882a593Smuzhiyun /* Set SLV-T Bank : 0x11 */
3051*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11);
3052*4882a593Smuzhiyun data[0] = 0xEB;
3053*4882a593Smuzhiyun data[1] = 0x03;
3054*4882a593Smuzhiyun data[2] = 0x3B;
3055*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x33, data, 3);
3056*4882a593Smuzhiyun
3057*4882a593Smuzhiyun /* Set SLV-T Bank : 0x20 */
3058*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x20);
3059*4882a593Smuzhiyun data[0] = 0x5E;
3060*4882a593Smuzhiyun data[1] = 0x5E;
3061*4882a593Smuzhiyun data[2] = 0x47;
3062*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x95, data, 3);
3063*4882a593Smuzhiyun
3064*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x99, 0x18);
3065*4882a593Smuzhiyun
3066*4882a593Smuzhiyun data[0] = 0x3F;
3067*4882a593Smuzhiyun data[1] = 0xFF;
3068*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xD9, data, 2);
3069*4882a593Smuzhiyun
3070*4882a593Smuzhiyun /* Set SLV-T Bank : 0x24 */
3071*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x24);
3072*4882a593Smuzhiyun data[0] = 0x0B;
3073*4882a593Smuzhiyun data[1] = 0x72;
3074*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x34, data, 2);
3075*4882a593Smuzhiyun
3076*4882a593Smuzhiyun data[0] = 0x93;
3077*4882a593Smuzhiyun data[1] = 0xF3;
3078*4882a593Smuzhiyun data[2] = 0x00;
3079*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xD2, data, 3);
3080*4882a593Smuzhiyun
3081*4882a593Smuzhiyun data[0] = 0x05;
3082*4882a593Smuzhiyun data[1] = 0xB8;
3083*4882a593Smuzhiyun data[2] = 0xD8;
3084*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xDD, data, 3);
3085*4882a593Smuzhiyun
3086*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xE0, 0x00);
3087*4882a593Smuzhiyun
3088*4882a593Smuzhiyun /* Set SLV-T Bank : 0x25 */
3089*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x25);
3090*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xED, 0x60);
3091*4882a593Smuzhiyun
3092*4882a593Smuzhiyun /* Set SLV-T Bank : 0x27 */
3093*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x27);
3094*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xFA, 0x34);
3095*4882a593Smuzhiyun
3096*4882a593Smuzhiyun /* Set SLV-T Bank : 0x2B */
3097*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2B);
3098*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x4B, 0x2F);
3099*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x9E, 0x0E);
3100*4882a593Smuzhiyun
3101*4882a593Smuzhiyun /* Set SLV-T Bank : 0x2D */
3102*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x2D);
3103*4882a593Smuzhiyun data[0] = 0x89;
3104*4882a593Smuzhiyun data[1] = 0x89;
3105*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x24, data, 2);
3106*4882a593Smuzhiyun
3107*4882a593Smuzhiyun /* Set SLV-T Bank : 0x5E */
3108*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x5E);
3109*4882a593Smuzhiyun data[0] = 0x24;
3110*4882a593Smuzhiyun data[1] = 0x95;
3111*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x8C, data, 2);
3112*4882a593Smuzhiyun }
3113*4882a593Smuzhiyun
3114*4882a593Smuzhiyun cxd2841er_sleep_tc_to_active_t2_band(priv, bandwidth);
3115*4882a593Smuzhiyun
3116*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
3117*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
3118*4882a593Smuzhiyun /* Disable HiZ Setting 1 */
3119*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28);
3120*4882a593Smuzhiyun /* Disable HiZ Setting 2 */
3121*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00);
3122*4882a593Smuzhiyun priv->state = STATE_ACTIVE_TC;
3123*4882a593Smuzhiyun return 0;
3124*4882a593Smuzhiyun }
3125*4882a593Smuzhiyun
3126*4882a593Smuzhiyun /* ISDB-Tb part */
cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv * priv,u32 bandwidth)3127*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_i(struct cxd2841er_priv *priv,
3128*4882a593Smuzhiyun u32 bandwidth)
3129*4882a593Smuzhiyun {
3130*4882a593Smuzhiyun u8 data[2] = { 0x09, 0x54 };
3131*4882a593Smuzhiyun u8 data24m[2] = {0x60, 0x00};
3132*4882a593Smuzhiyun u8 data24m2[3] = {0xB7, 0x1B, 0x00};
3133*4882a593Smuzhiyun
3134*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
3135*4882a593Smuzhiyun cxd2841er_set_ts_clock_mode(priv, SYS_DVBT);
3136*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
3137*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
3138*4882a593Smuzhiyun /* Set demod mode */
3139*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x06);
3140*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
3141*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
3142*4882a593Smuzhiyun /* Enable demod clock */
3143*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01);
3144*4882a593Smuzhiyun /* Enable RF level monitor */
3145*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x01);
3146*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x01);
3147*4882a593Smuzhiyun /* Enable ADC clock */
3148*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
3149*4882a593Smuzhiyun /* Enable ADC 1 */
3150*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a);
3151*4882a593Smuzhiyun /* xtal freq 20.5MHz or 24M */
3152*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2);
3153*4882a593Smuzhiyun /* Enable ADC 4 */
3154*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
3155*4882a593Smuzhiyun /* ASCOT setting */
3156*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
3157*4882a593Smuzhiyun ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
3158*4882a593Smuzhiyun /* FEC Auto Recovery setting */
3159*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x30, 0x01, 0x01);
3160*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x31, 0x00, 0x01);
3161*4882a593Smuzhiyun /* ISDB-T initial setting */
3162*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
3163*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
3164*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x00, 0x01);
3165*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x00, 0x01);
3166*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
3167*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
3168*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x69, 0x04, 0x07);
3169*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x6B, 0x03, 0x07);
3170*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x9D, 0x50, 0xFF);
3171*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xD3, 0x06, 0x1F);
3172*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xED, 0x00, 0x01);
3173*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xE2, 0xCE, 0x80);
3174*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xF2, 0x13, 0x10);
3175*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xDE, 0x2E, 0x3F);
3176*4882a593Smuzhiyun /* Set SLV-T Bank : 0x15 */
3177*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x15);
3178*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xDE, 0x02, 0x03);
3179*4882a593Smuzhiyun /* Set SLV-T Bank : 0x1E */
3180*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x1E);
3181*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x73, 0x68, 0xFF);
3182*4882a593Smuzhiyun /* Set SLV-T Bank : 0x63 */
3183*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x63);
3184*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0x81, 0x00, 0x01);
3185*4882a593Smuzhiyun
3186*4882a593Smuzhiyun /* for xtal 24MHz */
3187*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
3188*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
3189*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xBF, data24m, 2);
3190*4882a593Smuzhiyun /* Set SLV-T Bank : 0x60 */
3191*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x60);
3192*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0xA8, data24m2, 3);
3193*4882a593Smuzhiyun
3194*4882a593Smuzhiyun cxd2841er_sleep_tc_to_active_i_band(priv, bandwidth);
3195*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
3196*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
3197*4882a593Smuzhiyun /* Disable HiZ Setting 1 */
3198*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28);
3199*4882a593Smuzhiyun /* Disable HiZ Setting 2 */
3200*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00);
3201*4882a593Smuzhiyun priv->state = STATE_ACTIVE_TC;
3202*4882a593Smuzhiyun return 0;
3203*4882a593Smuzhiyun }
3204*4882a593Smuzhiyun
cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv * priv,u32 bandwidth)3205*4882a593Smuzhiyun static int cxd2841er_sleep_tc_to_active_c(struct cxd2841er_priv *priv,
3206*4882a593Smuzhiyun u32 bandwidth)
3207*4882a593Smuzhiyun {
3208*4882a593Smuzhiyun u8 data[2] = { 0x09, 0x54 };
3209*4882a593Smuzhiyun
3210*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
3211*4882a593Smuzhiyun cxd2841er_set_ts_clock_mode(priv, SYS_DVBC_ANNEX_A);
3212*4882a593Smuzhiyun /* Set SLV-X Bank : 0x00 */
3213*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x00, 0x00);
3214*4882a593Smuzhiyun /* Set demod mode */
3215*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x17, 0x04);
3216*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
3217*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
3218*4882a593Smuzhiyun /* Enable demod clock */
3219*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2c, 0x01);
3220*4882a593Smuzhiyun /* Disable RF level monitor */
3221*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x59, 0x00);
3222*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x2f, 0x00);
3223*4882a593Smuzhiyun /* Enable ADC clock */
3224*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x30, 0x00);
3225*4882a593Smuzhiyun /* Enable ADC 1 */
3226*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x41, 0x1a);
3227*4882a593Smuzhiyun /* xtal freq 20.5MHz */
3228*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x43, data, 2);
3229*4882a593Smuzhiyun /* Enable ADC 4 */
3230*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVX, 0x18, 0x00);
3231*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
3232*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
3233*4882a593Smuzhiyun /* IFAGC gain settings */
3234*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xd2, 0x09, 0x1f);
3235*4882a593Smuzhiyun /* Set SLV-T Bank : 0x11 */
3236*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x11);
3237*4882a593Smuzhiyun /* BBAGC TARGET level setting */
3238*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x6a, 0x48);
3239*4882a593Smuzhiyun /* Set SLV-T Bank : 0x10 */
3240*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
3241*4882a593Smuzhiyun /* ASCOT setting */
3242*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xa5,
3243*4882a593Smuzhiyun ((priv->flags & CXD2841ER_ASCOT) ? 0x01 : 0x00), 0x01);
3244*4882a593Smuzhiyun /* Set SLV-T Bank : 0x40 */
3245*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x40);
3246*4882a593Smuzhiyun /* Demod setting */
3247*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc3, 0x00, 0x04);
3248*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
3249*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
3250*4882a593Smuzhiyun /* TSIF setting */
3251*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xce, 0x01, 0x01);
3252*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcf, 0x01, 0x01);
3253*4882a593Smuzhiyun
3254*4882a593Smuzhiyun cxd2841er_sleep_tc_to_active_c_band(priv, bandwidth);
3255*4882a593Smuzhiyun /* Set SLV-T Bank : 0x00 */
3256*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
3257*4882a593Smuzhiyun /* Disable HiZ Setting 1 */
3258*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x80, 0x28);
3259*4882a593Smuzhiyun /* Disable HiZ Setting 2 */
3260*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x81, 0x00);
3261*4882a593Smuzhiyun priv->state = STATE_ACTIVE_TC;
3262*4882a593Smuzhiyun return 0;
3263*4882a593Smuzhiyun }
3264*4882a593Smuzhiyun
cxd2841er_get_frontend(struct dvb_frontend * fe,struct dtv_frontend_properties * p)3265*4882a593Smuzhiyun static int cxd2841er_get_frontend(struct dvb_frontend *fe,
3266*4882a593Smuzhiyun struct dtv_frontend_properties *p)
3267*4882a593Smuzhiyun {
3268*4882a593Smuzhiyun enum fe_status status = 0;
3269*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3270*4882a593Smuzhiyun
3271*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
3272*4882a593Smuzhiyun if (priv->state == STATE_ACTIVE_S)
3273*4882a593Smuzhiyun cxd2841er_read_status_s(fe, &status);
3274*4882a593Smuzhiyun else if (priv->state == STATE_ACTIVE_TC)
3275*4882a593Smuzhiyun cxd2841er_read_status_tc(fe, &status);
3276*4882a593Smuzhiyun
3277*4882a593Smuzhiyun if (priv->state == STATE_ACTIVE_TC || priv->state == STATE_ACTIVE_S)
3278*4882a593Smuzhiyun cxd2841er_read_signal_strength(fe);
3279*4882a593Smuzhiyun else
3280*4882a593Smuzhiyun p->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3281*4882a593Smuzhiyun
3282*4882a593Smuzhiyun if (status & FE_HAS_LOCK) {
3283*4882a593Smuzhiyun if (priv->stats_time &&
3284*4882a593Smuzhiyun (!time_after(jiffies, priv->stats_time)))
3285*4882a593Smuzhiyun return 0;
3286*4882a593Smuzhiyun
3287*4882a593Smuzhiyun /* Prevent retrieving stats faster than once per second */
3288*4882a593Smuzhiyun priv->stats_time = jiffies + msecs_to_jiffies(1000);
3289*4882a593Smuzhiyun
3290*4882a593Smuzhiyun cxd2841er_read_snr(fe);
3291*4882a593Smuzhiyun cxd2841er_read_ucblocks(fe);
3292*4882a593Smuzhiyun cxd2841er_read_ber(fe);
3293*4882a593Smuzhiyun } else {
3294*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3295*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3296*4882a593Smuzhiyun p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3297*4882a593Smuzhiyun p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3298*4882a593Smuzhiyun }
3299*4882a593Smuzhiyun return 0;
3300*4882a593Smuzhiyun }
3301*4882a593Smuzhiyun
cxd2841er_set_frontend_s(struct dvb_frontend * fe)3302*4882a593Smuzhiyun static int cxd2841er_set_frontend_s(struct dvb_frontend *fe)
3303*4882a593Smuzhiyun {
3304*4882a593Smuzhiyun int ret = 0, i, timeout, carr_offset;
3305*4882a593Smuzhiyun enum fe_status status;
3306*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3307*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
3308*4882a593Smuzhiyun u32 symbol_rate = p->symbol_rate/1000;
3309*4882a593Smuzhiyun
3310*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): %s frequency=%d symbol_rate=%d xtal=%d\n",
3311*4882a593Smuzhiyun __func__,
3312*4882a593Smuzhiyun (p->delivery_system == SYS_DVBS ? "DVB-S" : "DVB-S2"),
3313*4882a593Smuzhiyun p->frequency, symbol_rate, priv->xtal);
3314*4882a593Smuzhiyun
3315*4882a593Smuzhiyun if (priv->flags & CXD2841ER_EARLY_TUNE)
3316*4882a593Smuzhiyun cxd2841er_tuner_set(fe);
3317*4882a593Smuzhiyun
3318*4882a593Smuzhiyun switch (priv->state) {
3319*4882a593Smuzhiyun case STATE_SLEEP_S:
3320*4882a593Smuzhiyun ret = cxd2841er_sleep_s_to_active_s(
3321*4882a593Smuzhiyun priv, p->delivery_system, symbol_rate);
3322*4882a593Smuzhiyun break;
3323*4882a593Smuzhiyun case STATE_ACTIVE_S:
3324*4882a593Smuzhiyun ret = cxd2841er_retune_active(priv, p);
3325*4882a593Smuzhiyun break;
3326*4882a593Smuzhiyun default:
3327*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
3328*4882a593Smuzhiyun __func__, priv->state);
3329*4882a593Smuzhiyun ret = -EINVAL;
3330*4882a593Smuzhiyun goto done;
3331*4882a593Smuzhiyun }
3332*4882a593Smuzhiyun if (ret) {
3333*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): tune failed\n", __func__);
3334*4882a593Smuzhiyun goto done;
3335*4882a593Smuzhiyun }
3336*4882a593Smuzhiyun
3337*4882a593Smuzhiyun if (!(priv->flags & CXD2841ER_EARLY_TUNE))
3338*4882a593Smuzhiyun cxd2841er_tuner_set(fe);
3339*4882a593Smuzhiyun
3340*4882a593Smuzhiyun cxd2841er_tune_done(priv);
3341*4882a593Smuzhiyun timeout = ((3000000 + (symbol_rate - 1)) / symbol_rate) + 150;
3342*4882a593Smuzhiyun
3343*4882a593Smuzhiyun i = 0;
3344*4882a593Smuzhiyun do {
3345*4882a593Smuzhiyun usleep_range(CXD2841ER_DVBS_POLLING_INVL*1000,
3346*4882a593Smuzhiyun (CXD2841ER_DVBS_POLLING_INVL + 2) * 1000);
3347*4882a593Smuzhiyun cxd2841er_read_status_s(fe, &status);
3348*4882a593Smuzhiyun if (status & FE_HAS_LOCK)
3349*4882a593Smuzhiyun break;
3350*4882a593Smuzhiyun i++;
3351*4882a593Smuzhiyun } while (i < timeout / CXD2841ER_DVBS_POLLING_INVL);
3352*4882a593Smuzhiyun
3353*4882a593Smuzhiyun if (status & FE_HAS_LOCK) {
3354*4882a593Smuzhiyun if (cxd2841er_get_carrier_offset_s_s2(
3355*4882a593Smuzhiyun priv, &carr_offset)) {
3356*4882a593Smuzhiyun ret = -EINVAL;
3357*4882a593Smuzhiyun goto done;
3358*4882a593Smuzhiyun }
3359*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): carrier_offset=%d\n",
3360*4882a593Smuzhiyun __func__, carr_offset);
3361*4882a593Smuzhiyun }
3362*4882a593Smuzhiyun done:
3363*4882a593Smuzhiyun /* Reset stats */
3364*4882a593Smuzhiyun p->strength.stat[0].scale = FE_SCALE_RELATIVE;
3365*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3366*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3367*4882a593Smuzhiyun p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3368*4882a593Smuzhiyun p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3369*4882a593Smuzhiyun
3370*4882a593Smuzhiyun /* Reset the wait for jiffies logic */
3371*4882a593Smuzhiyun priv->stats_time = 0;
3372*4882a593Smuzhiyun
3373*4882a593Smuzhiyun return ret;
3374*4882a593Smuzhiyun }
3375*4882a593Smuzhiyun
cxd2841er_set_frontend_tc(struct dvb_frontend * fe)3376*4882a593Smuzhiyun static int cxd2841er_set_frontend_tc(struct dvb_frontend *fe)
3377*4882a593Smuzhiyun {
3378*4882a593Smuzhiyun int ret = 0, timeout;
3379*4882a593Smuzhiyun enum fe_status status;
3380*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3381*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
3382*4882a593Smuzhiyun
3383*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s() delivery_system=%d bandwidth_hz=%d\n",
3384*4882a593Smuzhiyun __func__, p->delivery_system, p->bandwidth_hz);
3385*4882a593Smuzhiyun
3386*4882a593Smuzhiyun if (priv->flags & CXD2841ER_EARLY_TUNE)
3387*4882a593Smuzhiyun cxd2841er_tuner_set(fe);
3388*4882a593Smuzhiyun
3389*4882a593Smuzhiyun /* deconfigure/put demod to sleep on delsys switch if active */
3390*4882a593Smuzhiyun if (priv->state == STATE_ACTIVE_TC &&
3391*4882a593Smuzhiyun priv->system != p->delivery_system) {
3392*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): old_delsys=%d, new_delsys=%d -> sleep\n",
3393*4882a593Smuzhiyun __func__, priv->system, p->delivery_system);
3394*4882a593Smuzhiyun cxd2841er_sleep_tc(fe);
3395*4882a593Smuzhiyun }
3396*4882a593Smuzhiyun
3397*4882a593Smuzhiyun if (p->delivery_system == SYS_DVBT) {
3398*4882a593Smuzhiyun priv->system = SYS_DVBT;
3399*4882a593Smuzhiyun switch (priv->state) {
3400*4882a593Smuzhiyun case STATE_SLEEP_TC:
3401*4882a593Smuzhiyun ret = cxd2841er_sleep_tc_to_active_t(
3402*4882a593Smuzhiyun priv, p->bandwidth_hz);
3403*4882a593Smuzhiyun break;
3404*4882a593Smuzhiyun case STATE_ACTIVE_TC:
3405*4882a593Smuzhiyun ret = cxd2841er_retune_active(priv, p);
3406*4882a593Smuzhiyun break;
3407*4882a593Smuzhiyun default:
3408*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
3409*4882a593Smuzhiyun __func__, priv->state);
3410*4882a593Smuzhiyun ret = -EINVAL;
3411*4882a593Smuzhiyun }
3412*4882a593Smuzhiyun } else if (p->delivery_system == SYS_DVBT2) {
3413*4882a593Smuzhiyun priv->system = SYS_DVBT2;
3414*4882a593Smuzhiyun cxd2841er_dvbt2_set_plp_config(priv,
3415*4882a593Smuzhiyun (int)(p->stream_id > 255), p->stream_id);
3416*4882a593Smuzhiyun cxd2841er_dvbt2_set_profile(priv, DVBT2_PROFILE_BASE);
3417*4882a593Smuzhiyun switch (priv->state) {
3418*4882a593Smuzhiyun case STATE_SLEEP_TC:
3419*4882a593Smuzhiyun ret = cxd2841er_sleep_tc_to_active_t2(priv,
3420*4882a593Smuzhiyun p->bandwidth_hz);
3421*4882a593Smuzhiyun break;
3422*4882a593Smuzhiyun case STATE_ACTIVE_TC:
3423*4882a593Smuzhiyun ret = cxd2841er_retune_active(priv, p);
3424*4882a593Smuzhiyun break;
3425*4882a593Smuzhiyun default:
3426*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
3427*4882a593Smuzhiyun __func__, priv->state);
3428*4882a593Smuzhiyun ret = -EINVAL;
3429*4882a593Smuzhiyun }
3430*4882a593Smuzhiyun } else if (p->delivery_system == SYS_ISDBT) {
3431*4882a593Smuzhiyun priv->system = SYS_ISDBT;
3432*4882a593Smuzhiyun switch (priv->state) {
3433*4882a593Smuzhiyun case STATE_SLEEP_TC:
3434*4882a593Smuzhiyun ret = cxd2841er_sleep_tc_to_active_i(
3435*4882a593Smuzhiyun priv, p->bandwidth_hz);
3436*4882a593Smuzhiyun break;
3437*4882a593Smuzhiyun case STATE_ACTIVE_TC:
3438*4882a593Smuzhiyun ret = cxd2841er_retune_active(priv, p);
3439*4882a593Smuzhiyun break;
3440*4882a593Smuzhiyun default:
3441*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
3442*4882a593Smuzhiyun __func__, priv->state);
3443*4882a593Smuzhiyun ret = -EINVAL;
3444*4882a593Smuzhiyun }
3445*4882a593Smuzhiyun } else if (p->delivery_system == SYS_DVBC_ANNEX_A ||
3446*4882a593Smuzhiyun p->delivery_system == SYS_DVBC_ANNEX_C) {
3447*4882a593Smuzhiyun priv->system = SYS_DVBC_ANNEX_A;
3448*4882a593Smuzhiyun /* correct bandwidth */
3449*4882a593Smuzhiyun if (p->bandwidth_hz != 6000000 &&
3450*4882a593Smuzhiyun p->bandwidth_hz != 7000000 &&
3451*4882a593Smuzhiyun p->bandwidth_hz != 8000000) {
3452*4882a593Smuzhiyun p->bandwidth_hz = 8000000;
3453*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): forcing bandwidth to %d\n",
3454*4882a593Smuzhiyun __func__, p->bandwidth_hz);
3455*4882a593Smuzhiyun }
3456*4882a593Smuzhiyun
3457*4882a593Smuzhiyun switch (priv->state) {
3458*4882a593Smuzhiyun case STATE_SLEEP_TC:
3459*4882a593Smuzhiyun ret = cxd2841er_sleep_tc_to_active_c(
3460*4882a593Smuzhiyun priv, p->bandwidth_hz);
3461*4882a593Smuzhiyun break;
3462*4882a593Smuzhiyun case STATE_ACTIVE_TC:
3463*4882a593Smuzhiyun ret = cxd2841er_retune_active(priv, p);
3464*4882a593Smuzhiyun break;
3465*4882a593Smuzhiyun default:
3466*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): invalid state %d\n",
3467*4882a593Smuzhiyun __func__, priv->state);
3468*4882a593Smuzhiyun ret = -EINVAL;
3469*4882a593Smuzhiyun }
3470*4882a593Smuzhiyun } else {
3471*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
3472*4882a593Smuzhiyun "%s(): invalid delivery system %d\n",
3473*4882a593Smuzhiyun __func__, p->delivery_system);
3474*4882a593Smuzhiyun ret = -EINVAL;
3475*4882a593Smuzhiyun }
3476*4882a593Smuzhiyun if (ret)
3477*4882a593Smuzhiyun goto done;
3478*4882a593Smuzhiyun
3479*4882a593Smuzhiyun if (!(priv->flags & CXD2841ER_EARLY_TUNE))
3480*4882a593Smuzhiyun cxd2841er_tuner_set(fe);
3481*4882a593Smuzhiyun
3482*4882a593Smuzhiyun cxd2841er_tune_done(priv);
3483*4882a593Smuzhiyun
3484*4882a593Smuzhiyun if (priv->flags & CXD2841ER_NO_WAIT_LOCK)
3485*4882a593Smuzhiyun goto done;
3486*4882a593Smuzhiyun
3487*4882a593Smuzhiyun timeout = 2500;
3488*4882a593Smuzhiyun while (timeout > 0) {
3489*4882a593Smuzhiyun ret = cxd2841er_read_status_tc(fe, &status);
3490*4882a593Smuzhiyun if (ret)
3491*4882a593Smuzhiyun goto done;
3492*4882a593Smuzhiyun if (status & FE_HAS_LOCK)
3493*4882a593Smuzhiyun break;
3494*4882a593Smuzhiyun msleep(20);
3495*4882a593Smuzhiyun timeout -= 20;
3496*4882a593Smuzhiyun }
3497*4882a593Smuzhiyun if (timeout < 0)
3498*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
3499*4882a593Smuzhiyun "%s(): LOCK wait timeout\n", __func__);
3500*4882a593Smuzhiyun done:
3501*4882a593Smuzhiyun return ret;
3502*4882a593Smuzhiyun }
3503*4882a593Smuzhiyun
cxd2841er_tune_s(struct dvb_frontend * fe,bool re_tune,unsigned int mode_flags,unsigned int * delay,enum fe_status * status)3504*4882a593Smuzhiyun static int cxd2841er_tune_s(struct dvb_frontend *fe,
3505*4882a593Smuzhiyun bool re_tune,
3506*4882a593Smuzhiyun unsigned int mode_flags,
3507*4882a593Smuzhiyun unsigned int *delay,
3508*4882a593Smuzhiyun enum fe_status *status)
3509*4882a593Smuzhiyun {
3510*4882a593Smuzhiyun int ret, carrier_offset;
3511*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3512*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
3513*4882a593Smuzhiyun
3514*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s() re_tune=%d\n", __func__, re_tune);
3515*4882a593Smuzhiyun if (re_tune) {
3516*4882a593Smuzhiyun ret = cxd2841er_set_frontend_s(fe);
3517*4882a593Smuzhiyun if (ret)
3518*4882a593Smuzhiyun return ret;
3519*4882a593Smuzhiyun cxd2841er_read_status_s(fe, status);
3520*4882a593Smuzhiyun if (*status & FE_HAS_LOCK) {
3521*4882a593Smuzhiyun if (cxd2841er_get_carrier_offset_s_s2(
3522*4882a593Smuzhiyun priv, &carrier_offset))
3523*4882a593Smuzhiyun return -EINVAL;
3524*4882a593Smuzhiyun p->frequency += carrier_offset;
3525*4882a593Smuzhiyun ret = cxd2841er_set_frontend_s(fe);
3526*4882a593Smuzhiyun if (ret)
3527*4882a593Smuzhiyun return ret;
3528*4882a593Smuzhiyun }
3529*4882a593Smuzhiyun }
3530*4882a593Smuzhiyun *delay = HZ / 5;
3531*4882a593Smuzhiyun return cxd2841er_read_status_s(fe, status);
3532*4882a593Smuzhiyun }
3533*4882a593Smuzhiyun
cxd2841er_tune_tc(struct dvb_frontend * fe,bool re_tune,unsigned int mode_flags,unsigned int * delay,enum fe_status * status)3534*4882a593Smuzhiyun static int cxd2841er_tune_tc(struct dvb_frontend *fe,
3535*4882a593Smuzhiyun bool re_tune,
3536*4882a593Smuzhiyun unsigned int mode_flags,
3537*4882a593Smuzhiyun unsigned int *delay,
3538*4882a593Smuzhiyun enum fe_status *status)
3539*4882a593Smuzhiyun {
3540*4882a593Smuzhiyun int ret, carrier_offset;
3541*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3542*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
3543*4882a593Smuzhiyun
3544*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): re_tune %d bandwidth=%d\n", __func__,
3545*4882a593Smuzhiyun re_tune, p->bandwidth_hz);
3546*4882a593Smuzhiyun if (re_tune) {
3547*4882a593Smuzhiyun ret = cxd2841er_set_frontend_tc(fe);
3548*4882a593Smuzhiyun if (ret)
3549*4882a593Smuzhiyun return ret;
3550*4882a593Smuzhiyun cxd2841er_read_status_tc(fe, status);
3551*4882a593Smuzhiyun if (*status & FE_HAS_LOCK) {
3552*4882a593Smuzhiyun switch (priv->system) {
3553*4882a593Smuzhiyun case SYS_ISDBT:
3554*4882a593Smuzhiyun ret = cxd2841er_get_carrier_offset_i(
3555*4882a593Smuzhiyun priv, p->bandwidth_hz,
3556*4882a593Smuzhiyun &carrier_offset);
3557*4882a593Smuzhiyun if (ret)
3558*4882a593Smuzhiyun return ret;
3559*4882a593Smuzhiyun break;
3560*4882a593Smuzhiyun case SYS_DVBT:
3561*4882a593Smuzhiyun ret = cxd2841er_get_carrier_offset_t(
3562*4882a593Smuzhiyun priv, p->bandwidth_hz,
3563*4882a593Smuzhiyun &carrier_offset);
3564*4882a593Smuzhiyun if (ret)
3565*4882a593Smuzhiyun return ret;
3566*4882a593Smuzhiyun break;
3567*4882a593Smuzhiyun case SYS_DVBT2:
3568*4882a593Smuzhiyun ret = cxd2841er_get_carrier_offset_t2(
3569*4882a593Smuzhiyun priv, p->bandwidth_hz,
3570*4882a593Smuzhiyun &carrier_offset);
3571*4882a593Smuzhiyun if (ret)
3572*4882a593Smuzhiyun return ret;
3573*4882a593Smuzhiyun break;
3574*4882a593Smuzhiyun case SYS_DVBC_ANNEX_A:
3575*4882a593Smuzhiyun ret = cxd2841er_get_carrier_offset_c(
3576*4882a593Smuzhiyun priv, &carrier_offset);
3577*4882a593Smuzhiyun if (ret)
3578*4882a593Smuzhiyun return ret;
3579*4882a593Smuzhiyun break;
3580*4882a593Smuzhiyun default:
3581*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
3582*4882a593Smuzhiyun "%s(): invalid delivery system %d\n",
3583*4882a593Smuzhiyun __func__, priv->system);
3584*4882a593Smuzhiyun return -EINVAL;
3585*4882a593Smuzhiyun }
3586*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): carrier offset %d\n",
3587*4882a593Smuzhiyun __func__, carrier_offset);
3588*4882a593Smuzhiyun p->frequency += carrier_offset;
3589*4882a593Smuzhiyun ret = cxd2841er_set_frontend_tc(fe);
3590*4882a593Smuzhiyun if (ret)
3591*4882a593Smuzhiyun return ret;
3592*4882a593Smuzhiyun }
3593*4882a593Smuzhiyun }
3594*4882a593Smuzhiyun *delay = HZ / 5;
3595*4882a593Smuzhiyun return cxd2841er_read_status_tc(fe, status);
3596*4882a593Smuzhiyun }
3597*4882a593Smuzhiyun
cxd2841er_sleep_s(struct dvb_frontend * fe)3598*4882a593Smuzhiyun static int cxd2841er_sleep_s(struct dvb_frontend *fe)
3599*4882a593Smuzhiyun {
3600*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3601*4882a593Smuzhiyun
3602*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
3603*4882a593Smuzhiyun cxd2841er_active_s_to_sleep_s(fe->demodulator_priv);
3604*4882a593Smuzhiyun cxd2841er_sleep_s_to_shutdown(fe->demodulator_priv);
3605*4882a593Smuzhiyun return 0;
3606*4882a593Smuzhiyun }
3607*4882a593Smuzhiyun
cxd2841er_sleep_tc(struct dvb_frontend * fe)3608*4882a593Smuzhiyun static int cxd2841er_sleep_tc(struct dvb_frontend *fe)
3609*4882a593Smuzhiyun {
3610*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3611*4882a593Smuzhiyun
3612*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
3613*4882a593Smuzhiyun
3614*4882a593Smuzhiyun if (priv->state == STATE_ACTIVE_TC) {
3615*4882a593Smuzhiyun switch (priv->system) {
3616*4882a593Smuzhiyun case SYS_DVBT:
3617*4882a593Smuzhiyun cxd2841er_active_t_to_sleep_tc(priv);
3618*4882a593Smuzhiyun break;
3619*4882a593Smuzhiyun case SYS_DVBT2:
3620*4882a593Smuzhiyun cxd2841er_active_t2_to_sleep_tc(priv);
3621*4882a593Smuzhiyun break;
3622*4882a593Smuzhiyun case SYS_ISDBT:
3623*4882a593Smuzhiyun cxd2841er_active_i_to_sleep_tc(priv);
3624*4882a593Smuzhiyun break;
3625*4882a593Smuzhiyun case SYS_DVBC_ANNEX_A:
3626*4882a593Smuzhiyun cxd2841er_active_c_to_sleep_tc(priv);
3627*4882a593Smuzhiyun break;
3628*4882a593Smuzhiyun default:
3629*4882a593Smuzhiyun dev_warn(&priv->i2c->dev,
3630*4882a593Smuzhiyun "%s(): unknown delivery system %d\n",
3631*4882a593Smuzhiyun __func__, priv->system);
3632*4882a593Smuzhiyun }
3633*4882a593Smuzhiyun }
3634*4882a593Smuzhiyun if (priv->state != STATE_SLEEP_TC) {
3635*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid state %d\n",
3636*4882a593Smuzhiyun __func__, priv->state);
3637*4882a593Smuzhiyun return -EINVAL;
3638*4882a593Smuzhiyun }
3639*4882a593Smuzhiyun return 0;
3640*4882a593Smuzhiyun }
3641*4882a593Smuzhiyun
cxd2841er_shutdown_tc(struct dvb_frontend * fe)3642*4882a593Smuzhiyun static int cxd2841er_shutdown_tc(struct dvb_frontend *fe)
3643*4882a593Smuzhiyun {
3644*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3645*4882a593Smuzhiyun
3646*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
3647*4882a593Smuzhiyun
3648*4882a593Smuzhiyun if (!cxd2841er_sleep_tc(fe))
3649*4882a593Smuzhiyun cxd2841er_sleep_tc_to_shutdown(priv);
3650*4882a593Smuzhiyun return 0;
3651*4882a593Smuzhiyun }
3652*4882a593Smuzhiyun
cxd2841er_send_burst(struct dvb_frontend * fe,enum fe_sec_mini_cmd burst)3653*4882a593Smuzhiyun static int cxd2841er_send_burst(struct dvb_frontend *fe,
3654*4882a593Smuzhiyun enum fe_sec_mini_cmd burst)
3655*4882a593Smuzhiyun {
3656*4882a593Smuzhiyun u8 data;
3657*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3658*4882a593Smuzhiyun
3659*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): burst mode %s\n", __func__,
3660*4882a593Smuzhiyun (burst == SEC_MINI_A ? "A" : "B"));
3661*4882a593Smuzhiyun if (priv->state != STATE_SLEEP_S &&
3662*4882a593Smuzhiyun priv->state != STATE_ACTIVE_S) {
3663*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid demod state %d\n",
3664*4882a593Smuzhiyun __func__, priv->state);
3665*4882a593Smuzhiyun return -EINVAL;
3666*4882a593Smuzhiyun }
3667*4882a593Smuzhiyun data = (burst == SEC_MINI_A ? 0 : 1);
3668*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xbb);
3669*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x34, 0x01);
3670*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x35, data);
3671*4882a593Smuzhiyun return 0;
3672*4882a593Smuzhiyun }
3673*4882a593Smuzhiyun
cxd2841er_set_tone(struct dvb_frontend * fe,enum fe_sec_tone_mode tone)3674*4882a593Smuzhiyun static int cxd2841er_set_tone(struct dvb_frontend *fe,
3675*4882a593Smuzhiyun enum fe_sec_tone_mode tone)
3676*4882a593Smuzhiyun {
3677*4882a593Smuzhiyun u8 data;
3678*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3679*4882a593Smuzhiyun
3680*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): tone %s\n", __func__,
3681*4882a593Smuzhiyun (tone == SEC_TONE_ON ? "On" : "Off"));
3682*4882a593Smuzhiyun if (priv->state != STATE_SLEEP_S &&
3683*4882a593Smuzhiyun priv->state != STATE_ACTIVE_S) {
3684*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid demod state %d\n",
3685*4882a593Smuzhiyun __func__, priv->state);
3686*4882a593Smuzhiyun return -EINVAL;
3687*4882a593Smuzhiyun }
3688*4882a593Smuzhiyun data = (tone == SEC_TONE_ON ? 1 : 0);
3689*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xbb);
3690*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x36, data);
3691*4882a593Smuzhiyun return 0;
3692*4882a593Smuzhiyun }
3693*4882a593Smuzhiyun
cxd2841er_send_diseqc_msg(struct dvb_frontend * fe,struct dvb_diseqc_master_cmd * cmd)3694*4882a593Smuzhiyun static int cxd2841er_send_diseqc_msg(struct dvb_frontend *fe,
3695*4882a593Smuzhiyun struct dvb_diseqc_master_cmd *cmd)
3696*4882a593Smuzhiyun {
3697*4882a593Smuzhiyun int i;
3698*4882a593Smuzhiyun u8 data[12];
3699*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3700*4882a593Smuzhiyun
3701*4882a593Smuzhiyun if (priv->state != STATE_SLEEP_S &&
3702*4882a593Smuzhiyun priv->state != STATE_ACTIVE_S) {
3703*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid demod state %d\n",
3704*4882a593Smuzhiyun __func__, priv->state);
3705*4882a593Smuzhiyun return -EINVAL;
3706*4882a593Smuzhiyun }
3707*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
3708*4882a593Smuzhiyun "%s(): cmd->len %d\n", __func__, cmd->msg_len);
3709*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xbb);
3710*4882a593Smuzhiyun /* DiDEqC enable */
3711*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x33, 0x01);
3712*4882a593Smuzhiyun /* cmd1 length & data */
3713*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x3d, cmd->msg_len);
3714*4882a593Smuzhiyun memset(data, 0, sizeof(data));
3715*4882a593Smuzhiyun for (i = 0; i < cmd->msg_len && i < sizeof(data); i++)
3716*4882a593Smuzhiyun data[i] = cmd->msg[i];
3717*4882a593Smuzhiyun cxd2841er_write_regs(priv, I2C_SLVT, 0x3e, data, sizeof(data));
3718*4882a593Smuzhiyun /* repeat count for cmd1 */
3719*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x37, 1);
3720*4882a593Smuzhiyun /* repeat count for cmd2: always 0 */
3721*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x38, 0);
3722*4882a593Smuzhiyun /* start transmit */
3723*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x32, 0x01);
3724*4882a593Smuzhiyun /* wait for 1 sec timeout */
3725*4882a593Smuzhiyun for (i = 0; i < 50; i++) {
3726*4882a593Smuzhiyun cxd2841er_read_reg(priv, I2C_SLVT, 0x10, data);
3727*4882a593Smuzhiyun if (!data[0]) {
3728*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
3729*4882a593Smuzhiyun "%s(): DiSEqC cmd has been sent\n", __func__);
3730*4882a593Smuzhiyun return 0;
3731*4882a593Smuzhiyun }
3732*4882a593Smuzhiyun msleep(20);
3733*4882a593Smuzhiyun }
3734*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev,
3735*4882a593Smuzhiyun "%s(): DiSEqC cmd transmit timeout\n", __func__);
3736*4882a593Smuzhiyun return -ETIMEDOUT;
3737*4882a593Smuzhiyun }
3738*4882a593Smuzhiyun
cxd2841er_release(struct dvb_frontend * fe)3739*4882a593Smuzhiyun static void cxd2841er_release(struct dvb_frontend *fe)
3740*4882a593Smuzhiyun {
3741*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3742*4882a593Smuzhiyun
3743*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
3744*4882a593Smuzhiyun kfree(priv);
3745*4882a593Smuzhiyun }
3746*4882a593Smuzhiyun
cxd2841er_i2c_gate_ctrl(struct dvb_frontend * fe,int enable)3747*4882a593Smuzhiyun static int cxd2841er_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
3748*4882a593Smuzhiyun {
3749*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3750*4882a593Smuzhiyun
3751*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s(): enable=%d\n", __func__, enable);
3752*4882a593Smuzhiyun cxd2841er_set_reg_bits(
3753*4882a593Smuzhiyun priv, I2C_SLVX, 0x8, (enable ? 0x01 : 0x00), 0x01);
3754*4882a593Smuzhiyun return 0;
3755*4882a593Smuzhiyun }
3756*4882a593Smuzhiyun
cxd2841er_get_algo(struct dvb_frontend * fe)3757*4882a593Smuzhiyun static enum dvbfe_algo cxd2841er_get_algo(struct dvb_frontend *fe)
3758*4882a593Smuzhiyun {
3759*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3760*4882a593Smuzhiyun
3761*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
3762*4882a593Smuzhiyun return DVBFE_ALGO_HW;
3763*4882a593Smuzhiyun }
3764*4882a593Smuzhiyun
cxd2841er_init_stats(struct dvb_frontend * fe)3765*4882a593Smuzhiyun static void cxd2841er_init_stats(struct dvb_frontend *fe)
3766*4882a593Smuzhiyun {
3767*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
3768*4882a593Smuzhiyun
3769*4882a593Smuzhiyun p->strength.len = 1;
3770*4882a593Smuzhiyun p->strength.stat[0].scale = FE_SCALE_RELATIVE;
3771*4882a593Smuzhiyun p->cnr.len = 1;
3772*4882a593Smuzhiyun p->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3773*4882a593Smuzhiyun p->block_error.len = 1;
3774*4882a593Smuzhiyun p->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3775*4882a593Smuzhiyun p->post_bit_error.len = 1;
3776*4882a593Smuzhiyun p->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3777*4882a593Smuzhiyun p->post_bit_count.len = 1;
3778*4882a593Smuzhiyun p->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
3779*4882a593Smuzhiyun }
3780*4882a593Smuzhiyun
3781*4882a593Smuzhiyun
cxd2841er_init_s(struct dvb_frontend * fe)3782*4882a593Smuzhiyun static int cxd2841er_init_s(struct dvb_frontend *fe)
3783*4882a593Smuzhiyun {
3784*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3785*4882a593Smuzhiyun
3786*4882a593Smuzhiyun /* sanity. force demod to SHUTDOWN state */
3787*4882a593Smuzhiyun if (priv->state == STATE_SLEEP_S) {
3788*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s() forcing sleep->shutdown\n",
3789*4882a593Smuzhiyun __func__);
3790*4882a593Smuzhiyun cxd2841er_sleep_s_to_shutdown(priv);
3791*4882a593Smuzhiyun } else if (priv->state == STATE_ACTIVE_S) {
3792*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s() forcing active->sleep->shutdown\n",
3793*4882a593Smuzhiyun __func__);
3794*4882a593Smuzhiyun cxd2841er_active_s_to_sleep_s(priv);
3795*4882a593Smuzhiyun cxd2841er_sleep_s_to_shutdown(priv);
3796*4882a593Smuzhiyun }
3797*4882a593Smuzhiyun
3798*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
3799*4882a593Smuzhiyun cxd2841er_shutdown_to_sleep_s(priv);
3800*4882a593Smuzhiyun /* SONY_DEMOD_CONFIG_SAT_IFAGCNEG set to 1 */
3801*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0xa0);
3802*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xb9, 0x01, 0x01);
3803*4882a593Smuzhiyun
3804*4882a593Smuzhiyun cxd2841er_init_stats(fe);
3805*4882a593Smuzhiyun
3806*4882a593Smuzhiyun return 0;
3807*4882a593Smuzhiyun }
3808*4882a593Smuzhiyun
cxd2841er_init_tc(struct dvb_frontend * fe)3809*4882a593Smuzhiyun static int cxd2841er_init_tc(struct dvb_frontend *fe)
3810*4882a593Smuzhiyun {
3811*4882a593Smuzhiyun struct cxd2841er_priv *priv = fe->demodulator_priv;
3812*4882a593Smuzhiyun struct dtv_frontend_properties *p = &fe->dtv_property_cache;
3813*4882a593Smuzhiyun
3814*4882a593Smuzhiyun dev_dbg(&priv->i2c->dev, "%s() bandwidth_hz=%d\n",
3815*4882a593Smuzhiyun __func__, p->bandwidth_hz);
3816*4882a593Smuzhiyun cxd2841er_shutdown_to_sleep_tc(priv);
3817*4882a593Smuzhiyun /* SONY_DEMOD_CONFIG_IFAGCNEG = 1 (0 for NO_AGCNEG */
3818*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x10);
3819*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xcb,
3820*4882a593Smuzhiyun ((priv->flags & CXD2841ER_NO_AGCNEG) ? 0x00 : 0x40), 0x40);
3821*4882a593Smuzhiyun /* SONY_DEMOD_CONFIG_IFAGC_ADC_FS = 0 */
3822*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0xcd, 0x50);
3823*4882a593Smuzhiyun /* SONY_DEMOD_CONFIG_PARALLEL_SEL = 1 */
3824*4882a593Smuzhiyun cxd2841er_write_reg(priv, I2C_SLVT, 0x00, 0x00);
3825*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4,
3826*4882a593Smuzhiyun ((priv->flags & CXD2841ER_TS_SERIAL) ? 0x80 : 0x00), 0x80);
3827*4882a593Smuzhiyun
3828*4882a593Smuzhiyun /* clear TSCFG bits 3+4 */
3829*4882a593Smuzhiyun if (priv->flags & CXD2841ER_TSBITS)
3830*4882a593Smuzhiyun cxd2841er_set_reg_bits(priv, I2C_SLVT, 0xc4, 0x00, 0x18);
3831*4882a593Smuzhiyun
3832*4882a593Smuzhiyun cxd2841er_init_stats(fe);
3833*4882a593Smuzhiyun
3834*4882a593Smuzhiyun return 0;
3835*4882a593Smuzhiyun }
3836*4882a593Smuzhiyun
3837*4882a593Smuzhiyun static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops;
3838*4882a593Smuzhiyun static struct dvb_frontend_ops cxd2841er_t_c_ops;
3839*4882a593Smuzhiyun
cxd2841er_attach(struct cxd2841er_config * cfg,struct i2c_adapter * i2c,u8 system)3840*4882a593Smuzhiyun static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg,
3841*4882a593Smuzhiyun struct i2c_adapter *i2c,
3842*4882a593Smuzhiyun u8 system)
3843*4882a593Smuzhiyun {
3844*4882a593Smuzhiyun u8 chip_id = 0;
3845*4882a593Smuzhiyun const char *type;
3846*4882a593Smuzhiyun const char *name;
3847*4882a593Smuzhiyun struct cxd2841er_priv *priv = NULL;
3848*4882a593Smuzhiyun
3849*4882a593Smuzhiyun /* allocate memory for the internal state */
3850*4882a593Smuzhiyun priv = kzalloc(sizeof(struct cxd2841er_priv), GFP_KERNEL);
3851*4882a593Smuzhiyun if (!priv)
3852*4882a593Smuzhiyun return NULL;
3853*4882a593Smuzhiyun priv->i2c = i2c;
3854*4882a593Smuzhiyun priv->config = cfg;
3855*4882a593Smuzhiyun priv->i2c_addr_slvx = (cfg->i2c_addr + 4) >> 1;
3856*4882a593Smuzhiyun priv->i2c_addr_slvt = (cfg->i2c_addr) >> 1;
3857*4882a593Smuzhiyun priv->xtal = cfg->xtal;
3858*4882a593Smuzhiyun priv->flags = cfg->flags;
3859*4882a593Smuzhiyun priv->frontend.demodulator_priv = priv;
3860*4882a593Smuzhiyun dev_info(&priv->i2c->dev,
3861*4882a593Smuzhiyun "%s(): I2C adapter %p SLVX addr %x SLVT addr %x\n",
3862*4882a593Smuzhiyun __func__, priv->i2c,
3863*4882a593Smuzhiyun priv->i2c_addr_slvx, priv->i2c_addr_slvt);
3864*4882a593Smuzhiyun chip_id = cxd2841er_chip_id(priv);
3865*4882a593Smuzhiyun switch (chip_id) {
3866*4882a593Smuzhiyun case CXD2837ER_CHIP_ID:
3867*4882a593Smuzhiyun snprintf(cxd2841er_t_c_ops.info.name, 128,
3868*4882a593Smuzhiyun "Sony CXD2837ER DVB-T/T2/C demodulator");
3869*4882a593Smuzhiyun name = "CXD2837ER";
3870*4882a593Smuzhiyun type = "C/T/T2";
3871*4882a593Smuzhiyun break;
3872*4882a593Smuzhiyun case CXD2838ER_CHIP_ID:
3873*4882a593Smuzhiyun snprintf(cxd2841er_t_c_ops.info.name, 128,
3874*4882a593Smuzhiyun "Sony CXD2838ER ISDB-T demodulator");
3875*4882a593Smuzhiyun cxd2841er_t_c_ops.delsys[0] = SYS_ISDBT;
3876*4882a593Smuzhiyun cxd2841er_t_c_ops.delsys[1] = SYS_UNDEFINED;
3877*4882a593Smuzhiyun cxd2841er_t_c_ops.delsys[2] = SYS_UNDEFINED;
3878*4882a593Smuzhiyun name = "CXD2838ER";
3879*4882a593Smuzhiyun type = "ISDB-T";
3880*4882a593Smuzhiyun break;
3881*4882a593Smuzhiyun case CXD2841ER_CHIP_ID:
3882*4882a593Smuzhiyun snprintf(cxd2841er_t_c_ops.info.name, 128,
3883*4882a593Smuzhiyun "Sony CXD2841ER DVB-T/T2/C demodulator");
3884*4882a593Smuzhiyun name = "CXD2841ER";
3885*4882a593Smuzhiyun type = "T/T2/C/ISDB-T";
3886*4882a593Smuzhiyun break;
3887*4882a593Smuzhiyun case CXD2843ER_CHIP_ID:
3888*4882a593Smuzhiyun snprintf(cxd2841er_t_c_ops.info.name, 128,
3889*4882a593Smuzhiyun "Sony CXD2843ER DVB-T/T2/C/C2 demodulator");
3890*4882a593Smuzhiyun name = "CXD2843ER";
3891*4882a593Smuzhiyun type = "C/C2/T/T2";
3892*4882a593Smuzhiyun break;
3893*4882a593Smuzhiyun case CXD2854ER_CHIP_ID:
3894*4882a593Smuzhiyun snprintf(cxd2841er_t_c_ops.info.name, 128,
3895*4882a593Smuzhiyun "Sony CXD2854ER DVB-T/T2/C and ISDB-T demodulator");
3896*4882a593Smuzhiyun cxd2841er_t_c_ops.delsys[3] = SYS_ISDBT;
3897*4882a593Smuzhiyun name = "CXD2854ER";
3898*4882a593Smuzhiyun type = "C/C2/T/T2/ISDB-T";
3899*4882a593Smuzhiyun break;
3900*4882a593Smuzhiyun default:
3901*4882a593Smuzhiyun dev_err(&priv->i2c->dev, "%s(): invalid chip ID 0x%02x\n",
3902*4882a593Smuzhiyun __func__, chip_id);
3903*4882a593Smuzhiyun priv->frontend.demodulator_priv = NULL;
3904*4882a593Smuzhiyun kfree(priv);
3905*4882a593Smuzhiyun return NULL;
3906*4882a593Smuzhiyun }
3907*4882a593Smuzhiyun
3908*4882a593Smuzhiyun /* create dvb_frontend */
3909*4882a593Smuzhiyun if (system == SYS_DVBS) {
3910*4882a593Smuzhiyun memcpy(&priv->frontend.ops,
3911*4882a593Smuzhiyun &cxd2841er_dvbs_s2_ops,
3912*4882a593Smuzhiyun sizeof(struct dvb_frontend_ops));
3913*4882a593Smuzhiyun type = "S/S2";
3914*4882a593Smuzhiyun } else {
3915*4882a593Smuzhiyun memcpy(&priv->frontend.ops,
3916*4882a593Smuzhiyun &cxd2841er_t_c_ops,
3917*4882a593Smuzhiyun sizeof(struct dvb_frontend_ops));
3918*4882a593Smuzhiyun }
3919*4882a593Smuzhiyun
3920*4882a593Smuzhiyun dev_info(&priv->i2c->dev,
3921*4882a593Smuzhiyun "%s(): attaching %s DVB-%s frontend\n",
3922*4882a593Smuzhiyun __func__, name, type);
3923*4882a593Smuzhiyun dev_info(&priv->i2c->dev, "%s(): chip ID 0x%02x OK.\n",
3924*4882a593Smuzhiyun __func__, chip_id);
3925*4882a593Smuzhiyun return &priv->frontend;
3926*4882a593Smuzhiyun }
3927*4882a593Smuzhiyun
cxd2841er_attach_s(struct cxd2841er_config * cfg,struct i2c_adapter * i2c)3928*4882a593Smuzhiyun struct dvb_frontend *cxd2841er_attach_s(struct cxd2841er_config *cfg,
3929*4882a593Smuzhiyun struct i2c_adapter *i2c)
3930*4882a593Smuzhiyun {
3931*4882a593Smuzhiyun return cxd2841er_attach(cfg, i2c, SYS_DVBS);
3932*4882a593Smuzhiyun }
3933*4882a593Smuzhiyun EXPORT_SYMBOL(cxd2841er_attach_s);
3934*4882a593Smuzhiyun
cxd2841er_attach_t_c(struct cxd2841er_config * cfg,struct i2c_adapter * i2c)3935*4882a593Smuzhiyun struct dvb_frontend *cxd2841er_attach_t_c(struct cxd2841er_config *cfg,
3936*4882a593Smuzhiyun struct i2c_adapter *i2c)
3937*4882a593Smuzhiyun {
3938*4882a593Smuzhiyun return cxd2841er_attach(cfg, i2c, 0);
3939*4882a593Smuzhiyun }
3940*4882a593Smuzhiyun EXPORT_SYMBOL(cxd2841er_attach_t_c);
3941*4882a593Smuzhiyun
3942*4882a593Smuzhiyun static const struct dvb_frontend_ops cxd2841er_dvbs_s2_ops = {
3943*4882a593Smuzhiyun .delsys = { SYS_DVBS, SYS_DVBS2 },
3944*4882a593Smuzhiyun .info = {
3945*4882a593Smuzhiyun .name = "Sony CXD2841ER DVB-S/S2 demodulator",
3946*4882a593Smuzhiyun .frequency_min_hz = 500 * MHz,
3947*4882a593Smuzhiyun .frequency_max_hz = 2500 * MHz,
3948*4882a593Smuzhiyun .symbol_rate_min = 1000000,
3949*4882a593Smuzhiyun .symbol_rate_max = 45000000,
3950*4882a593Smuzhiyun .symbol_rate_tolerance = 500,
3951*4882a593Smuzhiyun .caps = FE_CAN_INVERSION_AUTO |
3952*4882a593Smuzhiyun FE_CAN_FEC_AUTO |
3953*4882a593Smuzhiyun FE_CAN_QPSK,
3954*4882a593Smuzhiyun },
3955*4882a593Smuzhiyun .init = cxd2841er_init_s,
3956*4882a593Smuzhiyun .sleep = cxd2841er_sleep_s,
3957*4882a593Smuzhiyun .release = cxd2841er_release,
3958*4882a593Smuzhiyun .set_frontend = cxd2841er_set_frontend_s,
3959*4882a593Smuzhiyun .get_frontend = cxd2841er_get_frontend,
3960*4882a593Smuzhiyun .read_status = cxd2841er_read_status_s,
3961*4882a593Smuzhiyun .i2c_gate_ctrl = cxd2841er_i2c_gate_ctrl,
3962*4882a593Smuzhiyun .get_frontend_algo = cxd2841er_get_algo,
3963*4882a593Smuzhiyun .set_tone = cxd2841er_set_tone,
3964*4882a593Smuzhiyun .diseqc_send_burst = cxd2841er_send_burst,
3965*4882a593Smuzhiyun .diseqc_send_master_cmd = cxd2841er_send_diseqc_msg,
3966*4882a593Smuzhiyun .tune = cxd2841er_tune_s
3967*4882a593Smuzhiyun };
3968*4882a593Smuzhiyun
3969*4882a593Smuzhiyun static struct dvb_frontend_ops cxd2841er_t_c_ops = {
3970*4882a593Smuzhiyun .delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
3971*4882a593Smuzhiyun .info = {
3972*4882a593Smuzhiyun .name = "", /* will set in attach function */
3973*4882a593Smuzhiyun .caps = FE_CAN_FEC_1_2 |
3974*4882a593Smuzhiyun FE_CAN_FEC_2_3 |
3975*4882a593Smuzhiyun FE_CAN_FEC_3_4 |
3976*4882a593Smuzhiyun FE_CAN_FEC_5_6 |
3977*4882a593Smuzhiyun FE_CAN_FEC_7_8 |
3978*4882a593Smuzhiyun FE_CAN_FEC_AUTO |
3979*4882a593Smuzhiyun FE_CAN_QPSK |
3980*4882a593Smuzhiyun FE_CAN_QAM_16 |
3981*4882a593Smuzhiyun FE_CAN_QAM_32 |
3982*4882a593Smuzhiyun FE_CAN_QAM_64 |
3983*4882a593Smuzhiyun FE_CAN_QAM_128 |
3984*4882a593Smuzhiyun FE_CAN_QAM_256 |
3985*4882a593Smuzhiyun FE_CAN_QAM_AUTO |
3986*4882a593Smuzhiyun FE_CAN_TRANSMISSION_MODE_AUTO |
3987*4882a593Smuzhiyun FE_CAN_GUARD_INTERVAL_AUTO |
3988*4882a593Smuzhiyun FE_CAN_HIERARCHY_AUTO |
3989*4882a593Smuzhiyun FE_CAN_MUTE_TS |
3990*4882a593Smuzhiyun FE_CAN_2G_MODULATION,
3991*4882a593Smuzhiyun .frequency_min_hz = 42 * MHz,
3992*4882a593Smuzhiyun .frequency_max_hz = 1002 * MHz,
3993*4882a593Smuzhiyun .symbol_rate_min = 870000,
3994*4882a593Smuzhiyun .symbol_rate_max = 11700000
3995*4882a593Smuzhiyun },
3996*4882a593Smuzhiyun .init = cxd2841er_init_tc,
3997*4882a593Smuzhiyun .sleep = cxd2841er_shutdown_tc,
3998*4882a593Smuzhiyun .release = cxd2841er_release,
3999*4882a593Smuzhiyun .set_frontend = cxd2841er_set_frontend_tc,
4000*4882a593Smuzhiyun .get_frontend = cxd2841er_get_frontend,
4001*4882a593Smuzhiyun .read_status = cxd2841er_read_status_tc,
4002*4882a593Smuzhiyun .tune = cxd2841er_tune_tc,
4003*4882a593Smuzhiyun .i2c_gate_ctrl = cxd2841er_i2c_gate_ctrl,
4004*4882a593Smuzhiyun .get_frontend_algo = cxd2841er_get_algo
4005*4882a593Smuzhiyun };
4006*4882a593Smuzhiyun
4007*4882a593Smuzhiyun MODULE_DESCRIPTION("Sony CXD2837/38/41/43/54ER DVB-C/C2/T/T2/S/S2 demodulator driver");
4008*4882a593Smuzhiyun MODULE_AUTHOR("Sergey Kozlov <serjk@netup.ru>, Abylay Ospan <aospan@netup.ru>");
4009*4882a593Smuzhiyun MODULE_LICENSE("GPL");
4010