This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / drivers / media / dvb / cinergyT2 / cinergyT2.c
1 /*
2  * TerraTec Cinergy T²/qanu USB2 DVB-T adapter.
3  *
4  * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
5  *                  Holger Waechtler <holger@qanu.de>
6  *
7  *  Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  */
24
25 #include <linux/config.h>
26 #include <linux/init.h>
27 #include <linux/module.h>
28 #include <linux/version.h>
29 #include <linux/slab.h>
30 #include <linux/usb.h>
31 #include <linux/pci.h>
32 #include <linux/input.h>
33 #include <linux/dvb/frontend.h>
34
35 #include "dmxdev.h"
36 #include "dvb_demux.h"
37 #include "dvb_net.h"
38
39
40
41
42
43
44
45
46
47 #ifdef CONFIG_DVB_CINERGYT2_TUNING
48         #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT)
49         #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE)
50         #define QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_QUERY_INTERVAL)
51         #ifdef CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
52                 #define RC_QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL)
53                 #define ENABLE_RC (1)
54         #endif
55 #else
56         #define STREAM_URB_COUNT (32)
57         #define STREAM_BUF_SIZE (512)   /* bytes */
58         #define ENABLE_RC (1)
59         #define RC_QUERY_INTERVAL (100) /* milliseconds */
60         #define QUERY_INTERVAL (333)    /* milliseconds */
61 #endif
62
63 #define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
64
65 static int debug;
66 module_param_named(debug, debug, int, 0644);
67 MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
68
69 #define dprintk(level, args...) \
70 do {                                                                    \
71         if ((debug & level)) {                                          \
72                 printk("%s: %s(): ", __stringify(KBUILD_MODNAME),       \
73                        __FUNCTION__);                                   \
74                 printk(args); }                                         \
75 } while (0)
76
77 enum cinergyt2_ep1_cmd {
78         CINERGYT2_EP1_PID_TABLE_RESET           = 0x01,
79         CINERGYT2_EP1_PID_SETUP                 = 0x02,
80         CINERGYT2_EP1_CONTROL_STREAM_TRANSFER   = 0x03,
81         CINERGYT2_EP1_SET_TUNER_PARAMETERS      = 0x04,
82         CINERGYT2_EP1_GET_TUNER_STATUS          = 0x05,
83         CINERGYT2_EP1_START_SCAN                = 0x06,
84         CINERGYT2_EP1_CONTINUE_SCAN             = 0x07,
85         CINERGYT2_EP1_GET_RC_EVENTS             = 0x08,
86         CINERGYT2_EP1_SLEEP_MODE                = 0x09
87 };
88
89 struct dvbt_set_parameters_msg {
90         uint8_t cmd;
91         uint32_t freq;
92         uint8_t bandwidth;
93         uint16_t tps;
94         uint8_t flags;
95 } __attribute__((packed));
96
97 struct dvbt_get_status_msg {
98         uint32_t freq;
99         uint8_t bandwidth;
100         uint16_t tps;
101         uint8_t flags;
102         uint16_t gain;
103         uint8_t snr;
104         uint32_t viterbi_error_rate;
105         uint32_t rs_error_rate;
106         uint32_t uncorrected_block_count;
107         uint8_t lock_bits;
108         uint8_t prev_lock_bits;
109 } __attribute__((packed));
110
111 static struct dvb_frontend_info cinergyt2_fe_info = {
112         .name = DRIVER_NAME,
113         .type = FE_OFDM,
114         .frequency_min = 174000000,
115         .frequency_max = 862000000,
116         .frequency_stepsize = 166667,
117         .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
118                 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
119                 FE_CAN_FEC_AUTO |
120                 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
121                 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
122                 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS
123 };
124
125 struct cinergyt2 {
126         struct dvb_demux demux;
127         struct usb_device *udev;
128         struct semaphore sem;
129         struct dvb_adapter *adapter;
130         struct dvb_device *fedev;
131         struct dmxdev dmxdev;
132         struct dvb_net dvbnet;
133
134         int streaming;
135         int sleeping;
136
137         struct dvbt_set_parameters_msg param;
138         struct dvbt_get_status_msg status;
139         struct work_struct query_work;
140
141         wait_queue_head_t poll_wq;
142         int pending_fe_events;
143
144         void *streambuf;
145         dma_addr_t streambuf_dmahandle;
146         struct urb *stream_urb[STREAM_URB_COUNT];
147
148 #ifdef ENABLE_RC
149         struct input_dev rc_input_dev;
150         struct work_struct rc_query_work;
151         int rc_input_event;
152 #endif
153 };
154
155 enum {
156         CINERGYT2_RC_EVENT_TYPE_NONE = 0x00,
157         CINERGYT2_RC_EVENT_TYPE_NEC  = 0x01,
158         CINERGYT2_RC_EVENT_TYPE_RC5  = 0x02
159 };
160
161 struct cinergyt2_rc_event {
162         char type;
163         uint32_t value;
164 } __attribute__((packed));
165
166 static const uint32_t rc_keys [] = {
167         CINERGYT2_RC_EVENT_TYPE_NEC,    0xfe01eb04,     KEY_POWER,
168         CINERGYT2_RC_EVENT_TYPE_NEC,    0xfd02eb04,     KEY_1,
169         CINERGYT2_RC_EVENT_TYPE_NEC,    0xfc03eb04,     KEY_2,
170         CINERGYT2_RC_EVENT_TYPE_NEC,    0xfb04eb04,     KEY_3,
171         CINERGYT2_RC_EVENT_TYPE_NEC,    0xfa05eb04,     KEY_4,
172         CINERGYT2_RC_EVENT_TYPE_NEC,    0xf906eb04,     KEY_5,
173         CINERGYT2_RC_EVENT_TYPE_NEC,    0xf807eb04,     KEY_6,
174         CINERGYT2_RC_EVENT_TYPE_NEC,    0xf708eb04,     KEY_7,
175         CINERGYT2_RC_EVENT_TYPE_NEC,    0xf609eb04,     KEY_8,
176         CINERGYT2_RC_EVENT_TYPE_NEC,    0xf50aeb04,     KEY_9,
177         CINERGYT2_RC_EVENT_TYPE_NEC,    0xf30ceb04,     KEY_0,
178         CINERGYT2_RC_EVENT_TYPE_NEC,    0xf40beb04,     KEY_VIDEO,
179         CINERGYT2_RC_EVENT_TYPE_NEC,    0xf20deb04,     KEY_REFRESH,
180         CINERGYT2_RC_EVENT_TYPE_NEC,    0xf10eeb04,     KEY_SELECT,
181         CINERGYT2_RC_EVENT_TYPE_NEC,    0xf00feb04,     KEY_EPG,
182         CINERGYT2_RC_EVENT_TYPE_NEC,    0xef10eb04,     KEY_UP,
183         CINERGYT2_RC_EVENT_TYPE_NEC,    0xeb14eb04,     KEY_DOWN,
184         CINERGYT2_RC_EVENT_TYPE_NEC,    0xee11eb04,     KEY_LEFT,
185         CINERGYT2_RC_EVENT_TYPE_NEC,    0xec13eb04,     KEY_RIGHT,
186         CINERGYT2_RC_EVENT_TYPE_NEC,    0xed12eb04,     KEY_OK, 
187         CINERGYT2_RC_EVENT_TYPE_NEC,    0xea15eb04,     KEY_TEXT,
188         CINERGYT2_RC_EVENT_TYPE_NEC,    0xe916eb04,     KEY_INFO,
189         CINERGYT2_RC_EVENT_TYPE_NEC,    0xe817eb04,     KEY_RED,
190         CINERGYT2_RC_EVENT_TYPE_NEC,    0xe718eb04,     KEY_GREEN,
191         CINERGYT2_RC_EVENT_TYPE_NEC,    0xe619eb04,     KEY_YELLOW,
192         CINERGYT2_RC_EVENT_TYPE_NEC,    0xe51aeb04,     KEY_BLUE,
193         CINERGYT2_RC_EVENT_TYPE_NEC,    0xe31ceb04,     KEY_VOLUMEUP,
194         CINERGYT2_RC_EVENT_TYPE_NEC,    0xe11eeb04,     KEY_VOLUMEDOWN,
195         CINERGYT2_RC_EVENT_TYPE_NEC,    0xe21deb04,     KEY_MUTE,
196         CINERGYT2_RC_EVENT_TYPE_NEC,    0xe41beb04,     KEY_CHANNELUP,
197         CINERGYT2_RC_EVENT_TYPE_NEC,    0xe01feb04,     KEY_CHANNELDOWN,
198         CINERGYT2_RC_EVENT_TYPE_NEC,    0xbf40eb04,     KEY_PAUSE,
199         CINERGYT2_RC_EVENT_TYPE_NEC,    0xb34ceb04,     KEY_PLAY,
200         CINERGYT2_RC_EVENT_TYPE_NEC,    0xa758eb04,     KEY_RECORD,
201         CINERGYT2_RC_EVENT_TYPE_NEC,    0xab54eb04,     KEY_PREVIOUS,
202         CINERGYT2_RC_EVENT_TYPE_NEC,    0xb748eb04,     KEY_STOP,
203         CINERGYT2_RC_EVENT_TYPE_NEC,    0xa35ceb04,     KEY_NEXT
204 };
205
206 static int cinergyt2_command (struct cinergyt2 *cinergyt2,
207                     char *send_buf, int send_buf_len,
208                               char *recv_buf, int recv_buf_len)
209 {
210         int actual_len;
211         char dummy;
212         int ret;
213
214         ret = usb_bulk_msg(cinergyt2->udev, usb_sndbulkpipe(cinergyt2->udev, 1),
215                            send_buf, send_buf_len, &actual_len, HZ);
216
217         if (ret)
218                 dprintk(1, "usb_bulk_msg (send) failed, err %i\n", ret);
219
220         if (!recv_buf)
221                 recv_buf = &dummy;
222
223         ret = usb_bulk_msg(cinergyt2->udev, usb_rcvbulkpipe(cinergyt2->udev, 1),
224                            recv_buf, recv_buf_len, &actual_len, HZ);
225
226         if (ret)
227                 dprintk(1, "usb_bulk_msg (read) failed, err %i\n", ret);
228
229         return ret ? ret : actual_len;
230 }
231
232 static void cinergyt2_control_stream_transfer (struct cinergyt2 *cinergyt2, int enable)
233 {
234         char buf [] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER, enable ? 1 : 0 };
235         cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0);
236 }
237
238 static void cinergyt2_sleep (struct cinergyt2 *cinergyt2, int sleep)
239 {
240         char buf [] = { CINERGYT2_EP1_SLEEP_MODE, sleep ? 1 : 0 };
241         cinergyt2_command(cinergyt2, buf, sizeof(buf), NULL, 0);
242         cinergyt2->sleeping = sleep;
243 }
244
245 static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs);
246
247 static int cinergyt2_submit_stream_urb (struct cinergyt2 *cinergyt2, struct urb *urb)
248 {
249         int err;
250
251         usb_fill_bulk_urb(urb,
252                           cinergyt2->udev,
253                           usb_rcvbulkpipe(cinergyt2->udev, 0x2),
254                           urb->transfer_buffer,
255                           STREAM_BUF_SIZE,
256                           cinergyt2_stream_irq,
257                           cinergyt2);
258
259         if ((err = usb_submit_urb(urb, GFP_ATOMIC)))
260                 dprintk(1, "urb submission failed (err = %i)!\n", err);
261
262         return err;
263 }
264
265 static void cinergyt2_stream_irq (struct urb *urb, struct pt_regs *regs)
266 {
267         struct cinergyt2 *cinergyt2 = urb->context;
268
269         if (urb->actual_length > 0)
270                 dvb_dmx_swfilter(&cinergyt2->demux,
271                                  urb->transfer_buffer, urb->actual_length);
272
273         if (cinergyt2->streaming)
274                 cinergyt2_submit_stream_urb(cinergyt2, urb);
275 }
276
277 static void cinergyt2_free_stream_urbs (struct cinergyt2 *cinergyt2)
278 {
279         int i;
280
281         for (i=0; i<STREAM_URB_COUNT; i++)
282                 if (cinergyt2->stream_urb[i])
283                         usb_free_urb(cinergyt2->stream_urb[i]);
284
285         pci_free_consistent(NULL, STREAM_URB_COUNT*STREAM_BUF_SIZE,
286                             cinergyt2->streambuf, cinergyt2->streambuf_dmahandle);
287 }
288
289 static int cinergyt2_alloc_stream_urbs (struct cinergyt2 *cinergyt2)
290 {
291         int i;
292
293         cinergyt2->streambuf = pci_alloc_consistent(NULL, 
294                                               STREAM_URB_COUNT*STREAM_BUF_SIZE,
295                                               &cinergyt2->streambuf_dmahandle);
296         if (!cinergyt2->streambuf) {
297                 dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n");
298                 return -ENOMEM;
299         }
300
301         memset(cinergyt2->streambuf, 0, STREAM_URB_COUNT*STREAM_BUF_SIZE);
302
303         for (i=0; i<STREAM_URB_COUNT; i++) {
304                 struct urb *urb;        
305
306                 if (!(urb = usb_alloc_urb(0, GFP_ATOMIC))) {
307                         dprintk(1, "failed to alloc consistent stream urbs, bailing out!\n");
308                         cinergyt2_free_stream_urbs(cinergyt2);
309                         return -ENOMEM;
310                 }
311
312                 urb->transfer_buffer = cinergyt2->streambuf + i * STREAM_BUF_SIZE;
313                 urb->transfer_buffer_length = STREAM_BUF_SIZE;
314
315                 cinergyt2->stream_urb[i] = urb;
316         }
317
318         return 0;
319 }
320
321 static void cinergyt2_stop_stream_xfer (struct cinergyt2 *cinergyt2)
322 {
323         int i;
324
325         cinergyt2_control_stream_transfer(cinergyt2, 0);
326
327         for (i=0; i<STREAM_URB_COUNT; i++)
328                 if (cinergyt2->stream_urb[i])
329                         usb_kill_urb(cinergyt2->stream_urb[i]);
330 }
331
332 static int cinergyt2_start_stream_xfer (struct cinergyt2 *cinergyt2)
333 {
334         int i, err;
335
336         for (i=0; i<STREAM_URB_COUNT; i++) {
337                 if ((err = cinergyt2_submit_stream_urb(cinergyt2, cinergyt2->stream_urb[i]))) {
338                         cinergyt2_stop_stream_xfer(cinergyt2);
339                         dprintk(1, "failed urb submission (%i: err = %i)!\n", i, err);
340                         return err;
341                 }
342         }
343
344         cinergyt2_control_stream_transfer(cinergyt2, 1);
345         return 0;
346 }
347
348 static int cinergyt2_start_feed(struct dvb_demux_feed *dvbdmxfeed)
349 {
350         struct dvb_demux *demux = dvbdmxfeed->demux;
351         struct cinergyt2 *cinergyt2 = demux->priv;
352
353         if (down_interruptible(&cinergyt2->sem))
354                 return -ERESTARTSYS;
355         
356         if (cinergyt2->streaming == 0)
357                 cinergyt2_start_stream_xfer(cinergyt2);
358
359         cinergyt2->streaming++;
360         up(&cinergyt2->sem);
361         return 0;
362 }
363
364 static int cinergyt2_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
365 {
366         struct dvb_demux *demux = dvbdmxfeed->demux;
367         struct cinergyt2 *cinergyt2 = demux->priv;      
368
369         if (down_interruptible(&cinergyt2->sem))
370                 return -ERESTARTSYS;
371
372         if (--cinergyt2->streaming == 0)
373                 cinergyt2_stop_stream_xfer(cinergyt2);
374
375         up(&cinergyt2->sem);
376         return 0;
377 }
378
379 /**
380  *  convert linux-dvb frontend parameter set into TPS.
381  *  See ETSI ETS-300744, section 4.6.2, table 9 for details.
382  *
383  *  This function is probably reusable and may better get placed in a support
384  *  library.
385  *
386  *  We replace errornous fields by default TPS fields (the ones with value 0).
387  */
388 static uint16_t compute_tps (struct dvb_frontend_parameters *p)
389 {
390         struct dvb_ofdm_parameters *op = &p->u.ofdm;
391         uint16_t tps = 0;
392
393         switch (op->code_rate_HP) {
394                 case FEC_2_3:
395                         tps |= (1 << 7);
396                         break;
397                 case FEC_3_4:
398                         tps |= (2 << 7);
399                         break;
400                 case FEC_5_6:
401                         tps |= (3 << 7);
402                         break;
403                 case FEC_7_8:
404                         tps |= (4 << 7);
405                         break;
406                 case FEC_1_2:
407                 case FEC_AUTO:
408                 default:
409                         /* tps |= (0 << 7) */;
410         }
411
412         switch (op->code_rate_LP) {
413                 case FEC_2_3:
414                         tps |= (1 << 4);
415                         break;
416                 case FEC_3_4:
417                         tps |= (2 << 4);
418                         break;
419                 case FEC_5_6:
420                         tps |= (3 << 4);
421                         break;
422                 case FEC_7_8:
423                         tps |= (4 << 4);
424                         break;
425                 case FEC_1_2:
426                 case FEC_AUTO:
427                 default:
428                         /* tps |= (0 << 4) */;
429         }
430
431         switch (op->constellation) {
432                 case QAM_16:
433                         tps |= (1 << 13);
434                         break;
435                 case QAM_64:
436                         tps |= (2 << 13);
437                         break;
438                 case QPSK:
439                 default:
440                         /* tps |= (0 << 13) */;
441         }
442
443         switch (op->transmission_mode) {
444                 case TRANSMISSION_MODE_8K:
445                         tps |= (1 << 0);
446                         break;
447                 case TRANSMISSION_MODE_2K:
448                 default:
449                         /* tps |= (0 << 0) */;
450         }
451
452         switch (op->guard_interval) {
453                 case GUARD_INTERVAL_1_16:
454                         tps |= (1 << 2);
455                         break;
456                 case GUARD_INTERVAL_1_8:
457                         tps |= (2 << 2);
458                         break;
459                 case GUARD_INTERVAL_1_4:
460                         tps |= (3 << 2);
461                         break;
462                 case GUARD_INTERVAL_1_32:
463                 default:
464                         /* tps |= (0 << 2) */;
465         }
466
467         switch (op->hierarchy_information) {
468                 case HIERARCHY_1:
469                         tps |= (1 << 10);
470                         break;
471                 case HIERARCHY_2:
472                         tps |= (2 << 10);
473                         break;
474                 case HIERARCHY_4:
475                         tps |= (3 << 10);
476                         break;
477                 case HIERARCHY_NONE:
478                 default:
479                         /* tps |= (0 << 10) */;
480         }
481
482         return tps;
483 }
484
485 static int cinergyt2_open (struct inode *inode, struct file *file)
486 {
487         struct dvb_device *dvbdev = file->private_data;
488         struct cinergyt2 *cinergyt2 = dvbdev->priv;
489         int err;
490
491         if ((err = dvb_generic_open(inode, file)))
492                 return err;
493
494         if (down_interruptible(&cinergyt2->sem))
495                 return -ERESTARTSYS;
496
497         if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
498                 cinergyt2_sleep(cinergyt2, 0);
499                 schedule_delayed_work(&cinergyt2->query_work, HZ/2);
500 }
501
502         up(&cinergyt2->sem);
503         return 0;
504 }
505
506 static int cinergyt2_release (struct inode *inode, struct file *file)
507 {
508         struct dvb_device *dvbdev = file->private_data;
509         struct cinergyt2 *cinergyt2 = dvbdev->priv;
510
511         if (down_interruptible(&cinergyt2->sem))
512                 return -ERESTARTSYS;
513
514         if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
515                 cancel_delayed_work(&cinergyt2->query_work);
516                 flush_scheduled_work();
517                 cinergyt2_sleep(cinergyt2, 1);
518         }
519
520         up(&cinergyt2->sem);
521
522         return dvb_generic_release(inode, file);
523         }
524
525 static unsigned int cinergyt2_poll (struct file *file, struct poll_table_struct *wait)
526         {
527         struct dvb_device *dvbdev = file->private_data;
528         struct cinergyt2 *cinergyt2 = dvbdev->priv;
529         poll_wait(file, &cinergyt2->poll_wq, wait);
530         return (POLLIN | POLLRDNORM | POLLPRI);
531         }
532
533
534 static int cinergyt2_ioctl (struct inode *inode, struct file *file,
535                      unsigned cmd, unsigned long arg)
536         {
537         struct dvb_device *dvbdev = file->private_data;
538         struct cinergyt2 *cinergyt2 = dvbdev->priv;
539         struct dvbt_get_status_msg *stat = &cinergyt2->status;
540         fe_status_t status = 0;
541
542         switch (cmd) {
543         case FE_GET_INFO:
544                 return copy_to_user((void*) arg, &cinergyt2_fe_info,
545                                     sizeof(struct dvb_frontend_info));
546
547         case FE_READ_STATUS:
548                 if (0xffff - le16_to_cpu(stat->gain) > 30)
549                         status |= FE_HAS_SIGNAL;
550                 if (stat->lock_bits & (1 << 6))
551                         status |= FE_HAS_LOCK;
552                 if (stat->lock_bits & (1 << 5))
553                         status |= FE_HAS_SYNC;
554                 if (stat->lock_bits & (1 << 4))
555                         status |= FE_HAS_CARRIER;
556                 if (stat->lock_bits & (1 << 1))
557                         status |= FE_HAS_VITERBI;
558
559                 return copy_to_user((void *) arg, &status, sizeof(status));
560
561         case FE_READ_BER:
562                 return put_user(le32_to_cpu(stat->viterbi_error_rate),
563                                 (__u32 __user *) arg);
564
565         case FE_READ_SIGNAL_STRENGTH:
566                 return put_user(0xffff - le16_to_cpu(stat->gain),
567                                 (__u16 __user *) arg);
568
569         case FE_READ_SNR:
570                 return put_user((stat->snr << 8) | stat->snr,
571                                 (__u16 __user *) arg);
572
573         case FE_READ_UNCORRECTED_BLOCKS:
574                 /* UNC are already converted to host byte order... */
575                 return put_user(stat->uncorrected_block_count,
576                                 (__u32 __user *) arg);
577         
578         case FE_SET_FRONTEND:
579         {
580                 struct dvbt_set_parameters_msg *param = &cinergyt2->param;
581                 struct dvb_frontend_parameters p;
582                 int err;
583
584                 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
585                         return -EPERM;
586
587                 if (copy_from_user(&p, (void *) arg, sizeof(p)))
588                         return -EFAULT;
589
590                 if (down_interruptible(&cinergyt2->sem))
591                         return -ERESTARTSYS;
592
593                 param->cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
594                 param->tps = cpu_to_le16(compute_tps(&p));
595                 param->freq = cpu_to_le32(p.frequency / 1000);
596                 param->bandwidth = 8 - p.u.ofdm.bandwidth - BANDWIDTH_8_MHZ;
597
598                 stat->lock_bits = 0;
599                 cinergyt2->pending_fe_events++;
600                 wake_up_interruptible(&cinergyt2->poll_wq);
601
602                 err = cinergyt2_command(cinergyt2,
603                                         (char *) param, sizeof(*param),
604                                         NULL, 0);
605
606                 up(&cinergyt2->sem);
607
608                 return (err < 0) ? err : 0;
609         }
610
611         case FE_GET_FRONTEND:
612                 /**
613                  *  trivial to implement (see struct dvbt_get_status_msg).
614                  *  equivalent to FE_READ ioctls, but needs 
615                  *  TPS -> linux-dvb parameter set conversion. Feel free
616                  *  to implement this and send us a patch if you need this
617                  *  functionality.
618                  */
619                 break;
620
621         case FE_GET_EVENT:
622         {
623                 /**
624                  *  for now we only fill the status field. the parameters
625                  *  are trivial to fill as soon FE_GET_FRONTEND is done.
626                  */
627                 struct dvb_frontend_event *e = (void *) arg;
628                 if (cinergyt2->pending_fe_events == 0) {
629                         if (file->f_flags & O_NONBLOCK)
630                                 return -EWOULDBLOCK;
631                         wait_event_interruptible(cinergyt2->poll_wq,
632                                                  cinergyt2->pending_fe_events > 0);
633                 }
634                 cinergyt2->pending_fe_events = 0;
635                 return cinergyt2_ioctl(inode, file, FE_READ_STATUS,
636                                         (unsigned long) &e->status);
637         }
638
639         default:
640                 ;
641         }
642
643         return -EINVAL;
644 }
645
646 static int cinergyt2_mmap(struct file *file, struct vm_area_struct *vma)
647 {
648         struct dvb_device *dvbdev = file->private_data;
649         struct cinergyt2 *cinergyt2 = dvbdev->priv;
650         int ret = 0;
651
652         lock_kernel();
653
654         if (vma->vm_flags & (VM_WRITE | VM_EXEC)) {
655                 ret = -EPERM;
656                 goto bailout;
657         }
658
659         if (vma->vm_end > vma->vm_start + STREAM_URB_COUNT * STREAM_BUF_SIZE) {
660                 ret = -EINVAL;
661                 goto bailout;
662         }
663
664         vma->vm_flags |= (VM_IO | VM_DONTCOPY);
665         vma->vm_file = file;
666
667         ret = remap_pfn_range(vma, vma->vm_start,
668                               virt_to_phys(cinergyt2->streambuf) >> PAGE_SHIFT,
669                               vma->vm_end - vma->vm_start,
670                               vma->vm_page_prot) ? -EAGAIN : 0;
671 bailout:
672         unlock_kernel();
673         return ret;
674 }
675
676 static struct file_operations cinergyt2_fops = {
677         .owner          = THIS_MODULE,
678         .ioctl          = cinergyt2_ioctl,
679         .poll           = cinergyt2_poll,
680         .open           = cinergyt2_open,
681         .release        = cinergyt2_release,
682         .mmap           = cinergyt2_mmap
683 };
684
685 static struct dvb_device cinergyt2_fe_template = {
686         .users = ~0,
687         .writers = 1,
688         .readers = (~0)-1,
689         .fops = &cinergyt2_fops
690 };
691
692 #ifdef ENABLE_RC
693 static void cinergyt2_query_rc (void *data)
694 {
695         struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data;
696         char buf [1] = { CINERGYT2_EP1_GET_RC_EVENTS };
697         struct cinergyt2_rc_event rc_events[12];
698         int n, len;
699
700         if (down_interruptible(&cinergyt2->sem))
701                 return;
702
703         len = cinergyt2_command(cinergyt2, buf, sizeof(buf), 
704                              (char *) rc_events, sizeof(rc_events));
705
706         for (n=0; len>0 && n<(len/sizeof(rc_events[0])); n++) {
707                 int i;
708
709                 if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC &&
710                     rc_events[n].value == ~0)
711                 {
712                         /**
713                          * keyrepeat bit. If we would handle this properly
714                          * we would need to emit down events as long the
715                          * keyrepeat goes, a up event if no further 
716                          * repeat bits occur. Would need a timer to implement
717                          * and no other driver does this, so we simply
718                          * emit the last key up/down sequence again.
719                          */
720                 } else {
721                         cinergyt2->rc_input_event = KEY_MAX;
722                         for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3) {
723                                 if (rc_keys[i+0] == rc_events[n].type &&
724                                     rc_keys[i+1] == rc_events[n].value)
725                                 {
726                                         cinergyt2->rc_input_event = rc_keys[i+2];
727                                         break;
728                                 }
729                         }
730                 }
731
732                 if (cinergyt2->rc_input_event != KEY_MAX) {
733                         input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 1);
734                         input_report_key(&cinergyt2->rc_input_dev, cinergyt2->rc_input_event, 0);
735                         input_sync(&cinergyt2->rc_input_dev);
736                 }
737         }
738
739         schedule_delayed_work(&cinergyt2->rc_query_work,
740                               msecs_to_jiffies(RC_QUERY_INTERVAL));
741
742         up(&cinergyt2->sem);
743 }
744 #endif
745
746 static void cinergyt2_query (void *data)
747 {
748         struct cinergyt2 *cinergyt2 = (struct cinergyt2 *) data;
749         char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS };
750         struct dvbt_get_status_msg *s = &cinergyt2->status;
751         uint8_t lock_bits;
752         uint32_t unc;
753
754         if (down_interruptible(&cinergyt2->sem))
755                 return;
756
757         unc = s->uncorrected_block_count;
758         lock_bits = s->lock_bits;
759
760         cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s));
761
762         unc += le32_to_cpu(s->uncorrected_block_count);
763         s->uncorrected_block_count = unc;
764
765         if (lock_bits != s->lock_bits) {
766                 wake_up_interruptible(&cinergyt2->poll_wq);
767                 cinergyt2->pending_fe_events++;
768         }
769
770         schedule_delayed_work(&cinergyt2->query_work,
771                               msecs_to_jiffies(QUERY_INTERVAL));
772
773         up(&cinergyt2->sem);
774 }
775
776 static int cinergyt2_probe (struct usb_interface *intf,
777                   const struct usb_device_id *id)
778 {
779         struct cinergyt2 *cinergyt2;
780         int i, err;
781
782         if (!(cinergyt2 = kmalloc (sizeof(struct cinergyt2), GFP_KERNEL))) {
783                 dprintk(1, "out of memory?!?\n");
784                 return -ENOMEM;
785         }
786
787         memset (cinergyt2, 0, sizeof (struct cinergyt2));
788         usb_set_intfdata (intf, (void *) cinergyt2);
789
790         init_MUTEX(&cinergyt2->sem);
791         init_waitqueue_head (&cinergyt2->poll_wq);
792         INIT_WORK(&cinergyt2->query_work, cinergyt2_query, cinergyt2);
793
794         cinergyt2->udev = interface_to_usbdev(intf);
795         cinergyt2->param.cmd = CINERGYT2_EP1_SET_TUNER_PARAMETERS;
796         
797         if (cinergyt2_alloc_stream_urbs (cinergyt2) < 0) {
798                 dprintk(1, "unable to allocate stream urbs\n");
799                 kfree(cinergyt2);
800                 return -ENOMEM;
801         }
802
803         dvb_register_adapter(&cinergyt2->adapter, DRIVER_NAME, THIS_MODULE);
804
805         cinergyt2->demux.priv = cinergyt2;
806         cinergyt2->demux.filternum = 256;
807         cinergyt2->demux.feednum = 256;
808         cinergyt2->demux.start_feed = cinergyt2_start_feed;
809         cinergyt2->demux.stop_feed = cinergyt2_stop_feed;
810         cinergyt2->demux.dmx.capabilities = DMX_TS_FILTERING |
811                                          DMX_SECTION_FILTERING |
812                                          DMX_MEMORY_BASED_FILTERING;
813
814         if ((err = dvb_dmx_init(&cinergyt2->demux)) < 0) {
815                 dprintk(1, "dvb_dmx_init() failed (err = %d)\n", err);
816                 goto bailout;
817         }
818
819         cinergyt2->dmxdev.filternum = cinergyt2->demux.filternum;
820         cinergyt2->dmxdev.demux = &cinergyt2->demux.dmx;
821         cinergyt2->dmxdev.capabilities = 0;
822
823         if ((err = dvb_dmxdev_init(&cinergyt2->dmxdev, cinergyt2->adapter)) < 0) {
824                 dprintk(1, "dvb_dmxdev_init() failed (err = %d)\n", err);
825                 goto bailout;
826         }
827
828         if (dvb_net_init(cinergyt2->adapter, &cinergyt2->dvbnet, &cinergyt2->demux.dmx))
829                 dprintk(1, "dvb_net_init() failed!\n");
830
831         dvb_register_device(cinergyt2->adapter, &cinergyt2->fedev,
832                             &cinergyt2_fe_template, cinergyt2,
833                             DVB_DEVICE_FRONTEND);
834
835 #ifdef ENABLE_RC
836         init_input_dev(&cinergyt2->rc_input_dev);                       
837
838         cinergyt2->rc_input_dev.evbit[0] = BIT(EV_KEY);
839         cinergyt2->rc_input_dev.keycodesize = sizeof(unsigned char);
840         cinergyt2->rc_input_dev.keycodemax = KEY_MAX;
841         cinergyt2->rc_input_dev.name = DRIVER_NAME " remote control";
842
843         for (i=0; i<sizeof(rc_keys)/sizeof(rc_keys[0]); i+=3)
844                 set_bit(rc_keys[i+2], cinergyt2->rc_input_dev.keybit);
845
846         input_register_device(&cinergyt2->rc_input_dev);
847
848         cinergyt2->rc_input_event = KEY_MAX;
849         
850         INIT_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc, cinergyt2);
851         schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
852 #endif
853         return 0;
854
855 bailout:
856         dvb_dmxdev_release(&cinergyt2->dmxdev);
857         dvb_dmx_release(&cinergyt2->demux);
858         dvb_unregister_adapter (cinergyt2->adapter);
859         cinergyt2_free_stream_urbs (cinergyt2);
860         kfree(cinergyt2);
861         return -ENOMEM;
862 }
863
864 static void cinergyt2_disconnect (struct usb_interface *intf)
865 {
866         struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
867
868         if (down_interruptible(&cinergyt2->sem))
869                 return;
870
871 #ifdef ENABLE_RC
872         cancel_delayed_work(&cinergyt2->rc_query_work);
873         flush_scheduled_work();
874         input_unregister_device(&cinergyt2->rc_input_dev);
875 #endif
876
877         cinergyt2->demux.dmx.close(&cinergyt2->demux.dmx);
878         dvb_net_release(&cinergyt2->dvbnet);
879         dvb_dmxdev_release(&cinergyt2->dmxdev);
880         dvb_dmx_release(&cinergyt2->demux);
881
882         dvb_unregister_device(cinergyt2->fedev);
883         dvb_unregister_adapter(cinergyt2->adapter);
884
885         cinergyt2_free_stream_urbs(cinergyt2);
886         up(&cinergyt2->sem);
887         kfree(cinergyt2);
888 }
889
890 static int cinergyt2_suspend (struct usb_interface *intf, u32 state)
891 {
892         struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
893
894         if (down_interruptible(&cinergyt2->sem))
895                 return -ERESTARTSYS;
896
897         if (state > 0) {        /* state 0 seems to mean DEVICE_PM_ON */
898                 struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
899 #ifdef ENABLE_RC
900                 cancel_delayed_work(&cinergyt2->rc_query_work);
901 #endif
902                 cancel_delayed_work(&cinergyt2->query_work);
903                 if (cinergyt2->streaming)
904                         cinergyt2_stop_stream_xfer(cinergyt2);
905                 flush_scheduled_work();
906                 cinergyt2_sleep(cinergyt2, 1);
907         }
908
909         up(&cinergyt2->sem);
910         return 0;
911 }
912
913 static int cinergyt2_resume (struct usb_interface *intf)
914 {
915         struct cinergyt2 *cinergyt2 = usb_get_intfdata (intf);
916         struct dvbt_set_parameters_msg *param = &cinergyt2->param;
917
918         if (down_interruptible(&cinergyt2->sem))
919                 return -ERESTARTSYS;
920
921         if (!cinergyt2->sleeping) {
922                 cinergyt2_sleep(cinergyt2, 0);
923                 cinergyt2_command(cinergyt2, (char *) param, sizeof(*param), NULL, 0);
924                 if (cinergyt2->streaming)
925                         cinergyt2_start_stream_xfer(cinergyt2);
926                 schedule_delayed_work(&cinergyt2->query_work, HZ/2);
927         }
928
929 #ifdef ENABLE_RC
930         schedule_delayed_work(&cinergyt2->rc_query_work, HZ/2);
931 #endif
932         up(&cinergyt2->sem);
933         return 0;
934 }
935
936 static const struct usb_device_id cinergyt2_table [] __devinitdata = {
937         { USB_DEVICE(0x0ccd, 0x0038) },
938         { 0 }
939 };
940
941 MODULE_DEVICE_TABLE(usb, cinergyt2_table);
942
943 static struct usb_driver cinergyt2_driver = {
944         .owner          = THIS_MODULE,
945         .name   = "cinergyT2",
946         .probe          = cinergyt2_probe,
947         .disconnect     = cinergyt2_disconnect,
948         .suspend        = cinergyt2_suspend,
949         .resume         = cinergyt2_resume,
950         .id_table       = cinergyt2_table
951 };
952
953 static int __init cinergyt2_init (void)
954 {
955         int err;
956
957         if ((err = usb_register(&cinergyt2_driver)) < 0)
958                 dprintk(1, "usb_register() failed! (err %i)\n", err);
959
960         return err;
961 }
962
963 static void __exit cinergyt2_exit (void)
964 {
965         usb_deregister(&cinergyt2_driver);
966 }
967
968 module_init (cinergyt2_init);
969 module_exit (cinergyt2_exit);
970
971 MODULE_LICENSE("GPL");
972 MODULE_AUTHOR("Holger Waechtler, Daniel Mack");
973