2 * TerraTec Cinergy T²/qanu USB2 DVB-T adapter.
4 * Copyright (C) 2004 Daniel Mack <daniel@qanu.de> and
5 * Holger Waechtler <holger@qanu.de>
7 * Protocol Spec published on http://qanu.de/specs/terratec_cinergyT2.pdf
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.
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.
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.
25 #include <linux/init.h>
26 #include <linux/module.h>
27 #include <linux/slab.h>
28 #include <linux/usb.h>
29 #include <linux/input.h>
30 #include <linux/dvb/frontend.h>
31 #include <linux/mutex.h>
36 #include "dvb_demux.h"
39 #ifdef CONFIG_DVB_CINERGYT2_TUNING
40 #define STREAM_URB_COUNT (CONFIG_DVB_CINERGYT2_STREAM_URB_COUNT)
41 #define STREAM_BUF_SIZE (CONFIG_DVB_CINERGYT2_STREAM_BUF_SIZE)
42 #define QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_QUERY_INTERVAL)
43 #ifdef CONFIG_DVB_CINERGYT2_ENABLE_RC_INPUT_DEVICE
44 #define RC_QUERY_INTERVAL (CONFIG_DVB_CINERGYT2_RC_QUERY_INTERVAL)
48 #define STREAM_URB_COUNT (32)
49 #define STREAM_BUF_SIZE (512) /* bytes */
51 #define RC_QUERY_INTERVAL (50) /* milliseconds */
52 #define QUERY_INTERVAL (333) /* milliseconds */
55 #define DRIVER_NAME "TerraTec/qanu USB2.0 Highspeed DVB-T Receiver"
58 module_param_named(debug
, debug
, int, 0644);
59 MODULE_PARM_DESC(debug
, "Turn on/off debugging (default:off).");
61 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr
);
63 #define dprintk(level, args...) \
65 if ((debug & level)) { \
66 printk("%s: %s(): ", KBUILD_MODNAME, \
71 enum cinergyt2_ep1_cmd
{
72 CINERGYT2_EP1_PID_TABLE_RESET
= 0x01,
73 CINERGYT2_EP1_PID_SETUP
= 0x02,
74 CINERGYT2_EP1_CONTROL_STREAM_TRANSFER
= 0x03,
75 CINERGYT2_EP1_SET_TUNER_PARAMETERS
= 0x04,
76 CINERGYT2_EP1_GET_TUNER_STATUS
= 0x05,
77 CINERGYT2_EP1_START_SCAN
= 0x06,
78 CINERGYT2_EP1_CONTINUE_SCAN
= 0x07,
79 CINERGYT2_EP1_GET_RC_EVENTS
= 0x08,
80 CINERGYT2_EP1_SLEEP_MODE
= 0x09
83 struct dvbt_set_parameters_msg
{
89 } __attribute__((packed
));
91 struct dvbt_get_status_msg
{
98 uint32_t viterbi_error_rate
;
99 uint32_t rs_error_rate
;
100 uint32_t uncorrected_block_count
;
102 uint8_t prev_lock_bits
;
103 } __attribute__((packed
));
105 static struct dvb_frontend_info cinergyt2_fe_info
= {
108 .frequency_min
= 174000000,
109 .frequency_max
= 862000000,
110 .frequency_stepsize
= 166667,
111 .caps
= FE_CAN_INVERSION_AUTO
| FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
|
112 FE_CAN_FEC_3_4
| FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
|
114 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
115 FE_CAN_TRANSMISSION_MODE_AUTO
| FE_CAN_GUARD_INTERVAL_AUTO
|
116 FE_CAN_HIERARCHY_AUTO
| FE_CAN_RECOVER
| FE_CAN_MUTE_TS
120 struct dvb_demux demux
;
121 struct usb_device
*udev
;
124 struct dvb_adapter adapter
;
125 struct dvb_device
*fedev
;
126 struct dmxdev dmxdev
;
127 struct dvb_net dvbnet
;
132 struct dvbt_set_parameters_msg param
;
133 struct dvbt_get_status_msg status
;
134 struct delayed_work query_work
;
136 wait_queue_head_t poll_wq
;
137 int pending_fe_events
;
138 int disconnect_pending
;
142 dma_addr_t streambuf_dmahandle
;
143 struct urb
*stream_urb
[STREAM_URB_COUNT
];
146 struct input_dev
*rc_input_dev
;
148 struct delayed_work rc_query_work
;
151 unsigned long last_event_jiffies
;
156 CINERGYT2_RC_EVENT_TYPE_NONE
= 0x00,
157 CINERGYT2_RC_EVENT_TYPE_NEC
= 0x01,
158 CINERGYT2_RC_EVENT_TYPE_RC5
= 0x02
161 struct cinergyt2_rc_event
{
164 } __attribute__((packed
));
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
206 static int cinergyt2_command (struct cinergyt2
*cinergyt2
,
207 char *send_buf
, int send_buf_len
,
208 char *recv_buf
, int recv_buf_len
)
214 ret
= usb_bulk_msg(cinergyt2
->udev
, usb_sndbulkpipe(cinergyt2
->udev
, 1),
215 send_buf
, send_buf_len
, &actual_len
, 1000);
218 dprintk(1, "usb_bulk_msg (send) failed, err %i\n", ret
);
223 ret
= usb_bulk_msg(cinergyt2
->udev
, usb_rcvbulkpipe(cinergyt2
->udev
, 1),
224 recv_buf
, recv_buf_len
, &actual_len
, 1000);
227 dprintk(1, "usb_bulk_msg (read) failed, err %i\n", ret
);
229 return ret
? ret
: actual_len
;
232 static void cinergyt2_control_stream_transfer (struct cinergyt2
*cinergyt2
, int enable
)
234 char buf
[] = { CINERGYT2_EP1_CONTROL_STREAM_TRANSFER
, enable
? 1 : 0 };
235 cinergyt2_command(cinergyt2
, buf
, sizeof(buf
), NULL
, 0);
238 static void cinergyt2_sleep (struct cinergyt2
*cinergyt2
, int sleep
)
240 char buf
[] = { CINERGYT2_EP1_SLEEP_MODE
, sleep
? 1 : 0 };
241 cinergyt2_command(cinergyt2
, buf
, sizeof(buf
), NULL
, 0);
242 cinergyt2
->sleeping
= sleep
;
245 static void cinergyt2_stream_irq (struct urb
*urb
);
247 static int cinergyt2_submit_stream_urb (struct cinergyt2
*cinergyt2
, struct urb
*urb
)
251 usb_fill_bulk_urb(urb
,
253 usb_rcvbulkpipe(cinergyt2
->udev
, 0x2),
254 urb
->transfer_buffer
,
256 cinergyt2_stream_irq
,
259 if ((err
= usb_submit_urb(urb
, GFP_ATOMIC
)))
260 dprintk(1, "urb submission failed (err = %i)!\n", err
);
265 static void cinergyt2_stream_irq (struct urb
*urb
)
267 struct cinergyt2
*cinergyt2
= urb
->context
;
269 if (urb
->actual_length
> 0)
270 dvb_dmx_swfilter(&cinergyt2
->demux
,
271 urb
->transfer_buffer
, urb
->actual_length
);
273 if (cinergyt2
->streaming
)
274 cinergyt2_submit_stream_urb(cinergyt2
, urb
);
277 static void cinergyt2_free_stream_urbs (struct cinergyt2
*cinergyt2
)
281 for (i
=0; i
<STREAM_URB_COUNT
; i
++)
282 usb_free_urb(cinergyt2
->stream_urb
[i
]);
284 usb_buffer_free(cinergyt2
->udev
, STREAM_URB_COUNT
*STREAM_BUF_SIZE
,
285 cinergyt2
->streambuf
, cinergyt2
->streambuf_dmahandle
);
288 static int cinergyt2_alloc_stream_urbs (struct cinergyt2
*cinergyt2
)
292 cinergyt2
->streambuf
= usb_buffer_alloc(cinergyt2
->udev
, STREAM_URB_COUNT
*STREAM_BUF_SIZE
,
293 GFP_KERNEL
, &cinergyt2
->streambuf_dmahandle
);
294 if (!cinergyt2
->streambuf
) {
295 dprintk(1, "failed to alloc consistent stream memory area, bailing out!\n");
299 memset(cinergyt2
->streambuf
, 0, STREAM_URB_COUNT
*STREAM_BUF_SIZE
);
301 for (i
=0; i
<STREAM_URB_COUNT
; i
++) {
304 if (!(urb
= usb_alloc_urb(0, GFP_ATOMIC
))) {
305 dprintk(1, "failed to alloc consistent stream urbs, bailing out!\n");
306 cinergyt2_free_stream_urbs(cinergyt2
);
310 urb
->transfer_buffer
= cinergyt2
->streambuf
+ i
* STREAM_BUF_SIZE
;
311 urb
->transfer_buffer_length
= STREAM_BUF_SIZE
;
313 cinergyt2
->stream_urb
[i
] = urb
;
319 static void cinergyt2_stop_stream_xfer (struct cinergyt2
*cinergyt2
)
323 cinergyt2_control_stream_transfer(cinergyt2
, 0);
325 for (i
=0; i
<STREAM_URB_COUNT
; i
++)
326 usb_kill_urb(cinergyt2
->stream_urb
[i
]);
329 static int cinergyt2_start_stream_xfer (struct cinergyt2
*cinergyt2
)
333 for (i
=0; i
<STREAM_URB_COUNT
; i
++) {
334 if ((err
= cinergyt2_submit_stream_urb(cinergyt2
, cinergyt2
->stream_urb
[i
]))) {
335 cinergyt2_stop_stream_xfer(cinergyt2
);
336 dprintk(1, "failed urb submission (%i: err = %i)!\n", i
, err
);
341 cinergyt2_control_stream_transfer(cinergyt2
, 1);
345 static int cinergyt2_start_feed(struct dvb_demux_feed
*dvbdmxfeed
)
347 struct dvb_demux
*demux
= dvbdmxfeed
->demux
;
348 struct cinergyt2
*cinergyt2
= demux
->priv
;
350 if (cinergyt2
->disconnect_pending
)
352 if (mutex_lock_interruptible(&cinergyt2
->sem
))
355 if (cinergyt2
->streaming
== 0)
356 cinergyt2_start_stream_xfer(cinergyt2
);
358 cinergyt2
->streaming
++;
359 mutex_unlock(&cinergyt2
->sem
);
363 static int cinergyt2_stop_feed(struct dvb_demux_feed
*dvbdmxfeed
)
365 struct dvb_demux
*demux
= dvbdmxfeed
->demux
;
366 struct cinergyt2
*cinergyt2
= demux
->priv
;
368 if (cinergyt2
->disconnect_pending
)
370 if (mutex_lock_interruptible(&cinergyt2
->sem
))
373 if (--cinergyt2
->streaming
== 0)
374 cinergyt2_stop_stream_xfer(cinergyt2
);
376 mutex_unlock(&cinergyt2
->sem
);
381 * convert linux-dvb frontend parameter set into TPS.
382 * See ETSI ETS-300744, section 4.6.2, table 9 for details.
384 * This function is probably reusable and may better get placed in a support
387 * We replace errornous fields by default TPS fields (the ones with value 0).
389 static uint16_t compute_tps (struct dvb_frontend_parameters
*p
)
391 struct dvb_ofdm_parameters
*op
= &p
->u
.ofdm
;
394 switch (op
->code_rate_HP
) {
410 /* tps |= (0 << 7) */;
413 switch (op
->code_rate_LP
) {
429 /* tps |= (0 << 4) */;
432 switch (op
->constellation
) {
441 /* tps |= (0 << 13) */;
444 switch (op
->transmission_mode
) {
445 case TRANSMISSION_MODE_8K
:
448 case TRANSMISSION_MODE_2K
:
450 /* tps |= (0 << 0) */;
453 switch (op
->guard_interval
) {
454 case GUARD_INTERVAL_1_16
:
457 case GUARD_INTERVAL_1_8
:
460 case GUARD_INTERVAL_1_4
:
463 case GUARD_INTERVAL_1_32
:
465 /* tps |= (0 << 2) */;
468 switch (op
->hierarchy_information
) {
480 /* tps |= (0 << 10) */;
486 static int cinergyt2_open (struct inode
*inode
, struct file
*file
)
488 struct dvb_device
*dvbdev
= file
->private_data
;
489 struct cinergyt2
*cinergyt2
= dvbdev
->priv
;
492 if (cinergyt2
->disconnect_pending
)
494 err
= mutex_lock_interruptible(&cinergyt2
->wq_sem
);
498 err
= mutex_lock_interruptible(&cinergyt2
->sem
);
502 if ((err
= dvb_generic_open(inode
, file
)))
505 if ((file
->f_flags
& O_ACCMODE
) != O_RDONLY
) {
506 cinergyt2_sleep(cinergyt2
, 0);
507 schedule_delayed_work(&cinergyt2
->query_work
, HZ
/2);
510 atomic_inc(&cinergyt2
->inuse
);
513 mutex_unlock(&cinergyt2
->sem
);
515 mutex_unlock(&cinergyt2
->wq_sem
);
520 static void cinergyt2_unregister(struct cinergyt2
*cinergyt2
)
522 dvb_net_release(&cinergyt2
->dvbnet
);
523 dvb_dmxdev_release(&cinergyt2
->dmxdev
);
524 dvb_dmx_release(&cinergyt2
->demux
);
525 dvb_unregister_device(cinergyt2
->fedev
);
526 dvb_unregister_adapter(&cinergyt2
->adapter
);
528 cinergyt2_free_stream_urbs(cinergyt2
);
532 static int cinergyt2_release (struct inode
*inode
, struct file
*file
)
534 struct dvb_device
*dvbdev
= file
->private_data
;
535 struct cinergyt2
*cinergyt2
= dvbdev
->priv
;
537 mutex_lock(&cinergyt2
->wq_sem
);
539 if (!cinergyt2
->disconnect_pending
&& (file
->f_flags
& O_ACCMODE
) != O_RDONLY
) {
540 cancel_rearming_delayed_work(&cinergyt2
->query_work
);
542 mutex_lock(&cinergyt2
->sem
);
543 cinergyt2_sleep(cinergyt2
, 1);
544 mutex_unlock(&cinergyt2
->sem
);
547 mutex_unlock(&cinergyt2
->wq_sem
);
549 if (atomic_dec_and_test(&cinergyt2
->inuse
) && cinergyt2
->disconnect_pending
) {
550 warn("delayed unregister in release");
551 cinergyt2_unregister(cinergyt2
);
554 return dvb_generic_release(inode
, file
);
557 static unsigned int cinergyt2_poll (struct file
*file
, struct poll_table_struct
*wait
)
559 struct dvb_device
*dvbdev
= file
->private_data
;
560 struct cinergyt2
*cinergyt2
= dvbdev
->priv
;
561 unsigned int mask
= 0;
563 if (cinergyt2
->disconnect_pending
)
565 if (mutex_lock_interruptible(&cinergyt2
->sem
))
568 poll_wait(file
, &cinergyt2
->poll_wq
, wait
);
570 if (cinergyt2
->pending_fe_events
!= 0)
571 mask
|= (POLLIN
| POLLRDNORM
| POLLPRI
);
573 mutex_unlock(&cinergyt2
->sem
);
579 static int cinergyt2_ioctl (struct inode
*inode
, struct file
*file
,
580 unsigned cmd
, unsigned long arg
)
582 struct dvb_device
*dvbdev
= file
->private_data
;
583 struct cinergyt2
*cinergyt2
= dvbdev
->priv
;
584 struct dvbt_get_status_msg
*stat
= &cinergyt2
->status
;
585 fe_status_t status
= 0;
589 return copy_to_user((void __user
*) arg
, &cinergyt2_fe_info
,
590 sizeof(struct dvb_frontend_info
));
593 if (0xffff - le16_to_cpu(stat
->gain
) > 30)
594 status
|= FE_HAS_SIGNAL
;
595 if (stat
->lock_bits
& (1 << 6))
596 status
|= FE_HAS_LOCK
;
597 if (stat
->lock_bits
& (1 << 5))
598 status
|= FE_HAS_SYNC
;
599 if (stat
->lock_bits
& (1 << 4))
600 status
|= FE_HAS_CARRIER
;
601 if (stat
->lock_bits
& (1 << 1))
602 status
|= FE_HAS_VITERBI
;
604 return copy_to_user((void __user
*) arg
, &status
, sizeof(status
));
607 return put_user(le32_to_cpu(stat
->viterbi_error_rate
),
608 (__u32 __user
*) arg
);
610 case FE_READ_SIGNAL_STRENGTH
:
611 return put_user(0xffff - le16_to_cpu(stat
->gain
),
612 (__u16 __user
*) arg
);
615 return put_user((stat
->snr
<< 8) | stat
->snr
,
616 (__u16 __user
*) arg
);
618 case FE_READ_UNCORRECTED_BLOCKS
:
622 unc_count
= stat
->uncorrected_block_count
;
623 stat
->uncorrected_block_count
= 0;
625 /* UNC are already converted to host byte order... */
626 return put_user(unc_count
,(__u32 __user
*) arg
);
628 case FE_SET_FRONTEND
:
630 struct dvbt_set_parameters_msg
*param
= &cinergyt2
->param
;
631 struct dvb_frontend_parameters p
;
634 if ((file
->f_flags
& O_ACCMODE
) == O_RDONLY
)
637 if (copy_from_user(&p
, (void __user
*) arg
, sizeof(p
)))
640 if (cinergyt2
->disconnect_pending
)
642 if (mutex_lock_interruptible(&cinergyt2
->sem
))
645 param
->cmd
= CINERGYT2_EP1_SET_TUNER_PARAMETERS
;
646 param
->tps
= cpu_to_le16(compute_tps(&p
));
647 param
->freq
= cpu_to_le32(p
.frequency
/ 1000);
648 param
->bandwidth
= 8 - p
.u
.ofdm
.bandwidth
- BANDWIDTH_8_MHZ
;
651 cinergyt2
->pending_fe_events
++;
652 wake_up_interruptible(&cinergyt2
->poll_wq
);
654 err
= cinergyt2_command(cinergyt2
,
655 (char *) param
, sizeof(*param
),
658 mutex_unlock(&cinergyt2
->sem
);
660 return (err
< 0) ? err
: 0;
663 case FE_GET_FRONTEND
:
665 * trivial to implement (see struct dvbt_get_status_msg).
666 * equivalent to FE_READ ioctls, but needs
667 * TPS -> linux-dvb parameter set conversion. Feel free
668 * to implement this and send us a patch if you need this
676 * for now we only fill the status field. the parameters
677 * are trivial to fill as soon FE_GET_FRONTEND is done.
679 struct dvb_frontend_event __user
*e
= (void __user
*) arg
;
680 if (cinergyt2
->pending_fe_events
== 0) {
681 if (file
->f_flags
& O_NONBLOCK
)
683 wait_event_interruptible(cinergyt2
->poll_wq
,
684 cinergyt2
->pending_fe_events
> 0);
686 cinergyt2
->pending_fe_events
= 0;
687 return cinergyt2_ioctl(inode
, file
, FE_READ_STATUS
,
688 (unsigned long) &e
->status
);
698 static int cinergyt2_mmap(struct file
*file
, struct vm_area_struct
*vma
)
700 struct dvb_device
*dvbdev
= file
->private_data
;
701 struct cinergyt2
*cinergyt2
= dvbdev
->priv
;
706 if (vma
->vm_flags
& (VM_WRITE
| VM_EXEC
)) {
711 if (vma
->vm_end
> vma
->vm_start
+ STREAM_URB_COUNT
* STREAM_BUF_SIZE
) {
716 vma
->vm_flags
|= (VM_IO
| VM_DONTCOPY
);
719 ret
= remap_pfn_range(vma
, vma
->vm_start
,
720 virt_to_phys(cinergyt2
->streambuf
) >> PAGE_SHIFT
,
721 vma
->vm_end
- vma
->vm_start
,
722 vma
->vm_page_prot
) ? -EAGAIN
: 0;
728 static struct file_operations cinergyt2_fops
= {
729 .owner
= THIS_MODULE
,
730 .ioctl
= cinergyt2_ioctl
,
731 .poll
= cinergyt2_poll
,
732 .open
= cinergyt2_open
,
733 .release
= cinergyt2_release
,
734 .mmap
= cinergyt2_mmap
737 static struct dvb_device cinergyt2_fe_template
= {
741 .fops
= &cinergyt2_fops
746 static void cinergyt2_query_rc (struct work_struct
*work
)
748 struct cinergyt2
*cinergyt2
=
749 container_of(work
, struct cinergyt2
, rc_query_work
.work
);
750 char buf
[1] = { CINERGYT2_EP1_GET_RC_EVENTS
};
751 struct cinergyt2_rc_event rc_events
[12];
754 if (cinergyt2
->disconnect_pending
|| mutex_lock_interruptible(&cinergyt2
->sem
))
757 len
= cinergyt2_command(cinergyt2
, buf
, sizeof(buf
),
758 (char *) rc_events
, sizeof(rc_events
));
762 if (time_after(jiffies
, cinergyt2
->last_event_jiffies
+
763 msecs_to_jiffies(150))) {
764 /* stop key repeat */
765 if (cinergyt2
->rc_input_event
!= KEY_MAX
) {
766 dprintk(1, "rc_input_event=%d Up\n", cinergyt2
->rc_input_event
);
767 input_report_key(cinergyt2
->rc_input_dev
,
768 cinergyt2
->rc_input_event
, 0);
769 input_sync(cinergyt2
->rc_input_dev
);
770 cinergyt2
->rc_input_event
= KEY_MAX
;
772 cinergyt2
->rc_last_code
= ~0;
776 cinergyt2
->last_event_jiffies
= jiffies
;
778 for (n
= 0; n
< (len
/ sizeof(rc_events
[0])); n
++) {
779 dprintk(1, "rc_events[%d].value = %x, type=%x\n",
780 n
, le32_to_cpu(rc_events
[n
].value
), rc_events
[n
].type
);
782 if (rc_events
[n
].type
== CINERGYT2_RC_EVENT_TYPE_NEC
&&
783 rc_events
[n
].value
== ~0) {
784 /* keyrepeat bit -> just repeat last rc_input_event */
786 cinergyt2
->rc_input_event
= KEY_MAX
;
787 for (i
= 0; i
< ARRAY_SIZE(rc_keys
); i
+= 3) {
788 if (rc_keys
[i
+ 0] == rc_events
[n
].type
&&
789 rc_keys
[i
+ 1] == le32_to_cpu(rc_events
[n
].value
)) {
790 cinergyt2
->rc_input_event
= rc_keys
[i
+ 2];
796 if (cinergyt2
->rc_input_event
!= KEY_MAX
) {
797 if (rc_events
[n
].value
== cinergyt2
->rc_last_code
&&
798 cinergyt2
->rc_last_code
!= ~0) {
799 /* emit a key-up so the double event is recognized */
800 dprintk(1, "rc_input_event=%d UP\n", cinergyt2
->rc_input_event
);
801 input_report_key(cinergyt2
->rc_input_dev
,
802 cinergyt2
->rc_input_event
, 0);
804 dprintk(1, "rc_input_event=%d\n", cinergyt2
->rc_input_event
);
805 input_report_key(cinergyt2
->rc_input_dev
,
806 cinergyt2
->rc_input_event
, 1);
807 input_sync(cinergyt2
->rc_input_dev
);
808 cinergyt2
->rc_last_code
= rc_events
[n
].value
;
813 schedule_delayed_work(&cinergyt2
->rc_query_work
,
814 msecs_to_jiffies(RC_QUERY_INTERVAL
));
816 mutex_unlock(&cinergyt2
->sem
);
819 static int cinergyt2_register_rc(struct cinergyt2
*cinergyt2
)
821 struct input_dev
*input_dev
;
825 input_dev
= input_allocate_device();
829 usb_make_path(cinergyt2
->udev
, cinergyt2
->phys
, sizeof(cinergyt2
->phys
));
830 strlcat(cinergyt2
->phys
, "/input0", sizeof(cinergyt2
->phys
));
831 cinergyt2
->rc_input_event
= KEY_MAX
;
832 cinergyt2
->rc_last_code
= ~0;
833 INIT_DELAYED_WORK(&cinergyt2
->rc_query_work
, cinergyt2_query_rc
);
835 input_dev
->name
= DRIVER_NAME
" remote control";
836 input_dev
->phys
= cinergyt2
->phys
;
837 input_dev
->evbit
[0] = BIT_MASK(EV_KEY
) | BIT_MASK(EV_REP
);
838 for (i
= 0; i
< ARRAY_SIZE(rc_keys
); i
+= 3)
839 set_bit(rc_keys
[i
+ 2], input_dev
->keybit
);
840 input_dev
->keycodesize
= 0;
841 input_dev
->keycodemax
= 0;
842 input_dev
->id
.bustype
= BUS_USB
;
843 input_dev
->id
.vendor
= cinergyt2
->udev
->descriptor
.idVendor
;
844 input_dev
->id
.product
= cinergyt2
->udev
->descriptor
.idProduct
;
845 input_dev
->id
.version
= 1;
846 input_dev
->dev
.parent
= &cinergyt2
->udev
->dev
;
848 err
= input_register_device(input_dev
);
850 input_free_device(input_dev
);
854 cinergyt2
->rc_input_dev
= input_dev
;
855 schedule_delayed_work(&cinergyt2
->rc_query_work
, HZ
/2);
860 static void cinergyt2_unregister_rc(struct cinergyt2
*cinergyt2
)
862 cancel_rearming_delayed_work(&cinergyt2
->rc_query_work
);
863 input_unregister_device(cinergyt2
->rc_input_dev
);
866 static inline void cinergyt2_suspend_rc(struct cinergyt2
*cinergyt2
)
868 cancel_rearming_delayed_work(&cinergyt2
->rc_query_work
);
871 static inline void cinergyt2_resume_rc(struct cinergyt2
*cinergyt2
)
873 schedule_delayed_work(&cinergyt2
->rc_query_work
, HZ
/2);
878 static inline int cinergyt2_register_rc(struct cinergyt2
*cinergyt2
) { return 0; }
879 static inline void cinergyt2_unregister_rc(struct cinergyt2
*cinergyt2
) { }
880 static inline void cinergyt2_suspend_rc(struct cinergyt2
*cinergyt2
) { }
881 static inline void cinergyt2_resume_rc(struct cinergyt2
*cinergyt2
) { }
883 #endif /* ENABLE_RC */
885 static void cinergyt2_query (struct work_struct
*work
)
887 struct cinergyt2
*cinergyt2
=
888 container_of(work
, struct cinergyt2
, query_work
.work
);
889 char cmd
[] = { CINERGYT2_EP1_GET_TUNER_STATUS
};
890 struct dvbt_get_status_msg
*s
= &cinergyt2
->status
;
894 if (cinergyt2
->disconnect_pending
|| mutex_lock_interruptible(&cinergyt2
->sem
))
897 unc
= s
->uncorrected_block_count
;
898 lock_bits
= s
->lock_bits
;
900 cinergyt2_command(cinergyt2
, cmd
, sizeof(cmd
), (char *) s
, sizeof(*s
));
902 unc
+= le32_to_cpu(s
->uncorrected_block_count
);
903 s
->uncorrected_block_count
= unc
;
905 if (lock_bits
!= s
->lock_bits
) {
906 wake_up_interruptible(&cinergyt2
->poll_wq
);
907 cinergyt2
->pending_fe_events
++;
910 schedule_delayed_work(&cinergyt2
->query_work
,
911 msecs_to_jiffies(QUERY_INTERVAL
));
913 mutex_unlock(&cinergyt2
->sem
);
916 static int cinergyt2_probe (struct usb_interface
*intf
,
917 const struct usb_device_id
*id
)
919 struct cinergyt2
*cinergyt2
;
922 if (!(cinergyt2
= kzalloc (sizeof(struct cinergyt2
), GFP_KERNEL
))) {
923 dprintk(1, "out of memory?!?\n");
927 usb_set_intfdata (intf
, (void *) cinergyt2
);
929 mutex_init(&cinergyt2
->sem
);
930 mutex_init(&cinergyt2
->wq_sem
);
931 init_waitqueue_head (&cinergyt2
->poll_wq
);
932 INIT_DELAYED_WORK(&cinergyt2
->query_work
, cinergyt2_query
);
934 cinergyt2
->udev
= interface_to_usbdev(intf
);
935 cinergyt2
->param
.cmd
= CINERGYT2_EP1_SET_TUNER_PARAMETERS
;
937 if (cinergyt2_alloc_stream_urbs (cinergyt2
) < 0) {
938 dprintk(1, "unable to allocate stream urbs\n");
943 err
= dvb_register_adapter(&cinergyt2
->adapter
, DRIVER_NAME
,
944 THIS_MODULE
, &cinergyt2
->udev
->dev
,
951 cinergyt2
->demux
.priv
= cinergyt2
;
952 cinergyt2
->demux
.filternum
= 256;
953 cinergyt2
->demux
.feednum
= 256;
954 cinergyt2
->demux
.start_feed
= cinergyt2_start_feed
;
955 cinergyt2
->demux
.stop_feed
= cinergyt2_stop_feed
;
956 cinergyt2
->demux
.dmx
.capabilities
= DMX_TS_FILTERING
|
957 DMX_SECTION_FILTERING
|
958 DMX_MEMORY_BASED_FILTERING
;
960 if ((err
= dvb_dmx_init(&cinergyt2
->demux
)) < 0) {
961 dprintk(1, "dvb_dmx_init() failed (err = %d)\n", err
);
965 cinergyt2
->dmxdev
.filternum
= cinergyt2
->demux
.filternum
;
966 cinergyt2
->dmxdev
.demux
= &cinergyt2
->demux
.dmx
;
967 cinergyt2
->dmxdev
.capabilities
= 0;
969 if ((err
= dvb_dmxdev_init(&cinergyt2
->dmxdev
, &cinergyt2
->adapter
)) < 0) {
970 dprintk(1, "dvb_dmxdev_init() failed (err = %d)\n", err
);
974 if (dvb_net_init(&cinergyt2
->adapter
, &cinergyt2
->dvbnet
, &cinergyt2
->demux
.dmx
))
975 dprintk(1, "dvb_net_init() failed!\n");
977 dvb_register_device(&cinergyt2
->adapter
, &cinergyt2
->fedev
,
978 &cinergyt2_fe_template
, cinergyt2
,
979 DVB_DEVICE_FRONTEND
);
981 err
= cinergyt2_register_rc(cinergyt2
);
988 dvb_net_release(&cinergyt2
->dvbnet
);
989 dvb_dmxdev_release(&cinergyt2
->dmxdev
);
990 dvb_dmx_release(&cinergyt2
->demux
);
991 dvb_unregister_adapter(&cinergyt2
->adapter
);
992 cinergyt2_free_stream_urbs(cinergyt2
);
997 static void cinergyt2_disconnect (struct usb_interface
*intf
)
999 struct cinergyt2
*cinergyt2
= usb_get_intfdata (intf
);
1001 cinergyt2_unregister_rc(cinergyt2
);
1002 cancel_rearming_delayed_work(&cinergyt2
->query_work
);
1003 wake_up_interruptible(&cinergyt2
->poll_wq
);
1005 cinergyt2
->demux
.dmx
.close(&cinergyt2
->demux
.dmx
);
1006 cinergyt2
->disconnect_pending
= 1;
1008 if (!atomic_read(&cinergyt2
->inuse
))
1009 cinergyt2_unregister(cinergyt2
);
1012 static int cinergyt2_suspend (struct usb_interface
*intf
, pm_message_t state
)
1014 struct cinergyt2
*cinergyt2
= usb_get_intfdata (intf
);
1016 if (cinergyt2
->disconnect_pending
)
1018 if (mutex_lock_interruptible(&cinergyt2
->wq_sem
))
1019 return -ERESTARTSYS
;
1021 cinergyt2_suspend_rc(cinergyt2
);
1022 cancel_rearming_delayed_work(&cinergyt2
->query_work
);
1024 mutex_lock(&cinergyt2
->sem
);
1025 if (cinergyt2
->streaming
)
1026 cinergyt2_stop_stream_xfer(cinergyt2
);
1027 cinergyt2_sleep(cinergyt2
, 1);
1028 mutex_unlock(&cinergyt2
->sem
);
1030 mutex_unlock(&cinergyt2
->wq_sem
);
1035 static int cinergyt2_resume (struct usb_interface
*intf
)
1037 struct cinergyt2
*cinergyt2
= usb_get_intfdata (intf
);
1038 struct dvbt_set_parameters_msg
*param
= &cinergyt2
->param
;
1041 if (cinergyt2
->disconnect_pending
)
1043 err
= mutex_lock_interruptible(&cinergyt2
->wq_sem
);
1047 err
= mutex_lock_interruptible(&cinergyt2
->sem
);
1051 if (!cinergyt2
->sleeping
) {
1052 cinergyt2_sleep(cinergyt2
, 0);
1053 cinergyt2_command(cinergyt2
, (char *) param
, sizeof(*param
), NULL
, 0);
1054 if (cinergyt2
->streaming
)
1055 cinergyt2_start_stream_xfer(cinergyt2
);
1056 schedule_delayed_work(&cinergyt2
->query_work
, HZ
/2);
1059 cinergyt2_resume_rc(cinergyt2
);
1061 mutex_unlock(&cinergyt2
->sem
);
1063 mutex_unlock(&cinergyt2
->wq_sem
);
1068 static const struct usb_device_id cinergyt2_table
[] __devinitdata
= {
1069 { USB_DEVICE(0x0ccd, 0x0038) },
1073 MODULE_DEVICE_TABLE(usb
, cinergyt2_table
);
1075 static struct usb_driver cinergyt2_driver
= {
1076 .name
= "cinergyT2",
1077 .probe
= cinergyt2_probe
,
1078 .disconnect
= cinergyt2_disconnect
,
1079 .suspend
= cinergyt2_suspend
,
1080 .resume
= cinergyt2_resume
,
1081 .id_table
= cinergyt2_table
1084 static int __init
cinergyt2_init (void)
1088 if ((err
= usb_register(&cinergyt2_driver
)) < 0)
1089 dprintk(1, "usb_register() failed! (err %i)\n", err
);
1094 static void __exit
cinergyt2_exit (void)
1096 usb_deregister(&cinergyt2_driver
);
1099 module_init (cinergyt2_init
);
1100 module_exit (cinergyt2_exit
);
1102 MODULE_LICENSE("GPL");
1103 MODULE_AUTHOR("Holger Waechtler, Daniel Mack");