static int usbtv_select_norm(struct usbtv *usbtv, v4l2_std_id norm) { int ret; static const u16 pal[][2] = { { USBTV_BASE + 0x001a, 0x0068 }, { USBTV_BASE + 0x010e, 0x0072 }, { USBTV_BASE + 0x010f, 0x00a2 }, { USBTV_BASE + 0x0112, 0x00b0 }, { USBTV_BASE + 0x0117, 0x0001 }, { USBTV_BASE + 0x0118, 0x002c }, { USBTV_BASE + 0x012d, 0x0010 }, { USBTV_BASE + 0x012f, 0x0020 }, { USBTV_BASE + 0x024f, 0x0002 }, { USBTV_BASE + 0x0254, 0x0059 }, { USBTV_BASE + 0x025a, 0x0016 }, { USBTV_BASE + 0x025b, 0x0035 }, { USBTV_BASE + 0x0263, 0x0017 }, { USBTV_BASE + 0x0266, 0x0016 }, { USBTV_BASE + 0x0267, 0x0036 } }; static const u16 ntsc[][2] = { { USBTV_BASE + 0x001a, 0x0079 }, { USBTV_BASE + 0x010e, 0x0068 }, { USBTV_BASE + 0x010f, 0x009c }, { USBTV_BASE + 0x0112, 0x00f0 }, { USBTV_BASE + 0x0117, 0x0000 }, { USBTV_BASE + 0x0118, 0x00fc }, { USBTV_BASE + 0x012d, 0x0004 }, { USBTV_BASE + 0x012f, 0x0008 }, { USBTV_BASE + 0x024f, 0x0001 }, { USBTV_BASE + 0x0254, 0x005f }, { USBTV_BASE + 0x025a, 0x0012 }, { USBTV_BASE + 0x025b, 0x0001 }, { USBTV_BASE + 0x0263, 0x001c }, { USBTV_BASE + 0x0266, 0x0011 }, { USBTV_BASE + 0x0267, 0x0005 } }; ret = usbtv_configure_for_norm(usbtv, norm); if (!ret) { if (norm & V4L2_STD_525_60) ret = usbtv_set_regs(usbtv, ntsc, ARRAY_SIZE(ntsc)); else if (norm & V4L2_STD_PAL) ret = usbtv_set_regs(usbtv, pal, ARRAY_SIZE(pal)); } return ret; }
static int usbtv_audio_start(struct usbtv *chip) { unsigned int pipe; static const u16 setup[][2] = { /* These seem to enable the device. */ { USBTV_BASE + 0x0008, 0x0001 }, { USBTV_BASE + 0x01d0, 0x00ff }, { USBTV_BASE + 0x01d9, 0x0002 }, { USBTV_BASE + 0x01da, 0x0013 }, { USBTV_BASE + 0x01db, 0x0012 }, { USBTV_BASE + 0x01e9, 0x0002 }, { USBTV_BASE + 0x01ec, 0x006c }, { USBTV_BASE + 0x0294, 0x0020 }, { USBTV_BASE + 0x0255, 0x00cf }, { USBTV_BASE + 0x0256, 0x0020 }, { USBTV_BASE + 0x01eb, 0x0030 }, { USBTV_BASE + 0x027d, 0x00a6 }, { USBTV_BASE + 0x0280, 0x0011 }, { USBTV_BASE + 0x0281, 0x0040 }, { USBTV_BASE + 0x0282, 0x0011 }, { USBTV_BASE + 0x0283, 0x0040 }, { 0xf891, 0x0010 }, /* this sets the input from composite */ { USBTV_BASE + 0x0284, 0x00aa }, }; chip->snd_bulk_urb = usb_alloc_urb(0, GFP_KERNEL); if (chip->snd_bulk_urb == NULL) goto err_alloc_urb; pipe = usb_rcvbulkpipe(chip->udev, USBTV_AUDIO_ENDP); chip->snd_bulk_urb->transfer_buffer = kzalloc( USBTV_AUDIO_URBSIZE, GFP_KERNEL); if (chip->snd_bulk_urb->transfer_buffer == NULL) goto err_transfer_buffer; usb_fill_bulk_urb(chip->snd_bulk_urb, chip->udev, pipe, chip->snd_bulk_urb->transfer_buffer, USBTV_AUDIO_URBSIZE, usbtv_audio_urb_received, chip); /* starting the stream */ usbtv_set_regs(chip, setup, ARRAY_SIZE(setup)); usb_clear_halt(chip->udev, pipe); usb_submit_urb(chip->snd_bulk_urb, GFP_ATOMIC); return 0; err_transfer_buffer: usb_free_urb(chip->snd_bulk_urb); chip->snd_bulk_urb = NULL; err_alloc_urb: return -ENOMEM; }
static int usbtv_select_input(struct usbtv *usbtv, int input) { int ret; static const u16 composite[][2] = { { USBTV_BASE + 0x0105, 0x0060 }, { USBTV_BASE + 0x011f, 0x00f2 }, { USBTV_BASE + 0x0127, 0x0060 }, { USBTV_BASE + 0x00ae, 0x0010 }, { USBTV_BASE + 0x0284, 0x00aa }, { USBTV_BASE + 0x0239, 0x0060 }, }; static const u16 svideo[][2] = { { USBTV_BASE + 0x0105, 0x0010 }, { USBTV_BASE + 0x011f, 0x00ff }, { USBTV_BASE + 0x0127, 0x0060 }, { USBTV_BASE + 0x00ae, 0x0030 }, { USBTV_BASE + 0x0284, 0x0088 }, { USBTV_BASE + 0x0239, 0x0060 }, }; switch (input) { case USBTV_COMPOSITE_INPUT: ret = usbtv_set_regs(usbtv, composite, ARRAY_SIZE(composite)); break; case USBTV_SVIDEO_INPUT: ret = usbtv_set_regs(usbtv, svideo, ARRAY_SIZE(svideo)); break; default: ret = -EINVAL; } if (!ret) usbtv->input = input; return ret; }
static int usbtv_audio_stop(struct usbtv *chip) { static const u16 setup[][2] = { /* The original windows driver sometimes sends also: * { USBTV_BASE + 0x00a2, 0x0013 } * but it seems useless and its real effects are untested at * the moment. */ { USBTV_BASE + 0x027d, 0x0000 }, { USBTV_BASE + 0x0280, 0x0010 }, { USBTV_BASE + 0x0282, 0x0010 }, }; if (chip->snd_bulk_urb) { usb_kill_urb(chip->snd_bulk_urb); kfree(chip->snd_bulk_urb->transfer_buffer); usb_free_urb(chip->snd_bulk_urb); chip->snd_bulk_urb = NULL; } usbtv_set_regs(chip, setup, ARRAY_SIZE(setup)); return 0; }
static int usbtv_setup_capture(struct usbtv *usbtv) { int ret; static const u16 setup[][2] = { /* These seem to enable the device. */ { USBTV_BASE + 0x0008, 0x0001 }, { USBTV_BASE + 0x01d0, 0x00ff }, { USBTV_BASE + 0x01d9, 0x0002 }, /* These seem to influence color parameters, such as * brightness, etc. */ { USBTV_BASE + 0x0239, 0x0040 }, { USBTV_BASE + 0x0240, 0x0000 }, { USBTV_BASE + 0x0241, 0x0000 }, { USBTV_BASE + 0x0242, 0x0002 }, { USBTV_BASE + 0x0243, 0x0080 }, { USBTV_BASE + 0x0244, 0x0012 }, { USBTV_BASE + 0x0245, 0x0090 }, { USBTV_BASE + 0x0246, 0x0000 }, { USBTV_BASE + 0x0278, 0x002d }, { USBTV_BASE + 0x0279, 0x000a }, { USBTV_BASE + 0x027a, 0x0032 }, { 0xf890, 0x000c }, { 0xf894, 0x0086 }, { USBTV_BASE + 0x00ac, 0x00c0 }, { USBTV_BASE + 0x00ad, 0x0000 }, { USBTV_BASE + 0x00a2, 0x0012 }, { USBTV_BASE + 0x00a3, 0x00e0 }, { USBTV_BASE + 0x00a4, 0x0028 }, { USBTV_BASE + 0x00a5, 0x0082 }, { USBTV_BASE + 0x00a7, 0x0080 }, { USBTV_BASE + 0x0000, 0x0014 }, { USBTV_BASE + 0x0006, 0x0003 }, { USBTV_BASE + 0x0090, 0x0099 }, { USBTV_BASE + 0x0091, 0x0090 }, { USBTV_BASE + 0x0094, 0x0068 }, { USBTV_BASE + 0x0095, 0x0070 }, { USBTV_BASE + 0x009c, 0x0030 }, { USBTV_BASE + 0x009d, 0x00c0 }, { USBTV_BASE + 0x009e, 0x00e0 }, { USBTV_BASE + 0x0019, 0x0006 }, { USBTV_BASE + 0x008c, 0x00ba }, { USBTV_BASE + 0x0101, 0x00ff }, { USBTV_BASE + 0x010c, 0x00b3 }, { USBTV_BASE + 0x01b2, 0x0080 }, { USBTV_BASE + 0x01b4, 0x00a0 }, { USBTV_BASE + 0x014c, 0x00ff }, { USBTV_BASE + 0x014d, 0x00ca }, { USBTV_BASE + 0x0113, 0x0053 }, { USBTV_BASE + 0x0119, 0x008a }, { USBTV_BASE + 0x013c, 0x0003 }, { USBTV_BASE + 0x0150, 0x009c }, { USBTV_BASE + 0x0151, 0x0071 }, { USBTV_BASE + 0x0152, 0x00c6 }, { USBTV_BASE + 0x0153, 0x0084 }, { USBTV_BASE + 0x0154, 0x00bc }, { USBTV_BASE + 0x0155, 0x00a0 }, { USBTV_BASE + 0x0156, 0x00a0 }, { USBTV_BASE + 0x0157, 0x009c }, { USBTV_BASE + 0x0158, 0x001f }, { USBTV_BASE + 0x0159, 0x0006 }, { USBTV_BASE + 0x015d, 0x0000 }, { USBTV_BASE + 0x0003, 0x0004 }, { USBTV_BASE + 0x0100, 0x00d3 }, { USBTV_BASE + 0x0115, 0x0015 }, { USBTV_BASE + 0x0220, 0x002e }, { USBTV_BASE + 0x0225, 0x0008 }, { USBTV_BASE + 0x024e, 0x0002 }, { USBTV_BASE + 0x024e, 0x0002 }, { USBTV_BASE + 0x024f, 0x0002 }, }; ret = usbtv_set_regs(usbtv, setup, ARRAY_SIZE(setup)); if (ret) return ret; ret = usbtv_select_norm(usbtv, usbtv->norm); if (ret) return ret; ret = usbtv_select_input(usbtv, usbtv->input); if (ret) return ret; return 0; }