diff options
author | Antti Palosaari <crope@iki.fi> | 2008-09-15 14:01:52 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-12 07:37:02 -0400 |
commit | 825b96708054ca16d6e4d56a29326d3b2cdd697d (patch) | |
tree | 82868b44a2bddc23c0485546d9f381d21a2d0992 /drivers/media/dvb/frontends/af9013.c | |
parent | 6e623433f7f566d8aca64c519a19c2f7bbb686be (diff) |
V4L/DVB (8971): initial driver for af9013 demodulator
- initial driver for the Afatech AF9013 demodulator
Signed-off-by: Antti Palosaari <crope@iki.fi>
[mchehab.redhat.com: having a global var called 'debug' is not a good idea. rename it to af9013_debug]
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/frontends/af9013.c')
-rw-r--r-- | drivers/media/dvb/frontends/af9013.c | 1691 |
1 files changed, 1691 insertions, 0 deletions
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c new file mode 100644 index 000000000000..9f2129d544c5 --- /dev/null +++ b/drivers/media/dvb/frontends/af9013.c | |||
@@ -0,0 +1,1691 @@ | |||
1 | /* | ||
2 | * DVB USB Linux driver for Afatech AF9015 DVB-T USB2.0 receiver | ||
3 | * | ||
4 | * Copyright (C) 2007 Antti Palosaari <crope@iki.fi> | ||
5 | * | ||
6 | * Thanks to Afatech who kindly provided information. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/moduleparam.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/string.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/firmware.h> | ||
32 | |||
33 | #include "dvb_frontend.h" | ||
34 | #include "af9013_priv.h" | ||
35 | #include "af9013.h" | ||
36 | |||
37 | int af9013_debug; | ||
38 | |||
39 | struct af9013_state { | ||
40 | struct i2c_adapter *i2c; | ||
41 | struct dvb_frontend frontend; | ||
42 | |||
43 | struct af9013_config config; | ||
44 | |||
45 | u16 signal_strength; | ||
46 | u32 ber; | ||
47 | u32 ucblocks; | ||
48 | u16 snr; | ||
49 | u32 frequency; | ||
50 | unsigned long next_statistics_check; | ||
51 | }; | ||
52 | |||
53 | static u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff }; | ||
54 | |||
55 | static int af9013_write_regs(struct af9013_state *state, u8 mbox, u16 reg, | ||
56 | u8 *val, u8 len) | ||
57 | { | ||
58 | u8 buf[3+len]; | ||
59 | struct i2c_msg msg = { | ||
60 | .addr = state->config.demod_address, | ||
61 | .flags = 0, | ||
62 | .len = sizeof(buf), | ||
63 | .buf = buf }; | ||
64 | |||
65 | buf[0] = reg >> 8; | ||
66 | buf[1] = reg & 0xff; | ||
67 | buf[2] = mbox; | ||
68 | memcpy(&buf[3], val, len); | ||
69 | |||
70 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { | ||
71 | warn("I2C write failed reg:%04x len:%d", reg, len); | ||
72 | return -EREMOTEIO; | ||
73 | } | ||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static int af9013_write_ofdm_regs(struct af9013_state *state, u16 reg, u8 *val, | ||
78 | u8 len) | ||
79 | { | ||
80 | u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(0 << 6)|(0 << 7); | ||
81 | return af9013_write_regs(state, mbox, reg, val, len); | ||
82 | } | ||
83 | |||
84 | static int af9013_write_ofsm_regs(struct af9013_state *state, u16 reg, u8 *val, | ||
85 | u8 len) | ||
86 | { | ||
87 | u8 mbox = (1 << 0)|(1 << 1)|((len - 1) << 2)|(1 << 6)|(1 << 7); | ||
88 | return af9013_write_regs(state, mbox, reg, val, len); | ||
89 | } | ||
90 | |||
91 | /* write single register */ | ||
92 | static int af9013_write_reg(struct af9013_state *state, u16 reg, u8 val) | ||
93 | { | ||
94 | return af9013_write_ofdm_regs(state, reg, &val, 1); | ||
95 | } | ||
96 | |||
97 | /* read single register */ | ||
98 | static int af9013_read_reg(struct af9013_state *state, u16 reg, u8 *val) | ||
99 | { | ||
100 | u8 obuf[3] = { reg >> 8, reg & 0xff, 0 }; | ||
101 | u8 ibuf[1]; | ||
102 | struct i2c_msg msg[2] = { | ||
103 | { | ||
104 | .addr = state->config.demod_address, | ||
105 | .flags = 0, | ||
106 | .len = sizeof(obuf), | ||
107 | .buf = obuf | ||
108 | }, { | ||
109 | .addr = state->config.demod_address, | ||
110 | .flags = I2C_M_RD, | ||
111 | .len = sizeof(ibuf), | ||
112 | .buf = ibuf | ||
113 | } | ||
114 | }; | ||
115 | |||
116 | if (i2c_transfer(state->i2c, msg, 2) != 2) { | ||
117 | warn("I2C read failed reg:%04x", reg); | ||
118 | return -EREMOTEIO; | ||
119 | } | ||
120 | *val = ibuf[0]; | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int af9013_write_reg_bits(struct af9013_state *state, u16 reg, u8 pos, | ||
125 | u8 len, u8 val) | ||
126 | { | ||
127 | int ret; | ||
128 | u8 tmp, mask; | ||
129 | |||
130 | ret = af9013_read_reg(state, reg, &tmp); | ||
131 | if (ret) | ||
132 | return ret; | ||
133 | |||
134 | mask = regmask[len - 1] << pos; | ||
135 | tmp = (tmp & ~mask) | ((val << pos) & mask); | ||
136 | |||
137 | return af9013_write_reg(state, reg, tmp); | ||
138 | } | ||
139 | |||
140 | static int af9013_read_reg_bits(struct af9013_state *state, u16 reg, u8 pos, | ||
141 | u8 len, u8 *val) | ||
142 | { | ||
143 | int ret; | ||
144 | u8 tmp; | ||
145 | |||
146 | ret = af9013_read_reg(state, reg, &tmp); | ||
147 | if (ret) | ||
148 | return ret; | ||
149 | *val = (tmp >> pos) & regmask[len - 1]; | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int af9013_set_gpio(struct af9013_state *state, u8 gpio, u8 gpioval) | ||
154 | { | ||
155 | int ret; | ||
156 | u8 pos; | ||
157 | u16 addr; | ||
158 | deb_info("%s: gpio:%d gpioval:%02x\n", __func__, gpio, gpioval); | ||
159 | |||
160 | /* GPIO0 & GPIO1 0xd735 | ||
161 | GPIO2 & GPIO3 0xd736 */ | ||
162 | |||
163 | switch (gpio) { | ||
164 | case 0: | ||
165 | case 1: | ||
166 | addr = 0xd735; | ||
167 | break; | ||
168 | case 2: | ||
169 | case 3: | ||
170 | addr = 0xd736; | ||
171 | break; | ||
172 | |||
173 | default: | ||
174 | err("invalid gpio:%d\n", gpio); | ||
175 | ret = -EINVAL; | ||
176 | goto error; | ||
177 | }; | ||
178 | |||
179 | switch (gpio) { | ||
180 | case 0: | ||
181 | case 2: | ||
182 | pos = 0; | ||
183 | break; | ||
184 | case 1: | ||
185 | case 3: | ||
186 | default: | ||
187 | pos = 4; | ||
188 | break; | ||
189 | }; | ||
190 | |||
191 | ret = af9013_write_reg_bits(state, addr, pos, 4, gpioval); | ||
192 | |||
193 | error: | ||
194 | return ret; | ||
195 | } | ||
196 | |||
197 | static u32 af913_div(u32 a, u32 b, u32 x) | ||
198 | { | ||
199 | u32 r = 0, c = 0, i; | ||
200 | deb_info("%s: a:%d b:%d x:%d\n", __func__, a, b, x); | ||
201 | |||
202 | if (a > b) { | ||
203 | c = a / b; | ||
204 | a = a - c * b; | ||
205 | } | ||
206 | |||
207 | for (i = 0; i < x; i++) { | ||
208 | if (a >= b) { | ||
209 | r += 1; | ||
210 | a -= b; | ||
211 | } | ||
212 | a <<= 1; | ||
213 | r <<= 1; | ||
214 | } | ||
215 | r = (c << (u32)x) + r; | ||
216 | |||
217 | deb_info("%s: a:%d b:%d x:%d r:%d r:%x\n", __func__, a, b, x, r, r); | ||
218 | return r; | ||
219 | } | ||
220 | |||
221 | static int af9013_set_coeff(struct af9013_state *state, fe_bandwidth_t bw) | ||
222 | { | ||
223 | int ret = 0; | ||
224 | u8 i = 0; | ||
225 | u8 buf[24]; | ||
226 | u32 ns_coeff1_2048nu; | ||
227 | u32 ns_coeff1_8191nu; | ||
228 | u32 ns_coeff1_8192nu; | ||
229 | u32 ns_coeff1_8193nu; | ||
230 | u32 ns_coeff2_2k; | ||
231 | u32 ns_coeff2_8k; | ||
232 | |||
233 | deb_info("%s: adc_clock:%d bw:%d\n", __func__, | ||
234 | state->config.adc_clock, bw); | ||
235 | |||
236 | switch (state->config.adc_clock) { | ||
237 | case 28800: /* 28.800 MHz */ | ||
238 | switch (bw) { | ||
239 | case BANDWIDTH_6_MHZ: | ||
240 | ns_coeff1_2048nu = 0x01e79e7a; | ||
241 | ns_coeff1_8191nu = 0x0079eb6e; | ||
242 | ns_coeff1_8192nu = 0x0079e79e; | ||
243 | ns_coeff1_8193nu = 0x0079e3cf; | ||
244 | ns_coeff2_2k = 0x00f3cf3d; | ||
245 | ns_coeff2_8k = 0x003cf3cf; | ||
246 | break; | ||
247 | case BANDWIDTH_7_MHZ: | ||
248 | ns_coeff1_2048nu = 0x0238e38e; | ||
249 | ns_coeff1_8191nu = 0x008e3d55; | ||
250 | ns_coeff1_8192nu = 0x008e38e4; | ||
251 | ns_coeff1_8193nu = 0x008e3472; | ||
252 | ns_coeff2_2k = 0x011c71c7; | ||
253 | ns_coeff2_8k = 0x00471c72; | ||
254 | break; | ||
255 | case BANDWIDTH_8_MHZ: | ||
256 | ns_coeff1_2048nu = 0x028a28a3; | ||
257 | ns_coeff1_8191nu = 0x00a28f3d; | ||
258 | ns_coeff1_8192nu = 0x00a28a29; | ||
259 | ns_coeff1_8193nu = 0x00a28514; | ||
260 | ns_coeff2_2k = 0x01451451; | ||
261 | ns_coeff2_8k = 0x00514514; | ||
262 | break; | ||
263 | default: | ||
264 | ret = -EINVAL; | ||
265 | } | ||
266 | break; | ||
267 | case 20480: /* 20.480 MHz */ | ||
268 | switch (bw) { | ||
269 | case BANDWIDTH_6_MHZ: | ||
270 | ns_coeff1_2048nu = 0x02adb6dc; | ||
271 | ns_coeff1_8191nu = 0x00ab7313; | ||
272 | ns_coeff1_8192nu = 0x00ab6db7; | ||
273 | ns_coeff1_8193nu = 0x00ab685c; | ||
274 | ns_coeff2_2k = 0x0156db6e; | ||
275 | ns_coeff2_8k = 0x0055b6dc; | ||
276 | break; | ||
277 | case BANDWIDTH_7_MHZ: | ||
278 | ns_coeff1_2048nu = 0x03200001; | ||
279 | ns_coeff1_8191nu = 0x00c80640; | ||
280 | ns_coeff1_8192nu = 0x00c80000; | ||
281 | ns_coeff1_8193nu = 0x00c7f9c0; | ||
282 | ns_coeff2_2k = 0x01900000; | ||
283 | ns_coeff2_8k = 0x00640000; | ||
284 | break; | ||
285 | case BANDWIDTH_8_MHZ: | ||
286 | ns_coeff1_2048nu = 0x03924926; | ||
287 | ns_coeff1_8191nu = 0x00e4996e; | ||
288 | ns_coeff1_8192nu = 0x00e49249; | ||
289 | ns_coeff1_8193nu = 0x00e48b25; | ||
290 | ns_coeff2_2k = 0x01c92493; | ||
291 | ns_coeff2_8k = 0x00724925; | ||
292 | break; | ||
293 | default: | ||
294 | ret = -EINVAL; | ||
295 | } | ||
296 | break; | ||
297 | case 28000: /* 28.000 MHz */ | ||
298 | switch (bw) { | ||
299 | case BANDWIDTH_6_MHZ: | ||
300 | ns_coeff1_2048nu = 0x01f58d10; | ||
301 | ns_coeff1_8191nu = 0x007d672f; | ||
302 | ns_coeff1_8192nu = 0x007d6344; | ||
303 | ns_coeff1_8193nu = 0x007d5f59; | ||
304 | ns_coeff2_2k = 0x00fac688; | ||
305 | ns_coeff2_8k = 0x003eb1a2; | ||
306 | break; | ||
307 | case BANDWIDTH_7_MHZ: | ||
308 | ns_coeff1_2048nu = 0x02492492; | ||
309 | ns_coeff1_8191nu = 0x00924db7; | ||
310 | ns_coeff1_8192nu = 0x00924925; | ||
311 | ns_coeff1_8193nu = 0x00924492; | ||
312 | ns_coeff2_2k = 0x01249249; | ||
313 | ns_coeff2_8k = 0x00492492; | ||
314 | break; | ||
315 | case BANDWIDTH_8_MHZ: | ||
316 | ns_coeff1_2048nu = 0x029cbc15; | ||
317 | ns_coeff1_8191nu = 0x00a7343f; | ||
318 | ns_coeff1_8192nu = 0x00a72f05; | ||
319 | ns_coeff1_8193nu = 0x00a729cc; | ||
320 | ns_coeff2_2k = 0x014e5e0a; | ||
321 | ns_coeff2_8k = 0x00539783; | ||
322 | break; | ||
323 | default: | ||
324 | ret = -EINVAL; | ||
325 | } | ||
326 | break; | ||
327 | case 25000: /* 25.000 MHz */ | ||
328 | switch (bw) { | ||
329 | case BANDWIDTH_6_MHZ: | ||
330 | ns_coeff1_2048nu = 0x0231bcb5; | ||
331 | ns_coeff1_8191nu = 0x008c7391; | ||
332 | ns_coeff1_8192nu = 0x008c6f2d; | ||
333 | ns_coeff1_8193nu = 0x008c6aca; | ||
334 | ns_coeff2_2k = 0x0118de5b; | ||
335 | ns_coeff2_8k = 0x00463797; | ||
336 | break; | ||
337 | case BANDWIDTH_7_MHZ: | ||
338 | ns_coeff1_2048nu = 0x028f5c29; | ||
339 | ns_coeff1_8191nu = 0x00a3dc29; | ||
340 | ns_coeff1_8192nu = 0x00a3d70a; | ||
341 | ns_coeff1_8193nu = 0x00a3d1ec; | ||
342 | ns_coeff2_2k = 0x0147ae14; | ||
343 | ns_coeff2_8k = 0x0051eb85; | ||
344 | break; | ||
345 | case BANDWIDTH_8_MHZ: | ||
346 | ns_coeff1_2048nu = 0x02ecfb9d; | ||
347 | ns_coeff1_8191nu = 0x00bb44c1; | ||
348 | ns_coeff1_8192nu = 0x00bb3ee7; | ||
349 | ns_coeff1_8193nu = 0x00bb390d; | ||
350 | ns_coeff2_2k = 0x01767dce; | ||
351 | ns_coeff2_8k = 0x005d9f74; | ||
352 | break; | ||
353 | default: | ||
354 | ret = -EINVAL; | ||
355 | } | ||
356 | break; | ||
357 | default: | ||
358 | err("invalid xtal"); | ||
359 | return -EINVAL; | ||
360 | } | ||
361 | if (ret) { | ||
362 | err("invalid bandwidth"); | ||
363 | return ret; | ||
364 | } | ||
365 | |||
366 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x03000000) >> 24); | ||
367 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x00ff0000) >> 16); | ||
368 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x0000ff00) >> 8); | ||
369 | buf[i++] = (u8) ((ns_coeff1_2048nu & 0x000000ff)); | ||
370 | buf[i++] = (u8) ((ns_coeff2_2k & 0x01c00000) >> 22); | ||
371 | buf[i++] = (u8) ((ns_coeff2_2k & 0x003fc000) >> 14); | ||
372 | buf[i++] = (u8) ((ns_coeff2_2k & 0x00003fc0) >> 6); | ||
373 | buf[i++] = (u8) ((ns_coeff2_2k & 0x0000003f)); | ||
374 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x03000000) >> 24); | ||
375 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x00ffc000) >> 16); | ||
376 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x0000ff00) >> 8); | ||
377 | buf[i++] = (u8) ((ns_coeff1_8191nu & 0x000000ff)); | ||
378 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x03000000) >> 24); | ||
379 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x00ffc000) >> 16); | ||
380 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x0000ff00) >> 8); | ||
381 | buf[i++] = (u8) ((ns_coeff1_8192nu & 0x000000ff)); | ||
382 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x03000000) >> 24); | ||
383 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x00ffc000) >> 16); | ||
384 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x0000ff00) >> 8); | ||
385 | buf[i++] = (u8) ((ns_coeff1_8193nu & 0x000000ff)); | ||
386 | buf[i++] = (u8) ((ns_coeff2_8k & 0x01c00000) >> 22); | ||
387 | buf[i++] = (u8) ((ns_coeff2_8k & 0x003fc000) >> 14); | ||
388 | buf[i++] = (u8) ((ns_coeff2_8k & 0x00003fc0) >> 6); | ||
389 | buf[i++] = (u8) ((ns_coeff2_8k & 0x0000003f)); | ||
390 | |||
391 | deb_info("%s: coeff:", __func__); | ||
392 | debug_dump(buf, sizeof(buf), deb_info); | ||
393 | |||
394 | /* program */ | ||
395 | for (i = 0; i < sizeof(buf); i++) { | ||
396 | ret = af9013_write_reg(state, 0xae00 + i, buf[i]); | ||
397 | if (ret) | ||
398 | break; | ||
399 | } | ||
400 | |||
401 | return ret; | ||
402 | } | ||
403 | |||
404 | static int af9013_set_adc_ctrl(struct af9013_state *state) | ||
405 | { | ||
406 | int ret; | ||
407 | u8 buf[3], tmp, i; | ||
408 | u32 adc_cw; | ||
409 | |||
410 | deb_info("%s: adc_clock:%d\n", __func__, state->config.adc_clock); | ||
411 | |||
412 | /* adc frequency type */ | ||
413 | switch (state->config.adc_clock) { | ||
414 | case 28800: /* 28.800 MHz */ | ||
415 | tmp = 0; | ||
416 | break; | ||
417 | case 20480: /* 20.480 MHz */ | ||
418 | tmp = 1; | ||
419 | break; | ||
420 | case 28000: /* 28.000 MHz */ | ||
421 | tmp = 2; | ||
422 | break; | ||
423 | case 25000: /* 25.000 MHz */ | ||
424 | tmp = 3; | ||
425 | break; | ||
426 | default: | ||
427 | err("invalid xtal"); | ||
428 | return -EINVAL; | ||
429 | } | ||
430 | |||
431 | adc_cw = af913_div(state->config.adc_clock*1000, 1000000ul, 19ul); | ||
432 | |||
433 | buf[0] = (u8) ((adc_cw & 0x000000ff)); | ||
434 | buf[1] = (u8) ((adc_cw & 0x0000ff00) >> 8); | ||
435 | buf[2] = (u8) ((adc_cw & 0x00ff0000) >> 16); | ||
436 | |||
437 | deb_info("%s: adc_cw:", __func__); | ||
438 | debug_dump(buf, sizeof(buf), deb_info); | ||
439 | |||
440 | /* program */ | ||
441 | for (i = 0; i < sizeof(buf); i++) { | ||
442 | ret = af9013_write_reg(state, 0xd180 + i, buf[i]); | ||
443 | if (ret) | ||
444 | goto error; | ||
445 | } | ||
446 | ret = af9013_write_reg_bits(state, 0x9bd2, 0, 4, tmp); | ||
447 | error: | ||
448 | return ret; | ||
449 | } | ||
450 | |||
451 | static int af9013_set_freq_ctrl(struct af9013_state *state, fe_bandwidth_t bw) | ||
452 | { | ||
453 | int ret; | ||
454 | u16 addr; | ||
455 | u8 buf[3], i, j; | ||
456 | u32 adc_freq, freq_cw; | ||
457 | s8 bfs_spec_inv; | ||
458 | int if_sample_freq; | ||
459 | |||
460 | for (j = 0; j < 3; j++) { | ||
461 | if (j == 0) { | ||
462 | addr = 0xd140; /* fcw normal */ | ||
463 | bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1; | ||
464 | } else if (j == 1) { | ||
465 | addr = 0x9be7; /* fcw dummy ram */ | ||
466 | bfs_spec_inv = state->config.rf_spec_inv ? -1 : 1; | ||
467 | } else { | ||
468 | addr = 0x9bea; /* fcw inverted */ | ||
469 | bfs_spec_inv = state->config.rf_spec_inv ? 1 : -1; | ||
470 | } | ||
471 | |||
472 | adc_freq = state->config.adc_clock * 1000; | ||
473 | if_sample_freq = state->config.tuner_if * 1000; | ||
474 | |||
475 | /* TDA18271 uses different sampling freq for every bw */ | ||
476 | if (state->config.tuner == AF9013_TUNER_TDA18271) { | ||
477 | switch (bw) { | ||
478 | case BANDWIDTH_6_MHZ: | ||
479 | if_sample_freq = 3300000; /* 3.3 MHz */ | ||
480 | break; | ||
481 | case BANDWIDTH_7_MHZ: | ||
482 | if_sample_freq = 3800000; /* 3.8 MHz */ | ||
483 | break; | ||
484 | case BANDWIDTH_8_MHZ: | ||
485 | default: | ||
486 | if_sample_freq = 4300000; /* 4.3 MHz */ | ||
487 | break; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | while (if_sample_freq > (adc_freq / 2)) | ||
492 | if_sample_freq = if_sample_freq - adc_freq; | ||
493 | |||
494 | if (if_sample_freq >= 0) | ||
495 | bfs_spec_inv = bfs_spec_inv * (-1); | ||
496 | else | ||
497 | if_sample_freq = if_sample_freq * (-1); | ||
498 | |||
499 | freq_cw = af913_div(if_sample_freq, adc_freq, 23ul); | ||
500 | |||
501 | if (bfs_spec_inv == -1) | ||
502 | freq_cw = 0x00800000 - freq_cw; | ||
503 | |||
504 | buf[0] = (u8) ((freq_cw & 0x000000ff)); | ||
505 | buf[1] = (u8) ((freq_cw & 0x0000ff00) >> 8); | ||
506 | buf[2] = (u8) ((freq_cw & 0x007f0000) >> 16); | ||
507 | |||
508 | |||
509 | deb_info("%s: freq_cw:", __func__); | ||
510 | debug_dump(buf, sizeof(buf), deb_info); | ||
511 | |||
512 | /* program */ | ||
513 | for (i = 0; i < sizeof(buf); i++) { | ||
514 | ret = af9013_write_reg(state, addr++, buf[i]); | ||
515 | if (ret) | ||
516 | goto error; | ||
517 | } | ||
518 | } | ||
519 | error: | ||
520 | return ret; | ||
521 | } | ||
522 | |||
523 | static int af9013_set_ofdm_params(struct af9013_state *state, | ||
524 | struct dvb_ofdm_parameters *params, u8 *auto_mode) | ||
525 | { | ||
526 | int ret; | ||
527 | u8 i, buf[3] = {0, 0, 0}; | ||
528 | *auto_mode = 0; /* set if parameters are requested to auto set */ | ||
529 | |||
530 | switch (params->transmission_mode) { | ||
531 | case TRANSMISSION_MODE_AUTO: | ||
532 | *auto_mode = 1; | ||
533 | case TRANSMISSION_MODE_2K: | ||
534 | break; | ||
535 | case TRANSMISSION_MODE_8K: | ||
536 | buf[0] |= (1 << 0); | ||
537 | break; | ||
538 | default: | ||
539 | return -EINVAL; | ||
540 | } | ||
541 | |||
542 | switch (params->guard_interval) { | ||
543 | case GUARD_INTERVAL_AUTO: | ||
544 | *auto_mode = 1; | ||
545 | case GUARD_INTERVAL_1_32: | ||
546 | break; | ||
547 | case GUARD_INTERVAL_1_16: | ||
548 | buf[0] |= (1 << 2); | ||
549 | break; | ||
550 | case GUARD_INTERVAL_1_8: | ||
551 | buf[0] |= (2 << 2); | ||
552 | break; | ||
553 | case GUARD_INTERVAL_1_4: | ||
554 | buf[0] |= (3 << 2); | ||
555 | break; | ||
556 | default: | ||
557 | return -EINVAL; | ||
558 | } | ||
559 | |||
560 | switch (params->hierarchy_information) { | ||
561 | case HIERARCHY_AUTO: | ||
562 | *auto_mode = 1; | ||
563 | case HIERARCHY_NONE: | ||
564 | break; | ||
565 | case HIERARCHY_1: | ||
566 | buf[0] |= (1 << 4); | ||
567 | break; | ||
568 | case HIERARCHY_2: | ||
569 | buf[0] |= (2 << 4); | ||
570 | break; | ||
571 | case HIERARCHY_4: | ||
572 | buf[0] |= (3 << 4); | ||
573 | break; | ||
574 | default: | ||
575 | return -EINVAL; | ||
576 | }; | ||
577 | |||
578 | switch (params->constellation) { | ||
579 | case QAM_AUTO: | ||
580 | *auto_mode = 1; | ||
581 | case QPSK: | ||
582 | break; | ||
583 | case QAM_16: | ||
584 | buf[1] |= (1 << 6); | ||
585 | break; | ||
586 | case QAM_64: | ||
587 | buf[1] |= (2 << 6); | ||
588 | break; | ||
589 | default: | ||
590 | return -EINVAL; | ||
591 | } | ||
592 | |||
593 | /* Use HP. How and which case we can switch to LP? */ | ||
594 | buf[1] |= (1 << 4); | ||
595 | |||
596 | switch (params->code_rate_HP) { | ||
597 | case FEC_AUTO: | ||
598 | *auto_mode = 1; | ||
599 | case FEC_1_2: | ||
600 | break; | ||
601 | case FEC_2_3: | ||
602 | buf[2] |= (1 << 0); | ||
603 | break; | ||
604 | case FEC_3_4: | ||
605 | buf[2] |= (2 << 0); | ||
606 | break; | ||
607 | case FEC_5_6: | ||
608 | buf[2] |= (3 << 0); | ||
609 | break; | ||
610 | case FEC_7_8: | ||
611 | buf[2] |= (4 << 0); | ||
612 | break; | ||
613 | default: | ||
614 | return -EINVAL; | ||
615 | } | ||
616 | |||
617 | switch (params->code_rate_LP) { | ||
618 | case FEC_AUTO: | ||
619 | /* if HIERARCHY_NONE and FEC_NONE then LP FEC is set to FEC_AUTO | ||
620 | by dvb_frontend.c for compatibility */ | ||
621 | if (params->hierarchy_information != HIERARCHY_NONE) | ||
622 | *auto_mode = 1; | ||
623 | case FEC_1_2: | ||
624 | break; | ||
625 | case FEC_2_3: | ||
626 | buf[2] |= (1 << 3); | ||
627 | break; | ||
628 | case FEC_3_4: | ||
629 | buf[2] |= (2 << 3); | ||
630 | break; | ||
631 | case FEC_5_6: | ||
632 | buf[2] |= (3 << 3); | ||
633 | break; | ||
634 | case FEC_7_8: | ||
635 | buf[2] |= (4 << 3); | ||
636 | break; | ||
637 | case FEC_NONE: | ||
638 | if (params->hierarchy_information == HIERARCHY_AUTO) | ||
639 | break; | ||
640 | default: | ||
641 | return -EINVAL; | ||
642 | } | ||
643 | |||
644 | switch (params->bandwidth) { | ||
645 | case BANDWIDTH_6_MHZ: | ||
646 | break; | ||
647 | case BANDWIDTH_7_MHZ: | ||
648 | buf[1] |= (1 << 2); | ||
649 | break; | ||
650 | case BANDWIDTH_8_MHZ: | ||
651 | buf[1] |= (2 << 2); | ||
652 | break; | ||
653 | default: | ||
654 | return -EINVAL; | ||
655 | } | ||
656 | |||
657 | /* program */ | ||
658 | for (i = 0; i < sizeof(buf); i++) { | ||
659 | ret = af9013_write_reg(state, 0xd3c0 + i, buf[i]); | ||
660 | if (ret) | ||
661 | break; | ||
662 | } | ||
663 | |||
664 | return ret; | ||
665 | } | ||
666 | |||
667 | static int af9013_reset(struct af9013_state *state, u8 sleep) | ||
668 | { | ||
669 | int ret; | ||
670 | u8 tmp, i; | ||
671 | deb_info("%s\n", __func__); | ||
672 | |||
673 | /* enable OFDM reset */ | ||
674 | ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 1); | ||
675 | if (ret) | ||
676 | goto error; | ||
677 | |||
678 | /* start reset mechanism */ | ||
679 | ret = af9013_write_reg(state, 0xaeff, 1); | ||
680 | if (ret) | ||
681 | goto error; | ||
682 | |||
683 | /* reset is done when bit 1 is set */ | ||
684 | for (i = 0; i < 150; i++) { | ||
685 | ret = af9013_read_reg_bits(state, 0xd417, 1, 1, &tmp); | ||
686 | if (ret) | ||
687 | goto error; | ||
688 | if (tmp) | ||
689 | break; /* reset done */ | ||
690 | msleep(10); | ||
691 | } | ||
692 | if (!tmp) | ||
693 | return -ETIMEDOUT; | ||
694 | |||
695 | /* don't clear reset when going to sleep */ | ||
696 | if (!sleep) { | ||
697 | /* clear OFDM reset */ | ||
698 | ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); | ||
699 | if (ret) | ||
700 | goto error; | ||
701 | |||
702 | /* disable OFDM reset */ | ||
703 | ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); | ||
704 | } | ||
705 | error: | ||
706 | return ret; | ||
707 | } | ||
708 | |||
709 | static int af9013_power_ctrl(struct af9013_state *state, u8 onoff) | ||
710 | { | ||
711 | int ret; | ||
712 | deb_info("%s: onoff:%d\n", __func__, onoff); | ||
713 | |||
714 | if (onoff) { | ||
715 | /* power on */ | ||
716 | ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 0); | ||
717 | if (ret) | ||
718 | goto error; | ||
719 | ret = af9013_write_reg_bits(state, 0xd417, 1, 1, 0); | ||
720 | if (ret) | ||
721 | goto error; | ||
722 | ret = af9013_write_reg_bits(state, 0xd417, 4, 1, 0); | ||
723 | } else { | ||
724 | /* power off */ | ||
725 | ret = af9013_reset(state, 1); | ||
726 | if (ret) | ||
727 | goto error; | ||
728 | ret = af9013_write_reg_bits(state, 0xd73a, 3, 1, 1); | ||
729 | } | ||
730 | error: | ||
731 | return ret; | ||
732 | } | ||
733 | |||
734 | static int af9013_lock_led(struct af9013_state *state, u8 onoff) | ||
735 | { | ||
736 | deb_info("%s: onoff:%d\n", __func__, onoff); | ||
737 | |||
738 | return af9013_write_reg_bits(state, 0xd730, 0, 1, onoff); | ||
739 | } | ||
740 | |||
741 | static int af9013_set_frontend(struct dvb_frontend *fe, | ||
742 | struct dvb_frontend_parameters *params) | ||
743 | { | ||
744 | struct af9013_state *state = fe->demodulator_priv; | ||
745 | int ret; | ||
746 | u8 auto_mode; /* auto set TPS */ | ||
747 | |||
748 | deb_info("%s: freq:%d bw:%d\n", __func__, params->frequency, | ||
749 | params->u.ofdm.bandwidth); | ||
750 | |||
751 | state->frequency = params->frequency; | ||
752 | |||
753 | /* program CFOE coefficients */ | ||
754 | ret = af9013_set_coeff(state, params->u.ofdm.bandwidth); | ||
755 | if (ret) | ||
756 | goto error; | ||
757 | |||
758 | /* program frequency control */ | ||
759 | ret = af9013_set_freq_ctrl(state, params->u.ofdm.bandwidth); | ||
760 | if (ret) | ||
761 | goto error; | ||
762 | |||
763 | /* clear TPS lock flag (inverted flag) */ | ||
764 | ret = af9013_write_reg_bits(state, 0xd330, 3, 1, 1); | ||
765 | if (ret) | ||
766 | goto error; | ||
767 | |||
768 | /* clear MPEG2 lock flag */ | ||
769 | ret = af9013_write_reg_bits(state, 0xd507, 6, 1, 0); | ||
770 | if (ret) | ||
771 | goto error; | ||
772 | |||
773 | /* empty channel function */ | ||
774 | ret = af9013_write_reg_bits(state, 0x9bfe, 0, 1, 0); | ||
775 | if (ret) | ||
776 | goto error; | ||
777 | |||
778 | /* empty DVB-T channel function */ | ||
779 | ret = af9013_write_reg_bits(state, 0x9bc2, 0, 1, 0); | ||
780 | if (ret) | ||
781 | goto error; | ||
782 | |||
783 | /* program tuner */ | ||
784 | if (fe->ops.tuner_ops.set_params) | ||
785 | fe->ops.tuner_ops.set_params(fe, params); | ||
786 | |||
787 | /* program TPS and bandwidth, check if auto mode needed */ | ||
788 | ret = af9013_set_ofdm_params(state, ¶ms->u.ofdm, &auto_mode); | ||
789 | if (ret) | ||
790 | goto error; | ||
791 | |||
792 | if (auto_mode) { | ||
793 | /* clear easy mode flag */ | ||
794 | ret = af9013_write_reg(state, 0xaefd, 0); | ||
795 | deb_info("%s: auto TPS\n", __func__); | ||
796 | } else { | ||
797 | /* set easy mode flag */ | ||
798 | ret = af9013_write_reg(state, 0xaefd, 1); | ||
799 | if (ret) | ||
800 | goto error; | ||
801 | ret = af9013_write_reg(state, 0xaefe, 0); | ||
802 | deb_info("%s: manual TPS\n", __func__); | ||
803 | } | ||
804 | if (ret) | ||
805 | goto error; | ||
806 | |||
807 | /* everything is set, lets try to receive channel - OFSM GO! */ | ||
808 | ret = af9013_write_reg(state, 0xffff, 0); | ||
809 | if (ret) | ||
810 | goto error; | ||
811 | |||
812 | error: | ||
813 | return ret; | ||
814 | } | ||
815 | |||
816 | static int af9013_get_frontend(struct dvb_frontend *fe, | ||
817 | struct dvb_frontend_parameters *p) | ||
818 | { | ||
819 | struct af9013_state *state = fe->demodulator_priv; | ||
820 | int ret; | ||
821 | u8 i, buf[3]; | ||
822 | deb_info("%s\n", __func__); | ||
823 | |||
824 | /* read TPS registers */ | ||
825 | for (i = 0; i < 3; i++) { | ||
826 | ret = af9013_read_reg(state, 0xd3c0 + i, &buf[i]); | ||
827 | if (ret) | ||
828 | goto error; | ||
829 | } | ||
830 | |||
831 | switch ((buf[1] >> 6) & 3) { | ||
832 | case 0: | ||
833 | p->u.ofdm.constellation = QPSK; | ||
834 | break; | ||
835 | case 1: | ||
836 | p->u.ofdm.constellation = QAM_16; | ||
837 | break; | ||
838 | case 2: | ||
839 | p->u.ofdm.constellation = QAM_64; | ||
840 | break; | ||
841 | } | ||
842 | |||
843 | switch ((buf[0] >> 0) & 3) { | ||
844 | case 0: | ||
845 | p->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; | ||
846 | break; | ||
847 | case 1: | ||
848 | p->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; | ||
849 | } | ||
850 | |||
851 | switch ((buf[0] >> 2) & 3) { | ||
852 | case 0: | ||
853 | p->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; | ||
854 | break; | ||
855 | case 1: | ||
856 | p->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; | ||
857 | break; | ||
858 | case 2: | ||
859 | p->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; | ||
860 | break; | ||
861 | case 3: | ||
862 | p->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; | ||
863 | break; | ||
864 | } | ||
865 | |||
866 | switch ((buf[0] >> 4) & 7) { | ||
867 | case 0: | ||
868 | p->u.ofdm.hierarchy_information = HIERARCHY_NONE; | ||
869 | break; | ||
870 | case 1: | ||
871 | p->u.ofdm.hierarchy_information = HIERARCHY_1; | ||
872 | break; | ||
873 | case 2: | ||
874 | p->u.ofdm.hierarchy_information = HIERARCHY_2; | ||
875 | break; | ||
876 | case 3: | ||
877 | p->u.ofdm.hierarchy_information = HIERARCHY_4; | ||
878 | break; | ||
879 | } | ||
880 | |||
881 | switch ((buf[2] >> 0) & 7) { | ||
882 | case 0: | ||
883 | p->u.ofdm.code_rate_HP = FEC_1_2; | ||
884 | break; | ||
885 | case 1: | ||
886 | p->u.ofdm.code_rate_HP = FEC_2_3; | ||
887 | break; | ||
888 | case 2: | ||
889 | p->u.ofdm.code_rate_HP = FEC_3_4; | ||
890 | break; | ||
891 | case 3: | ||
892 | p->u.ofdm.code_rate_HP = FEC_5_6; | ||
893 | break; | ||
894 | case 4: | ||
895 | p->u.ofdm.code_rate_HP = FEC_7_8; | ||
896 | break; | ||
897 | } | ||
898 | |||
899 | switch ((buf[2] >> 3) & 7) { | ||
900 | case 0: | ||
901 | p->u.ofdm.code_rate_LP = FEC_1_2; | ||
902 | break; | ||
903 | case 1: | ||
904 | p->u.ofdm.code_rate_LP = FEC_2_3; | ||
905 | break; | ||
906 | case 2: | ||
907 | p->u.ofdm.code_rate_LP = FEC_3_4; | ||
908 | break; | ||
909 | case 3: | ||
910 | p->u.ofdm.code_rate_LP = FEC_5_6; | ||
911 | break; | ||
912 | case 4: | ||
913 | p->u.ofdm.code_rate_LP = FEC_7_8; | ||
914 | break; | ||
915 | } | ||
916 | |||
917 | switch ((buf[1] >> 2) & 3) { | ||
918 | case 0: | ||
919 | p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ; | ||
920 | break; | ||
921 | case 1: | ||
922 | p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ; | ||
923 | break; | ||
924 | case 2: | ||
925 | p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ; | ||
926 | break; | ||
927 | } | ||
928 | |||
929 | p->inversion = INVERSION_AUTO; | ||
930 | p->frequency = state->frequency; | ||
931 | |||
932 | error: | ||
933 | return ret; | ||
934 | } | ||
935 | |||
936 | static int af9013_update_ber_unc(struct dvb_frontend *fe) | ||
937 | { | ||
938 | struct af9013_state *state = fe->demodulator_priv; | ||
939 | int ret; | ||
940 | u8 buf[3], i; | ||
941 | u32 error_bit_count = 0; | ||
942 | u32 total_bit_count = 0; | ||
943 | u32 abort_packet_count = 0; | ||
944 | u64 numerator, denominator; | ||
945 | |||
946 | state->ber = 0; | ||
947 | |||
948 | /* check if error bit count is ready */ | ||
949 | ret = af9013_read_reg_bits(state, 0xd391, 4, 1, &buf[0]); | ||
950 | if (ret) | ||
951 | goto error; | ||
952 | if (!buf[0]) | ||
953 | goto exit; | ||
954 | |||
955 | /* get RSD packet abort count */ | ||
956 | for (i = 0; i < 2; i++) { | ||
957 | ret = af9013_read_reg(state, 0xd38a + i, &buf[i]); | ||
958 | if (ret) | ||
959 | goto error; | ||
960 | } | ||
961 | abort_packet_count = (buf[1] << 8) + buf[0]; | ||
962 | |||
963 | /* get error bit count */ | ||
964 | for (i = 0; i < 3; i++) { | ||
965 | ret = af9013_read_reg(state, 0xd387 + i, &buf[i]); | ||
966 | if (ret) | ||
967 | goto error; | ||
968 | } | ||
969 | error_bit_count = (buf[2] << 16) + (buf[1] << 8) + buf[0]; | ||
970 | error_bit_count = error_bit_count - abort_packet_count * 8 * 8; | ||
971 | |||
972 | /* get used RSD counting period (10000 RSD packets used) */ | ||
973 | for (i = 0; i < 2; i++) { | ||
974 | ret = af9013_read_reg(state, 0xd385 + i, &buf[i]); | ||
975 | if (ret) | ||
976 | goto error; | ||
977 | } | ||
978 | total_bit_count = (buf[1] << 8) + buf[0]; | ||
979 | total_bit_count = total_bit_count - abort_packet_count; | ||
980 | total_bit_count = total_bit_count * 204 * 8; | ||
981 | |||
982 | if (total_bit_count) { | ||
983 | numerator = error_bit_count * 1000000000; | ||
984 | denominator = total_bit_count; | ||
985 | state->ber = numerator / denominator; | ||
986 | } | ||
987 | |||
988 | state->ucblocks += abort_packet_count; | ||
989 | |||
990 | deb_info("%s: err bits:%d total bits:%d abort count:%d\n", __func__, | ||
991 | error_bit_count, total_bit_count, abort_packet_count); | ||
992 | |||
993 | /* set BER counting range */ | ||
994 | ret = af9013_write_reg(state, 0xd385, 10000 & 0xff); | ||
995 | if (ret) | ||
996 | goto error; | ||
997 | ret = af9013_write_reg(state, 0xd386, 10000 >> 8); | ||
998 | if (ret) | ||
999 | goto error; | ||
1000 | /* reset and start BER counter */ | ||
1001 | ret = af9013_write_reg_bits(state, 0xd391, 4, 1, 1); | ||
1002 | if (ret) | ||
1003 | goto error; | ||
1004 | |||
1005 | exit: | ||
1006 | error: | ||
1007 | return ret; | ||
1008 | } | ||
1009 | |||
1010 | static int af9013_update_snr(struct dvb_frontend *fe) | ||
1011 | { | ||
1012 | struct af9013_state *state = fe->demodulator_priv; | ||
1013 | int ret; | ||
1014 | u8 buf[3], i, len; | ||
1015 | u32 quant = 0; | ||
1016 | struct snr_table *snr_table; | ||
1017 | |||
1018 | /* check if quantizer ready (for snr) */ | ||
1019 | ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]); | ||
1020 | if (ret) | ||
1021 | goto error; | ||
1022 | if (buf[0]) { | ||
1023 | /* quantizer ready - read it */ | ||
1024 | for (i = 0; i < 3; i++) { | ||
1025 | ret = af9013_read_reg(state, 0xd2e3 + i, &buf[i]); | ||
1026 | if (ret) | ||
1027 | goto error; | ||
1028 | } | ||
1029 | quant = (buf[2] << 16) + (buf[1] << 8) + buf[0]; | ||
1030 | |||
1031 | /* read current constellation */ | ||
1032 | ret = af9013_read_reg(state, 0xd3c1, &buf[0]); | ||
1033 | if (ret) | ||
1034 | goto error; | ||
1035 | |||
1036 | switch ((buf[0] >> 6) & 3) { | ||
1037 | case 0: | ||
1038 | len = ARRAY_SIZE(qpsk_snr_table); | ||
1039 | snr_table = qpsk_snr_table; | ||
1040 | break; | ||
1041 | case 1: | ||
1042 | len = ARRAY_SIZE(qam16_snr_table); | ||
1043 | snr_table = qam16_snr_table; | ||
1044 | break; | ||
1045 | case 2: | ||
1046 | len = ARRAY_SIZE(qam64_snr_table); | ||
1047 | snr_table = qam64_snr_table; | ||
1048 | break; | ||
1049 | default: | ||
1050 | len = 0; | ||
1051 | break; | ||
1052 | } | ||
1053 | |||
1054 | if (len) { | ||
1055 | for (i = 0; i < len; i++) { | ||
1056 | if (quant < snr_table[i].val) { | ||
1057 | state->snr = snr_table[i].snr * 10; | ||
1058 | break; | ||
1059 | } | ||
1060 | } | ||
1061 | } | ||
1062 | |||
1063 | /* set quantizer super frame count */ | ||
1064 | ret = af9013_write_reg(state, 0xd2e2, 1); | ||
1065 | if (ret) | ||
1066 | goto error; | ||
1067 | |||
1068 | /* check quantizer availability */ | ||
1069 | for (i = 0; i < 10; i++) { | ||
1070 | msleep(10); | ||
1071 | ret = af9013_read_reg_bits(state, 0xd2e6, 0, 1, | ||
1072 | &buf[0]); | ||
1073 | if (ret) | ||
1074 | goto error; | ||
1075 | if (!buf[0]) | ||
1076 | break; | ||
1077 | } | ||
1078 | |||
1079 | /* reset quantizer */ | ||
1080 | ret = af9013_write_reg_bits(state, 0xd2e1, 3, 1, 1); | ||
1081 | if (ret) | ||
1082 | goto error; | ||
1083 | } | ||
1084 | |||
1085 | error: | ||
1086 | return ret; | ||
1087 | } | ||
1088 | |||
1089 | static int af9013_update_signal_strength(struct dvb_frontend *fe) | ||
1090 | { | ||
1091 | struct af9013_state *state = fe->demodulator_priv; | ||
1092 | int ret; | ||
1093 | u8 tmp0; | ||
1094 | u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80; | ||
1095 | int signal_strength; | ||
1096 | |||
1097 | deb_info("%s\n", __func__); | ||
1098 | |||
1099 | state->signal_strength = 0; | ||
1100 | |||
1101 | ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0); | ||
1102 | if (ret) | ||
1103 | goto error; | ||
1104 | if (tmp0) { | ||
1105 | ret = af9013_read_reg(state, 0x9bbd, &rf_50); | ||
1106 | if (ret) | ||
1107 | goto error; | ||
1108 | ret = af9013_read_reg(state, 0x9bd0, &rf_80); | ||
1109 | if (ret) | ||
1110 | goto error; | ||
1111 | ret = af9013_read_reg(state, 0x9be2, &if_50); | ||
1112 | if (ret) | ||
1113 | goto error; | ||
1114 | ret = af9013_read_reg(state, 0x9be4, &if_80); | ||
1115 | if (ret) | ||
1116 | goto error; | ||
1117 | ret = af9013_read_reg(state, 0xd07c, &rf_gain); | ||
1118 | if (ret) | ||
1119 | goto error; | ||
1120 | ret = af9013_read_reg(state, 0xd07d, &if_gain); | ||
1121 | if (ret) | ||
1122 | goto error; | ||
1123 | signal_strength = (0xffff / (9 * (rf_50 + if_50) - \ | ||
1124 | 11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \ | ||
1125 | 11 * (rf_80 + if_80)); | ||
1126 | if (signal_strength < 0) | ||
1127 | signal_strength = 0; | ||
1128 | else if (signal_strength > 0xffff) | ||
1129 | signal_strength = 0xffff; | ||
1130 | |||
1131 | state->signal_strength = signal_strength; | ||
1132 | } | ||
1133 | |||
1134 | error: | ||
1135 | return ret; | ||
1136 | } | ||
1137 | |||
1138 | static int af9013_update_statistics(struct dvb_frontend *fe) | ||
1139 | { | ||
1140 | struct af9013_state *state = fe->demodulator_priv; | ||
1141 | int ret; | ||
1142 | |||
1143 | if (time_before(jiffies, state->next_statistics_check)) | ||
1144 | return 0; | ||
1145 | |||
1146 | /* set minimum statistic update interval */ | ||
1147 | state->next_statistics_check = jiffies + msecs_to_jiffies(1200); | ||
1148 | |||
1149 | ret = af9013_update_signal_strength(fe); | ||
1150 | if (ret) | ||
1151 | goto error; | ||
1152 | ret = af9013_update_snr(fe); | ||
1153 | if (ret) | ||
1154 | goto error; | ||
1155 | ret = af9013_update_ber_unc(fe); | ||
1156 | if (ret) | ||
1157 | goto error; | ||
1158 | |||
1159 | error: | ||
1160 | return ret; | ||
1161 | } | ||
1162 | |||
1163 | static int af9013_get_tune_settings(struct dvb_frontend *fe, | ||
1164 | struct dvb_frontend_tune_settings *fesettings) | ||
1165 | { | ||
1166 | fesettings->min_delay_ms = 800; | ||
1167 | fesettings->step_size = 0; | ||
1168 | fesettings->max_drift = 0; | ||
1169 | |||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status) | ||
1174 | { | ||
1175 | struct af9013_state *state = fe->demodulator_priv; | ||
1176 | int ret = 0; | ||
1177 | u8 tmp; | ||
1178 | *status = 0; | ||
1179 | |||
1180 | /* TPS lock */ | ||
1181 | ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp); | ||
1182 | if (ret) | ||
1183 | goto error; | ||
1184 | if (tmp) | ||
1185 | *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL; | ||
1186 | |||
1187 | /* MPEG2 lock */ | ||
1188 | ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp); | ||
1189 | if (ret) | ||
1190 | goto error; | ||
1191 | if (tmp) | ||
1192 | *status |= FE_HAS_SYNC | FE_HAS_LOCK; | ||
1193 | |||
1194 | if (!*status & FE_HAS_SIGNAL) { | ||
1195 | /* AGC lock */ | ||
1196 | ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp); | ||
1197 | if (ret) | ||
1198 | goto error; | ||
1199 | if (tmp) | ||
1200 | *status |= FE_HAS_SIGNAL; | ||
1201 | } | ||
1202 | |||
1203 | if (!*status & FE_HAS_CARRIER) { | ||
1204 | /* CFO lock */ | ||
1205 | ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp); | ||
1206 | if (ret) | ||
1207 | goto error; | ||
1208 | if (tmp) | ||
1209 | *status |= FE_HAS_CARRIER; | ||
1210 | } | ||
1211 | |||
1212 | if (!*status & FE_HAS_CARRIER) { | ||
1213 | /* SFOE lock */ | ||
1214 | ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp); | ||
1215 | if (ret) | ||
1216 | goto error; | ||
1217 | if (tmp) | ||
1218 | *status |= FE_HAS_CARRIER; | ||
1219 | } | ||
1220 | |||
1221 | ret = af9013_update_statistics(fe); | ||
1222 | |||
1223 | error: | ||
1224 | return ret; | ||
1225 | } | ||
1226 | |||
1227 | |||
1228 | static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber) | ||
1229 | { | ||
1230 | struct af9013_state *state = fe->demodulator_priv; | ||
1231 | int ret; | ||
1232 | ret = af9013_update_statistics(fe); | ||
1233 | *ber = state->ber; | ||
1234 | return ret; | ||
1235 | } | ||
1236 | |||
1237 | static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength) | ||
1238 | { | ||
1239 | struct af9013_state *state = fe->demodulator_priv; | ||
1240 | int ret; | ||
1241 | ret = af9013_update_statistics(fe); | ||
1242 | *strength = state->signal_strength; | ||
1243 | return ret; | ||
1244 | } | ||
1245 | |||
1246 | static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr) | ||
1247 | { | ||
1248 | struct af9013_state *state = fe->demodulator_priv; | ||
1249 | int ret; | ||
1250 | ret = af9013_update_statistics(fe); | ||
1251 | *snr = state->snr; | ||
1252 | return ret; | ||
1253 | } | ||
1254 | |||
1255 | static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) | ||
1256 | { | ||
1257 | struct af9013_state *state = fe->demodulator_priv; | ||
1258 | int ret; | ||
1259 | ret = af9013_update_statistics(fe); | ||
1260 | *ucblocks = state->ucblocks; | ||
1261 | return ret; | ||
1262 | } | ||
1263 | |||
1264 | static int af9013_sleep(struct dvb_frontend *fe) | ||
1265 | { | ||
1266 | struct af9013_state *state = fe->demodulator_priv; | ||
1267 | int ret; | ||
1268 | deb_info("%s\n", __func__); | ||
1269 | |||
1270 | ret = af9013_lock_led(state, 0); | ||
1271 | if (ret) | ||
1272 | goto error; | ||
1273 | |||
1274 | ret = af9013_power_ctrl(state, 0); | ||
1275 | error: | ||
1276 | return ret; | ||
1277 | } | ||
1278 | |||
1279 | static int af9013_init(struct dvb_frontend *fe) | ||
1280 | { | ||
1281 | struct af9013_state *state = fe->demodulator_priv; | ||
1282 | int ret, i, len; | ||
1283 | u8 tmp0, tmp1; | ||
1284 | struct regdesc *init; | ||
1285 | deb_info("%s\n", __func__); | ||
1286 | |||
1287 | /* reset OFDM */ | ||
1288 | ret = af9013_reset(state, 0); | ||
1289 | if (ret) | ||
1290 | goto error; | ||
1291 | |||
1292 | /* power on */ | ||
1293 | ret = af9013_power_ctrl(state, 1); | ||
1294 | if (ret) | ||
1295 | goto error; | ||
1296 | |||
1297 | /* enable ADC */ | ||
1298 | ret = af9013_write_reg(state, 0xd73a, 0xa4); | ||
1299 | if (ret) | ||
1300 | goto error; | ||
1301 | |||
1302 | /* write API version to firmware */ | ||
1303 | for (i = 0; i < sizeof(state->config.api_version); i++) { | ||
1304 | ret = af9013_write_reg(state, 0x9bf2 + i, | ||
1305 | state->config.api_version[i]); | ||
1306 | if (ret) | ||
1307 | goto error; | ||
1308 | } | ||
1309 | |||
1310 | /* program ADC control */ | ||
1311 | ret = af9013_set_adc_ctrl(state); | ||
1312 | if (ret) | ||
1313 | goto error; | ||
1314 | |||
1315 | /* set I2C master clock */ | ||
1316 | ret = af9013_write_reg(state, 0xd416, 0x14); | ||
1317 | if (ret) | ||
1318 | goto error; | ||
1319 | |||
1320 | /* set 16 embx */ | ||
1321 | ret = af9013_write_reg_bits(state, 0xd700, 1, 1, 1); | ||
1322 | if (ret) | ||
1323 | goto error; | ||
1324 | |||
1325 | /* set no trigger */ | ||
1326 | ret = af9013_write_reg_bits(state, 0xd700, 2, 1, 0); | ||
1327 | if (ret) | ||
1328 | goto error; | ||
1329 | |||
1330 | /* set read-update bit for constellation */ | ||
1331 | ret = af9013_write_reg_bits(state, 0xd371, 1, 1, 1); | ||
1332 | if (ret) | ||
1333 | goto error; | ||
1334 | |||
1335 | /* enable FEC monitor */ | ||
1336 | ret = af9013_write_reg_bits(state, 0xd392, 1, 1, 1); | ||
1337 | if (ret) | ||
1338 | goto error; | ||
1339 | |||
1340 | /* load OFSM settings */ | ||
1341 | deb_info("%s: load ofsm settings\n", __func__); | ||
1342 | len = ARRAY_SIZE(ofsm_init); | ||
1343 | init = ofsm_init; | ||
1344 | for (i = 0; i < len; i++) { | ||
1345 | ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos, | ||
1346 | init[i].len, init[i].val); | ||
1347 | if (ret) | ||
1348 | goto error; | ||
1349 | } | ||
1350 | |||
1351 | /* load tuner specific settings */ | ||
1352 | deb_info("%s: load tuner specific settings\n", __func__); | ||
1353 | switch (state->config.tuner) { | ||
1354 | case AF9013_TUNER_MXL5003D: | ||
1355 | len = ARRAY_SIZE(tuner_init_mxl5003d); | ||
1356 | init = tuner_init_mxl5003d; | ||
1357 | break; | ||
1358 | case AF9013_TUNER_MXL5005D: | ||
1359 | case AF9013_TUNER_MXL5005R: | ||
1360 | len = ARRAY_SIZE(tuner_init_mxl5005); | ||
1361 | init = tuner_init_mxl5005; | ||
1362 | break; | ||
1363 | case AF9013_TUNER_ENV77H11D5: | ||
1364 | len = ARRAY_SIZE(tuner_init_env77h11d5); | ||
1365 | init = tuner_init_env77h11d5; | ||
1366 | break; | ||
1367 | case AF9013_TUNER_MT2060: | ||
1368 | len = ARRAY_SIZE(tuner_init_mt2060); | ||
1369 | init = tuner_init_mt2060; | ||
1370 | break; | ||
1371 | case AF9013_TUNER_MC44S803: | ||
1372 | len = ARRAY_SIZE(tuner_init_mc44s803); | ||
1373 | init = tuner_init_mc44s803; | ||
1374 | break; | ||
1375 | case AF9013_TUNER_QT1010: | ||
1376 | case AF9013_TUNER_QT1010A: | ||
1377 | len = ARRAY_SIZE(tuner_init_qt1010); | ||
1378 | init = tuner_init_qt1010; | ||
1379 | break; | ||
1380 | case AF9013_TUNER_MT2060_2: | ||
1381 | len = ARRAY_SIZE(tuner_init_mt2060_2); | ||
1382 | init = tuner_init_mt2060_2; | ||
1383 | break; | ||
1384 | case AF9013_TUNER_TDA18271: | ||
1385 | len = ARRAY_SIZE(tuner_init_tda18271); | ||
1386 | init = tuner_init_tda18271; | ||
1387 | break; | ||
1388 | case AF9013_TUNER_UNKNOWN: | ||
1389 | default: | ||
1390 | len = ARRAY_SIZE(tuner_init_unknown); | ||
1391 | init = tuner_init_unknown; | ||
1392 | break; | ||
1393 | } | ||
1394 | |||
1395 | for (i = 0; i < len; i++) { | ||
1396 | ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos, | ||
1397 | init[i].len, init[i].val); | ||
1398 | if (ret) | ||
1399 | goto error; | ||
1400 | } | ||
1401 | |||
1402 | /* set TS mode */ | ||
1403 | deb_info("%s: setting ts mode\n", __func__); | ||
1404 | tmp0 = 0; /* parallel mode */ | ||
1405 | tmp1 = 0; /* serial mode */ | ||
1406 | switch (state->config.output_mode) { | ||
1407 | case AF9013_OUTPUT_MODE_PARALLEL: | ||
1408 | tmp0 = 1; | ||
1409 | break; | ||
1410 | case AF9013_OUTPUT_MODE_SERIAL: | ||
1411 | tmp1 = 1; | ||
1412 | break; | ||
1413 | case AF9013_OUTPUT_MODE_USB: | ||
1414 | /* usb mode for AF9015 */ | ||
1415 | default: | ||
1416 | break; | ||
1417 | } | ||
1418 | ret = af9013_write_reg_bits(state, 0xd500, 1, 1, tmp0); /* parallel */ | ||
1419 | if (ret) | ||
1420 | goto error; | ||
1421 | ret = af9013_write_reg_bits(state, 0xd500, 2, 1, tmp1); /* serial */ | ||
1422 | if (ret) | ||
1423 | goto error; | ||
1424 | |||
1425 | /* enable lock led */ | ||
1426 | ret = af9013_lock_led(state, 1); | ||
1427 | if (ret) | ||
1428 | goto error; | ||
1429 | |||
1430 | error: | ||
1431 | return ret; | ||
1432 | } | ||
1433 | |||
1434 | static struct dvb_frontend_ops af9013_ops; | ||
1435 | |||
1436 | static int af9013_download_firmware(struct af9013_state *state) | ||
1437 | { | ||
1438 | int i, len, packets, remainder, ret; | ||
1439 | const struct firmware *fw; | ||
1440 | u16 addr = 0x5100; /* firmware start address */ | ||
1441 | u16 checksum = 0; | ||
1442 | u8 val; | ||
1443 | u8 fw_params[4]; | ||
1444 | u8 *data; | ||
1445 | u8 *fw_file = AF9013_DEFAULT_FIRMWARE; | ||
1446 | |||
1447 | msleep(100); | ||
1448 | /* check whether firmware is already running */ | ||
1449 | ret = af9013_read_reg(state, 0x98be, &val); | ||
1450 | if (ret) | ||
1451 | goto error; | ||
1452 | else | ||
1453 | deb_info("%s: firmware status:%02x\n", __func__, val); | ||
1454 | |||
1455 | if (val == 0x0c) /* fw is running, no need for download */ | ||
1456 | goto exit; | ||
1457 | |||
1458 | info("found a '%s' in cold state, will try to load a firmware", | ||
1459 | af9013_ops.info.name); | ||
1460 | |||
1461 | /* request the firmware, this will block and timeout */ | ||
1462 | ret = request_firmware(&fw, fw_file, &state->i2c->dev); | ||
1463 | if (ret) { | ||
1464 | err("did not find the firmware file. (%s) " | ||
1465 | "Please see linux/Documentation/dvb/ for more details" \ | ||
1466 | " on firmware-problems. (%d)", | ||
1467 | fw_file, ret); | ||
1468 | goto error; | ||
1469 | } | ||
1470 | |||
1471 | info("downloading firmware from file '%s'", fw_file); | ||
1472 | |||
1473 | /* calc checksum */ | ||
1474 | for (i = 0; i < fw->size; i++) | ||
1475 | checksum += fw->data[i]; | ||
1476 | |||
1477 | fw_params[0] = checksum >> 8; | ||
1478 | fw_params[1] = checksum & 0xff; | ||
1479 | fw_params[2] = fw->size >> 8; | ||
1480 | fw_params[3] = fw->size & 0xff; | ||
1481 | |||
1482 | /* write fw checksum & size */ | ||
1483 | ret = af9013_write_ofsm_regs(state, 0x50fc, | ||
1484 | fw_params, sizeof(fw_params)); | ||
1485 | if (ret) | ||
1486 | goto error_release; | ||
1487 | |||
1488 | #define FW_PACKET_MAX_DATA 16 | ||
1489 | |||
1490 | packets = fw->size / FW_PACKET_MAX_DATA; | ||
1491 | remainder = fw->size % FW_PACKET_MAX_DATA; | ||
1492 | len = FW_PACKET_MAX_DATA; | ||
1493 | for (i = 0; i <= packets; i++) { | ||
1494 | if (i == packets) /* set size of the last packet */ | ||
1495 | len = remainder; | ||
1496 | |||
1497 | data = (fw->data + i * FW_PACKET_MAX_DATA); | ||
1498 | ret = af9013_write_ofsm_regs(state, addr, data, len); | ||
1499 | addr += FW_PACKET_MAX_DATA; | ||
1500 | |||
1501 | if (ret) { | ||
1502 | err("firmware download failed at %d with %d", i, ret); | ||
1503 | goto error_release; | ||
1504 | } | ||
1505 | } | ||
1506 | |||
1507 | #undef FW_PACKET_MAX_DATA | ||
1508 | |||
1509 | /* request boot firmware */ | ||
1510 | ret = af9013_write_reg(state, 0xe205, 1); | ||
1511 | if (ret) | ||
1512 | goto error_release; | ||
1513 | |||
1514 | for (i = 0; i < 15; i++) { | ||
1515 | msleep(100); | ||
1516 | |||
1517 | /* check firmware status */ | ||
1518 | ret = af9013_read_reg(state, 0x98be, &val); | ||
1519 | if (ret) | ||
1520 | goto error_release; | ||
1521 | |||
1522 | deb_info("%s: firmware status:%02x\n", __func__, val); | ||
1523 | |||
1524 | if (val == 0x0c || val == 0x04) /* success or fail */ | ||
1525 | break; | ||
1526 | } | ||
1527 | |||
1528 | if (val == 0x04) { | ||
1529 | err("firmware did not run"); | ||
1530 | ret = -1; | ||
1531 | } else if (val != 0x0c) { | ||
1532 | err("firmware boot timeout"); | ||
1533 | ret = -1; | ||
1534 | } | ||
1535 | |||
1536 | error_release: | ||
1537 | release_firmware(fw); | ||
1538 | error: | ||
1539 | exit: | ||
1540 | if (!ret) | ||
1541 | info("found a '%s' in warm state.", af9013_ops.info.name); | ||
1542 | return ret; | ||
1543 | } | ||
1544 | |||
1545 | static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
1546 | { | ||
1547 | int ret; | ||
1548 | struct af9013_state *state = fe->demodulator_priv; | ||
1549 | deb_info("%s: enable:%d\n", __func__, enable); | ||
1550 | |||
1551 | if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) | ||
1552 | ret = af9013_write_reg_bits(state, 0xd417, 3, 1, enable); | ||
1553 | else | ||
1554 | ret = af9013_write_reg_bits(state, 0xd607, 2, 1, enable); | ||
1555 | |||
1556 | return ret; | ||
1557 | } | ||
1558 | |||
1559 | static void af9013_release(struct dvb_frontend *fe) | ||
1560 | { | ||
1561 | struct af9013_state *state = fe->demodulator_priv; | ||
1562 | kfree(state); | ||
1563 | } | ||
1564 | |||
1565 | static struct dvb_frontend_ops af9013_ops; | ||
1566 | |||
1567 | struct dvb_frontend *af9013_attach(const struct af9013_config *config, | ||
1568 | struct i2c_adapter *i2c) | ||
1569 | { | ||
1570 | int ret; | ||
1571 | struct af9013_state *state = NULL; | ||
1572 | u8 buf[3], i; | ||
1573 | |||
1574 | /* allocate memory for the internal state */ | ||
1575 | state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL); | ||
1576 | if (state == NULL) | ||
1577 | goto error; | ||
1578 | |||
1579 | /* setup the state */ | ||
1580 | state->i2c = i2c; | ||
1581 | memcpy(&state->config, config, sizeof(struct af9013_config)); | ||
1582 | |||
1583 | /* chip version */ | ||
1584 | ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]); | ||
1585 | if (ret) | ||
1586 | goto error; | ||
1587 | |||
1588 | /* ROM version */ | ||
1589 | for (i = 0; i < 2; i++) { | ||
1590 | ret = af9013_read_reg(state, 0x116b + i, &buf[i]); | ||
1591 | if (ret) | ||
1592 | goto error; | ||
1593 | } | ||
1594 | deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__, | ||
1595 | buf[2], buf[0], buf[1]); | ||
1596 | |||
1597 | /* download firmware */ | ||
1598 | if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) { | ||
1599 | ret = af9013_download_firmware(state); | ||
1600 | if (ret) | ||
1601 | goto error; | ||
1602 | } | ||
1603 | |||
1604 | /* firmware version */ | ||
1605 | for (i = 0; i < 3; i++) { | ||
1606 | ret = af9013_read_reg(state, 0x5103 + i, &buf[i]); | ||
1607 | if (ret) | ||
1608 | goto error; | ||
1609 | } | ||
1610 | info("firmware version:%d.%d.%d", buf[0], buf[1], buf[2]); | ||
1611 | |||
1612 | /* settings for mp2if */ | ||
1613 | if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) { | ||
1614 | /* AF9015 split PSB to 1.5k + 0.5k */ | ||
1615 | ret = af9013_write_reg_bits(state, 0xd50b, 2, 1, 1); | ||
1616 | } else { | ||
1617 | /* AF9013 change the output bit to data7 */ | ||
1618 | ret = af9013_write_reg_bits(state, 0xd500, 3, 1, 1); | ||
1619 | if (ret) | ||
1620 | goto error; | ||
1621 | /* AF9013 set mpeg to full speed */ | ||
1622 | ret = af9013_write_reg_bits(state, 0xd502, 4, 1, 1); | ||
1623 | } | ||
1624 | if (ret) | ||
1625 | goto error; | ||
1626 | ret = af9013_write_reg_bits(state, 0xd520, 4, 1, 1); | ||
1627 | if (ret) | ||
1628 | goto error; | ||
1629 | |||
1630 | /* set GPIOs */ | ||
1631 | for (i = 0; i < sizeof(state->config.gpio); i++) { | ||
1632 | ret = af9013_set_gpio(state, i, state->config.gpio[i]); | ||
1633 | if (ret) | ||
1634 | goto error; | ||
1635 | } | ||
1636 | |||
1637 | /* create dvb_frontend */ | ||
1638 | memcpy(&state->frontend.ops, &af9013_ops, | ||
1639 | sizeof(struct dvb_frontend_ops)); | ||
1640 | state->frontend.demodulator_priv = state; | ||
1641 | |||
1642 | return &state->frontend; | ||
1643 | error: | ||
1644 | kfree(state); | ||
1645 | return NULL; | ||
1646 | } | ||
1647 | EXPORT_SYMBOL(af9013_attach); | ||
1648 | |||
1649 | static struct dvb_frontend_ops af9013_ops = { | ||
1650 | .info = { | ||
1651 | .name = "Afatech AF9013 DVB-T", | ||
1652 | .type = FE_OFDM, | ||
1653 | .frequency_min = 174000000, | ||
1654 | .frequency_max = 862000000, | ||
1655 | .frequency_stepsize = 250000, | ||
1656 | .frequency_tolerance = 0, | ||
1657 | .caps = | ||
1658 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
1659 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
1660 | FE_CAN_QPSK | FE_CAN_QAM_16 | | ||
1661 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | | ||
1662 | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
1663 | FE_CAN_GUARD_INTERVAL_AUTO | | ||
1664 | FE_CAN_HIERARCHY_AUTO | | ||
1665 | FE_CAN_RECOVER | | ||
1666 | FE_CAN_MUTE_TS | ||
1667 | }, | ||
1668 | |||
1669 | .release = af9013_release, | ||
1670 | .init = af9013_init, | ||
1671 | .sleep = af9013_sleep, | ||
1672 | .i2c_gate_ctrl = af9013_i2c_gate_ctrl, | ||
1673 | |||
1674 | .set_frontend = af9013_set_frontend, | ||
1675 | .get_frontend = af9013_get_frontend, | ||
1676 | |||
1677 | .get_tune_settings = af9013_get_tune_settings, | ||
1678 | |||
1679 | .read_status = af9013_read_status, | ||
1680 | .read_ber = af9013_read_ber, | ||
1681 | .read_signal_strength = af9013_read_signal_strength, | ||
1682 | .read_snr = af9013_read_snr, | ||
1683 | .read_ucblocks = af9013_read_ucblocks, | ||
1684 | }; | ||
1685 | |||
1686 | module_param_named(debug, af9013_debug, int, 0644); | ||
1687 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
1688 | |||
1689 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | ||
1690 | MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver"); | ||
1691 | MODULE_LICENSE("GPL"); | ||