ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / media / dvb / frontends / grundig_29504-491.c
1 /* 
2     Driver for Grundig 29504-491, a Philips TDA8083 based QPSK Frontend
3
4     Copyright (C) 2001 Convergence Integrated Media GmbH
5
6     written by Ralph Metzler <ralph@convergence.de>
7
8     adoption to the new DVB frontend API and diagnostic ioctl's
9     by Holger Waechtler <holger@convergence.de>
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 #include <linux/init.h>
28 #include <linux/kernel.h>
29 #include <linux/module.h>
30 #include <linux/string.h>
31 #include <linux/slab.h>
32
33 #include "dvb_frontend.h"
34 #include "dvb_functions.h"
35
36 static int debug = 0;
37 #define dprintk if (debug) printk
38
39
40 static struct dvb_frontend_info grundig_29504_491_info = {
41         .name                   = "Grundig 29504-491, (TDA8083 based)",
42         .type                   = FE_QPSK,
43         .frequency_min          = 950000,     /* FIXME: guessed! */
44         .frequency_max          = 1400000,    /* FIXME: guessed! */
45         .frequency_stepsize     = 125,   /* kHz for QPSK frontends */
46 /*      .frequency_tolerance    = ???,*/
47         .symbol_rate_min        = 1000000,   /* FIXME: guessed! */
48         .symbol_rate_max        = 45000000,  /* FIXME: guessed! */
49 /*      .symbol_rate_tolerance  = ???,*/
50         .notifier_delay         = 0,
51         .caps = FE_CAN_INVERSION_AUTO |
52                 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
53                 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
54                 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
55                 FE_CAN_QPSK | FE_CAN_MUTE_TS
56 };
57
58
59
60 static u8 tda8083_init_tab [] = {
61         0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
62         0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
63         0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
64         0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
65         0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
66         0x00, 0x00, 0x00, 0x00
67 };
68
69
70
71 static int tda8083_writereg (struct dvb_i2c_bus *i2c, u8 reg, u8 data)
72 {
73         int ret;
74         u8 buf [] = { reg, data };
75         struct i2c_msg msg = { .addr = 0x68, .flags = 0, .buf = buf, .len = 2 };
76
77         ret = i2c->xfer (i2c, &msg, 1);
78
79         if (ret != 1)
80                 dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
81                         __FUNCTION__, reg, ret);
82
83         return (ret != 1) ? -1 : 0;
84 }
85
86
87 static int tda8083_readregs (struct dvb_i2c_bus *i2c, u8 reg1, u8 *b, u8 len)
88 {
89         int ret;
90         struct i2c_msg msg [] = { { .addr = 0x68, .flags = 0, .buf = &reg1, .len = 1 },
91                            { .addr = 0x68, .flags = I2C_M_RD, .buf = b, .len = len } };
92
93         ret = i2c->xfer (i2c, msg, 2);
94
95         if (ret != 2)
96                 dprintk ("%s: readreg error (reg %02x, ret == %i)\n",
97                         __FUNCTION__, reg1, ret);
98
99         return ret == 2 ? 0 : -1;
100 }
101
102
103 static inline u8 tda8083_readreg (struct dvb_i2c_bus *i2c, u8 reg)
104 {
105         u8 val;
106
107         tda8083_readregs (i2c, reg, &val, 1);
108
109         return val;
110 }
111
112
113 static int tsa5522_write (struct dvb_i2c_bus *i2c, u8 data [4])
114 {
115         int ret;
116         struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = 4 };
117
118         ret = i2c->xfer (i2c, &msg, 1);
119
120         if (ret != 1)
121                 dprintk("%s: i/o error (ret == %i)\n", __FUNCTION__, ret);
122
123         return (ret != 1) ? -1 : 0;
124 }
125
126
127 /**
128  *   set up the downconverter frequency divisor for a
129  *   reference clock comparision frequency of 125 kHz.
130  */
131 static int tsa5522_set_tv_freq (struct dvb_i2c_bus *i2c, u32 freq)
132 {
133         u32 div = freq / 125;
134         u8 buf [4] = { (div >> 8) & 0x7f, div & 0xff, 0x8e, 0x00 };
135
136         return tsa5522_write (i2c, buf);
137 }
138
139
140 static int tda8083_init (struct dvb_i2c_bus *i2c)
141 {
142         int i;
143         
144         dprintk("%s: init TDA8083\n", __FILE__);
145
146         for (i=0; i<44; i++)
147                 tda8083_writereg (i2c, i, tda8083_init_tab[i]);
148
149         return 0;
150 }
151
152
153 static int tda8083_set_inversion (struct dvb_i2c_bus *i2c, fe_spectral_inversion_t inversion)
154 {
155         /*  XXX FIXME: implement other modes than FEC_AUTO */
156         if (inversion == INVERSION_AUTO)
157                 return 0;
158         
159         return -EINVAL;
160 }
161
162
163 static int tda8083_set_fec (struct dvb_i2c_bus *i2c, fe_code_rate_t fec)
164 {
165         if (fec == FEC_AUTO)
166                 return tda8083_writereg (i2c, 0x07, 0xff);
167
168         if (fec >= FEC_1_2 && fec <= FEC_8_9)
169                 return tda8083_writereg (i2c, 0x07, 1 << (FEC_8_9 - fec));
170
171         return -EINVAL;
172 }
173
174
175 static fe_code_rate_t tda8083_get_fec (struct dvb_i2c_bus *i2c)
176 {
177         u8 index;
178         static fe_code_rate_t fec_tab [] = { FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
179                                        FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8 };
180
181         index = tda8083_readreg(i2c, 0x0e) & 0x07;
182
183         return fec_tab [index];
184 }
185
186
187 static int tda8083_set_symbolrate (struct dvb_i2c_bus *i2c, u32 srate)
188 {
189         u32 ratio;
190         u32 tmp;
191         u8 filter;
192
193         if (srate > 32000000)
194                 srate = 32000000;
195         if (srate < 500000)
196                 srate = 500000;
197
198         filter = 0;
199         if (srate < 24000000)
200                 filter = 2;
201         if (srate < 16000000)
202                 filter = 3;
203
204         tmp = 31250 << 16;
205         ratio = tmp / srate;
206         
207         tmp = (tmp % srate) << 8;
208         ratio = (ratio << 8) + tmp / srate;
209         
210         tmp = (tmp % srate) << 8;
211         ratio = (ratio << 8) + tmp / srate;
212         
213         dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio);
214
215         tda8083_writereg (i2c, 0x05, filter);
216         tda8083_writereg (i2c, 0x02, (ratio >> 16) & 0xff);
217         tda8083_writereg (i2c, 0x03, (ratio >>  8) & 0xff);
218         tda8083_writereg (i2c, 0x04, (ratio      ) & 0xff);
219         
220         tda8083_writereg (i2c, 0x00, 0x3c);
221         tda8083_writereg (i2c, 0x00, 0x04);
222
223         return 1;
224 }
225
226
227 static void tda8083_wait_diseqc_fifo (struct dvb_i2c_bus *i2c, int timeout)
228 {
229         unsigned long start = jiffies;
230
231         while (jiffies - start < timeout &&
232                !(tda8083_readreg(i2c, 0x02) & 0x80))
233         {
234                 dvb_delay(50);
235         };
236 }
237
238
239 static int tda8083_send_diseqc_msg (struct dvb_i2c_bus *i2c,
240                              struct dvb_diseqc_master_cmd *m)
241 {
242         int i;
243
244         tda8083_writereg (i2c, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */
245
246         for (i=0; i<m->msg_len; i++)
247                 tda8083_writereg (i2c, 0x23 + i, m->msg[i]);
248
249         tda8083_writereg (i2c, 0x29, (m->msg_len - 3) | (3 << 2)); /* send!! */
250
251         tda8083_wait_diseqc_fifo (i2c, 100);
252
253         return 0;
254 }
255
256
257 static int tda8083_send_diseqc_burst (struct dvb_i2c_bus *i2c, fe_sec_mini_cmd_t burst)
258 {
259         switch (burst) {
260         case SEC_MINI_A:
261                 tda8083_writereg (i2c, 0x29, (5 << 2));  /* send burst A */
262                 break;
263         case SEC_MINI_B:
264                 tda8083_writereg (i2c, 0x29, (7 << 2));  /* send B */
265                 break;
266         default:
267                 return -EINVAL;
268         };
269         
270         tda8083_wait_diseqc_fifo (i2c, 100); 
271
272         return 0;
273 }
274
275
276 static int tda8083_set_tone (struct dvb_i2c_bus *i2c, fe_sec_tone_mode_t tone)
277 {
278         tda8083_writereg (i2c, 0x26, 0xf1);
279
280         switch (tone) {
281         case SEC_TONE_OFF:
282                 return tda8083_writereg (i2c, 0x29, 0x00);
283         case SEC_TONE_ON:
284                 return tda8083_writereg (i2c, 0x29, 0x80);
285         default:
286                 return -EINVAL;
287         };
288 }
289
290
291 static int tda8083_set_voltage (struct dvb_i2c_bus *i2c, fe_sec_voltage_t voltage)
292 {
293         switch (voltage) {
294         case SEC_VOLTAGE_13:
295                 return tda8083_writereg (i2c, 0x20, 0x00);
296         case SEC_VOLTAGE_18:
297                 return tda8083_writereg (i2c, 0x20, 0x11);
298         default:
299                 return -EINVAL;
300         };
301 }
302
303
304 static int grundig_29504_491_ioctl (struct dvb_frontend *fe, unsigned int cmd,
305                              void *arg)
306 {
307         struct dvb_i2c_bus *i2c = fe->i2c;
308
309         switch (cmd) {
310         case FE_GET_INFO:
311                 memcpy (arg, &grundig_29504_491_info, 
312                         sizeof(struct dvb_frontend_info));
313                 break;
314
315         case FE_READ_STATUS:
316         {
317                 fe_status_t *status=(fe_status_t *) arg;
318                 u8 signal = ~tda8083_readreg (i2c, 0x01);
319                 u8 sync = tda8083_readreg (i2c, 0x02);
320
321                 *status = 0;
322
323                 if (signal > 10)
324                         *status |= FE_HAS_SIGNAL;
325
326                 if (sync & 0x01)
327                         *status |= FE_HAS_CARRIER;
328
329                 if (sync & 0x02)
330                         *status |= FE_HAS_VITERBI;
331
332                 if (sync & 0x10)
333                         *status |= FE_HAS_SYNC;
334
335                 if ((sync & 0x1f) == 0x1f)
336                         *status |= FE_HAS_LOCK;
337
338                 break;
339         }
340
341         case FE_READ_BER:
342                 *((u32*) arg) = 0; /*   XXX FIXME: implement me!!! */
343                 return -EOPNOTSUPP;
344
345         case FE_READ_SIGNAL_STRENGTH:
346         {
347                 u8 signal = ~tda8083_readreg (i2c, 0x01);
348                 *((u16*) arg) = (signal << 8) | signal;
349                 break;
350         }
351         case FE_READ_SNR:
352         {
353                 u8 snr = tda8083_readreg (i2c, 0x08);
354                 *((u16*) arg) = (snr << 8) | snr;
355                 break;
356         }
357         case FE_READ_UNCORRECTED_BLOCKS:
358                 *((u32*) arg) = 0; /*   XXX FIXME: implement me!!! */
359                 return -EOPNOTSUPP;
360
361
362         case FE_SET_FRONTEND:
363         {
364                 struct dvb_frontend_parameters *p = arg;
365
366                 tsa5522_set_tv_freq (i2c, p->frequency);
367                 tda8083_set_inversion (i2c, p->inversion);
368                 tda8083_set_fec (i2c, p->u.qpsk.fec_inner);
369                 tda8083_set_symbolrate (i2c, p->u.qpsk.symbol_rate);
370
371                 tda8083_writereg (i2c, 0x00, 0x3c);
372                 tda8083_writereg (i2c, 0x00, 0x04);
373
374                 break;
375         }
376
377         case FE_GET_FRONTEND:
378         {
379                 struct dvb_frontend_parameters *p = arg;
380
381                 /*  FIXME: get symbolrate & frequency offset...*/
382                 /*p->frequency = ???;*/
383                 p->inversion = (tda8083_readreg (i2c, 0x0e) & 0x80) ?
384                                 INVERSION_ON : INVERSION_OFF;
385                 p->u.qpsk.fec_inner = tda8083_get_fec (i2c);
386                 /*p->u.qpsk.symbol_rate = tda8083_get_symbolrate (i2c);*/
387                 break;
388         }
389
390         case FE_SLEEP:
391                 tda8083_writereg (i2c, 0x00, 0x02);
392                 break;
393
394         case FE_INIT:
395                 tda8083_init (i2c);
396                 tda8083_writereg (i2c, 0x00, 0x3c);
397                 tda8083_writereg (i2c, 0x00, 0x04);
398                 break;
399
400         case FE_DISEQC_SEND_MASTER_CMD:
401                 return tda8083_send_diseqc_msg (i2c, arg);
402
403         case FE_DISEQC_SEND_BURST:
404                 tda8083_send_diseqc_burst (i2c, (fe_sec_mini_cmd_t) arg);
405                 tda8083_writereg (i2c, 0x00, 0x3c);
406                 tda8083_writereg (i2c, 0x00, 0x04);
407
408                 break;
409
410         case FE_SET_TONE:
411                 tda8083_set_tone (i2c, (fe_sec_tone_mode_t) arg);
412                 tda8083_writereg (i2c, 0x00, 0x3c);
413                 tda8083_writereg (i2c, 0x00, 0x04);
414                 break;
415
416         case FE_SET_VOLTAGE:
417                 tda8083_set_voltage (i2c, (fe_sec_voltage_t) arg);
418                 tda8083_writereg (i2c, 0x00, 0x3c);
419                 tda8083_writereg (i2c, 0x00, 0x04);
420                 break;
421
422         default:
423                 return -EOPNOTSUPP;
424         };
425
426         return 0;
427
428
429
430 static int tda8083_attach (struct dvb_i2c_bus *i2c, void **data)
431 {
432         if ((tda8083_readreg (i2c, 0x00)) != 0x05)
433                 return -ENODEV;
434
435         return dvb_register_frontend (grundig_29504_491_ioctl, i2c, NULL,
436                                &grundig_29504_491_info);
437 }
438
439
440 static void tda8083_detach (struct dvb_i2c_bus *i2c, void *data)
441 {
442         dvb_unregister_frontend (grundig_29504_491_ioctl, i2c);
443 }
444
445
446 static int __init init_tda8083 (void)
447 {
448         return dvb_register_i2c_device (THIS_MODULE,
449                                         tda8083_attach, tda8083_detach);
450 }
451
452
453 static void __exit exit_tda8083 (void)
454 {
455         dvb_unregister_i2c_device (tda8083_attach);
456 }
457
458 module_init(init_tda8083);
459 module_exit(exit_tda8083);
460
461 MODULE_PARM(debug,"i");
462 MODULE_DESCRIPTION("Grundig 29504-491 DVB frontend driver");
463 MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
464 MODULE_LICENSE("GPL");
465