aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/hdpvr/hdpvr-core.c
diff options
context:
space:
mode:
authorJanne Grunau <j@jannau.net>2009-03-18 17:10:04 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:28 -0400
commit9aba42efe85bc7a55e3fed0747ce14abc9ee96e7 (patch)
treeee27b9d4844da17b4d4bb80132991f29d04ff265 /drivers/media/video/hdpvr/hdpvr-core.c
parent8c84cfda3e37540abc38f42383b03dd69829faee (diff)
V4L/DVB (11096): V4L2 Driver for the Hauppauge HD PVR usb capture device
The device encodes component video up to 1080i to a MPEG-TS stream with H.264 video and stereo AAC audio. Newer firmwares accept also AC3 (up to 5.1) audio over optical SPDIF without reencoding. Firmware upgrade is unimplemeted but rather unimportant since the firmware sits on a flash chip. The I2C adapter to drive the integrated infrared receiver/sender is currently disabled due to a conflict with cx18-based devices. Tested-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: Janne Grunau <j@jannau.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/hdpvr/hdpvr-core.c')
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c439
1 files changed, 439 insertions, 0 deletions
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
new file mode 100644
index 000000000000..e7300b570bb7
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -0,0 +1,439 @@
1/*
2 * Hauppage HD PVR USB driver
3 *
4 * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2008 Janne Grunau (j@jannau.net)
6 * Copyright (C) 2008 John Poet
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, version 2.
11 *
12 */
13
14#include <linux/kernel.h>
15#include <linux/errno.h>
16#include <linux/init.h>
17#include <linux/slab.h>
18#include <linux/module.h>
19#include <linux/uaccess.h>
20#include <asm/atomic.h>
21#include <linux/usb.h>
22#include <linux/mutex.h>
23#include <linux/i2c.h>
24
25#include <linux/videodev2.h>
26#include <media/v4l2-dev.h>
27#include <media/v4l2-common.h>
28
29#include "hdpvr.h"
30
31static int video_nr[HDPVR_MAX] = {[0 ... (HDPVR_MAX - 1)] = UNSET};
32module_param_array(video_nr, int, NULL, 0);
33MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
34
35/* holds the number of currently registered devices */
36static atomic_t dev_nr = ATOMIC_INIT(-1);
37
38int hdpvr_debug;
39module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR);
40MODULE_PARM_DESC(hdpvr_debug, "enable debugging output");
41
42uint default_video_input = HDPVR_VIDEO_INPUTS;
43module_param(default_video_input, uint, S_IRUGO|S_IWUSR);
44MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / "
45 "1=S-Video / 2=Composite");
46
47uint default_audio_input = HDPVR_AUDIO_INPUTS;
48module_param(default_audio_input, uint, S_IRUGO|S_IWUSR);
49MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / "
50 "1=RCA front / 2=S/PDIF");
51
52static int boost_audio;
53module_param(boost_audio, bool, S_IRUGO|S_IWUSR);
54MODULE_PARM_DESC(boost_audio, "boost the audio signal");
55
56
57/* table of devices that work with this driver */
58static struct usb_device_id hdpvr_table[] = {
59 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) },
60 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) },
61 { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) },
62 { } /* Terminating entry */
63};
64MODULE_DEVICE_TABLE(usb, hdpvr_table);
65
66
67void hdpvr_delete(struct hdpvr_device *dev)
68{
69 hdpvr_free_buffers(dev);
70
71 if (dev->video_dev)
72 video_device_release(dev->video_dev);
73
74 usb_put_dev(dev->udev);
75}
76
77static void challenge(u8 *bytes)
78{
79 u64 *i64P, tmp64;
80 uint i, idx;
81
82 for (idx = 0; idx < 32; ++idx) {
83
84 if (idx & 0x3)
85 bytes[(idx >> 3) + 3] = bytes[(idx >> 2) & 0x3];
86
87 switch (idx & 0x3) {
88 case 0x3:
89 bytes[2] += bytes[3] * 4 + bytes[4] + bytes[5];
90 bytes[4] += bytes[(idx & 0x1) * 2] * 9 + 9;
91 break;
92 case 0x1:
93 bytes[0] *= 8;
94 bytes[0] += 7*idx + 4;
95 bytes[6] += bytes[3] * 3;
96 break;
97 case 0x0:
98 bytes[3 - (idx >> 3)] = bytes[idx >> 2];
99 bytes[5] += bytes[6] * 3;
100 for (i = 0; i < 3; i++)
101 bytes[3] *= bytes[3] + 1;
102 break;
103 case 0x2:
104 for (i = 0; i < 3; i++)
105 bytes[1] *= bytes[6] + 1;
106 for (i = 0; i < 3; i++) {
107 i64P = (u64 *)bytes;
108 tmp64 = le64_to_cpup(i64P);
109 tmp64 <<= bytes[7] & 0x0f;
110 *i64P += cpu_to_le64(tmp64);
111 }
112 break;
113 }
114 }
115}
116
117/* try to init the device like the windows driver */
118static int device_authorization(struct hdpvr_device *dev)
119{
120
121 int ret, retval = -ENOMEM;
122 char request_type = 0x38, rcv_request = 0x81;
123 char *response;
124#ifdef HDPVR_DEBUG
125 size_t buf_size = 46;
126 char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
127 if (!print_buf) {
128 dev_err(&dev->udev->dev, "Out of memory");
129 goto error;
130 }
131#endif
132
133 mutex_lock(&dev->usbc_mutex);
134 ret = usb_control_msg(dev->udev,
135 usb_rcvctrlpipe(dev->udev, 0),
136 rcv_request, 0x80 | request_type,
137 0x0400, 0x0003,
138 dev->usbc_buf, 46,
139 10000);
140 if (ret != 46) {
141 dev_err(&dev->udev->dev,
142 "unexpected answer of status request, len %d", ret);
143 goto error;
144 }
145#ifdef HDPVR_DEBUG
146 else {
147 hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf,
148 sizeof(print_buf), 0);
149 dev_dbg(&dev->udev->dev,
150 "Status request returned, len %d: %s\n",
151 ret, print_buf);
152 }
153#endif
154 if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION) {
155 dev->flags &= ~HDPVR_FLAG_AC3_CAP;
156 } else if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION_AC3) {
157 dev->flags |= HDPVR_FLAG_AC3_CAP;
158 } else if (dev->usbc_buf[1] > HDPVR_FIRMWARE_VERSION_AC3) {
159 dev_notice(&dev->udev->dev, "untested firmware version 0x%x, "
160 "the driver might not work\n", dev->usbc_buf[1]);
161 dev->flags |= HDPVR_FLAG_AC3_CAP;
162 } else {
163 dev_err(&dev->udev->dev, "unknown firmware version 0x%x\n",
164 dev->usbc_buf[1]);
165 ret = -EINVAL;
166 goto error;
167 }
168
169 response = dev->usbc_buf+38;
170#ifdef HDPVR_DEBUG
171 hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
172 dev_dbg(&dev->udev->dev, "challenge: %s\n", print_buf);
173#endif
174 challenge(response);
175#ifdef HDPVR_DEBUG
176 hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
177 dev_dbg(&dev->udev->dev, " response: %s\n", print_buf);
178#endif
179
180 msleep(100);
181 ret = usb_control_msg(dev->udev,
182 usb_sndctrlpipe(dev->udev, 0),
183 0xd1, 0x00 | request_type,
184 0x0000, 0x0000,
185 response, 8,
186 10000);
187 dev_dbg(&dev->udev->dev, "magic request returned %d\n", ret);
188 mutex_unlock(&dev->usbc_mutex);
189
190 retval = ret != 8;
191error:
192 return retval;
193}
194
195static int hdpvr_device_init(struct hdpvr_device *dev)
196{
197 int ret;
198 u8 *buf;
199 struct hdpvr_video_info *vidinf;
200
201 if (device_authorization(dev))
202 return -EACCES;
203
204 /* default options for init */
205 hdpvr_set_options(dev);
206
207 /* set filter options */
208 mutex_lock(&dev->usbc_mutex);
209 buf = dev->usbc_buf;
210 buf[0] = 0x03; buf[1] = 0x03; buf[2] = 0x00; buf[3] = 0x00;
211 ret = usb_control_msg(dev->udev,
212 usb_sndctrlpipe(dev->udev, 0),
213 0x01, 0x38,
214 CTRL_LOW_PASS_FILTER_VALUE, CTRL_DEFAULT_INDEX,
215 buf, 4,
216 1000);
217 dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
218 mutex_unlock(&dev->usbc_mutex);
219
220 vidinf = get_video_info(dev);
221 if (!vidinf)
222 dev_dbg(&dev->udev->dev,
223 "no valid video signal or device init failed\n");
224 else
225 kfree(vidinf);
226
227 /* enable fan and bling leds */
228 mutex_lock(&dev->usbc_mutex);
229 buf[0] = 0x1;
230 ret = usb_control_msg(dev->udev,
231 usb_sndctrlpipe(dev->udev, 0),
232 0xd4, 0x38, 0, 0, buf, 1,
233 1000);
234 dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
235
236 /* boost analog audio */
237 buf[0] = boost_audio;
238 ret = usb_control_msg(dev->udev,
239 usb_sndctrlpipe(dev->udev, 0),
240 0xd5, 0x38, 0, 0, buf, 1,
241 1000);
242 dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
243 mutex_unlock(&dev->usbc_mutex);
244
245 dev->status = STATUS_IDLE;
246 return 0;
247}
248
249static const struct hdpvr_options hdpvr_default_options = {
250 .video_std = HDPVR_60HZ,
251 .video_input = HDPVR_COMPONENT,
252 .audio_input = HDPVR_RCA_BACK,
253 .bitrate = 65, /* 6 mbps */
254 .peak_bitrate = 90, /* 9 mbps */
255 .bitrate_mode = HDPVR_CONSTANT,
256 .gop_mode = HDPVR_SIMPLE_IDR_GOP,
257 .audio_codec = V4L2_MPEG_AUDIO_ENCODING_AAC,
258 .brightness = 0x86,
259 .contrast = 0x80,
260 .hue = 0x80,
261 .saturation = 0x80,
262 .sharpness = 0x80,
263};
264
265static int hdpvr_probe(struct usb_interface *interface,
266 const struct usb_device_id *id)
267{
268 struct hdpvr_device *dev;
269 struct usb_host_interface *iface_desc;
270 struct usb_endpoint_descriptor *endpoint;
271 size_t buffer_size;
272 int i;
273 int retval = -ENOMEM;
274
275 /* allocate memory for our device state and initialize it */
276 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
277 if (!dev) {
278 err("Out of memory");
279 goto error;
280 }
281 mutex_init(&dev->io_mutex);
282 mutex_init(&dev->i2c_mutex);
283 mutex_init(&dev->usbc_mutex);
284 dev->usbc_buf = kmalloc(64, GFP_KERNEL);
285 if (!dev->usbc_buf) {
286 dev_err(&dev->udev->dev, "Out of memory");
287 goto error;
288 }
289
290 init_waitqueue_head(&dev->wait_buffer);
291 init_waitqueue_head(&dev->wait_data);
292
293 dev->workqueue = create_singlethread_workqueue("hdpvr_buffer");
294 if (!dev->workqueue)
295 goto error;
296
297 /* init video transfer queues */
298 INIT_LIST_HEAD(&dev->free_buff_list);
299 INIT_LIST_HEAD(&dev->rec_buff_list);
300
301 dev->options = hdpvr_default_options;
302
303 if (default_video_input < HDPVR_VIDEO_INPUTS)
304 dev->options.video_input = default_video_input;
305
306 if (default_audio_input < HDPVR_AUDIO_INPUTS)
307 dev->options.audio_input = default_audio_input;
308
309 dev->udev = usb_get_dev(interface_to_usbdev(interface));
310
311 /* set up the endpoint information */
312 /* use only the first bulk-in and bulk-out endpoints */
313 iface_desc = interface->cur_altsetting;
314 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
315 endpoint = &iface_desc->endpoint[i].desc;
316
317 if (!dev->bulk_in_endpointAddr &&
318 usb_endpoint_is_bulk_in(endpoint)) {
319 /* USB interface description is buggy, reported max
320 * packet size is 512 bytes, windows driver uses 8192 */
321 buffer_size = 8192;
322 dev->bulk_in_size = buffer_size;
323 dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
324 }
325
326 }
327 if (!dev->bulk_in_endpointAddr) {
328 err("Could not find bulk-in endpoint");
329 goto error;
330 }
331
332 /* init the device */
333 if (hdpvr_device_init(dev)) {
334 err("device init failed");
335 goto error;
336 }
337
338 mutex_lock(&dev->io_mutex);
339 if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) {
340 err("allocating transfer buffers failed");
341 goto error;
342 }
343 mutex_unlock(&dev->io_mutex);
344
345 if (hdpvr_register_videodev(dev,
346 video_nr[atomic_inc_return(&dev_nr)])) {
347 err("registering videodev failed");
348 goto error;
349 }
350
351
352 /* save our data pointer in this interface device */
353 usb_set_intfdata(interface, dev);
354
355 /* let the user know what node this device is now attached to */
356 v4l2_info(dev->video_dev, "device now attached to /dev/video%d\n",
357 dev->video_dev->minor);
358 return 0;
359
360error:
361 if (dev) {
362 mutex_unlock(&dev->io_mutex);
363 /* this frees allocated memory */
364 hdpvr_delete(dev);
365 }
366 return retval;
367}
368
369static void hdpvr_disconnect(struct usb_interface *interface)
370{
371 struct hdpvr_device *dev;
372 int minor;
373
374 dev = usb_get_intfdata(interface);
375 usb_set_intfdata(interface, NULL);
376
377 minor = dev->video_dev->minor;
378
379 /* prevent more I/O from starting and stop any ongoing */
380 mutex_lock(&dev->io_mutex);
381 dev->status = STATUS_DISCONNECTED;
382 video_unregister_device(dev->video_dev);
383 wake_up_interruptible(&dev->wait_data);
384 wake_up_interruptible(&dev->wait_buffer);
385 msleep(100);
386 flush_workqueue(dev->workqueue);
387 hdpvr_cancel_queue(dev);
388 destroy_workqueue(dev->workqueue);
389 mutex_unlock(&dev->io_mutex);
390
391 /* deregister I2C adapter */
392 mutex_lock(&dev->i2c_mutex);
393 if (dev->i2c_adapter)
394 i2c_del_adapter(dev->i2c_adapter);
395 kfree(dev->i2c_adapter);
396 dev->i2c_adapter = NULL;
397 mutex_unlock(&dev->i2c_mutex);
398
399 atomic_dec(&dev_nr);
400
401 printk(KERN_INFO "Hauppauge HD PVR: device /dev/video%d disconnected\n",
402 minor);
403
404 kfree(dev->usbc_buf);
405 kfree(dev);
406}
407
408
409static struct usb_driver hdpvr_usb_driver = {
410 .name = "hdpvr",
411 .probe = hdpvr_probe,
412 .disconnect = hdpvr_disconnect,
413 .id_table = hdpvr_table,
414};
415
416static int __init hdpvr_init(void)
417{
418 int result;
419
420 /* register this driver with the USB subsystem */
421 result = usb_register(&hdpvr_usb_driver);
422 if (result)
423 err("usb_register failed. Error number %d", result);
424
425 return result;
426}
427
428static void __exit hdpvr_exit(void)
429{
430 /* deregister this driver with the USB subsystem */
431 usb_deregister(&hdpvr_usb_driver);
432}
433
434module_init(hdpvr_init);
435module_exit(hdpvr_exit);
436
437MODULE_LICENSE("GPL");
438MODULE_AUTHOR("Janne Grunau");
439MODULE_DESCRIPTION("Hauppauge HD PVR driver");