Commit | Line | Data |
---|---|---|
c942fddf | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2dc1ed4e AO |
2 | /* |
3 | * helene.c | |
4 | * | |
5 | * Sony HELENE DVB-S/S2 DVB-T/T2 DVB-C/C2 ISDB-T/S tuner driver (CXD2858ER) | |
6 | * | |
7 | * Copyright 2012 Sony Corporation | |
8 | * Copyright (C) 2014 NetUP Inc. | |
9 | * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru> | |
2dc1ed4e AO |
10 | */ |
11 | ||
12 | #include <linux/slab.h> | |
13 | #include <linux/module.h> | |
14 | #include <linux/dvb/frontend.h> | |
15 | #include <linux/types.h> | |
16 | #include "helene.h" | |
fada1935 | 17 | #include <media/dvb_frontend.h> |
2dc1ed4e AO |
18 | |
19 | #define MAX_WRITE_REGSIZE 20 | |
20 | ||
21 | enum helene_state { | |
22 | STATE_UNKNOWN, | |
23 | STATE_SLEEP, | |
24 | STATE_ACTIVE | |
25 | }; | |
26 | ||
27 | struct helene_priv { | |
28 | u32 frequency; | |
29 | u8 i2c_address; | |
30 | struct i2c_adapter *i2c; | |
31 | enum helene_state state; | |
32 | void *set_tuner_data; | |
33 | int (*set_tuner)(void *, int); | |
34 | enum helene_xtal xtal; | |
35 | }; | |
36 | ||
37 | #define TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system) \ | |
38 | (((tv_system) != SONY_HELENE_DTV_DVBC_6) && \ | |
39 | ((tv_system) != SONY_HELENE_DTV_DVBC_8)\ | |
40 | && ((tv_system) != SONY_HELENE_DTV_DVBC2_6) && \ | |
41 | ((tv_system) != SONY_HELENE_DTV_DVBC2_8)) | |
42 | ||
43 | #define HELENE_AUTO 0xff | |
44 | #define HELENE_OFFSET(ofs) ((u8)(ofs) & 0x1F) | |
45 | #define HELENE_BW_6 0x00 | |
46 | #define HELENE_BW_7 0x01 | |
47 | #define HELENE_BW_8 0x02 | |
48 | #define HELENE_BW_1_7 0x03 | |
49 | ||
50 | enum helene_tv_system_t { | |
51 | SONY_HELENE_TV_SYSTEM_UNKNOWN, | |
52 | /* Terrestrial Analog */ | |
53 | SONY_HELENE_ATV_MN_EIAJ, | |
54 | /**< System-M (Japan) (IF: Fp=5.75MHz in default) */ | |
55 | SONY_HELENE_ATV_MN_SAP, | |
56 | /**< System-M (US) (IF: Fp=5.75MHz in default) */ | |
57 | SONY_HELENE_ATV_MN_A2, | |
58 | /**< System-M (Korea) (IF: Fp=5.9MHz in default) */ | |
59 | SONY_HELENE_ATV_BG, | |
60 | /**< System-B/G (IF: Fp=7.3MHz in default) */ | |
61 | SONY_HELENE_ATV_I, | |
62 | /**< System-I (IF: Fp=7.85MHz in default) */ | |
63 | SONY_HELENE_ATV_DK, | |
64 | /**< System-D/K (IF: Fp=7.85MHz in default) */ | |
65 | SONY_HELENE_ATV_L, | |
66 | /**< System-L (IF: Fp=7.85MHz in default) */ | |
67 | SONY_HELENE_ATV_L_DASH, | |
68 | /**< System-L DASH (IF: Fp=2.2MHz in default) */ | |
69 | /* Terrestrial/Cable Digital */ | |
70 | SONY_HELENE_DTV_8VSB, | |
71 | /**< ATSC 8VSB (IF: Fc=3.7MHz in default) */ | |
72 | SONY_HELENE_DTV_QAM, | |
73 | /**< US QAM (IF: Fc=3.7MHz in default) */ | |
74 | SONY_HELENE_DTV_ISDBT_6, | |
75 | /**< ISDB-T 6MHzBW (IF: Fc=3.55MHz in default) */ | |
76 | SONY_HELENE_DTV_ISDBT_7, | |
77 | /**< ISDB-T 7MHzBW (IF: Fc=4.15MHz in default) */ | |
78 | SONY_HELENE_DTV_ISDBT_8, | |
79 | /**< ISDB-T 8MHzBW (IF: Fc=4.75MHz in default) */ | |
80 | SONY_HELENE_DTV_DVBT_5, | |
81 | /**< DVB-T 5MHzBW (IF: Fc=3.6MHz in default) */ | |
82 | SONY_HELENE_DTV_DVBT_6, | |
83 | /**< DVB-T 6MHzBW (IF: Fc=3.6MHz in default) */ | |
84 | SONY_HELENE_DTV_DVBT_7, | |
85 | /**< DVB-T 7MHzBW (IF: Fc=4.2MHz in default) */ | |
86 | SONY_HELENE_DTV_DVBT_8, | |
87 | /**< DVB-T 8MHzBW (IF: Fc=4.8MHz in default) */ | |
88 | SONY_HELENE_DTV_DVBT2_1_7, | |
89 | /**< DVB-T2 1.7MHzBW (IF: Fc=3.5MHz in default) */ | |
90 | SONY_HELENE_DTV_DVBT2_5, | |
91 | /**< DVB-T2 5MHzBW (IF: Fc=3.6MHz in default) */ | |
92 | SONY_HELENE_DTV_DVBT2_6, | |
93 | /**< DVB-T2 6MHzBW (IF: Fc=3.6MHz in default) */ | |
94 | SONY_HELENE_DTV_DVBT2_7, | |
95 | /**< DVB-T2 7MHzBW (IF: Fc=4.2MHz in default) */ | |
96 | SONY_HELENE_DTV_DVBT2_8, | |
97 | /**< DVB-T2 8MHzBW (IF: Fc=4.8MHz in default) */ | |
98 | SONY_HELENE_DTV_DVBC_6, | |
99 | /**< DVB-C 6MHzBW (IF: Fc=3.7MHz in default) */ | |
100 | SONY_HELENE_DTV_DVBC_8, | |
101 | /**< DVB-C 8MHzBW (IF: Fc=4.9MHz in default) */ | |
102 | SONY_HELENE_DTV_DVBC2_6, | |
103 | /**< DVB-C2 6MHzBW (IF: Fc=3.7MHz in default) */ | |
104 | SONY_HELENE_DTV_DVBC2_8, | |
105 | /**< DVB-C2 8MHzBW (IF: Fc=4.9MHz in default) */ | |
106 | SONY_HELENE_DTV_DTMB, | |
107 | /**< DTMB (IF: Fc=5.1MHz in default) */ | |
108 | /* Satellite */ | |
109 | SONY_HELENE_STV_ISDBS, | |
110 | /**< ISDB-S */ | |
111 | SONY_HELENE_STV_DVBS, | |
112 | /**< DVB-S */ | |
113 | SONY_HELENE_STV_DVBS2, | |
114 | /**< DVB-S2 */ | |
115 | ||
116 | SONY_HELENE_ATV_MIN = SONY_HELENE_ATV_MN_EIAJ, | |
117 | /**< Minimum analog terrestrial system */ | |
118 | SONY_HELENE_ATV_MAX = SONY_HELENE_ATV_L_DASH, | |
119 | /**< Maximum analog terrestrial system */ | |
120 | SONY_HELENE_DTV_MIN = SONY_HELENE_DTV_8VSB, | |
121 | /**< Minimum digital terrestrial system */ | |
122 | SONY_HELENE_DTV_MAX = SONY_HELENE_DTV_DTMB, | |
123 | /**< Maximum digital terrestrial system */ | |
124 | SONY_HELENE_TERR_TV_SYSTEM_NUM, | |
125 | /**< Number of supported terrestrial broadcasting system */ | |
126 | SONY_HELENE_STV_MIN = SONY_HELENE_STV_ISDBS, | |
127 | /**< Minimum satellite system */ | |
128 | SONY_HELENE_STV_MAX = SONY_HELENE_STV_DVBS2 | |
129 | /**< Maximum satellite system */ | |
130 | }; | |
131 | ||
132 | struct helene_terr_adjust_param_t { | |
133 | /* < Addr:0x69 Bit[6:4] : RFVGA gain. | |
134 | * 0xFF means Auto. (RF_GAIN_SEL = 1) | |
135 | */ | |
136 | uint8_t RF_GAIN; | |
137 | /* < Addr:0x69 Bit[3:0] : IF_BPF gain. | |
138 | */ | |
139 | uint8_t IF_BPF_GC; | |
140 | /* < Addr:0x6B Bit[3:0] : RF overload | |
141 | * RF input detect level. (FRF <= 172MHz) | |
142 | */ | |
143 | uint8_t RFOVLD_DET_LV1_VL; | |
144 | /* < Addr:0x6B Bit[3:0] : RF overload | |
145 | * RF input detect level. (172MHz < FRF <= 464MHz) | |
146 | */ | |
147 | uint8_t RFOVLD_DET_LV1_VH; | |
148 | /* < Addr:0x6B Bit[3:0] : RF overload | |
149 | * RF input detect level. (FRF > 464MHz) | |
150 | */ | |
151 | uint8_t RFOVLD_DET_LV1_U; | |
152 | /* < Addr:0x6C Bit[2:0] : | |
153 | * Internal RFAGC detect level. (FRF <= 172MHz) | |
154 | */ | |
155 | uint8_t IFOVLD_DET_LV_VL; | |
156 | /* < Addr:0x6C Bit[2:0] : | |
157 | * Internal RFAGC detect level. (172MHz < FRF <= 464MHz) | |
158 | */ | |
159 | uint8_t IFOVLD_DET_LV_VH; | |
160 | /* < Addr:0x6C Bit[2:0] : | |
161 | * Internal RFAGC detect level. (FRF > 464MHz) | |
162 | */ | |
163 | uint8_t IFOVLD_DET_LV_U; | |
164 | /* < Addr:0x6D Bit[5:4] : | |
165 | * IF filter center offset. | |
166 | */ | |
167 | uint8_t IF_BPF_F0; | |
168 | /* < Addr:0x6D Bit[1:0] : | |
169 | * 6MHzBW(0x00) or 7MHzBW(0x01) | |
170 | * or 8MHzBW(0x02) or 1.7MHzBW(0x03) | |
171 | */ | |
172 | uint8_t BW; | |
173 | /* < Addr:0x6E Bit[4:0] : | |
174 | * 5bit signed. IF offset (kHz) = FIF_OFFSET x 50 | |
175 | */ | |
176 | uint8_t FIF_OFFSET; | |
177 | /* < Addr:0x6F Bit[4:0] : | |
178 | * 5bit signed. BW offset (kHz) = | |
179 | * BW_OFFSET x 50 (BW_OFFSET x 10 in 1.7MHzBW) | |
180 | */ | |
181 | uint8_t BW_OFFSET; | |
182 | /* < Addr:0x9C Bit[0] : | |
183 | * Local polarity. (0: Upper Local, 1: Lower Local) | |
184 | */ | |
185 | uint8_t IS_LOWERLOCAL; | |
186 | }; | |
187 | ||
188 | static const struct helene_terr_adjust_param_t | |
189 | terr_params[SONY_HELENE_TERR_TV_SYSTEM_NUM] = { | |
190 | /*< SONY_HELENE_TV_SYSTEM_UNKNOWN */ | |
191 | {HELENE_AUTO, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
192 | HELENE_BW_6, HELENE_OFFSET(0), HELENE_OFFSET(0), 0x00}, | |
193 | /* Analog */ | |
194 | /**< SONY_HELENE_ATV_MN_EIAJ (System-M (Japan)) */ | |
195 | {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00, | |
196 | HELENE_BW_6, HELENE_OFFSET(0), HELENE_OFFSET(1), 0x00}, | |
197 | /**< SONY_HELENE_ATV_MN_SAP (System-M (US)) */ | |
198 | {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00, | |
199 | HELENE_BW_6, HELENE_OFFSET(0), HELENE_OFFSET(1), 0x00}, | |
200 | {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00, | |
201 | HELENE_BW_6, HELENE_OFFSET(3), HELENE_OFFSET(1), 0x00}, | |
202 | /**< SONY_HELENE_ATV_MN_A2 (System-M (Korea)) */ | |
203 | {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00, | |
204 | HELENE_BW_7, HELENE_OFFSET(11), HELENE_OFFSET(5), 0x00}, | |
205 | /**< SONY_HELENE_ATV_BG (System-B/G) */ | |
206 | {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00, | |
207 | HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(-3), 0x00}, | |
208 | /**< SONY_HELENE_ATV_I (System-I) */ | |
209 | {HELENE_AUTO, 0x05, 0x03, 0x06, 0x03, 0x01, 0x01, 0x01, 0x00, | |
210 | HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(-3), 0x00}, | |
211 | /**< SONY_HELENE_ATV_DK (System-D/K) */ | |
212 | {HELENE_AUTO, 0x03, 0x04, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x00, | |
213 | HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(-3), 0x00}, | |
214 | /**< SONY_HELENE_ATV_L (System-L) */ | |
215 | {HELENE_AUTO, 0x03, 0x04, 0x0A, 0x04, 0x04, 0x04, 0x04, 0x00, | |
216 | HELENE_BW_8, HELENE_OFFSET(-1), HELENE_OFFSET(4), 0x00}, | |
217 | /**< SONY_HELENE_ATV_L_DASH (System-L DASH) */ | |
218 | /* Digital */ | |
219 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x03, 0x03, 0x03, 0x00, | |
220 | HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-3), 0x00}, | |
221 | /**< SONY_HELENE_DTV_8VSB (ATSC 8VSB) */ | |
222 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
223 | HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-3), 0x00}, | |
224 | /**< SONY_HELENE_DTV_QAM (US QAM) */ | |
225 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
226 | HELENE_BW_6, HELENE_OFFSET(-9), HELENE_OFFSET(-5), 0x00}, | |
227 | /**< SONY_HELENE_DTV_ISDBT_6 (ISDB-T 6MHzBW) */ | |
228 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
229 | HELENE_BW_7, HELENE_OFFSET(-7), HELENE_OFFSET(-6), 0x00}, | |
230 | /**< SONY_HELENE_DTV_ISDBT_7 (ISDB-T 7MHzBW) */ | |
231 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
232 | HELENE_BW_8, HELENE_OFFSET(-5), HELENE_OFFSET(-7), 0x00}, | |
233 | /**< SONY_HELENE_DTV_ISDBT_8 (ISDB-T 8MHzBW) */ | |
234 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
235 | HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00}, | |
236 | /**< SONY_HELENE_DTV_DVBT_5 (DVB-T 5MHzBW) */ | |
237 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
238 | HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00}, | |
239 | /**< SONY_HELENE_DTV_DVBT_6 (DVB-T 6MHzBW) */ | |
240 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
241 | HELENE_BW_7, HELENE_OFFSET(-6), HELENE_OFFSET(-5), 0x00}, | |
242 | /**< SONY_HELENE_DTV_DVBT_7 (DVB-T 7MHzBW) */ | |
243 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
244 | HELENE_BW_8, HELENE_OFFSET(-4), HELENE_OFFSET(-6), 0x00}, | |
245 | /**< SONY_HELENE_DTV_DVBT_8 (DVB-T 8MHzBW) */ | |
246 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
247 | HELENE_BW_1_7, HELENE_OFFSET(-10), HELENE_OFFSET(-10), 0x00}, | |
248 | /**< SONY_HELENE_DTV_DVBT2_1_7 (DVB-T2 1.7MHzBW) */ | |
249 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
250 | HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00}, | |
251 | /**< SONY_HELENE_DTV_DVBT2_5 (DVB-T2 5MHzBW) */ | |
252 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
253 | HELENE_BW_6, HELENE_OFFSET(-8), HELENE_OFFSET(-3), 0x00}, | |
254 | /**< SONY_HELENE_DTV_DVBT2_6 (DVB-T2 6MHzBW) */ | |
255 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
256 | HELENE_BW_7, HELENE_OFFSET(-6), HELENE_OFFSET(-5), 0x00}, | |
257 | /**< SONY_HELENE_DTV_DVBT2_7 (DVB-T2 7MHzBW) */ | |
258 | {HELENE_AUTO, 0x09, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
259 | HELENE_BW_8, HELENE_OFFSET(-4), HELENE_OFFSET(-6), 0x00}, | |
260 | /**< SONY_HELENE_DTV_DVBT2_8 (DVB-T2 8MHzBW) */ | |
261 | {HELENE_AUTO, 0x05, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, | |
262 | HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-4), 0x00}, | |
263 | /**< SONY_HELENE_DTV_DVBC_6 (DVB-C 6MHzBW) */ | |
264 | {HELENE_AUTO, 0x05, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, | |
265 | HELENE_BW_8, HELENE_OFFSET(-2), HELENE_OFFSET(-3), 0x00}, | |
266 | /**< SONY_HELENE_DTV_DVBC_8 (DVB-C 8MHzBW) */ | |
267 | {HELENE_AUTO, 0x03, 0x09, 0x09, 0x09, 0x02, 0x02, 0x02, 0x00, | |
268 | HELENE_BW_6, HELENE_OFFSET(-6), HELENE_OFFSET(-2), 0x00}, | |
269 | /**< SONY_HELENE_DTV_DVBC2_6 (DVB-C2 6MHzBW) */ | |
270 | {HELENE_AUTO, 0x03, 0x09, 0x09, 0x09, 0x02, 0x02, 0x02, 0x00, | |
271 | HELENE_BW_8, HELENE_OFFSET(-2), HELENE_OFFSET(0), 0x00}, | |
272 | /**< SONY_HELENE_DTV_DVBC2_8 (DVB-C2 8MHzBW) */ | |
273 | {HELENE_AUTO, 0x04, 0x0B, 0x0B, 0x0B, 0x02, 0x02, 0x02, 0x00, | |
274 | HELENE_BW_8, HELENE_OFFSET(2), HELENE_OFFSET(1), 0x00} | |
275 | /**< SONY_HELENE_DTV_DTMB (DTMB) */ | |
276 | }; | |
277 | ||
278 | static void helene_i2c_debug(struct helene_priv *priv, | |
279 | u8 reg, u8 write, const u8 *data, u32 len) | |
280 | { | |
281 | dev_dbg(&priv->i2c->dev, "helene: I2C %s reg 0x%02x size %d\n", | |
282 | (write == 0 ? "read" : "write"), reg, len); | |
283 | print_hex_dump_bytes("helene: I2C data: ", | |
284 | DUMP_PREFIX_OFFSET, data, len); | |
285 | } | |
286 | ||
287 | static int helene_write_regs(struct helene_priv *priv, | |
288 | u8 reg, const u8 *data, u32 len) | |
289 | { | |
290 | int ret; | |
291 | u8 buf[MAX_WRITE_REGSIZE + 1]; | |
292 | struct i2c_msg msg[1] = { | |
293 | { | |
294 | .addr = priv->i2c_address, | |
295 | .flags = 0, | |
296 | .len = len + 1, | |
297 | .buf = buf, | |
298 | } | |
299 | }; | |
300 | ||
301 | if (len + 1 > sizeof(buf)) { | |
302 | dev_warn(&priv->i2c->dev, | |
5b5e0928 | 303 | "wr reg=%04x: len=%d vs %zu is too big!\n", |
2dc1ed4e AO |
304 | reg, len + 1, sizeof(buf)); |
305 | return -E2BIG; | |
306 | } | |
307 | ||
308 | helene_i2c_debug(priv, reg, 1, data, len); | |
309 | buf[0] = reg; | |
310 | memcpy(&buf[1], data, len); | |
311 | ret = i2c_transfer(priv->i2c, msg, 1); | |
312 | if (ret >= 0 && ret != 1) | |
313 | ret = -EREMOTEIO; | |
314 | if (ret < 0) { | |
315 | dev_warn(&priv->i2c->dev, | |
316 | "%s: i2c wr failed=%d reg=%02x len=%d\n", | |
317 | KBUILD_MODNAME, ret, reg, len); | |
318 | return ret; | |
319 | } | |
320 | return 0; | |
321 | } | |
322 | ||
323 | static int helene_write_reg(struct helene_priv *priv, u8 reg, u8 val) | |
324 | { | |
3cd890db AB |
325 | u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */ |
326 | ||
327 | return helene_write_regs(priv, reg, &tmp, 1); | |
2dc1ed4e AO |
328 | } |
329 | ||
330 | static int helene_read_regs(struct helene_priv *priv, | |
331 | u8 reg, u8 *val, u32 len) | |
332 | { | |
333 | int ret; | |
334 | struct i2c_msg msg[2] = { | |
335 | { | |
336 | .addr = priv->i2c_address, | |
337 | .flags = 0, | |
338 | .len = 1, | |
339 | .buf = ®, | |
340 | }, { | |
341 | .addr = priv->i2c_address, | |
342 | .flags = I2C_M_RD, | |
343 | .len = len, | |
344 | .buf = val, | |
345 | } | |
346 | }; | |
347 | ||
348 | ret = i2c_transfer(priv->i2c, &msg[0], 1); | |
349 | if (ret >= 0 && ret != 1) | |
350 | ret = -EREMOTEIO; | |
351 | if (ret < 0) { | |
352 | dev_warn(&priv->i2c->dev, | |
353 | "%s: I2C rw failed=%d addr=%02x reg=%02x\n", | |
354 | KBUILD_MODNAME, ret, priv->i2c_address, reg); | |
355 | return ret; | |
356 | } | |
357 | ret = i2c_transfer(priv->i2c, &msg[1], 1); | |
358 | if (ret >= 0 && ret != 1) | |
359 | ret = -EREMOTEIO; | |
360 | if (ret < 0) { | |
361 | dev_warn(&priv->i2c->dev, | |
362 | "%s: i2c rd failed=%d addr=%02x reg=%02x\n", | |
363 | KBUILD_MODNAME, ret, priv->i2c_address, reg); | |
364 | return ret; | |
365 | } | |
366 | helene_i2c_debug(priv, reg, 0, val, len); | |
367 | return 0; | |
368 | } | |
369 | ||
370 | static int helene_read_reg(struct helene_priv *priv, u8 reg, u8 *val) | |
371 | { | |
372 | return helene_read_regs(priv, reg, val, 1); | |
373 | } | |
374 | ||
375 | static int helene_set_reg_bits(struct helene_priv *priv, | |
376 | u8 reg, u8 data, u8 mask) | |
377 | { | |
378 | int res; | |
379 | u8 rdata; | |
380 | ||
381 | if (mask != 0xff) { | |
382 | res = helene_read_reg(priv, reg, &rdata); | |
383 | if (res != 0) | |
384 | return res; | |
385 | data = ((data & mask) | (rdata & (mask ^ 0xFF))); | |
386 | } | |
387 | return helene_write_reg(priv, reg, data); | |
388 | } | |
389 | ||
390 | static int helene_enter_power_save(struct helene_priv *priv) | |
391 | { | |
392 | dev_dbg(&priv->i2c->dev, "%s()\n", __func__); | |
393 | if (priv->state == STATE_SLEEP) | |
394 | return 0; | |
395 | ||
396 | /* Standby setting for CPU */ | |
397 | helene_write_reg(priv, 0x88, 0x0); | |
398 | ||
399 | /* Standby setting for internal logic block */ | |
400 | helene_write_reg(priv, 0x87, 0xC0); | |
401 | ||
402 | priv->state = STATE_SLEEP; | |
403 | return 0; | |
404 | } | |
405 | ||
406 | static int helene_leave_power_save(struct helene_priv *priv) | |
407 | { | |
408 | dev_dbg(&priv->i2c->dev, "%s()\n", __func__); | |
409 | if (priv->state == STATE_ACTIVE) | |
410 | return 0; | |
411 | ||
412 | /* Standby setting for internal logic block */ | |
413 | helene_write_reg(priv, 0x87, 0xC4); | |
414 | ||
415 | /* Standby setting for CPU */ | |
416 | helene_write_reg(priv, 0x88, 0x40); | |
417 | ||
418 | priv->state = STATE_ACTIVE; | |
419 | return 0; | |
420 | } | |
421 | ||
422 | static int helene_init(struct dvb_frontend *fe) | |
423 | { | |
424 | struct helene_priv *priv = fe->tuner_priv; | |
425 | ||
426 | dev_dbg(&priv->i2c->dev, "%s()\n", __func__); | |
427 | return helene_leave_power_save(priv); | |
428 | } | |
429 | ||
194ced7a | 430 | static void helene_release(struct dvb_frontend *fe) |
2dc1ed4e AO |
431 | { |
432 | struct helene_priv *priv = fe->tuner_priv; | |
433 | ||
434 | dev_dbg(&priv->i2c->dev, "%s()\n", __func__); | |
435 | kfree(fe->tuner_priv); | |
436 | fe->tuner_priv = NULL; | |
2dc1ed4e AO |
437 | } |
438 | ||
439 | static int helene_sleep(struct dvb_frontend *fe) | |
440 | { | |
441 | struct helene_priv *priv = fe->tuner_priv; | |
442 | ||
443 | dev_dbg(&priv->i2c->dev, "%s()\n", __func__); | |
444 | helene_enter_power_save(priv); | |
445 | return 0; | |
446 | } | |
447 | ||
448 | static enum helene_tv_system_t helene_get_tv_system(struct dvb_frontend *fe) | |
449 | { | |
450 | enum helene_tv_system_t system = SONY_HELENE_TV_SYSTEM_UNKNOWN; | |
451 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | |
452 | struct helene_priv *priv = fe->tuner_priv; | |
453 | ||
454 | if (p->delivery_system == SYS_DVBT) { | |
455 | if (p->bandwidth_hz <= 5000000) | |
456 | system = SONY_HELENE_DTV_DVBT_5; | |
457 | else if (p->bandwidth_hz <= 6000000) | |
458 | system = SONY_HELENE_DTV_DVBT_6; | |
459 | else if (p->bandwidth_hz <= 7000000) | |
460 | system = SONY_HELENE_DTV_DVBT_7; | |
461 | else if (p->bandwidth_hz <= 8000000) | |
462 | system = SONY_HELENE_DTV_DVBT_8; | |
463 | else { | |
464 | system = SONY_HELENE_DTV_DVBT_8; | |
465 | p->bandwidth_hz = 8000000; | |
466 | } | |
467 | } else if (p->delivery_system == SYS_DVBT2) { | |
468 | if (p->bandwidth_hz <= 5000000) | |
469 | system = SONY_HELENE_DTV_DVBT2_5; | |
470 | else if (p->bandwidth_hz <= 6000000) | |
471 | system = SONY_HELENE_DTV_DVBT2_6; | |
472 | else if (p->bandwidth_hz <= 7000000) | |
473 | system = SONY_HELENE_DTV_DVBT2_7; | |
474 | else if (p->bandwidth_hz <= 8000000) | |
475 | system = SONY_HELENE_DTV_DVBT2_8; | |
476 | else { | |
477 | system = SONY_HELENE_DTV_DVBT2_8; | |
478 | p->bandwidth_hz = 8000000; | |
479 | } | |
480 | } else if (p->delivery_system == SYS_DVBS) { | |
481 | system = SONY_HELENE_STV_DVBS; | |
482 | } else if (p->delivery_system == SYS_DVBS2) { | |
483 | system = SONY_HELENE_STV_DVBS2; | |
484 | } else if (p->delivery_system == SYS_ISDBS) { | |
485 | system = SONY_HELENE_STV_ISDBS; | |
486 | } else if (p->delivery_system == SYS_ISDBT) { | |
487 | if (p->bandwidth_hz <= 6000000) | |
488 | system = SONY_HELENE_DTV_ISDBT_6; | |
489 | else if (p->bandwidth_hz <= 7000000) | |
490 | system = SONY_HELENE_DTV_ISDBT_7; | |
491 | else if (p->bandwidth_hz <= 8000000) | |
492 | system = SONY_HELENE_DTV_ISDBT_8; | |
493 | else { | |
494 | system = SONY_HELENE_DTV_ISDBT_8; | |
495 | p->bandwidth_hz = 8000000; | |
496 | } | |
497 | } else if (p->delivery_system == SYS_DVBC_ANNEX_A) { | |
498 | if (p->bandwidth_hz <= 6000000) | |
499 | system = SONY_HELENE_DTV_DVBC_6; | |
500 | else if (p->bandwidth_hz <= 8000000) | |
501 | system = SONY_HELENE_DTV_DVBC_8; | |
502 | } | |
503 | dev_dbg(&priv->i2c->dev, | |
504 | "%s(): HELENE DTV system %d (delsys %d, bandwidth %d)\n", | |
505 | __func__, (int)system, p->delivery_system, | |
506 | p->bandwidth_hz); | |
507 | return system; | |
508 | } | |
509 | ||
510 | static int helene_set_params_s(struct dvb_frontend *fe) | |
511 | { | |
512 | u8 data[MAX_WRITE_REGSIZE]; | |
513 | u32 frequency; | |
514 | enum helene_tv_system_t tv_system; | |
515 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | |
516 | struct helene_priv *priv = fe->tuner_priv; | |
1cdc4f09 | 517 | int frequencykHz = p->frequency; |
2dc1ed4e AO |
518 | uint32_t frequency4kHz = 0; |
519 | u32 symbol_rate = p->symbol_rate/1000; | |
520 | ||
521 | dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz sr=%uKsps\n", | |
522 | __func__, frequencykHz, symbol_rate); | |
523 | tv_system = helene_get_tv_system(fe); | |
524 | ||
525 | if (tv_system == SONY_HELENE_TV_SYSTEM_UNKNOWN) { | |
526 | dev_err(&priv->i2c->dev, "%s(): unknown DTV system\n", | |
527 | __func__); | |
528 | return -EINVAL; | |
529 | } | |
530 | /* RF switch turn to satellite */ | |
531 | if (priv->set_tuner) | |
532 | priv->set_tuner(priv->set_tuner_data, 0); | |
533 | frequency = roundup(p->frequency / 1000, 1); | |
534 | ||
535 | /* Disable IF signal output */ | |
536 | helene_write_reg(priv, 0x15, 0x02); | |
537 | ||
538 | /* RFIN matching in power save (Sat) reset */ | |
539 | helene_write_reg(priv, 0x43, 0x06); | |
540 | ||
541 | /* Analog block setting (0x6A, 0x6B) */ | |
542 | data[0] = 0x00; | |
543 | data[1] = 0x00; | |
544 | helene_write_regs(priv, 0x6A, data, 2); | |
545 | helene_write_reg(priv, 0x75, 0x99); | |
546 | helene_write_reg(priv, 0x9D, 0x00); | |
547 | ||
548 | /* Tuning setting for CPU (0x61) */ | |
549 | helene_write_reg(priv, 0x61, 0x07); | |
550 | ||
551 | /* Satellite mode select (0x01) */ | |
552 | helene_write_reg(priv, 0x01, 0x01); | |
553 | ||
554 | /* Clock enable for internal logic block, CPU wake-up (0x04, 0x05) */ | |
555 | data[0] = 0xC4; | |
556 | data[1] = 0x40; | |
557 | ||
558 | switch (priv->xtal) { | |
559 | case SONY_HELENE_XTAL_16000: | |
560 | data[2] = 0x02; | |
561 | break; | |
562 | case SONY_HELENE_XTAL_20500: | |
563 | data[2] = 0x02; | |
564 | break; | |
565 | case SONY_HELENE_XTAL_24000: | |
566 | data[2] = 0x03; | |
567 | break; | |
568 | case SONY_HELENE_XTAL_41000: | |
569 | data[2] = 0x05; | |
570 | break; | |
571 | default: | |
572 | dev_err(&priv->i2c->dev, "%s(): unknown xtal %d\n", | |
573 | __func__, priv->xtal); | |
574 | return -EINVAL; | |
575 | } | |
576 | ||
577 | /* Setting for analog block (0x07). LOOPFILTER INTERNAL */ | |
578 | data[3] = 0x80; | |
579 | ||
580 | /* Tuning setting for analog block | |
581 | * (0x08, 0x09, 0x0A, 0x0B). LOOPFILTER INTERNAL | |
582 | */ | |
583 | if (priv->xtal == SONY_HELENE_XTAL_20500) | |
584 | data[4] = 0x58; | |
585 | else | |
586 | data[4] = 0x70; | |
587 | ||
588 | data[5] = 0x1E; | |
589 | data[6] = 0x02; | |
590 | data[7] = 0x24; | |
591 | ||
592 | /* Enable for analog block (0x0C, 0x0D, 0x0E). SAT LNA ON */ | |
593 | data[8] = 0x0F; | |
594 | data[8] |= 0xE0; /* POWERSAVE_TERR_RF_ACTIVE */ | |
595 | data[9] = 0x02; | |
596 | data[10] = 0x1E; | |
597 | ||
598 | /* Setting for LPF cutoff frequency (0x0F) */ | |
599 | switch (tv_system) { | |
600 | case SONY_HELENE_STV_ISDBS: | |
601 | data[11] = 0x22; /* 22MHz */ | |
602 | break; | |
603 | case SONY_HELENE_STV_DVBS: | |
604 | if (symbol_rate <= 4000) | |
605 | data[11] = 0x05; | |
606 | else if (symbol_rate <= 10000) | |
607 | data[11] = (uint8_t)((symbol_rate * 47 | |
608 | + (40000-1)) / 40000); | |
609 | else | |
610 | data[11] = (uint8_t)((symbol_rate * 27 | |
611 | + (40000-1)) / 40000 + 5); | |
612 | ||
613 | if (data[11] > 36) | |
614 | data[11] = 36; /* 5 <= lpf_cutoff <= 36 is valid */ | |
615 | break; | |
616 | case SONY_HELENE_STV_DVBS2: | |
617 | if (symbol_rate <= 4000) | |
618 | data[11] = 0x05; | |
619 | else if (symbol_rate <= 10000) | |
620 | data[11] = (uint8_t)((symbol_rate * 11 | |
621 | + (10000-1)) / 10000); | |
622 | else | |
623 | data[11] = (uint8_t)((symbol_rate * 3 | |
624 | + (5000-1)) / 5000 + 5); | |
625 | ||
626 | if (data[11] > 36) | |
627 | data[11] = 36; /* 5 <= lpf_cutoff <= 36 is valid */ | |
628 | break; | |
629 | default: | |
630 | dev_err(&priv->i2c->dev, "%s(): unknown standard %d\n", | |
631 | __func__, tv_system); | |
632 | return -EINVAL; | |
633 | } | |
634 | ||
635 | /* RF tuning frequency setting (0x10, 0x11, 0x12) */ | |
636 | frequency4kHz = (frequencykHz + 2) / 4; | |
637 | data[12] = (uint8_t)(frequency4kHz & 0xFF); /* FRF_L */ | |
638 | data[13] = (uint8_t)((frequency4kHz >> 8) & 0xFF); /* FRF_M */ | |
639 | /* FRF_H (bit[3:0]) */ | |
640 | data[14] = (uint8_t)((frequency4kHz >> 16) & 0x0F); | |
641 | ||
642 | /* Tuning command (0x13) */ | |
643 | data[15] = 0xFF; | |
644 | ||
645 | /* Setting for IQOUT_LIMIT (0x14) 0.75Vpp */ | |
646 | data[16] = 0x00; | |
647 | ||
648 | /* Enable IQ output (0x15) */ | |
649 | data[17] = 0x01; | |
650 | ||
651 | helene_write_regs(priv, 0x04, data, 18); | |
652 | ||
653 | dev_dbg(&priv->i2c->dev, "%s(): tune done\n", | |
654 | __func__); | |
655 | ||
656 | priv->frequency = frequency; | |
657 | return 0; | |
658 | } | |
659 | ||
817dc4b5 | 660 | static int helene_set_params_t(struct dvb_frontend *fe) |
2dc1ed4e AO |
661 | { |
662 | u8 data[MAX_WRITE_REGSIZE]; | |
663 | u32 frequency; | |
664 | enum helene_tv_system_t tv_system; | |
665 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | |
666 | struct helene_priv *priv = fe->tuner_priv; | |
667 | int frequencykHz = p->frequency / 1000; | |
668 | ||
669 | dev_dbg(&priv->i2c->dev, "%s(): tune frequency %dkHz\n", | |
670 | __func__, frequencykHz); | |
671 | tv_system = helene_get_tv_system(fe); | |
672 | ||
673 | if (tv_system == SONY_HELENE_TV_SYSTEM_UNKNOWN) { | |
674 | dev_dbg(&priv->i2c->dev, "%s(): unknown DTV system\n", | |
675 | __func__); | |
676 | return -EINVAL; | |
677 | } | |
678 | if (priv->set_tuner) | |
679 | priv->set_tuner(priv->set_tuner_data, 1); | |
680 | frequency = roundup(p->frequency / 1000, 25); | |
681 | ||
682 | /* mode select */ | |
683 | helene_write_reg(priv, 0x01, 0x00); | |
684 | ||
685 | /* Disable IF signal output */ | |
686 | helene_write_reg(priv, 0x74, 0x02); | |
687 | ||
688 | if (priv->state == STATE_SLEEP) | |
689 | helene_leave_power_save(priv); | |
690 | ||
691 | /* Initial setting for internal analog block (0x91, 0x92) */ | |
692 | if ((tv_system == SONY_HELENE_DTV_DVBC_6) || | |
693 | (tv_system == SONY_HELENE_DTV_DVBC_8)) { | |
694 | data[0] = 0x16; | |
695 | data[1] = 0x26; | |
696 | } else { | |
697 | data[0] = 0x10; | |
698 | data[1] = 0x20; | |
699 | } | |
700 | helene_write_regs(priv, 0x91, data, 2); | |
701 | ||
702 | /* Setting for analog block */ | |
703 | if (TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system)) | |
704 | data[0] = 0x90; | |
705 | else | |
706 | data[0] = 0x00; | |
707 | ||
708 | /* Setting for local polarity (0x9D) */ | |
709 | data[1] = (uint8_t)(terr_params[tv_system].IS_LOWERLOCAL & 0x01); | |
710 | helene_write_regs(priv, 0x9C, data, 2); | |
711 | ||
712 | /* Enable for analog block */ | |
713 | data[0] = 0xEE; | |
714 | data[1] = 0x02; | |
715 | data[2] = 0x1E; | |
716 | data[3] = 0x67; /* Tuning setting for CPU */ | |
717 | ||
718 | /* Setting for PLL reference divider for xtal=24MHz */ | |
719 | if ((tv_system == SONY_HELENE_DTV_DVBC_6) || | |
720 | (tv_system == SONY_HELENE_DTV_DVBC_8)) | |
721 | data[4] = 0x18; | |
722 | else | |
723 | data[4] = 0x03; | |
724 | ||
725 | /* Tuning setting for analog block */ | |
726 | if (TERR_INTERNAL_LOOPFILTER_AVAILABLE(tv_system)) { | |
727 | data[5] = 0x38; | |
728 | data[6] = 0x1E; | |
729 | data[7] = 0x02; | |
730 | data[8] = 0x24; | |
731 | } else if ((tv_system == SONY_HELENE_DTV_DVBC_6) || | |
732 | (tv_system == SONY_HELENE_DTV_DVBC_8)) { | |
733 | data[5] = 0x1C; | |
734 | data[6] = 0x78; | |
735 | data[7] = 0x08; | |
736 | data[8] = 0x1C; | |
737 | } else { | |
738 | data[5] = 0xB4; | |
739 | data[6] = 0x78; | |
740 | data[7] = 0x08; | |
741 | data[8] = 0x30; | |
155af08b | 742 | } |
2dc1ed4e AO |
743 | helene_write_regs(priv, 0x5E, data, 9); |
744 | ||
745 | /* LT_AMP_EN should be 0 */ | |
746 | helene_set_reg_bits(priv, 0x67, 0x0, 0x02); | |
747 | ||
748 | /* Setting for IFOUT_LIMIT */ | |
749 | data[0] = 0x00; /* 1.5Vpp */ | |
750 | ||
751 | /* RF_GAIN setting */ | |
752 | if (terr_params[tv_system].RF_GAIN == HELENE_AUTO) | |
753 | data[1] = 0x80; /* RF_GAIN_SEL = 1 */ | |
754 | else | |
755 | data[1] = (uint8_t)((terr_params[tv_system].RF_GAIN | |
756 | << 4) & 0x70); | |
757 | ||
758 | /* IF_BPF_GC setting */ | |
759 | data[1] |= (uint8_t)(terr_params[tv_system].IF_BPF_GC & 0x0F); | |
760 | ||
761 | /* Setting for internal RFAGC (0x6A, 0x6B, 0x6C) */ | |
762 | data[2] = 0x00; | |
763 | if (frequencykHz <= 172000) { | |
764 | data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_VL | |
765 | & 0x0F); | |
766 | data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_VL | |
767 | & 0x07); | |
768 | } else if (frequencykHz <= 464000) { | |
769 | data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_VH | |
770 | & 0x0F); | |
771 | data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_VH | |
772 | & 0x07); | |
773 | } else { | |
774 | data[3] = (uint8_t)(terr_params[tv_system].RFOVLD_DET_LV1_U | |
775 | & 0x0F); | |
776 | data[4] = (uint8_t)(terr_params[tv_system].IFOVLD_DET_LV_U | |
777 | & 0x07); | |
778 | } | |
779 | data[4] |= 0x20; | |
780 | ||
781 | /* Setting for IF frequency and bandwidth */ | |
782 | ||
783 | /* IF filter center frequency offset (IF_BPF_F0) (0x6D) */ | |
784 | data[5] = (uint8_t)((terr_params[tv_system].IF_BPF_F0 << 4) & 0x30); | |
785 | ||
786 | /* IF filter band width (BW) (0x6D) */ | |
787 | data[5] |= (uint8_t)(terr_params[tv_system].BW & 0x03); | |
788 | ||
789 | /* IF frequency offset value (FIF_OFFSET) (0x6E) */ | |
790 | data[6] = (uint8_t)(terr_params[tv_system].FIF_OFFSET & 0x1F); | |
791 | ||
792 | /* IF band width offset value (BW_OFFSET) (0x6F) */ | |
793 | data[7] = (uint8_t)(terr_params[tv_system].BW_OFFSET & 0x1F); | |
794 | ||
795 | /* RF tuning frequency setting (0x70, 0x71, 0x72) */ | |
796 | data[8] = (uint8_t)(frequencykHz & 0xFF); /* FRF_L */ | |
797 | data[9] = (uint8_t)((frequencykHz >> 8) & 0xFF); /* FRF_M */ | |
798 | data[10] = (uint8_t)((frequencykHz >> 16) | |
799 | & 0x0F); /* FRF_H (bit[3:0]) */ | |
800 | ||
801 | /* Tuning command */ | |
802 | data[11] = 0xFF; | |
803 | ||
804 | /* Enable IF output, AGC and IFOUT pin selection (0x74) */ | |
805 | data[12] = 0x01; | |
806 | ||
807 | if ((tv_system == SONY_HELENE_DTV_DVBC_6) || | |
808 | (tv_system == SONY_HELENE_DTV_DVBC_8)) { | |
809 | data[13] = 0xD9; | |
810 | data[14] = 0x0F; | |
811 | data[15] = 0x24; | |
812 | data[16] = 0x87; | |
813 | } else { | |
814 | data[13] = 0x99; | |
815 | data[14] = 0x00; | |
816 | data[15] = 0x24; | |
817 | data[16] = 0x87; | |
818 | } | |
819 | ||
820 | helene_write_regs(priv, 0x68, data, 17); | |
821 | ||
822 | dev_dbg(&priv->i2c->dev, "%s(): tune done\n", | |
823 | __func__); | |
824 | ||
825 | priv->frequency = frequency; | |
826 | return 0; | |
827 | } | |
828 | ||
817dc4b5 KS |
829 | static int helene_set_params(struct dvb_frontend *fe) |
830 | { | |
831 | struct dtv_frontend_properties *p = &fe->dtv_property_cache; | |
832 | ||
833 | if (p->delivery_system == SYS_DVBT || | |
834 | p->delivery_system == SYS_DVBT2 || | |
835 | p->delivery_system == SYS_ISDBT || | |
836 | p->delivery_system == SYS_DVBC_ANNEX_A) | |
837 | return helene_set_params_t(fe); | |
838 | ||
839 | return helene_set_params_s(fe); | |
840 | } | |
841 | ||
2dc1ed4e AO |
842 | static int helene_get_frequency(struct dvb_frontend *fe, u32 *frequency) |
843 | { | |
844 | struct helene_priv *priv = fe->tuner_priv; | |
845 | ||
846 | *frequency = priv->frequency * 1000; | |
847 | return 0; | |
848 | } | |
849 | ||
817dc4b5 | 850 | static const struct dvb_tuner_ops helene_tuner_ops_t = { |
2dc1ed4e AO |
851 | .info = { |
852 | .name = "Sony HELENE Ter tuner", | |
a3f90c75 MCC |
853 | .frequency_min_hz = 1 * MHz, |
854 | .frequency_max_hz = 1200 * MHz, | |
855 | .frequency_step_hz = 25 * kHz, | |
2dc1ed4e AO |
856 | }, |
857 | .init = helene_init, | |
858 | .release = helene_release, | |
859 | .sleep = helene_sleep, | |
817dc4b5 | 860 | .set_params = helene_set_params_t, |
2dc1ed4e AO |
861 | .get_frequency = helene_get_frequency, |
862 | }; | |
863 | ||
14c4bf3c | 864 | static const struct dvb_tuner_ops helene_tuner_ops_s = { |
2dc1ed4e AO |
865 | .info = { |
866 | .name = "Sony HELENE Sat tuner", | |
a3f90c75 MCC |
867 | .frequency_min_hz = 500 * MHz, |
868 | .frequency_max_hz = 2500 * MHz, | |
869 | .frequency_step_hz = 1 * MHz, | |
2dc1ed4e AO |
870 | }, |
871 | .init = helene_init, | |
872 | .release = helene_release, | |
873 | .sleep = helene_sleep, | |
874 | .set_params = helene_set_params_s, | |
875 | .get_frequency = helene_get_frequency, | |
876 | }; | |
877 | ||
817dc4b5 KS |
878 | static const struct dvb_tuner_ops helene_tuner_ops = { |
879 | .info = { | |
880 | .name = "Sony HELENE Sat/Ter tuner", | |
881 | .frequency_min_hz = 1 * MHz, | |
882 | .frequency_max_hz = 2500 * MHz, | |
883 | .frequency_step_hz = 25 * kHz, | |
884 | }, | |
885 | .init = helene_init, | |
886 | .release = helene_release, | |
887 | .sleep = helene_sleep, | |
888 | .set_params = helene_set_params, | |
889 | .get_frequency = helene_get_frequency, | |
890 | }; | |
891 | ||
2dc1ed4e AO |
892 | /* power-on tuner |
893 | * call once after reset | |
894 | */ | |
895 | static int helene_x_pon(struct helene_priv *priv) | |
896 | { | |
897 | /* RFIN matching in power save (terrestrial) = ACTIVE */ | |
898 | /* RFIN matching in power save (satellite) = ACTIVE */ | |
899 | u8 dataT[] = { 0x06, 0x00, 0x02, 0x00 }; | |
900 | /* SAT_RF_ACTIVE = true, lnaOff = false, terrRfActive = true */ | |
901 | u8 dataS[] = { 0x05, 0x06 }; | |
902 | u8 cdata[] = {0x7A, 0x01}; | |
903 | u8 data[20]; | |
904 | u8 rdata[2]; | |
905 | ||
906 | /* mode select */ | |
907 | helene_write_reg(priv, 0x01, 0x00); | |
908 | ||
909 | helene_write_reg(priv, 0x67, dataT[3]); | |
910 | helene_write_reg(priv, 0x43, dataS[1]); | |
911 | helene_write_regs(priv, 0x5E, dataT, 3); | |
912 | helene_write_reg(priv, 0x0C, dataS[0]); | |
913 | ||
914 | /* Initial setting for internal logic block */ | |
915 | helene_write_regs(priv, 0x99, cdata, sizeof(cdata)); | |
916 | ||
917 | /* 0x81 - 0x94 */ | |
a00e5f07 KS |
918 | if (priv->xtal == SONY_HELENE_XTAL_16000) |
919 | data[0] = 0x10; /* xtal 16 MHz */ | |
920 | else | |
921 | data[0] = 0x18; /* xtal 24 MHz */ | |
2dc1ed4e AO |
922 | data[1] = (uint8_t)(0x80 | (0x04 & 0x1F)); /* 4 x 25 = 100uA */ |
923 | data[2] = (uint8_t)(0x80 | (0x26 & 0x7F)); /* 38 x 0.25 = 9.5pF */ | |
924 | data[3] = 0x80; /* REFOUT signal output 500mVpp */ | |
925 | data[4] = 0x00; /* GPIO settings */ | |
926 | data[5] = 0x00; /* GPIO settings */ | |
927 | data[6] = 0xC4; /* Clock enable for internal logic block */ | |
928 | data[7] = 0x40; /* Start CPU boot-up */ | |
929 | data[8] = 0x10; /* For burst-write */ | |
930 | ||
931 | /* Setting for internal RFAGC */ | |
932 | data[9] = 0x00; | |
933 | data[10] = 0x45; | |
934 | data[11] = 0x75; | |
935 | ||
936 | data[12] = 0x07; /* Setting for analog block */ | |
937 | ||
938 | /* Initial setting for internal analog block */ | |
939 | data[13] = 0x1C; | |
940 | data[14] = 0x3F; | |
941 | data[15] = 0x02; | |
942 | data[16] = 0x10; | |
943 | data[17] = 0x20; | |
944 | data[18] = 0x0A; | |
945 | data[19] = 0x00; | |
946 | ||
947 | helene_write_regs(priv, 0x81, data, sizeof(data)); | |
948 | ||
949 | /* Setting for internal RFAGC */ | |
950 | helene_write_reg(priv, 0x9B, 0x00); | |
951 | ||
952 | msleep(20); | |
953 | ||
954 | /* Check CPU_STT/CPU_ERR */ | |
955 | helene_read_regs(priv, 0x1A, rdata, sizeof(rdata)); | |
956 | ||
957 | if (rdata[0] != 0x00) { | |
958 | dev_err(&priv->i2c->dev, | |
959 | "HELENE tuner CPU error 0x%x\n", rdata[0]); | |
960 | return -EIO; | |
961 | } | |
962 | ||
963 | /* VCO current setting */ | |
964 | cdata[0] = 0x90; | |
965 | cdata[1] = 0x06; | |
966 | helene_write_regs(priv, 0x17, cdata, sizeof(cdata)); | |
967 | msleep(20); | |
968 | helene_read_reg(priv, 0x19, data); | |
969 | helene_write_reg(priv, 0x95, (uint8_t)((data[0] >> 4) & 0x0F)); | |
970 | ||
971 | /* Disable IF signal output */ | |
972 | helene_write_reg(priv, 0x74, 0x02); | |
973 | ||
974 | /* Standby setting for CPU */ | |
975 | helene_write_reg(priv, 0x88, 0x00); | |
976 | ||
977 | /* Standby setting for internal logic block */ | |
978 | helene_write_reg(priv, 0x87, 0xC0); | |
979 | ||
980 | /* Load capacitance control setting for crystal oscillator */ | |
981 | helene_write_reg(priv, 0x80, 0x01); | |
982 | ||
983 | /* Satellite initial setting */ | |
984 | cdata[0] = 0x07; | |
985 | cdata[1] = 0x00; | |
986 | helene_write_regs(priv, 0x41, cdata, sizeof(cdata)); | |
987 | ||
988 | dev_info(&priv->i2c->dev, | |
989 | "HELENE tuner x_pon done\n"); | |
990 | ||
991 | return 0; | |
992 | } | |
993 | ||
994 | struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe, | |
995 | const struct helene_config *config, | |
996 | struct i2c_adapter *i2c) | |
997 | { | |
998 | struct helene_priv *priv = NULL; | |
999 | ||
1000 | priv = kzalloc(sizeof(struct helene_priv), GFP_KERNEL); | |
1001 | if (priv == NULL) | |
1002 | return NULL; | |
1003 | priv->i2c_address = (config->i2c_address >> 1); | |
1004 | priv->i2c = i2c; | |
1005 | priv->set_tuner_data = config->set_tuner_priv; | |
1006 | priv->set_tuner = config->set_tuner_callback; | |
1007 | priv->xtal = config->xtal; | |
1008 | ||
1009 | if (fe->ops.i2c_gate_ctrl) | |
1010 | fe->ops.i2c_gate_ctrl(fe, 1); | |
1011 | ||
fd322396 CIK |
1012 | if (helene_x_pon(priv) != 0) { |
1013 | kfree(priv); | |
2dc1ed4e | 1014 | return NULL; |
fd322396 | 1015 | } |
2dc1ed4e AO |
1016 | |
1017 | if (fe->ops.i2c_gate_ctrl) | |
1018 | fe->ops.i2c_gate_ctrl(fe, 0); | |
1019 | ||
1020 | memcpy(&fe->ops.tuner_ops, &helene_tuner_ops_s, | |
1021 | sizeof(struct dvb_tuner_ops)); | |
1022 | fe->tuner_priv = priv; | |
1023 | dev_info(&priv->i2c->dev, | |
1024 | "Sony HELENE Sat attached on addr=%x at I2C adapter %p\n", | |
1025 | priv->i2c_address, priv->i2c); | |
1026 | return fe; | |
1027 | } | |
1028 | EXPORT_SYMBOL(helene_attach_s); | |
1029 | ||
1030 | struct dvb_frontend *helene_attach(struct dvb_frontend *fe, | |
1031 | const struct helene_config *config, | |
1032 | struct i2c_adapter *i2c) | |
1033 | { | |
1034 | struct helene_priv *priv = NULL; | |
1035 | ||
1036 | priv = kzalloc(sizeof(struct helene_priv), GFP_KERNEL); | |
1037 | if (priv == NULL) | |
1038 | return NULL; | |
1039 | priv->i2c_address = (config->i2c_address >> 1); | |
1040 | priv->i2c = i2c; | |
1041 | priv->set_tuner_data = config->set_tuner_priv; | |
1042 | priv->set_tuner = config->set_tuner_callback; | |
1043 | priv->xtal = config->xtal; | |
1044 | ||
1045 | if (fe->ops.i2c_gate_ctrl) | |
1046 | fe->ops.i2c_gate_ctrl(fe, 1); | |
1047 | ||
fd322396 CIK |
1048 | if (helene_x_pon(priv) != 0) { |
1049 | kfree(priv); | |
2dc1ed4e | 1050 | return NULL; |
fd322396 | 1051 | } |
2dc1ed4e AO |
1052 | |
1053 | if (fe->ops.i2c_gate_ctrl) | |
1054 | fe->ops.i2c_gate_ctrl(fe, 0); | |
1055 | ||
817dc4b5 | 1056 | memcpy(&fe->ops.tuner_ops, &helene_tuner_ops_t, |
2dc1ed4e AO |
1057 | sizeof(struct dvb_tuner_ops)); |
1058 | fe->tuner_priv = priv; | |
1059 | dev_info(&priv->i2c->dev, | |
1060 | "Sony HELENE Ter attached on addr=%x at I2C adapter %p\n", | |
1061 | priv->i2c_address, priv->i2c); | |
1062 | return fe; | |
1063 | } | |
1064 | EXPORT_SYMBOL(helene_attach); | |
1065 | ||
817dc4b5 KS |
1066 | static int helene_probe(struct i2c_client *client, |
1067 | const struct i2c_device_id *id) | |
1068 | { | |
1069 | struct helene_config *config = client->dev.platform_data; | |
1070 | struct dvb_frontend *fe = config->fe; | |
1071 | struct device *dev = &client->dev; | |
1072 | struct helene_priv *priv; | |
1073 | ||
1074 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | |
1075 | if (!priv) | |
1076 | return -ENOMEM; | |
1077 | ||
1078 | priv->i2c_address = client->addr; | |
1079 | priv->i2c = client->adapter; | |
1080 | priv->set_tuner_data = config->set_tuner_priv; | |
1081 | priv->set_tuner = config->set_tuner_callback; | |
1082 | priv->xtal = config->xtal; | |
1083 | ||
1084 | if (fe->ops.i2c_gate_ctrl) | |
1085 | fe->ops.i2c_gate_ctrl(fe, 1); | |
1086 | ||
1087 | if (helene_x_pon(priv) != 0) | |
1088 | return -EINVAL; | |
1089 | ||
1090 | if (fe->ops.i2c_gate_ctrl) | |
1091 | fe->ops.i2c_gate_ctrl(fe, 0); | |
1092 | ||
1093 | memcpy(&fe->ops.tuner_ops, &helene_tuner_ops, | |
1094 | sizeof(struct dvb_tuner_ops)); | |
1095 | fe->tuner_priv = priv; | |
1096 | i2c_set_clientdata(client, priv); | |
1097 | ||
1098 | dev_info(dev, "Sony HELENE attached on addr=%x at I2C adapter %p\n", | |
1099 | priv->i2c_address, priv->i2c); | |
1100 | ||
1101 | return 0; | |
1102 | } | |
1103 | ||
1104 | static const struct i2c_device_id helene_id[] = { | |
1105 | { "helene", }, | |
1106 | {} | |
1107 | }; | |
1108 | MODULE_DEVICE_TABLE(i2c, helene_id); | |
1109 | ||
1110 | static struct i2c_driver helene_driver = { | |
1111 | .driver = { | |
1112 | .name = "helene", | |
1113 | }, | |
1114 | .probe = helene_probe, | |
1115 | .id_table = helene_id, | |
1116 | }; | |
1117 | module_i2c_driver(helene_driver); | |
1118 | ||
2dc1ed4e AO |
1119 | MODULE_DESCRIPTION("Sony HELENE Sat/Ter tuner driver"); |
1120 | MODULE_AUTHOR("Abylay Ospan <aospan@netup.ru>"); | |
1121 | MODULE_LICENSE("GPL"); |