Archived:Em2820
Currently supported devices
The em2820 driver should support:
- Pinnacle Systems PCTV USB2 (Audio/Video OK)
- MSI VOX USB-TV
- Terratec Cinergy 250 USB TV (AV OK)
- Gadmei UTV310 has generic empia vendor/product ID Em2820/gadmei_utv_310
- Hauppauge WinTV-USB2 (no sound yet?)
- Leadtek WinFast USB2 (AV OK)
- Hercules Smart TV USB2
- V-Gear PocketTV (AV OK) Em2820/vgear
- KWORLD PVR-TV 2800RF USB 2 Em2820/kworld
- Usbgear VD204 USB 2.0 Em2820/usbgear-vd204
- ZEB - TV2005E(USB) http://www.zebronics.net/tvtunercard.asp
- Videology 21K15x-USB camera (supported by the new em28xx driver, http://linuxtv.org/hg/~mrechberger/v4l-dvb)
- The em2880 is a more complete driver which supports all these devices and more. See Em2880.
News
Di Sep 27 23:11:07 CEST 2005
catch the fish! the driver is public
video4linux news:
We are creating a newer tree to join V4L projects that are not yet ready to go to kernel. The main idea is to have a centralized point for V4L development. Experimental projects will stay at v4l_experimental until: 1) providing V4L2 API support; 2) don't providing other non-kernel API; 3) having CodingStyle; 4) being stable enough. After having these conditions, the project (or drivers) will be migrated to V4L tree and follow the normal development cycle. Currently, there's a new project on that, providing support for Empiatech USB based boards with em2820 and em2840. Boards currently supported: *) Terratec Cinergy 250 USB - video decoder: saa7113; *) Pinnacle PCTV USB 2 - video decoder: saa7113; *) Hauppauge WinTV USB 2 (model 42012 Rev C186) - video decoder: tvp5150am1, audio decoder: msp3445G. The latest one still lacks audio support. Video is ok. For those who want to help, CVS version is provided at linuxtv.org: cvs -d :pserver:anonymous@cvs.linuxtv.org:/cvs/video4linux login cvs -d :pserver:anonymous@cvs.linuxtv.org:/cvs/video4linux co -P v4l_experimental Cheers, Mauro.
Markus Rechberger
Sa Sep 24 14:37:29 CEST 2005
the driver gets prepared for joining the video4linux package, and finally to get into the linux kernel :)
Mon Sep 19 23:04:20 CEST 2005
on wednesday we'll know how to go on with the development, if everything turns out in a good way we'll release the driver and turn our CVS public
Markus Rechberger
Sa Sep 10 16:33:47 CEST 2005
getting digital audio work (don't expect too much the snd_usb_audio driver does no error checking so it might even lock up your keyboard):
mplayer -zoom -tv amode=1:input=2:norm=PAL:driver=v4l2:alsa:width=720:height=576:outfmt=yuy2:adevice=hw.0:forceaudio tv:// sox -t ossdsp -r 48000 -b -c 2 /dev/dsp -t ossdsp /dev/dsp2
this should work with the latest driver (just requested Empia for persission to distribute it!).
Markus Rechberger
Sun Sep 4 16:13:23 CEST 2005
We have started implementing some features based on the specs from empia. As soon as we have some cleaner and stable code, we will submit it to empia and release it.
Here is some detail about the status: setting video size is working with most resolutions; mplayer, xawtv and tvtime are working. We managed to mute/unmute audio for both analog external cable and USB transfer. All three video (tuner, composite and s-video) with relative audio sources (tuner and line in) are working.
I have managed to acquire three hours of video and audio from a VCR (although the isoc transfer stopped three times for a reason still unclear to me) with:
mencoder -v tv:// -tv driver=v4l2:device=/dev/video0:outfmt=i420:width=640:height=480:forceaudio:adevice=/dev/dsp1 -ovc lavc -lavcopts acodec=mp3:abitrate=112:vbitrate=950:mbd=2 -oac lavc -vf lavcdeint -o video.avi
Ludovico Cavedon
So Sep 4 10:14:03 CEST 2005
since Ludovice didn't post anything during the last week, he implemented digital audio (using the ac97 link). and did some code cleanup. We also partly set up VBI(Teletext) support, though we have to get deeper into that topic. I still fight with the Pinnacle PCTV USB2 (Pal/Secam) drivers, downloading the installation CD now, just want to fix up that audio issue...
Audio issue fixed, there's no audio out jack, the Pinnacle PCTV only works with the USB Audio link which has been enabled as written in the specs by Ludovico :-)
for the pinnacle pctv usb2 a relay tool is required to get synced Audio/Video since A/V is not multiplexed (for testing the device >>dd if=/dev/dsp of=/dev/dsp1<< should work)
Markus Rechberger
So Aug 28 13:53:39 CEST 2005
received the pinnacle PCTV USB2 device, video and tuning already works but no sound yet..
Upload:MarkusRechberger/pro7.jpg
Fr Aug 26 20:09:36 CEST 2005
pinnacle will send us an usb device for testing the current em2820 driver with it, deinterlacing is also implemented into the old available driver.
Mo Aug 15 00:27:33 CEST 2005
ok there was a discussion about that half framed interlace issue theoretically it should be done in userspace, practically the userspace tv applications haven't implemented that function (so it won't work if I'd set the right option in the driver). btw. tuning also works in the old driver we give away (use H and K/mplayer)
Sa Aug 13 20:22:26 CEST 2005
isoc transfer is done so far I get the frames I want, atm the glue between v4l(1) and the isoc irq is missing (this is the most important step atm. also to get that interlacing problem done) even usb_video.c in the kernel tree uses depreciated functions and I try to not use the way like it's used in the em2800 driver so let's see how it turns out during the next week. if someone wants to join the development process everyone who knows more about kernel development is welcome! the driver will get distributed under GPL (there's no other way empia didn't respond yet they have to face it then - I signed the NDA to not give away the docs (I will not for sure)), I don't see any negative point at that, they only have windoze drivers yet.. more than 20 people contacted me for now for linux drivers during 1 week (so don't spreed the working (hacked) driver around so that we can count everyone for now.. the actual full featured driver will be available during the next 2-3 weeks) everyone who asked for the current hacked driver got it via email.
Markus Rechberger
Do Aug 11 11:34:55 CEST 2005
new thursday news - if you have any questions regarding that driver or similar devices send them to mrechberger AT g m a i l (DOT) c o m, some people mailed me that the
* Pinnacle Systems PCTV USB2 * MSI VOX USB-TV * Terratec Cinergy 250 USB TV * Hauppauge WinTV-USB2 * Gadmei UTV310(http://www.gadmei.com), * Leadtek WinFast USBII
contain almost the same chips.
If you want to get your empia2820 device supported please send an output of usbview to the email address which is shown above
Markus Rechberger
Do Aug 4 03:46:57 CEST 2005
just some news.. I rewrite the em2820 driver (of course some code is borrowed from the em2800 driver and usb driver in the kernel tree), atm I'm at the video datatransfer. also want to take care about interlaced video this time..
Markus Rechberger
Do Jul 28 21:08:28 CEST 2005
even better news now we(MarkusR. and LudovicoC.) received the specs! During legal issues we won't publish any further informations on the Hardware from now on.
Do Jul 28 03:45:45 CEST 2005
probably good news, I got an email from empia, they will give us support
Markus Rechberger
Preface
Cinergy USB TV 250 Driver development, this device is currently not supported by linux... but we're on the right way to get it done
developers:
Sascha Sommer (skeleton driver/em2800) Ludovico Cavedon (i2c tuner support) Markus Rechberger (enabling videostream for the 2820, and some other em2820 protocol options)
we also contacted empiatech if they can hand out some details about the emp2820 chip.. we haven't got any informations from them
the current driver is available uppon request (of course I don't give any warranty it might even damage your device) we'll release the driver as soon as it's more complete Markus Rechberger
This site mainly contains notes about the driver development, so it's not perfectly structured
General Informations about the Terratec Cinergy 250 USB
The cinergy 250 USB Device contains (figured that out by opening the device):
* saa7113H (video input processor) * emp2820 * emp202 (audio processor/AC97 compatible)
Template:/USB/usbview usbview output
Useful Links
Writing a Simple USB Driver
http://www.linuxjournal.com/article/7353
Another doc I found about it (google only returned broken links, but it is stored in the web.archive as well
http://web.archive.org/web/20041024164832/http://www.toth.demon.co.uk/usb/reverse-0.3.txt
The Linux USB sub-system, Chapter 2. How to get USB devices working under Linux
http://www.linux-usb.org/USB-guide/x173.html
how to sniff usb data:
http://www.linuxjournal.com/article/7582 (I used usbsnoop for windows)
Marketing information/general overview:
http://www.komplett.ie/k/ki.asp?sku=302293&cks=PLS
The Linux Kernel Module Programming Guide
http://www.tldp.org/LDP/lkmpg/2.6/html/index.html
Programming Guide for Linux USB Device Drivers
http://www.lrr.in.tum.de/Par/arch/usb/usbdoc/
Driver porting: compiling external modules
http://lwn.net/Articles/21823/
USB Snoop:
http://benoit.papillault.free.fr/usbsnoop/
USB 2.0 Specs:
http://www.usb.org/developers/docs/usb_20_02212005.zip
Empia general informations:
http://www.empiatech.com.tw/pro_em2820.htm
Template:/USB a few infos about USB, and a nice parser for USBSnoop Logs
V4L2 Standards:
http://v4l2spec.bytesex.org/spec/standard.html
Video for Linux Two - Driver Writer's Guide
http://www.thedirks.org/v4l2/v4l2dwg.htm
Sniffing/Replaying Data
I followed http://www.linuxjournal.com/article/7582, since it didn't really work (the source looks incomplete at that point) I had to add the sniffing feature by myself to the linux kernel ...
00000202 0.02435058 <<<<<<< URB 6 coming back... 00000203 0.02435784 Status = 00000000 00000204 0.02436511 -- URB_FUNCTION_CONTROL_TRANSFER: 00000205 0.02437349 PipeHandle = 0x847EB4E0 00000206 0.02438355 TransferFlags = 0000000b (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK) 00000207 0.02439193 TransferBufferLength = 00000001 00000208 0.02440031 TransferBuffer = eb83f91f 00000209 0.02440869 TransferBufferMDL = 84799808 00000210 0.02441483 00000211 0.02442852 0000: 12 00000212 0.02445199 UrbLink = 00000000 00000213 0.02450032 SetupPacket : c0 00 00 00 0a 00 01 00 00000214 0.02514565 UsbSnoop - IRP_MJ_INTERNAL_DEVICE_CONTROL, IOCTL_INTERNAL_USB_SUBMIT_URB
starting to replay some sniffed protocol points:
static int em2800_read_reg_ext(struct em2800 *dev,__u16 reg,int cnt) { __u8 val[cnt]; int i; int ret; for(i=0;i<cnt;i++){ val[i]=0; } printk("READING(ext): 0x%x 0x%x 0x0000 0x%x 1 HZ\n",USB_REQ_GET_STATUS,USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE,reg); ret = usb_control_msg(dev->udev,usb_rcvctrlpipe(dev->udev,0),USB_REQ_GET_STATUS, USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_DEVICE, 0x0000,reg,val,1, HZ); printk("device returned:(ext) "); for(i=0;i<cnt;i++){ printk(" 0x%x",val[i]); } printk("\n"); return 0; }
<nowiki> dev->em2800_read_reg_ext(dev,0x0a,1);
</nowiki>
the result we get:
READING(ext): 0x0 0xc0 0x0000 0xa 1 HZ device returned:(ext) 0x12
It seems that usbsnoop dropps packets, so I'll try another way to figure out the protocol http://www.vmware.com/support/kb/enduser/std_adp.php?p_faqid=1622 vmware 5.0 supports isochronous transfers *the thing I suffer*
Isoc Transfer - just a guess?
since the data which arrives is empty I think it's because it uses following configuration:
Interface Number: 0 Name: em2800 Alternate Number: 0 Class: ff(vend.) Sub Class: 0 Protocol: 0 Number of Endpoints: 3 Endpoint Address: 81 Direction: in Attribute: 3 Type: Int. Max Packet Size: 1 Interval: 128ms Endpoint Address: 82 Direction: in Attribute: 1 Type: Isoc Max Packet Size: 0 Interval: 125us Endpoint Address: 84 Direction: in Attribute: 2 Type: Bulk Max Packet Size: 512 Interval: 0ms
somehow I have to switch to .
Interface Number: 0 Name: em2800 Alternate Number: 1 Class: ff(vend.) Sub Class: 0 Protocol: 0 Number of Endpoints: 3 Endpoint Address: 81 Direction: in Attribute: 3 Type: Int. Max Packet Size: 1 Interval: 128ms Endpoint Address: 82 Direction: in Attribute: 1 Type: Isoc Max Packet Size: 1024 Interval: 125us Endpoint Address: 84 Direction: in Attribute: 2 Type: Bulk Max Packet Size: 512 Interval: 0ms
(usbsnoop sniffed packet)
68 8:30:20 PM <<<<<<< URB 103 coming back... 00002869 8:30:20 PM Status = 00000000 00002870 8:30:20 PM -- URB_FUNCTION_SELECT_INTERFACE: 00002871 8:30:20 PM ConfigurationHandle = 0x83f4a2a8 00002872 8:30:20 PM Interface: Length = 0x0000004c 00002873 8:30:20 PM Interface: InterfaceNumber = 0x00 00002874 8:30:20 PM Interface: AlternateSetting = 0x05 00002875 8:30:20 PM Interface: Class = 0xff 00002876 8:30:20 PM Interface: SubClass = 0x00 00002877 8:30:20 PM Interface: Protocol = 0xff 00002878 8:30:20 PM Interface: InterfaceHandle = 0x84a1e148 00002879 8:30:20 PM Interface: NumberOfPipes = 0x00000003 00002880 8:30:20 PM Interface: Pipes[0] : MaximumPacketSize = 0x0001 00002881 8:30:20 PM Interface: Pipes[0] : EndpointAddress = 0x81 00002882 8:30:20 PM Interface: Pipes[0] : Interval = 0x0b 00002883 8:30:20 PM Interface: Pipes[0] : PipeType = 0x03 (UsbdPipeTypeInterrupt) 00002884 8:30:20 PM Interface: Pipes[0] : PipeHandle = 0x84A1E164 00002885 8:30:20 PM Interface: Pipes[0] : MaxTransferSize = 0x00000040 00002886 8:30:20 PM Interface: Pipes[0] : PipeFlags = 0x00 00002887 8:30:20 PM Interface: Pipes[1] : MaximumPacketSize = 0x0a14 00002888 8:30:20 PM Interface: Pipes[1] : EndpointAddress = 0x82 00002889 8:30:20 PM Interface: Pipes[1] : Interval = 0x01 00002890 8:30:20 PM Interface: Pipes[1] : PipeType = 0x01 (UsbdPipeTypeIsochronous) 00002891 8:30:20 PM Interface: Pipes[1] : PipeHandle = 0x84A1E184 00002892 8:30:20 PM Interface: Pipes[1] : MaxTransferSize = 0x00010000 00002893 8:30:20 PM Interface: Pipes[1] : PipeFlags = 0x00 00002894 8:30:20 PM Interface: Pipes[2] : MaximumPacketSize = 0x0200 00002895 8:30:20 PM Interface: Pipes[2] : EndpointAddress = 0x84 00002896 8:30:20 PM Interface: Pipes[2] : Interval = 0x01 00002897 8:30:20 PM Interface: Pipes[2] : PipeType = 0x02 (UsbdPipeTypeBulk) 00002898 8:30:20 PM Interface: Pipes[2] : PipeHandle = 0x84A1E1A4 00002899 8:30:20 PM Interface: Pipes[2] : MaxTransferSize = 0x00001000 00002900 8:30:20 PM Interface: Pipes[2] : PipeFlags = 0x00 00002901 8:30:20 PM UsbSnoop - IRP_MJ_INTERNAL_DEVICE_CONTROL, IOCTL_INTERNAL_USB_SUBMIT_URB 00002902 8:30:20 PM
for switching the configuration the function usb_set_interface() is available
usb_set_interface(device,<interface number>,<Alternate Number>)
.. yes somehow I was wrong with that.. I switched to Alternate number 5 (though no bytes delivered) next step going to clean up the driver and flooding the device with all sniffed packets I got (or even may get soon),...
to recompile usbsnoop you require win2kddk.exe (it's not available on the microsoft website anymore.. I found an active (slow) mirror with google though.. it was free a longer time ago microsoft just dropped it..) (when writing that I thought about doing that but then I figured out how to modify the kernel and it wasn't so hard)
Adding an USB Sniffer to usbfs
I added some printk's for determining the flow through devio.c
usb 1-3: usbdev_ioctl: SUBMITURB USBDEVFS urpb CONTROL length: 10 <-- this is what looks interesting 10 bytes let's see what's in it.. CONTROL malloc() CONTROL copy from user() CONTROL buffer_length() check_ctrlrecip() CONTROL access_ok alloc_async kmalloc() copy_from_user() usb_submit_urb() return -- 0 --
ok add some more code to the kernelmodule and reload..
static int proc_submiturb(struct dev_state *ps, void __user *arg) { unsigned int iter; ... in case USBDEVFS_URB_TYPE_CONTROL: printk("USBDEVFS_URB_TYPE_CONTROL (recv): "); for(iter=0;iter<uurb.buffer_length;iter++){ printk("0x%x ",((char*)uurb.buffer)[iter]); } printk("\n"); }
bingo..
USBDEVFS urpb CONTROL length: 9 CONTROL malloc() CONTROL copy from user() CONTROL buffer_length() USBDEVFS_URB_TYPE_CONTROL (recv): 0xffffffc0 0x0 0x0 0x0 0x12 0x0 0x1 0x0 0x0 # <-- this looks like a read request to the USB device check_ctrlrecip() CONTROL access_ok alloc_async kmalloc() copy_from_user() usb_submit_urb() return -- 0 -- usb 1-3: usbdev_ioctl: REAPURBDELAY usb 1-3: usbdev_ioctl: REAPURBDELAY usb 1-3: usbdev_ioctl: SUBMITURB USBDEVFS urpb CONTROL length: 9 CONTROL malloc() CONTROL copy from user() CONTROL buffer_length() USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x12 0x0 0x1 0x0 0x67 # <-- this looks like an update request to the device check_ctrlrecip() CONTROL access_ok alloc_async kmalloc() copy_from_user() usb_submit_urb() return -- 0 --
filtered..
... Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0xc 0x0 0x1 0x0 0x10 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x12 0x0 0x1 0x0 0x67 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x22 0x0 0x1 0x0 0x10 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x20 0x0 0x1 0x0 0x10 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x3 0x0 0x0 0x4a 0x0 0x1 0x0 0x1f Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x21 0x0 0x1 0x0 0x34 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x20 0x0 0x1 0x0 0x10 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x2 0x0 0x0 0x4a 0x0 0x2 0x0 0xd 0x0 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x22 0x0 0x1 0x0 0x10 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x14 0x0 0x1 0x0 0x32 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x25 0x0 0x1 0x0 0x2 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0xe 0x0 0x1 0x0 0xffffffeb Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0xf 0x0 0x1 0x0 0xffffff87 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x40 0x0 0x2 0x0 0x0 0x0 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x42 0x0 0x1 0x0 0x2 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0xe 0x0 0x1 0x0 0xffffffeb Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0xf 0x0 0x1 0x0 0xffffff87 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x40 0x0 0x2 0x0 0x0 0x0 Jul 8 05:35:02 debian kernel: USBDEVFS_URB_TYPE_CONTROL (recv): 0x40 0x0 0x0 0x0 0x42 0x0 0x1 0x0 0x2 ...
now let's play the game again and replay what we got... oh yes... it took me that long to figure out that I did something wrong... I forgot about the so called "bRequest", it's the second value in the sniffed list
it's also documented in usb_20.pdf in chapter 9.3 USB Device Requests (Site 276) which is downloadable on usb.org
USB Control Message
Offset,Field,Size,Value,Description 0,bmRequestType,1,Bitmap,Characteristics of request: D7 Data transfer direction; D6..5 Type; D4..0 Recipient 1,bRequest,1,Value,Specific request (refer to Table 9-3) 2,wValue,2,Value,Word-sized field that varies according to request 4,wIndex,2,Index of Offset, Word-sized field that varies according to request; typically used to pass an index or offset 6,wLength,2,Count,Number of bytes to transfer if there is a Data stage
bRequest:
This field specifies the particular request. The Type bits in the bmRequestType field modify the meaning of this field. This specification defines values for the bRequest field only when the bits are reset to zero, indicating a standard request (refer to Table 9-3).
ok I modified the existing em2800 driver and added a function em2820_write_regs which supports the bmreq value.
calls look like: em2820_write_regs(dev,0x03,0x4a,"\x1f",1); now :-)
YESS, the basic driver works now (very rude..) I receive data!
Sniffed Log when starting up a Windows TV Player
Parsed WinDVR Startup Log (vmware only supports usb 1.1, so that's why there are no isoc transfers in it though everything would be prepared for it): http://linuxwiki.de/MarkusRechberger/em2820?action=AttachFile&do=get&target=dvrstartup-parsed.log
switchchannel2.LOG
001393: OUT: 40 03 00 00 4a 00 01 00 >>> 1f 001394: OUT: c0 00 00 00 05 00 01 00 <<< 00 001395: OUT: c0 02 00 00 4a 00 01 00 <<< 91 001396: OUT: c0 00 00 00 05 00 01 00 <<< 00 001397: OUT: 40 03 00 00 4a 00 01 00 >>> 1f 001398: OUT: c0 00 00 00 05 00 01 00 <<< 00 001399: OUT: c0 02 00 00 4a 00 01 00 <<< 91 001400: OUT: c0 00 00 00 05 00 01 00 <<< 00 001401: OUT: 40 03 00 00 4a 00 01 00 >>> 1f 001402: OUT: c0 00 00 00 05 00 01 00 <<< 00 001403: OUT: c0 02 00 00 4a 00 01 00 <<< 91 001404: OUT: c0 00 00 00 05 00 01 00 <<< 00 001405: OUT: 40 03 00 00 4a 00 01 00 >>> 1f 001406: OUT: c0 00 00 00 05 00 01 00 <<< 00 001407: OUT: c0 02 00 00 4a 00 01 00 <<< 91 001408: OUT: c0 00 00 00 05 00 01 00 <<< 00 001409: OUT: 40 03 00 00 4a 00 01 00 >>> 1f 001410: OUT: c0 00 00 00 05 00 01 00 <<< 00 001411: OUT: c0 02 00 00 4a 00 01 00 <<< 91 001412: OUT: c0 00 00 00 05 00 01 00 <<< 00 001413: OUT: 40 03 00 00 4a 00 01 00 >>> 1f 001414: OUT: c0 00 00 00 05 00 01 00 <<< 00 001415: OUT: c0 02 00 00 4a 00 01 00 <<< 91 001416: OUT: c0 00 00 00 05 00 01 00 <<< 00 001417: OUT: 40 00 00 00 20 00 01 00 >>> 00 001418: OUT: 40 00 00 00 22 00 01 00 >>> 00 001419: OUT: c0 00 00 00 12 00 01 00 <<< 67 001420: OUT: 40 00 00 00 12 00 01 00 >>> 27 001421: OUT: c0 00 00 00 0c 00 01 00 <<< 10 001422: OUT: 40 00 00 00 0c 00 01 00 >>> 00 001423: OUT: 40 02 00 00 c2 00 04 00 >>> 05 e2 8e 01 001424: OUT: c0 00 00 00 05 00 01 00 <<< 00 001425: OUT: 40 02 00 00 86 00 04 00 >>> 00 d6 70 49 001426: OUT: c0 00 00 00 05 00 01 00 <<< 00 001427: OUT: c0 02 00 00 c2 00 01 00 <<< 39 001428: OUT: c0 00 00 00 05 00 01 00 <<< 00 001429: OUT: c0 02 00 00 c2 00 01 00 <<< 7b 001430: OUT: c0 00 00 00 05 00 01 00 <<< 00 001431: OUT: c0 02 00 00 c2 00 01 00 <<< 7b 001432: OUT: c0 00 00 00 05 00 01 00 <<< 00 001433: OUT: c0 02 00 00 c2 00 01 00 <<< 7b 001434: OUT: c0 00 00 00 05 00 01 00 <<< 00 001435: OUT: c0 02 00 00 c2 00 01 00 <<< 7b 001436: OUT: c0 00 00 00 05 00 01 00 <<< 00 001437: OUT: c0 00 00 00 0c 00 01 00 <<< 00 001438: OUT: 40 00 00 00 0c 00 01 00 >>> 10 001439: OUT: 40 00 00 00 12 00 01 00 >>> 67 001440: OUT: 40 00 00 00 22 00 01 00 >>> 10 001441: OUT: 40 00 00 00 20 00 01 00 >>> 10 001442: OUT: c0 02 00 00 c2 00 01 00 <<< 7b 001443: OUT: c0 00 00 00 05 00 01 00 <<< 00 001444: OUT: c0 02 00 00 c2 00 01 00 <<< 7b 001445: OUT: c0 00 00 00 05 00 01 00 <<< 00 001446: OUT: 40 00 00 00 20 00 01 00 >>> 00 001447: OUT: 40 00 00 00 22 00 01 00 >>> 00 001448: OUT: c0 00 00 00 12 00 01 00 <<< 67 001449: OUT: 40 00 00 00 12 00 01 00 >>> 27 001450: OUT: c0 00 00 00 0c 00 01 00 <<< 10 001451: OUT: 40 00 00 00 0c 00 01 00 >>> 00 001452: OUT: 40 02 00 00 c2 00 04 00 >>> 05 e3 8e 01 001453: OUT: c0 00 00 00 05 00 01 00 <<< 00 001454: OUT: 40 02 00 00 86 00 04 00 >>> 00 d6 70 49
Screenshots
Initial Screenshot
mplayer
mplayer -tv driver=v4l2:width=320:height=240 -vo x11 tv://
current screenshot (mplayer):
http://www.linuxwiki.de/MarkusRechberger/em2820?action=AttachFile&do=get&target=screenshot.jpg
the magic number 7
used configuration:
Interface Number: 0 Name: em2800 Alternate Number: 7 Class: ff(vend.) Sub Class: 0 Protocol: 0 Number of Endpoints: 3 Endpoint Address: 81 Direction: in Attribute: 3 Type: Int. Max Packet Size: 1 Interval: 128ms Endpoint Address: 82 Direction: in Attribute: 1 Type: Isoc Max Packet Size: 3072 Interval: 125us Endpoint Address: 84 Direction: in Attribute: 2 Type: Bulk Max Packet Size: 512 Interval: 0ms
mplayer -zoom -tv driver=v4l2:width=720:height=576:norm=PAL:fps=25 -vo x11 tv://
http://www.linuxwiki.de/MarkusRechberger/em2820?action=AttachFile&do=get&target=screenshot2.jpg
(playing around with the supported input resolution now) Digital Video Capture Resolution 720 x 480, 352 x 240, 352 x 288, 720 x 576
Issues with the size
though the video is oversized now...
mplayer -zoom -tv driver=v4l2:width=750:height=480:fps=25:norm=palm:noaudio:outfmt=i420 tv:// -vo x11
http://www.linuxwiki.de/MarkusRechberger/em2820?action=AttachFile&do=get&target=screenshot4.jpg
http://www.linuxwiki.de/MarkusRechberger/em2820?action=AttachFile&do=get&target=screenshot5.jpg
Fixed Size
there's a function called set_window within the em2800 driver, and 320x288 was hardcoded, I changed this so that the size gets set using ioctls.. looks like the video is 1:1 (width/height)
mplayer -zoom -tv driver=v4l2:width=244:height=244:fps=30:norm=pal:noaudio:outfmt=yuy2 tv:// -vo x11
Upload:MarkusRechberger/244x240.jpg
Alternate Number 5
alternate number 5 .. guess some bytes are missing? the isoc transfer complains about an incomplete frame.. let's see I don't know the frame size which should be behind that transfer data (guessing doesn't work following frame is the best result) ..
http://linuxwiki.de/MarkusRechberger/em2820?action=AttachFile&do=get&target=frame.jpg
Alternate Number 2
Alternate setting 2
Upload:MarkusRechberger/zdf.jpg
Alternate Number 7
ok I figured out the usb control message which allows to switch to 720px width.. interesting thing is that interface 0 alternate number 7 doesn't automatically return a full sized video at 720x576 ok the width looks _right_ the cinergy usb tv delivers 2 frames interlaced, think it has something to do with the v4l2 option V4L2_FIELD_SEQ_TB in the driver but it didn't work out for me yet.. so there's probably something else
mplayer -zoom -tv driver=v4l2:width=720:height=288:fps=25:norm=palm:noaudio:outfmt=yuy2 tv:// -vo x11
Upload:MarkusRechberger/720x288.jpg
Screenshot 720x576
Upload:MarkusRechberger/screenshot8.jpg
here's the v4l2 doc regarding that issue http://v4l2spec.bytesex.org/spec/field-order.html
Alternate 7 de-interlaced
this will play the video at the correct size:
mplayer -zoom -tv driver=v4l2:width=720:height=288:fps=60:noaudio:outfmt=yuy2 tv:// -vf tinterlace
Ludovico C. pointed me out that tinterlace switch ..
Upload:MarkusRechberger/test4.jpg
next step would be to put that interlace feature into the usb kernel driver..
Isoc Request issues
another issue frame problems ... after a while the video had some problems these problems were caused because of requesting 60 isoc urbs from the device, in windows it only requests 40 urbs (after modifying the driver again the video looks stable!)
Changing the resolution?
Changing Resolution:
Switched to 640x480 (sniffed with usbsniff) this probably covers that 0x05 delivers a 640x480 frame?
640x480 - vga - yuy2
000426: OUT: c0 00 00 00 0f 00 01 00 <<< 87 000427: OUT: 40 00 00 00 0f 00 01 00 >>> 07 000428: OUT: 40 00 00 00 40 00 02 00 >>> 00 80 000429: OUT: 40 00 00 00 42 00 01 00 >>> 02 000430: OUT: c0 00 00 00 43 00 01 00 <<< 00 000431: Changing to Alternative Setting 0x05 000432: Changing to Alternative Setting 0x05 000433: Changing to Alternative Setting 0x05 000434: Changing to Alternative Setting 0x05 000435: OUT: c0 00 00 00 0e 00 01 00 <<< cd 000436: OUT: 40 00 00 00 0e 00 01 00 >>> cd 000437: OUT: c0 00 00 00 0f 00 01 00 <<< 07 000438: OUT: 40 00 00 00 0f 00 01 00 >>> 87 000439: OUT: 40 00 00 00 40 00 02 00 >>> 00 00 ## try to mute 000440: OUT: 40 00 00 00 42 00 01 00 >>> 02 000441: OUT: c0 00 00 00 43 00 01 00 <<< 00 000442: OUT: c0 00 00 00 0e 00 01 00 <<< cd 000443: OUT: 40 00 00 00 0e 00 01 00 >>> cd 000444: OUT: c0 00 00 00 0f 00 01 00 <<< 87 000445: OUT: 40 00 00 00 0f 00 01 00 >>> 87 000446: OUT: 40 00 00 00 40 00 02 00 >>> 00 00 ## try to mute 000447: OUT: 40 00 00 00 42 00 01 00 >>> 02 000448: OUT: c0 00 00 00 43 00 01 00 <<< 00 000449: OUT: 40 00 00 00 21 00 01 00 >>> 14 000450: OUT: 40 00 00 00 20 00 01 00 >>> 10 000451: OUT: 40 00 00 00 22 00 01 00 >>> 10 000452: OUT: 40 00 00 00 25 00 01 00 >>> 02 000453: OUT: c0 00 00 00 0f 00 01 00 <<< 87 000454: OUT: 40 00 00 00 0f 00 01 00 >>> 07 000455: OUT: 40 00 00 00 40 00 02 00 >>> 00 80 ## unmute 000456: OUT: 40 00 00 00 42 00 01 00 >>> 02 000457: OUT: c0 00 00 00 43 00 01 00 <<< 00
setting 640x480 - i420
000486: Changing to Alternative Setting 0x05 000487: Changing to Alternative Setting 0x05 000488: Changing to Alternative Setting 0x05 000489: Changing to Alternative Setting 0x05 000490: OUT: c0 00 00 00 0f 00 01 00 <<< 07 000491: OUT: 40 00 00 00 0f 00 01 00 >>> 07 000492: OUT: 40 00 00 00 40 00 02 00 >>> 00 80 #unmute 000493: OUT: 40 00 00 00 42 00 01 00 >>> 02 000494: OUT: c0 00 00 00 43 00 01 00 <<< 00 000495: OUT: c0 00 00 00 0f 00 01 00 <<< 07 000496: OUT: 40 00 00 00 0f 00 01 00 >>> 07 000497: OUT: 40 00 00 00 40 00 02 00 >>> 00 80 #unmute 000498: OUT: 40 00 00 00 42 00 01 00 >>> 02 000499: OUT: c0 00 00 00 43 00 01 00 <<< 00 000500: OUT: 40 00 00 00 21 00 01 00 >>> 14 000501: OUT: 40 00 00 00 20 00 01 00 >>> 10 000502: OUT: 40 00 00 00 22 00 01 00 >>> 10 000503: OUT: 40 00 00 00 25 00 01 00 >>> 02 000504: OUT: c0 00 00 00 0f 00 01 00 <<< 07 000505: OUT: 40 00 00 00 0f 00 01 00 >>> 07 000506: OUT: 40 00 00 00 40 00 02 00 >>> 00 80 #unmute 000507: OUT: 40 00 00 00 42 00 01 00 >>> 02 000508: OUT: c0 00 00 00 43 00 01 00 <<< 00 000509: OUT: c0 00 00 00 0f 00 01 00 <<< 07 000510: OUT: 40 00 00 00 0f 00 01 00 >>> 07 000511: OUT: 40 00 00 00 40 00 02 00 >>> 00 80 #unmute 000512: OUT: 40 00 00 00 42 00 01 00 >>> 02 000513: OUT: c0 00 00 00 43 00 01 00 <<< 00
difference might be 0x0f, once it got switched to 87, since it didn't work it might have got switched back to 0x07
General thoughts and informations
played 400.000 frames without lockup (makes about 4 hours!).. Ludovico reported a lockup after 40.000 frames seems like a hardware issue here (maybe the windows driver currently fixes that problem..) I had such an issue with my usb soundblaster it finally locked up the kernel within 5 minutes until I replaced the cable with an usb 2.0 certified wire... it always takes a while till mplayers deinterlace filter works correctly (just looked over that topic very short..) but finally as expected the quality is way better in linux than in microsoft windows.. mythtv (www.mythtv.org) will be fun with it as soon as someone gets the i2c stuff working.. I just sit back now and take it easy I'm already glad to get a full quality video in linux :) the i2c indexes are already known atm. another news are terratec denies supporting linux officially because there are too less linux users out there (well .. munich(Germany) migrates their administrational services over to linux and so does vienna(Austria) oh no sorry noone uses linux.. But maybe some information from empia is coming...
i2c Hacking
Something about the I2C on the device: the main chip is the emp2820, but there are other chips connected through an i2c:
Address, Chip 0x4a, Philips saa7113h: video decoder 0xc0, LG TALN-M200: tuner 0xc2, again the tuner 0x68, I don't know :) maybe a tda9887
The saa7113h si well documented:
http://www.semiconductors.philips.com/pip/SAA7113.html
The tuner id detected at address 0xc0, but address 0xc2 is used to communicate with it.
There is also something at the 0x68 address, but I don't know what it is. Maybe a tda9887 (PLL demodulator) but I didn't see it when I opened my cinergy.
An standard I2C address is an 8 bit value. The least significant bit specifies the direction of the trasfer: 0 means write (from master to slave), 1 read (from slave to master). Fo this reason, max 127 can be connected to an I2C bus, and they have two addresses (at least), the first to receive data, the second to send data.
The I2C protocol is very simple. See here:
http://www.wikiservice.at/dse/wiki.cgi?MarkusRechberger/I2C
and a the documentation from Philips:
http://www.semiconductors.philips.com/markets/mms/protocols/i2c/
The major problem, in this case, is to unserstand how tell the em2820 to write on the bus (since we can only communicate with the em2820 through the usb bus). That is what I could understand examining the logs; something is still obscure, btw:
All the operation on the i2c bus have the bRequest set to 0x02 or 0x03. More over every operation is followed by a read at the register 0x05 of the em2820, that usually returns 0x00. It should be a way to ask if the operation was successful. The only times I saw a number different from 0x00 was during the scan of the i2c bus: wheen a read from a nonexitent device return 0x10.
c0 02 0000 004a 0001 data: 11 c0 00 0000 0005 0001 data: 00 # Success, device present! c0 02 0000 00c6 0001 data: 00 c0 00 0000 0005 0001 data: 10 # Failure, device not present!
Writing or reading to/from a device is streightforward: set bRequest to 0x02 and wIndex to the address of the device you want to write to.
40 02 0000 00c2 0004 data: 06 52 8e 01 c0 00 0000 0005 0001 data: 00 c0 02 0000 00c2 0001 data: 38 c0 00 0000 0005 0001 data: 00
BUT...
The saa7113 has many adressable registers, so when writing to it, the first byte specifies the subaddress (internal address of the register), the second byte the data to write; following bytes, if present, are written to consecutive registers. That means that the write here above reported sets 0x52 in register 0x06, 0x8e in register 0x07 and 0x01 in register 0x08.
But, during a read, how can registered be addressed? The datasheet of the saa7113 specifies this: first perform a write of length 1 to the device specifying the subaddress as data. Than read from the device.
Well, looking at the logs, that is what happens, but in addition the bRequest of the write before the each read is set to 0x03. Why this happens?
Anyway, I have some troubles with reads... I have to investigate more...
Ludovico Cavedon
got following email from Sascha Sommer a longer time ago, this is regarding I2C reads:
Folgendes schaut mir nach einem i2c read aus:
001401: OUT: 40 03 00 00 4a 00 01 00 >>> 1f 001402: OUT: c0 00 00 00 05 00 01 00 <<< 00 001403: OUT: c0 02 00 00 4a 00 01 00 <<< 91 001404: OUT: c0 00 00 00 05 00 01 00 <<< 00
Als erstes wird das statusregister (0x1f) zum lesen ausgewählt (1401). Dann wirt index 0x5 überprüft ob alles glatt gegangen ist.(1402) Dann wird der Wert des ausgewählten Registers aus 0x4a gelesen (1403) und wieder überprüft ob ein Fehler passiert ist (1404).
Markus Rechberger
I2C Tuner Hacking
Now some let's look at the tuner. Changing the frequency is very simple, just write it a 4 byte i2c message to the 0xc2 address:
40 02 0000 00c2 0004 data: 06 52 8e 01 c0 00 0000 0005 0001 data: 00
I saw also reads from athe tuner, but haven't investigated yet...
c0 02 0000 00c2 0001 data: 3c c0 00 0000 0005 0001 data: 00
However, code for the tuner is already implemented in the kernel (drivers/media/video/tuner.c).
A good news: we managed to change the channel!! At the moment it's working only with mplayer, nor with with tvtime or xawtv. I think it's just some wrong setting somewhere...
As I previously wrote, there is a device at address 0x68. Here are the operations I logged, but I haven't gone deep into it yet:
c0 02 0000 0086 0001 data: af c0 00 0000 0005 0001 data: 00 c0 02 0000 0086 0001 data: ad c0 00 0000 0005 0001 data: 00 40 02 0000 0086 0004 data: 00 d6 70 49 c0 00 0000 0005 0001 data: 00 40 02 0000 0086 0004 data: 00 16 70 49 c0 00 0000 0005 0001 data: 00 ] ... never logged anything different. ''Ludovico Cavedon'' == Resolution == remember the saa7113 is similar with the saa7111 (which is also in the kernel sourcetree) regarding the video resolution.. Mauro pointed me to an existing driver which does software scaling, if you have a look at our device with usbview you can see following: Endpoint Address: 82 Direction: in Attribute: 1 Type: Isoc Max Packet Size: 1024 Interval: 125us
max packet size 1024 bytes <- this one is also connected with a resolution interface 0 alternate number 7 has the highest max packet size (3072 bytes) and it supports the highest resolution. in windows if you switch the resolution it also changes the alternate number(you know you have the choice between a few resolutions in windows) if you close cinergytv it switches back to interface 0 alternate 0 which has a max packet size of 0 bytes (and you will also notice that the device cools down again), but also index 0x0c is able to switch the device off (so that the led goes off.. looks like my led doesn't work at all anymore)
Markus Rechberger
em2820 protocol overview
(I only work with alternate number 7)
example:
0x1c -> value 0x1b -> width 694 0x1c -> value 0x1d -> width 692 (but blueish video/colorspace?) 0x1c -> value 0x1e -> width 692 (correct color) 0x1c -> value 0xff -> width 466
possible writes to the device:
OUT: 40 00 00 00 06 00 01 00 >>> 40 OUT: 40 00 00 00 08 00 01 00 >>> ff OUT: 40 00 00 00 0c 00 01 00 >>> 00 #disable device OUT: 40 00 00 00 0c 00 01 00 >>> 10 #enable device OUT: 40 00 00 00 0e 00 01 00 >>> c0 OUT: 40 00 00 00 0e 00 01 00 >>> c2 OUT: 40 00 00 00 0e 00 01 00 >>> c5 OUT: 40 00 00 00 0e 00 01 00 >>> c6 OUT: 40 00 00 00 0f 00 01 00 >>> 00 OUT: 40 00 00 00 0f 00 01 00 >>> 07 OUT: 40 00 00 00 0f 00 01 00 >>> 87 OUT: 40 00 00 00 10 00 01 00 >>> 00 OUT: 40 00 00 00 11 00 01 00 >>> 11 OUT: 40 00 00 00 12 00 01 00 >>> 25 # disabled video output? OUT: 40 00 00 00 12 00 01 00 >>> 27 # disabled video output? OUT: 40 00 00 00 12 00 01 00 >>> 67 # enables TV video? OUT: 40 00 00 00 13 00 01 00 >>> 08 OUT: 40 00 00 00 14 00 01 00 >>> 32 OUT: 40 00 00 00 15 00 01 00 >>> 20 OUT: 40 00 00 00 16 00 01 00 >>> 20 OUT: 40 00 00 00 17 00 01 00 >>> 20 OUT: 40 00 00 00 18 00 01 00 >>> 00 OUT: 40 00 00 00 19 00 01 00 >>> 00 OUT: 40 00 00 00 1a 00 01 00 >>> 00 OUT: 40 00 00 00 1b 00 01 00 >>> 00 #strange effect.. if I set it to 0x01 the videosize is 722 0x02 => 720, 0x03=>722 so only takes the first bit? OUT: 40 00 00 00 1c 00 01 00 >>> 00 #cropping left side OUT: 40 00 00 00 1c 00 01 00 >>> 08 #cropping left side OUT: 40 00 00 00 1d 00 01 00 >>> 00 #cropping top OUT: 40 00 00 00 1e 00 01 00 >>> b0 #cropping right side OUT: 40 00 00 00 1e 00 01 00 >>> b4 #cropping right side OUT: 40 00 00 00 1f 00 01 00 >>> 48 #cropping from the bottom OUT: 40 00 00 00 20 00 01 00 >>> 00 #contrast OUT: 40 00 00 00 20 00 01 00 >>> 10 #contrast OUT: 40 00 00 00 21 00 01 00 >>> 00 #brightness OUT: 40 00 00 00 21 00 01 00 >>> 14 #brightness OUT: 40 00 00 00 22 00 01 00 >>> 00 #saturation OUT: 40 00 00 00 22 00 01 00 >>> 10 #saturation OUT: 40 00 00 00 23 00 01 00 >>> 00 #blue 00 (default?) look closer at 16*n (U) (YUV)? OUT: 40 00 00 00 24 00 01 00 >>> 00 #red (V) (YUV)? OUT: 40 00 00 00 25 00 01 00 >>> 00 #sharpness OUT: 40 00 00 00 26 00 01 00 >>> 00 #input height OUT: 40 00 00 00 26 00 01 00 >>> 10 #input height OUT: 40 00 00 00 26 00 01 00 >>> 30 #input height OUT: 40 00 00 00 27 00 01 00 >>> 34 # alternate 7 # 34 .. full sized video(width) # 10 .. half sized video(width) # alternate 3, 5 # 34 .. invalid video # 10 .. valid video ---- 10000 .. #0x10 110100 .. #0x34 100 .. screws the video at alternate 3 and 5? 10000 .. this bit is responsible for the colorspace? 100000 .. sets valid video at alternate 3 and 5 ---- OUT: 40 00 00 00 28 00 01 00 >>> 01 OUT: 40 00 00 00 29 00 01 00 >>> af OUT: 40 00 00 00 29 00 01 00 >>> b3 OUT: 40 00 00 00 2a 00 01 00 >>> 01 OUT: 40 00 00 00 2b 00 01 00 >>> 47 OUT: 40 00 00 00 30 00 02 00 >>> 33 13 OUT: 40 00 00 00 30 00 02 00 >>> 99 01 OUT: 40 00 00 00 32 00 02 00 >>> 33 03 OUT: 40 00 00 00 40 00 02 00 >>> 00 00 #unmute OUT: 40 00 00 00 40 00 02 00 >>> 00 80 #mute OUT: 40 00 00 00 42 00 01 00 >>> 02 OUT: 40 02 00 00 4a 00 02 00 >>> 01 08 # video i2c OUT: 40 02 00 00 4a 00 02 00 >>> 02 c2 # video i2c OUT: 40 02 00 00 4a 00 02 00 >>> 03 30 # video i2c OUT: 40 02 00 00 4a 00 02 00 >>> 0a 80 # video i2c OUT: 40 02 00 00 4a 00 02 00 >>> 0d 00 # video i2c OUT: 40 02 00 00 4a 00 02 00 >>> 0e 01 # video i2c OUT: 40 02 00 00 4a 00 02 00 >>> 0f 2a # video i2c OUT: 40 02 00 00 4a 00 05 00 >>> 06 e9 0d 88 01 # video i2c OUT: 40 02 00 00 4a 00 05 00 >>> 0a 80 47 40 00 # video i2c OUT: 40 02 00 00 4a 00 05 00 >>> 10 08 0c e7 00 # video i2c OUT: 40 02 00 00 86 00 04 00 >>> 00 16 70 49 OUT: 40 02 00 00 86 00 04 00 >>> 00 d6 70 49 OUT: 40 02 00 00 c2 00 04 00 >>> 05 e2 8e 01 OUT: 40 02 00 00 c2 00 04 00 >>> 05 e3 8e 01 OUT: 40 02 00 00 c2 00 04 00 >>> 06 52 8e 01 OUT: 40 02 00 00 c2 00 04 00 >>> 06 a2 8e 01 OUT: 40 02 00 00 c2 00 04 00 >>> 10 02 8e 02 OUT: 40 03 00 00 4a 00 01 00 >>> 00 OUT: 40 03 00 00 4a 00 01 00 >>> 1f OUT: 40 03 00 00 a0 00 01 00 >>> 04
Markus Rechberger
Just some addtionaly simple informations about em2820 registers:
Register, Min., Max., Default, Meaning 0x20, 0x00, 0x1f, 0x10, contrast 0x21, 0x00, 0x7f, 0x14, brightness 0x22, 0x00, 0x1f, 0x10, saturation 0x25, 0x00, 0x0f, 0x03, sharpness
Moreover bit 0 of register 0x27 flips the image ;-)
I also logged something about muting/unmuting audio. The Cinergy 250 has two ways of outputting audio: via the USB link, orvia an external analog cable.
Looking at logs I supposed:
# To mute analog audio 40 00 0000 0040 0002 data: 00 80 40 00 0000 0042 0001 data: 02 c0 00 0000 0043 0001 data: 00 # To unmute analog audio 40 00 0000 0040 0002 data: 00 00 40 00 0000 0042 0001 data: 02 c0 00 0000 0043 0001 data: 00 # To mute USB audio 40 00 0000 000f 0001 data: 07 # To unmute USB audio 40 00 0000 000f 0001 data: 87
But it is not working in our code :-(
Register 0x0e is also involved: it is sometimes accessed (when changing usb audio status) and I saw it with various values (0x8e, 0xce, 0xca, 0xcb). Maybe some kind of volume?
Moreover: sometimes, when umuting analog audio, the following operations are performed:
40 00 0000 0040 0002 data: 08 88 40 00 0000 0042 0001 data: 0e c0 00 0000 0043 0001 data: 00 40 00 0000 0040 0002 data: 08 88 40 00 0000 0042 0001 data: 10 c0 00 0000 0043 0001 data: 00 40 00 0000 0040 0002 data: 08 08 40 00 0000 0042 0001 data: 14 c0 00 0000 0043 0001 data: 00 40 00 0000 0040 0002 data: 08 88 40 00 0000 0042 0001 data: 16 c0 00 0000 0043 0001 data: 00 40 00 0000 0040 0002 data: 00 00 40 00 0000 0042 0001 data: 02 c0 00 0000 0043 0001 data: 00
Ludovico Cavedon
USB Audio
Small update aboute the audio volume:
the voulme of the audio in controlled by the USB device of the Cinergy, also when the audio is not sent through the USB link, but through an external audio cable.
Just load the snd-usb-audio ALSA module, see what the card number of the Cinergy is:
$ cat /proc/asound/cards 0 [V8235 ]: VIA8233 - VIA 8235 VIA 8235 with ALC202 at 0x1400, irq 9 1 [USB ]: USB-Audio - Cinergy 250 USB TerraTec Electronic GmbH Cinergy 250 USB at usb-0000:00:10.3-4, high speed
So card 1 in my case:
$ amixer -c 1 Simple mixer control 'PCM',0 Capabilities: cvolume cswitch cswitch-joined Capture channels: Mono Limits: Capture 0 - 16 Mono: Capture 4 [25%] [on] $ amixer -c 1 sset PCM 5 Simple mixer control 'PCM',0 Capabilities: cvolume cswitch cswitch-joined Capture channels: Mono Limits: Capture 0 - 16 Mono: Capture 5 [31%] [on]
Ludovico Cavedon
be sure you loaded the alsa usbaudio driver not the depreciated one that floats around somewhere else in the kernel.
to get it work with a higher quality use sox (you might have to adjust dsp and dsp2 there):
sox -t ossdsp -r 48000 -b -c 2 /dev/dsp -t ossdsp /dev/dsp2
Kernel 2.6.14 issue, the videotransfer will stop if usbaudio gets initialized with too less requested packets:
to get full quality audio work you need to patch this kernel
/usr/src/linux-2.6.14/sound/usb/usbaudio.c set: #define MAX_PACKS 10 to #define MAX_PACKS 100 recompile the snd_usb_audio module and load it with modprobe snd_usb_audio nrpacks=80
good luck with it
Markus
Support for various alternate numbers
Index 0x27 with value 0x34 alternate number 5:
mplayer -tv driver=v4l2:width=360:height=288:outfmt=yuy2 tv:// -vo x11
Upload:MarkusRechberger/alternate5-1.jpg
another screenshot with 0x27 having 0x34 as value:
mplayer -tv driver=v4l2:width=720:height=288:outfmt=yuy2 tv:// -vo x11
Upload:MarkusRechberger/alternate5-2.jpg
and finally a correct one (with the patched driver, alternate 5):
mplayer -tv driver=v4l2:width=360:height=288:outfmt=yuy2 tv:// -vf tinterlace -vo x11
Upload:MarkusRechberger/alternate5.jpg
alternate 3:
mplayer -tv driver=v4l2:width=360:height=288:outfmt=yuy2 tv:// -vo x11
Upload:MarkusRechberger/alternate3-ok.jpg
valid configurations for following alternate numbers are still missing:
alternate 1,2,4,6
Markus Rechberger
i2c Video Hacking
as mentioned in the tuner hacking section, the first byte identifies a register on the saa7113H chip, so in that case the sniffed data would never have shown up the i2c writes that exactly:
i2c table for the saa7113H chip on the terratec cinergy usb 250
Breq, Index, first byte, data, description 0x02, 0x4a, 0x0b, 0x47, enables video (default looks like black/white) 0x02, 0x4a, 0x0c, 0x40, enables the colour
so the call to enable a coloured video looks like:
em2800_write_regs_req(dev,0x02,0x4a,"\x0b\x47",2); em2800_write_regs_req(dev,0x02,0x4a,"\x0c\x40",2);
or
em2800_write_regs_req(dev,0x02,0x4a,"\x0b\x47\x40",3);
Markus Rechberger
Ok, I stopped asking my why bRequest is 3; maybe if we manage to have some specs, it will be easier to understand.
Let's look more in detail at what is happening with the saa7113. The device is always initialized writing a fixed set of values to it's first 16 registers. The Windows driver does this many times: I wondering why; however I noticed this fact: if I first initialize the saa7113, second set up the em2820 with the data from the logs (from Markus), then the settings of the the saa7113h are lost. Maybe the em2820 is doing some kind of reset of the chips on the board.
Here the modified initialization table follows; the values marked with **, are those I changed to match the setting from the Windows driver.
0x00, 0x00, /* PH7113_CHIP_VERSION 00 - ID byte */ 0x01, 0x08, /* PH7113_INCREMENT_DELAY - (1) (1) (1) (1) IDEL3 IDEL2 IDELL1 IDEL0 */ 0x02, 0xc2, /** PH7113_ANALOG_INPUT_CONTR_1 - FUSE1 FUSE0 GUDL1 GUDL0 MODE3 MODE2 MODE1 MODE0 */ 0x03, 0x30, /** PH7113_ANALOG_INPUT_CONTR_2 - (1) HLNRS VBSL WPOFF HOLDG GAFIX GAI28 GAI18 */ 0x04, 0x00, /* PH7113_ANALOG_INPUT_CONTR_3 - GAI17 GAI16 GAI15 GAI14 GAI13 GAI12 GAI11 GAI10 */ 0x05, 0x00, /* PH7113_ANALOG_INPUT_CONTR_4 - GAI27 GAI26 GAI25 GAI24 GAI23 GAI22 GAI21 GAI20 */ 0x06, 0x89, /** PH7113_HORIZONTAL_SYNC_START - HSB7 HSB6 HSB5 HSB4 HSB3 HSB2 HSB1 HSB0 */ 0x07, 0x0d, /** PH7113_HORIZONTAL_SYNC_STOP - HSS7 HSS6 HSS5 HSS4 HSS3 HSS2 HSS1 HSS0 */ 0x08, 0x88, /* PH7113_SYNC_CONTROL - AUFD FSEL FOET HTC1 HTC0 HPLL VNOI1 VNOI0 */ 0x09, 0x01, /** PH7113_LUMINANCE_CONTROL - BYPS PREF BPSS1 BPSS0 VBLB UPTCV APER1 APER0 */ 0x0a, 0x80, /* PH7113_LUMINANCE_BRIGHTNESS - BRIG7 BRIG6 BRIG5 BRIG4 BRIG3 BRIG2 BRIG1 BRIG0 */ 0x0b, 0x47, /* PH7113_LUMINANCE_CONTRAST - CONT7 CONT6 CONT5 CONT4 CONT3 CONT2 CONT1 CONT0 */ 0x0c, 0x40, /* PH7113_CHROMA_SATURATION - SATN7 SATN6 SATN5 SATN4 SATN3 SATN2 SATN1 SATN0 */ 0x0d, 0x00, /* PH7113_CHROMA_HUE_CONTROL - HUEC7 HUEC6 HUEC5 HUEC4 HUEC3 HUEC2 HUEC1 HUEC0 */ 0x0e, 0x01, /* PH7113_CHROMA_CONTROL - CDTO CSTD2 CSTD1 CSTD0 DCCF FCTC CHBW1 CHBW0 */ 0x0f, 0x2a, /** PH7113_CHROMA_GAIN_CONTROL - ACGC CGAIN6 CGAIN5 CGAIN4 CGAIN3 CGAIN2 CGAIN1 CGAIN0 */ 0x10, 0x08, /** PH7113_FORMAT_DELAY_CONTROL - OFTS1 OFTS0 HDEL1 HDEL0 VRLN YDEL2 YDEL1 YDEL0 */ 0x11, 0x0c, /** PH7113_OUTPUT_CONTROL_1 - GPSW1 CM99 GPSW0 HLSEL OEYC OERT VIPB COLO */ 0x12, 0x07, /** PH7113_OUTPUT_CONTROL_2 - RTSE13 RTSE12 RTSE11 RTSE10 RTSE03 RTSE02 RTSE01 RTSE00 */ 0x13, 0x00, /* PH7113_OUTPUT_CONTROL_3 - ADLSB (1) (1) OLDSB FIDP (1) AOSL1 AOSL0 */ 0x14, 0x00, /* RESERVED 14 - (1) (1) (1) (1) (1) (1) (1) (1) */ 0x15, 0x00, /* PH7113_V_GATE1_START - VSTA7 VSTA6 VSTA5 VSTA4 VSTA3 VSTA2 VSTA1 VSTA0 */ 0x16, 0x00, /* PH7113_V_GATE1_STOP - VSTO7 VSTO6 VSTO5 VSTO4 VSTO3 VSTO2 VSTO1 VSTO0 */ 0x17, 0x00, /* PH7113_V_GATE1_MSB - (1) (1) (1) (1) (1) (1) VSTO8 VSTA8 */
The registers we are interested in are:
- 0x02: to select video input (tuner, composite, S-Video)
- 0x08 and 0x0e: to select video standard (PAL, NTSC, SECAM, ...)
- 0x0a to 0x0c: are the brightness, contrast and saturation; please note that the Windows driver does not change these registers, but those registers inside the em2820. It would be interesting to try both ways and see quality differences.
- 0x0d: hue; changed also by the Windows driver.
The only register I saw being read is 0x1f, that reports the status of the decoder, but I haven't strted to play with it yet. However, the code to control
Ludovico Cavedon