aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r--drivers/media/dvb/frontends/Kconfig47
-rw-r--r--drivers/media/dvb/frontends/Makefile7
-rw-r--r--drivers/media/dvb/frontends/af9013.c1685
-rw-r--r--drivers/media/dvb/frontends/af9013.h107
-rw-r--r--drivers/media/dvb/frontends/af9013_priv.h869
-rw-r--r--drivers/media/dvb/frontends/au8522.c133
-rw-r--r--drivers/media/dvb/frontends/au8522.h17
-rw-r--r--drivers/media/dvb/frontends/cx24110.h15
-rw-r--r--drivers/media/dvb/frontends/cx24116.c1423
-rw-r--r--drivers/media/dvb/frontends/cx24116.h53
-rw-r--r--drivers/media/dvb/frontends/dib0070.h8
-rw-r--r--drivers/media/dvb/frontends/dib7000m.c6
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c3
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h41
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c288
-rw-r--r--drivers/media/dvb/frontends/drx397xD.h6
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.c11
-rw-r--r--drivers/media/dvb/frontends/eds1547.h133
-rw-r--r--drivers/media/dvb/frontends/lgs8gl5.c454
-rw-r--r--drivers/media/dvb/frontends/lgs8gl5.h45
-rw-r--r--drivers/media/dvb/frontends/nxt200x.c4
-rw-r--r--drivers/media/dvb/frontends/or51211.c2
-rw-r--r--drivers/media/dvb/frontends/s5h1420.c11
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h8
-rw-r--r--drivers/media/dvb/frontends/si21xx.c974
-rw-r--r--drivers/media/dvb/frontends/si21xx.h37
-rw-r--r--drivers/media/dvb/frontends/sp887x.c3
-rw-r--r--drivers/media/dvb/frontends/stb6000.c255
-rw-r--r--drivers/media/dvb/frontends/stb6000.h51
-rw-r--r--drivers/media/dvb/frontends/stv0288.c618
-rw-r--r--drivers/media/dvb/frontends/stv0288.h67
-rw-r--r--drivers/media/dvb/frontends/stv0299.c2
-rw-r--r--drivers/media/dvb/frontends/stv0299.h13
-rw-r--r--drivers/media/dvb/frontends/tdhd1.h73
34 files changed, 7291 insertions, 178 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 7dbb4a223c99..96b93e21a84b 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -43,6 +43,20 @@ config DVB_S5H1420
43 help 43 help
44 A DVB-S tuner module. Say Y when you want to support this frontend. 44 A DVB-S tuner module. Say Y when you want to support this frontend.
45 45
46config DVB_STV0288
47 tristate "ST STV0288 based"
48 depends on DVB_CORE && I2C
49 default m if DVB_FE_CUSTOMISE
50 help
51 A DVB-S tuner module. Say Y when you want to support this frontend.
52
53config DVB_STB6000
54 tristate "ST STB6000 silicon tuner"
55 depends on DVB_CORE && I2C
56 default m if DVB_FE_CUSTOMISE
57 help
58 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
59
46config DVB_STV0299 60config DVB_STV0299
47 tristate "ST STV0299 based" 61 tristate "ST STV0299 based"
48 depends on DVB_CORE && I2C 62 depends on DVB_CORE && I2C
@@ -92,6 +106,20 @@ config DVB_TUA6100
92 help 106 help
93 A DVB-S PLL chip. 107 A DVB-S PLL chip.
94 108
109config DVB_CX24116
110 tristate "Conexant CX24116 based"
111 depends on DVB_CORE && I2C
112 default m if DVB_FE_CUSTOMISE
113 help
114 A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
115
116config DVB_SI21XX
117 tristate "Silicon Labs SI21XX based"
118 depends on DVB_CORE && I2C
119 default m if DVB_FE_CUSTOMISE
120 help
121 A DVB-S tuner module. Say Y when you want to support this frontend.
122
95comment "DVB-T (terrestrial) frontends" 123comment "DVB-T (terrestrial) frontends"
96 depends on DVB_CORE 124 depends on DVB_CORE
97 125
@@ -385,4 +413,23 @@ config DVB_ISL6421
385 help 413 help
386 An SEC control chip. 414 An SEC control chip.
387 415
416config DVB_LGS8GL5
417 tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)"
418 depends on DVB_CORE && I2C
419 default m if DVB_FE_CUSTOMISE
420 help
421 A DMB-TH tuner module. Say Y when you want to support this frontend.
422
423comment "Tools to develop new frontends"
424
425config DVB_DUMMY_FE
426 tristate "Dummy frontend driver"
427 default n
428
429config DVB_AF9013
430 tristate "Afatech AF9013 demodulator"
431 depends on DVB_CORE && I2C
432 default m if DVB_FE_CUSTOMISE
433 help
434 Say Y when you want to support this frontend.
388endmenu 435endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 028da55611c0..aba79f4a63a7 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -48,3 +48,10 @@ obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
48obj-$(CONFIG_DVB_AU8522) += au8522.o 48obj-$(CONFIG_DVB_AU8522) += au8522.o
49obj-$(CONFIG_DVB_TDA10048) += tda10048.o 49obj-$(CONFIG_DVB_TDA10048) += tda10048.o
50obj-$(CONFIG_DVB_S5H1411) += s5h1411.o 50obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
51obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
52obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
53obj-$(CONFIG_DVB_AF9013) += af9013.o
54obj-$(CONFIG_DVB_CX24116) += cx24116.o
55obj-$(CONFIG_DVB_SI21XX) += si21xx.o
56obj-$(CONFIG_DVB_STV0288) += stv0288.o
57obj-$(CONFIG_DVB_STB6000) += stb6000.o
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
new file mode 100644
index 000000000000..21c1060cf10e
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -0,0 +1,1685 @@
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
37int af9013_debug;
38
39struct 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
53static u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
54
55static 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
77static 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
84static 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 */
92static 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 */
98static 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
124static 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
140static 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
153static 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
193error:
194 return ret;
195}
196
197static 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
221static 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
404static 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);
447error:
448 return ret;
449}
450
451static 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 }
519error:
520 return ret;
521}
522
523static 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
667static 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 }
705error:
706 return ret;
707}
708
709static 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 }
730error:
731 return ret;
732}
733
734static 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
741static 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, &params->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
812error:
813 return ret;
814}
815
816static 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
932error:
933 return ret;
934}
935
936static 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
945 state->ber = 0;
946
947 /* check if error bit count is ready */
948 ret = af9013_read_reg_bits(state, 0xd391, 4, 1, &buf[0]);
949 if (ret)
950 goto error;
951 if (!buf[0])
952 goto exit;
953
954 /* get RSD packet abort count */
955 for (i = 0; i < 2; i++) {
956 ret = af9013_read_reg(state, 0xd38a + i, &buf[i]);
957 if (ret)
958 goto error;
959 }
960 abort_packet_count = (buf[1] << 8) + buf[0];
961
962 /* get error bit count */
963 for (i = 0; i < 3; i++) {
964 ret = af9013_read_reg(state, 0xd387 + i, &buf[i]);
965 if (ret)
966 goto error;
967 }
968 error_bit_count = (buf[2] << 16) + (buf[1] << 8) + buf[0];
969 error_bit_count = error_bit_count - abort_packet_count * 8 * 8;
970
971 /* get used RSD counting period (10000 RSD packets used) */
972 for (i = 0; i < 2; i++) {
973 ret = af9013_read_reg(state, 0xd385 + i, &buf[i]);
974 if (ret)
975 goto error;
976 }
977 total_bit_count = (buf[1] << 8) + buf[0];
978 total_bit_count = total_bit_count - abort_packet_count;
979 total_bit_count = total_bit_count * 204 * 8;
980
981 if (total_bit_count)
982 state->ber = error_bit_count * 1000000000 / total_bit_count;
983
984 state->ucblocks += abort_packet_count;
985
986 deb_info("%s: err bits:%d total bits:%d abort count:%d\n", __func__,
987 error_bit_count, total_bit_count, abort_packet_count);
988
989 /* set BER counting range */
990 ret = af9013_write_reg(state, 0xd385, 10000 & 0xff);
991 if (ret)
992 goto error;
993 ret = af9013_write_reg(state, 0xd386, 10000 >> 8);
994 if (ret)
995 goto error;
996 /* reset and start BER counter */
997 ret = af9013_write_reg_bits(state, 0xd391, 4, 1, 1);
998 if (ret)
999 goto error;
1000
1001exit:
1002error:
1003 return ret;
1004}
1005
1006static int af9013_update_snr(struct dvb_frontend *fe)
1007{
1008 struct af9013_state *state = fe->demodulator_priv;
1009 int ret;
1010 u8 buf[3], i, len;
1011 u32 quant = 0;
1012 struct snr_table *snr_table;
1013
1014 /* check if quantizer ready (for snr) */
1015 ret = af9013_read_reg_bits(state, 0xd2e1, 3, 1, &buf[0]);
1016 if (ret)
1017 goto error;
1018 if (buf[0]) {
1019 /* quantizer ready - read it */
1020 for (i = 0; i < 3; i++) {
1021 ret = af9013_read_reg(state, 0xd2e3 + i, &buf[i]);
1022 if (ret)
1023 goto error;
1024 }
1025 quant = (buf[2] << 16) + (buf[1] << 8) + buf[0];
1026
1027 /* read current constellation */
1028 ret = af9013_read_reg(state, 0xd3c1, &buf[0]);
1029 if (ret)
1030 goto error;
1031
1032 switch ((buf[0] >> 6) & 3) {
1033 case 0:
1034 len = ARRAY_SIZE(qpsk_snr_table);
1035 snr_table = qpsk_snr_table;
1036 break;
1037 case 1:
1038 len = ARRAY_SIZE(qam16_snr_table);
1039 snr_table = qam16_snr_table;
1040 break;
1041 case 2:
1042 len = ARRAY_SIZE(qam64_snr_table);
1043 snr_table = qam64_snr_table;
1044 break;
1045 default:
1046 len = 0;
1047 break;
1048 }
1049
1050 if (len) {
1051 for (i = 0; i < len; i++) {
1052 if (quant < snr_table[i].val) {
1053 state->snr = snr_table[i].snr * 10;
1054 break;
1055 }
1056 }
1057 }
1058
1059 /* set quantizer super frame count */
1060 ret = af9013_write_reg(state, 0xd2e2, 1);
1061 if (ret)
1062 goto error;
1063
1064 /* check quantizer availability */
1065 for (i = 0; i < 10; i++) {
1066 msleep(10);
1067 ret = af9013_read_reg_bits(state, 0xd2e6, 0, 1,
1068 &buf[0]);
1069 if (ret)
1070 goto error;
1071 if (!buf[0])
1072 break;
1073 }
1074
1075 /* reset quantizer */
1076 ret = af9013_write_reg_bits(state, 0xd2e1, 3, 1, 1);
1077 if (ret)
1078 goto error;
1079 }
1080
1081error:
1082 return ret;
1083}
1084
1085static int af9013_update_signal_strength(struct dvb_frontend *fe)
1086{
1087 struct af9013_state *state = fe->demodulator_priv;
1088 int ret;
1089 u8 tmp0;
1090 u8 rf_gain, rf_50, rf_80, if_gain, if_50, if_80;
1091 int signal_strength;
1092
1093 deb_info("%s\n", __func__);
1094
1095 state->signal_strength = 0;
1096
1097 ret = af9013_read_reg_bits(state, 0x9bee, 0, 1, &tmp0);
1098 if (ret)
1099 goto error;
1100 if (tmp0) {
1101 ret = af9013_read_reg(state, 0x9bbd, &rf_50);
1102 if (ret)
1103 goto error;
1104 ret = af9013_read_reg(state, 0x9bd0, &rf_80);
1105 if (ret)
1106 goto error;
1107 ret = af9013_read_reg(state, 0x9be2, &if_50);
1108 if (ret)
1109 goto error;
1110 ret = af9013_read_reg(state, 0x9be4, &if_80);
1111 if (ret)
1112 goto error;
1113 ret = af9013_read_reg(state, 0xd07c, &rf_gain);
1114 if (ret)
1115 goto error;
1116 ret = af9013_read_reg(state, 0xd07d, &if_gain);
1117 if (ret)
1118 goto error;
1119 signal_strength = (0xffff / (9 * (rf_50 + if_50) - \
1120 11 * (rf_80 + if_80))) * (10 * (rf_gain + if_gain) - \
1121 11 * (rf_80 + if_80));
1122 if (signal_strength < 0)
1123 signal_strength = 0;
1124 else if (signal_strength > 0xffff)
1125 signal_strength = 0xffff;
1126
1127 state->signal_strength = signal_strength;
1128 }
1129
1130error:
1131 return ret;
1132}
1133
1134static int af9013_update_statistics(struct dvb_frontend *fe)
1135{
1136 struct af9013_state *state = fe->demodulator_priv;
1137 int ret;
1138
1139 if (time_before(jiffies, state->next_statistics_check))
1140 return 0;
1141
1142 /* set minimum statistic update interval */
1143 state->next_statistics_check = jiffies + msecs_to_jiffies(1200);
1144
1145 ret = af9013_update_signal_strength(fe);
1146 if (ret)
1147 goto error;
1148 ret = af9013_update_snr(fe);
1149 if (ret)
1150 goto error;
1151 ret = af9013_update_ber_unc(fe);
1152 if (ret)
1153 goto error;
1154
1155error:
1156 return ret;
1157}
1158
1159static int af9013_get_tune_settings(struct dvb_frontend *fe,
1160 struct dvb_frontend_tune_settings *fesettings)
1161{
1162 fesettings->min_delay_ms = 800;
1163 fesettings->step_size = 0;
1164 fesettings->max_drift = 0;
1165
1166 return 0;
1167}
1168
1169static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
1170{
1171 struct af9013_state *state = fe->demodulator_priv;
1172 int ret = 0;
1173 u8 tmp;
1174 *status = 0;
1175
1176 /* TPS lock */
1177 ret = af9013_read_reg_bits(state, 0xd330, 3, 1, &tmp);
1178 if (ret)
1179 goto error;
1180 if (tmp)
1181 *status |= FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
1182
1183 /* MPEG2 lock */
1184 ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp);
1185 if (ret)
1186 goto error;
1187 if (tmp)
1188 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
1189
1190 if (!*status & FE_HAS_SIGNAL) {
1191 /* AGC lock */
1192 ret = af9013_read_reg_bits(state, 0xd1a0, 6, 1, &tmp);
1193 if (ret)
1194 goto error;
1195 if (tmp)
1196 *status |= FE_HAS_SIGNAL;
1197 }
1198
1199 if (!*status & FE_HAS_CARRIER) {
1200 /* CFO lock */
1201 ret = af9013_read_reg_bits(state, 0xd333, 7, 1, &tmp);
1202 if (ret)
1203 goto error;
1204 if (tmp)
1205 *status |= FE_HAS_CARRIER;
1206 }
1207
1208 if (!*status & FE_HAS_CARRIER) {
1209 /* SFOE lock */
1210 ret = af9013_read_reg_bits(state, 0xd334, 6, 1, &tmp);
1211 if (ret)
1212 goto error;
1213 if (tmp)
1214 *status |= FE_HAS_CARRIER;
1215 }
1216
1217 ret = af9013_update_statistics(fe);
1218
1219error:
1220 return ret;
1221}
1222
1223
1224static int af9013_read_ber(struct dvb_frontend *fe, u32 *ber)
1225{
1226 struct af9013_state *state = fe->demodulator_priv;
1227 int ret;
1228 ret = af9013_update_statistics(fe);
1229 *ber = state->ber;
1230 return ret;
1231}
1232
1233static int af9013_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1234{
1235 struct af9013_state *state = fe->demodulator_priv;
1236 int ret;
1237 ret = af9013_update_statistics(fe);
1238 *strength = state->signal_strength;
1239 return ret;
1240}
1241
1242static int af9013_read_snr(struct dvb_frontend *fe, u16 *snr)
1243{
1244 struct af9013_state *state = fe->demodulator_priv;
1245 int ret;
1246 ret = af9013_update_statistics(fe);
1247 *snr = state->snr;
1248 return ret;
1249}
1250
1251static int af9013_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1252{
1253 struct af9013_state *state = fe->demodulator_priv;
1254 int ret;
1255 ret = af9013_update_statistics(fe);
1256 *ucblocks = state->ucblocks;
1257 return ret;
1258}
1259
1260static int af9013_sleep(struct dvb_frontend *fe)
1261{
1262 struct af9013_state *state = fe->demodulator_priv;
1263 int ret;
1264 deb_info("%s\n", __func__);
1265
1266 ret = af9013_lock_led(state, 0);
1267 if (ret)
1268 goto error;
1269
1270 ret = af9013_power_ctrl(state, 0);
1271error:
1272 return ret;
1273}
1274
1275static int af9013_init(struct dvb_frontend *fe)
1276{
1277 struct af9013_state *state = fe->demodulator_priv;
1278 int ret, i, len;
1279 u8 tmp0, tmp1;
1280 struct regdesc *init;
1281 deb_info("%s\n", __func__);
1282
1283 /* reset OFDM */
1284 ret = af9013_reset(state, 0);
1285 if (ret)
1286 goto error;
1287
1288 /* power on */
1289 ret = af9013_power_ctrl(state, 1);
1290 if (ret)
1291 goto error;
1292
1293 /* enable ADC */
1294 ret = af9013_write_reg(state, 0xd73a, 0xa4);
1295 if (ret)
1296 goto error;
1297
1298 /* write API version to firmware */
1299 for (i = 0; i < sizeof(state->config.api_version); i++) {
1300 ret = af9013_write_reg(state, 0x9bf2 + i,
1301 state->config.api_version[i]);
1302 if (ret)
1303 goto error;
1304 }
1305
1306 /* program ADC control */
1307 ret = af9013_set_adc_ctrl(state);
1308 if (ret)
1309 goto error;
1310
1311 /* set I2C master clock */
1312 ret = af9013_write_reg(state, 0xd416, 0x14);
1313 if (ret)
1314 goto error;
1315
1316 /* set 16 embx */
1317 ret = af9013_write_reg_bits(state, 0xd700, 1, 1, 1);
1318 if (ret)
1319 goto error;
1320
1321 /* set no trigger */
1322 ret = af9013_write_reg_bits(state, 0xd700, 2, 1, 0);
1323 if (ret)
1324 goto error;
1325
1326 /* set read-update bit for constellation */
1327 ret = af9013_write_reg_bits(state, 0xd371, 1, 1, 1);
1328 if (ret)
1329 goto error;
1330
1331 /* enable FEC monitor */
1332 ret = af9013_write_reg_bits(state, 0xd392, 1, 1, 1);
1333 if (ret)
1334 goto error;
1335
1336 /* load OFSM settings */
1337 deb_info("%s: load ofsm settings\n", __func__);
1338 len = ARRAY_SIZE(ofsm_init);
1339 init = ofsm_init;
1340 for (i = 0; i < len; i++) {
1341 ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos,
1342 init[i].len, init[i].val);
1343 if (ret)
1344 goto error;
1345 }
1346
1347 /* load tuner specific settings */
1348 deb_info("%s: load tuner specific settings\n", __func__);
1349 switch (state->config.tuner) {
1350 case AF9013_TUNER_MXL5003D:
1351 len = ARRAY_SIZE(tuner_init_mxl5003d);
1352 init = tuner_init_mxl5003d;
1353 break;
1354 case AF9013_TUNER_MXL5005D:
1355 case AF9013_TUNER_MXL5005R:
1356 len = ARRAY_SIZE(tuner_init_mxl5005);
1357 init = tuner_init_mxl5005;
1358 break;
1359 case AF9013_TUNER_ENV77H11D5:
1360 len = ARRAY_SIZE(tuner_init_env77h11d5);
1361 init = tuner_init_env77h11d5;
1362 break;
1363 case AF9013_TUNER_MT2060:
1364 len = ARRAY_SIZE(tuner_init_mt2060);
1365 init = tuner_init_mt2060;
1366 break;
1367 case AF9013_TUNER_MC44S803:
1368 len = ARRAY_SIZE(tuner_init_mc44s803);
1369 init = tuner_init_mc44s803;
1370 break;
1371 case AF9013_TUNER_QT1010:
1372 case AF9013_TUNER_QT1010A:
1373 len = ARRAY_SIZE(tuner_init_qt1010);
1374 init = tuner_init_qt1010;
1375 break;
1376 case AF9013_TUNER_MT2060_2:
1377 len = ARRAY_SIZE(tuner_init_mt2060_2);
1378 init = tuner_init_mt2060_2;
1379 break;
1380 case AF9013_TUNER_TDA18271:
1381 len = ARRAY_SIZE(tuner_init_tda18271);
1382 init = tuner_init_tda18271;
1383 break;
1384 case AF9013_TUNER_UNKNOWN:
1385 default:
1386 len = ARRAY_SIZE(tuner_init_unknown);
1387 init = tuner_init_unknown;
1388 break;
1389 }
1390
1391 for (i = 0; i < len; i++) {
1392 ret = af9013_write_reg_bits(state, init[i].addr, init[i].pos,
1393 init[i].len, init[i].val);
1394 if (ret)
1395 goto error;
1396 }
1397
1398 /* set TS mode */
1399 deb_info("%s: setting ts mode\n", __func__);
1400 tmp0 = 0; /* parallel mode */
1401 tmp1 = 0; /* serial mode */
1402 switch (state->config.output_mode) {
1403 case AF9013_OUTPUT_MODE_PARALLEL:
1404 tmp0 = 1;
1405 break;
1406 case AF9013_OUTPUT_MODE_SERIAL:
1407 tmp1 = 1;
1408 break;
1409 case AF9013_OUTPUT_MODE_USB:
1410 /* usb mode for AF9015 */
1411 default:
1412 break;
1413 }
1414 ret = af9013_write_reg_bits(state, 0xd500, 1, 1, tmp0); /* parallel */
1415 if (ret)
1416 goto error;
1417 ret = af9013_write_reg_bits(state, 0xd500, 2, 1, tmp1); /* serial */
1418 if (ret)
1419 goto error;
1420
1421 /* enable lock led */
1422 ret = af9013_lock_led(state, 1);
1423 if (ret)
1424 goto error;
1425
1426error:
1427 return ret;
1428}
1429
1430static struct dvb_frontend_ops af9013_ops;
1431
1432static int af9013_download_firmware(struct af9013_state *state)
1433{
1434 int i, len, packets, remainder, ret;
1435 const struct firmware *fw;
1436 u16 addr = 0x5100; /* firmware start address */
1437 u16 checksum = 0;
1438 u8 val;
1439 u8 fw_params[4];
1440 u8 *data;
1441 u8 *fw_file = AF9013_DEFAULT_FIRMWARE;
1442
1443 msleep(100);
1444 /* check whether firmware is already running */
1445 ret = af9013_read_reg(state, 0x98be, &val);
1446 if (ret)
1447 goto error;
1448 else
1449 deb_info("%s: firmware status:%02x\n", __func__, val);
1450
1451 if (val == 0x0c) /* fw is running, no need for download */
1452 goto exit;
1453
1454 info("found a '%s' in cold state, will try to load a firmware",
1455 af9013_ops.info.name);
1456
1457 /* request the firmware, this will block and timeout */
1458 ret = request_firmware(&fw, fw_file, &state->i2c->dev);
1459 if (ret) {
1460 err("did not find the firmware file. (%s) "
1461 "Please see linux/Documentation/dvb/ for more details" \
1462 " on firmware-problems. (%d)",
1463 fw_file, ret);
1464 goto error;
1465 }
1466
1467 info("downloading firmware from file '%s'", fw_file);
1468
1469 /* calc checksum */
1470 for (i = 0; i < fw->size; i++)
1471 checksum += fw->data[i];
1472
1473 fw_params[0] = checksum >> 8;
1474 fw_params[1] = checksum & 0xff;
1475 fw_params[2] = fw->size >> 8;
1476 fw_params[3] = fw->size & 0xff;
1477
1478 /* write fw checksum & size */
1479 ret = af9013_write_ofsm_regs(state, 0x50fc,
1480 fw_params, sizeof(fw_params));
1481 if (ret)
1482 goto error_release;
1483
1484 #define FW_PACKET_MAX_DATA 16
1485
1486 packets = fw->size / FW_PACKET_MAX_DATA;
1487 remainder = fw->size % FW_PACKET_MAX_DATA;
1488 len = FW_PACKET_MAX_DATA;
1489 for (i = 0; i <= packets; i++) {
1490 if (i == packets) /* set size of the last packet */
1491 len = remainder;
1492
1493 data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
1494 ret = af9013_write_ofsm_regs(state, addr, data, len);
1495 addr += FW_PACKET_MAX_DATA;
1496
1497 if (ret) {
1498 err("firmware download failed at %d with %d", i, ret);
1499 goto error_release;
1500 }
1501 }
1502
1503 /* request boot firmware */
1504 ret = af9013_write_reg(state, 0xe205, 1);
1505 if (ret)
1506 goto error_release;
1507
1508 for (i = 0; i < 15; i++) {
1509 msleep(100);
1510
1511 /* check firmware status */
1512 ret = af9013_read_reg(state, 0x98be, &val);
1513 if (ret)
1514 goto error_release;
1515
1516 deb_info("%s: firmware status:%02x\n", __func__, val);
1517
1518 if (val == 0x0c || val == 0x04) /* success or fail */
1519 break;
1520 }
1521
1522 if (val == 0x04) {
1523 err("firmware did not run");
1524 ret = -1;
1525 } else if (val != 0x0c) {
1526 err("firmware boot timeout");
1527 ret = -1;
1528 }
1529
1530error_release:
1531 release_firmware(fw);
1532error:
1533exit:
1534 if (!ret)
1535 info("found a '%s' in warm state.", af9013_ops.info.name);
1536 return ret;
1537}
1538
1539static int af9013_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
1540{
1541 int ret;
1542 struct af9013_state *state = fe->demodulator_priv;
1543 deb_info("%s: enable:%d\n", __func__, enable);
1544
1545 if (state->config.output_mode == AF9013_OUTPUT_MODE_USB)
1546 ret = af9013_write_reg_bits(state, 0xd417, 3, 1, enable);
1547 else
1548 ret = af9013_write_reg_bits(state, 0xd607, 2, 1, enable);
1549
1550 return ret;
1551}
1552
1553static void af9013_release(struct dvb_frontend *fe)
1554{
1555 struct af9013_state *state = fe->demodulator_priv;
1556 kfree(state);
1557}
1558
1559static struct dvb_frontend_ops af9013_ops;
1560
1561struct dvb_frontend *af9013_attach(const struct af9013_config *config,
1562 struct i2c_adapter *i2c)
1563{
1564 int ret;
1565 struct af9013_state *state = NULL;
1566 u8 buf[3], i;
1567
1568 /* allocate memory for the internal state */
1569 state = kzalloc(sizeof(struct af9013_state), GFP_KERNEL);
1570 if (state == NULL)
1571 goto error;
1572
1573 /* setup the state */
1574 state->i2c = i2c;
1575 memcpy(&state->config, config, sizeof(struct af9013_config));
1576
1577 /* chip version */
1578 ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]);
1579 if (ret)
1580 goto error;
1581
1582 /* ROM version */
1583 for (i = 0; i < 2; i++) {
1584 ret = af9013_read_reg(state, 0x116b + i, &buf[i]);
1585 if (ret)
1586 goto error;
1587 }
1588 deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__,
1589 buf[2], buf[0], buf[1]);
1590
1591 /* download firmware */
1592 if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) {
1593 ret = af9013_download_firmware(state);
1594 if (ret)
1595 goto error;
1596 }
1597
1598 /* firmware version */
1599 for (i = 0; i < 3; i++) {
1600 ret = af9013_read_reg(state, 0x5103 + i, &buf[i]);
1601 if (ret)
1602 goto error;
1603 }
1604 info("firmware version:%d.%d.%d", buf[0], buf[1], buf[2]);
1605
1606 /* settings for mp2if */
1607 if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) {
1608 /* AF9015 split PSB to 1.5k + 0.5k */
1609 ret = af9013_write_reg_bits(state, 0xd50b, 2, 1, 1);
1610 } else {
1611 /* AF9013 change the output bit to data7 */
1612 ret = af9013_write_reg_bits(state, 0xd500, 3, 1, 1);
1613 if (ret)
1614 goto error;
1615 /* AF9013 set mpeg to full speed */
1616 ret = af9013_write_reg_bits(state, 0xd502, 4, 1, 1);
1617 }
1618 if (ret)
1619 goto error;
1620 ret = af9013_write_reg_bits(state, 0xd520, 4, 1, 1);
1621 if (ret)
1622 goto error;
1623
1624 /* set GPIOs */
1625 for (i = 0; i < sizeof(state->config.gpio); i++) {
1626 ret = af9013_set_gpio(state, i, state->config.gpio[i]);
1627 if (ret)
1628 goto error;
1629 }
1630
1631 /* create dvb_frontend */
1632 memcpy(&state->frontend.ops, &af9013_ops,
1633 sizeof(struct dvb_frontend_ops));
1634 state->frontend.demodulator_priv = state;
1635
1636 return &state->frontend;
1637error:
1638 kfree(state);
1639 return NULL;
1640}
1641EXPORT_SYMBOL(af9013_attach);
1642
1643static struct dvb_frontend_ops af9013_ops = {
1644 .info = {
1645 .name = "Afatech AF9013 DVB-T",
1646 .type = FE_OFDM,
1647 .frequency_min = 174000000,
1648 .frequency_max = 862000000,
1649 .frequency_stepsize = 250000,
1650 .frequency_tolerance = 0,
1651 .caps =
1652 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1653 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1654 FE_CAN_QPSK | FE_CAN_QAM_16 |
1655 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1656 FE_CAN_TRANSMISSION_MODE_AUTO |
1657 FE_CAN_GUARD_INTERVAL_AUTO |
1658 FE_CAN_HIERARCHY_AUTO |
1659 FE_CAN_RECOVER |
1660 FE_CAN_MUTE_TS
1661 },
1662
1663 .release = af9013_release,
1664 .init = af9013_init,
1665 .sleep = af9013_sleep,
1666 .i2c_gate_ctrl = af9013_i2c_gate_ctrl,
1667
1668 .set_frontend = af9013_set_frontend,
1669 .get_frontend = af9013_get_frontend,
1670
1671 .get_tune_settings = af9013_get_tune_settings,
1672
1673 .read_status = af9013_read_status,
1674 .read_ber = af9013_read_ber,
1675 .read_signal_strength = af9013_read_signal_strength,
1676 .read_snr = af9013_read_snr,
1677 .read_ucblocks = af9013_read_ucblocks,
1678};
1679
1680module_param_named(debug, af9013_debug, int, 0644);
1681MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
1682
1683MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
1684MODULE_DESCRIPTION("Afatech AF9013 DVB-T demodulator driver");
1685MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h
new file mode 100644
index 000000000000..28b90c91c766
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9013.h
@@ -0,0 +1,107 @@
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#ifndef _AF9013_H_
25#define _AF9013_H_
26
27#include <linux/dvb/frontend.h>
28
29enum af9013_ts_mode {
30 AF9013_OUTPUT_MODE_PARALLEL,
31 AF9013_OUTPUT_MODE_SERIAL,
32 AF9013_OUTPUT_MODE_USB, /* only for AF9015 */
33};
34
35enum af9013_tuner {
36 AF9013_TUNER_MXL5003D = 3, /* MaxLinear */
37 AF9013_TUNER_MXL5005D = 13, /* MaxLinear */
38 AF9013_TUNER_MXL5005R = 30, /* MaxLinear */
39 AF9013_TUNER_ENV77H11D5 = 129, /* Panasonic */
40 AF9013_TUNER_MT2060 = 130, /* Microtune */
41 AF9013_TUNER_MC44S803 = 133, /* Freescale */
42 AF9013_TUNER_QT1010 = 134, /* Quantek */
43 AF9013_TUNER_UNKNOWN = 140, /* for can tuners ? */
44 AF9013_TUNER_MT2060_2 = 147, /* Microtune */
45 AF9013_TUNER_TDA18271 = 156, /* NXP */
46 AF9013_TUNER_QT1010A = 162, /* Quantek */
47};
48
49/* AF9013/5 GPIOs (mostly guessed)
50 demod#1-gpio#0 - set demod#2 i2c-addr for dual devices
51 demod#1-gpio#1 - xtal setting (?)
52 demod#1-gpio#3 - tuner#1
53 demod#2-gpio#0 - tuner#2
54 demod#2-gpio#1 - xtal setting (?)
55*/
56#define AF9013_GPIO_ON (1 << 0)
57#define AF9013_GPIO_EN (1 << 1)
58#define AF9013_GPIO_O (1 << 2)
59#define AF9013_GPIO_I (1 << 3)
60
61#define AF9013_GPIO_LO (AF9013_GPIO_ON|AF9013_GPIO_EN)
62#define AF9013_GPIO_HI (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
63
64#define AF9013_GPIO_TUNER_ON (AF9013_GPIO_ON|AF9013_GPIO_EN)
65#define AF9013_GPIO_TUNER_OFF (AF9013_GPIO_ON|AF9013_GPIO_EN|AF9013_GPIO_O)
66
67struct af9013_config {
68 /* demodulator's I2C address */
69 u8 demod_address;
70
71 /* frequencies in kHz */
72 u32 adc_clock;
73
74 /* tuner ID */
75 u8 tuner;
76
77 /* tuner IF */
78 u16 tuner_if;
79
80 /* TS data output mode */
81 u8 output_mode:2;
82
83 /* RF spectrum inversion */
84 u8 rf_spec_inv:1;
85
86 /* API version */
87 u8 api_version[4];
88
89 /* GPIOs */
90 u8 gpio[4];
91};
92
93
94#if defined(CONFIG_DVB_AF9013) || \
95 (defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE))
96extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
97 struct i2c_adapter *i2c);
98#else
99static inline struct dvb_frontend *af9013_attach(
100const struct af9013_config *config, struct i2c_adapter *i2c)
101{
102 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
103 return NULL;
104}
105#endif /* CONFIG_DVB_AF9013 */
106
107#endif /* _AF9013_H_ */
diff --git a/drivers/media/dvb/frontends/af9013_priv.h b/drivers/media/dvb/frontends/af9013_priv.h
new file mode 100644
index 000000000000..163e251d0b73
--- /dev/null
+++ b/drivers/media/dvb/frontends/af9013_priv.h
@@ -0,0 +1,869 @@
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#ifndef _AF9013_PRIV_
25#define _AF9013_PRIV_
26
27#define LOG_PREFIX "af9013"
28extern int af9013_debug;
29
30#define dprintk(var, level, args...) \
31 do { if ((var & level)) printk(args); } while (0)
32
33#define debug_dump(b, l, func) {\
34 int loop_; \
35 for (loop_ = 0; loop_ < l; loop_++) \
36 func("%02x ", b[loop_]); \
37 func("\n");\
38}
39
40#define deb_info(args...) dprintk(af9013_debug, 0x01, args)
41
42#undef err
43#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
44#undef info
45#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
46#undef warn
47#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
48
49#define AF9013_DEFAULT_FIRMWARE "dvb-fe-af9013.fw"
50
51struct regdesc {
52 u16 addr;
53 u8 pos:4;
54 u8 len:4;
55 u8 val;
56};
57
58struct snr_table {
59 u32 val;
60 u8 snr;
61};
62
63/* QPSK SNR lookup table */
64static struct snr_table qpsk_snr_table[] = {
65 { 0x0b4771, 0 },
66 { 0x0c1aed, 1 },
67 { 0x0d0d27, 2 },
68 { 0x0e4d19, 3 },
69 { 0x0e5da8, 4 },
70 { 0x107097, 5 },
71 { 0x116975, 6 },
72 { 0x1252d9, 7 },
73 { 0x131fa4, 8 },
74 { 0x13d5e1, 9 },
75 { 0x148e53, 10 },
76 { 0x15358b, 11 },
77 { 0x15dd29, 12 },
78 { 0x168112, 13 },
79 { 0x170b61, 14 },
80 { 0xffffff, 15 },
81};
82
83/* QAM16 SNR lookup table */
84static struct snr_table qam16_snr_table[] = {
85 { 0x05eb62, 5 },
86 { 0x05fecf, 6 },
87 { 0x060b80, 7 },
88 { 0x062501, 8 },
89 { 0x064865, 9 },
90 { 0x069604, 10 },
91 { 0x06f356, 11 },
92 { 0x07706a, 12 },
93 { 0x0804d3, 13 },
94 { 0x089d1a, 14 },
95 { 0x093e3d, 15 },
96 { 0x09e35d, 16 },
97 { 0x0a7c3c, 17 },
98 { 0x0afaf8, 18 },
99 { 0x0b719d, 19 },
100 { 0xffffff, 20 },
101};
102
103/* QAM64 SNR lookup table */
104static struct snr_table qam64_snr_table[] = {
105 { 0x03109b, 12 },
106 { 0x0310d4, 13 },
107 { 0x031920, 14 },
108 { 0x0322d0, 15 },
109 { 0x0339fc, 16 },
110 { 0x0364a1, 17 },
111 { 0x038bcc, 18 },
112 { 0x03c7d3, 19 },
113 { 0x0408cc, 20 },
114 { 0x043bed, 21 },
115 { 0x048061, 22 },
116 { 0x04be95, 23 },
117 { 0x04fa7d, 24 },
118 { 0x052405, 25 },
119 { 0x05570d, 26 },
120 { 0xffffff, 27 },
121};
122
123static struct regdesc ofsm_init[] = {
124 { 0xd73a, 0, 8, 0xa1 },
125 { 0xd73b, 0, 8, 0x1f },
126 { 0xd73c, 4, 4, 0x0a },
127 { 0xd732, 3, 1, 0x00 },
128 { 0xd731, 4, 2, 0x03 },
129 { 0xd73d, 7, 1, 0x01 },
130 { 0xd740, 0, 1, 0x00 },
131 { 0xd740, 1, 1, 0x00 },
132 { 0xd740, 2, 1, 0x00 },
133 { 0xd740, 3, 1, 0x01 },
134 { 0xd3c1, 4, 1, 0x01 },
135 { 0xd3a2, 0, 8, 0x00 },
136 { 0xd3a3, 0, 8, 0x04 },
137 { 0xd305, 0, 8, 0x32 },
138 { 0xd306, 0, 8, 0x10 },
139 { 0xd304, 0, 8, 0x04 },
140 { 0x9112, 0, 1, 0x01 },
141 { 0x911d, 0, 1, 0x01 },
142 { 0x911a, 0, 1, 0x01 },
143 { 0x911b, 0, 1, 0x01 },
144 { 0x9bce, 0, 4, 0x02 },
145 { 0x9116, 0, 1, 0x01 },
146 { 0x9bd1, 0, 1, 0x01 },
147 { 0xd2e0, 0, 8, 0xd0 },
148 { 0xd2e9, 0, 4, 0x0d },
149 { 0xd38c, 0, 8, 0xfc },
150 { 0xd38d, 0, 8, 0x00 },
151 { 0xd38e, 0, 8, 0x7e },
152 { 0xd38f, 0, 8, 0x00 },
153 { 0xd390, 0, 8, 0x2f },
154 { 0xd145, 4, 1, 0x01 },
155 { 0xd1a9, 4, 1, 0x01 },
156 { 0xd158, 5, 3, 0x01 },
157 { 0xd159, 0, 6, 0x06 },
158 { 0xd167, 0, 8, 0x00 },
159 { 0xd168, 0, 4, 0x07 },
160 { 0xd1c3, 5, 3, 0x00 },
161 { 0xd1c4, 0, 6, 0x00 },
162 { 0xd1c5, 0, 7, 0x10 },
163 { 0xd1c6, 0, 3, 0x02 },
164 { 0xd080, 2, 5, 0x03 },
165 { 0xd081, 4, 4, 0x09 },
166 { 0xd098, 4, 4, 0x0f },
167 { 0xd098, 0, 4, 0x03 },
168 { 0xdbc0, 3, 1, 0x01 },
169 { 0xdbc0, 4, 1, 0x01 },
170 { 0xdbc7, 0, 8, 0x08 },
171 { 0xdbc8, 4, 4, 0x00 },
172 { 0xdbc9, 0, 5, 0x01 },
173 { 0xd280, 0, 8, 0xe0 },
174 { 0xd281, 0, 8, 0xff },
175 { 0xd282, 0, 8, 0xff },
176 { 0xd283, 0, 8, 0xc3 },
177 { 0xd284, 0, 8, 0xff },
178 { 0xd285, 0, 4, 0x01 },
179 { 0xd0f0, 0, 7, 0x1a },
180 { 0xd0f1, 4, 1, 0x01 },
181 { 0xd0f2, 0, 8, 0x0c },
182 { 0xd103, 0, 4, 0x08 },
183 { 0xd0f8, 0, 7, 0x20 },
184 { 0xd111, 5, 1, 0x00 },
185 { 0xd111, 6, 1, 0x00 },
186 { 0x910b, 0, 8, 0x0a },
187 { 0x9115, 0, 8, 0x02 },
188 { 0x910c, 0, 8, 0x02 },
189 { 0x910d, 0, 8, 0x08 },
190 { 0x910e, 0, 8, 0x0a },
191 { 0x9bf6, 0, 8, 0x06 },
192 { 0x9bf8, 0, 8, 0x02 },
193 { 0x9bf7, 0, 8, 0x05 },
194 { 0x9bf9, 0, 8, 0x0f },
195 { 0x9bfc, 0, 8, 0x13 },
196 { 0x9bd3, 0, 8, 0xff },
197 { 0x9bbe, 0, 1, 0x01 },
198 { 0x9bcc, 0, 1, 0x01 },
199};
200
201/* Panasonic ENV77H11D5 tuner init
202 AF9013_TUNER_ENV77H11D5 = 129 */
203static struct regdesc tuner_init_env77h11d5[] = {
204 { 0x9bd5, 0, 8, 0x01 },
205 { 0x9bd6, 0, 8, 0x03 },
206 { 0x9bbe, 0, 8, 0x01 },
207 { 0xd1a0, 1, 1, 0x01 },
208 { 0xd000, 0, 1, 0x01 },
209 { 0xd000, 1, 1, 0x00 },
210 { 0xd001, 1, 1, 0x01 },
211 { 0xd001, 0, 1, 0x00 },
212 { 0xd001, 5, 1, 0x00 },
213 { 0xd002, 0, 5, 0x19 },
214 { 0xd003, 0, 5, 0x1a },
215 { 0xd004, 0, 5, 0x19 },
216 { 0xd005, 0, 5, 0x1a },
217 { 0xd00e, 0, 5, 0x10 },
218 { 0xd00f, 0, 3, 0x04 },
219 { 0xd00f, 3, 3, 0x05 },
220 { 0xd010, 0, 3, 0x04 },
221 { 0xd010, 3, 3, 0x05 },
222 { 0xd016, 4, 4, 0x03 },
223 { 0xd01f, 0, 6, 0x0a },
224 { 0xd020, 0, 6, 0x0a },
225 { 0x9bda, 0, 8, 0x00 },
226 { 0x9be3, 0, 8, 0x00 },
227 { 0xd015, 0, 8, 0x50 },
228 { 0xd016, 0, 1, 0x00 },
229 { 0xd044, 0, 8, 0x46 },
230 { 0xd045, 0, 1, 0x00 },
231 { 0xd008, 0, 8, 0xdf },
232 { 0xd009, 0, 2, 0x02 },
233 { 0xd006, 0, 8, 0x44 },
234 { 0xd007, 0, 2, 0x01 },
235 { 0xd00c, 0, 8, 0xeb },
236 { 0xd00d, 0, 2, 0x02 },
237 { 0xd00a, 0, 8, 0xf4 },
238 { 0xd00b, 0, 2, 0x01 },
239 { 0x9bba, 0, 8, 0xf9 },
240 { 0x9bc3, 0, 8, 0xdf },
241 { 0x9bc4, 0, 8, 0x02 },
242 { 0x9bc5, 0, 8, 0xeb },
243 { 0x9bc6, 0, 8, 0x02 },
244 { 0x9bc9, 0, 8, 0x52 },
245 { 0xd011, 0, 8, 0x3c },
246 { 0xd012, 0, 2, 0x01 },
247 { 0xd013, 0, 8, 0xf7 },
248 { 0xd014, 0, 2, 0x02 },
249 { 0xd040, 0, 8, 0x0b },
250 { 0xd041, 0, 2, 0x02 },
251 { 0xd042, 0, 8, 0x4d },
252 { 0xd043, 0, 2, 0x00 },
253 { 0xd045, 1, 1, 0x00 },
254 { 0x9bcf, 0, 1, 0x01 },
255 { 0xd045, 2, 1, 0x01 },
256 { 0xd04f, 0, 8, 0x9a },
257 { 0xd050, 0, 1, 0x01 },
258 { 0xd051, 0, 8, 0x5a },
259 { 0xd052, 0, 1, 0x01 },
260 { 0xd053, 0, 8, 0x50 },
261 { 0xd054, 0, 8, 0x46 },
262 { 0x9bd7, 0, 8, 0x0a },
263 { 0x9bd8, 0, 8, 0x14 },
264 { 0x9bd9, 0, 8, 0x08 },
265};
266
267/* Microtune MT2060 tuner init
268 AF9013_TUNER_MT2060 = 130 */
269static struct regdesc tuner_init_mt2060[] = {
270 { 0x9bd5, 0, 8, 0x01 },
271 { 0x9bd6, 0, 8, 0x07 },
272 { 0xd1a0, 1, 1, 0x01 },
273 { 0xd000, 0, 1, 0x01 },
274 { 0xd000, 1, 1, 0x00 },
275 { 0xd001, 1, 1, 0x01 },
276 { 0xd001, 0, 1, 0x00 },
277 { 0xd001, 5, 1, 0x00 },
278 { 0xd002, 0, 5, 0x19 },
279 { 0xd003, 0, 5, 0x1a },
280 { 0xd004, 0, 5, 0x19 },
281 { 0xd005, 0, 5, 0x1a },
282 { 0xd00e, 0, 5, 0x10 },
283 { 0xd00f, 0, 3, 0x04 },
284 { 0xd00f, 3, 3, 0x05 },
285 { 0xd010, 0, 3, 0x04 },
286 { 0xd010, 3, 3, 0x05 },
287 { 0xd016, 4, 4, 0x03 },
288 { 0xd01f, 0, 6, 0x0a },
289 { 0xd020, 0, 6, 0x0a },
290 { 0x9bda, 0, 8, 0x00 },
291 { 0x9be3, 0, 8, 0x00 },
292 { 0x9bbe, 0, 1, 0x00 },
293 { 0x9bcc, 0, 1, 0x00 },
294 { 0x9bb9, 0, 8, 0x75 },
295 { 0x9bcd, 0, 8, 0x24 },
296 { 0x9bff, 0, 8, 0x30 },
297 { 0xd015, 0, 8, 0x46 },
298 { 0xd016, 0, 1, 0x00 },
299 { 0xd044, 0, 8, 0x46 },
300 { 0xd045, 0, 1, 0x00 },
301 { 0xd008, 0, 8, 0x0f },
302 { 0xd009, 0, 2, 0x02 },
303 { 0xd006, 0, 8, 0x32 },
304 { 0xd007, 0, 2, 0x01 },
305 { 0xd00c, 0, 8, 0x36 },
306 { 0xd00d, 0, 2, 0x03 },
307 { 0xd00a, 0, 8, 0x35 },
308 { 0xd00b, 0, 2, 0x01 },
309 { 0x9bc7, 0, 8, 0x07 },
310 { 0x9bc8, 0, 8, 0x90 },
311 { 0x9bc3, 0, 8, 0x0f },
312 { 0x9bc4, 0, 8, 0x02 },
313 { 0x9bc5, 0, 8, 0x36 },
314 { 0x9bc6, 0, 8, 0x03 },
315 { 0x9bba, 0, 8, 0xc9 },
316 { 0x9bc9, 0, 8, 0x79 },
317 { 0xd011, 0, 8, 0x10 },
318 { 0xd012, 0, 2, 0x01 },
319 { 0xd013, 0, 8, 0x45 },
320 { 0xd014, 0, 2, 0x03 },
321 { 0xd040, 0, 8, 0x98 },
322 { 0xd041, 0, 2, 0x00 },
323 { 0xd042, 0, 8, 0xcf },
324 { 0xd043, 0, 2, 0x03 },
325 { 0xd045, 1, 1, 0x00 },
326 { 0x9bcf, 0, 1, 0x01 },
327 { 0xd045, 2, 1, 0x01 },
328 { 0xd04f, 0, 8, 0x9a },
329 { 0xd050, 0, 1, 0x01 },
330 { 0xd051, 0, 8, 0x5a },
331 { 0xd052, 0, 1, 0x01 },
332 { 0xd053, 0, 8, 0x50 },
333 { 0xd054, 0, 8, 0x46 },
334 { 0x9bd7, 0, 8, 0x0a },
335 { 0x9bd8, 0, 8, 0x14 },
336 { 0x9bd9, 0, 8, 0x08 },
337 { 0x9bd0, 0, 8, 0xcc },
338 { 0x9be4, 0, 8, 0xa0 },
339 { 0x9bbd, 0, 8, 0x8e },
340 { 0x9be2, 0, 8, 0x4d },
341 { 0x9bee, 0, 1, 0x01 },
342};
343
344/* Microtune MT2060 tuner init
345 AF9013_TUNER_MT2060_2 = 147 */
346static struct regdesc tuner_init_mt2060_2[] = {
347 { 0x9bd5, 0, 8, 0x01 },
348 { 0x9bd6, 0, 8, 0x06 },
349 { 0x9bbe, 0, 8, 0x01 },
350 { 0xd1a0, 1, 1, 0x01 },
351 { 0xd000, 0, 1, 0x01 },
352 { 0xd000, 1, 1, 0x00 },
353 { 0xd001, 1, 1, 0x01 },
354 { 0xd001, 0, 1, 0x00 },
355 { 0xd001, 5, 1, 0x00 },
356 { 0xd002, 0, 5, 0x19 },
357 { 0xd003, 0, 5, 0x1a },
358 { 0xd004, 0, 5, 0x19 },
359 { 0xd005, 0, 5, 0x1a },
360 { 0xd00e, 0, 5, 0x10 },
361 { 0xd00f, 0, 3, 0x04 },
362 { 0xd00f, 3, 3, 0x05 },
363 { 0xd010, 0, 3, 0x04 },
364 { 0xd010, 3, 3, 0x05 },
365 { 0xd016, 4, 4, 0x03 },
366 { 0xd01f, 0, 6, 0x0a },
367 { 0xd020, 0, 6, 0x0a },
368 { 0xd015, 0, 8, 0x46 },
369 { 0xd016, 0, 1, 0x00 },
370 { 0xd044, 0, 8, 0x46 },
371 { 0xd045, 0, 1, 0x00 },
372 { 0xd008, 0, 8, 0x0f },
373 { 0xd009, 0, 2, 0x02 },
374 { 0xd006, 0, 8, 0x32 },
375 { 0xd007, 0, 2, 0x01 },
376 { 0xd00c, 0, 8, 0x36 },
377 { 0xd00d, 0, 2, 0x03 },
378 { 0xd00a, 0, 8, 0x35 },
379 { 0xd00b, 0, 2, 0x01 },
380 { 0x9bc7, 0, 8, 0x07 },
381 { 0x9bc8, 0, 8, 0x90 },
382 { 0x9bc3, 0, 8, 0x0f },
383 { 0x9bc4, 0, 8, 0x02 },
384 { 0x9bc5, 0, 8, 0x36 },
385 { 0x9bc6, 0, 8, 0x03 },
386 { 0x9bba, 0, 8, 0xc9 },
387 { 0x9bc9, 0, 8, 0x79 },
388 { 0xd011, 0, 8, 0x10 },
389 { 0xd012, 0, 2, 0x01 },
390 { 0xd013, 0, 8, 0x45 },
391 { 0xd014, 0, 2, 0x03 },
392 { 0xd040, 0, 8, 0x98 },
393 { 0xd041, 0, 2, 0x00 },
394 { 0xd042, 0, 8, 0xcf },
395 { 0xd043, 0, 2, 0x03 },
396 { 0xd045, 1, 1, 0x00 },
397 { 0x9bcf, 0, 8, 0x01 },
398 { 0xd045, 2, 1, 0x01 },
399 { 0xd04f, 0, 8, 0x9a },
400 { 0xd050, 0, 1, 0x01 },
401 { 0xd051, 0, 8, 0x5a },
402 { 0xd052, 0, 1, 0x01 },
403 { 0xd053, 0, 8, 0x96 },
404 { 0xd054, 0, 8, 0x46 },
405 { 0xd045, 7, 1, 0x00 },
406 { 0x9bd7, 0, 8, 0x0a },
407 { 0x9bd8, 0, 8, 0x14 },
408 { 0x9bd9, 0, 8, 0x08 },
409};
410
411/* MaxLinear MXL5003 tuner init
412 AF9013_TUNER_MXL5003D = 3 */
413static struct regdesc tuner_init_mxl5003d[] = {
414 { 0x9bd5, 0, 8, 0x01 },
415 { 0x9bd6, 0, 8, 0x09 },
416 { 0xd1a0, 1, 1, 0x01 },
417 { 0xd000, 0, 1, 0x01 },
418 { 0xd000, 1, 1, 0x00 },
419 { 0xd001, 1, 1, 0x01 },
420 { 0xd001, 0, 1, 0x00 },
421 { 0xd001, 5, 1, 0x00 },
422 { 0xd002, 0, 5, 0x19 },
423 { 0xd003, 0, 5, 0x1a },
424 { 0xd004, 0, 5, 0x19 },
425 { 0xd005, 0, 5, 0x1a },
426 { 0xd00e, 0, 5, 0x10 },
427 { 0xd00f, 0, 3, 0x04 },
428 { 0xd00f, 3, 3, 0x05 },
429 { 0xd010, 0, 3, 0x04 },
430 { 0xd010, 3, 3, 0x05 },
431 { 0xd016, 4, 4, 0x03 },
432 { 0xd01f, 0, 6, 0x0a },
433 { 0xd020, 0, 6, 0x0a },
434 { 0x9bda, 0, 8, 0x00 },
435 { 0x9be3, 0, 8, 0x00 },
436 { 0x9bfc, 0, 8, 0x0f },
437 { 0x9bf6, 0, 8, 0x01 },
438 { 0x9bbe, 0, 1, 0x01 },
439 { 0xd015, 0, 8, 0x33 },
440 { 0xd016, 0, 1, 0x00 },
441 { 0xd044, 0, 8, 0x40 },
442 { 0xd045, 0, 1, 0x00 },
443 { 0xd008, 0, 8, 0x0f },
444 { 0xd009, 0, 2, 0x02 },
445 { 0xd006, 0, 8, 0x6c },
446 { 0xd007, 0, 2, 0x00 },
447 { 0xd00c, 0, 8, 0x3d },
448 { 0xd00d, 0, 2, 0x00 },
449 { 0xd00a, 0, 8, 0x45 },
450 { 0xd00b, 0, 2, 0x01 },
451 { 0x9bc7, 0, 8, 0x07 },
452 { 0x9bc8, 0, 8, 0x52 },
453 { 0x9bc3, 0, 8, 0x0f },
454 { 0x9bc4, 0, 8, 0x02 },
455 { 0x9bc5, 0, 8, 0x3d },
456 { 0x9bc6, 0, 8, 0x00 },
457 { 0x9bba, 0, 8, 0xa2 },
458 { 0x9bc9, 0, 8, 0xa0 },
459 { 0xd011, 0, 8, 0x56 },
460 { 0xd012, 0, 2, 0x00 },
461 { 0xd013, 0, 8, 0x50 },
462 { 0xd014, 0, 2, 0x00 },
463 { 0xd040, 0, 8, 0x56 },
464 { 0xd041, 0, 2, 0x00 },
465 { 0xd042, 0, 8, 0x50 },
466 { 0xd043, 0, 2, 0x00 },
467 { 0xd045, 1, 1, 0x00 },
468 { 0x9bcf, 0, 8, 0x01 },
469 { 0xd045, 2, 1, 0x01 },
470 { 0xd04f, 0, 8, 0x9a },
471 { 0xd050, 0, 1, 0x01 },
472 { 0xd051, 0, 8, 0x5a },
473 { 0xd052, 0, 1, 0x01 },
474 { 0xd053, 0, 8, 0x50 },
475 { 0xd054, 0, 8, 0x46 },
476 { 0x9bd7, 0, 8, 0x0a },
477 { 0x9bd8, 0, 8, 0x14 },
478 { 0x9bd9, 0, 8, 0x08 },
479};
480
481/* MaxLinear MXL5005 tuner init
482 AF9013_TUNER_MXL5005D = 13
483 AF9013_TUNER_MXL5005R = 30 */
484static struct regdesc tuner_init_mxl5005[] = {
485 { 0x9bd5, 0, 8, 0x01 },
486 { 0x9bd6, 0, 8, 0x07 },
487 { 0xd1a0, 1, 1, 0x01 },
488 { 0xd000, 0, 1, 0x01 },
489 { 0xd000, 1, 1, 0x00 },
490 { 0xd001, 1, 1, 0x01 },
491 { 0xd001, 0, 1, 0x00 },
492 { 0xd001, 5, 1, 0x00 },
493 { 0xd002, 0, 5, 0x19 },
494 { 0xd003, 0, 5, 0x1a },
495 { 0xd004, 0, 5, 0x19 },
496 { 0xd005, 0, 5, 0x1a },
497 { 0xd00e, 0, 5, 0x10 },
498 { 0xd00f, 0, 3, 0x04 },
499 { 0xd00f, 3, 3, 0x05 },
500 { 0xd010, 0, 3, 0x04 },
501 { 0xd010, 3, 3, 0x05 },
502 { 0xd016, 4, 4, 0x03 },
503 { 0xd01f, 0, 6, 0x0a },
504 { 0xd020, 0, 6, 0x0a },
505 { 0x9bda, 0, 8, 0x01 },
506 { 0x9be3, 0, 8, 0x01 },
507 { 0x9bbe, 0, 1, 0x01 },
508 { 0x9bcc, 0, 1, 0x01 },
509 { 0x9bb9, 0, 8, 0x00 },
510 { 0x9bcd, 0, 8, 0x28 },
511 { 0x9bff, 0, 8, 0x24 },
512 { 0xd015, 0, 8, 0x40 },
513 { 0xd016, 0, 1, 0x00 },
514 { 0xd044, 0, 8, 0x40 },
515 { 0xd045, 0, 1, 0x00 },
516 { 0xd008, 0, 8, 0x0f },
517 { 0xd009, 0, 2, 0x02 },
518 { 0xd006, 0, 8, 0x73 },
519 { 0xd007, 0, 2, 0x01 },
520 { 0xd00c, 0, 8, 0xfa },
521 { 0xd00d, 0, 2, 0x01 },
522 { 0xd00a, 0, 8, 0xff },
523 { 0xd00b, 0, 2, 0x01 },
524 { 0x9bc7, 0, 8, 0x23 },
525 { 0x9bc8, 0, 8, 0x55 },
526 { 0x9bc3, 0, 8, 0x01 },
527 { 0x9bc4, 0, 8, 0x02 },
528 { 0x9bc5, 0, 8, 0xfa },
529 { 0x9bc6, 0, 8, 0x01 },
530 { 0x9bba, 0, 8, 0xff },
531 { 0x9bc9, 0, 8, 0xff },
532 { 0x9bd3, 0, 8, 0x95 },
533 { 0xd011, 0, 8, 0x70 },
534 { 0xd012, 0, 2, 0x01 },
535 { 0xd013, 0, 8, 0xfb },
536 { 0xd014, 0, 2, 0x01 },
537 { 0xd040, 0, 8, 0x70 },
538 { 0xd041, 0, 2, 0x01 },
539 { 0xd042, 0, 8, 0xfb },
540 { 0xd043, 0, 2, 0x01 },
541 { 0xd045, 1, 1, 0x00 },
542 { 0x9bcf, 0, 1, 0x01 },
543 { 0xd045, 2, 1, 0x01 },
544 { 0xd04f, 0, 8, 0x9a },
545 { 0xd050, 0, 1, 0x01 },
546 { 0xd051, 0, 8, 0x5a },
547 { 0xd052, 0, 1, 0x01 },
548 { 0xd053, 0, 8, 0x50 },
549 { 0xd054, 0, 8, 0x46 },
550 { 0x9bd7, 0, 8, 0x0a },
551 { 0x9bd8, 0, 8, 0x14 },
552 { 0x9bd9, 0, 8, 0x08 },
553 { 0x9bd0, 0, 8, 0x93 },
554 { 0x9be4, 0, 8, 0xfe },
555 { 0x9bbd, 0, 8, 0x63 },
556 { 0x9be2, 0, 8, 0xfe },
557 { 0x9bee, 0, 1, 0x01 },
558};
559
560/* Quantek QT1010 tuner init
561 AF9013_TUNER_QT1010 = 134
562 AF9013_TUNER_QT1010A = 162 */
563static struct regdesc tuner_init_qt1010[] = {
564 { 0x9bd5, 0, 8, 0x01 },
565 { 0x9bd6, 0, 8, 0x09 },
566 { 0xd1a0, 1, 1, 0x01 },
567 { 0xd000, 0, 1, 0x01 },
568 { 0xd000, 1, 1, 0x00 },
569 { 0xd001, 1, 1, 0x01 },
570 { 0xd001, 0, 1, 0x00 },
571 { 0xd001, 5, 1, 0x00 },
572 { 0xd002, 0, 5, 0x19 },
573 { 0xd003, 0, 5, 0x1a },
574 { 0xd004, 0, 5, 0x19 },
575 { 0xd005, 0, 5, 0x1a },
576 { 0xd00e, 0, 5, 0x10 },
577 { 0xd00f, 0, 3, 0x04 },
578 { 0xd00f, 3, 3, 0x05 },
579 { 0xd010, 0, 3, 0x04 },
580 { 0xd010, 3, 3, 0x05 },
581 { 0xd016, 4, 4, 0x03 },
582 { 0xd01f, 0, 6, 0x0a },
583 { 0xd020, 0, 6, 0x0a },
584 { 0x9bda, 0, 8, 0x01 },
585 { 0x9be3, 0, 8, 0x01 },
586 { 0xd015, 0, 8, 0x46 },
587 { 0xd016, 0, 1, 0x00 },
588 { 0xd044, 0, 8, 0x46 },
589 { 0xd045, 0, 1, 0x00 },
590 { 0x9bbe, 0, 1, 0x01 },
591 { 0x9bcc, 0, 1, 0x01 },
592 { 0x9bb9, 0, 8, 0x00 },
593 { 0x9bcd, 0, 8, 0x28 },
594 { 0x9bff, 0, 8, 0x20 },
595 { 0xd008, 0, 8, 0x0f },
596 { 0xd009, 0, 2, 0x02 },
597 { 0xd006, 0, 8, 0x99 },
598 { 0xd007, 0, 2, 0x01 },
599 { 0xd00c, 0, 8, 0x0f },
600 { 0xd00d, 0, 2, 0x02 },
601 { 0xd00a, 0, 8, 0x50 },
602 { 0xd00b, 0, 2, 0x01 },
603 { 0x9bc7, 0, 8, 0x00 },
604 { 0x9bc8, 0, 8, 0x00 },
605 { 0x9bc3, 0, 8, 0x0f },
606 { 0x9bc4, 0, 8, 0x02 },
607 { 0x9bc5, 0, 8, 0x0f },
608 { 0x9bc6, 0, 8, 0x02 },
609 { 0x9bba, 0, 8, 0xc5 },
610 { 0x9bc9, 0, 8, 0xff },
611 { 0xd011, 0, 8, 0x58 },
612 { 0xd012, 0, 2, 0x02 },
613 { 0xd013, 0, 8, 0x89 },
614 { 0xd014, 0, 2, 0x01 },
615 { 0xd040, 0, 8, 0x58 },
616 { 0xd041, 0, 2, 0x02 },
617 { 0xd042, 0, 8, 0x89 },
618 { 0xd043, 0, 2, 0x01 },
619 { 0xd045, 1, 1, 0x00 },
620 { 0x9bcf, 0, 1, 0x01 },
621 { 0xd045, 2, 1, 0x01 },
622 { 0xd04f, 0, 8, 0x9a },
623 { 0xd050, 0, 1, 0x01 },
624 { 0xd051, 0, 8, 0x5a },
625 { 0xd052, 0, 1, 0x01 },
626 { 0xd053, 0, 8, 0x50 },
627 { 0xd054, 0, 8, 0x46 },
628 { 0x9bd7, 0, 8, 0x0a },
629 { 0x9bd8, 0, 8, 0x14 },
630 { 0x9bd9, 0, 8, 0x08 },
631 { 0x9bd0, 0, 8, 0xcd },
632 { 0x9be4, 0, 8, 0xbb },
633 { 0x9bbd, 0, 8, 0x93 },
634 { 0x9be2, 0, 8, 0x80 },
635 { 0x9bee, 0, 1, 0x01 },
636};
637
638/* Freescale MC44S803 tuner init
639 AF9013_TUNER_MC44S803 = 133 */
640static struct regdesc tuner_init_mc44s803[] = {
641 { 0x9bd5, 0, 8, 0x01 },
642 { 0x9bd6, 0, 8, 0x06 },
643 { 0xd1a0, 1, 1, 0x01 },
644 { 0xd000, 0, 1, 0x01 },
645 { 0xd000, 1, 1, 0x00 },
646 { 0xd001, 1, 1, 0x01 },
647 { 0xd001, 0, 1, 0x00 },
648 { 0xd001, 5, 1, 0x00 },
649 { 0xd002, 0, 5, 0x19 },
650 { 0xd003, 0, 5, 0x1a },
651 { 0xd004, 0, 5, 0x19 },
652 { 0xd005, 0, 5, 0x1a },
653 { 0xd00e, 0, 5, 0x10 },
654 { 0xd00f, 0, 3, 0x04 },
655 { 0xd00f, 3, 3, 0x05 },
656 { 0xd010, 0, 3, 0x04 },
657 { 0xd010, 3, 3, 0x05 },
658 { 0xd016, 4, 4, 0x03 },
659 { 0xd01f, 0, 6, 0x0a },
660 { 0xd020, 0, 6, 0x0a },
661 { 0x9bda, 0, 8, 0x00 },
662 { 0x9be3, 0, 8, 0x00 },
663 { 0x9bf6, 0, 8, 0x01 },
664 { 0x9bf8, 0, 8, 0x02 },
665 { 0x9bf9, 0, 8, 0x02 },
666 { 0x9bfc, 0, 8, 0x1f },
667 { 0x9bbe, 0, 1, 0x01 },
668 { 0x9bcc, 0, 1, 0x01 },
669 { 0x9bb9, 0, 8, 0x00 },
670 { 0x9bcd, 0, 8, 0x24 },
671 { 0x9bff, 0, 8, 0x24 },
672 { 0xd015, 0, 8, 0x46 },
673 { 0xd016, 0, 1, 0x00 },
674 { 0xd044, 0, 8, 0x46 },
675 { 0xd045, 0, 1, 0x00 },
676 { 0xd008, 0, 8, 0x01 },
677 { 0xd009, 0, 2, 0x02 },
678 { 0xd006, 0, 8, 0x7b },
679 { 0xd007, 0, 2, 0x00 },
680 { 0xd00c, 0, 8, 0x7c },
681 { 0xd00d, 0, 2, 0x02 },
682 { 0xd00a, 0, 8, 0xfe },
683 { 0xd00b, 0, 2, 0x01 },
684 { 0x9bc7, 0, 8, 0x08 },
685 { 0x9bc8, 0, 8, 0x9a },
686 { 0x9bc3, 0, 8, 0x01 },
687 { 0x9bc4, 0, 8, 0x02 },
688 { 0x9bc5, 0, 8, 0x7c },
689 { 0x9bc6, 0, 8, 0x02 },
690 { 0x9bba, 0, 8, 0xfc },
691 { 0x9bc9, 0, 8, 0xaa },
692 { 0xd011, 0, 8, 0x6b },
693 { 0xd012, 0, 2, 0x00 },
694 { 0xd013, 0, 8, 0x88 },
695 { 0xd014, 0, 2, 0x02 },
696 { 0xd040, 0, 8, 0x6b },
697 { 0xd041, 0, 2, 0x00 },
698 { 0xd042, 0, 8, 0x7c },
699 { 0xd043, 0, 2, 0x02 },
700 { 0xd045, 1, 1, 0x00 },
701 { 0x9bcf, 0, 1, 0x01 },
702 { 0xd045, 2, 1, 0x01 },
703 { 0xd04f, 0, 8, 0x9a },
704 { 0xd050, 0, 1, 0x01 },
705 { 0xd051, 0, 8, 0x5a },
706 { 0xd052, 0, 1, 0x01 },
707 { 0xd053, 0, 8, 0x50 },
708 { 0xd054, 0, 8, 0x46 },
709 { 0x9bd7, 0, 8, 0x0a },
710 { 0x9bd8, 0, 8, 0x14 },
711 { 0x9bd9, 0, 8, 0x08 },
712 { 0x9bd0, 0, 8, 0x9e },
713 { 0x9be4, 0, 8, 0xff },
714 { 0x9bbd, 0, 8, 0x9e },
715 { 0x9be2, 0, 8, 0x25 },
716 { 0x9bee, 0, 1, 0x01 },
717 { 0xd73b, 3, 1, 0x00 },
718};
719
720/* unknown, probably for tin can tuner, tuner init
721 AF9013_TUNER_UNKNOWN = 140 */
722static struct regdesc tuner_init_unknown[] = {
723 { 0x9bd5, 0, 8, 0x01 },
724 { 0x9bd6, 0, 8, 0x02 },
725 { 0xd1a0, 1, 1, 0x01 },
726 { 0xd000, 0, 1, 0x01 },
727 { 0xd000, 1, 1, 0x00 },
728 { 0xd001, 1, 1, 0x01 },
729 { 0xd001, 0, 1, 0x00 },
730 { 0xd001, 5, 1, 0x00 },
731 { 0xd002, 0, 5, 0x19 },
732 { 0xd003, 0, 5, 0x1a },
733 { 0xd004, 0, 5, 0x19 },
734 { 0xd005, 0, 5, 0x1a },
735 { 0xd00e, 0, 5, 0x10 },
736 { 0xd00f, 0, 3, 0x04 },
737 { 0xd00f, 3, 3, 0x05 },
738 { 0xd010, 0, 3, 0x04 },
739 { 0xd010, 3, 3, 0x05 },
740 { 0xd016, 4, 4, 0x03 },
741 { 0xd01f, 0, 6, 0x0a },
742 { 0xd020, 0, 6, 0x0a },
743 { 0x9bda, 0, 8, 0x01 },
744 { 0x9be3, 0, 8, 0x01 },
745 { 0xd1a0, 1, 1, 0x00 },
746 { 0x9bbe, 0, 1, 0x01 },
747 { 0x9bcc, 0, 1, 0x01 },
748 { 0x9bb9, 0, 8, 0x00 },
749 { 0x9bcd, 0, 8, 0x18 },
750 { 0x9bff, 0, 8, 0x2c },
751 { 0xd015, 0, 8, 0x46 },
752 { 0xd016, 0, 1, 0x00 },
753 { 0xd044, 0, 8, 0x46 },
754 { 0xd045, 0, 1, 0x00 },
755 { 0xd008, 0, 8, 0xdf },
756 { 0xd009, 0, 2, 0x02 },
757 { 0xd006, 0, 8, 0x44 },
758 { 0xd007, 0, 2, 0x01 },
759 { 0xd00c, 0, 8, 0x00 },
760 { 0xd00d, 0, 2, 0x02 },
761 { 0xd00a, 0, 8, 0xf6 },
762 { 0xd00b, 0, 2, 0x01 },
763 { 0x9bba, 0, 8, 0xf9 },
764 { 0x9bc8, 0, 8, 0xaa },
765 { 0x9bc3, 0, 8, 0xdf },
766 { 0x9bc4, 0, 8, 0x02 },
767 { 0x9bc5, 0, 8, 0x00 },
768 { 0x9bc6, 0, 8, 0x02 },
769 { 0x9bc9, 0, 8, 0xf0 },
770 { 0xd011, 0, 8, 0x3c },
771 { 0xd012, 0, 2, 0x01 },
772 { 0xd013, 0, 8, 0xf7 },
773 { 0xd014, 0, 2, 0x02 },
774 { 0xd040, 0, 8, 0x0b },
775 { 0xd041, 0, 2, 0x02 },
776 { 0xd042, 0, 8, 0x4d },
777 { 0xd043, 0, 2, 0x00 },
778 { 0xd045, 1, 1, 0x00 },
779 { 0x9bcf, 0, 1, 0x01 },
780 { 0xd045, 2, 1, 0x01 },
781 { 0xd04f, 0, 8, 0x9a },
782 { 0xd050, 0, 1, 0x01 },
783 { 0xd051, 0, 8, 0x5a },
784 { 0xd052, 0, 1, 0x01 },
785 { 0xd053, 0, 8, 0x50 },
786 { 0xd054, 0, 8, 0x46 },
787 { 0x9bd7, 0, 8, 0x0a },
788 { 0x9bd8, 0, 8, 0x14 },
789 { 0x9bd9, 0, 8, 0x08 },
790};
791
792/* NXP TDA18271 tuner init
793 AF9013_TUNER_TDA18271 = 156 */
794static struct regdesc tuner_init_tda18271[] = {
795 { 0x9bd5, 0, 8, 0x01 },
796 { 0x9bd6, 0, 8, 0x04 },
797 { 0xd1a0, 1, 1, 0x01 },
798 { 0xd000, 0, 1, 0x01 },
799 { 0xd000, 1, 1, 0x00 },
800 { 0xd001, 1, 1, 0x01 },
801 { 0xd001, 0, 1, 0x00 },
802 { 0xd001, 5, 1, 0x00 },
803 { 0xd002, 0, 5, 0x19 },
804 { 0xd003, 0, 5, 0x1a },
805 { 0xd004, 0, 5, 0x19 },
806 { 0xd005, 0, 5, 0x1a },
807 { 0xd00e, 0, 5, 0x10 },
808 { 0xd00f, 0, 3, 0x04 },
809 { 0xd00f, 3, 3, 0x05 },
810 { 0xd010, 0, 3, 0x04 },
811 { 0xd010, 3, 3, 0x05 },
812 { 0xd016, 4, 4, 0x03 },
813 { 0xd01f, 0, 6, 0x0a },
814 { 0xd020, 0, 6, 0x0a },
815 { 0x9bda, 0, 8, 0x01 },
816 { 0x9be3, 0, 8, 0x01 },
817 { 0xd1a0, 1, 1, 0x00 },
818 { 0x9bbe, 0, 1, 0x01 },
819 { 0x9bcc, 0, 1, 0x01 },
820 { 0x9bb9, 0, 8, 0x00 },
821 { 0x9bcd, 0, 8, 0x18 },
822 { 0x9bff, 0, 8, 0x2c },
823 { 0xd015, 0, 8, 0x46 },
824 { 0xd016, 0, 1, 0x00 },
825 { 0xd044, 0, 8, 0x46 },
826 { 0xd045, 0, 1, 0x00 },
827 { 0xd008, 0, 8, 0xdf },
828 { 0xd009, 0, 2, 0x02 },
829 { 0xd006, 0, 8, 0x44 },
830 { 0xd007, 0, 2, 0x01 },
831 { 0xd00c, 0, 8, 0x00 },
832 { 0xd00d, 0, 2, 0x02 },
833 { 0xd00a, 0, 8, 0xf6 },
834 { 0xd00b, 0, 2, 0x01 },
835 { 0x9bba, 0, 8, 0xf9 },
836 { 0x9bc8, 0, 8, 0xaa },
837 { 0x9bc3, 0, 8, 0xdf },
838 { 0x9bc4, 0, 8, 0x02 },
839 { 0x9bc5, 0, 8, 0x00 },
840 { 0x9bc6, 0, 8, 0x02 },
841 { 0x9bc9, 0, 8, 0xf0 },
842 { 0xd011, 0, 8, 0x3c },
843 { 0xd012, 0, 2, 0x01 },
844 { 0xd013, 0, 8, 0xf7 },
845 { 0xd014, 0, 2, 0x02 },
846 { 0xd040, 0, 8, 0x0b },
847 { 0xd041, 0, 2, 0x02 },
848 { 0xd042, 0, 8, 0x4d },
849 { 0xd043, 0, 2, 0x00 },
850 { 0xd045, 1, 1, 0x00 },
851 { 0x9bcf, 0, 1, 0x01 },
852 { 0xd045, 2, 1, 0x01 },
853 { 0xd04f, 0, 8, 0x9a },
854 { 0xd050, 0, 1, 0x01 },
855 { 0xd051, 0, 8, 0x5a },
856 { 0xd052, 0, 1, 0x01 },
857 { 0xd053, 0, 8, 0x50 },
858 { 0xd054, 0, 8, 0x46 },
859 { 0x9bd7, 0, 8, 0x0a },
860 { 0x9bd8, 0, 8, 0x14 },
861 { 0x9bd9, 0, 8, 0x08 },
862 { 0x9bd0, 0, 8, 0xa8 },
863 { 0x9be4, 0, 8, 0x7f },
864 { 0x9bbd, 0, 8, 0xa8 },
865 { 0x9be2, 0, 8, 0x20 },
866 { 0x9bee, 0, 1, 0x01 },
867};
868
869#endif /* _AF9013_PRIV_ */
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522.c
index 0b82cc2a1e16..eabf9a68e7ec 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522.c
@@ -40,6 +40,8 @@ struct au8522_state {
40 u32 current_frequency; 40 u32 current_frequency;
41 fe_modulation_t current_modulation; 41 fe_modulation_t current_modulation;
42 42
43 u32 fe_status;
44 unsigned int led_state;
43}; 45};
44 46
45static int debug; 47static int debug;
@@ -538,11 +540,98 @@ static int au8522_init(struct dvb_frontend *fe)
538 return 0; 540 return 0;
539} 541}
540 542
543static int au8522_led_gpio_enable(struct au8522_state *state, int onoff)
544{
545 struct au8522_led_config *led_config = state->config->led_cfg;
546 u8 val;
547
548 /* bail out if we cant control an LED */
549 if (!led_config || !led_config->gpio_output ||
550 !led_config->gpio_output_enable || !led_config->gpio_output_disable)
551 return 0;
552
553 val = au8522_readreg(state, 0x4000 |
554 (led_config->gpio_output & ~0xc000));
555 if (onoff) {
556 /* enable GPIO output */
557 val &= ~((led_config->gpio_output_enable >> 8) & 0xff);
558 val |= (led_config->gpio_output_enable & 0xff);
559 } else {
560 /* disable GPIO output */
561 val &= ~((led_config->gpio_output_disable >> 8) & 0xff);
562 val |= (led_config->gpio_output_disable & 0xff);
563 }
564 return au8522_writereg(state, 0x8000 |
565 (led_config->gpio_output & ~0xc000), val);
566}
567
568/* led = 0 | off
569 * led = 1 | signal ok
570 * led = 2 | signal strong
571 * led < 0 | only light led if leds are currently off
572 */
573static int au8522_led_ctrl(struct au8522_state *state, int led)
574{
575 struct au8522_led_config *led_config = state->config->led_cfg;
576 int i, ret = 0;
577
578 /* bail out if we cant control an LED */
579 if (!led_config || !led_config->gpio_leds ||
580 !led_config->num_led_states || !led_config->led_states)
581 return 0;
582
583 if (led < 0) {
584 /* if LED is already lit, then leave it as-is */
585 if (state->led_state)
586 return 0;
587 else
588 led *= -1;
589 }
590
591 /* toggle LED if changing state */
592 if (state->led_state != led) {
593 u8 val;
594
595 dprintk("%s: %d\n", __func__, led);
596
597 au8522_led_gpio_enable(state, 1);
598
599 val = au8522_readreg(state, 0x4000 |
600 (led_config->gpio_leds & ~0xc000));
601
602 /* start with all leds off */
603 for (i = 0; i < led_config->num_led_states; i++)
604 val &= ~led_config->led_states[i];
605
606 /* set selected LED state */
607 if (led < led_config->num_led_states)
608 val |= led_config->led_states[led];
609 else if (led_config->num_led_states)
610 val |=
611 led_config->led_states[led_config->num_led_states - 1];
612
613 ret = au8522_writereg(state, 0x8000 |
614 (led_config->gpio_leds & ~0xc000), val);
615 if (ret < 0)
616 return ret;
617
618 state->led_state = led;
619
620 if (led == 0)
621 au8522_led_gpio_enable(state, 0);
622 }
623
624 return 0;
625}
626
541static int au8522_sleep(struct dvb_frontend *fe) 627static int au8522_sleep(struct dvb_frontend *fe)
542{ 628{
543 struct au8522_state *state = fe->demodulator_priv; 629 struct au8522_state *state = fe->demodulator_priv;
544 dprintk("%s()\n", __func__); 630 dprintk("%s()\n", __func__);
545 631
632 /* turn off led */
633 au8522_led_ctrl(state, 0);
634
546 state->current_frequency = 0; 635 state->current_frequency = 0;
547 636
548 return 0; 637 return 0;
@@ -592,12 +681,53 @@ static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
592 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; 681 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
593 break; 682 break;
594 } 683 }
684 state->fe_status = *status;
685
686 if (*status & FE_HAS_LOCK)
687 /* turn on LED, if it isn't on already */
688 au8522_led_ctrl(state, -1);
689 else
690 /* turn off LED */
691 au8522_led_ctrl(state, 0);
595 692
596 dprintk("%s() status 0x%08x\n", __func__, *status); 693 dprintk("%s() status 0x%08x\n", __func__, *status);
597 694
598 return 0; 695 return 0;
599} 696}
600 697
698static int au8522_led_status(struct au8522_state *state, const u16 *snr)
699{
700 struct au8522_led_config *led_config = state->config->led_cfg;
701 int led;
702 u16 strong;
703
704 /* bail out if we cant control an LED */
705 if (!led_config)
706 return 0;
707
708 if (0 == (state->fe_status & FE_HAS_LOCK))
709 return au8522_led_ctrl(state, 0);
710 else if (state->current_modulation == QAM_256)
711 strong = led_config->qam256_strong;
712 else if (state->current_modulation == QAM_64)
713 strong = led_config->qam64_strong;
714 else /* (state->current_modulation == VSB_8) */
715 strong = led_config->vsb8_strong;
716
717 if (*snr >= strong)
718 led = 2;
719 else
720 led = 1;
721
722 if ((state->led_state) &&
723 (((strong < *snr) ? (*snr - strong) : (strong - *snr)) <= 10))
724 /* snr didn't change enough to bother
725 * changing the color of the led */
726 return 0;
727
728 return au8522_led_ctrl(state, led);
729}
730
601static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr) 731static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
602{ 732{
603 struct au8522_state *state = fe->demodulator_priv; 733 struct au8522_state *state = fe->demodulator_priv;
@@ -621,6 +751,9 @@ static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
621 au8522_readreg(state, 0x4311), 751 au8522_readreg(state, 0x4311),
622 snr); 752 snr);
623 753
754 if (state->config->led_cfg)
755 au8522_led_status(state, snr);
756
624 return ret; 757 return ret;
625} 758}
626 759
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h
index 595915ade8c3..7b94f554a093 100644
--- a/drivers/media/dvb/frontends/au8522.h
+++ b/drivers/media/dvb/frontends/au8522.h
@@ -30,6 +30,21 @@ enum au8522_if_freq {
30 AU8522_IF_3_25MHZ, 30 AU8522_IF_3_25MHZ,
31}; 31};
32 32
33struct au8522_led_config {
34 u16 vsb8_strong;
35 u16 qam64_strong;
36 u16 qam256_strong;
37
38 u16 gpio_output;
39 /* unset hi bits, set low bits */
40 u16 gpio_output_enable;
41 u16 gpio_output_disable;
42
43 u16 gpio_leds;
44 u8 *led_states;
45 unsigned int num_led_states;
46};
47
33struct au8522_config { 48struct au8522_config {
34 /* the demodulator's i2c address */ 49 /* the demodulator's i2c address */
35 u8 demod_address; 50 u8 demod_address;
@@ -39,6 +54,8 @@ struct au8522_config {
39#define AU8522_DEMODLOCKING 1 54#define AU8522_DEMODLOCKING 1
40 u8 status_mode; 55 u8 status_mode;
41 56
57 struct au8522_led_config *led_cfg;
58
42 enum au8522_if_freq vsb_if; 59 enum au8522_if_freq vsb_if;
43 enum au8522_if_freq qam_if; 60 enum au8522_if_freq qam_if;
44}; 61};
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
index 1792adb23c4d..fdcceee91f3a 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -33,12 +33,17 @@ struct cx24110_config
33 u8 demod_address; 33 u8 demod_address;
34}; 34};
35 35
36static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) { 36static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val)
37 int r = 0; 37{
38 u8 buf[] = {(u8) (val>>24), (u8) (val>>16), (u8) (val>>8)}; 38 u8 buf[] = {
39 (u8)((val >> 24) & 0xff),
40 (u8)((val >> 16) & 0xff),
41 (u8)((val >> 8) & 0xff)
42 };
43
39 if (fe->ops.write) 44 if (fe->ops.write)
40 r = fe->ops.write(fe, buf, 3); 45 return fe->ops.write(fe, buf, 3);
41 return r; 46 return 0;
42} 47}
43 48
44#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE)) 49#if defined(CONFIG_DVB_CX24110) || (defined(CONFIG_DVB_CX24110_MODULE) && defined(MODULE))
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
new file mode 100644
index 000000000000..deb36f469ada
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -0,0 +1,1423 @@
1/*
2 Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
3
4 Copyright (C) 2006-2008 Steven Toth <stoth@hauppauge.com>
5 Copyright (C) 2006-2007 Georg Acher
6 Copyright (C) 2007-2008 Darron Broad
7 March 2007
8 Fixed some bugs.
9 Added diseqc support.
10 Added corrected signal strength support.
11 August 2007
12 Sync with legacy version.
13 Some clean ups.
14 Copyright (C) 2008 Igor Liplianin
15 September, 9th 2008
16 Fixed locking on high symbol rates (>30000).
17 Implement MPEG initialization parameter.
18
19 This program is free software; you can redistribute it and/or modify
20 it under the terms of the GNU General Public License as published by
21 the Free Software Foundation; either version 2 of the License, or
22 (at your option) any later version.
23
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 GNU General Public License for more details.
28
29 You should have received a copy of the GNU General Public License
30 along with this program; if not, write to the Free Software
31 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32*/
33
34#include <linux/slab.h>
35#include <linux/kernel.h>
36#include <linux/module.h>
37#include <linux/moduleparam.h>
38#include <linux/init.h>
39#include <linux/firmware.h>
40
41#include "dvb_frontend.h"
42#include "cx24116.h"
43
44static int debug = 0;
45#define dprintk(args...) \
46 do { \
47 if (debug) printk ("cx24116: " args); \
48 } while (0)
49
50#define CX24116_DEFAULT_FIRMWARE "dvb-fe-cx24116.fw"
51#define CX24116_SEARCH_RANGE_KHZ 5000
52
53/* known registers */
54#define CX24116_REG_COMMAND (0x00) /* command args 0x00..0x1e */
55#define CX24116_REG_EXECUTE (0x1f) /* execute command */
56#define CX24116_REG_MAILBOX (0x96) /* FW or multipurpose mailbox? */
57#define CX24116_REG_RESET (0x20) /* reset status > 0 */
58#define CX24116_REG_SIGNAL (0x9e) /* signal low */
59#define CX24116_REG_SSTATUS (0x9d) /* signal high / status */
60#define CX24116_REG_QUALITY8 (0xa3)
61#define CX24116_REG_QSTATUS (0xbc)
62#define CX24116_REG_QUALITY0 (0xd5)
63#define CX24116_REG_BER0 (0xc9)
64#define CX24116_REG_BER8 (0xc8)
65#define CX24116_REG_BER16 (0xc7)
66#define CX24116_REG_BER24 (0xc6)
67#define CX24116_REG_UCB0 (0xcb)
68#define CX24116_REG_UCB8 (0xca)
69#define CX24116_REG_CLKDIV (0xf3)
70#define CX24116_REG_RATEDIV (0xf9)
71#define CX24116_REG_FECSTATUS (0x9c) /* configured fec (not tuned) or actual FEC (tuned) 1=1/2 2=2/3 etc */
72
73/* FECSTATUS bits */
74#define CX24116_FEC_FECMASK (0x1f) /* mask to determine configured fec (not tuned) or actual fec (tuned) */
75#define CX24116_FEC_DVBS (0x20) /* Select DVB-S demodulator, else DVB-S2 */
76#define CX24116_FEC_UNKNOWN (0x40) /* Unknown/unused */
77#define CX24116_FEC_PILOT (0x80) /* Pilot mode requested when tuning else always reset when tuned */
78
79/* arg buffer size */
80#define CX24116_ARGLEN (0x1e)
81
82/* rolloff */
83#define CX24116_ROLLOFF_020 (0x00)
84#define CX24116_ROLLOFF_025 (0x01)
85#define CX24116_ROLLOFF_035 (0x02)
86
87/* pilot bit */
88#define CX24116_PILOT_OFF (0x00)
89#define CX24116_PILOT_ON (0x40)
90
91/* signal status */
92#define CX24116_HAS_SIGNAL (0x01)
93#define CX24116_HAS_CARRIER (0x02)
94#define CX24116_HAS_VITERBI (0x04)
95#define CX24116_HAS_SYNCLOCK (0x08)
96#define CX24116_HAS_UNKNOWN1 (0x10)
97#define CX24116_HAS_UNKNOWN2 (0x20)
98#define CX24116_STATUS_MASK (0x3f)
99#define CX24116_SIGNAL_MASK (0xc0)
100
101#define CX24116_DISEQC_TONEOFF (0) /* toneburst never sent */
102#define CX24116_DISEQC_TONECACHE (1) /* toneburst cached */
103#define CX24116_DISEQC_MESGCACHE (2) /* message cached */
104
105/* arg offset for DiSEqC */
106#define CX24116_DISEQC_BURST (1)
107#define CX24116_DISEQC_ARG2_2 (2) /* unknown value=2 */
108#define CX24116_DISEQC_ARG3_0 (3) /* unknown value=0 */
109#define CX24116_DISEQC_ARG4_0 (4) /* unknown value=0 */
110#define CX24116_DISEQC_MSGLEN (5)
111#define CX24116_DISEQC_MSGOFS (6)
112
113/* DiSEqC burst */
114#define CX24116_DISEQC_MINI_A (0)
115#define CX24116_DISEQC_MINI_B (1)
116
117/* DiSEqC tone burst */
118static int toneburst = 1;
119
120/* SNR measurements */
121static int esno_snr = 0;
122
123enum cmds
124{
125 CMD_SET_VCO = 0x10,
126 CMD_TUNEREQUEST = 0x11,
127 CMD_MPEGCONFIG = 0x13,
128 CMD_TUNERINIT = 0x14,
129 CMD_BANDWIDTH = 0x15,
130 CMD_GETAGC = 0x19,
131 CMD_LNBCONFIG = 0x20,
132 CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */
133 CMD_SET_TONEPRE = 0x22,
134 CMD_SET_TONE = 0x23,
135 CMD_UPDFWVERS = 0x35,
136 CMD_TUNERSLEEP = 0x36,
137 CMD_AGCCONTROL = 0x3b, /* Unknown */
138};
139
140/* The Demod/Tuner can't easily provide these, we cache them */
141struct cx24116_tuning
142{
143 u32 frequency;
144 u32 symbol_rate;
145 fe_spectral_inversion_t inversion;
146 fe_code_rate_t fec;
147
148 fe_modulation_t modulation;
149 fe_pilot_t pilot;
150 fe_rolloff_t rolloff;
151
152 /* Demod values */
153 u8 fec_val;
154 u8 fec_mask;
155 u8 inversion_val;
156 u8 pilot_val;
157 u8 rolloff_val;
158};
159
160/* Basic commands that are sent to the firmware */
161struct cx24116_cmd
162{
163 u8 len;
164 u8 args[CX24116_ARGLEN];
165};
166
167struct cx24116_state
168{
169 struct i2c_adapter* i2c;
170 const struct cx24116_config* config;
171
172 struct dvb_frontend frontend;
173
174 struct cx24116_tuning dcur;
175 struct cx24116_tuning dnxt;
176
177 u8 skip_fw_load;
178 u8 burst;
179 struct cx24116_cmd dsec_cmd;
180};
181
182static int cx24116_writereg(struct cx24116_state* state, int reg, int data)
183{
184 u8 buf[] = { reg, data };
185 struct i2c_msg msg = { .addr = state->config->demod_address,
186 .flags = 0, .buf = buf, .len = 2 };
187 int err;
188
189 if (debug>1)
190 printk("cx24116: %s: write reg 0x%02x, value 0x%02x\n",
191 __func__,reg, data);
192
193 if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
194 printk("%s: writereg error(err == %i, reg == 0x%02x,"
195 " value == 0x%02x)\n", __func__, err, reg, data);
196 return -EREMOTEIO;
197 }
198
199 return 0;
200}
201
202/* Bulk byte writes to a single I2C address, for 32k firmware load */
203static int cx24116_writeregN(struct cx24116_state* state, int reg, u8 *data, u16 len)
204{
205 int ret = -EREMOTEIO;
206 struct i2c_msg msg;
207 u8 *buf;
208
209 buf = kmalloc(len + 1, GFP_KERNEL);
210 if (buf == NULL) {
211 printk("Unable to kmalloc\n");
212 ret = -ENOMEM;
213 goto error;
214 }
215
216 *(buf) = reg;
217 memcpy(buf + 1, data, len);
218
219 msg.addr = state->config->demod_address;
220 msg.flags = 0;
221 msg.buf = buf;
222 msg.len = len + 1;
223
224 if (debug>1)
225 printk("cx24116: %s: write regN 0x%02x, len = %d\n",
226 __func__,reg, len);
227
228 if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) {
229 printk("%s: writereg error(err == %i, reg == 0x%02x\n",
230 __func__, ret, reg);
231 ret = -EREMOTEIO;
232 }
233
234error:
235 kfree(buf);
236
237 return ret;
238}
239
240static int cx24116_readreg(struct cx24116_state* state, u8 reg)
241{
242 int ret;
243 u8 b0[] = { reg };
244 u8 b1[] = { 0 };
245 struct i2c_msg msg[] = {
246 { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
247 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 }
248 };
249
250 ret = i2c_transfer(state->i2c, msg, 2);
251
252 if (ret != 2) {
253 printk("%s: reg=0x%x (error=%d)\n", __func__, reg, ret);
254 return ret;
255 }
256
257 if (debug>1)
258 printk("cx24116: read reg 0x%02x, value 0x%02x\n",reg, b1[0]);
259
260 return b1[0];
261}
262
263static int cx24116_set_inversion(struct cx24116_state* state, fe_spectral_inversion_t inversion)
264{
265 dprintk("%s(%d)\n", __func__, inversion);
266
267 switch (inversion) {
268 case INVERSION_OFF:
269 state->dnxt.inversion_val = 0x00;
270 break;
271 case INVERSION_ON:
272 state->dnxt.inversion_val = 0x04;
273 break;
274 case INVERSION_AUTO:
275 state->dnxt.inversion_val = 0x0C;
276 break;
277 default:
278 return -EINVAL;
279 }
280
281 state->dnxt.inversion = inversion;
282
283 return 0;
284}
285
286/*
287 * modfec (modulation and FEC)
288 * ===========================
289 *
290 * MOD FEC mask/val standard
291 * ---- -------- ----------- --------
292 * QPSK FEC_1_2 0x02 0x02+X DVB-S
293 * QPSK FEC_2_3 0x04 0x02+X DVB-S
294 * QPSK FEC_3_4 0x08 0x02+X DVB-S
295 * QPSK FEC_4_5 0x10 0x02+X DVB-S (?)
296 * QPSK FEC_5_6 0x20 0x02+X DVB-S
297 * QPSK FEC_6_7 0x40 0x02+X DVB-S
298 * QPSK FEC_7_8 0x80 0x02+X DVB-S
299 * QPSK FEC_8_9 0x01 0x02+X DVB-S (?) (NOT SUPPORTED?)
300 * QPSK AUTO 0xff 0x02+X DVB-S
301 *
302 * For DVB-S high byte probably represents FEC
303 * and low byte selects the modulator. The high
304 * byte is search range mask. Bit 5 may turn
305 * on DVB-S and remaining bits represent some
306 * kind of calibration (how/what i do not know).
307 *
308 * Eg.(2/3) szap "Zone Horror"
309 *
310 * mask/val = 0x04, 0x20
311 * status 1f | signal c3c0 | snr a333 | ber 00000098 | unc 00000000 | FE_HAS_LOCK
312 *
313 * mask/val = 0x04, 0x30
314 * status 1f | signal c3c0 | snr a333 | ber 00000000 | unc 00000000 | FE_HAS_LOCK
315 *
316 * After tuning FECSTATUS contains actual FEC
317 * in use numbered 1 through to 8 for 1/2 .. 2/3 etc
318 *
319 * NBC=NOT/NON BACKWARD COMPATIBLE WITH DVB-S (DVB-S2 only)
320 *
321 * NBC-QPSK FEC_1_2 0x00, 0x04 DVB-S2
322 * NBC-QPSK FEC_3_5 0x00, 0x05 DVB-S2
323 * NBC-QPSK FEC_2_3 0x00, 0x06 DVB-S2
324 * NBC-QPSK FEC_3_4 0x00, 0x07 DVB-S2
325 * NBC-QPSK FEC_4_5 0x00, 0x08 DVB-S2
326 * NBC-QPSK FEC_5_6 0x00, 0x09 DVB-S2
327 * NBC-QPSK FEC_8_9 0x00, 0x0a DVB-S2
328 * NBC-QPSK FEC_9_10 0x00, 0x0b DVB-S2
329 *
330 * NBC-8PSK FEC_3_5 0x00, 0x0c DVB-S2
331 * NBC-8PSK FEC_2_3 0x00, 0x0d DVB-S2
332 * NBC-8PSK FEC_3_4 0x00, 0x0e DVB-S2
333 * NBC-8PSK FEC_5_6 0x00, 0x0f DVB-S2
334 * NBC-8PSK FEC_8_9 0x00, 0x10 DVB-S2
335 * NBC-8PSK FEC_9_10 0x00, 0x11 DVB-S2
336 *
337 * For DVB-S2 low bytes selects both modulator
338 * and FEC. High byte is meaningless here. To
339 * set pilot, bit 6 (0x40) is set. When inspecting
340 * FECSTATUS bit 7 (0x80) represents the pilot
341 * selection whilst not tuned. When tuned, actual FEC
342 * in use is found in FECSTATUS as per above. Pilot
343 * value is reset.
344 */
345
346/* A table of modulation, fec and configuration bytes for the demod.
347 * Not all S2 mmodulation schemes are support and not all rates with
348 * a scheme are support. Especially, no auto detect when in S2 mode.
349 */
350struct cx24116_modfec {
351 fe_delivery_system_t delivery_system;
352 fe_modulation_t modulation;
353 fe_code_rate_t fec;
354 u8 mask; /* In DVBS mode this is used to autodetect */
355 u8 val; /* Passed to the firmware to indicate mode selection */
356} CX24116_MODFEC_MODES[] = {
357 /* QPSK. For unknown rates we set hardware to auto detect 0xfe 0x30 */
358
359 /*mod fec mask val */
360 { SYS_DVBS, QPSK, FEC_NONE, 0xfe, 0x30 },
361 { SYS_DVBS, QPSK, FEC_1_2, 0x02, 0x2e }, /* 00000010 00101110 */
362 { SYS_DVBS, QPSK, FEC_2_3, 0x04, 0x2f }, /* 00000100 00101111 */
363 { SYS_DVBS, QPSK, FEC_3_4, 0x08, 0x30 }, /* 00001000 00110000 */
364 { SYS_DVBS, QPSK, FEC_4_5, 0xfe, 0x30 }, /* 000?0000 ? */
365 { SYS_DVBS, QPSK, FEC_5_6, 0x20, 0x31 }, /* 00100000 00110001 */
366 { SYS_DVBS, QPSK, FEC_6_7, 0xfe, 0x30 }, /* 0?000000 ? */
367 { SYS_DVBS, QPSK, FEC_7_8, 0x80, 0x32 }, /* 10000000 00110010 */
368 { SYS_DVBS, QPSK, FEC_8_9, 0xfe, 0x30 }, /* 0000000? ? */
369 { SYS_DVBS, QPSK, FEC_AUTO, 0xfe, 0x30 },
370 /* NBC-QPSK */
371 { SYS_DVBS2, QPSK, FEC_1_2, 0x00, 0x04 },
372 { SYS_DVBS2, QPSK, FEC_3_5, 0x00, 0x05 },
373 { SYS_DVBS2, QPSK, FEC_2_3, 0x00, 0x06 },
374 { SYS_DVBS2, QPSK, FEC_3_4, 0x00, 0x07 },
375 { SYS_DVBS2, QPSK, FEC_4_5, 0x00, 0x08 },
376 { SYS_DVBS2, QPSK, FEC_5_6, 0x00, 0x09 },
377 { SYS_DVBS2, QPSK, FEC_8_9, 0x00, 0x0a },
378 { SYS_DVBS2, QPSK, FEC_9_10, 0x00, 0x0b },
379 /* 8PSK */
380 { SYS_DVBS2, PSK_8, FEC_3_5, 0x00, 0x0c },
381 { SYS_DVBS2, PSK_8, FEC_2_3, 0x00, 0x0d },
382 { SYS_DVBS2, PSK_8, FEC_3_4, 0x00, 0x0e },
383 { SYS_DVBS2, PSK_8, FEC_5_6, 0x00, 0x0f },
384 { SYS_DVBS2, PSK_8, FEC_8_9, 0x00, 0x10 },
385 { SYS_DVBS2, PSK_8, FEC_9_10, 0x00, 0x11 },
386 /*
387 * `val' can be found in the FECSTATUS register when tuning.
388 * FECSTATUS will give the actual FEC in use if tuning was successful.
389 */
390};
391
392static int cx24116_lookup_fecmod(struct cx24116_state* state,
393 fe_modulation_t m, fe_code_rate_t f)
394{
395 int i, ret = -EOPNOTSUPP;
396
397 dprintk("%s(0x%02x,0x%02x)\n", __func__, m, f);
398
399 for(i=0 ; i < sizeof(CX24116_MODFEC_MODES) / sizeof(struct cx24116_modfec) ; i++)
400 {
401 if( (m == CX24116_MODFEC_MODES[i].modulation) &&
402 (f == CX24116_MODFEC_MODES[i].fec) )
403 {
404 ret = i;
405 break;
406 }
407 }
408
409 return ret;
410}
411
412static int cx24116_set_fec(struct cx24116_state* state, fe_modulation_t mod, fe_code_rate_t fec)
413{
414 int ret = 0;
415
416 dprintk("%s(0x%02x,0x%02x)\n", __func__, mod, fec);
417
418 ret = cx24116_lookup_fecmod(state, mod, fec);
419
420 if(ret < 0)
421 return ret;
422
423 state->dnxt.fec = fec;
424 state->dnxt.fec_val = CX24116_MODFEC_MODES[ret].val;
425 state->dnxt.fec_mask = CX24116_MODFEC_MODES[ret].mask;
426 dprintk("%s() mask/val = 0x%02x/0x%02x\n", __func__,
427 state->dnxt.fec_mask, state->dnxt.fec_val);
428
429 return 0;
430}
431
432static int cx24116_set_symbolrate(struct cx24116_state* state, u32 rate)
433{
434 dprintk("%s(%d)\n", __func__, rate);
435
436 /* check if symbol rate is within limits */
437 if ((rate > state->frontend.ops.info.symbol_rate_max) ||
438 (rate < state->frontend.ops.info.symbol_rate_min)) {
439 dprintk("%s() unsupported symbol_rate = %d\n", __func__, rate);
440 return -EOPNOTSUPP;
441 }
442
443 state->dnxt.symbol_rate = rate;
444 dprintk("%s() symbol_rate = %d\n", __func__, rate);
445
446 return 0;
447}
448
449static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw);
450
451static int cx24116_firmware_ondemand(struct dvb_frontend* fe)
452{
453 struct cx24116_state *state = fe->demodulator_priv;
454 const struct firmware *fw;
455 int ret = 0;
456
457 dprintk("%s()\n",__func__);
458
459 if (cx24116_readreg(state, 0x20) > 0)
460 {
461
462 if (state->skip_fw_load)
463 return 0;
464
465 /* Load firmware */
466 /* request the firmware, this will block until someone uploads it */
467 printk("%s: Waiting for firmware upload (%s)...\n", __func__, CX24116_DEFAULT_FIRMWARE);
468 ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, &state->i2c->dev);
469 printk("%s: Waiting for firmware upload(2)...\n", __func__);
470 if (ret) {
471 printk("%s: No firmware uploaded (timeout or file not found?)\n", __func__);
472 return ret;
473 }
474
475 /* Make sure we don't recurse back through here during loading */
476 state->skip_fw_load = 1;
477
478 ret = cx24116_load_firmware(fe, fw);
479 if (ret)
480 printk("%s: Writing firmware to device failed\n", __func__);
481
482 release_firmware(fw);
483
484 printk("%s: Firmware upload %s\n", __func__, ret == 0 ? "complete" : "failed");
485
486 /* Ensure firmware is always loaded if required */
487 state->skip_fw_load = 0;
488 }
489
490 return ret;
491}
492
493/* Take a basic firmware command structure, format it and forward it for processing */
494static int cx24116_cmd_execute(struct dvb_frontend* fe, struct cx24116_cmd *cmd)
495{
496 struct cx24116_state *state = fe->demodulator_priv;
497 int i, ret;
498
499 dprintk("%s()\n", __func__);
500
501 /* Load the firmware if required */
502 if ( (ret = cx24116_firmware_ondemand(fe)) != 0)
503 {
504 printk("%s(): Unable initialise the firmware\n", __func__);
505 return ret;
506 }
507
508 /* Write the command */
509 for(i = 0; i < cmd->len ; i++)
510 {
511 dprintk("%s: 0x%02x == 0x%02x\n", __func__, i, cmd->args[i]);
512 cx24116_writereg(state, i, cmd->args[i]);
513 }
514
515 /* Start execution and wait for cmd to terminate */
516 cx24116_writereg(state, CX24116_REG_EXECUTE, 0x01);
517 while( cx24116_readreg(state, CX24116_REG_EXECUTE) )
518 {
519 msleep(10);
520 if(i++ > 64)
521 {
522 /* Avoid looping forever if the firmware does no respond */
523 printk("%s() Firmware not responding\n", __func__);
524 return -EREMOTEIO;
525 }
526 }
527 return 0;
528}
529
530static int cx24116_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
531{
532 struct cx24116_state* state = fe->demodulator_priv;
533 struct cx24116_cmd cmd;
534 int i, ret;
535 unsigned char vers[4];
536
537 dprintk("%s\n", __func__);
538 dprintk("Firmware is %zu bytes (%02x %02x .. %02x %02x)\n"
539 ,fw->size
540 ,fw->data[0]
541 ,fw->data[1]
542 ,fw->data[ fw->size-2 ]
543 ,fw->data[ fw->size-1 ]
544 );
545
546 /* Toggle 88x SRST pin to reset demod */
547 if (state->config->reset_device)
548 state->config->reset_device(fe);
549
550 /* Begin the firmware load process */
551 /* Prepare the demod, load the firmware, cleanup after load */
552
553 /* Init PLL */
554 cx24116_writereg(state, 0xE5, 0x00);
555 cx24116_writereg(state, 0xF1, 0x08);
556 cx24116_writereg(state, 0xF2, 0x13);
557
558 /* Start PLL */
559 cx24116_writereg(state, 0xe0, 0x03);
560 cx24116_writereg(state, 0xe0, 0x00);
561
562 /* Unknown */
563 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
564 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
565
566 /* Unknown */
567 cx24116_writereg(state, 0xF0, 0x03);
568 cx24116_writereg(state, 0xF4, 0x81);
569 cx24116_writereg(state, 0xF5, 0x00);
570 cx24116_writereg(state, 0xF6, 0x00);
571
572 /* write the entire firmware as one transaction */
573 cx24116_writeregN(state, 0xF7, fw->data, fw->size);
574
575 cx24116_writereg(state, 0xF4, 0x10);
576 cx24116_writereg(state, 0xF0, 0x00);
577 cx24116_writereg(state, 0xF8, 0x06);
578
579 /* Firmware CMD 10: VCO config */
580 cmd.args[0x00] = CMD_SET_VCO;
581 cmd.args[0x01] = 0x05;
582 cmd.args[0x02] = 0xdc;
583 cmd.args[0x03] = 0xda;
584 cmd.args[0x04] = 0xae;
585 cmd.args[0x05] = 0xaa;
586 cmd.args[0x06] = 0x04;
587 cmd.args[0x07] = 0x9d;
588 cmd.args[0x08] = 0xfc;
589 cmd.args[0x09] = 0x06;
590 cmd.len= 0x0a;
591 ret = cx24116_cmd_execute(fe, &cmd);
592 if (ret != 0)
593 return ret;
594
595 cx24116_writereg(state, CX24116_REG_SSTATUS, 0x00);
596
597 /* Firmware CMD 14: Tuner config */
598 cmd.args[0x00] = CMD_TUNERINIT;
599 cmd.args[0x01] = 0x00;
600 cmd.args[0x02] = 0x00;
601 cmd.len= 0x03;
602 ret = cx24116_cmd_execute(fe, &cmd);
603 if (ret != 0)
604 return ret;
605
606 cx24116_writereg(state, 0xe5, 0x00);
607
608 /* Firmware CMD 13: MPEG config */
609 cmd.args[0x00] = CMD_MPEGCONFIG;
610 cmd.args[0x01] = 0x01;
611 cmd.args[0x02] = 0x75;
612 cmd.args[0x03] = 0x00;
613 if (state->config->mpg_clk_pos_pol)
614 cmd.args[0x04] = state->config->mpg_clk_pos_pol;
615 else
616 cmd.args[0x04] = 0x02;
617 cmd.args[0x05] = 0x00;
618 cmd.len= 0x06;
619 ret = cx24116_cmd_execute(fe, &cmd);
620 if (ret != 0)
621 return ret;
622
623 /* Firmware CMD 35: Get firmware version */
624 cmd.args[0x00] = CMD_UPDFWVERS;
625 cmd.len= 0x02;
626 for(i=0; i<4; i++) {
627 cmd.args[0x01] = i;
628 ret = cx24116_cmd_execute(fe, &cmd);
629 if (ret != 0)
630 return ret;
631 vers[i]= cx24116_readreg(state, CX24116_REG_MAILBOX);
632 }
633 printk("%s: FW version %i.%i.%i.%i\n", __func__,
634 vers[0], vers[1], vers[2], vers[3]);
635
636 return 0;
637}
638
639static int cx24116_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
640{
641 /* The isl6421 module will override this function in the fops. */
642 dprintk("%s() This should never appear if the isl6421 module is loaded correctly\n",__func__);
643
644 return -EOPNOTSUPP;
645}
646
647static int cx24116_read_status(struct dvb_frontend* fe, fe_status_t* status)
648{
649 struct cx24116_state *state = fe->demodulator_priv;
650
651 int lock = cx24116_readreg(state, CX24116_REG_SSTATUS);
652
653 dprintk("%s: status = 0x%02x\n", __func__, lock);
654
655 *status = 0;
656
657 if (lock & CX24116_HAS_SIGNAL)
658 *status |= FE_HAS_SIGNAL;
659 if (lock & CX24116_HAS_CARRIER)
660 *status |= FE_HAS_CARRIER;
661 if (lock & CX24116_HAS_VITERBI)
662 *status |= FE_HAS_VITERBI;
663 if (lock & CX24116_HAS_SYNCLOCK)
664 *status |= FE_HAS_SYNC | FE_HAS_LOCK;
665
666 return 0;
667}
668
669static int cx24116_read_ber(struct dvb_frontend* fe, u32* ber)
670{
671 struct cx24116_state *state = fe->demodulator_priv;
672
673 dprintk("%s()\n", __func__);
674
675 *ber = ( cx24116_readreg(state, CX24116_REG_BER24) << 24 ) |
676 ( cx24116_readreg(state, CX24116_REG_BER16) << 16 ) |
677 ( cx24116_readreg(state, CX24116_REG_BER8 ) << 8 ) |
678 cx24116_readreg(state, CX24116_REG_BER0 );
679
680 return 0;
681}
682
683/* TODO Determine function and scale appropriately */
684static int cx24116_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
685{
686 struct cx24116_state *state = fe->demodulator_priv;
687 struct cx24116_cmd cmd;
688 int ret;
689 u16 sig_reading;
690
691 dprintk("%s()\n", __func__);
692
693 /* Firmware CMD 19: Get AGC */
694 cmd.args[0x00] = CMD_GETAGC;
695 cmd.len= 0x01;
696 ret = cx24116_cmd_execute(fe, &cmd);
697 if (ret != 0)
698 return ret;
699
700 sig_reading = ( cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK ) |
701 ( cx24116_readreg(state, CX24116_REG_SIGNAL) << 6 );
702 *signal_strength= 0 - sig_reading;
703
704 dprintk("%s: raw / cooked = 0x%04x / 0x%04x\n", __func__, sig_reading, *signal_strength);
705
706 return 0;
707}
708
709/* SNR (0..100)% = (sig & 0xf0) * 10 + (sig & 0x0f) * 10 / 16 */
710static int cx24116_read_snr_pct(struct dvb_frontend* fe, u16* snr)
711{
712 struct cx24116_state *state = fe->demodulator_priv;
713 u8 snr_reading;
714 static const u32 snr_tab[] = { /* 10 x Table (rounded up) */
715 0x00000,0x0199A,0x03333,0x04ccD,0x06667,
716 0x08000,0x0999A,0x0b333,0x0cccD,0x0e667,
717 0x10000,0x1199A,0x13333,0x14ccD,0x16667,0x18000 };
718
719 dprintk("%s()\n", __func__);
720
721 snr_reading = cx24116_readreg(state, CX24116_REG_QUALITY0);
722
723 if(snr_reading >= 0xa0 /* 100% */)
724 *snr = 0xffff;
725 else
726 *snr = snr_tab [ ( snr_reading & 0xf0 ) >> 4 ] +
727 ( snr_tab [ ( snr_reading & 0x0f ) ] >> 4 );
728
729 dprintk("%s: raw / cooked = 0x%02x / 0x%04x\n", __func__,
730 snr_reading, *snr);
731
732 return 0;
733}
734
735/* The reelbox patches show the value in the registers represents
736 * ESNO, from 0->30db (values 0->300). We provide this value by
737 * default.
738 */
739static int cx24116_read_snr_esno(struct dvb_frontend* fe, u16* snr)
740{
741 struct cx24116_state *state = fe->demodulator_priv;
742
743 dprintk("%s()\n", __func__);
744
745 *snr = cx24116_readreg(state, CX24116_REG_QUALITY8) << 8 |
746 cx24116_readreg(state, CX24116_REG_QUALITY0);
747
748 dprintk("%s: raw 0x%04x\n", __func__, *snr);
749
750 return 0;
751}
752
753static int cx24116_read_snr(struct dvb_frontend* fe, u16* snr)
754{
755 if (esno_snr == 1)
756 return cx24116_read_snr_esno(fe, snr);
757 else
758 return cx24116_read_snr_pct(fe, snr);
759}
760
761static int cx24116_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
762{
763 struct cx24116_state *state = fe->demodulator_priv;
764
765 dprintk("%s()\n", __func__);
766
767 *ucblocks = ( cx24116_readreg(state, CX24116_REG_UCB8) << 8 ) |
768 cx24116_readreg(state, CX24116_REG_UCB0);
769
770 return 0;
771}
772
773/* Overwrite the current tuning params, we are about to tune */
774static void cx24116_clone_params(struct dvb_frontend* fe)
775{
776 struct cx24116_state *state = fe->demodulator_priv;
777 memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
778}
779
780/* Wait for LNB */
781static int cx24116_wait_for_lnb(struct dvb_frontend* fe)
782{
783 struct cx24116_state *state = fe->demodulator_priv;
784 int i;
785
786 dprintk("%s() qstatus = 0x%02x\n", __func__,
787 cx24116_readreg(state, CX24116_REG_QSTATUS));
788
789 /* Wait for up to 300 ms */
790 for(i = 0; i < 30 ; i++) {
791 if (cx24116_readreg(state, CX24116_REG_QSTATUS) & 0x20)
792 return 0;
793 msleep(10);
794 }
795
796 dprintk("%s(): LNB not ready\n", __func__);
797
798 return -ETIMEDOUT; /* -EBUSY ? */
799}
800
801static int cx24116_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
802{
803 struct cx24116_cmd cmd;
804 int ret;
805
806 dprintk("%s(%d)\n", __func__, tone);
807 if ( (tone != SEC_TONE_ON) && (tone != SEC_TONE_OFF) ) {
808 printk("%s: Invalid, tone=%d\n", __func__, tone);
809 return -EINVAL;
810 }
811
812 /* Wait for LNB ready */
813 ret = cx24116_wait_for_lnb(fe);
814 if(ret != 0)
815 return ret;
816
817 /* Min delay time after DiSEqC send */
818 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
819
820 /* This is always done before the tone is set */
821 cmd.args[0x00] = CMD_SET_TONEPRE;
822 cmd.args[0x01] = 0x00;
823 cmd.len= 0x02;
824 ret = cx24116_cmd_execute(fe, &cmd);
825 if (ret != 0)
826 return ret;
827
828 /* Now we set the tone */
829 cmd.args[0x00] = CMD_SET_TONE;
830 cmd.args[0x01] = 0x00;
831 cmd.args[0x02] = 0x00;
832
833 switch (tone) {
834 case SEC_TONE_ON:
835 dprintk("%s: setting tone on\n", __func__);
836 cmd.args[0x03] = 0x01;
837 break;
838 case SEC_TONE_OFF:
839 dprintk("%s: setting tone off\n",__func__);
840 cmd.args[0x03] = 0x00;
841 break;
842 }
843 cmd.len= 0x04;
844
845 /* Min delay time before DiSEqC send */
846 msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
847
848 return cx24116_cmd_execute(fe, &cmd);
849}
850
851/* Initialise DiSEqC */
852static int cx24116_diseqc_init(struct dvb_frontend* fe)
853{
854 struct cx24116_state *state = fe->demodulator_priv;
855 struct cx24116_cmd cmd;
856 int ret;
857
858 /* Firmware CMD 20: LNB/DiSEqC config */
859 cmd.args[0x00] = CMD_LNBCONFIG;
860 cmd.args[0x01] = 0x00;
861 cmd.args[0x02] = 0x10;
862 cmd.args[0x03] = 0x00;
863 cmd.args[0x04] = 0x8f;
864 cmd.args[0x05] = 0x28;
865 cmd.args[0x06] = (toneburst == CX24116_DISEQC_TONEOFF) ? 0x00 : 0x01;
866 cmd.args[0x07] = 0x01;
867 cmd.len= 0x08;
868 ret = cx24116_cmd_execute(fe, &cmd);
869 if (ret != 0)
870 return ret;
871
872 /* Prepare a DiSEqC command */
873 state->dsec_cmd.args[0x00] = CMD_LNBSEND;
874
875 /* DiSEqC burst */
876 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A;
877
878 /* Unknown */
879 state->dsec_cmd.args[CX24116_DISEQC_ARG2_2] = 0x02;
880 state->dsec_cmd.args[CX24116_DISEQC_ARG3_0] = 0x00;
881 state->dsec_cmd.args[CX24116_DISEQC_ARG4_0] = 0x00; /* Continuation flag? */
882
883 /* DiSEqC message length */
884 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = 0x00;
885
886 /* Command length */
887 state->dsec_cmd.len= CX24116_DISEQC_MSGOFS;
888
889 return 0;
890}
891
892/* Send DiSEqC message with derived burst (hack) || previous burst */
893static int cx24116_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *d)
894{
895 struct cx24116_state *state = fe->demodulator_priv;
896 int i, ret;
897
898 /* Dump DiSEqC message */
899 if (debug) {
900 printk("cx24116: %s(", __func__);
901 for(i = 0 ; i < d->msg_len ;) {
902 printk("0x%02x", d->msg[i]);
903 if(++i < d->msg_len)
904 printk(", ");
905 }
906 printk(") toneburst=%d\n", toneburst);
907 }
908
909 /* Validate length */
910 if(d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS))
911 return -EINVAL;
912
913 /* DiSEqC message */
914 for (i = 0; i < d->msg_len; i++)
915 state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i];
916
917 /* DiSEqC message length */
918 state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] = d->msg_len;
919
920 /* Command length */
921 state->dsec_cmd.len= CX24116_DISEQC_MSGOFS + state->dsec_cmd.args[CX24116_DISEQC_MSGLEN];
922
923 /* DiSEqC toneburst */
924 if(toneburst == CX24116_DISEQC_MESGCACHE)
925 /* Message is cached */
926 return 0;
927
928 else if(toneburst == CX24116_DISEQC_TONEOFF)
929 /* Message is sent without burst */
930 state->dsec_cmd.args[CX24116_DISEQC_BURST] = 0;
931
932 else if(toneburst == CX24116_DISEQC_TONECACHE) {
933 /*
934 * Message is sent with derived else cached burst
935 *
936 * WRITE PORT GROUP COMMAND 38
937 *
938 * 0/A/A: E0 10 38 F0..F3
939 * 1/B/B: E0 10 38 F4..F7
940 * 2/C/A: E0 10 38 F8..FB
941 * 3/D/B: E0 10 38 FC..FF
942 *
943 * databyte[3]= 8421:8421
944 * ABCD:WXYZ
945 * CLR :SET
946 *
947 * WX= PORT SELECT 0..3 (X=TONEBURST)
948 * Y = VOLTAGE (0=13V, 1=18V)
949 * Z = BAND (0=LOW, 1=HIGH(22K))
950 */
951 if(d->msg_len >= 4 && d->msg[2] == 0x38)
952 state->dsec_cmd.args[CX24116_DISEQC_BURST] = ((d->msg[3] & 4) >> 2);
953 if(debug)
954 dprintk("%s burst=%d\n", __func__, state->dsec_cmd.args[CX24116_DISEQC_BURST]);
955 }
956
957 /* Wait for LNB ready */
958 ret = cx24116_wait_for_lnb(fe);
959 if(ret != 0)
960 return ret;
961
962 /* Wait for voltage/min repeat delay */
963 msleep(100);
964
965 /* Command */
966 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
967 if(ret != 0)
968 return ret;
969 /*
970 * Wait for send
971 *
972 * Eutelsat spec:
973 * >15ms delay + (XXX determine if FW does this, see set_tone)
974 * 13.5ms per byte +
975 * >15ms delay +
976 * 12.5ms burst +
977 * >15ms delay (XXX determine if FW does this, see set_tone)
978 */
979 msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + ((toneburst == CX24116_DISEQC_TONEOFF) ? 30 : 60) );
980
981 return 0;
982}
983
984/* Send DiSEqC burst */
985static int cx24116_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
986{
987 struct cx24116_state *state = fe->demodulator_priv;
988 int ret;
989
990 dprintk("%s(%d) toneburst=%d\n",__func__, burst, toneburst);
991
992 /* DiSEqC burst */
993 if (burst == SEC_MINI_A)
994 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_A;
995 else if(burst == SEC_MINI_B)
996 state->dsec_cmd.args[CX24116_DISEQC_BURST] = CX24116_DISEQC_MINI_B;
997 else
998 return -EINVAL;
999
1000 /* DiSEqC toneburst */
1001 if(toneburst != CX24116_DISEQC_MESGCACHE)
1002 /* Burst is cached */
1003 return 0;
1004
1005 /* Burst is to be sent with cached message */
1006
1007 /* Wait for LNB ready */
1008 ret = cx24116_wait_for_lnb(fe);
1009 if(ret != 0)
1010 return ret;
1011
1012 /* Wait for voltage/min repeat delay */
1013 msleep(100);
1014
1015 /* Command */
1016 ret = cx24116_cmd_execute(fe, &state->dsec_cmd);
1017 if(ret != 0)
1018 return ret;
1019
1020 /*
1021 * Wait for send
1022 *
1023 * Eutelsat spec:
1024 * >15ms delay + (XXX determine if FW does this, see set_tone)
1025 * 13.5ms per byte +
1026 * >15ms delay +
1027 * 12.5ms burst +
1028 * >15ms delay (XXX determine if FW does this, see set_tone)
1029 */
1030 msleep( (state->dsec_cmd.args[CX24116_DISEQC_MSGLEN] << 4) + 60 );
1031
1032 return 0;
1033}
1034
1035static void cx24116_release(struct dvb_frontend* fe)
1036{
1037 struct cx24116_state* state = fe->demodulator_priv;
1038 dprintk("%s\n",__func__);
1039 kfree(state);
1040}
1041
1042static struct dvb_frontend_ops cx24116_ops;
1043
1044struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
1045 struct i2c_adapter* i2c)
1046{
1047 struct cx24116_state* state = NULL;
1048 int ret;
1049
1050 dprintk("%s\n",__func__);
1051
1052 /* allocate memory for the internal state */
1053 state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL);
1054 if (state == NULL) {
1055 printk("Unable to kmalloc\n");
1056 goto error1;
1057 }
1058
1059 /* setup the state */
1060 memset(state, 0, sizeof(struct cx24116_state));
1061
1062 state->config = config;
1063 state->i2c = i2c;
1064
1065 /* check if the demod is present */
1066 ret = (cx24116_readreg(state, 0xFF) << 8) | cx24116_readreg(state, 0xFE);
1067 if (ret != 0x0501) {
1068 printk("Invalid probe, probably not a CX24116 device\n");
1069 goto error2;
1070 }
1071
1072 /* create dvb_frontend */
1073 memcpy(&state->frontend.ops, &cx24116_ops, sizeof(struct dvb_frontend_ops));
1074 state->frontend.demodulator_priv = state;
1075 return &state->frontend;
1076
1077error2: kfree(state);
1078error1: return NULL;
1079}
1080/*
1081 * Initialise or wake up device
1082 *
1083 * Power config will reset and load initial firmware if required
1084 */
1085static int cx24116_initfe(struct dvb_frontend* fe)
1086{
1087 struct cx24116_state* state = fe->demodulator_priv;
1088 struct cx24116_cmd cmd;
1089 int ret;
1090
1091 dprintk("%s()\n",__func__);
1092
1093 /* Power on */
1094 cx24116_writereg(state, 0xe0, 0);
1095 cx24116_writereg(state, 0xe1, 0);
1096 cx24116_writereg(state, 0xea, 0);
1097
1098 /* Firmware CMD 36: Power config */
1099 cmd.args[0x00] = CMD_TUNERSLEEP;
1100 cmd.args[0x01] = 0;
1101 cmd.len= 0x02;
1102 ret = cx24116_cmd_execute(fe, &cmd);
1103 if(ret != 0)
1104 return ret;
1105
1106 return cx24116_diseqc_init(fe);
1107}
1108
1109/*
1110 * Put device to sleep
1111 */
1112static int cx24116_sleep(struct dvb_frontend* fe)
1113{
1114 struct cx24116_state* state = fe->demodulator_priv;
1115 struct cx24116_cmd cmd;
1116 int ret;
1117
1118 dprintk("%s()\n",__func__);
1119
1120 /* Firmware CMD 36: Power config */
1121 cmd.args[0x00] = CMD_TUNERSLEEP;
1122 cmd.args[0x01] = 1;
1123 cmd.len= 0x02;
1124 ret = cx24116_cmd_execute(fe, &cmd);
1125 if(ret != 0)
1126 return ret;
1127
1128 /* Power off (Shutdown clocks) */
1129 cx24116_writereg(state, 0xea, 0xff);
1130 cx24116_writereg(state, 0xe1, 1);
1131 cx24116_writereg(state, 0xe0, 1);
1132
1133 return 0;
1134}
1135
1136static int cx24116_set_property(struct dvb_frontend *fe, struct dtv_property* tvp)
1137{
1138 dprintk("%s(..)\n", __func__);
1139 return 0;
1140}
1141
1142static int cx24116_get_property(struct dvb_frontend *fe, struct dtv_property* tvp)
1143{
1144 dprintk("%s(..)\n", __func__);
1145 return 0;
1146}
1147
1148/* dvb-core told us to tune, the tv property cache will be complete,
1149 * it's safe for is to pull values and use them for tuning purposes.
1150 */
1151static int cx24116_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
1152{
1153 struct cx24116_state *state = fe->demodulator_priv;
1154 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1155 struct cx24116_cmd cmd;
1156 fe_status_t tunerstat;
1157 int i, status, ret, retune;
1158
1159 dprintk("%s()\n",__func__);
1160
1161 switch(c->delivery_system) {
1162 case SYS_DVBS:
1163 dprintk("%s: DVB-S delivery system selected\n",__func__);
1164
1165 /* Only QPSK is supported for DVB-S */
1166 if(c->modulation != QPSK) {
1167 dprintk("%s: unsupported modulation selected (%d)\n",
1168 __func__, c->modulation);
1169 return -EOPNOTSUPP;
1170 }
1171
1172 /* Pilot doesn't exist in DVB-S, turn bit off */
1173 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1174 retune = 1;
1175
1176 /* DVB-S only supports 0.35 */
1177 if(c->rolloff != ROLLOFF_35) {
1178 dprintk("%s: unsupported rolloff selected (%d)\n",
1179 __func__, c->rolloff);
1180 return -EOPNOTSUPP;
1181 }
1182 state->dnxt.rolloff_val = CX24116_ROLLOFF_035;
1183 break;
1184
1185 case SYS_DVBS2:
1186 dprintk("%s: DVB-S2 delivery system selected\n",__func__);
1187
1188 /*
1189 * NBC 8PSK/QPSK with DVB-S is supported for DVB-S2,
1190 * but not hardware auto detection
1191 */
1192 if(c->modulation != PSK_8 && c->modulation != QPSK) {
1193 dprintk("%s: unsupported modulation selected (%d)\n",
1194 __func__, c->modulation);
1195 return -EOPNOTSUPP;
1196 }
1197
1198 switch(c->pilot) {
1199 case PILOT_AUTO: /* Not supported but emulated */
1200 retune = 2; /* Fall-through */
1201 case PILOT_OFF:
1202 state->dnxt.pilot_val = CX24116_PILOT_OFF;
1203 break;
1204 case PILOT_ON:
1205 state->dnxt.pilot_val = CX24116_PILOT_ON;
1206 break;
1207 default:
1208 dprintk("%s: unsupported pilot mode selected (%d)\n",
1209 __func__, c->pilot);
1210 return -EOPNOTSUPP;
1211 }
1212
1213 switch(c->rolloff) {
1214 case ROLLOFF_20:
1215 state->dnxt.rolloff_val= CX24116_ROLLOFF_020;
1216 break;
1217 case ROLLOFF_25:
1218 state->dnxt.rolloff_val= CX24116_ROLLOFF_025;
1219 break;
1220 case ROLLOFF_35:
1221 state->dnxt.rolloff_val= CX24116_ROLLOFF_035;
1222 break;
1223 case ROLLOFF_AUTO: /* Rolloff must be explicit */
1224 default:
1225 dprintk("%s: unsupported rolloff selected (%d)\n",
1226 __func__, c->rolloff);
1227 return -EOPNOTSUPP;
1228 }
1229 break;
1230
1231 default:
1232 dprintk("%s: unsupported delivery system selected (%d)\n",
1233 __func__, c->delivery_system);
1234 return -EOPNOTSUPP;
1235 }
1236 state->dnxt.modulation = c->modulation;
1237 state->dnxt.frequency = c->frequency;
1238 state->dnxt.pilot = c->pilot;
1239 state->dnxt.rolloff = c->rolloff;
1240
1241 if ((ret = cx24116_set_inversion(state, c->inversion)) != 0)
1242 return ret;
1243
1244 /* FEC_NONE/AUTO for DVB-S2 is not supported and detected here */
1245 if ((ret = cx24116_set_fec(state, c->modulation, c->fec_inner)) != 0)
1246 return ret;
1247
1248 if ((ret = cx24116_set_symbolrate(state, c->symbol_rate)) != 0)
1249 return ret;
1250
1251 /* discard the 'current' tuning parameters and prepare to tune */
1252 cx24116_clone_params(fe);
1253
1254 dprintk("%s: modulation = %d\n", __func__, state->dcur.modulation);
1255 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency);
1256 dprintk("%s: pilot = %d (val = 0x%02x)\n", __func__,
1257 state->dcur.pilot, state->dcur.pilot_val);
1258 dprintk("%s: retune = %d\n", __func__, retune);
1259 dprintk("%s: rolloff = %d (val = 0x%02x)\n", __func__,
1260 state->dcur.rolloff, state->dcur.rolloff_val);
1261 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate);
1262 dprintk("%s: FEC = %d (mask/val = 0x%02x/0x%02x)\n", __func__,
1263 state->dcur.fec, state->dcur.fec_mask, state->dcur.fec_val);
1264 dprintk("%s: Inversion = %d (val = 0x%02x)\n", __func__,
1265 state->dcur.inversion, state->dcur.inversion_val);
1266
1267 /* This is also done in advise/acquire on HVR4000 but not on LITE */
1268 if (state->config->set_ts_params)
1269 state->config->set_ts_params(fe, 0);
1270
1271 /* Set/Reset B/W */
1272 cmd.args[0x00] = CMD_BANDWIDTH;
1273 cmd.args[0x01] = 0x01;
1274 cmd.len= 0x02;
1275 ret = cx24116_cmd_execute(fe, &cmd);
1276 if (ret != 0)
1277 return ret;
1278
1279 /* Prepare a tune request */
1280 cmd.args[0x00] = CMD_TUNEREQUEST;
1281
1282 /* Frequency */
1283 cmd.args[0x01] = (state->dcur.frequency & 0xff0000) >> 16;
1284 cmd.args[0x02] = (state->dcur.frequency & 0x00ff00) >> 8;
1285 cmd.args[0x03] = (state->dcur.frequency & 0x0000ff);
1286
1287 /* Symbol Rate */
1288 cmd.args[0x04] = ((state->dcur.symbol_rate / 1000) & 0xff00) >> 8;
1289 cmd.args[0x05] = ((state->dcur.symbol_rate / 1000) & 0x00ff);
1290
1291 /* Automatic Inversion */
1292 cmd.args[0x06] = state->dcur.inversion_val;
1293
1294 /* Modulation / FEC / Pilot */
1295 cmd.args[0x07] = state->dcur.fec_val | state->dcur.pilot_val;
1296
1297 cmd.args[0x08] = CX24116_SEARCH_RANGE_KHZ >> 8;
1298 cmd.args[0x09] = CX24116_SEARCH_RANGE_KHZ & 0xff;
1299 cmd.args[0x0a] = 0x00;
1300 cmd.args[0x0b] = 0x00;
1301 cmd.args[0x0c] = state->dcur.rolloff_val;
1302 cmd.args[0x0d] = state->dcur.fec_mask;
1303
1304 if (state->dcur.symbol_rate > 30000000) {
1305 cmd.args[0x0e] = 0x04;
1306 cmd.args[0x0f] = 0x00;
1307 cmd.args[0x10] = 0x01;
1308 cmd.args[0x11] = 0x77;
1309 cmd.args[0x12] = 0x36;
1310 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x44);
1311 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x01);
1312 } else {
1313 cmd.args[0x0e] = 0x06;
1314 cmd.args[0x0f] = 0x00;
1315 cmd.args[0x10] = 0x00;
1316 cmd.args[0x11] = 0xFA;
1317 cmd.args[0x12] = 0x24;
1318 cx24116_writereg(state, CX24116_REG_CLKDIV, 0x46);
1319 cx24116_writereg(state, CX24116_REG_RATEDIV, 0x00);
1320 }
1321
1322 cmd.len= 0x13;
1323
1324 /* We need to support pilot and non-pilot tuning in the
1325 * driver automatically. This is a workaround for because
1326 * the demod does not support autodetect.
1327 */
1328 do {
1329 /* Reset status register */
1330 status = cx24116_readreg(state, CX24116_REG_SSTATUS) & CX24116_SIGNAL_MASK;
1331 cx24116_writereg(state, CX24116_REG_SSTATUS, status);
1332
1333 /* Tune */
1334 ret = cx24116_cmd_execute(fe, &cmd);
1335 if( ret != 0 )
1336 break;
1337
1338 /*
1339 * Wait for up to 500 ms before retrying
1340 *
1341 * If we are able to tune then generally it occurs within 100ms.
1342 * If it takes longer, try a different toneburst setting.
1343 */
1344 for(i = 0; i < 50 ; i++) {
1345 cx24116_read_status(fe, &tunerstat);
1346 status = tunerstat & (FE_HAS_SIGNAL | FE_HAS_SYNC);
1347 if(status == (FE_HAS_SIGNAL | FE_HAS_SYNC)) {
1348 dprintk("%s: Tuned\n",__func__);
1349 goto tuned;
1350 }
1351 msleep(10);
1352 }
1353
1354 dprintk("%s: Not tuned\n",__func__);
1355
1356 /* Toggle pilot bit when in auto-pilot */
1357 if(state->dcur.pilot == PILOT_AUTO)
1358 cmd.args[0x07] ^= CX24116_PILOT_ON;
1359 }
1360 while(--retune);
1361
1362tuned: /* Set/Reset B/W */
1363 cmd.args[0x00] = CMD_BANDWIDTH;
1364 cmd.args[0x01] = 0x00;
1365 cmd.len= 0x02;
1366 ret = cx24116_cmd_execute(fe, &cmd);
1367 if (ret != 0)
1368 return ret;
1369
1370 return ret;
1371}
1372
1373static struct dvb_frontend_ops cx24116_ops = {
1374
1375 .info = {
1376 .name = "Conexant CX24116/CX24118",
1377 .type = FE_QPSK,
1378 .frequency_min = 950000,
1379 .frequency_max = 2150000,
1380 .frequency_stepsize = 1011, /* kHz for QPSK frontends */
1381 .frequency_tolerance = 5000,
1382 .symbol_rate_min = 1000000,
1383 .symbol_rate_max = 45000000,
1384 .caps = FE_CAN_INVERSION_AUTO |
1385 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1386 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
1387 FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1388 FE_CAN_QPSK | FE_CAN_RECOVER
1389 },
1390
1391 .release = cx24116_release,
1392
1393 .init = cx24116_initfe,
1394 .sleep = cx24116_sleep,
1395 .read_status = cx24116_read_status,
1396 .read_ber = cx24116_read_ber,
1397 .read_signal_strength = cx24116_read_signal_strength,
1398 .read_snr = cx24116_read_snr,
1399 .read_ucblocks = cx24116_read_ucblocks,
1400 .set_tone = cx24116_set_tone,
1401 .set_voltage = cx24116_set_voltage,
1402 .diseqc_send_master_cmd = cx24116_send_diseqc_msg,
1403 .diseqc_send_burst = cx24116_diseqc_send_burst,
1404
1405 .set_property = cx24116_set_property,
1406 .get_property = cx24116_get_property,
1407 .set_frontend = cx24116_set_frontend,
1408};
1409
1410module_param(debug, int, 0644);
1411MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
1412
1413module_param(toneburst, int, 0644);
1414MODULE_PARM_DESC(toneburst, "DiSEqC toneburst 0=OFF, 1=TONE CACHE, 2=MESSAGE CACHE (default:1)");
1415
1416module_param(esno_snr, int, 0644);
1417MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, 1=ESNO(db * 10) (default:0)");
1418
1419MODULE_DESCRIPTION("DVB Frontend module for Conexant cx24116/cx24118 hardware");
1420MODULE_AUTHOR("Steven Toth");
1421MODULE_LICENSE("GPL");
1422
1423EXPORT_SYMBOL(cx24116_attach);
diff --git a/drivers/media/dvb/frontends/cx24116.h b/drivers/media/dvb/frontends/cx24116.h
new file mode 100644
index 000000000000..8dbcec268394
--- /dev/null
+++ b/drivers/media/dvb/frontends/cx24116.h
@@ -0,0 +1,53 @@
1/*
2 Conexant cx24116/cx24118 - DVBS/S2 Satellite demod/tuner driver
3
4 Copyright (C) 2006 Steven Toth <stoth@linuxtv.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef CX24116_H
22#define CX24116_H
23
24#include <linux/dvb/frontend.h>
25
26struct cx24116_config
27{
28 /* the demodulator's i2c address */
29 u8 demod_address;
30
31 /* Need to set device param for start_dma */
32 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
33
34 /* Need to reset device during firmware loading */
35 int (*reset_device)(struct dvb_frontend* fe);
36
37 /* Need to set MPEG parameters */
38 u8 mpg_clk_pos_pol:0x02;
39};
40
41#if defined(CONFIG_DVB_CX24116) || defined(CONFIG_DVB_CX24116_MODULE)
42extern struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
43 struct i2c_adapter* i2c);
44#else
45static inline struct dvb_frontend* cx24116_attach(const struct cx24116_config* config,
46 struct i2c_adapter* i2c)
47{
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
49 return NULL;
50}
51#endif // CONFIG_DVB_CX24116
52
53#endif /* CX24116_H */
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
index 3eedfdf505bc..21f2c5161af4 100644
--- a/drivers/media/dvb/frontends/dib0070.h
+++ b/drivers/media/dvb/frontends/dib0070.h
@@ -41,6 +41,7 @@ struct dib0070_config {
41extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, 41extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
42 struct i2c_adapter *i2c, 42 struct i2c_adapter *i2c,
43 struct dib0070_config *cfg); 43 struct dib0070_config *cfg);
44extern u16 dib0070_wbd_offset(struct dvb_frontend *);
44#else 45#else
45static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, 46static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
46 struct i2c_adapter *i2c, 47 struct i2c_adapter *i2c,
@@ -49,9 +50,14 @@ static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
49 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
50 return NULL; 51 return NULL;
51} 52}
53
54static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return -ENODEV;
58}
52#endif 59#endif
53 60
54extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); 61extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open);
55extern u16 dib0070_wbd_offset(struct dvb_frontend *);
56 62
57#endif 63#endif
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c
index 5f1375e30dfc..0109720353bd 100644
--- a/drivers/media/dvb/frontends/dib7000m.c
+++ b/drivers/media/dvb/frontends/dib7000m.c
@@ -1284,7 +1284,10 @@ struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum di
1284} 1284}
1285EXPORT_SYMBOL(dib7000m_get_i2c_master); 1285EXPORT_SYMBOL(dib7000m_get_i2c_master);
1286 1286
1287int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000m_config cfg[]) 1287#if 0
1288/* used with some prototype boards */
1289int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
1290 u8 default_addr, struct dib7000m_config cfg[])
1288{ 1291{
1289 struct dib7000m_state st = { .i2c_adap = i2c }; 1292 struct dib7000m_state st = { .i2c_adap = i2c };
1290 int k = 0; 1293 int k = 0;
@@ -1329,6 +1332,7 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1329 return 0; 1332 return 0;
1330} 1333}
1331EXPORT_SYMBOL(dib7000m_i2c_enumeration); 1334EXPORT_SYMBOL(dib7000m_i2c_enumeration);
1335#endif
1332 1336
1333static struct dvb_frontend_ops dib7000m_ops; 1337static struct dvb_frontend_ops dib7000m_ops;
1334struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg) 1338struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 1a0142e0d741..8217e5b38f47 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -1333,7 +1333,8 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
1333 /* Ensure the output mode remains at the previous default if it's 1333 /* Ensure the output mode remains at the previous default if it's
1334 * not specifically set by the caller. 1334 * not specifically set by the caller.
1335 */ 1335 */
1336 if (st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) 1336 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) &&
1337 (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
1337 st->cfg.output_mode = OUTMODE_MPEG2_FIFO; 1338 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
1338 1339
1339 demod = &st->demod; 1340 demod = &st->demod;
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index 07c4d12ed5b7..3e8126857127 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -41,6 +41,14 @@ struct dib7000p_config {
41extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, 41extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
42 u8 i2c_addr, 42 u8 i2c_addr,
43 struct dib7000p_config *cfg); 43 struct dib7000p_config *cfg);
44extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *,
45 enum dibx000_i2c_interface,
46 int);
47extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
48 int no_of_demods, u8 default_addr,
49 struct dib7000p_config cfg[]);
50extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
51extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
44#else 52#else
45static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, 53static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
46 u8 i2c_addr, 54 u8 i2c_addr,
@@ -49,13 +57,36 @@ static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
49 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 57 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
50 return NULL; 58 return NULL;
51} 59}
52#endif
53 60
54extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]); 61static inline
62struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe,
63 enum dibx000_i2c_interface i, int x)
64{
65 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
66 return NULL;
67}
68
69extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
70 int no_of_demods, u8 default_addr,
71 struct dib7000p_config cfg[])
72{
73 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
74 return -ENODEV;
75}
76
77extern int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
78{
79 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
80 return -ENODEV;
81}
82
83extern int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
84{
85 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
86 return -ENODEV;
87}
88#endif
55 89
56extern struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
57extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); 90extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
58extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
59extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
60 91
61#endif 92#endif
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index 3cbed874a6f8..b9ca5c8d2dd9 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -38,35 +38,32 @@ static const char mod_name[] = "drx397xD";
38#define F_SET_0D0h 1 38#define F_SET_0D0h 1
39#define F_SET_0D4h 2 39#define F_SET_0D4h 2
40 40
41typedef enum fw_ix { 41enum fw_ix {
42#define _FW_ENTRY(a, b) b 42#define _FW_ENTRY(a, b) b
43#include "drx397xD_fw.h" 43#include "drx397xD_fw.h"
44} fw_ix_t; 44};
45 45
46/* chip specifics */ 46/* chip specifics */
47struct drx397xD_state { 47struct drx397xD_state {
48 struct i2c_adapter *i2c; 48 struct i2c_adapter *i2c;
49 struct dvb_frontend frontend; 49 struct dvb_frontend frontend;
50 struct drx397xD_config config; 50 struct drx397xD_config config;
51 fw_ix_t chip_rev; 51 enum fw_ix chip_rev;
52 int flags; 52 int flags;
53 u32 bandwidth_parm; /* internal bandwidth conversions */ 53 u32 bandwidth_parm; /* internal bandwidth conversions */
54 u32 f_osc; /* w90: actual osc frequency [Hz] */ 54 u32 f_osc; /* w90: actual osc frequency [Hz] */
55}; 55};
56 56
57/******************************************************************************* 57/* Firmware */
58 * Firmware
59 ******************************************************************************/
60
61static const char *blob_name[] = { 58static const char *blob_name[] = {
62#define _BLOB_ENTRY(a, b) a 59#define _BLOB_ENTRY(a, b) a
63#include "drx397xD_fw.h" 60#include "drx397xD_fw.h"
64}; 61};
65 62
66typedef enum blob_ix { 63enum blob_ix {
67#define _BLOB_ENTRY(a, b) b 64#define _BLOB_ENTRY(a, b) b
68#include "drx397xD_fw.h" 65#include "drx397xD_fw.h"
69} blob_ix_t; 66};
70 67
71static struct { 68static struct {
72 const char *name; 69 const char *name;
@@ -85,7 +82,7 @@ static struct {
85}; 82};
86 83
87/* use only with writer lock aquired */ 84/* use only with writer lock aquired */
88static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix) 85static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix)
89{ 86{
90 memset(&fw[ix].data[0], 0, sizeof(fw[0].data)); 87 memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
91 if (fw[ix].file) 88 if (fw[ix].file)
@@ -94,9 +91,9 @@ static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix)
94 91
95static void drx_release_fw(struct drx397xD_state *s) 92static void drx_release_fw(struct drx397xD_state *s)
96{ 93{
97 fw_ix_t ix = s->chip_rev; 94 enum fw_ix ix = s->chip_rev;
98 95
99 pr_debug("%s\n", __FUNCTION__); 96 pr_debug("%s\n", __func__);
100 97
101 write_lock(&fw[ix].lock); 98 write_lock(&fw[ix].lock);
102 if (fw[ix].refcnt) { 99 if (fw[ix].refcnt) {
@@ -107,13 +104,13 @@ static void drx_release_fw(struct drx397xD_state *s)
107 write_unlock(&fw[ix].lock); 104 write_unlock(&fw[ix].lock);
108} 105}
109 106
110static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix) 107static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix)
111{ 108{
112 const u8 *data; 109 const u8 *data;
113 size_t size, len; 110 size_t size, len;
114 int i = 0, j, rc = -EINVAL; 111 int i = 0, j, rc = -EINVAL;
115 112
116 pr_debug("%s\n", __FUNCTION__); 113 pr_debug("%s\n", __func__);
117 114
118 if (ix < 0 || ix >= ARRAY_SIZE(fw)) 115 if (ix < 0 || ix >= ARRAY_SIZE(fw))
119 return -EINVAL; 116 return -EINVAL;
@@ -175,32 +172,34 @@ static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix)
175 goto exit_corrupt; 172 goto exit_corrupt;
176 } 173 }
177 } while (i < size); 174 } while (i < size);
178 exit_corrupt: 175
176exit_corrupt:
179 printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name); 177 printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name);
180 exit_err: 178exit_err:
181 _drx_release_fw(s, ix); 179 _drx_release_fw(s, ix);
182 fw[ix].refcnt--; 180 fw[ix].refcnt--;
183 exit_ok: 181exit_ok:
184 fw[ix].refcnt++; 182 fw[ix].refcnt++;
185 write_unlock(&fw[ix].lock); 183 write_unlock(&fw[ix].lock);
184
186 return rc; 185 return rc;
187} 186}
188 187
189/******************************************************************************* 188/* i2c bus IO */
190 * i2c bus IO 189static int write_fw(struct drx397xD_state *s, enum blob_ix ix)
191 ******************************************************************************/
192
193static int write_fw(struct drx397xD_state *s, blob_ix_t ix)
194{ 190{
195 struct i2c_msg msg = {.addr = s->config.demod_address,.flags = 0 };
196 const u8 *data; 191 const u8 *data;
197 int len, rc = 0, i = 0; 192 int len, rc = 0, i = 0;
193 struct i2c_msg msg = {
194 .addr = s->config.demod_address,
195 .flags = 0
196 };
198 197
199 if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) { 198 if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) {
200 pr_debug("%s drx_fw_ix_t out of range\n", __FUNCTION__); 199 pr_debug("%s drx_fw_ix_t out of range\n", __func__);
201 return -EINVAL; 200 return -EINVAL;
202 } 201 }
203 pr_debug("%s %s\n", __FUNCTION__, blob_name[ix]); 202 pr_debug("%s %s\n", __func__, blob_name[ix]);
204 203
205 read_lock(&fw[s->chip_rev].lock); 204 read_lock(&fw[s->chip_rev].lock);
206 data = fw[s->chip_rev].data[ix]; 205 data = fw[s->chip_rev].data[ix];
@@ -229,33 +228,33 @@ static int write_fw(struct drx397xD_state *s, blob_ix_t ix)
229 goto exit_rc; 228 goto exit_rc;
230 } 229 }
231 } 230 }
232 exit_rc: 231exit_rc:
233 read_unlock(&fw[s->chip_rev].lock); 232 read_unlock(&fw[s->chip_rev].lock);
233
234 return 0; 234 return 0;
235} 235}
236 236
237/* Function is not endian safe, use the RD16 wrapper below */ 237/* Function is not endian safe, use the RD16 wrapper below */
238static int _read16(struct drx397xD_state *s, u32 i2c_adr) 238static int _read16(struct drx397xD_state *s, __le32 i2c_adr)
239{ 239{
240 int rc; 240 int rc;
241 u8 a[4]; 241 u8 a[4];
242 u16 v; 242 __le16 v;
243 struct i2c_msg msg[2] = { 243 struct i2c_msg msg[2] = {
244 { 244 {
245 .addr = s->config.demod_address, 245 .addr = s->config.demod_address,
246 .flags = 0, 246 .flags = 0,
247 .buf = a, 247 .buf = a,
248 .len = sizeof(a) 248 .len = sizeof(a)
249 } 249 }, {
250 , { 250 .addr = s->config.demod_address,
251 .addr = s->config.demod_address, 251 .flags = I2C_M_RD,
252 .flags = I2C_M_RD, 252 .buf = (u8 *)&v,
253 .buf = (u8 *) & v, 253 .len = sizeof(v)
254 .len = sizeof(v) 254 }
255 }
256 }; 255 };
257 256
258 *(u32 *) a = i2c_adr; 257 *(__le32 *) a = i2c_adr;
259 258
260 rc = i2c_transfer(s->i2c, msg, 2); 259 rc = i2c_transfer(s->i2c, msg, 2);
261 if (rc != 2) 260 if (rc != 2)
@@ -265,7 +264,7 @@ static int _read16(struct drx397xD_state *s, u32 i2c_adr)
265} 264}
266 265
267/* Function is not endian safe, use the WR16.. wrappers below */ 266/* Function is not endian safe, use the WR16.. wrappers below */
268static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val) 267static int _write16(struct drx397xD_state *s, __le32 i2c_adr, __le16 val)
269{ 268{
270 u8 a[6]; 269 u8 a[6];
271 int rc; 270 int rc;
@@ -276,28 +275,28 @@ static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val)
276 .len = sizeof(a) 275 .len = sizeof(a)
277 }; 276 };
278 277
279 *(u32 *) a = i2c_adr; 278 *(__le32 *)a = i2c_adr;
280 *(u16 *) & a[4] = val; 279 *(__le16 *)&a[4] = val;
281 280
282 rc = i2c_transfer(s->i2c, &msg, 1); 281 rc = i2c_transfer(s->i2c, &msg, 1);
283 if (rc != 1) 282 if (rc != 1)
284 return -EIO; 283 return -EIO;
284
285 return 0; 285 return 0;
286} 286}
287 287
288#define WR16(ss,adr, val) \ 288#define WR16(ss, adr, val) \
289 _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val)) 289 _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val))
290#define WR16_E0(ss,adr, val) \ 290#define WR16_E0(ss, adr, val) \
291 _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val)) 291 _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val))
292#define RD16(ss,adr) \ 292#define RD16(ss, adr) \
293 _read16(ss, I2C_ADR_C0(adr)) 293 _read16(ss, I2C_ADR_C0(adr))
294 294
295#define EXIT_RC( cmd ) if ( (rc = (cmd)) < 0) goto exit_rc 295#define EXIT_RC(cmd) \
296 296 if ((rc = (cmd)) < 0) \
297/******************************************************************************* 297 goto exit_rc
298 * Tuner callback
299 ******************************************************************************/
300 298
299/* Tuner callback */
301static int PLL_Set(struct drx397xD_state *s, 300static int PLL_Set(struct drx397xD_state *s,
302 struct dvb_frontend_parameters *fep, int *df_tuner) 301 struct dvb_frontend_parameters *fep, int *df_tuner)
303{ 302{
@@ -305,7 +304,7 @@ static int PLL_Set(struct drx397xD_state *s,
305 u32 f_tuner, f = fep->frequency; 304 u32 f_tuner, f = fep->frequency;
306 int rc; 305 int rc;
307 306
308 pr_debug("%s\n", __FUNCTION__); 307 pr_debug("%s\n", __func__);
309 308
310 if ((f > s->frontend.ops.tuner_ops.info.frequency_max) || 309 if ((f > s->frontend.ops.tuner_ops.info.frequency_max) ||
311 (f < s->frontend.ops.tuner_ops.info.frequency_min)) 310 (f < s->frontend.ops.tuner_ops.info.frequency_min))
@@ -325,28 +324,26 @@ static int PLL_Set(struct drx397xD_state *s,
325 return rc; 324 return rc;
326 325
327 *df_tuner = f_tuner - f; 326 *df_tuner = f_tuner - f;
328 pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __FUNCTION__, f, 327 pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __func__, f,
329 f_tuner); 328 f_tuner);
330 329
331 return 0; 330 return 0;
332} 331}
333 332
334/******************************************************************************* 333/* Demodulator helper functions */
335 * Demodulator helper functions
336 ******************************************************************************/
337
338static int SC_WaitForReady(struct drx397xD_state *s) 334static int SC_WaitForReady(struct drx397xD_state *s)
339{ 335{
340 int cnt = 1000; 336 int cnt = 1000;
341 int rc; 337 int rc;
342 338
343 pr_debug("%s\n", __FUNCTION__); 339 pr_debug("%s\n", __func__);
344 340
345 while (cnt--) { 341 while (cnt--) {
346 rc = RD16(s, 0x820043); 342 rc = RD16(s, 0x820043);
347 if (rc == 0) 343 if (rc == 0)
348 return 0; 344 return 0;
349 } 345 }
346
350 return -1; 347 return -1;
351} 348}
352 349
@@ -354,13 +351,14 @@ static int SC_SendCommand(struct drx397xD_state *s, int cmd)
354{ 351{
355 int rc; 352 int rc;
356 353
357 pr_debug("%s\n", __FUNCTION__); 354 pr_debug("%s\n", __func__);
358 355
359 WR16(s, 0x820043, cmd); 356 WR16(s, 0x820043, cmd);
360 SC_WaitForReady(s); 357 SC_WaitForReady(s);
361 rc = RD16(s, 0x820042); 358 rc = RD16(s, 0x820042);
362 if ((rc & 0xffff) == 0xffff) 359 if ((rc & 0xffff) == 0xffff)
363 return -1; 360 return -1;
361
364 return 0; 362 return 0;
365} 363}
366 364
@@ -368,7 +366,7 @@ static int HI_Command(struct drx397xD_state *s, u16 cmd)
368{ 366{
369 int rc, cnt = 1000; 367 int rc, cnt = 1000;
370 368
371 pr_debug("%s\n", __FUNCTION__); 369 pr_debug("%s\n", __func__);
372 370
373 rc = WR16(s, 0x420032, cmd); 371 rc = WR16(s, 0x420032, cmd);
374 if (rc < 0) 372 if (rc < 0)
@@ -383,22 +381,24 @@ static int HI_Command(struct drx397xD_state *s, u16 cmd)
383 if (rc < 0) 381 if (rc < 0)
384 return rc; 382 return rc;
385 } while (--cnt); 383 } while (--cnt);
384
386 return rc; 385 return rc;
387} 386}
388 387
389static int HI_CfgCommand(struct drx397xD_state *s) 388static int HI_CfgCommand(struct drx397xD_state *s)
390{ 389{
391 390
392 pr_debug("%s\n", __FUNCTION__); 391 pr_debug("%s\n", __func__);
393 392
394 WR16(s, 0x420033, 0x3973); 393 WR16(s, 0x420033, 0x3973);
395 WR16(s, 0x420034, s->config.w50); // code 4, log 4 394 WR16(s, 0x420034, s->config.w50); /* code 4, log 4 */
396 WR16(s, 0x420035, s->config.w52); // code 15, log 9 395 WR16(s, 0x420035, s->config.w52); /* code 15, log 9 */
397 WR16(s, 0x420036, s->config.demod_address << 1); 396 WR16(s, 0x420036, s->config.demod_address << 1);
398 WR16(s, 0x420037, s->config.w56); // code (set_i2c ?? initX 1 ), log 1 397 WR16(s, 0x420037, s->config.w56); /* code (set_i2c ?? initX 1 ), log 1 */
399// WR16(s, 0x420033, 0x3973); 398 /* WR16(s, 0x420033, 0x3973); */
400 if ((s->config.w56 & 8) == 0) 399 if ((s->config.w56 & 8) == 0)
401 return HI_Command(s, 3); 400 return HI_Command(s, 3);
401
402 return WR16(s, 0x420032, 0x3); 402 return WR16(s, 0x420032, 0x3);
403} 403}
404 404
@@ -419,7 +419,7 @@ static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc)
419 u16 w0C = agc->w0C; 419 u16 w0C = agc->w0C;
420 int quot, rem, i, rc = -EINVAL; 420 int quot, rem, i, rc = -EINVAL;
421 421
422 pr_debug("%s\n", __FUNCTION__); 422 pr_debug("%s\n", __func__);
423 423
424 if (agc->w04 > 0x3ff) 424 if (agc->w04 > 0x3ff)
425 goto exit_rc; 425 goto exit_rc;
@@ -468,7 +468,7 @@ static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc)
468 i = slowIncrDecLUT_15272[rem / 28]; 468 i = slowIncrDecLUT_15272[rem / 28];
469 EXIT_RC(WR16(s, 0x0c2002b, i)); 469 EXIT_RC(WR16(s, 0x0c2002b, i));
470 rc = WR16(s, 0x0c2002c, i); 470 rc = WR16(s, 0x0c2002c, i);
471 exit_rc: 471exit_rc:
472 return rc; 472 return rc;
473} 473}
474 474
@@ -478,7 +478,7 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
478 u16 w06 = agc->w06; 478 u16 w06 = agc->w06;
479 int rc = -1; 479 int rc = -1;
480 480
481 pr_debug("%s %d 0x%x 0x%x\n", __FUNCTION__, agc->d00, w04, w06); 481 pr_debug("%s %d 0x%x 0x%x\n", __func__, agc->d00, w04, w06);
482 482
483 if (w04 > 0x3ff) 483 if (w04 > 0x3ff)
484 goto exit_rc; 484 goto exit_rc;
@@ -498,7 +498,7 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
498 rc &= ~2; 498 rc &= ~2;
499 break; 499 break;
500 case 0: 500 case 0:
501 // loc_8000659 501 /* loc_8000659 */
502 s->config.w9C &= ~2; 502 s->config.w9C &= ~2;
503 EXIT_RC(WR16(s, 0x0c20015, s->config.w9C)); 503 EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
504 EXIT_RC(RD16(s, 0x0c20010)); 504 EXIT_RC(RD16(s, 0x0c20010));
@@ -522,7 +522,8 @@ static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
522 rc |= 2; 522 rc |= 2;
523 } 523 }
524 rc = WR16(s, 0x0c20013, rc); 524 rc = WR16(s, 0x0c20013, rc);
525 exit_rc: 525
526exit_rc:
526 return rc; 527 return rc;
527} 528}
528 529
@@ -554,7 +555,7 @@ static int CorrectSysClockDeviation(struct drx397xD_state *s)
554 int lockstat; 555 int lockstat;
555 u32 clk, clk_limit; 556 u32 clk, clk_limit;
556 557
557 pr_debug("%s\n", __FUNCTION__); 558 pr_debug("%s\n", __func__);
558 559
559 if (s->config.d5C == 0) { 560 if (s->config.d5C == 0) {
560 EXIT_RC(WR16(s, 0x08200e8, 0x010)); 561 EXIT_RC(WR16(s, 0x08200e8, 0x010));
@@ -598,11 +599,12 @@ static int CorrectSysClockDeviation(struct drx397xD_state *s)
598 599
599 if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) { 600 if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) {
600 s->f_osc = clk; 601 s->f_osc = clk;
601 pr_debug("%s: osc %d %d [Hz]\n", __FUNCTION__, 602 pr_debug("%s: osc %d %d [Hz]\n", __func__,
602 s->config.f_osc * 1000, clk - s->config.f_osc * 1000); 603 s->config.f_osc * 1000, clk - s->config.f_osc * 1000);
603 } 604 }
604 rc = WR16(s, 0x08200e8, 0); 605 rc = WR16(s, 0x08200e8, 0);
605 exit_rc: 606
607exit_rc:
606 return rc; 608 return rc;
607} 609}
608 610
@@ -610,7 +612,7 @@ static int ConfigureMPEGOutput(struct drx397xD_state *s, int type)
610{ 612{
611 int rc, si, bp; 613 int rc, si, bp;
612 614
613 pr_debug("%s\n", __FUNCTION__); 615 pr_debug("%s\n", __func__);
614 616
615 si = s->config.wA0; 617 si = s->config.wA0;
616 if (s->config.w98 == 0) { 618 if (s->config.w98 == 0) {
@@ -620,17 +622,17 @@ static int ConfigureMPEGOutput(struct drx397xD_state *s, int type)
620 si &= ~1; 622 si &= ~1;
621 bp = 0x200; 623 bp = 0x200;
622 } 624 }
623 if (s->config.w9A == 0) { 625 if (s->config.w9A == 0)
624 si |= 0x80; 626 si |= 0x80;
625 } else { 627 else
626 si &= ~0x80; 628 si &= ~0x80;
627 }
628 629
629 EXIT_RC(WR16(s, 0x2150045, 0)); 630 EXIT_RC(WR16(s, 0x2150045, 0));
630 EXIT_RC(WR16(s, 0x2150010, si)); 631 EXIT_RC(WR16(s, 0x2150010, si));
631 EXIT_RC(WR16(s, 0x2150011, bp)); 632 EXIT_RC(WR16(s, 0x2150011, bp));
632 rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0)); 633 rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0));
633 exit_rc: 634
635exit_rc:
634 return rc; 636 return rc;
635} 637}
636 638
@@ -646,7 +648,7 @@ static int drx_tune(struct drx397xD_state *s,
646 648
647 int rc, df_tuner; 649 int rc, df_tuner;
648 int a, b, c, d; 650 int a, b, c, d;
649 pr_debug("%s %d\n", __FUNCTION__, s->config.d60); 651 pr_debug("%s %d\n", __func__, s->config.d60);
650 652
651 if (s->config.d60 != 2) 653 if (s->config.d60 != 2)
652 goto set_tuner; 654 goto set_tuner;
@@ -658,7 +660,7 @@ static int drx_tune(struct drx397xD_state *s,
658 rc = ConfigureMPEGOutput(s, 0); 660 rc = ConfigureMPEGOutput(s, 0);
659 if (rc < 0) 661 if (rc < 0)
660 goto set_tuner; 662 goto set_tuner;
661 set_tuner: 663set_tuner:
662 664
663 rc = PLL_Set(s, fep, &df_tuner); 665 rc = PLL_Set(s, fep, &df_tuner);
664 if (rc < 0) { 666 if (rc < 0) {
@@ -835,16 +837,16 @@ static int drx_tune(struct drx397xD_state *s,
835 rc = WR16(s, 0x2010012, 0); 837 rc = WR16(s, 0x2010012, 0);
836 if (rc < 0) 838 if (rc < 0)
837 goto exit_rc; 839 goto exit_rc;
838 // QPSK QAM16 QAM64 840 /* QPSK QAM16 QAM64 */
839 ebx = 0x19f; // 62 841 ebx = 0x19f; /* 62 */
840 ebp = 0x1fb; // 15 842 ebp = 0x1fb; /* 15 */
841 v20 = 0x16a; // 62 843 v20 = 0x16a; /* 62 */
842 v1E = 0x195; // 62 844 v1E = 0x195; /* 62 */
843 v16 = 0x1bb; // 15 845 v16 = 0x1bb; /* 15 */
844 v14 = 0x1ef; // 15 846 v14 = 0x1ef; /* 15 */
845 v12 = 5; // 16 847 v12 = 5; /* 16 */
846 v10 = 5; // 16 848 v10 = 5; /* 16 */
847 v0E = 5; // 16 849 v0E = 5; /* 16 */
848 } 850 }
849 851
850 switch (fep->u.ofdm.constellation) { 852 switch (fep->u.ofdm.constellation) {
@@ -997,17 +999,17 @@ static int drx_tune(struct drx397xD_state *s,
997 case BANDWIDTH_8_MHZ: /* 0 */ 999 case BANDWIDTH_8_MHZ: /* 0 */
998 case BANDWIDTH_AUTO: 1000 case BANDWIDTH_AUTO:
999 rc = WR16(s, 0x0c2003f, 0x32); 1001 rc = WR16(s, 0x0c2003f, 0x32);
1000 s->bandwidth_parm = ebx = 0x8b8249; // 9142857 1002 s->bandwidth_parm = ebx = 0x8b8249;
1001 edx = 0; 1003 edx = 0;
1002 break; 1004 break;
1003 case BANDWIDTH_7_MHZ: 1005 case BANDWIDTH_7_MHZ:
1004 rc = WR16(s, 0x0c2003f, 0x3b); 1006 rc = WR16(s, 0x0c2003f, 0x3b);
1005 s->bandwidth_parm = ebx = 0x7a1200; // 8000000 1007 s->bandwidth_parm = ebx = 0x7a1200;
1006 edx = 0x4807; 1008 edx = 0x4807;
1007 break; 1009 break;
1008 case BANDWIDTH_6_MHZ: 1010 case BANDWIDTH_6_MHZ:
1009 rc = WR16(s, 0x0c2003f, 0x47); 1011 rc = WR16(s, 0x0c2003f, 0x47);
1010 s->bandwidth_parm = ebx = 0x68a1b6; // 6857142 1012 s->bandwidth_parm = ebx = 0x68a1b6;
1011 edx = 0x0f07; 1013 edx = 0x0f07;
1012 break; 1014 break;
1013 }; 1015 };
@@ -1060,8 +1062,6 @@ static int drx_tune(struct drx397xD_state *s,
1060 WR16(s, 0x0820040, 1); 1062 WR16(s, 0x0820040, 1);
1061 SC_SendCommand(s, 1); 1063 SC_SendCommand(s, 1);
1062 1064
1063// rc = WR16(s, 0x2150000, 1);
1064// if (rc < 0) goto exit_rc;
1065 1065
1066 rc = WR16(s, 0x2150000, 2); 1066 rc = WR16(s, 0x2150000, 2);
1067 rc = WR16(s, 0x2150016, a); 1067 rc = WR16(s, 0x2150016, a);
@@ -1069,7 +1069,8 @@ static int drx_tune(struct drx397xD_state *s,
1069 rc = WR16(s, 0x2150036, 0); 1069 rc = WR16(s, 0x2150036, 0);
1070 rc = WR16(s, 0x2150000, 1); 1070 rc = WR16(s, 0x2150000, 1);
1071 s->config.d60 = 2; 1071 s->config.d60 = 2;
1072 exit_rc: 1072
1073exit_rc:
1073 return rc; 1074 return rc;
1074} 1075}
1075 1076
@@ -1082,7 +1083,7 @@ static int drx397x_init(struct dvb_frontend *fe)
1082 struct drx397xD_state *s = fe->demodulator_priv; 1083 struct drx397xD_state *s = fe->demodulator_priv;
1083 int rc; 1084 int rc;
1084 1085
1085 pr_debug("%s\n", __FUNCTION__); 1086 pr_debug("%s\n", __func__);
1086 1087
1087 s->config.rfagc.d00 = 2; /* 0x7c */ 1088 s->config.rfagc.d00 = 2; /* 0x7c */
1088 s->config.rfagc.w04 = 0; 1089 s->config.rfagc.w04 = 0;
@@ -1102,18 +1103,18 @@ static int drx397x_init(struct dvb_frontend *fe)
1102 1103
1103 /* HI_CfgCommand */ 1104 /* HI_CfgCommand */
1104 s->config.w50 = 4; 1105 s->config.w50 = 4;
1105 s->config.w52 = 9; // 0xf; 1106 s->config.w52 = 9;
1106 1107
1107 s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */ 1108 s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */
1108 s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */ 1109 s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */
1109 s->config.w92 = 12000; // 20000; 1110 s->config.w92 = 12000;
1110 1111
1111 s->config.w9C = 0x000e; 1112 s->config.w9C = 0x000e;
1112 s->config.w9E = 0x0000; 1113 s->config.w9E = 0x0000;
1113 1114
1114 /* ConfigureMPEGOutput params */ 1115 /* ConfigureMPEGOutput params */
1115 s->config.wA0 = 4; 1116 s->config.wA0 = 4;
1116 s->config.w98 = 1; // 0; 1117 s->config.w98 = 1;
1117 s->config.w9A = 1; 1118 s->config.w9A = 1;
1118 1119
1119 /* get chip revision */ 1120 /* get chip revision */
@@ -1248,7 +1249,7 @@ static int drx397x_init(struct dvb_frontend *fe)
1248 rc = WR16(s, 0x0c20012, 1); 1249 rc = WR16(s, 0x0c20012, 1);
1249 } 1250 }
1250 1251
1251 write_DRXD_InitFE_1: 1252write_DRXD_InitFE_1:
1252 1253
1253 rc = write_fw(s, DRXD_InitFE_1); 1254 rc = write_fw(s, DRXD_InitFE_1);
1254 if (rc < 0) 1255 if (rc < 0)
@@ -1311,7 +1312,8 @@ static int drx397x_init(struct dvb_frontend *fe)
1311 s->config.d5C = 0; 1312 s->config.d5C = 0;
1312 s->config.d60 = 1; 1313 s->config.d60 = 1;
1313 s->config.d48 = 1; 1314 s->config.d48 = 1;
1314 error: 1315
1316error:
1315 return rc; 1317 return rc;
1316} 1318}
1317 1319
@@ -1326,7 +1328,8 @@ static int drx397x_set_frontend(struct dvb_frontend *fe,
1326{ 1328{
1327 struct drx397xD_state *s = fe->demodulator_priv; 1329 struct drx397xD_state *s = fe->demodulator_priv;
1328 1330
1329 s->config.s20d24 = 1; // 0; 1331 s->config.s20d24 = 1;
1332
1330 return drx_tune(s, params); 1333 return drx_tune(s, params);
1331} 1334}
1332 1335
@@ -1337,18 +1340,16 @@ static int drx397x_get_tune_settings(struct dvb_frontend *fe,
1337 fe_tune_settings->min_delay_ms = 10000; 1340 fe_tune_settings->min_delay_ms = 10000;
1338 fe_tune_settings->step_size = 0; 1341 fe_tune_settings->step_size = 0;
1339 fe_tune_settings->max_drift = 0; 1342 fe_tune_settings->max_drift = 0;
1343
1340 return 0; 1344 return 0;
1341} 1345}
1342 1346
1343static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status) 1347static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t *status)
1344{ 1348{
1345 struct drx397xD_state *s = fe->demodulator_priv; 1349 struct drx397xD_state *s = fe->demodulator_priv;
1346 int lockstat; 1350 int lockstat;
1347 1351
1348 GetLockStatus(s, &lockstat); 1352 GetLockStatus(s, &lockstat);
1349 /* TODO */
1350// if (lockstat & 1)
1351// CorrectSysClockDeviation(s);
1352 1353
1353 *status = 0; 1354 *status = 0;
1354 if (lockstat & 2) { 1355 if (lockstat & 2) {
@@ -1356,9 +1357,8 @@ static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status)
1356 ConfigureMPEGOutput(s, 1); 1357 ConfigureMPEGOutput(s, 1);
1357 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI; 1358 *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
1358 } 1359 }
1359 if (lockstat & 4) { 1360 if (lockstat & 4)
1360 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL; 1361 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
1361 }
1362 1362
1363 return 0; 1363 return 0;
1364} 1364}
@@ -1366,16 +1366,18 @@ static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status)
1366static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber) 1366static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber)
1367{ 1367{
1368 *ber = 0; 1368 *ber = 0;
1369
1369 return 0; 1370 return 0;
1370} 1371}
1371 1372
1372static int drx397x_read_snr(struct dvb_frontend *fe, u16 * snr) 1373static int drx397x_read_snr(struct dvb_frontend *fe, u16 *snr)
1373{ 1374{
1374 *snr = 0; 1375 *snr = 0;
1376
1375 return 0; 1377 return 0;
1376} 1378}
1377 1379
1378static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength) 1380static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1379{ 1381{
1380 struct drx397xD_state *s = fe->demodulator_priv; 1382 struct drx397xD_state *s = fe->demodulator_priv;
1381 int rc; 1383 int rc;
@@ -1401,6 +1403,7 @@ static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1401 * The following does the same but with less rounding errors: 1403 * The following does the same but with less rounding errors:
1402 */ 1404 */
1403 *strength = ~(7720 + (rc * 30744 >> 10)); 1405 *strength = ~(7720 + (rc * 30744 >> 10));
1406
1404 return 0; 1407 return 0;
1405} 1408}
1406 1409
@@ -1408,6 +1411,7 @@ static int drx397x_read_ucblocks(struct dvb_frontend *fe,
1408 unsigned int *ucblocks) 1411 unsigned int *ucblocks)
1409{ 1412{
1410 *ucblocks = 0; 1413 *ucblocks = 0;
1414
1411 return 0; 1415 return 0;
1412} 1416}
1413 1417
@@ -1436,22 +1440,22 @@ static struct dvb_frontend_ops drx397x_ops = {
1436 .frequency_max = 855250000, 1440 .frequency_max = 855250000,
1437 .frequency_stepsize = 166667, 1441 .frequency_stepsize = 166667,
1438 .frequency_tolerance = 0, 1442 .frequency_tolerance = 0,
1439 .caps = /* 0x0C01B2EAE */ 1443 .caps = /* 0x0C01B2EAE */
1440 FE_CAN_FEC_1_2 | // = 0x2, 1444 FE_CAN_FEC_1_2 | /* = 0x2, */
1441 FE_CAN_FEC_2_3 | // = 0x4, 1445 FE_CAN_FEC_2_3 | /* = 0x4, */
1442 FE_CAN_FEC_3_4 | // = 0x8, 1446 FE_CAN_FEC_3_4 | /* = 0x8, */
1443 FE_CAN_FEC_5_6 | // = 0x20, 1447 FE_CAN_FEC_5_6 | /* = 0x20, */
1444 FE_CAN_FEC_7_8 | // = 0x80, 1448 FE_CAN_FEC_7_8 | /* = 0x80, */
1445 FE_CAN_FEC_AUTO | // = 0x200, 1449 FE_CAN_FEC_AUTO | /* = 0x200, */
1446 FE_CAN_QPSK | // = 0x400, 1450 FE_CAN_QPSK | /* = 0x400, */
1447 FE_CAN_QAM_16 | // = 0x800, 1451 FE_CAN_QAM_16 | /* = 0x800, */
1448 FE_CAN_QAM_64 | // = 0x2000, 1452 FE_CAN_QAM_64 | /* = 0x2000, */
1449 FE_CAN_QAM_AUTO | // = 0x10000, 1453 FE_CAN_QAM_AUTO | /* = 0x10000, */
1450 FE_CAN_TRANSMISSION_MODE_AUTO | // = 0x20000, 1454 FE_CAN_TRANSMISSION_MODE_AUTO | /* = 0x20000, */
1451 FE_CAN_GUARD_INTERVAL_AUTO | // = 0x80000, 1455 FE_CAN_GUARD_INTERVAL_AUTO | /* = 0x80000, */
1452 FE_CAN_HIERARCHY_AUTO | // = 0x100000, 1456 FE_CAN_HIERARCHY_AUTO | /* = 0x100000, */
1453 FE_CAN_RECOVER | // = 0x40000000, 1457 FE_CAN_RECOVER | /* = 0x40000000, */
1454 FE_CAN_MUTE_TS // = 0x80000000 1458 FE_CAN_MUTE_TS /* = 0x80000000 */
1455 }, 1459 },
1456 1460
1457 .release = drx397x_release, 1461 .release = drx397x_release,
@@ -1472,33 +1476,35 @@ static struct dvb_frontend_ops drx397x_ops = {
1472struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config, 1476struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config,
1473 struct i2c_adapter *i2c) 1477 struct i2c_adapter *i2c)
1474{ 1478{
1475 struct drx397xD_state *s = NULL; 1479 struct drx397xD_state *state;
1476 1480
1477 /* allocate memory for the internal state */ 1481 /* allocate memory for the internal state */
1478 s = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL); 1482 state = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL);
1479 if (s == NULL) 1483 if (!state)
1480 goto error; 1484 goto error;
1481 1485
1482 /* setup the state */ 1486 /* setup the state */
1483 s->i2c = i2c; 1487 state->i2c = i2c;
1484 memcpy(&s->config, config, sizeof(struct drx397xD_config)); 1488 memcpy(&state->config, config, sizeof(struct drx397xD_config));
1485 1489
1486 /* check if the demod is there */ 1490 /* check if the demod is there */
1487 if (RD16(s, 0x2410019) < 0) 1491 if (RD16(state, 0x2410019) < 0)
1488 goto error; 1492 goto error;
1489 1493
1490 /* create dvb_frontend */ 1494 /* create dvb_frontend */
1491 memcpy(&s->frontend.ops, &drx397x_ops, sizeof(struct dvb_frontend_ops)); 1495 memcpy(&state->frontend.ops, &drx397x_ops,
1492 s->frontend.demodulator_priv = s; 1496 sizeof(struct dvb_frontend_ops));
1497 state->frontend.demodulator_priv = state;
1498
1499 return &state->frontend;
1500error:
1501 kfree(state);
1493 1502
1494 return &s->frontend;
1495 error:
1496 kfree(s);
1497 return NULL; 1503 return NULL;
1498} 1504}
1505EXPORT_SYMBOL(drx397xD_attach);
1499 1506
1500MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend"); 1507MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend");
1501MODULE_AUTHOR("Henk Vergonet"); 1508MODULE_AUTHOR("Henk Vergonet");
1502MODULE_LICENSE("GPL"); 1509MODULE_LICENSE("GPL");
1503 1510
1504EXPORT_SYMBOL(drx397xD_attach);
diff --git a/drivers/media/dvb/frontends/drx397xD.h b/drivers/media/dvb/frontends/drx397xD.h
index ddc7a07971b7..ba05d17290c6 100644
--- a/drivers/media/dvb/frontends/drx397xD.h
+++ b/drivers/media/dvb/frontends/drx397xD.h
@@ -28,7 +28,7 @@
28#define DRX_F_OFFSET 36000000 28#define DRX_F_OFFSET 36000000
29 29
30#define I2C_ADR_C0(x) \ 30#define I2C_ADR_C0(x) \
31( (u32)cpu_to_le32( \ 31( cpu_to_le32( \
32 (u32)( \ 32 (u32)( \
33 (((u32)(x) & (u32)0x000000ffUL) ) | \ 33 (((u32)(x) & (u32)0x000000ffUL) ) | \
34 (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ 34 (((u32)(x) & (u32)0x0000ff00UL) << 16) | \
@@ -38,7 +38,7 @@
38) 38)
39 39
40#define I2C_ADR_E0(x) \ 40#define I2C_ADR_E0(x) \
41( (u32)cpu_to_le32( \ 41( cpu_to_le32( \
42 (u32)( \ 42 (u32)( \
43 (((u32)(x) & (u32)0x000000ffUL) ) | \ 43 (((u32)(x) & (u32)0x000000ffUL) ) | \
44 (((u32)(x) & (u32)0x0000ff00UL) << 16) | \ 44 (((u32)(x) & (u32)0x0000ff00UL) << 16) | \
@@ -122,7 +122,7 @@ extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config
122static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config, 122static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
123 struct i2c_adapter *i2c) 123 struct i2c_adapter *i2c)
124{ 124{
125 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); 125 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
126 return NULL; 126 return NULL;
127} 127}
128#endif /* CONFIG_DVB_DRX397XD */ 128#endif /* CONFIG_DVB_DRX397XD */
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c
index fed09dfb2b7c..db8a937cc630 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.c
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c
@@ -75,9 +75,10 @@ static int dvb_dummy_fe_get_frontend(struct dvb_frontend* fe, struct dvb_fronten
75 75
76static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) 76static int dvb_dummy_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
77{ 77{
78 if (fe->ops->tuner_ops->set_params) { 78 if (fe->ops.tuner_ops.set_params) {
79 fe->ops->tuner_ops->set_params(fe, p); 79 fe->ops.tuner_ops.set_params(fe, p);
80 if (fe->ops->i2c_gate_ctrl) fe->ops->i2c_gate_ctrl(fe, 0); 80 if (fe->ops.i2c_gate_ctrl)
81 fe->ops.i2c_gate_ctrl(fe, 0);
81 } 82 }
82 83
83 return 0; 84 return 0;
@@ -131,7 +132,7 @@ error:
131 132
132static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops; 133static struct dvb_frontend_ops dvb_dummy_fe_qpsk_ops;
133 134
134struct dvb_frontend* dvb_dummy_fe_qpsk_attach() 135struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
135{ 136{
136 struct dvb_dummy_fe_state* state = NULL; 137 struct dvb_dummy_fe_state* state = NULL;
137 138
@@ -151,7 +152,7 @@ error:
151 152
152static struct dvb_frontend_ops dvb_dummy_fe_qam_ops; 153static struct dvb_frontend_ops dvb_dummy_fe_qam_ops;
153 154
154struct dvb_frontend* dvb_dummy_fe_qam_attach() 155struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
155{ 156{
156 struct dvb_dummy_fe_state* state = NULL; 157 struct dvb_dummy_fe_state* state = NULL;
157 158
diff --git a/drivers/media/dvb/frontends/eds1547.h b/drivers/media/dvb/frontends/eds1547.h
new file mode 100644
index 000000000000..fa79b7c83dd2
--- /dev/null
+++ b/drivers/media/dvb/frontends/eds1547.h
@@ -0,0 +1,133 @@
1/* eds1547.h Earda EDS-1547 tuner support
2*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
4*
5* This program is free software; you can redistribute it and/or modify it
6* under the terms of the GNU General Public License as published by the
7* Free Software Foundation, version 2.
8*
9* see Documentation/dvb/README.dvb-usb for more information
10*/
11
12#ifndef EDS1547
13#define EDS1547
14
15static u8 stv0288_earda_inittab[] = {
16 0x01, 0x57,
17 0x02, 0x20,
18 0x03, 0x8e,
19 0x04, 0x8e,
20 0x05, 0x12,
21 0x06, 0x00,
22 0x07, 0x00,
23 0x09, 0x00,
24 0x0a, 0x04,
25 0x0b, 0x00,
26 0x0c, 0x00,
27 0x0d, 0x00,
28 0x0e, 0xd4,
29 0x0f, 0x30,
30 0x11, 0x44,
31 0x12, 0x03,
32 0x13, 0x48,
33 0x14, 0x84,
34 0x15, 0x45,
35 0x16, 0xb7,
36 0x17, 0x9c,
37 0x18, 0x00,
38 0x19, 0xa6,
39 0x1a, 0x88,
40 0x1b, 0x8f,
41 0x1c, 0xf0,
42 0x20, 0x0b,
43 0x21, 0x54,
44 0x22, 0x00,
45 0x23, 0x00,
46 0x2b, 0xff,
47 0x2c, 0xf7,
48 0x30, 0x00,
49 0x31, 0x1e,
50 0x32, 0x14,
51 0x33, 0x0f,
52 0x34, 0x09,
53 0x35, 0x0c,
54 0x36, 0x05,
55 0x37, 0x2f,
56 0x38, 0x16,
57 0x39, 0xbd,
58 0x3a, 0x00,
59 0x3b, 0x13,
60 0x3c, 0x11,
61 0x3d, 0x30,
62 0x40, 0x63,
63 0x41, 0x04,
64 0x42, 0x60,
65 0x43, 0x00,
66 0x44, 0x00,
67 0x45, 0x00,
68 0x46, 0x00,
69 0x47, 0x00,
70 0x4a, 0x00,
71 0x50, 0x10,
72 0x51, 0x36,
73 0x52, 0x09,
74 0x53, 0x94,
75 0x54, 0x62,
76 0x55, 0x29,
77 0x56, 0x64,
78 0x57, 0x2b,
79 0x58, 0x54,
80 0x59, 0x86,
81 0x5a, 0x00,
82 0x5b, 0x9b,
83 0x5c, 0x08,
84 0x5d, 0x7f,
85 0x5e, 0x00,
86 0x5f, 0xff,
87 0x70, 0x00,
88 0x71, 0x00,
89 0x72, 0x00,
90 0x74, 0x00,
91 0x75, 0x00,
92 0x76, 0x00,
93 0x81, 0x00,
94 0x82, 0x3f,
95 0x83, 0x3f,
96 0x84, 0x00,
97 0x85, 0x00,
98 0x88, 0x00,
99 0x89, 0x00,
100 0x8a, 0x00,
101 0x8b, 0x00,
102 0x8c, 0x00,
103 0x90, 0x00,
104 0x91, 0x00,
105 0x92, 0x00,
106 0x93, 0x00,
107 0x94, 0x1c,
108 0x97, 0x00,
109 0xa0, 0x48,
110 0xa1, 0x00,
111 0xb0, 0xb8,
112 0xb1, 0x3a,
113 0xb2, 0x10,
114 0xb3, 0x82,
115 0xb4, 0x80,
116 0xb5, 0x82,
117 0xb6, 0x82,
118 0xb7, 0x82,
119 0xb8, 0x20,
120 0xb9, 0x00,
121 0xf0, 0x00,
122 0xf1, 0x00,
123 0xf2, 0xc0,
124 0xff,0xff,
125};
126
127static struct stv0288_config earda_config = {
128 .demod_address = 0x68,
129 .min_delay_ms = 100,
130 .inittab = stv0288_earda_inittab,
131};
132
133#endif
diff --git a/drivers/media/dvb/frontends/lgs8gl5.c b/drivers/media/dvb/frontends/lgs8gl5.c
new file mode 100644
index 000000000000..855852fddf22
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gl5.c
@@ -0,0 +1,454 @@
1/*
2 Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver
3
4 Copyright (C) 2008 Sirius International (Hong Kong) Limited
5 Timothy Lee <timothy.lee@siriushk.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/string.h>
27#include <linux/slab.h>
28#include "dvb_frontend.h"
29#include "lgs8gl5.h"
30
31
32#define REG_RESET 0x02
33#define REG_RESET_OFF 0x01
34#define REG_03 0x03
35#define REG_04 0x04
36#define REG_07 0x07
37#define REG_09 0x09
38#define REG_0A 0x0a
39#define REG_0B 0x0b
40#define REG_0C 0x0c
41#define REG_37 0x37
42#define REG_STRENGTH 0x4b
43#define REG_STRENGTH_MASK 0x7f
44#define REG_STRENGTH_CARRIER 0x80
45#define REG_INVERSION 0x7c
46#define REG_INVERSION_ON 0x80
47#define REG_7D 0x7d
48#define REG_7E 0x7e
49#define REG_A2 0xa2
50#define REG_STATUS 0xa4
51#define REG_STATUS_SYNC 0x04
52#define REG_STATUS_LOCK 0x01
53
54
55struct lgs8gl5_state {
56 struct i2c_adapter *i2c;
57 const struct lgs8gl5_config *config;
58 struct dvb_frontend frontend;
59};
60
61
62static int debug;
63#define dprintk(args...) \
64 do { \
65 if (debug) \
66 printk(KERN_DEBUG "lgs8gl5: " args); \
67 } while (0)
68
69
70/* Writes into demod's register */
71static int
72lgs8gl5_write_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
73{
74 int ret;
75 u8 buf[] = {reg, data};
76 struct i2c_msg msg = {
77 .addr = state->config->demod_address,
78 .flags = 0,
79 .buf = buf,
80 .len = 2
81 };
82
83 ret = i2c_transfer(state->i2c, &msg, 1);
84 if (ret != 1)
85 dprintk("%s: error (reg=0x%02x, val=0x%02x, ret=%i)\n",
86 __func__, reg, data, ret);
87 return (ret != 1) ? -1 : 0;
88}
89
90
91/* Reads from demod's register */
92static int
93lgs8gl5_read_reg(struct lgs8gl5_state *state, u8 reg)
94{
95 int ret;
96 u8 b0[] = {reg};
97 u8 b1[] = {0};
98 struct i2c_msg msg[2] = {
99 {
100 .addr = state->config->demod_address,
101 .flags = 0,
102 .buf = b0,
103 .len = 1
104 },
105 {
106 .addr = state->config->demod_address,
107 .flags = I2C_M_RD,
108 .buf = b1,
109 .len = 1
110 }
111 };
112
113 ret = i2c_transfer(state->i2c, msg, 2);
114 if (ret != 2)
115 return -EIO;
116
117 return b1[0];
118}
119
120
121static int
122lgs8gl5_update_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
123{
124 lgs8gl5_read_reg(state, reg);
125 lgs8gl5_write_reg(state, reg, data);
126 return 0;
127}
128
129
130/* Writes into alternate device's register */
131/* TODO: Find out what that device is for! */
132static int
133lgs8gl5_update_alt_reg(struct lgs8gl5_state *state, u8 reg, u8 data)
134{
135 int ret;
136 u8 b0[] = {reg};
137 u8 b1[] = {0};
138 u8 b2[] = {reg, data};
139 struct i2c_msg msg[3] = {
140 {
141 .addr = state->config->demod_address + 2,
142 .flags = 0,
143 .buf = b0,
144 .len = 1
145 },
146 {
147 .addr = state->config->demod_address + 2,
148 .flags = I2C_M_RD,
149 .buf = b1,
150 .len = 1
151 },
152 {
153 .addr = state->config->demod_address + 2,
154 .flags = 0,
155 .buf = b2,
156 .len = 2
157 },
158 };
159
160 ret = i2c_transfer(state->i2c, msg, 3);
161 return (ret != 3) ? -1 : 0;
162}
163
164
165static void
166lgs8gl5_soft_reset(struct lgs8gl5_state *state)
167{
168 u8 val;
169
170 dprintk("%s\n", __func__);
171
172 val = lgs8gl5_read_reg(state, REG_RESET);
173 lgs8gl5_write_reg(state, REG_RESET, val & ~REG_RESET_OFF);
174 lgs8gl5_write_reg(state, REG_RESET, val | REG_RESET_OFF);
175 msleep(5);
176}
177
178
179/* Starts demodulation */
180static void
181lgs8gl5_start_demod(struct lgs8gl5_state *state)
182{
183 u8 val;
184 int n;
185
186 dprintk("%s\n", __func__);
187
188 lgs8gl5_update_alt_reg(state, 0xc2, 0x28);
189 lgs8gl5_soft_reset(state);
190 lgs8gl5_update_reg(state, REG_07, 0x10);
191 lgs8gl5_update_reg(state, REG_07, 0x10);
192 lgs8gl5_write_reg(state, REG_09, 0x0e);
193 lgs8gl5_write_reg(state, REG_0A, 0xe5);
194 lgs8gl5_write_reg(state, REG_0B, 0x35);
195 lgs8gl5_write_reg(state, REG_0C, 0x30);
196
197 lgs8gl5_update_reg(state, REG_03, 0x00);
198 lgs8gl5_update_reg(state, REG_7E, 0x01);
199 lgs8gl5_update_alt_reg(state, 0xc5, 0x00);
200 lgs8gl5_update_reg(state, REG_04, 0x02);
201 lgs8gl5_update_reg(state, REG_37, 0x01);
202 lgs8gl5_soft_reset(state);
203
204 /* Wait for carrier */
205 for (n = 0; n < 10; n++) {
206 val = lgs8gl5_read_reg(state, REG_STRENGTH);
207 dprintk("Wait for carrier[%d] 0x%02X\n", n, val);
208 if (val & REG_STRENGTH_CARRIER)
209 break;
210 msleep(4);
211 }
212 if (!(val & REG_STRENGTH_CARRIER))
213 return;
214
215 /* Wait for lock */
216 for (n = 0; n < 20; n++) {
217 val = lgs8gl5_read_reg(state, REG_STATUS);
218 dprintk("Wait for lock[%d] 0x%02X\n", n, val);
219 if (val & REG_STATUS_LOCK)
220 break;
221 msleep(12);
222 }
223 if (!(val & REG_STATUS_LOCK))
224 return;
225
226 lgs8gl5_write_reg(state, REG_7D, lgs8gl5_read_reg(state, REG_A2));
227 lgs8gl5_soft_reset(state);
228}
229
230
231static int
232lgs8gl5_init(struct dvb_frontend *fe)
233{
234 struct lgs8gl5_state *state = fe->demodulator_priv;
235
236 dprintk("%s\n", __func__);
237
238 lgs8gl5_update_alt_reg(state, 0xc2, 0x28);
239 lgs8gl5_soft_reset(state);
240 lgs8gl5_update_reg(state, REG_07, 0x10);
241 lgs8gl5_update_reg(state, REG_07, 0x10);
242 lgs8gl5_write_reg(state, REG_09, 0x0e);
243 lgs8gl5_write_reg(state, REG_0A, 0xe5);
244 lgs8gl5_write_reg(state, REG_0B, 0x35);
245 lgs8gl5_write_reg(state, REG_0C, 0x30);
246
247 return 0;
248}
249
250
251static int
252lgs8gl5_read_status(struct dvb_frontend *fe, fe_status_t *status)
253{
254 struct lgs8gl5_state *state = fe->demodulator_priv;
255 u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
256 u8 flags = lgs8gl5_read_reg(state, REG_STATUS);
257
258 *status = 0;
259
260 if ((level & REG_STRENGTH_MASK) > 0)
261 *status |= FE_HAS_SIGNAL;
262 if (level & REG_STRENGTH_CARRIER)
263 *status |= FE_HAS_CARRIER;
264 if (flags & REG_STATUS_SYNC)
265 *status |= FE_HAS_SYNC;
266 if (flags & REG_STATUS_LOCK)
267 *status |= FE_HAS_LOCK;
268
269 return 0;
270}
271
272
273static int
274lgs8gl5_read_ber(struct dvb_frontend *fe, u32 *ber)
275{
276 *ber = 0;
277
278 return 0;
279}
280
281
282static int
283lgs8gl5_read_signal_strength(struct dvb_frontend *fe, u16 *signal_strength)
284{
285 struct lgs8gl5_state *state = fe->demodulator_priv;
286 u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
287 *signal_strength = (level & REG_STRENGTH_MASK) << 8;
288
289 return 0;
290}
291
292
293static int
294lgs8gl5_read_snr(struct dvb_frontend *fe, u16 *snr)
295{
296 struct lgs8gl5_state *state = fe->demodulator_priv;
297 u8 level = lgs8gl5_read_reg(state, REG_STRENGTH);
298 *snr = (level & REG_STRENGTH_MASK) << 8;
299
300 return 0;
301}
302
303
304static int
305lgs8gl5_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
306{
307 *ucblocks = 0;
308
309 return 0;
310}
311
312
313static int
314lgs8gl5_set_frontend(struct dvb_frontend *fe,
315 struct dvb_frontend_parameters *p)
316{
317 struct lgs8gl5_state *state = fe->demodulator_priv;
318
319 dprintk("%s\n", __func__);
320
321 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ)
322 return -EINVAL;
323
324 if (fe->ops.tuner_ops.set_params) {
325 fe->ops.tuner_ops.set_params(fe, p);
326 if (fe->ops.i2c_gate_ctrl)
327 fe->ops.i2c_gate_ctrl(fe, 0);
328 }
329
330 /* lgs8gl5_set_inversion(state, p->inversion); */
331
332 lgs8gl5_start_demod(state);
333
334 return 0;
335}
336
337
338static int
339lgs8gl5_get_frontend(struct dvb_frontend *fe,
340 struct dvb_frontend_parameters *p)
341{
342 struct lgs8gl5_state *state = fe->demodulator_priv;
343 u8 inv = lgs8gl5_read_reg(state, REG_INVERSION);
344 struct dvb_ofdm_parameters *o = &p->u.ofdm;
345
346 p->inversion = (inv & REG_INVERSION_ON) ? INVERSION_ON : INVERSION_OFF;
347
348 o->code_rate_HP = FEC_1_2;
349 o->code_rate_LP = FEC_7_8;
350 o->guard_interval = GUARD_INTERVAL_1_32;
351 o->transmission_mode = TRANSMISSION_MODE_2K;
352 o->constellation = QAM_64;
353 o->hierarchy_information = HIERARCHY_NONE;
354 o->bandwidth = BANDWIDTH_8_MHZ;
355
356 return 0;
357}
358
359
360static int
361lgs8gl5_get_tune_settings(struct dvb_frontend *fe,
362 struct dvb_frontend_tune_settings *fesettings)
363{
364 fesettings->min_delay_ms = 240;
365 fesettings->step_size = 0;
366 fesettings->max_drift = 0;
367 return 0;
368}
369
370
371static void
372lgs8gl5_release(struct dvb_frontend *fe)
373{
374 struct lgs8gl5_state *state = fe->demodulator_priv;
375 kfree(state);
376}
377
378
379static struct dvb_frontend_ops lgs8gl5_ops;
380
381
382struct dvb_frontend*
383lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c)
384{
385 struct lgs8gl5_state *state = NULL;
386
387 dprintk("%s\n", __func__);
388
389 /* Allocate memory for the internal state */
390 state = kmalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL);
391 if (state == NULL)
392 goto error;
393
394 /* Setup the state */
395 state->config = config;
396 state->i2c = i2c;
397
398 /* Check if the demod is there */
399 if (lgs8gl5_read_reg(state, REG_RESET) < 0)
400 goto error;
401
402 /* Create dvb_frontend */
403 memcpy(&state->frontend.ops, &lgs8gl5_ops,
404 sizeof(struct dvb_frontend_ops));
405 state->frontend.demodulator_priv = state;
406 return &state->frontend;
407
408error:
409 kfree(state);
410 return NULL;
411}
412EXPORT_SYMBOL(lgs8gl5_attach);
413
414
415static struct dvb_frontend_ops lgs8gl5_ops = {
416 .info = {
417 .name = "Legend Silicon LGS-8GL5 DMB-TH",
418 .type = FE_OFDM,
419 .frequency_min = 474000000,
420 .frequency_max = 858000000,
421 .frequency_stepsize = 10000,
422 .frequency_tolerance = 0,
423 .caps = FE_CAN_FEC_AUTO |
424 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_32 |
425 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
426 FE_CAN_TRANSMISSION_MODE_AUTO |
427 FE_CAN_BANDWIDTH_AUTO |
428 FE_CAN_GUARD_INTERVAL_AUTO |
429 FE_CAN_HIERARCHY_AUTO |
430 FE_CAN_RECOVER
431 },
432
433 .release = lgs8gl5_release,
434
435 .init = lgs8gl5_init,
436
437 .set_frontend = lgs8gl5_set_frontend,
438 .get_frontend = lgs8gl5_get_frontend,
439 .get_tune_settings = lgs8gl5_get_tune_settings,
440
441 .read_status = lgs8gl5_read_status,
442 .read_ber = lgs8gl5_read_ber,
443 .read_signal_strength = lgs8gl5_read_signal_strength,
444 .read_snr = lgs8gl5_read_snr,
445 .read_ucblocks = lgs8gl5_read_ucblocks,
446};
447
448
449module_param(debug, int, 0644);
450MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
451
452MODULE_DESCRIPTION("Legend Silicon LGS-8GL5 DMB-TH Demodulator driver");
453MODULE_AUTHOR("Timothy Lee");
454MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lgs8gl5.h b/drivers/media/dvb/frontends/lgs8gl5.h
new file mode 100644
index 000000000000..d14176787a7d
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgs8gl5.h
@@ -0,0 +1,45 @@
1/*
2 Legend Silicon LGS-8GL5 DMB-TH OFDM demodulator driver
3
4 Copyright (C) 2008 Sirius International (Hong Kong) Limited
5 Timothy Lee <timothy.lee@siriushk.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef LGS8GL5_H
24#define LGS8GL5_H
25
26#include <linux/dvb/frontend.h>
27
28struct lgs8gl5_config {
29 /* the demodulator's i2c address */
30 u8 demod_address;
31};
32
33#if defined(CONFIG_DVB_LGS8GL5) || \
34 (defined(CONFIG_DVB_LGS8GL5_MODULE) && defined(MODULE))
35extern struct dvb_frontend *lgs8gl5_attach(
36 const struct lgs8gl5_config *config, struct i2c_adapter *i2c);
37#else
38static inline struct dvb_frontend *lgs8gl5_attach(
39 const struct lgs8gl5_config *config, struct i2c_adapter *i2c) {
40 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
41 return NULL;
42}
43#endif /* CONFIG_DVB_LGS8GL5 */
44
45#endif /* LGS8GL5_H */
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c
index af298358e822..a8429ebfa8a2 100644
--- a/drivers/media/dvb/frontends/nxt200x.c
+++ b/drivers/media/dvb/frontends/nxt200x.c
@@ -80,7 +80,7 @@ static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len
80 return 0; 80 return 0;
81} 81}
82 82
83static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len) 83static int i2c_readbytes(struct nxt200x_state *state, u8 addr, u8 *buf, u8 len)
84{ 84{
85 int err; 85 int err;
86 struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len }; 86 struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
@@ -111,7 +111,7 @@ static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg,
111 return 0; 111 return 0;
112} 112}
113 113
114static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len) 114static int nxt200x_readbytes(struct nxt200x_state *state, u8 reg, u8 *buf, u8 len)
115{ 115{
116 u8 reg2 [] = { reg }; 116 u8 reg2 [] = { reg };
117 117
diff --git a/drivers/media/dvb/frontends/or51211.c b/drivers/media/dvb/frontends/or51211.c
index 6afe12aaca4e..16cf2fdd5d7d 100644
--- a/drivers/media/dvb/frontends/or51211.c
+++ b/drivers/media/dvb/frontends/or51211.c
@@ -88,7 +88,7 @@ static int i2c_writebytes (struct or51211_state* state, u8 reg, const u8 *buf,
88 return 0; 88 return 0;
89} 89}
90 90
91static u8 i2c_readbytes (struct or51211_state* state, u8 reg, u8* buf, int len) 91static int i2c_readbytes(struct or51211_state *state, u8 reg, u8 *buf, int len)
92{ 92{
93 int err; 93 int err;
94 struct i2c_msg msg; 94 struct i2c_msg msg;
diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c
index 747d3fa2e5e5..2e9fd2893ede 100644
--- a/drivers/media/dvb/frontends/s5h1420.c
+++ b/drivers/media/dvb/frontends/s5h1420.c
@@ -59,7 +59,7 @@ struct s5h1420_state {
59 * it does not support repeated-start, workaround: write addr-1 59 * it does not support repeated-start, workaround: write addr-1
60 * and then read 60 * and then read
61 */ 61 */
62 u8 shadow[255]; 62 u8 shadow[256];
63}; 63};
64 64
65static u32 s5h1420_getsymbolrate(struct s5h1420_state* state); 65static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
@@ -94,8 +94,11 @@ static u8 s5h1420_readreg(struct s5h1420_state *state, u8 reg)
94 if (ret != 3) 94 if (ret != 3)
95 return ret; 95 return ret;
96 } else { 96 } else {
97 ret = i2c_transfer(state->i2c, &msg[1], 2); 97 ret = i2c_transfer(state->i2c, &msg[1], 1);
98 if (ret != 2) 98 if (ret != 1)
99 return ret;
100 ret = i2c_transfer(state->i2c, &msg[2], 1);
101 if (ret != 1)
99 return ret; 102 return ret;
100 } 103 }
101 104
@@ -823,7 +826,7 @@ static int s5h1420_init (struct dvb_frontend* fe)
823 struct s5h1420_state* state = fe->demodulator_priv; 826 struct s5h1420_state* state = fe->demodulator_priv;
824 827
825 /* disable power down and do reset */ 828 /* disable power down and do reset */
826 state->CON_1_val = 0x10; 829 state->CON_1_val = state->config->serial_mpeg << 4;
827 s5h1420_writereg(state, 0x02, state->CON_1_val); 830 s5h1420_writereg(state, 0x02, state->CON_1_val);
828 msleep(10); 831 msleep(10);
829 s5h1420_reset(state); 832 s5h1420_reset(state);
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
index 4c913f142bc4..ff308136d865 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -32,10 +32,12 @@ struct s5h1420_config
32 u8 demod_address; 32 u8 demod_address;
33 33
34 /* does the inversion require inversion? */ 34 /* does the inversion require inversion? */
35 u8 invert : 1; 35 u8 invert:1;
36 36
37 u8 repeated_start_workaround : 1; 37 u8 repeated_start_workaround:1;
38 u8 cdclk_polarity : 1; /* 1 == falling edge, 0 == raising edge */ 38 u8 cdclk_polarity:1; /* 1 == falling edge, 0 == raising edge */
39
40 u8 serial_mpeg:1;
39}; 41};
40 42
41#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE)) 43#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE))
diff --git a/drivers/media/dvb/frontends/si21xx.c b/drivers/media/dvb/frontends/si21xx.c
new file mode 100644
index 000000000000..3ddbe69c45ce
--- /dev/null
+++ b/drivers/media/dvb/frontends/si21xx.c
@@ -0,0 +1,974 @@
1/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
2*
3* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
4*
5* This program is free software; you can redistribute it and/or modify
6* it under the terms of the GNU General Public License as published by
7* the Free Software Foundation; either version 2 of the License, or
8* (at your option) any later version.
9*
10*/
11#include <linux/version.h>
12#include <linux/init.h>
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/string.h>
16#include <linux/slab.h>
17#include <linux/jiffies.h>
18#include <asm/div64.h>
19
20#include "dvb_frontend.h"
21#include "si21xx.h"
22
23#define REVISION_REG 0x00
24#define SYSTEM_MODE_REG 0x01
25#define TS_CTRL_REG_1 0x02
26#define TS_CTRL_REG_2 0x03
27#define PIN_CTRL_REG_1 0x04
28#define PIN_CTRL_REG_2 0x05
29#define LOCK_STATUS_REG_1 0x0f
30#define LOCK_STATUS_REG_2 0x10
31#define ACQ_STATUS_REG 0x11
32#define ACQ_CTRL_REG_1 0x13
33#define ACQ_CTRL_REG_2 0x14
34#define PLL_DIVISOR_REG 0x15
35#define COARSE_TUNE_REG 0x16
36#define FINE_TUNE_REG_L 0x17
37#define FINE_TUNE_REG_H 0x18
38
39#define ANALOG_AGC_POWER_LEVEL_REG 0x28
40#define CFO_ESTIMATOR_CTRL_REG_1 0x29
41#define CFO_ESTIMATOR_CTRL_REG_2 0x2a
42#define CFO_ESTIMATOR_CTRL_REG_3 0x2b
43
44#define SYM_RATE_ESTIMATE_REG_L 0x31
45#define SYM_RATE_ESTIMATE_REG_M 0x32
46#define SYM_RATE_ESTIMATE_REG_H 0x33
47
48#define CFO_ESTIMATOR_OFFSET_REG_L 0x36
49#define CFO_ESTIMATOR_OFFSET_REG_H 0x37
50#define CFO_ERROR_REG_L 0x38
51#define CFO_ERROR_REG_H 0x39
52#define SYM_RATE_ESTIMATOR_CTRL_REG 0x3a
53
54#define SYM_RATE_REG_L 0x3f
55#define SYM_RATE_REG_M 0x40
56#define SYM_RATE_REG_H 0x41
57#define SYM_RATE_ESTIMATOR_MAXIMUM_REG 0x42
58#define SYM_RATE_ESTIMATOR_MINIMUM_REG 0x43
59
60#define C_N_ESTIMATOR_CTRL_REG 0x7c
61#define C_N_ESTIMATOR_THRSHLD_REG 0x7d
62#define C_N_ESTIMATOR_LEVEL_REG_L 0x7e
63#define C_N_ESTIMATOR_LEVEL_REG_H 0x7f
64
65#define BLIND_SCAN_CTRL_REG 0x80
66
67#define LSA_CTRL_REG_1 0x8D
68#define SPCTRM_TILT_CORR_THRSHLD_REG 0x8f
69#define ONE_DB_BNDWDTH_THRSHLD_REG 0x90
70#define TWO_DB_BNDWDTH_THRSHLD_REG 0x91
71#define THREE_DB_BNDWDTH_THRSHLD_REG 0x92
72#define INBAND_POWER_THRSHLD_REG 0x93
73#define REF_NOISE_LVL_MRGN_THRSHLD_REG 0x94
74
75#define VIT_SRCH_CTRL_REG_1 0xa0
76#define VIT_SRCH_CTRL_REG_2 0xa1
77#define VIT_SRCH_CTRL_REG_3 0xa2
78#define VIT_SRCH_STATUS_REG 0xa3
79#define VITERBI_BER_COUNT_REG_L 0xab
80#define REED_SOLOMON_CTRL_REG 0xb0
81#define REED_SOLOMON_ERROR_COUNT_REG_L 0xb1
82#define PRBS_CTRL_REG 0xb5
83
84#define LNB_CTRL_REG_1 0xc0
85#define LNB_CTRL_REG_2 0xc1
86#define LNB_CTRL_REG_3 0xc2
87#define LNB_CTRL_REG_4 0xc3
88#define LNB_CTRL_STATUS_REG 0xc4
89#define LNB_FIFO_REGS_0 0xc5
90#define LNB_FIFO_REGS_1 0xc6
91#define LNB_FIFO_REGS_2 0xc7
92#define LNB_FIFO_REGS_3 0xc8
93#define LNB_FIFO_REGS_4 0xc9
94#define LNB_FIFO_REGS_5 0xca
95#define LNB_SUPPLY_CTRL_REG_1 0xcb
96#define LNB_SUPPLY_CTRL_REG_2 0xcc
97#define LNB_SUPPLY_CTRL_REG_3 0xcd
98#define LNB_SUPPLY_CTRL_REG_4 0xce
99#define LNB_SUPPLY_STATUS_REG 0xcf
100
101#define FALSE 0
102#define TRUE 1
103#define FAIL -1
104#define PASS 0
105
106#define ALLOWABLE_FS_COUNT 10
107#define STATUS_BER 0
108#define STATUS_UCBLOCKS 1
109
110static int debug;
111#define dprintk(args...) \
112 do { \
113 if (debug) \
114 printk(KERN_DEBUG "si21xx: " args); \
115 } while (0)
116
117enum {
118 ACTIVE_HIGH,
119 ACTIVE_LOW
120};
121enum {
122 BYTE_WIDE,
123 BIT_WIDE
124};
125enum {
126 CLK_GAPPED_MODE,
127 CLK_CONTINUOUS_MODE
128};
129enum {
130 RISING_EDGE,
131 FALLING_EDGE
132};
133enum {
134 MSB_FIRST,
135 LSB_FIRST
136};
137enum {
138 SERIAL,
139 PARALLEL
140};
141
142struct si21xx_state {
143 struct i2c_adapter *i2c;
144 const struct si21xx_config *config;
145 struct dvb_frontend frontend;
146 u8 initialised:1;
147 int errmode;
148 int fs; /*Sampling rate of the ADC in MHz*/
149};
150
151/* register default initialization */
152static u8 serit_sp1511lhb_inittab[] = {
153 0x01, 0x28, /* set i2c_inc_disable */
154 0x20, 0x03,
155 0x27, 0x20,
156 0xe0, 0x45,
157 0xe1, 0x08,
158 0xfe, 0x01,
159 0x01, 0x28,
160 0x89, 0x09,
161 0x04, 0x80,
162 0x05, 0x01,
163 0x06, 0x00,
164 0x20, 0x03,
165 0x24, 0x88,
166 0x29, 0x09,
167 0x2a, 0x0f,
168 0x2c, 0x10,
169 0x2d, 0x19,
170 0x2e, 0x08,
171 0x2f, 0x10,
172 0x30, 0x19,
173 0x34, 0x20,
174 0x35, 0x03,
175 0x45, 0x02,
176 0x46, 0x45,
177 0x47, 0xd0,
178 0x48, 0x00,
179 0x49, 0x40,
180 0x4a, 0x03,
181 0x4c, 0xfd,
182 0x4f, 0x2e,
183 0x50, 0x2e,
184 0x51, 0x10,
185 0x52, 0x10,
186 0x56, 0x92,
187 0x59, 0x00,
188 0x5a, 0x2d,
189 0x5b, 0x33,
190 0x5c, 0x1f,
191 0x5f, 0x76,
192 0x62, 0xc0,
193 0x63, 0xc0,
194 0x64, 0xf3,
195 0x65, 0xf3,
196 0x79, 0x40,
197 0x6a, 0x40,
198 0x6b, 0x0a,
199 0x6c, 0x80,
200 0x6d, 0x27,
201 0x71, 0x06,
202 0x75, 0x60,
203 0x78, 0x00,
204 0x79, 0xb5,
205 0x7c, 0x05,
206 0x7d, 0x1a,
207 0x87, 0x55,
208 0x88, 0x72,
209 0x8f, 0x08,
210 0x90, 0xe0,
211 0x94, 0x40,
212 0xa0, 0x3f,
213 0xa1, 0xc0,
214 0xa4, 0xcc,
215 0xa5, 0x66,
216 0xa6, 0x66,
217 0xa7, 0x7b,
218 0xa8, 0x7b,
219 0xa9, 0x7b,
220 0xaa, 0x9a,
221 0xed, 0x04,
222 0xad, 0x00,
223 0xae, 0x03,
224 0xcc, 0xab,
225 0x01, 0x08,
226 0xff, 0xff
227};
228
229/* low level read/writes */
230static int si21_writeregs(struct si21xx_state *state, u8 reg1,
231 u8 *data, int len)
232{
233 int ret;
234 u8 buf[60];/* = { reg1, data };*/
235 struct i2c_msg msg = {
236 .addr = state->config->demod_address,
237 .flags = 0,
238 .buf = buf,
239 .len = len + 1
240 };
241
242 msg.buf[0] = reg1;
243 memcpy(msg.buf + 1, data, len);
244
245 ret = i2c_transfer(state->i2c, &msg, 1);
246
247 if (ret != 1)
248 dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
249 "ret == %i)\n", __func__, reg1, data[0], ret);
250
251 return (ret != 1) ? -EREMOTEIO : 0;
252}
253
254static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
255{
256 int ret;
257 u8 buf[] = { reg, data };
258 struct i2c_msg msg = {
259 .addr = state->config->demod_address,
260 .flags = 0,
261 .buf = buf,
262 .len = 2
263 };
264
265 ret = i2c_transfer(state->i2c, &msg, 1);
266
267 if (ret != 1)
268 dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
269 "ret == %i)\n", __func__, reg, data, ret);
270
271 return (ret != 1) ? -EREMOTEIO : 0;
272}
273
274static int si21_write(struct dvb_frontend *fe, u8 *buf, int len)
275{
276 struct si21xx_state *state = fe->demodulator_priv;
277
278 if (len != 2)
279 return -EINVAL;
280
281 return si21_writereg(state, buf[0], buf[1]);
282}
283
284static u8 si21_readreg(struct si21xx_state *state, u8 reg)
285{
286 int ret;
287 u8 b0[] = { reg };
288 u8 b1[] = { 0 };
289 struct i2c_msg msg[] = {
290 {
291 .addr = state->config->demod_address,
292 .flags = 0,
293 .buf = b0,
294 .len = 1
295 }, {
296 .addr = state->config->demod_address,
297 .flags = I2C_M_RD,
298 .buf = b1,
299 .len = 1
300 }
301 };
302
303 ret = i2c_transfer(state->i2c, msg, 2);
304
305 if (ret != 2)
306 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
307 __func__, reg, ret);
308
309 return b1[0];
310}
311
312static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
313{
314 int ret;
315 struct i2c_msg msg[] = {
316 {
317 .addr = state->config->demod_address,
318 .flags = 0,
319 .buf = &reg1,
320 .len = 1
321 }, {
322 .addr = state->config->demod_address,
323 .flags = I2C_M_RD,
324 .buf = b,
325 .len = len
326 }
327 };
328
329 ret = i2c_transfer(state->i2c, msg, 2);
330
331 if (ret != 2)
332 dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
333
334 return ret == 2 ? 0 : -1;
335}
336
337static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
338{
339 unsigned long start = jiffies;
340
341 dprintk("%s\n", __func__);
342
343 while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
344 if (jiffies - start > timeout) {
345 dprintk("%s: timeout!!\n", __func__);
346 return -ETIMEDOUT;
347 }
348 msleep(10);
349 };
350
351 return 0;
352}
353
354static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
355{
356 struct si21xx_state *state = fe->demodulator_priv;
357 u32 sym_rate, data_rate;
358 int i;
359 u8 sym_rate_bytes[3];
360
361 dprintk("%s : srate = %i\n", __func__ , srate);
362
363 if ((srate < 1000000) || (srate > 45000000))
364 return -EINVAL;
365
366 data_rate = srate;
367 sym_rate = 0;
368
369 for (i = 0; i < 4; ++i) {
370 sym_rate /= 100;
371 sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
372 state->fs;
373 data_rate /= 100;
374 }
375 for (i = 0; i < 3; ++i)
376 sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
377
378 si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
379
380 return 0;
381}
382
383static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
384 struct dvb_diseqc_master_cmd *m)
385{
386 struct si21xx_state *state = fe->demodulator_priv;
387 u8 lnb_status;
388 u8 LNB_CTRL_1;
389 int status;
390
391 dprintk("%s\n", __func__);
392
393 status = PASS;
394 LNB_CTRL_1 = 0;
395
396 status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
397 status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
398
399 /*fill the FIFO*/
400 status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
401
402 LNB_CTRL_1 = (lnb_status & 0x70);
403 LNB_CTRL_1 |= m->msg_len;
404
405 LNB_CTRL_1 |= 0x80; /* begin LNB signaling */
406
407 status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
408
409 return status;
410}
411
412static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
413 fe_sec_mini_cmd_t burst)
414{
415 struct si21xx_state *state = fe->demodulator_priv;
416 u8 val;
417
418 dprintk("%s\n", __func__);
419
420 if (si21xx_wait_diseqc_idle(state, 100) < 0)
421 return -ETIMEDOUT;
422
423 val = (0x80 | si21_readreg(state, 0xc1));
424 if (si21_writereg(state, LNB_CTRL_REG_1,
425 burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
426 return -EREMOTEIO;
427
428 if (si21xx_wait_diseqc_idle(state, 100) < 0)
429 return -ETIMEDOUT;
430
431 if (si21_writereg(state, LNB_CTRL_REG_1, val))
432 return -EREMOTEIO;
433
434 return 0;
435}
436/* 30.06.2008 */
437static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
438{
439 struct si21xx_state *state = fe->demodulator_priv;
440 u8 val;
441
442 dprintk("%s\n", __func__);
443 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
444
445 switch (tone) {
446 case SEC_TONE_ON:
447 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
448
449 case SEC_TONE_OFF:
450 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
451
452 default:
453 return -EINVAL;
454 }
455}
456
457static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
458{
459 struct si21xx_state *state = fe->demodulator_priv;
460
461 u8 val;
462 dprintk("%s: %s\n", __func__,
463 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
464 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
465
466
467 val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
468
469 switch (volt) {
470 case SEC_VOLTAGE_18:
471 return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
472 break;
473 case SEC_VOLTAGE_13:
474 return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
475 break;
476 default:
477 return -EINVAL;
478 };
479}
480
481static int si21xx_init(struct dvb_frontend *fe)
482{
483 struct si21xx_state *state = fe->demodulator_priv;
484 int i;
485 int status = 0;
486 u8 reg1;
487 u8 val;
488 u8 reg2[2];
489
490 dprintk("%s\n", __func__);
491
492 for (i = 0; ; i += 2) {
493 reg1 = serit_sp1511lhb_inittab[i];
494 val = serit_sp1511lhb_inittab[i+1];
495 if (reg1 == 0xff && val == 0xff)
496 break;
497 si21_writeregs(state, reg1, &val, 1);
498 }
499
500 /*DVB QPSK SYSTEM MODE REG*/
501 reg1 = 0x08;
502 si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
503
504 /*transport stream config*/
505 /*
506 mode = PARALLEL;
507 sdata_form = LSB_FIRST;
508 clk_edge = FALLING_EDGE;
509 clk_mode = CLK_GAPPED_MODE;
510 strt_len = BYTE_WIDE;
511 sync_pol = ACTIVE_HIGH;
512 val_pol = ACTIVE_HIGH;
513 err_pol = ACTIVE_HIGH;
514 sclk_rate = 0x00;
515 parity = 0x00 ;
516 data_delay = 0x00;
517 clk_delay = 0x00;
518 pclk_smooth = 0x00;
519 */
520 reg2[0] =
521 PARALLEL + (LSB_FIRST << 1)
522 + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
523 + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
524 + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
525
526 reg2[1] = 0;
527 /* sclk_rate + (parity << 2)
528 + (data_delay << 3) + (clk_delay << 4)
529 + (pclk_smooth << 5);
530 */
531 status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
532 if (status != 0)
533 dprintk(" %s : TS Set Error\n", __func__);
534
535 return 0;
536
537}
538
539static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
540{
541 struct si21xx_state *state = fe->demodulator_priv;
542 u8 regs_read[2];
543 u8 reg_read;
544 u8 i;
545 u8 lock;
546 u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
547
548 si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
549 reg_read = 0;
550
551 for (i = 0; i < 7; ++i)
552 reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
553
554 lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
555
556 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
557 *status = 0;
558
559 if (signal > 10)
560 *status |= FE_HAS_SIGNAL;
561
562 if (lock & 0x2)
563 *status |= FE_HAS_CARRIER;
564
565 if (lock & 0x20)
566 *status |= FE_HAS_VITERBI;
567
568 if (lock & 0x40)
569 *status |= FE_HAS_SYNC;
570
571 if ((lock & 0x7b) == 0x7b)
572 *status |= FE_HAS_LOCK;
573
574 return 0;
575}
576
577static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
578{
579 struct si21xx_state *state = fe->demodulator_priv;
580
581 /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
582 (u8*)agclevel, 0x01);*/
583
584 u16 signal = (3 * si21_readreg(state, 0x27) *
585 si21_readreg(state, 0x28));
586
587 dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
588 si21_readreg(state, 0x27),
589 si21_readreg(state, 0x28), (int) signal);
590
591 signal <<= 4;
592 *strength = signal;
593
594 return 0;
595}
596
597static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
598{
599 struct si21xx_state *state = fe->demodulator_priv;
600
601 dprintk("%s\n", __func__);
602
603 if (state->errmode != STATUS_BER)
604 return 0;
605
606 *ber = (si21_readreg(state, 0x1d) << 8) |
607 si21_readreg(state, 0x1e);
608
609 return 0;
610}
611
612static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
613{
614 struct si21xx_state *state = fe->demodulator_priv;
615
616 s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
617 si21_readreg(state, 0x25));
618 xsnr = 3 * (xsnr - 0xa100);
619 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
620
621 dprintk("%s\n", __func__);
622
623 return 0;
624}
625
626static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
627{
628 struct si21xx_state *state = fe->demodulator_priv;
629
630 dprintk("%s\n", __func__);
631
632 if (state->errmode != STATUS_UCBLOCKS)
633 *ucblocks = 0;
634 else
635 *ucblocks = (si21_readreg(state, 0x1d) << 8) |
636 si21_readreg(state, 0x1e);
637
638 return 0;
639}
640
641/* initiates a channel acquisition sequence
642 using the specified symbol rate and code rate */
643static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
644 fe_code_rate_t crate)
645{
646
647 struct si21xx_state *state = fe->demodulator_priv;
648 u8 coderates[] = {
649 0x0, 0x01, 0x02, 0x04, 0x00,
650 0x8, 0x10, 0x20, 0x00, 0x3f
651 };
652
653 u8 coderate_ptr;
654 int status;
655 u8 start_acq = 0x80;
656 u8 reg, regs[3];
657
658 dprintk("%s\n", __func__);
659
660 status = PASS;
661 coderate_ptr = coderates[crate];
662
663 si21xx_set_symbolrate(fe, symbrate);
664
665 /* write code rates to use in the Viterbi search */
666 status |= si21_writeregs(state,
667 VIT_SRCH_CTRL_REG_1,
668 &coderate_ptr, 0x01);
669
670 /* clear acq_start bit */
671 status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
672 reg &= ~start_acq;
673 status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
674
675 /* use new Carrier Frequency Offset Estimator (QuickLock) */
676 regs[0] = 0xCB;
677 regs[1] = 0x40;
678 regs[2] = 0xCB;
679
680 status |= si21_writeregs(state,
681 TWO_DB_BNDWDTH_THRSHLD_REG,
682 &regs[0], 0x03);
683 reg = 0x56;
684 status |= si21_writeregs(state,
685 LSA_CTRL_REG_1, &reg, 1);
686 reg = 0x05;
687 status |= si21_writeregs(state,
688 BLIND_SCAN_CTRL_REG, &reg, 1);
689 /* start automatic acq */
690 status |= si21_writeregs(state,
691 ACQ_CTRL_REG_2, &start_acq, 0x01);
692
693 return status;
694}
695
696static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p)
697{
698 dprintk("%s(..)\n", __func__);
699 return 0;
700}
701
702static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p)
703{
704 dprintk("%s(..)\n", __func__);
705 return 0;
706}
707
708static int si21xx_set_frontend(struct dvb_frontend *fe,
709 struct dvb_frontend_parameters *dfp)
710{
711 struct si21xx_state *state = fe->demodulator_priv;
712 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
713
714 /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz)
715 datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/
716
717 /* in MHz */
718 unsigned char coarse_tune_freq;
719 int fine_tune_freq;
720 unsigned char sample_rate = 0;
721 /* boolean */
722 unsigned int inband_interferer_ind;
723
724 /* INTERMEDIATE VALUES */
725 int icoarse_tune_freq; /* MHz */
726 int ifine_tune_freq; /* MHz */
727 unsigned int band_high;
728 unsigned int band_low;
729 unsigned int x1;
730 unsigned int x2;
731 int i;
732 unsigned int inband_interferer_div2[ALLOWABLE_FS_COUNT] = {
733 FALSE, FALSE, FALSE, FALSE, FALSE,
734 FALSE, FALSE, FALSE, FALSE, FALSE
735 };
736 unsigned int inband_interferer_div4[ALLOWABLE_FS_COUNT] = {
737 FALSE, FALSE, FALSE, FALSE, FALSE,
738 FALSE, FALSE, FALSE, FALSE, FALSE
739 };
740
741 int status;
742
743 /* allowable sample rates for ADC in MHz */
744 int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
745 196, 204, 205, 206, 207
746 };
747 /* in MHz */
748 int if_limit_high;
749 int if_limit_low;
750 int lnb_lo;
751 int lnb_uncertanity;
752
753 int rf_freq;
754 int data_rate;
755 unsigned char regs[4];
756
757 dprintk("%s : FE_SET_FRONTEND\n", __func__);
758
759 if (c->delivery_system != SYS_DVBS) {
760 dprintk("%s: unsupported delivery system selected (%d)\n",
761 __func__, c->delivery_system);
762 return -EOPNOTSUPP;
763 }
764
765 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
766 inband_interferer_div2[i] = inband_interferer_div4[i] = FALSE;
767
768 if_limit_high = -700000;
769 if_limit_low = -100000;
770 /* in MHz */
771 lnb_lo = 0;
772 lnb_uncertanity = 0;
773
774 rf_freq = 10 * c->frequency ;
775 data_rate = c->symbol_rate / 100;
776
777 status = PASS;
778
779 band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
780 + (data_rate * 135)) / 200;
781
782 band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
783 + (data_rate * 135)) / 200;
784
785
786 icoarse_tune_freq = 100000 *
787 (((rf_freq - lnb_lo) -
788 (if_limit_low + if_limit_high) / 2)
789 / 100000);
790
791 ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
792
793 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
794 x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
795 (afs[i] * 2500) + afs[i] * 2500;
796
797 x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
798 (afs[i] * 2500);
799
800 if (((band_low < x1) && (x1 < band_high)) ||
801 ((band_low < x2) && (x2 < band_high)))
802 inband_interferer_div4[i] = TRUE;
803
804 }
805
806 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
807 x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
808 (afs[i] * 5000) + afs[i] * 5000;
809
810 x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
811 (afs[i] * 5000);
812
813 if (((band_low < x1) && (x1 < band_high)) ||
814 ((band_low < x2) && (x2 < band_high)))
815 inband_interferer_div2[i] = TRUE;
816 }
817
818 inband_interferer_ind = TRUE;
819 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
820 inband_interferer_ind &= inband_interferer_div2[i] |
821 inband_interferer_div4[i];
822
823 if (inband_interferer_ind) {
824 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
825 if (inband_interferer_div2[i] == FALSE) {
826 sample_rate = (u8) afs[i];
827 break;
828 }
829 }
830 } else {
831 for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
832 if ((inband_interferer_div2[i] |
833 inband_interferer_div4[i]) == FALSE) {
834 sample_rate = (u8) afs[i];
835 break;
836 }
837 }
838
839 }
840
841 if (sample_rate > 207 || sample_rate < 192)
842 sample_rate = 200;
843
844 fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
845 ((sample_rate) * 1000));
846
847 coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
848
849 regs[0] = sample_rate;
850 regs[1] = coarse_tune_freq;
851 regs[2] = fine_tune_freq & 0xFF;
852 regs[3] = fine_tune_freq >> 8 & 0xFF;
853
854 status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
855
856 state->fs = sample_rate;/*ADC MHz*/
857 si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
858
859 return 0;
860}
861
862static int si21xx_sleep(struct dvb_frontend *fe)
863{
864 struct si21xx_state *state = fe->demodulator_priv;
865 u8 regdata;
866
867 dprintk("%s\n", __func__);
868
869 si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
870 regdata |= 1 << 6;
871 si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
872 state->initialised = 0;
873
874 return 0;
875}
876
877static void si21xx_release(struct dvb_frontend *fe)
878{
879 struct si21xx_state *state = fe->demodulator_priv;
880
881 dprintk("%s\n", __func__);
882
883 kfree(state);
884}
885
886static struct dvb_frontend_ops si21xx_ops = {
887
888 .info = {
889 .name = "SL SI21XX DVB-S",
890 .type = FE_QPSK,
891 .frequency_min = 950000,
892 .frequency_max = 2150000,
893 .frequency_stepsize = 125, /* kHz for QPSK frontends */
894 .frequency_tolerance = 0,
895 .symbol_rate_min = 1000000,
896 .symbol_rate_max = 45000000,
897 .symbol_rate_tolerance = 500, /* ppm */
898 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
899 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
900 FE_CAN_QPSK |
901 FE_CAN_FEC_AUTO
902 },
903
904 .release = si21xx_release,
905 .init = si21xx_init,
906 .sleep = si21xx_sleep,
907 .write = si21_write,
908 .read_status = si21_read_status,
909 .read_ber = si21_read_ber,
910 .read_signal_strength = si21_read_signal_strength,
911 .read_snr = si21_read_snr,
912 .read_ucblocks = si21_read_ucblocks,
913 .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
914 .diseqc_send_burst = si21xx_send_diseqc_burst,
915 .set_tone = si21xx_set_tone,
916 .set_voltage = si21xx_set_voltage,
917
918 .set_property = si21xx_set_property,
919 .get_property = si21xx_get_property,
920 .set_frontend = si21xx_set_frontend,
921};
922
923struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
924 struct i2c_adapter *i2c)
925{
926 struct si21xx_state *state = NULL;
927 int id;
928
929 dprintk("%s\n", __func__);
930
931 /* allocate memory for the internal state */
932 state = kmalloc(sizeof(struct si21xx_state), GFP_KERNEL);
933 if (state == NULL)
934 goto error;
935
936 /* setup the state */
937 state->config = config;
938 state->i2c = i2c;
939 state->initialised = 0;
940 state->errmode = STATUS_BER;
941
942 /* check if the demod is there */
943 id = si21_readreg(state, SYSTEM_MODE_REG);
944 si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
945 msleep(200);
946 id = si21_readreg(state, 0x00);
947
948 /* register 0x00 contains:
949 0x34 for SI2107
950 0x24 for SI2108
951 0x14 for SI2109
952 0x04 for SI2110
953 */
954 if (id != 0x04 && id != 0x14)
955 goto error;
956
957 /* create dvb_frontend */
958 memcpy(&state->frontend.ops, &si21xx_ops,
959 sizeof(struct dvb_frontend_ops));
960 state->frontend.demodulator_priv = state;
961 return &state->frontend;
962
963error:
964 kfree(state);
965 return NULL;
966}
967EXPORT_SYMBOL(si21xx_attach);
968
969module_param(debug, int, 0644);
970MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
971
972MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
973MODULE_AUTHOR("Igor M. Liplianin");
974MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/si21xx.h b/drivers/media/dvb/frontends/si21xx.h
new file mode 100644
index 000000000000..141b5b8a5f63
--- /dev/null
+++ b/drivers/media/dvb/frontends/si21xx.h
@@ -0,0 +1,37 @@
1#ifndef SI21XX_H
2#define SI21XX_H
3
4#include <linux/dvb/frontend.h>
5#include "dvb_frontend.h"
6
7struct si21xx_config {
8 /* the demodulator's i2c address */
9 u8 demod_address;
10
11 /* minimum delay before retuning */
12 int min_delay_ms;
13};
14
15#if defined(CONFIG_DVB_SI21XX) || \
16 (defined(CONFIG_DVB_SI21XX_MODULE) && defined(MODULE))
17extern struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
18 struct i2c_adapter *i2c);
19#else
20static inline struct dvb_frontend *si21xx_attach(
21 const struct si21xx_config *config, struct i2c_adapter *i2c)
22{
23 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
24 return NULL;
25}
26#endif
27
28static inline int si21xx_writeregister(struct dvb_frontend *fe, u8 reg, u8 val)
29{
30 int r = 0;
31 u8 buf[] = {reg, val};
32 if (fe->ops.write)
33 r = fe->ops.write(fe, buf, 2);
34 return r;
35}
36
37#endif
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c
index 4543609e1816..559509ab4dab 100644
--- a/drivers/media/dvb/frontends/sp887x.c
+++ b/drivers/media/dvb/frontends/sp887x.c
@@ -337,7 +337,8 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe,
337 struct dvb_frontend_parameters *p) 337 struct dvb_frontend_parameters *p)
338{ 338{
339 struct sp887x_state* state = fe->demodulator_priv; 339 struct sp887x_state* state = fe->demodulator_priv;
340 int actual_freq, err; 340 unsigned actual_freq;
341 int err;
341 u16 val, reg0xc05; 342 u16 val, reg0xc05;
342 343
343 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ && 344 if (p->u.ofdm.bandwidth != BANDWIDTH_8_MHZ &&
diff --git a/drivers/media/dvb/frontends/stb6000.c b/drivers/media/dvb/frontends/stb6000.c
new file mode 100644
index 000000000000..0e2cb0df1441
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6000.c
@@ -0,0 +1,255 @@
1 /*
2 Driver for ST STB6000 DVBS Silicon tuner
3
4 Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#include <linux/module.h>
24#include <linux/dvb/frontend.h>
25#include <asm/types.h>
26
27#include "stb6000.h"
28
29static int debug;
30#define dprintk(args...) \
31 do { \
32 if (debug) \
33 printk(KERN_DEBUG "stb6000: " args); \
34 } while (0)
35
36struct stb6000_priv {
37 /* i2c details */
38 int i2c_address;
39 struct i2c_adapter *i2c;
40 u32 frequency;
41};
42
43static int stb6000_release(struct dvb_frontend *fe)
44{
45 kfree(fe->tuner_priv);
46 fe->tuner_priv = NULL;
47 return 0;
48}
49
50static int stb6000_sleep(struct dvb_frontend *fe)
51{
52 struct stb6000_priv *priv = fe->tuner_priv;
53 int ret;
54 u8 buf[] = { 10, 0 };
55 struct i2c_msg msg = {
56 .addr = priv->i2c_address,
57 .flags = 0,
58 .buf = buf,
59 .len = 2
60 };
61
62 dprintk("%s:\n", __func__);
63
64 if (fe->ops.i2c_gate_ctrl)
65 fe->ops.i2c_gate_ctrl(fe, 1);
66
67 ret = i2c_transfer(priv->i2c, &msg, 1);
68 if (ret != 1)
69 dprintk("%s: i2c error\n", __func__);
70
71 if (fe->ops.i2c_gate_ctrl)
72 fe->ops.i2c_gate_ctrl(fe, 0);
73
74 return (ret == 1) ? 0 : ret;
75}
76
77static int stb6000_set_params(struct dvb_frontend *fe,
78 struct dvb_frontend_parameters *params)
79{
80 struct stb6000_priv *priv = fe->tuner_priv;
81 unsigned int n, m;
82 int ret;
83 u32 freq_mhz;
84 int bandwidth;
85 u8 buf[12];
86 struct i2c_msg msg = {
87 .addr = priv->i2c_address,
88 .flags = 0,
89 .buf = buf,
90 .len = 12
91 };
92
93 dprintk("%s:\n", __func__);
94
95 freq_mhz = params->frequency / 1000;
96 bandwidth = params->u.qpsk.symbol_rate / 1000000;
97
98 if (bandwidth > 31)
99 bandwidth = 31;
100
101 if ((freq_mhz > 949) && (freq_mhz < 2151)) {
102 buf[0] = 0x01;
103 buf[1] = 0xac;
104 if (freq_mhz < 1950)
105 buf[1] = 0xaa;
106 if (freq_mhz < 1800)
107 buf[1] = 0xa8;
108 if (freq_mhz < 1650)
109 buf[1] = 0xa6;
110 if (freq_mhz < 1530)
111 buf[1] = 0xa5;
112 if (freq_mhz < 1470)
113 buf[1] = 0xa4;
114 if (freq_mhz < 1370)
115 buf[1] = 0xa2;
116 if (freq_mhz < 1300)
117 buf[1] = 0xa1;
118 if (freq_mhz < 1200)
119 buf[1] = 0xa0;
120 if (freq_mhz < 1075)
121 buf[1] = 0xbc;
122 if (freq_mhz < 1000)
123 buf[1] = 0xba;
124 if (freq_mhz < 1075) {
125 n = freq_mhz / 8; /* vco=lo*4 */
126 m = 2;
127 } else {
128 n = freq_mhz / 16; /* vco=lo*2 */
129 m = 1;
130 }
131 buf[2] = n >> 1;
132 buf[3] = (unsigned char)(((n & 1) << 7) |
133 (m * freq_mhz - n * 16) | 0x60);
134 buf[4] = 0x04;
135 buf[5] = 0x0e;
136
137 buf[6] = (unsigned char)(bandwidth);
138
139 buf[7] = 0xd8;
140 buf[8] = 0xd0;
141 buf[9] = 0x50;
142 buf[10] = 0xeb;
143 buf[11] = 0x4f;
144
145 if (fe->ops.i2c_gate_ctrl)
146 fe->ops.i2c_gate_ctrl(fe, 1);
147
148 ret = i2c_transfer(priv->i2c, &msg, 1);
149 if (ret != 1)
150 dprintk("%s: i2c error\n", __func__);
151
152 udelay(10);
153 if (fe->ops.i2c_gate_ctrl)
154 fe->ops.i2c_gate_ctrl(fe, 0);
155
156 buf[0] = 0x07;
157 buf[1] = 0xdf;
158 buf[2] = 0xd0;
159 buf[3] = 0x50;
160 buf[4] = 0xfb;
161 msg.len = 5;
162
163 if (fe->ops.i2c_gate_ctrl)
164 fe->ops.i2c_gate_ctrl(fe, 1);
165
166 ret = i2c_transfer(priv->i2c, &msg, 1);
167 if (ret != 1)
168 dprintk("%s: i2c error\n", __func__);
169
170 udelay(10);
171 if (fe->ops.i2c_gate_ctrl)
172 fe->ops.i2c_gate_ctrl(fe, 0);
173
174 priv->frequency = freq_mhz * 1000;
175
176 return (ret == 1) ? 0 : ret;
177 }
178 return -1;
179}
180
181static int stb6000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
182{
183 struct stb6000_priv *priv = fe->tuner_priv;
184 *frequency = priv->frequency;
185 return 0;
186}
187
188static struct dvb_tuner_ops stb6000_tuner_ops = {
189 .info = {
190 .name = "ST STB6000",
191 .frequency_min = 950000,
192 .frequency_max = 2150000
193 },
194 .release = stb6000_release,
195 .sleep = stb6000_sleep,
196 .set_params = stb6000_set_params,
197 .get_frequency = stb6000_get_frequency,
198};
199
200struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
201 struct i2c_adapter *i2c)
202{
203 struct stb6000_priv *priv = NULL;
204 u8 b0[] = { 0 };
205 u8 b1[] = { 0, 0 };
206 struct i2c_msg msg[2] = {
207 {
208 .addr = addr,
209 .flags = 0,
210 .buf = b0,
211 .len = 0
212 }, {
213 .addr = addr,
214 .flags = I2C_M_RD,
215 .buf = b1,
216 .len = 2
217 }
218 };
219 int ret;
220
221 dprintk("%s:\n", __func__);
222
223 if (fe->ops.i2c_gate_ctrl)
224 fe->ops.i2c_gate_ctrl(fe, 1);
225
226 /* is some i2c device here ? */
227 ret = i2c_transfer(i2c, msg, 2);
228 if (fe->ops.i2c_gate_ctrl)
229 fe->ops.i2c_gate_ctrl(fe, 0);
230
231 if (ret != 2)
232 return NULL;
233
234 priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL);
235 if (priv == NULL)
236 return NULL;
237
238 priv->i2c_address = addr;
239 priv->i2c = i2c;
240
241 memcpy(&fe->ops.tuner_ops, &stb6000_tuner_ops,
242 sizeof(struct dvb_tuner_ops));
243
244 fe->tuner_priv = priv;
245
246 return fe;
247}
248EXPORT_SYMBOL(stb6000_attach);
249
250module_param(debug, int, 0644);
251MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
252
253MODULE_DESCRIPTION("DVB STB6000 driver");
254MODULE_AUTHOR("Igor M. Liplianin <liplianin@me.by>");
255MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stb6000.h b/drivers/media/dvb/frontends/stb6000.h
new file mode 100644
index 000000000000..7be479c22d5b
--- /dev/null
+++ b/drivers/media/dvb/frontends/stb6000.h
@@ -0,0 +1,51 @@
1 /*
2 Driver for ST stb6000 DVBS Silicon tuner
3
4 Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 */
22
23#ifndef __DVB_STB6000_H__
24#define __DVB_STB6000_H__
25
26#include <linux/i2c.h>
27#include "dvb_frontend.h"
28
29/**
30 * Attach a stb6000 tuner to the supplied frontend structure.
31 *
32 * @param fe Frontend to attach to.
33 * @param addr i2c address of the tuner.
34 * @param i2c i2c adapter to use.
35 * @return FE pointer on success, NULL on failure.
36 */
37#if defined(CONFIG_DVB_STB6000) || (defined(CONFIG_DVB_STB6000_MODULE) \
38 && defined(MODULE))
39extern struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr,
40 struct i2c_adapter *i2c);
41#else
42static inline struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe,
43 int addr,
44 struct i2c_adapter *i2c)
45{
46 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
47 return NULL;
48}
49#endif /* CONFIG_DVB_STB6000 */
50
51#endif /* __DVB_STB6000_H__ */
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c
new file mode 100644
index 000000000000..ff1194de34c0
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0288.c
@@ -0,0 +1,618 @@
1/*
2 Driver for ST STV0288 demodulator
3 Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
4 for Reel Multimedia
5 Copyright (C) 2008 TurboSight.com, Bob Liu <bob@turbosight.com>
6 Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
7 Removed stb6000 specific tuner code and revised some
8 procedures.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24*/
25
26#include <linux/init.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/string.h>
30#include <linux/slab.h>
31#include <linux/jiffies.h>
32#include <asm/div64.h>
33
34#include "dvb_frontend.h"
35#include "stv0288.h"
36
37struct stv0288_state {
38 struct i2c_adapter *i2c;
39 const struct stv0288_config *config;
40 struct dvb_frontend frontend;
41
42 u8 initialised:1;
43 u32 tuner_frequency;
44 u32 symbol_rate;
45 fe_code_rate_t fec_inner;
46 int errmode;
47};
48
49#define STATUS_BER 0
50#define STATUS_UCBLOCKS 1
51
52static int debug;
53static int debug_legacy_dish_switch;
54#define dprintk(args...) \
55 do { \
56 if (debug) \
57 printk(KERN_DEBUG "stv0288: " args); \
58 } while (0)
59
60
61static int stv0288_writeregI(struct stv0288_state *state, u8 reg, u8 data)
62{
63 int ret;
64 u8 buf[] = { reg, data };
65 struct i2c_msg msg = {
66 .addr = state->config->demod_address,
67 .flags = 0,
68 .buf = buf,
69 .len = 2
70 };
71
72 ret = i2c_transfer(state->i2c, &msg, 1);
73
74 if (ret != 1)
75 dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
76 "ret == %i)\n", __func__, reg, data, ret);
77
78 return (ret != 1) ? -EREMOTEIO : 0;
79}
80
81static int stv0288_write(struct dvb_frontend *fe, u8 *buf, int len)
82{
83 struct stv0288_state *state = fe->demodulator_priv;
84
85 if (len != 2)
86 return -EINVAL;
87
88 return stv0288_writeregI(state, buf[0], buf[1]);
89}
90
91static u8 stv0288_readreg(struct stv0288_state *state, u8 reg)
92{
93 int ret;
94 u8 b0[] = { reg };
95 u8 b1[] = { 0 };
96 struct i2c_msg msg[] = {
97 {
98 .addr = state->config->demod_address,
99 .flags = 0,
100 .buf = b0,
101 .len = 1
102 }, {
103 .addr = state->config->demod_address,
104 .flags = I2C_M_RD,
105 .buf = b1,
106 .len = 1
107 }
108 };
109
110 ret = i2c_transfer(state->i2c, msg, 2);
111
112 if (ret != 2)
113 dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
114 __func__, reg, ret);
115
116 return b1[0];
117}
118
119static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate)
120{
121 struct stv0288_state *state = fe->demodulator_priv;
122 unsigned int temp;
123 unsigned char b[3];
124
125 if ((srate < 1000000) || (srate > 45000000))
126 return -EINVAL;
127
128 temp = (unsigned int)srate / 1000;
129
130 temp = temp * 32768;
131 temp = temp / 25;
132 temp = temp / 125;
133 b[0] = (unsigned char)((temp >> 12) & 0xff);
134 b[1] = (unsigned char)((temp >> 4) & 0xff);
135 b[2] = (unsigned char)((temp << 4) & 0xf0);
136 stv0288_writeregI(state, 0x28, 0x80); /* SFRH */
137 stv0288_writeregI(state, 0x29, 0); /* SFRM */
138 stv0288_writeregI(state, 0x2a, 0); /* SFRL */
139
140 stv0288_writeregI(state, 0x28, b[0]);
141 stv0288_writeregI(state, 0x29, b[1]);
142 stv0288_writeregI(state, 0x2a, b[2]);
143 dprintk("stv0288: stv0288_set_symbolrate\n");
144
145 return 0;
146}
147
148static int stv0288_send_diseqc_msg(struct dvb_frontend *fe,
149 struct dvb_diseqc_master_cmd *m)
150{
151 struct stv0288_state *state = fe->demodulator_priv;
152
153 int i;
154
155 dprintk("%s\n", __func__);
156
157 stv0288_writeregI(state, 0x09, 0);
158 msleep(30);
159 stv0288_writeregI(state, 0x05, 0x16);
160
161 for (i = 0; i < m->msg_len; i++) {
162 if (stv0288_writeregI(state, 0x06, m->msg[i]))
163 return -EREMOTEIO;
164 msleep(12);
165 }
166
167 return 0;
168}
169
170static int stv0288_send_diseqc_burst(struct dvb_frontend *fe,
171 fe_sec_mini_cmd_t burst)
172{
173 struct stv0288_state *state = fe->demodulator_priv;
174
175 dprintk("%s\n", __func__);
176
177 if (stv0288_writeregI(state, 0x05, 0x16))/* burst mode */
178 return -EREMOTEIO;
179
180 if (stv0288_writeregI(state, 0x06, burst == SEC_MINI_A ? 0x00 : 0xff))
181 return -EREMOTEIO;
182
183 if (stv0288_writeregI(state, 0x06, 0x12))
184 return -EREMOTEIO;
185
186 return 0;
187}
188
189static int stv0288_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
190{
191 struct stv0288_state *state = fe->demodulator_priv;
192
193 switch (tone) {
194 case SEC_TONE_ON:
195 if (stv0288_writeregI(state, 0x05, 0x10))/* burst mode */
196 return -EREMOTEIO;
197 return stv0288_writeregI(state, 0x06, 0xff);
198
199 case SEC_TONE_OFF:
200 if (stv0288_writeregI(state, 0x05, 0x13))/* burst mode */
201 return -EREMOTEIO;
202 return stv0288_writeregI(state, 0x06, 0x00);
203
204 default:
205 return -EINVAL;
206 }
207}
208
209static u8 stv0288_inittab[] = {
210 0x01, 0x15,
211 0x02, 0x20,
212 0x09, 0x0,
213 0x0a, 0x4,
214 0x0b, 0x0,
215 0x0c, 0x0,
216 0x0d, 0x0,
217 0x0e, 0xd4,
218 0x0f, 0x30,
219 0x11, 0x80,
220 0x12, 0x03,
221 0x13, 0x48,
222 0x14, 0x84,
223 0x15, 0x45,
224 0x16, 0xb7,
225 0x17, 0x9c,
226 0x18, 0x0,
227 0x19, 0xa6,
228 0x1a, 0x88,
229 0x1b, 0x8f,
230 0x1c, 0xf0,
231 0x20, 0x0b,
232 0x21, 0x54,
233 0x22, 0x0,
234 0x23, 0x0,
235 0x2b, 0xff,
236 0x2c, 0xf7,
237 0x30, 0x0,
238 0x31, 0x1e,
239 0x32, 0x14,
240 0x33, 0x0f,
241 0x34, 0x09,
242 0x35, 0x0c,
243 0x36, 0x05,
244 0x37, 0x2f,
245 0x38, 0x16,
246 0x39, 0xbe,
247 0x3a, 0x0,
248 0x3b, 0x13,
249 0x3c, 0x11,
250 0x3d, 0x30,
251 0x40, 0x63,
252 0x41, 0x04,
253 0x42, 0x60,
254 0x43, 0x00,
255 0x44, 0x00,
256 0x45, 0x00,
257 0x46, 0x00,
258 0x47, 0x00,
259 0x4a, 0x00,
260 0x50, 0x10,
261 0x51, 0x38,
262 0x52, 0x21,
263 0x58, 0x54,
264 0x59, 0x86,
265 0x5a, 0x0,
266 0x5b, 0x9b,
267 0x5c, 0x08,
268 0x5d, 0x7f,
269 0x5e, 0x0,
270 0x5f, 0xff,
271 0x70, 0x0,
272 0x71, 0x0,
273 0x72, 0x0,
274 0x74, 0x0,
275 0x75, 0x0,
276 0x76, 0x0,
277 0x81, 0x0,
278 0x82, 0x3f,
279 0x83, 0x3f,
280 0x84, 0x0,
281 0x85, 0x0,
282 0x88, 0x0,
283 0x89, 0x0,
284 0x8a, 0x0,
285 0x8b, 0x0,
286 0x8c, 0x0,
287 0x90, 0x0,
288 0x91, 0x0,
289 0x92, 0x0,
290 0x93, 0x0,
291 0x94, 0x1c,
292 0x97, 0x0,
293 0xa0, 0x48,
294 0xa1, 0x0,
295 0xb0, 0xb8,
296 0xb1, 0x3a,
297 0xb2, 0x10,
298 0xb3, 0x82,
299 0xb4, 0x80,
300 0xb5, 0x82,
301 0xb6, 0x82,
302 0xb7, 0x82,
303 0xb8, 0x20,
304 0xb9, 0x0,
305 0xf0, 0x0,
306 0xf1, 0x0,
307 0xf2, 0xc0,
308 0x51, 0x36,
309 0x52, 0x09,
310 0x53, 0x94,
311 0x54, 0x62,
312 0x55, 0x29,
313 0x56, 0x64,
314 0x57, 0x2b,
315 0xff, 0xff,
316};
317
318static int stv0288_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
319{
320 dprintk("%s: %s\n", __func__,
321 volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
322 volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
323
324 return 0;
325}
326
327static int stv0288_init(struct dvb_frontend *fe)
328{
329 struct stv0288_state *state = fe->demodulator_priv;
330 int i;
331 u8 reg;
332 u8 val;
333
334 dprintk("stv0288: init chip\n");
335 stv0288_writeregI(state, 0x41, 0x04);
336 msleep(50);
337
338 /* we have default inittab */
339 if (state->config->inittab == NULL) {
340 for (i = 0; !(stv0288_inittab[i] == 0xff &&
341 stv0288_inittab[i + 1] == 0xff); i += 2)
342 stv0288_writeregI(state, stv0288_inittab[i],
343 stv0288_inittab[i + 1]);
344 } else {
345 for (i = 0; ; i += 2) {
346 reg = state->config->inittab[i];
347 val = state->config->inittab[i+1];
348 if (reg == 0xff && val == 0xff)
349 break;
350 stv0288_writeregI(state, reg, val);
351 }
352 }
353 return 0;
354}
355
356static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
357{
358 struct stv0288_state *state = fe->demodulator_priv;
359
360 u8 sync = stv0288_readreg(state, 0x24);
361 if (sync == 255)
362 sync = 0;
363
364 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
365
366 *status = 0;
367
368 if ((sync & 0x08) == 0x08) {
369 *status |= FE_HAS_LOCK;
370 dprintk("stv0288 has locked\n");
371 }
372
373 return 0;
374}
375
376static int stv0288_read_ber(struct dvb_frontend *fe, u32 *ber)
377{
378 struct stv0288_state *state = fe->demodulator_priv;
379
380 if (state->errmode != STATUS_BER)
381 return 0;
382 *ber = (stv0288_readreg(state, 0x26) << 8) |
383 stv0288_readreg(state, 0x27);
384 dprintk("stv0288_read_ber %d\n", *ber);
385
386 return 0;
387}
388
389
390static int stv0288_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
391{
392 struct stv0288_state *state = fe->demodulator_priv;
393
394 s32 signal = 0xffff - ((stv0288_readreg(state, 0x10) << 8));
395
396
397 signal = signal * 5 / 4;
398 *strength = (signal > 0xffff) ? 0xffff : (signal < 0) ? 0 : signal;
399 dprintk("stv0288_read_signal_strength %d\n", *strength);
400
401 return 0;
402}
403static int stv0288_sleep(struct dvb_frontend *fe)
404{
405 struct stv0288_state *state = fe->demodulator_priv;
406
407 stv0288_writeregI(state, 0x41, 0x84);
408 state->initialised = 0;
409
410 return 0;
411}
412static int stv0288_read_snr(struct dvb_frontend *fe, u16 *snr)
413{
414 struct stv0288_state *state = fe->demodulator_priv;
415
416 s32 xsnr = 0xffff - ((stv0288_readreg(state, 0x2d) << 8)
417 | stv0288_readreg(state, 0x2e));
418 xsnr = 3 * (xsnr - 0xa100);
419 *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
420 dprintk("stv0288_read_snr %d\n", *snr);
421
422 return 0;
423}
424
425static int stv0288_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
426{
427 struct stv0288_state *state = fe->demodulator_priv;
428
429 if (state->errmode != STATUS_BER)
430 return 0;
431 *ucblocks = (stv0288_readreg(state, 0x26) << 8) |
432 stv0288_readreg(state, 0x27);
433 dprintk("stv0288_read_ber %d\n", *ucblocks);
434
435 return 0;
436}
437
438static int stv0288_set_property(struct dvb_frontend *fe, struct dtv_property *p)
439{
440 dprintk("%s(..)\n", __func__);
441 return 0;
442}
443
444static int stv0288_get_property(struct dvb_frontend *fe, struct dtv_property *p)
445{
446 dprintk("%s(..)\n", __func__);
447 return 0;
448}
449
450static int stv0288_set_frontend(struct dvb_frontend *fe,
451 struct dvb_frontend_parameters *dfp)
452{
453 struct stv0288_state *state = fe->demodulator_priv;
454 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
455
456 char tm;
457 unsigned char tda[3];
458
459 dprintk("%s : FE_SET_FRONTEND\n", __func__);
460
461 if (c->delivery_system != SYS_DVBS) {
462 dprintk("%s: unsupported delivery "
463 "system selected (%d)\n",
464 __func__, c->delivery_system);
465 return -EOPNOTSUPP;
466 }
467
468 if (state->config->set_ts_params)
469 state->config->set_ts_params(fe, 0);
470
471 /* only frequency & symbol_rate are used for tuner*/
472 dfp->frequency = c->frequency;
473 dfp->u.qpsk.symbol_rate = c->symbol_rate;
474 if (fe->ops.tuner_ops.set_params) {
475 fe->ops.tuner_ops.set_params(fe, dfp);
476 if (fe->ops.i2c_gate_ctrl)
477 fe->ops.i2c_gate_ctrl(fe, 0);
478 }
479
480 udelay(10);
481 stv0288_set_symbolrate(fe, c->symbol_rate);
482 /* Carrier lock control register */
483 stv0288_writeregI(state, 0x15, 0xc5);
484
485 tda[0] = 0x2b; /* CFRM */
486 tda[2] = 0x0; /* CFRL */
487 for (tm = -6; tm < 7;) {
488 /* Viterbi status */
489 if (stv0288_readreg(state, 0x24) & 0x80)
490 break;
491
492 tda[2] += 40;
493 if (tda[2] < 40)
494 tm++;
495 tda[1] = (unsigned char)tm;
496 stv0288_writeregI(state, 0x2b, tda[1]);
497 stv0288_writeregI(state, 0x2c, tda[2]);
498 udelay(30);
499 }
500
501 state->tuner_frequency = c->frequency;
502 state->fec_inner = FEC_AUTO;
503 state->symbol_rate = c->symbol_rate;
504
505 return 0;
506}
507
508static int stv0288_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
509{
510 struct stv0288_state *state = fe->demodulator_priv;
511
512 if (enable)
513 stv0288_writeregI(state, 0x01, 0xb5);
514 else
515 stv0288_writeregI(state, 0x01, 0x35);
516
517 udelay(1);
518
519 return 0;
520}
521
522static void stv0288_release(struct dvb_frontend *fe)
523{
524 struct stv0288_state *state = fe->demodulator_priv;
525 kfree(state);
526}
527
528static struct dvb_frontend_ops stv0288_ops = {
529
530 .info = {
531 .name = "ST STV0288 DVB-S",
532 .type = FE_QPSK,
533 .frequency_min = 950000,
534 .frequency_max = 2150000,
535 .frequency_stepsize = 1000, /* kHz for QPSK frontends */
536 .frequency_tolerance = 0,
537 .symbol_rate_min = 1000000,
538 .symbol_rate_max = 45000000,
539 .symbol_rate_tolerance = 500, /* ppm */
540 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
541 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
542 FE_CAN_QPSK |
543 FE_CAN_FEC_AUTO
544 },
545
546 .release = stv0288_release,
547 .init = stv0288_init,
548 .sleep = stv0288_sleep,
549 .write = stv0288_write,
550 .i2c_gate_ctrl = stv0288_i2c_gate_ctrl,
551 .read_status = stv0288_read_status,
552 .read_ber = stv0288_read_ber,
553 .read_signal_strength = stv0288_read_signal_strength,
554 .read_snr = stv0288_read_snr,
555 .read_ucblocks = stv0288_read_ucblocks,
556 .diseqc_send_master_cmd = stv0288_send_diseqc_msg,
557 .diseqc_send_burst = stv0288_send_diseqc_burst,
558 .set_tone = stv0288_set_tone,
559 .set_voltage = stv0288_set_voltage,
560
561 .set_property = stv0288_set_property,
562 .get_property = stv0288_get_property,
563 .set_frontend = stv0288_set_frontend,
564};
565
566struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
567 struct i2c_adapter *i2c)
568{
569 struct stv0288_state *state = NULL;
570 int id;
571
572 /* allocate memory for the internal state */
573 state = kmalloc(sizeof(struct stv0288_state), GFP_KERNEL);
574 if (state == NULL)
575 goto error;
576
577 /* setup the state */
578 state->config = config;
579 state->i2c = i2c;
580 state->initialised = 0;
581 state->tuner_frequency = 0;
582 state->symbol_rate = 0;
583 state->fec_inner = 0;
584 state->errmode = STATUS_BER;
585
586 stv0288_writeregI(state, 0x41, 0x04);
587 msleep(200);
588 id = stv0288_readreg(state, 0x00);
589 dprintk("stv0288 id %x\n", id);
590
591 /* register 0x00 contains 0x11 for STV0288 */
592 if (id != 0x11)
593 goto error;
594
595 /* create dvb_frontend */
596 memcpy(&state->frontend.ops, &stv0288_ops,
597 sizeof(struct dvb_frontend_ops));
598 state->frontend.demodulator_priv = state;
599 return &state->frontend;
600
601error:
602 kfree(state);
603
604 return NULL;
605}
606EXPORT_SYMBOL(stv0288_attach);
607
608module_param(debug_legacy_dish_switch, int, 0444);
609MODULE_PARM_DESC(debug_legacy_dish_switch,
610 "Enable timing analysis for Dish Network legacy switches");
611
612module_param(debug, int, 0644);
613MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
614
615MODULE_DESCRIPTION("ST STV0288 DVB Demodulator driver");
616MODULE_AUTHOR("Georg Acher, Bob Liu, Igor liplianin");
617MODULE_LICENSE("GPL");
618
diff --git a/drivers/media/dvb/frontends/stv0288.h b/drivers/media/dvb/frontends/stv0288.h
new file mode 100644
index 000000000000..f2b53db0606d
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0288.h
@@ -0,0 +1,67 @@
1/*
2 Driver for ST STV0288 demodulator
3
4 Copyright (C) 2006 Georg Acher, BayCom GmbH, acher (at) baycom (dot) de
5 for Reel Multimedia
6 Copyright (C) 2008 TurboSight.com, <bob@turbosight.com>
7 Copyright (C) 2008 Igor M. Liplianin <liplianin@me.by>
8 Removed stb6000 specific tuner code and revised some
9 procedures.
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#ifndef STV0288_H
28#define STV0288_H
29
30#include <linux/dvb/frontend.h>
31#include "dvb_frontend.h"
32
33struct stv0288_config {
34 /* the demodulator's i2c address */
35 u8 demod_address;
36
37 u8* inittab;
38
39 /* minimum delay before retuning */
40 int min_delay_ms;
41
42 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
43};
44
45#if defined(CONFIG_DVB_STV0288) || (defined(CONFIG_DVB_STV0288_MODULE) && \
46 defined(MODULE))
47extern struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
48 struct i2c_adapter *i2c);
49#else
50static inline struct dvb_frontend *stv0288_attach(const struct stv0288_config *config,
51 struct i2c_adapter *i2c)
52{
53 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
54 return NULL;
55}
56#endif /* CONFIG_DVB_STV0288 */
57
58static inline int stv0288_writereg(struct dvb_frontend *fe, u8 reg, u8 val)
59{
60 int r = 0;
61 u8 buf[] = { reg, val };
62 if (fe->ops.write)
63 r = fe->ops.write(fe, buf, 2);
64 return r;
65}
66
67#endif /* STV0288_H */
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 35435bef8e79..6c1cb1973c6e 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -559,6 +559,8 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
559 int invval = 0; 559 int invval = 0;
560 560
561 dprintk ("%s : FE_SET_FRONTEND\n", __func__); 561 dprintk ("%s : FE_SET_FRONTEND\n", __func__);
562 if (state->config->set_ts_params)
563 state->config->set_ts_params(fe, 0);
562 564
563 // set the inversion 565 // set the inversion
564 if (p->inversion == INVERSION_OFF) invval = 0; 566 if (p->inversion == INVERSION_OFF) invval = 0;
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 3282f43022f5..0fd96e22b650 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -89,15 +89,18 @@ struct stv0299_config
89 int min_delay_ms; 89 int min_delay_ms;
90 90
91 /* Set the symbol rate */ 91 /* Set the symbol rate */
92 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); 92 int (*set_symbol_rate)(struct dvb_frontend *fe, u32 srate, u32 ratio);
93
94 /* Set device param to start dma */
95 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
93}; 96};
94 97
95#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE)) 98#if defined(CONFIG_DVB_STV0299) || (defined(CONFIG_DVB_STV0299_MODULE) && defined(MODULE))
96extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, 99extern struct dvb_frontend *stv0299_attach(const struct stv0299_config *config,
97 struct i2c_adapter* i2c); 100 struct i2c_adapter *i2c);
98#else 101#else
99static inline struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, 102static inline struct dvb_frontend *stv0299_attach(const struct stv0299_config *config,
100 struct i2c_adapter* i2c) 103 struct i2c_adapter *i2c)
101{ 104{
102 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 105 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
103 return NULL; 106 return NULL;
diff --git a/drivers/media/dvb/frontends/tdhd1.h b/drivers/media/dvb/frontends/tdhd1.h
new file mode 100644
index 000000000000..51f170678650
--- /dev/null
+++ b/drivers/media/dvb/frontends/tdhd1.h
@@ -0,0 +1,73 @@
1/*
2 * tdhd1.h - ALPS TDHD1-204A tuner support
3 *
4 * Copyright (C) 2008 Oliver Endriss <o.endriss@gmx.de>
5 *
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
21 *
22 *
23 * The project's page is at http://www.linuxtv.org
24 */
25
26#ifndef TDHD1_H
27#define TDHD1_H
28
29#include "tda1004x.h"
30
31static int alps_tdhd1_204_request_firmware(struct dvb_frontend *fe, const struct firmware **fw, char *name);
32
33static struct tda1004x_config alps_tdhd1_204a_config = {
34 .demod_address = 0x8,
35 .invert = 1,
36 .invert_oclk = 0,
37 .xtal_freq = TDA10046_XTAL_4M,
38 .agc_config = TDA10046_AGC_DEFAULT,
39 .if_freq = TDA10046_FREQ_3617,
40 .request_firmware = alps_tdhd1_204_request_firmware
41};
42
43static int alps_tdhd1_204a_tuner_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
44{
45 struct i2c_adapter *i2c = fe->tuner_priv;
46 u8 data[4];
47 struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
48 u32 div;
49
50 div = (params->frequency + 36166666) / 166666;
51
52 data[0] = (div >> 8) & 0x7f;
53 data[1] = div & 0xff;
54 data[2] = 0x85;
55
56 if (params->frequency >= 174000000 && params->frequency <= 230000000)
57 data[3] = 0x02;
58 else if (params->frequency >= 470000000 && params->frequency <= 823000000)
59 data[3] = 0x0C;
60 else if (params->frequency > 823000000 && params->frequency <= 862000000)
61 data[3] = 0x8C;
62 else
63 return -EINVAL;
64
65 if (fe->ops.i2c_gate_ctrl)
66 fe->ops.i2c_gate_ctrl(fe, 1);
67 if (i2c_transfer(i2c, &msg, 1) != 1)
68 return -EIO;
69
70 return 0;
71}
72
73#endif /* TDHD1_H */