aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-09-10 15:49:47 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:16:26 -0500
commit3a509bb11acded0dfebbfcc740d85e0774b0769a (patch)
tree41e1039c40447a902cc21f749a6e29663ad002bd
parent387c31c7e5c9805b0aef8833d1731a5fe7bdea14 (diff)
[media] Re-write the s921 frontend
On our tests with Leadership ISDBT, the s921 frontend were not work. As its design contained some weird things, it ended to be easier to just re-write it, getting another frontend as an example (cx24123). As the old s921 driver weren't used, there's no regression. Some info from the old frontend were used as a way to double check the behavior that were noticed on the USB dumps retrieved from Leadership driver. Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/dvb/frontends/Kconfig2
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/s921.c548
-rw-r--r--drivers/media/dvb/frontends/s921.h47
-rw-r--r--drivers/media/dvb/frontends/s921_core.c216
-rw-r--r--drivers/media/dvb/frontends/s921_core.h114
-rw-r--r--drivers/media/dvb/frontends/s921_module.c192
-rw-r--r--drivers/media/dvb/frontends/s921_module.h49
8 files changed, 596 insertions, 573 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 96b27016670e..00dbf1e488b8 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -497,7 +497,7 @@ comment "ISDB-T (terrestrial) frontends"
497 depends on DVB_CORE 497 depends on DVB_CORE
498 498
499config DVB_S921 499config DVB_S921
500 tristate "Sharp S921 tuner" 500 tristate "Sharp S921 frontend"
501 depends on DVB_CORE && I2C 501 depends on DVB_CORE && I2C
502 default m if DVB_FE_CUSTOMISE 502 default m if DVB_FE_CUSTOMISE
503 help 503 help
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 9a31985c0dfb..48b9fd356711 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -5,7 +5,6 @@
5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ 5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
6EXTRA_CFLAGS += -Idrivers/media/common/tuners/ 6EXTRA_CFLAGS += -Idrivers/media/common/tuners/
7 7
8s921-objs := s921_module.o s921_core.o
9stb0899-objs = stb0899_drv.o stb0899_algo.o 8stb0899-objs = stb0899_drv.o stb0899_algo.o
10stv0900-objs = stv0900_core.o stv0900_sw.o 9stv0900-objs = stv0900_core.o stv0900_sw.o
11au8522-objs = au8522_dig.o au8522_decoder.o 10au8522-objs = au8522_dig.o au8522_decoder.o
diff --git a/drivers/media/dvb/frontends/s921.c b/drivers/media/dvb/frontends/s921.c
new file mode 100644
index 000000000000..ca0103d5f148
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921.c
@@ -0,0 +1,548 @@
1/*
2 * Sharp VA3A5JZ921 One Seg Broadcast Module driver
3 * This device is labeled as just S. 921 at the top of the frontend can
4 *
5 * Copyright (C) 2009-2010 Mauro Carvalho Chehab <mchehab@redhat.com>
6 * Copyright (C) 2009-2010 Douglas Landgraf <dougsland@redhat.com>
7 *
8 * Developed for Leadership SBTVD 1seg device sold in Brazil
9 *
10 * Frontend module based on cx24123 driver, getting some info from
11 * the old s921 driver.
12 *
13 * FIXME: Need to port to DVB v5.2 API
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation version 2.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 */
24
25#include <linux/kernel.h>
26#include <asm/div64.h>
27
28#include "dvb_frontend.h"
29#include "s921.h"
30
31static int debug = 1;
32module_param(debug, int, 0644);
33MODULE_PARM_DESC(debug, "Activates frontend debugging (default:0)");
34
35#define rc(args...) do { \
36 printk(KERN_ERR "s921: " args); \
37} while (0)
38
39#define dprintk(args...) \
40 do { \
41 if (debug) { \
42 printk(KERN_DEBUG "s921: %s: ", __func__); \
43 printk(args); \
44 } \
45 } while (0)
46
47struct s921_state {
48 struct i2c_adapter *i2c;
49 const struct s921_config *config;
50
51 struct dvb_frontend frontend;
52
53 /* The Demod can't easily provide these, we cache them */
54 u32 currentfreq;
55};
56
57/*
58 * Various tuner defaults need to be established for a given frequency kHz.
59 * fixme: The bounds on the bands do not match the doc in real life.
60 * fixme: Some of them have been moved, other might need adjustment.
61 */
62static struct s921_bandselect_val {
63 u32 freq_low;
64 u8 band_reg;
65} s921_bandselect[] = {
66 { 0, 0x7b },
67 { 485140000, 0x5b },
68 { 515140000, 0x3b },
69 { 545140000, 0x1b },
70 { 599140000, 0xfb },
71 { 623140000, 0xdb },
72 { 659140000, 0xbb },
73 { 713140000, 0x9b },
74};
75
76struct regdata {
77 u8 reg;
78 u8 data;
79};
80
81static struct regdata s921_init[] = {
82 { 0x01, 0x80 }, /* Probably, a reset sequence */
83 { 0x01, 0x40 },
84 { 0x01, 0x80 },
85 { 0x01, 0x40 },
86
87 { 0x02, 0x00 },
88 { 0x03, 0x40 },
89 { 0x04, 0x01 },
90 { 0x05, 0x00 },
91 { 0x06, 0x00 },
92 { 0x07, 0x00 },
93 { 0x08, 0x00 },
94 { 0x09, 0x00 },
95 { 0x0a, 0x00 },
96 { 0x0b, 0x5a },
97 { 0x0c, 0x00 },
98 { 0x0d, 0x00 },
99 { 0x0f, 0x00 },
100 { 0x13, 0x1b },
101 { 0x14, 0x80 },
102 { 0x15, 0x40 },
103 { 0x17, 0x70 },
104 { 0x18, 0x01 },
105 { 0x19, 0x12 },
106 { 0x1a, 0x01 },
107 { 0x1b, 0x12 },
108 { 0x1c, 0xa0 },
109 { 0x1d, 0x00 },
110 { 0x1e, 0x0a },
111 { 0x1f, 0x08 },
112 { 0x20, 0x40 },
113 { 0x21, 0xff },
114 { 0x22, 0x4c },
115 { 0x23, 0x4e },
116 { 0x24, 0x4c },
117 { 0x25, 0x00 },
118 { 0x26, 0x00 },
119 { 0x27, 0xf4 },
120 { 0x28, 0x60 },
121 { 0x29, 0x88 },
122 { 0x2a, 0x40 },
123 { 0x2b, 0x40 },
124 { 0x2c, 0xff },
125 { 0x2d, 0x00 },
126 { 0x2e, 0xff },
127 { 0x2f, 0x00 },
128 { 0x30, 0x20 },
129 { 0x31, 0x06 },
130 { 0x32, 0x0c },
131 { 0x34, 0x0f },
132 { 0x37, 0xfe },
133 { 0x38, 0x00 },
134 { 0x39, 0x63 },
135 { 0x3a, 0x10 },
136 { 0x3b, 0x10 },
137 { 0x47, 0x00 },
138 { 0x49, 0xe5 },
139 { 0x4b, 0x00 },
140 { 0x50, 0xc0 },
141 { 0x52, 0x20 },
142 { 0x54, 0x5a },
143 { 0x55, 0x5b },
144 { 0x56, 0x40 },
145 { 0x57, 0x70 },
146 { 0x5c, 0x50 },
147 { 0x5d, 0x00 },
148 { 0x62, 0x17 },
149 { 0x63, 0x2f },
150 { 0x64, 0x6f },
151 { 0x68, 0x00 },
152 { 0x69, 0x89 },
153 { 0x6a, 0x00 },
154 { 0x6b, 0x00 },
155 { 0x6c, 0x00 },
156 { 0x6d, 0x00 },
157 { 0x6e, 0x00 },
158 { 0x70, 0x10 },
159 { 0x71, 0x00 },
160 { 0x75, 0x00 },
161 { 0x76, 0x30 },
162 { 0x77, 0x01 },
163 { 0xaf, 0x00 },
164 { 0xb0, 0xa0 },
165 { 0xb2, 0x3d },
166 { 0xb3, 0x25 },
167 { 0xb4, 0x8b },
168 { 0xb5, 0x4b },
169 { 0xb6, 0x3f },
170 { 0xb7, 0xff },
171 { 0xb8, 0xff },
172 { 0xb9, 0xfc },
173 { 0xba, 0x00 },
174 { 0xbb, 0x00 },
175 { 0xbc, 0x00 },
176 { 0xd0, 0x30 },
177 { 0xe4, 0x84 },
178 { 0xf0, 0x48 },
179 { 0xf1, 0x19 },
180 { 0xf2, 0x5a },
181 { 0xf3, 0x8e },
182 { 0xf4, 0x2d },
183 { 0xf5, 0x07 },
184 { 0xf6, 0x5a },
185 { 0xf7, 0xba },
186 { 0xf8, 0xd7 },
187};
188
189static struct regdata s921_prefreq[] = {
190 { 0x47, 0x60 },
191 { 0x68, 0x00 },
192 { 0x69, 0x89 },
193 { 0xf0, 0x48 },
194 { 0xf1, 0x19 },
195};
196
197static struct regdata s921_postfreq[] = {
198 { 0xf5, 0xae },
199 { 0xf6, 0xb7 },
200 { 0xf7, 0xba },
201 { 0xf8, 0xd7 },
202 { 0x68, 0x0a },
203 { 0x69, 0x09 },
204};
205
206static int s921_i2c_writereg(struct s921_state *state,
207 u8 i2c_addr, int reg, int data)
208{
209 u8 buf[] = { reg, data };
210 struct i2c_msg msg = {
211 .addr = i2c_addr, .flags = 0, .buf = buf, .len = 2
212 };
213 int rc;
214
215 rc = i2c_transfer(state->i2c, &msg, 1);
216 if (rc != 1) {
217 printk("%s: writereg rcor(rc == %i, reg == 0x%02x,"
218 " data == 0x%02x)\n", __func__, rc, reg, data);
219 return rc;
220 }
221
222 return 0;
223}
224
225static int s921_i2c_writeregdata(struct s921_state *state, u8 i2c_addr,
226 struct regdata *rd, int size)
227{
228 int i, rc;
229
230 for (i = 0; i < size; i++) {
231 rc = s921_i2c_writereg(state, i2c_addr, rd[i].reg, rd[i].data);
232 if (rc < 0)
233 return rc;
234 }
235 return 0;
236}
237
238static int s921_i2c_readreg(struct s921_state *state, u8 i2c_addr, u8 reg)
239{
240 u8 val;
241 int rc;
242 struct i2c_msg msg[] = {
243 { .addr = i2c_addr, .flags = 0, .buf = &reg, .len = 1 },
244 { .addr = i2c_addr, .flags = I2C_M_RD, .buf = &val, .len = 1 }
245 };
246
247 rc = i2c_transfer(state->i2c, msg, 2);
248
249 if (rc != 2) {
250 rc("%s: reg=0x%x (rcor=%d)\n", __func__, reg, rc);
251 return rc;
252 }
253
254 return val;
255}
256
257#define s921_readreg(state, reg) \
258 s921_i2c_readreg(state, state->config->demod_address, reg)
259#define s921_writereg(state, reg, val) \
260 s921_i2c_writereg(state, state->config->demod_address, reg, val)
261#define s921_writeregdata(state, regdata) \
262 s921_i2c_writeregdata(state, state->config->demod_address, \
263 regdata, ARRAY_SIZE(regdata))
264
265static int s921_pll_tune(struct dvb_frontend *fe,
266 struct dvb_frontend_parameters *p)
267{
268 struct s921_state *state = fe->demodulator_priv;
269 int band, rc, i;
270 unsigned long f_offset;
271 u8 f_switch;
272 u64 offset;
273
274 dprintk("frequency=%i\n", p->frequency);
275
276 for (band = 0; band < ARRAY_SIZE(s921_bandselect); band++)
277 if (p->frequency < s921_bandselect[band].freq_low)
278 break;
279 band--;
280
281 if (band < 0) {
282 rc("%s: frequency out of range\n", __func__);
283 return -EINVAL;
284 }
285
286 f_switch = s921_bandselect[band].band_reg;
287
288 offset = ((u64)p->frequency) * 258;
289 do_div(offset, 6000000);
290 f_offset = ((unsigned long)offset) + 2321;
291
292 rc = s921_writeregdata(state, s921_prefreq);
293 if (rc < 0)
294 return rc;
295
296 rc = s921_writereg(state, 0xf2, (f_offset >> 8) & 0xff);
297 if (rc < 0)
298 return rc;
299
300 rc = s921_writereg(state, 0xf3, f_offset & 0xff);
301 if (rc < 0)
302 return rc;
303
304 rc = s921_writereg(state, 0xf4, f_switch);
305 if (rc < 0)
306 return rc;
307
308 rc = s921_writeregdata(state, s921_postfreq);
309 if (rc < 0)
310 return rc;
311
312 for (i = 0 ; i < 6; i++) {
313 rc = s921_readreg(state, 0x80);
314 dprintk("status 0x80: %02x\n", rc);
315 }
316 rc = s921_writereg(state, 0x01, 0x40);
317 if (rc < 0)
318 return rc;
319
320 rc = s921_readreg(state, 0x01);
321 dprintk("status 0x01: %02x\n", rc);
322
323 rc = s921_readreg(state, 0x80);
324 dprintk("status 0x80: %02x\n", rc);
325
326 rc = s921_readreg(state, 0x80);
327 dprintk("status 0x80: %02x\n", rc);
328
329 rc = s921_readreg(state, 0x32);
330 dprintk("status 0x32: %02x\n", rc);
331
332 dprintk("pll tune band=%d, pll=%d\n", f_switch, (int)f_offset);
333
334 return 0;
335}
336
337static int s921_initfe(struct dvb_frontend *fe)
338{
339 struct s921_state *state = fe->demodulator_priv;
340 int rc;
341
342 dprintk("\n");
343
344 rc = s921_writeregdata(state, s921_init);
345 if (rc < 0)
346 return rc;
347
348 return 0;
349}
350
351static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
352{
353 struct s921_state *state = fe->demodulator_priv;
354 int regstatus, rc;
355
356 *status = 0;
357
358 rc = s921_readreg(state, 0x81);
359 if (rc < 0)
360 return rc;
361
362 regstatus = rc << 8;
363
364 rc = s921_readreg(state, 0x82);
365 if (rc < 0)
366 return rc;
367
368 regstatus |= rc;
369
370 dprintk("status = %04x\n", regstatus);
371
372 /* Full Sync - We don't know what each bit means on regs 0x81/0x82 */
373 if ((regstatus & 0xff) == 0x40) {
374 *status = FE_HAS_SIGNAL |
375 FE_HAS_CARRIER |
376 FE_HAS_VITERBI |
377 FE_HAS_SYNC |
378 FE_HAS_LOCK;
379 } else if (regstatus & 0x40) {
380 /* This is close to Full Sync, but not enough to get useful info */
381 *status = FE_HAS_SIGNAL |
382 FE_HAS_CARRIER |
383 FE_HAS_VITERBI |
384 FE_HAS_SYNC;
385 }
386
387 return 0;
388}
389
390static int s921_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
391{
392 fe_status_t status;
393 struct s921_state *state = fe->demodulator_priv;
394 int rc;
395
396 /* FIXME: Use the proper register for it... 0x80? */
397 rc = s921_read_status(fe, &status);
398 if (rc < 0)
399 return rc;
400
401 *strength = (status & FE_HAS_LOCK) ? 0xffff : 0;
402
403 dprintk("strength = 0x%04x\n", *strength);
404
405 rc = s921_readreg(state, 0x01);
406 dprintk("status 0x01: %02x\n", rc);
407
408 rc = s921_readreg(state, 0x80);
409 dprintk("status 0x80: %02x\n", rc);
410
411 rc = s921_readreg(state, 0x32);
412 dprintk("status 0x32: %02x\n", rc);
413
414 return 0;
415}
416
417static int s921_set_frontend(struct dvb_frontend *fe,
418 struct dvb_frontend_parameters *p)
419{
420 struct s921_state *state = fe->demodulator_priv;
421 int rc;
422
423 dprintk("\n");
424
425 /* FIXME: We don't know how to use non-auto mode */
426
427 rc = s921_pll_tune(fe, p);
428 if (rc < 0)
429 return rc;
430
431 state->currentfreq = p->frequency;
432
433 return 0;
434}
435
436static int s921_get_frontend(struct dvb_frontend *fe,
437 struct dvb_frontend_parameters *p)
438{
439 struct s921_state *state = fe->demodulator_priv;
440
441 /* FIXME: Probably it is possible to get it from regs f1 and f2 */
442 p->frequency = state->currentfreq;
443
444 return 0;
445}
446
447static int s921_tune(struct dvb_frontend *fe,
448 struct dvb_frontend_parameters *params,
449 unsigned int mode_flags,
450 unsigned int *delay,
451 fe_status_t *status)
452{
453 int rc = 0;
454
455 dprintk("\n");
456
457 if (params != NULL)
458 rc = s921_set_frontend(fe, params);
459
460 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
461 s921_read_status(fe, status);
462
463 return rc;
464}
465
466static int s921_get_algo(struct dvb_frontend *fe)
467{
468 return 1; /* FE_ALGO_HW */
469}
470
471static void s921_release(struct dvb_frontend *fe)
472{
473 struct s921_state *state = fe->demodulator_priv;
474
475 dprintk("\n");
476 kfree(state);
477}
478
479static struct dvb_frontend_ops s921_ops;
480
481struct dvb_frontend *s921_attach(const struct s921_config *config,
482 struct i2c_adapter *i2c)
483{
484 /* allocate memory for the internal state */
485 struct s921_state *state =
486 kzalloc(sizeof(struct s921_state), GFP_KERNEL);
487
488 dprintk("\n");
489 if (state == NULL) {
490 rc("Unable to kzalloc\n");
491 goto rcor;
492 }
493
494 /* setup the state */
495 state->config = config;
496 state->i2c = i2c;
497
498 /* create dvb_frontend */
499 memcpy(&state->frontend.ops, &s921_ops,
500 sizeof(struct dvb_frontend_ops));
501 state->frontend.demodulator_priv = state;
502
503 return &state->frontend;
504
505rcor:
506 kfree(state);
507
508 return NULL;
509}
510EXPORT_SYMBOL(s921_attach);
511
512static struct dvb_frontend_ops s921_ops = {
513 /* Use dib8000 values per default */
514 .info = {
515 .name = "Sharp S921",
516 .type = FE_OFDM,
517 .frequency_min = 470000000,
518 /*
519 * Max should be 770MHz instead, according with Sharp docs,
520 * but Leadership doc says it works up to 806 MHz. This is
521 * required to get channel 69, used in Brazil
522 */
523 .frequency_max = 806000000,
524 .frequency_tolerance = 0,
525 .caps = FE_CAN_INVERSION_AUTO |
526 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
527 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
528 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
529 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
530 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER |
531 FE_CAN_HIERARCHY_AUTO,
532 },
533
534 .release = s921_release,
535
536 .init = s921_initfe,
537 .set_frontend = s921_set_frontend,
538 .get_frontend = s921_get_frontend,
539 .read_status = s921_read_status,
540 .read_signal_strength = s921_read_signal_strength,
541 .tune = s921_tune,
542 .get_frontend_algo = s921_get_algo,
543};
544
545MODULE_DESCRIPTION("DVB Frontend module for Sharp S921 hardware");
546MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
547MODULE_AUTHOR("Douglas Landgraf <dougsland@redhat.com>");
548MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s921.h b/drivers/media/dvb/frontends/s921.h
new file mode 100644
index 000000000000..f220d8299c81
--- /dev/null
+++ b/drivers/media/dvb/frontends/s921.h
@@ -0,0 +1,47 @@
1/*
2 * Sharp s921 driver
3 *
4 * Copyright (C) 2009 Mauro Carvalho Chehab <mchehab@redhat.com>
5 * Copyright (C) 2009 Douglas Landgraf <dougsland@redhat.com>
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 as
9 * published by the Free Software Foundation version 2.
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 GNU
14 * General Public License for more details.
15 */
16
17#ifndef S921_H
18#define S921_H
19
20#include <linux/dvb/frontend.h>
21
22struct s921_config {
23 /* the demodulator's i2c address */
24 u8 demod_address;
25};
26
27#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) \
28 && defined(MODULE))
29extern struct dvb_frontend *s921_attach(const struct s921_config *config,
30 struct i2c_adapter *i2c);
31extern struct i2c_adapter *s921_get_tuner_i2c_adapter(struct dvb_frontend *);
32#else
33static inline struct dvb_frontend *s921_attach(
34 const struct s921_config *config, struct i2c_adapter *i2c)
35{
36 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
37 return NULL;
38}
39static struct i2c_adapter *
40 s921_get_tuner_i2c_adapter(struct dvb_frontend *fe)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
43 return NULL;
44}
45#endif
46
47#endif /* S921_H */
diff --git a/drivers/media/dvb/frontends/s921_core.c b/drivers/media/dvb/frontends/s921_core.c
deleted file mode 100644
index 974b52be9aea..000000000000
--- a/drivers/media/dvb/frontends/s921_core.c
+++ /dev/null
@@ -1,216 +0,0 @@
1/*
2 * Driver for Sharp s921 driver
3 *
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
5 *
6 */
7
8
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/delay.h>
12#include "s921_core.h"
13
14static int s921_isdb_init(struct s921_isdb_t *dev);
15static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params);
16static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params);
17static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data);
18
19static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01,
20 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00,
21 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00,
22 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80,
23 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12,
24 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00,
25 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff,
26 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00,
27 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88,
28 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00,
29 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06,
30 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00,
31 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00,
32 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20,
33 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70,
34 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f,
35 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00,
36 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00,
37 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30,
38 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d,
39 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f,
40 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00,
41 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84,
42 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e,
43 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba,
44 0xf8, 0xd7 };
45
46static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b,
47 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b,
48 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b,
49 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b,
50 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b,
51 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b,
52 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b,
53 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb,
54 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb,
55 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb,
56 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb,
57 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb,
58 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb,
59 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b,
60 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b,
61 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b,
62 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b };
63
64int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) {
65 switch(cmd) {
66 case ISDB_T_CMD_INIT:
67 s921_isdb_init(dev);
68 break;
69 case ISDB_T_CMD_SET_PARAM:
70 s921_isdb_set_parameters(dev, data);
71 break;
72 case ISDB_T_CMD_TUNE:
73 s921_isdb_tune(dev, data);
74 break;
75 case ISDB_T_CMD_GET_STATUS:
76 s921_isdb_get_status(dev, data);
77 break;
78 default:
79 printk("unhandled command\n");
80 return -EINVAL;
81 }
82 return 0;
83}
84
85static int s921_isdb_init(struct s921_isdb_t *dev) {
86 unsigned int i;
87 unsigned int ret;
88 printk("isdb_init\n");
89 for (i = 0; i < sizeof(init_table); i+=2) {
90 ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]);
91 if (ret != 0) {
92 printk("i2c write failed\n");
93 return ret;
94 }
95 }
96 return 0;
97}
98
99static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) {
100
101 int ret;
102 /* auto is sufficient for now, lateron this should be reflected in an extra interface */
103
104
105
106 ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2);
107 ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2);
108
109 if (ret < 0)
110 return -EINVAL;
111
112 ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3);
113 if (ret < 0)
114 return -EINVAL;
115
116 ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4);
117 if (ret < 0)
118 return -EINVAL;
119
120 ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5);
121 if (ret < 0)
122 return -EINVAL;
123
124 ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6);
125 if (ret < 0)
126 return -EINVAL;
127
128 ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7);
129 if (ret < 0)
130 return -EINVAL;
131
132 return E_OK;
133}
134
135static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) {
136
137 int ret;
138 int index;
139
140 index = (params->frequency - 473143000)/6000000;
141
142 if (index > 48) {
143 return -EINVAL;
144 }
145
146 dev->i2c_write(dev->priv_dev, 0x47, 0x60);
147
148 ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00);
149 if (ret < 0)
150 return -EINVAL;
151
152 ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89);
153 if (ret < 0)
154 return -EINVAL;
155
156 ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48);
157 if (ret < 0)
158 return -EINVAL;
159
160 ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19);
161 if (ret < 0)
162 return -EINVAL;
163
164 ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]);
165 if (ret < 0)
166 return -EINVAL;
167
168 ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]);
169 if (ret < 0)
170 return -EINVAL;
171
172 ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]);
173 if (ret < 0)
174 return -EINVAL;
175
176 ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae);
177 if (ret < 0)
178 return -EINVAL;
179
180 ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7);
181 if (ret < 0)
182 return -EINVAL;
183
184 ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba);
185 if (ret < 0)
186 return -EINVAL;
187
188 ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7);
189 if (ret < 0)
190 return -EINVAL;
191
192 ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a);
193 if (ret < 0)
194 return -EINVAL;
195
196 ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09);
197 if (ret < 0)
198 return -EINVAL;
199
200 dev->i2c_write(dev->priv_dev, 0x01, 0x40);
201 return 0;
202}
203
204static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) {
205 unsigned int *ret = (unsigned int*)data;
206 u8 ifagc_dt;
207 u8 rfagc_dt;
208
209 mdelay(10);
210 ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81);
211 rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82);
212 if (rfagc_dt == 0x40) {
213 *ret = 1;
214 }
215 return 0;
216}
diff --git a/drivers/media/dvb/frontends/s921_core.h b/drivers/media/dvb/frontends/s921_core.h
deleted file mode 100644
index de2f10a44e72..000000000000
--- a/drivers/media/dvb/frontends/s921_core.h
+++ /dev/null
@@ -1,114 +0,0 @@
1#ifndef _S921_CORE_H
2#define _S921_CORE_H
3//#define u8 unsigned int
4//#define u32 unsigned int
5
6
7
8//#define EINVAL -1
9#define E_OK 0
10
11struct s921_isdb_t {
12 void *priv_dev;
13 int (*i2c_write)(void *dev, u8 reg, u8 val);
14 int (*i2c_read)(void *dev, u8 reg);
15};
16
17#define ISDB_T_CMD_INIT 0
18#define ISDB_T_CMD_SET_PARAM 1
19#define ISDB_T_CMD_TUNE 2
20#define ISDB_T_CMD_GET_STATUS 3
21
22struct s921_isdb_t_tune_params {
23 u32 frequency;
24};
25
26struct s921_isdb_t_status {
27};
28
29struct s921_isdb_t_transmission_mode_params {
30 u8 mode;
31 u8 layer_a_mode;
32#define ISDB_T_LA_MODE_1 0
33#define ISDB_T_LA_MODE_2 1
34#define ISDB_T_LA_MODE_3 2
35 u8 layer_a_carrier_modulation;
36#define ISDB_T_LA_CM_DQPSK 0
37#define ISDB_T_LA_CM_QPSK 1
38#define ISDB_T_LA_CM_16QAM 2
39#define ISDB_T_LA_CM_64QAM 3
40#define ISDB_T_LA_CM_NOLAYER 4
41 u8 layer_a_code_rate;
42#define ISDB_T_LA_CR_1_2 0
43#define ISDB_T_LA_CR_2_3 1
44#define ISDB_T_LA_CR_3_4 2
45#define ISDB_T_LA_CR_5_6 4
46#define ISDB_T_LA_CR_7_8 8
47#define ISDB_T_LA_CR_NOLAYER 16
48 u8 layer_a_time_interleave;
49#define ISDB_T_LA_TI_0 0
50#define ISDB_T_LA_TI_1 1
51#define ISDB_T_LA_TI_2 2
52#define ISDB_T_LA_TI_4 4
53#define ISDB_T_LA_TI_8 8
54#define ISDB_T_LA_TI_16 16
55#define ISDB_T_LA_TI_32 32
56 u8 layer_a_nseg;
57
58 u8 layer_b_mode;
59#define ISDB_T_LB_MODE_1 0
60#define ISDB_T_LB_MODE_2 1
61#define ISDB_T_LB_MODE_3 2
62 u8 layer_b_carrier_modulation;
63#define ISDB_T_LB_CM_DQPSK 0
64#define ISDB_T_LB_CM_QPSK 1
65#define ISDB_T_LB_CM_16QAM 2
66#define ISDB_T_LB_CM_64QAM 3
67#define ISDB_T_LB_CM_NOLAYER 4
68 u8 layer_b_code_rate;
69#define ISDB_T_LB_CR_1_2 0
70#define ISDB_T_LB_CR_2_3 1
71#define ISDB_T_LB_CR_3_4 2
72#define ISDB_T_LB_CR_5_6 4
73#define ISDB_T_LB_CR_7_8 8
74#define ISDB_T_LB_CR_NOLAYER 16
75 u8 layer_b_time_interleave;
76#define ISDB_T_LB_TI_0 0
77#define ISDB_T_LB_TI_1 1
78#define ISDB_T_LB_TI_2 2
79#define ISDB_T_LB_TI_4 4
80#define ISDB_T_LB_TI_8 8
81#define ISDB_T_LB_TI_16 16
82#define ISDB_T_LB_TI_32 32
83 u8 layer_b_nseg;
84
85 u8 layer_c_mode;
86#define ISDB_T_LC_MODE_1 0
87#define ISDB_T_LC_MODE_2 1
88#define ISDB_T_LC_MODE_3 2
89 u8 layer_c_carrier_modulation;
90#define ISDB_T_LC_CM_DQPSK 0
91#define ISDB_T_LC_CM_QPSK 1
92#define ISDB_T_LC_CM_16QAM 2
93#define ISDB_T_LC_CM_64QAM 3
94#define ISDB_T_LC_CM_NOLAYER 4
95 u8 layer_c_code_rate;
96#define ISDB_T_LC_CR_1_2 0
97#define ISDB_T_LC_CR_2_3 1
98#define ISDB_T_LC_CR_3_4 2
99#define ISDB_T_LC_CR_5_6 4
100#define ISDB_T_LC_CR_7_8 8
101#define ISDB_T_LC_CR_NOLAYER 16
102 u8 layer_c_time_interleave;
103#define ISDB_T_LC_TI_0 0
104#define ISDB_T_LC_TI_1 1
105#define ISDB_T_LC_TI_2 2
106#define ISDB_T_LC_TI_4 4
107#define ISDB_T_LC_TI_8 8
108#define ISDB_T_LC_TI_16 16
109#define ISDB_T_LC_TI_32 32
110 u8 layer_c_nseg;
111};
112
113int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
114#endif
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
deleted file mode 100644
index 0eefff61cc50..000000000000
--- a/drivers/media/dvb/frontends/s921_module.c
+++ /dev/null
@@ -1,192 +0,0 @@
1/*
2 * Driver for Sharp s921 driver
3 *
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
5 *
6 * All rights reserved.
7 *
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/delay.h>
14#include "dvb_frontend.h"
15#include "s921_module.h"
16#include "s921_core.h"
17
18static unsigned int debug = 0;
19module_param(debug, int, 0644);
20MODULE_PARM_DESC(debug,"s921 debugging (default off)");
21
22#define dprintk(fmt, args...) if (debug) do {\
23 printk("s921 debug: " fmt, ##args); } while (0)
24
25struct s921_state
26{
27 struct dvb_frontend frontend;
28 fe_modulation_t current_modulation;
29 __u32 snr;
30 __u32 current_frequency;
31 __u8 addr;
32 struct s921_isdb_t dev;
33 struct i2c_adapter *i2c;
34};
35
36static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
37 struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
38 struct s921_isdb_t_transmission_mode_params params;
39 struct s921_isdb_t_tune_params tune_params;
40
41 tune_params.frequency = param->frequency;
42 s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, &params);
43 s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params);
44 mdelay(100);
45 return 0;
46}
47
48static int s921_init(struct dvb_frontend *fe) {
49 printk("s921 init\n");
50 return 0;
51}
52
53static int s921_sleep(struct dvb_frontend *fe) {
54 printk("s921 sleep\n");
55 return 0;
56}
57
58static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status)
59{
60 struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
61 unsigned int ret;
62 mdelay(5);
63 s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret);
64 *status = 0;
65
66 printk("status: %02x\n", ret);
67 if (ret == 1) {
68 *status |= FE_HAS_CARRIER;
69 *status |= FE_HAS_VITERBI;
70 *status |= FE_HAS_LOCK;
71 *status |= FE_HAS_SYNC;
72 *status |= FE_HAS_SIGNAL;
73 }
74
75 return 0;
76}
77
78static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber)
79{
80 dprintk("read ber\n");
81 return 0;
82}
83
84static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr)
85{
86 dprintk("read snr\n");
87 return 0;
88}
89
90static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
91{
92 dprintk("read ucblocks\n");
93 return 0;
94}
95
96static void s921_release(struct dvb_frontend *fe)
97{
98 struct s921_state *state = (struct s921_state *)fe->demodulator_priv;
99 kfree(state);
100}
101
102static struct dvb_frontend_ops demod_s921={
103 .info = {
104 .name = "SHARP S921",
105 .type = FE_OFDM,
106 .frequency_min = 473143000,
107 .frequency_max = 767143000,
108 .frequency_stepsize = 6000000,
109 .frequency_tolerance = 0,
110 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
111 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
112 FE_CAN_FEC_AUTO |
113 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
114 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
115 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER |
116 FE_CAN_MUTE_TS
117 },
118 .init = s921_init,
119 .sleep = s921_sleep,
120 .set_frontend = s921_set_parameters,
121 .read_snr = s921_read_snr,
122 .read_ber = s921_read_ber,
123 .read_status = s921_read_status,
124 .read_ucblocks = s921_read_ucblocks,
125 .release = s921_release,
126};
127
128static int s921_write(void *dev, u8 reg, u8 val) {
129 struct s921_state *state = dev;
130 char buf[2]={reg,val};
131 int err;
132 struct i2c_msg i2cmsgs = {
133 .addr = state->addr,
134 .flags = 0,
135 .len = 2,
136 .buf = buf
137 };
138
139 if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
140 printk("%s i2c_transfer error %d\n", __func__, err);
141 if (err < 0)
142 return err;
143 else
144 return -EREMOTEIO;
145 }
146
147 return 0;
148}
149
150static int s921_read(void *dev, u8 reg) {
151 struct s921_state *state = dev;
152 u8 b1;
153 int ret;
154 struct i2c_msg msg[2] = { { .addr = state->addr,
155 .flags = 0,
156 .buf = &reg, .len = 1 },
157 { .addr = state->addr,
158 .flags = I2C_M_RD,
159 .buf = &b1, .len = 1 } };
160
161 ret = i2c_transfer(state->i2c, msg, 2);
162 if (ret != 2)
163 return ret;
164 return b1;
165}
166
167struct dvb_frontend* s921_attach(const struct s921_config *config,
168 struct i2c_adapter *i2c)
169{
170
171 struct s921_state *state;
172 state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
173 if (state == NULL)
174 return NULL;
175
176 state->addr = config->i2c_address;
177 state->i2c = i2c;
178 state->dev.i2c_write = &s921_write;
179 state->dev.i2c_read = &s921_read;
180 state->dev.priv_dev = state;
181
182 s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL);
183
184 memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops));
185 state->frontend.demodulator_priv = state;
186 return &state->frontend;
187}
188
189EXPORT_SYMBOL_GPL(s921_attach);
190MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
191MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg");
192MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/s921_module.h b/drivers/media/dvb/frontends/s921_module.h
deleted file mode 100644
index 78660424ba95..000000000000
--- a/drivers/media/dvb/frontends/s921_module.h
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * Driver for DVB-T s921 demodulator
3 *
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
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#ifndef S921_MODULE_H
23#define S921_MODULE_H
24
25#include <linux/dvb/frontend.h>
26#include "s921_core.h"
27
28int s921_isdb_init(struct s921_isdb_t *dev);
29int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data);
30
31struct s921_config
32{
33 /* demodulator's I2C address */
34 u8 i2c_address;
35};
36
37#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE))
38extern struct dvb_frontend* s921_attach(const struct s921_config *config,
39 struct i2c_adapter *i2c);
40#else
41static inline struct dvb_frontend* s921_attach(const struct s921_config *config,
42 struct i2c_adapter *i2c)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL;
46}
47#endif /* CONFIG_DVB_S921 */
48
49#endif /* S921_H */