Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (442 commits) [media] videobuf2-dma-contig: make cookie() return a pointer to dma_addr_t [media] sh_mobile_ceu_camera: Do not call vb2's mem_ops directly [media] V4L: soc-camera: explicitly require V4L2_BUF_TYPE_VIDEO_CAPTURE [media] v4l: soc-camera: Store negotiated buffer settings [media] rc: interim support for 32-bit NEC-ish scancodes [media] mceusb: topseed 0x0011 needs gen3 init for tx to work [media] lirc_zilog: error out if buffer read bytes != chunk size [media] lirc: silence some compile warnings [media] hdpvr: use same polling interval as other OS [media] ir-kbd-i2c: pass device code w/key in hauppauge case [media] rc/keymaps: Remove the obsolete rc-rc5-tv keymap [media] remove the old RC_MAP_HAUPPAUGE_NEW RC map [media] rc/keymaps: Rename Hauppauge table as rc-hauppauge [media] rc-rc5-hauppauge-new: Fix Hauppauge Grey mapping [media] rc-rc5-hauppauge-new: Add support for the old Black RC [media] rc-rc5-hauppauge-new: Add the old control to the table [media] rc-winfast: Fix the keycode tables [media] a800: Fix a few wrong IR key assignments [media] opera1: Use multimedia keys instead of an app-specific mapping [media] dw2102: Use multimedia keys instead of an app-specific mapping ... Fix up trivial conflicts (remove/modify and some real conflicts) in: arch/arm/mach-omap2/devices.c drivers/staging/Kconfig drivers/staging/Makefile drivers/staging/dabusb/dabusb.c drivers/staging/dabusb/dabusb.h drivers/staging/easycap/easycap_ioctl.c drivers/staging/usbvideo/usbvideo.c drivers/staging/usbvideo/vicam.c
This commit is contained in:
		
						commit
						76d21c5635
					
				
							
								
								
									
										6
									
								
								Documentation/ABI/testing/sysfs-bus-media
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Documentation/ABI/testing/sysfs-bus-media
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| What:		/sys/bus/media/devices/.../model | ||||
| Date:		January 2011 | ||||
| Contact:	Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||||
| 		linux-media@vger.kernel.org | ||||
| Description:	Contains the device model name in UTF-8. The device version is | ||||
| 		is not be appended to the model name. | ||||
| @ -53,7 +53,10 @@ MAN := $(patsubst %.xml, %.9, $(BOOKS)) | ||||
| mandocs: $(MAN) | ||||
| 
 | ||||
| build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
 | ||||
| 	       cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/ | ||||
| 	       cp $(srctree)/Documentation/DocBook/dvb/*.png \
 | ||||
| 	          $(srctree)/Documentation/DocBook/v4l/*.gif \
 | ||||
| 	          $(srctree)/Documentation/DocBook/v4l/*.png \
 | ||||
| 		  $(objtree)/Documentation/DocBook/media/ | ||||
| 
 | ||||
| xmldoclinks: | ||||
| ifneq ($(objtree),$(srctree)) | ||||
|  | ||||
| @ -11,6 +11,10 @@ | ||||
| <!ENTITY func-select "<link linkend='func-select'><function>select()</function></link>"> | ||||
| <!ENTITY func-write "<link linkend='func-write'><function>write()</function></link>"> | ||||
| 
 | ||||
| <!ENTITY media-func-close "<link linkend='media-func-close'><function>close()</function></link>"> | ||||
| <!ENTITY media-func-ioctl "<link linkend='media-func-ioctl'><function>ioctl()</function></link>"> | ||||
| <!ENTITY media-func-open "<link linkend='media-func-open'><function>open()</function></link>"> | ||||
| 
 | ||||
| <!-- Ioctls --> | ||||
| <!ENTITY VIDIOC-CROPCAP "<link linkend='vidioc-cropcap'><constant>VIDIOC_CROPCAP</constant></link>"> | ||||
| <!ENTITY VIDIOC-DBG-G-CHIP-IDENT "<link linkend='vidioc-dbg-g-chip-ident'><constant>VIDIOC_DBG_G_CHIP_IDENT</constant></link>"> | ||||
| @ -82,11 +86,24 @@ | ||||
| <!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>"> | ||||
| <!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>"> | ||||
| <!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>"> | ||||
| <!ENTITY VIDIOC-SUBDEV-ENUM-FRAME-SIZE "<link linkend='vidioc-subdev-enum-frame-size'><constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant></link>"> | ||||
| <!ENTITY VIDIOC-SUBDEV-ENUM-MBUS-CODE "<link linkend='vidioc-subdev-enum-mbus-code'><constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant></link>"> | ||||
| <!ENTITY VIDIOC-SUBDEV-G-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_G_CROP</constant></link>"> | ||||
| <!ENTITY VIDIOC-SUBDEV-G-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_G_FMT</constant></link>"> | ||||
| <!ENTITY VIDIOC-SUBDEV-G-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant></link>"> | ||||
| <!ENTITY VIDIOC-SUBDEV-S-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_S_CROP</constant></link>"> | ||||
| <!ENTITY VIDIOC-SUBDEV-S-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_S_FMT</constant></link>"> | ||||
| <!ENTITY VIDIOC-SUBDEV-S-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></link>"> | ||||
| <!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>"> | ||||
| <!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>"> | ||||
| <!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>"> | ||||
| <!ENTITY VIDIOC-UNSUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_UNSUBSCRIBE_EVENT</constant></link>"> | ||||
| 
 | ||||
| <!ENTITY MEDIA-IOC-DEVICE-INFO "<link linkend='media-ioc-device-info'><constant>MEDIA_IOC_DEVICE_INFO</constant></link>"> | ||||
| <!ENTITY MEDIA-IOC-ENUM-ENTITIES "<link linkend='media-ioc-enum-entities'><constant>MEDIA_IOC_ENUM_ENTITIES</constant></link>"> | ||||
| <!ENTITY MEDIA-IOC-ENUM-LINKS "<link linkend='media-ioc-enum-links'><constant>MEDIA_IOC_ENUM_LINKS</constant></link>"> | ||||
| <!ENTITY MEDIA-IOC-SETUP-LINK "<link linkend='media-ioc-setup-link'><constant>MEDIA_IOC_SETUP_LINK</constant></link>"> | ||||
| 
 | ||||
| <!-- Types --> | ||||
| <!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>"> | ||||
| 
 | ||||
| @ -98,6 +115,7 @@ | ||||
| <!ENTITY v4l2-field "enum <link linkend='v4l2-field'>v4l2_field</link>"> | ||||
| <!ENTITY v4l2-frmivaltypes "enum <link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>"> | ||||
| <!ENTITY v4l2-frmsizetypes "enum <link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>"> | ||||
| <!ENTITY v4l2-mbus-pixelcode "enum <link linkend='v4l2-mbus-pixelcode'>v4l2_mbus_pixelcode</link>"> | ||||
| <!ENTITY v4l2-memory "enum <link linkend='v4l2-memory'>v4l2_memory</link>"> | ||||
| <!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum <link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>"> | ||||
| <!ENTITY v4l2-mpeg-audio-crc "enum <link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>"> | ||||
| @ -121,6 +139,7 @@ | ||||
| <!ENTITY v4l2-mpeg-video-encoding "enum <link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>"> | ||||
| <!ENTITY v4l2-power-line-frequency "enum <link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>"> | ||||
| <!ENTITY v4l2-priority "enum <link linkend='v4l2-priority'>v4l2_priority</link>"> | ||||
| <!ENTITY v4l2-subdev-format-whence "enum <link linkend='v4l2-subdev-format-whence'>v4l2_subdev_format_whence</link>"> | ||||
| <!ENTITY v4l2-tuner-type "enum <link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>"> | ||||
| <!ENTITY v4l2-preemphasis "enum <link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>"> | ||||
| 
 | ||||
| @ -129,6 +148,7 @@ | ||||
| <!ENTITY v4l2-audioout "struct <link linkend='v4l2-audioout'>v4l2_audioout</link>"> | ||||
| <!ENTITY v4l2-bt-timings "struct <link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>"> | ||||
| <!ENTITY v4l2-buffer "struct <link linkend='v4l2-buffer'>v4l2_buffer</link>"> | ||||
| <!ENTITY v4l2-plane "struct <link linkend='v4l2-plane'>v4l2_plane</link>"> | ||||
| <!ENTITY v4l2-capability "struct <link linkend='v4l2-capability'>v4l2_capability</link>"> | ||||
| <!ENTITY v4l2-captureparm "struct <link linkend='v4l2-captureparm'>v4l2_captureparm</link>"> | ||||
| <!ENTITY v4l2-clip "struct <link linkend='v4l2-clip'>v4l2_clip</link>"> | ||||
| @ -162,11 +182,14 @@ | ||||
| <!ENTITY v4l2-hw-freq-seek "struct <link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>"> | ||||
| <!ENTITY v4l2-input "struct <link linkend='v4l2-input'>v4l2_input</link>"> | ||||
| <!ENTITY v4l2-jpegcompression "struct <link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>"> | ||||
| <!ENTITY v4l2-mbus-framefmt "struct <link linkend='v4l2-mbus-framefmt'>v4l2_mbus_framefmt</link>"> | ||||
| <!ENTITY v4l2-modulator "struct <link linkend='v4l2-modulator'>v4l2_modulator</link>"> | ||||
| <!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct <link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>"> | ||||
| <!ENTITY v4l2-output "struct <link linkend='v4l2-output'>v4l2_output</link>"> | ||||
| <!ENTITY v4l2-outputparm "struct <link linkend='v4l2-outputparm'>v4l2_outputparm</link>"> | ||||
| <!ENTITY v4l2-pix-format "struct <link linkend='v4l2-pix-format'>v4l2_pix_format</link>"> | ||||
| <!ENTITY v4l2-pix-format-mplane "struct <link linkend='v4l2-pix-format-mplane'>v4l2_pix_format_mplane</link>"> | ||||
| <!ENTITY v4l2-plane-pix-format "struct <link linkend='v4l2-plane-pix-format'>v4l2_plane_pix_format</link>"> | ||||
| <!ENTITY v4l2-queryctrl "struct <link linkend='v4l2-queryctrl'>v4l2_queryctrl</link>"> | ||||
| <!ENTITY v4l2-querymenu "struct <link linkend='v4l2-querymenu'>v4l2_querymenu</link>"> | ||||
| <!ENTITY v4l2-rect "struct <link linkend='v4l2-rect'>v4l2_rect</link>"> | ||||
| @ -174,6 +197,12 @@ | ||||
| <!ENTITY v4l2-sliced-vbi-cap "struct <link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>"> | ||||
| <!ENTITY v4l2-sliced-vbi-data "struct <link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>"> | ||||
| <!ENTITY v4l2-sliced-vbi-format "struct <link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>"> | ||||
| <!ENTITY v4l2-subdev-frame-interval "struct <link linkend='v4l2-subdev-frame-interval'>v4l2_subdev_frame_interval</link>"> | ||||
| <!ENTITY v4l2-subdev-frame-interval-enum "struct <link linkend='v4l2-subdev-frame-interval-enum'>v4l2_subdev_frame_interval_enum</link>"> | ||||
| <!ENTITY v4l2-subdev-frame-size-enum "struct <link linkend='v4l2-subdev-frame-size-enum'>v4l2_subdev_frame_size_enum</link>"> | ||||
| <!ENTITY v4l2-subdev-crop "struct <link linkend='v4l2-subdev-crop'>v4l2_subdev_crop</link>"> | ||||
| <!ENTITY v4l2-subdev-format "struct <link linkend='v4l2-subdev-format'>v4l2_subdev_format</link>"> | ||||
| <!ENTITY v4l2-subdev-mbus-code-enum "struct <link linkend='v4l2-subdev-mbus-code-enum'>v4l2_subdev_mbus_code_enum</link>"> | ||||
| <!ENTITY v4l2-standard "struct <link linkend='v4l2-standard'>v4l2_standard</link>"> | ||||
| <!ENTITY v4l2-streamparm "struct <link linkend='v4l2-streamparm'>v4l2_streamparm</link>"> | ||||
| <!ENTITY v4l2-timecode "struct <link linkend='v4l2-timecode'>v4l2_timecode</link>"> | ||||
| @ -181,6 +210,12 @@ | ||||
| <!ENTITY v4l2-vbi-format "struct <link linkend='v4l2-vbi-format'>v4l2_vbi_format</link>"> | ||||
| <!ENTITY v4l2-window "struct <link linkend='v4l2-window'>v4l2_window</link>"> | ||||
| 
 | ||||
| <!ENTITY media-device-info "struct <link linkend='media-device-info'>media_device_info</link>"> | ||||
| <!ENTITY media-entity-desc "struct <link linkend='media-entity-desc'>media_entity_desc</link>"> | ||||
| <!ENTITY media-links-enum "struct <link linkend='media-links-enum'>media_links_enum</link>"> | ||||
| <!ENTITY media-pad-desc "struct <link linkend='media-pad-desc'>media_pad_desc</link>"> | ||||
| <!ENTITY media-link-desc "struct <link linkend='media-link-desc'>media_link_desc</link>"> | ||||
| 
 | ||||
| <!-- Error Codes --> | ||||
| <!ENTITY EACCES "<errorcode>EACCES</errorcode> error code"> | ||||
| <!ENTITY EAGAIN "<errorcode>EAGAIN</errorcode> error code"> | ||||
| @ -197,11 +232,13 @@ | ||||
| <!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code"> | ||||
| <!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code"> | ||||
| <!ENTITY EPERM "<errorcode>EPERM</errorcode> error code"> | ||||
| <!ENTITY EPIPE "<errorcode>EPIPE</errorcode> error code"> | ||||
| <!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code"> | ||||
| 
 | ||||
| <!-- Subsections --> | ||||
| <!ENTITY sub-biblio SYSTEM "v4l/biblio.xml"> | ||||
| <!ENTITY sub-common SYSTEM "v4l/common.xml"> | ||||
| <!ENTITY sub-planar-apis SYSTEM "v4l/planar-apis.xml"> | ||||
| <!ENTITY sub-compat SYSTEM "v4l/compat.xml"> | ||||
| <!ENTITY sub-controls SYSTEM "v4l/controls.xml"> | ||||
| <!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml"> | ||||
| @ -215,6 +252,7 @@ | ||||
| <!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml"> | ||||
| <!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml"> | ||||
| <!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml"> | ||||
| <!ENTITY sub-dev-subdev SYSTEM "v4l/dev-subdev.xml"> | ||||
| <!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml"> | ||||
| <!ENTITY sub-driver SYSTEM "v4l/driver.xml"> | ||||
| <!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml"> | ||||
| @ -233,6 +271,8 @@ | ||||
| <!ENTITY sub-io SYSTEM "v4l/io.xml"> | ||||
| <!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml"> | ||||
| <!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml"> | ||||
| <!ENTITY sub-nv12m SYSTEM "v4l/pixfmt-nv12m.xml"> | ||||
| <!ENTITY sub-nv12mt SYSTEM "v4l/pixfmt-nv12mt.xml"> | ||||
| <!ENTITY sub-nv16 SYSTEM "v4l/pixfmt-nv16.xml"> | ||||
| <!ENTITY sub-packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml"> | ||||
| <!ENTITY sub-packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml"> | ||||
| @ -247,6 +287,7 @@ | ||||
| <!ENTITY sub-yuv410 SYSTEM "v4l/pixfmt-yuv410.xml"> | ||||
| <!ENTITY sub-yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml"> | ||||
| <!ENTITY sub-yuv420 SYSTEM "v4l/pixfmt-yuv420.xml"> | ||||
| <!ENTITY sub-yuv420m SYSTEM "v4l/pixfmt-yuv420m.xml"> | ||||
| <!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml"> | ||||
| <!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml"> | ||||
| <!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml"> | ||||
| @ -298,6 +339,13 @@ | ||||
| <!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml"> | ||||
| <!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml"> | ||||
| <!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml"> | ||||
| <!ENTITY sub-subdev-enum-frame-interval SYSTEM "v4l/vidioc-subdev-enum-frame-interval.xml"> | ||||
| <!ENTITY sub-subdev-enum-frame-size SYSTEM "v4l/vidioc-subdev-enum-frame-size.xml"> | ||||
| <!ENTITY sub-subdev-enum-mbus-code SYSTEM "v4l/vidioc-subdev-enum-mbus-code.xml"> | ||||
| <!ENTITY sub-subdev-formats SYSTEM "v4l/subdev-formats.xml"> | ||||
| <!ENTITY sub-subdev-g-crop SYSTEM "v4l/vidioc-subdev-g-crop.xml"> | ||||
| <!ENTITY sub-subdev-g-fmt SYSTEM "v4l/vidioc-subdev-g-fmt.xml"> | ||||
| <!ENTITY sub-subdev-g-frame-interval SYSTEM "v4l/vidioc-subdev-g-frame-interval.xml"> | ||||
| <!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml"> | ||||
| <!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml"> | ||||
| <!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml"> | ||||
| @ -321,6 +369,15 @@ | ||||
| <!ENTITY sub-media-entities SYSTEM "media-entities.tmpl"> | ||||
| <!ENTITY sub-media-indices SYSTEM "media-indices.tmpl"> | ||||
| 
 | ||||
| <!ENTITY sub-media-controller SYSTEM "v4l/media-controller.xml"> | ||||
| <!ENTITY sub-media-open SYSTEM "v4l/media-func-open.xml"> | ||||
| <!ENTITY sub-media-close SYSTEM "v4l/media-func-close.xml"> | ||||
| <!ENTITY sub-media-ioctl SYSTEM "v4l/media-func-ioctl.xml"> | ||||
| <!ENTITY sub-media-ioc-device-info SYSTEM "v4l/media-ioc-device-info.xml"> | ||||
| <!ENTITY sub-media-ioc-enum-entities SYSTEM "v4l/media-ioc-enum-entities.xml"> | ||||
| <!ENTITY sub-media-ioc-enum-links SYSTEM "v4l/media-ioc-enum-links.xml"> | ||||
| <!ENTITY sub-media-ioc-setup-link SYSTEM "v4l/media-ioc-setup-link.xml"> | ||||
| 
 | ||||
| <!-- Function Reference --> | ||||
| <!ENTITY close SYSTEM "v4l/func-close.xml"> | ||||
| <!ENTITY ioctl SYSTEM "v4l/func-ioctl.xml"> | ||||
| @ -333,6 +390,7 @@ | ||||
| <!ENTITY write SYSTEM "v4l/func-write.xml"> | ||||
| <!ENTITY grey SYSTEM "v4l/pixfmt-grey.xml"> | ||||
| <!ENTITY nv12 SYSTEM "v4l/pixfmt-nv12.xml"> | ||||
| <!ENTITY nv12m SYSTEM "v4l/pixfmt-nv12m.xml"> | ||||
| <!ENTITY nv16 SYSTEM "v4l/pixfmt-nv16.xml"> | ||||
| <!ENTITY packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml"> | ||||
| <!ENTITY packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml"> | ||||
| @ -347,6 +405,7 @@ | ||||
| <!ENTITY yuv410 SYSTEM "v4l/pixfmt-yuv410.xml"> | ||||
| <!ENTITY yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml"> | ||||
| <!ENTITY yuv420 SYSTEM "v4l/pixfmt-yuv420.xml"> | ||||
| <!ENTITY yuv420m SYSTEM "v4l/pixfmt-yuv420m.xml"> | ||||
| <!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml"> | ||||
| <!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml"> | ||||
| <!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml"> | ||||
|  | ||||
| @ -106,6 +106,9 @@ Foundation. A copy of the license is included in the chapter entitled | ||||
| &sub-remote_controllers; | ||||
| </chapter> | ||||
| </part> | ||||
| <part id="media_common"> | ||||
| &sub-media-controller; | ||||
| </part> | ||||
| 
 | ||||
| &sub-fdl-appendix; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/bayer.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/bayer.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/bayer.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/bayer.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 9.5 KiB | 
| @ -846,6 +846,8 @@ conversion routine or library for integration into applications.</para> | ||||
|     </section> | ||||
|   </section> | ||||
| 
 | ||||
|   &sub-planar-apis; | ||||
| 
 | ||||
|   <section id="crop"> | ||||
|     <title>Image Cropping, Insertion and Scaling</title> | ||||
| 
 | ||||
|  | ||||
| @ -1711,8 +1711,8 @@ ioctl would enumerate the available audio inputs. An ioctl to | ||||
| determine the current audio input, if more than one combines with the | ||||
| current video input, did not exist. So | ||||
| <constant>VIDIOC_G_AUDIO</constant> was renamed to | ||||
| <constant>VIDIOC_G_AUDIO_OLD</constant>, this ioctl will be removed in | ||||
| the future. The &VIDIOC-ENUMAUDIO; ioctl was added to enumerate | ||||
| <constant>VIDIOC_G_AUDIO_OLD</constant>, this ioctl was removed on | ||||
| Kernel 2.6.39. The &VIDIOC-ENUMAUDIO; ioctl was added to enumerate | ||||
| audio inputs, while &VIDIOC-G-AUDIO; now reports the current audio | ||||
| input.</para> | ||||
| 	  <para>The same changes were made to &VIDIOC-G-AUDOUT; and | ||||
| @ -1726,7 +1726,7 @@ must be updated to successfully compile again.</para> | ||||
| 	  <para>The &VIDIOC-OVERLAY; ioctl was incorrectly defined with | ||||
| write-read parameter. It was changed to write-only, while the write-read | ||||
| version was renamed to <constant>VIDIOC_OVERLAY_OLD</constant>. The old | ||||
| ioctl will be removed in the future. Until further the "videodev" | ||||
| ioctl was removed on Kernel 2.6.39. Until further the "videodev" | ||||
| kernel module will automatically translate to the new version, so drivers | ||||
| must be recompiled, but not applications.</para> | ||||
| 	</listitem> | ||||
| @ -1744,7 +1744,7 @@ surface can be seen.</para> | ||||
| defined with write-only parameter, inconsistent with other ioctls | ||||
| modifying their argument. They were changed to write-read, while a | ||||
| <constant>_OLD</constant> suffix was added to the write-only versions. | ||||
| The old ioctls will be removed in the future. Drivers and | ||||
| The old ioctls were removed on Kernel 2.6.39. Drivers and | ||||
| applications assuming a constant parameter need an update.</para> | ||||
| 	</listitem> | ||||
|       </orderedlist> | ||||
| @ -1815,8 +1815,8 @@ yet to be addressed, for details see <xref | ||||
| 	  <para>The &VIDIOC-CROPCAP; ioctl was incorrectly defined | ||||
| with read-only parameter. It is now defined as write-read ioctl, while | ||||
| the read-only version was renamed to | ||||
| <constant>VIDIOC_CROPCAP_OLD</constant>. The old ioctl will be removed | ||||
| in the future.</para> | ||||
| <constant>VIDIOC_CROPCAP_OLD</constant>. The old ioctl was removed | ||||
| on Kernel 2.6.39.</para> | ||||
| 	</listitem> | ||||
|       </orderedlist> | ||||
|     </section> | ||||
| @ -2353,6 +2353,20 @@ that used it. It was originally scheduled for removal in 2.6.35. | ||||
| 	</listitem> | ||||
|       </orderedlist> | ||||
|     </section> | ||||
|     <section> | ||||
|       <title>V4L2 in Linux 2.6.39</title> | ||||
|       <orderedlist> | ||||
|         <listitem> | ||||
|           <para>The old VIDIOC_*_OLD symbols and V4L1 support were removed.</para> | ||||
|         </listitem> | ||||
|         <listitem> | ||||
|           <para>Multi-planar API added. Does not affect the compatibility of | ||||
|           current drivers and applications. See | ||||
|           <link linkend="planar-apis">multi-planar API</link> | ||||
|           for details.</para> | ||||
|         </listitem> | ||||
|       </orderedlist> | ||||
|     </section> | ||||
| 
 | ||||
|     <section id="other"> | ||||
|       <title>Relation of V4L2 to other Linux multimedia APIs</title> | ||||
|  | ||||
| @ -18,7 +18,8 @@ files are used for video output devices.</para> | ||||
|     <title>Querying Capabilities</title> | ||||
| 
 | ||||
|     <para>Devices supporting the video capture interface set the | ||||
| <constant>V4L2_CAP_VIDEO_CAPTURE</constant> flag in the | ||||
| <constant>V4L2_CAP_VIDEO_CAPTURE</constant> or | ||||
| <constant>V4L2_CAP_VIDEO_CAPTURE_MPLANE</constant> flag in the | ||||
| <structfield>capabilities</structfield> field of &v4l2-capability; | ||||
| returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions | ||||
| they may also support the <link linkend="overlay">video overlay</link> | ||||
| @ -64,9 +65,11 @@ linkend="crop" />.</para> | ||||
| 
 | ||||
|     <para>To query the current image format applications set the | ||||
| <structfield>type</structfield> field of a &v4l2-format; to | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> and call the | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> or | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant> and call the | ||||
| &VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill | ||||
| the &v4l2-pix-format; <structfield>pix</structfield> member of the | ||||
| the &v4l2-pix-format; <structfield>pix</structfield> or the | ||||
| &v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member of the | ||||
| <structfield>fmt</structfield> union.</para> | ||||
| 
 | ||||
|     <para>To request different parameters applications set the | ||||
| @ -84,8 +87,8 @@ adjust the parameters and finally return the actual parameters as | ||||
| without disabling I/O or possibly time consuming hardware | ||||
| preparations.</para> | ||||
| 
 | ||||
|     <para>The contents of &v4l2-pix-format; are discussed in <xref | ||||
| linkend="pixfmt" />. See also the specification of the | ||||
|     <para>The contents of &v4l2-pix-format; and &v4l2-pix-format-mplane; | ||||
| are discussed in <xref linkend="pixfmt" />. See also the specification of the | ||||
| <constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant> | ||||
| and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video | ||||
| capture devices must implement both the | ||||
|  | ||||
| @ -17,7 +17,8 @@ files are used for video capture devices.</para> | ||||
|     <title>Querying Capabilities</title> | ||||
| 
 | ||||
|     <para>Devices supporting the video output interface set the | ||||
| <constant>V4L2_CAP_VIDEO_OUTPUT</constant> flag in the | ||||
| <constant>V4L2_CAP_VIDEO_OUTPUT</constant> or | ||||
| <constant>V4L2_CAP_VIDEO_OUTPUT_MPLANE</constant> flag in the | ||||
| <structfield>capabilities</structfield> field of &v4l2-capability; | ||||
| returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions | ||||
| they may also support the <link linkend="raw-vbi">raw VBI | ||||
| @ -60,9 +61,11 @@ linkend="crop" />.</para> | ||||
| 
 | ||||
|     <para>To query the current image format applications set the | ||||
| <structfield>type</structfield> field of a &v4l2-format; to | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> and call the | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> or | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant> and call the | ||||
| &VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill | ||||
| the &v4l2-pix-format; <structfield>pix</structfield> member of the | ||||
| the &v4l2-pix-format; <structfield>pix</structfield> or the | ||||
| &v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member of the | ||||
| <structfield>fmt</structfield> union.</para> | ||||
| 
 | ||||
|     <para>To request different parameters applications set the | ||||
| @ -80,8 +83,8 @@ adjust the parameters and finally return the actual parameters as | ||||
| without disabling I/O or possibly time consuming hardware | ||||
| preparations.</para> | ||||
| 
 | ||||
|     <para>The contents of &v4l2-pix-format; are discussed in <xref | ||||
| linkend="pixfmt" />. See also the specification of the | ||||
|     <para>The contents of &v4l2-pix-format; and &v4l2-pix-format-mplane; | ||||
| are discussed in <xref linkend="pixfmt" />. See also the specification of the | ||||
| <constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant> | ||||
| and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video | ||||
| output devices must implement both the | ||||
|  | ||||
							
								
								
									
										313
									
								
								Documentation/DocBook/v4l/dev-subdev.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								Documentation/DocBook/v4l/dev-subdev.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,313 @@ | ||||
|   <title>Sub-device Interface</title> | ||||
| 
 | ||||
|   <note> | ||||
|     <title>Experimental</title> | ||||
|     <para>This is an <link linkend="experimental">experimental</link> | ||||
|     interface and may change in the future.</para> | ||||
|   </note> | ||||
| 
 | ||||
|   <para>The complex nature of V4L2 devices, where hardware is often made of | ||||
|   several integrated circuits that need to interact with each other in a | ||||
|   controlled way, leads to complex V4L2 drivers. The drivers usually reflect | ||||
|   the hardware model in software, and model the different hardware components | ||||
|   as software blocks called sub-devices.</para> | ||||
| 
 | ||||
|   <para>V4L2 sub-devices are usually kernel-only objects. If the V4L2 driver | ||||
|   implements the media device API, they will automatically inherit from media | ||||
|   entities. Applications will be able to enumerate the sub-devices and discover | ||||
|   the hardware topology using the media entities, pads and links enumeration | ||||
|   API.</para> | ||||
| 
 | ||||
|   <para>In addition to make sub-devices discoverable, drivers can also choose | ||||
|   to make them directly configurable by applications. When both the sub-device | ||||
|   driver and the V4L2 device driver support this, sub-devices will feature a | ||||
|   character device node on which ioctls can be called to | ||||
|   <itemizedlist> | ||||
|     <listitem><para>query, read and write sub-devices controls</para></listitem> | ||||
|     <listitem><para>subscribe and unsubscribe to events and retrieve them</para></listitem> | ||||
|     <listitem><para>negotiate image formats on individual pads</para></listitem> | ||||
|   </itemizedlist> | ||||
|   </para> | ||||
| 
 | ||||
|   <para>Sub-device character device nodes, conventionally named | ||||
|   <filename>/dev/v4l-subdev*</filename>, use major number 81.</para> | ||||
| 
 | ||||
|   <section> | ||||
|     <title>Controls</title> | ||||
|     <para>Most V4L2 controls are implemented by sub-device hardware. Drivers | ||||
|     usually merge all controls and expose them through video device nodes. | ||||
|     Applications can control all sub-devices through a single interface.</para> | ||||
| 
 | ||||
|     <para>Complex devices sometimes implement the same control in different | ||||
|     pieces of hardware. This situation is common in embedded platforms, where | ||||
|     both sensors and image processing hardware implement identical functions, | ||||
|     such as contrast adjustment, white balance or faulty pixels correction. As | ||||
|     the V4L2 controls API doesn't support several identical controls in a single | ||||
|     device, all but one of the identical controls are hidden.</para> | ||||
| 
 | ||||
|     <para>Applications can access those hidden controls through the sub-device | ||||
|     node with the V4L2 control API described in <xref linkend="control" />. The | ||||
|     ioctls behave identically as when issued on V4L2 device nodes, with the | ||||
|     exception that they deal only with controls implemented in the sub-device. | ||||
|     </para> | ||||
| 
 | ||||
|     <para>Depending on the driver, those controls might also be exposed through | ||||
|     one (or several) V4L2 device nodes.</para> | ||||
|   </section> | ||||
| 
 | ||||
|   <section> | ||||
|     <title>Events</title> | ||||
|     <para>V4L2 sub-devices can notify applications of events as described in | ||||
|     <xref linkend="event" />. The API behaves identically as when used on V4L2 | ||||
|     device nodes, with the exception that it only deals with events generated by | ||||
|     the sub-device. Depending on the driver, those events might also be reported | ||||
|     on one (or several) V4L2 device nodes.</para> | ||||
|   </section> | ||||
| 
 | ||||
|   <section id="pad-level-formats"> | ||||
|     <title>Pad-level Formats</title> | ||||
| 
 | ||||
|     <warning><para>Pad-level formats are only applicable to very complex device that | ||||
|     need to expose low-level format configuration to user space. Generic V4L2 | ||||
|     applications do <emphasis>not</emphasis> need to use the API described in | ||||
|     this section.</para></warning> | ||||
| 
 | ||||
|     <note><para>For the purpose of this section, the term | ||||
|     <wordasword>format</wordasword> means the combination of media bus data | ||||
|     format, frame width and frame height.</para></note> | ||||
| 
 | ||||
|     <para>Image formats are typically negotiated on video capture and output | ||||
|     devices using the <link linkend="crop">cropping and scaling</link> ioctls. | ||||
|     The driver is responsible for configuring every block in the video pipeline | ||||
|     according to the requested format at the pipeline input and/or | ||||
|     output.</para> | ||||
| 
 | ||||
|     <para>For complex devices, such as often found in embedded systems, | ||||
|     identical image sizes at the output of a pipeline can be achieved using | ||||
|     different hardware configurations. One such example is shown on | ||||
|     <xref linkend="pipeline-scaling" />, where | ||||
|     image scaling can be performed on both the video sensor and the host image | ||||
|     processing hardware.</para> | ||||
| 
 | ||||
|     <figure id="pipeline-scaling"> | ||||
|       <title>Image Format Negotation on Pipelines</title> | ||||
|       <mediaobject> | ||||
| 	<imageobject> | ||||
| 	  <imagedata fileref="pipeline.pdf" format="PS" /> | ||||
| 	</imageobject> | ||||
| 	<imageobject> | ||||
| 	  <imagedata fileref="pipeline.png" format="PNG" /> | ||||
| 	</imageobject> | ||||
| 	<textobject> | ||||
| 	  <phrase>High quality and high speed pipeline configuration</phrase> | ||||
| 	</textobject> | ||||
|       </mediaobject> | ||||
|     </figure> | ||||
| 
 | ||||
|     <para>The sensor scaler is usually of less quality than the host scaler, but | ||||
|     scaling on the sensor is required to achieve higher frame rates. Depending | ||||
|     on the use case (quality vs. speed), the pipeline must be configured | ||||
|     differently. Applications need to configure the formats at every point in | ||||
|     the pipeline explicitly.</para> | ||||
| 
 | ||||
|     <para>Drivers that implement the <link linkend="media-controller-intro">media | ||||
|     API</link> can expose pad-level image format configuration to applications. | ||||
|     When they do, applications can use the &VIDIOC-SUBDEV-G-FMT; and | ||||
|     &VIDIOC-SUBDEV-S-FMT; ioctls. to negotiate formats on a per-pad basis.</para> | ||||
| 
 | ||||
|     <para>Applications are responsible for configuring coherent parameters on | ||||
|     the whole pipeline and making sure that connected pads have compatible | ||||
|     formats. The pipeline is checked for formats mismatch at &VIDIOC-STREAMON; | ||||
|     time, and an &EPIPE; is then returned if the configuration is | ||||
|     invalid.</para> | ||||
| 
 | ||||
|     <para>Pad-level image format configuration support can be tested by calling | ||||
|     the &VIDIOC-SUBDEV-G-FMT; ioctl on pad 0. If the driver returns an &EINVAL; | ||||
|     pad-level format configuration is not supported by the sub-device.</para> | ||||
| 
 | ||||
|     <section> | ||||
|       <title>Format Negotiation</title> | ||||
| 
 | ||||
|       <para>Acceptable formats on pads can (and usually do) depend on a number | ||||
|       of external parameters, such as formats on other pads, active links, or | ||||
|       even controls. Finding a combination of formats on all pads in a video | ||||
|       pipeline, acceptable to both application and driver, can't rely on formats | ||||
|       enumeration only. A format negotiation mechanism is required.</para> | ||||
| 
 | ||||
|       <para>Central to the format negotiation mechanism are the get/set format | ||||
|       operations. When called with the <structfield>which</structfield> argument | ||||
|       set to <constant>V4L2_SUBDEV_FORMAT_TRY</constant>, the | ||||
|       &VIDIOC-SUBDEV-G-FMT; and &VIDIOC-SUBDEV-S-FMT; ioctls operate on a set of | ||||
|       formats parameters that are not connected to the hardware configuration. | ||||
|       Modifying those 'try' formats leaves the device state untouched (this | ||||
|       applies to both the software state stored in the driver and the hardware | ||||
|       state stored in the device itself).</para> | ||||
| 
 | ||||
|       <para>While not kept as part of the device state, try formats are stored | ||||
|       in the sub-device file handles. A &VIDIOC-SUBDEV-G-FMT; call will return | ||||
|       the last try format set <emphasis>on the same sub-device file | ||||
|       handle</emphasis>. Several applications querying the same sub-device at | ||||
|       the same time will thus not interact with each other.</para> | ||||
| 
 | ||||
|       <para>To find out whether a particular format is supported by the device, | ||||
|       applications use the &VIDIOC-SUBDEV-S-FMT; ioctl. Drivers verify and, if | ||||
|       needed, change the requested <structfield>format</structfield> based on | ||||
|       device requirements and return the possibly modified value. Applications | ||||
|       can then choose to try a different format or accept the returned value and | ||||
|       continue.</para> | ||||
| 
 | ||||
|       <para>Formats returned by the driver during a negotiation iteration are | ||||
|       guaranteed to be supported by the device. In particular, drivers guarantee | ||||
|       that a returned format will not be further changed if passed to an | ||||
|       &VIDIOC-SUBDEV-S-FMT; call as-is (as long as external parameters, such as | ||||
|       formats on other pads or links' configuration are not changed).</para> | ||||
| 
 | ||||
|       <para>Drivers automatically propagate formats inside sub-devices. When a | ||||
|       try or active format is set on a pad, corresponding formats on other pads | ||||
|       of the same sub-device can be modified by the driver. Drivers are free to | ||||
|       modify formats as required by the device. However, they should comply with | ||||
|       the following rules when possible: | ||||
|       <itemizedlist> | ||||
|         <listitem><para>Formats should be propagated from sink pads to source pads. | ||||
| 	Modifying a format on a source pad should not modify the format on any | ||||
| 	sink pad.</para></listitem> | ||||
|         <listitem><para>Sub-devices that scale frames using variable scaling factors | ||||
| 	should reset the scale factors to default values when sink pads formats | ||||
| 	are modified. If the 1:1 scaling ratio is supported, this means that | ||||
| 	source pads formats should be reset to the sink pads formats.</para></listitem> | ||||
|       </itemizedlist> | ||||
|       </para> | ||||
| 
 | ||||
|       <para>Formats are not propagated across links, as that would involve | ||||
|       propagating them from one sub-device file handle to another. Applications | ||||
|       must then take care to configure both ends of every link explicitly with | ||||
|       compatible formats. Identical formats on the two ends of a link are | ||||
|       guaranteed to be compatible. Drivers are free to accept different formats | ||||
|       matching device requirements as being compatible.</para> | ||||
| 
 | ||||
|       <para><xref linkend="sample-pipeline-config" /> | ||||
|       shows a sample configuration sequence for the pipeline described in | ||||
|       <xref linkend="pipeline-scaling" /> (table | ||||
|       columns list entity names and pad numbers).</para> | ||||
| 
 | ||||
|       <table pgwide="0" frame="none" id="sample-pipeline-config"> | ||||
| 	<title>Sample Pipeline Configuration</title> | ||||
| 	<tgroup cols="3"> | ||||
| 	  <colspec colname="what"/> | ||||
| 	  <colspec colname="sensor-0" /> | ||||
| 	  <colspec colname="frontend-0" /> | ||||
| 	  <colspec colname="frontend-1" /> | ||||
| 	  <colspec colname="scaler-0" /> | ||||
| 	  <colspec colname="scaler-1" /> | ||||
| 	  <thead> | ||||
| 	    <row> | ||||
| 	      <entry></entry> | ||||
| 	      <entry>Sensor/0</entry> | ||||
| 	      <entry>Frontend/0</entry> | ||||
| 	      <entry>Frontend/1</entry> | ||||
| 	      <entry>Scaler/0</entry> | ||||
| 	      <entry>Scaler/1</entry> | ||||
| 	    </row> | ||||
| 	  </thead> | ||||
| 	  <tbody valign="top"> | ||||
| 	    <row> | ||||
| 	      <entry>Initial state</entry> | ||||
| 	      <entry>2048x1536</entry> | ||||
| 	      <entry>-</entry> | ||||
| 	      <entry>-</entry> | ||||
| 	      <entry>-</entry> | ||||
| 	      <entry>-</entry> | ||||
| 	    </row> | ||||
| 	    <row> | ||||
| 	      <entry>Configure frontend input</entry> | ||||
| 	      <entry>2048x1536</entry> | ||||
| 	      <entry><emphasis>2048x1536</emphasis></entry> | ||||
| 	      <entry><emphasis>2046x1534</emphasis></entry> | ||||
| 	      <entry>-</entry> | ||||
| 	      <entry>-</entry> | ||||
| 	    </row> | ||||
| 	    <row> | ||||
| 	      <entry>Configure scaler input</entry> | ||||
| 	      <entry>2048x1536</entry> | ||||
| 	      <entry>2048x1536</entry> | ||||
| 	      <entry>2046x1534</entry> | ||||
| 	      <entry><emphasis>2046x1534</emphasis></entry> | ||||
| 	      <entry><emphasis>2046x1534</emphasis></entry> | ||||
| 	    </row> | ||||
| 	    <row> | ||||
| 	      <entry>Configure scaler output</entry> | ||||
| 	      <entry>2048x1536</entry> | ||||
| 	      <entry>2048x1536</entry> | ||||
| 	      <entry>2046x1534</entry> | ||||
| 	      <entry>2046x1534</entry> | ||||
| 	      <entry><emphasis>1280x960</emphasis></entry> | ||||
| 	    </row> | ||||
| 	  </tbody> | ||||
| 	</tgroup> | ||||
|       </table> | ||||
| 
 | ||||
|       <para> | ||||
|       <orderedlist> | ||||
| 	<listitem><para>Initial state. The sensor output is set to its native 3MP | ||||
| 	resolution. Resolutions on the host frontend and scaler input and output | ||||
| 	pads are undefined.</para></listitem> | ||||
| 	<listitem><para>The application configures the frontend input pad resolution to | ||||
| 	2048x1536. The driver propagates the format to the frontend output pad. | ||||
| 	Note that the propagated output format can be different, as in this case, | ||||
| 	than the input format, as the hardware might need to crop pixels (for | ||||
| 	instance when converting a Bayer filter pattern to RGB or YUV).</para></listitem> | ||||
| 	<listitem><para>The application configures the scaler input pad resolution to | ||||
| 	2046x1534 to match the frontend output resolution. The driver propagates | ||||
| 	the format to the scaler output pad.</para></listitem> | ||||
| 	<listitem><para>The application configures the scaler output pad resolution to | ||||
| 	1280x960.</para></listitem> | ||||
|       </orderedlist> | ||||
|       </para> | ||||
| 
 | ||||
|       <para>When satisfied with the try results, applications can set the active | ||||
|       formats by setting the <structfield>which</structfield> argument to | ||||
|       <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. Active formats are changed | ||||
|       exactly as try formats by drivers. To avoid modifying the hardware state | ||||
|       during format negotiation, applications should negotiate try formats first | ||||
|       and then modify the active settings using the try formats returned during | ||||
|       the last negotiation iteration. This guarantees that the active format | ||||
|       will be applied as-is by the driver without being modified. | ||||
|       </para> | ||||
|     </section> | ||||
| 
 | ||||
|     <section> | ||||
|       <title>Cropping and scaling</title> | ||||
| 
 | ||||
|       <para>Many sub-devices support cropping frames on their input or output | ||||
|       pads (or possible even on both). Cropping is used to select the area of | ||||
|       interest in an image, typically on a video sensor or video decoder. It can | ||||
|       also be used as part of digital zoom implementations to select the area of | ||||
|       the image that will be scaled up.</para> | ||||
| 
 | ||||
|       <para>Crop settings are defined by a crop rectangle and represented in a | ||||
|       &v4l2-rect; by the coordinates of the top left corner and the rectangle | ||||
|       size. Both the coordinates and sizes are expressed in pixels.</para> | ||||
| 
 | ||||
|       <para>The crop rectangle is retrieved and set using the | ||||
|       &VIDIOC-SUBDEV-G-CROP; and &VIDIOC-SUBDEV-S-CROP; ioctls. Like for pad | ||||
|       formats, drivers store try and active crop rectangles. The format | ||||
|       negotiation mechanism applies to crop settings as well.</para> | ||||
| 
 | ||||
|       <para>On input pads, cropping is applied relatively to the current pad | ||||
|       format. The pad format represents the image size as received by the | ||||
|       sub-device from the previous block in the pipeline, and the crop rectangle | ||||
|       represents the sub-image that will be transmitted further inside the | ||||
|       sub-device for processing. The crop rectangle be entirely containted | ||||
|       inside the input image size.</para> | ||||
| 
 | ||||
|       <para>Input crop rectangle are reset to their default value when the input | ||||
|       image format is modified. Drivers should use the input image size as the | ||||
|       crop rectangle default value, but hardware requirements may prevent this. | ||||
|       </para> | ||||
| 
 | ||||
|       <para>Cropping behaviour on output pads is not defined.</para> | ||||
| 
 | ||||
|     </section> | ||||
|   </section> | ||||
| 
 | ||||
|   &sub-subdev-formats; | ||||
| @ -45,7 +45,10 @@ just specify a <constant>NULL</constant> pointer here.</para> | ||||
| 	<listitem> | ||||
| 	  <para>Length of the memory area to map. This must be the | ||||
| same value as returned by the driver in the &v4l2-buffer; | ||||
| <structfield>length</structfield> field.</para> | ||||
| <structfield>length</structfield> field for the | ||||
| single-planar API, and the same value as returned by the driver | ||||
| in the &v4l2-plane; <structfield>length</structfield> field for the | ||||
| multi-planar API.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| @ -106,7 +109,10 @@ flag.</para> | ||||
| 	<listitem> | ||||
| 	  <para>Offset of the buffer in device memory. This must be the | ||||
| same value as returned by the driver in the &v4l2-buffer; | ||||
| <structfield>m</structfield> union <structfield>offset</structfield> field.</para> | ||||
| <structfield>m</structfield> union <structfield>offset</structfield> field for | ||||
| the single-planar API, and the same value as returned by the driver | ||||
| in the &v4l2-plane; <structfield>m</structfield> union | ||||
| <structfield>mem_offset</structfield> field for the multi-planar API.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|  | ||||
| @ -37,7 +37,8 @@ | ||||
| 	  <para>Length of the mapped buffer. This must be the same | ||||
| value as given to <function>mmap()</function> and returned by the | ||||
| driver in the &v4l2-buffer; <structfield>length</structfield> | ||||
| field.</para> | ||||
| field for the single-planar API and in the &v4l2-plane; | ||||
| <structfield>length</structfield> field for the multi-planar API.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|  | ||||
| @ -121,18 +121,22 @@ mapped.</para> | ||||
|     <para>Before applications can access the buffers they must map | ||||
| them into their address space with the &func-mmap; function. The | ||||
| location of the buffers in device memory can be determined with the | ||||
| &VIDIOC-QUERYBUF; ioctl. The <structfield>m.offset</structfield> and | ||||
| <structfield>length</structfield> returned in a &v4l2-buffer; are | ||||
| passed as sixth and second parameter to the | ||||
| <function>mmap()</function> function. The offset and length values | ||||
| must not be modified. Remember the buffers are allocated in physical | ||||
| memory, as opposed to virtual memory which can be swapped out to disk. | ||||
| Applications should free the buffers as soon as possible with the | ||||
| &func-munmap; function.</para> | ||||
| &VIDIOC-QUERYBUF; ioctl. In the single-planar API case, the | ||||
| <structfield>m.offset</structfield> and <structfield>length</structfield> | ||||
| returned in a &v4l2-buffer; are passed as sixth and second parameter to the | ||||
| <function>mmap()</function> function. When using the multi-planar API, | ||||
| struct &v4l2-buffer; contains an array of &v4l2-plane; structures, each | ||||
| containing its own <structfield>m.offset</structfield> and | ||||
| <structfield>length</structfield>. When using the multi-planar API, every | ||||
| plane of every buffer has to be mapped separately, so the number of | ||||
| calls to &func-mmap; should be equal to number of buffers times number of | ||||
| planes in each buffer. The offset and length values must not be modified. | ||||
| Remember, the buffers are allocated in physical memory, as opposed to virtual | ||||
| memory, which can be swapped out to disk. Applications should free the buffers | ||||
| as soon as possible with the &func-munmap; function.</para> | ||||
| 
 | ||||
|     <example> | ||||
|       <title>Mapping buffers</title> | ||||
| 
 | ||||
|       <title>Mapping buffers in the single-planar API</title> | ||||
|       <programlisting> | ||||
| &v4l2-requestbuffers; reqbuf; | ||||
| struct { | ||||
| @ -141,63 +145,145 @@ struct { | ||||
| } *buffers; | ||||
| unsigned int i; | ||||
| 
 | ||||
| memset (&reqbuf, 0, sizeof (reqbuf)); | ||||
| memset(&reqbuf, 0, sizeof(reqbuf)); | ||||
| reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||||
| reqbuf.memory = V4L2_MEMORY_MMAP; | ||||
| reqbuf.count = 20; | ||||
| 
 | ||||
| if (-1 == ioctl (fd, &VIDIOC-REQBUFS;, &reqbuf)) { | ||||
| 	if (errno == EINVAL) | ||||
| 		printf ("Video capturing or mmap-streaming is not supported\n"); | ||||
| 		printf("Video capturing or mmap-streaming is not supported\n"); | ||||
| 	else | ||||
| 		perror ("VIDIOC_REQBUFS"); | ||||
| 		perror("VIDIOC_REQBUFS"); | ||||
| 
 | ||||
| 	exit (EXIT_FAILURE); | ||||
| 	exit(EXIT_FAILURE); | ||||
| } | ||||
| 
 | ||||
| /* We want at least five buffers. */ | ||||
| 
 | ||||
| if (reqbuf.count < 5) { | ||||
| 	/* You may need to free the buffers here. */ | ||||
| 	printf ("Not enough buffer memory\n"); | ||||
| 	exit (EXIT_FAILURE); | ||||
| 	printf("Not enough buffer memory\n"); | ||||
| 	exit(EXIT_FAILURE); | ||||
| } | ||||
| 
 | ||||
| buffers = calloc (reqbuf.count, sizeof (*buffers)); | ||||
| assert (buffers != NULL); | ||||
| buffers = calloc(reqbuf.count, sizeof(*buffers)); | ||||
| assert(buffers != NULL); | ||||
| 
 | ||||
| for (i = 0; i < reqbuf.count; i++) { | ||||
| 	&v4l2-buffer; buffer; | ||||
| 
 | ||||
| 	memset (&buffer, 0, sizeof (buffer)); | ||||
| 	memset(&buffer, 0, sizeof(buffer)); | ||||
| 	buffer.type = reqbuf.type; | ||||
| 	buffer.memory = V4L2_MEMORY_MMAP; | ||||
| 	buffer.index = i; | ||||
| 
 | ||||
| 	if (-1 == ioctl (fd, &VIDIOC-QUERYBUF;, &buffer)) { | ||||
| 		perror ("VIDIOC_QUERYBUF"); | ||||
| 		exit (EXIT_FAILURE); | ||||
| 		perror("VIDIOC_QUERYBUF"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	buffers[i].length = buffer.length; /* remember for munmap() */ | ||||
| 
 | ||||
| 	buffers[i].start = mmap (NULL, buffer.length, | ||||
| 				 PROT_READ | PROT_WRITE, /* recommended */ | ||||
| 				 MAP_SHARED,             /* recommended */ | ||||
| 				 fd, buffer.m.offset); | ||||
| 	buffers[i].start = mmap(NULL, buffer.length, | ||||
| 				PROT_READ | PROT_WRITE, /* recommended */ | ||||
| 				MAP_SHARED,             /* recommended */ | ||||
| 				fd, buffer.m.offset); | ||||
| 
 | ||||
| 	if (MAP_FAILED == buffers[i].start) { | ||||
| 		/* If you do not exit here you should unmap() and free() | ||||
| 		   the buffers mapped so far. */ | ||||
| 		perror ("mmap"); | ||||
| 		exit (EXIT_FAILURE); | ||||
| 		perror("mmap"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Cleanup. */ | ||||
| 
 | ||||
| for (i = 0; i < reqbuf.count; i++) | ||||
| 	munmap (buffers[i].start, buffers[i].length); | ||||
| 	munmap(buffers[i].start, buffers[i].length); | ||||
|       </programlisting> | ||||
|     </example> | ||||
| 
 | ||||
|     <example> | ||||
|       <title>Mapping buffers in the multi-planar API</title> | ||||
|       <programlisting> | ||||
| &v4l2-requestbuffers; reqbuf; | ||||
| /* Our current format uses 3 planes per buffer */ | ||||
| #define FMT_NUM_PLANES = 3; | ||||
| 
 | ||||
| struct { | ||||
| 	void *start[FMT_NUM_PLANES]; | ||||
| 	size_t length[FMT_NUM_PLANES]; | ||||
| } *buffers; | ||||
| unsigned int i, j; | ||||
| 
 | ||||
| memset(&reqbuf, 0, sizeof(reqbuf)); | ||||
| reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; | ||||
| reqbuf.memory = V4L2_MEMORY_MMAP; | ||||
| reqbuf.count = 20; | ||||
| 
 | ||||
| if (ioctl(fd, &VIDIOC-REQBUFS;, &reqbuf) < 0) { | ||||
| 	if (errno == EINVAL) | ||||
| 		printf("Video capturing or mmap-streaming is not supported\n"); | ||||
| 	else | ||||
| 		perror("VIDIOC_REQBUFS"); | ||||
| 
 | ||||
| 	exit(EXIT_FAILURE); | ||||
| } | ||||
| 
 | ||||
| /* We want at least five buffers. */ | ||||
| 
 | ||||
| if (reqbuf.count < 5) { | ||||
| 	/* You may need to free the buffers here. */ | ||||
| 	printf("Not enough buffer memory\n"); | ||||
| 	exit(EXIT_FAILURE); | ||||
| } | ||||
| 
 | ||||
| buffers = calloc(reqbuf.count, sizeof(*buffers)); | ||||
| assert(buffers != NULL); | ||||
| 
 | ||||
| for (i = 0; i < reqbuf.count; i++) { | ||||
| 	&v4l2-buffer; buffer; | ||||
| 	&v4l2-plane; planes[FMT_NUM_PLANES]; | ||||
| 
 | ||||
| 	memset(&buffer, 0, sizeof(buffer)); | ||||
| 	buffer.type = reqbuf.type; | ||||
| 	buffer.memory = V4L2_MEMORY_MMAP; | ||||
| 	buffer.index = i; | ||||
| 	/* length in struct v4l2_buffer in multi-planar API stores the size | ||||
| 	 * of planes array. */ | ||||
| 	buffer.length = FMT_NUM_PLANES; | ||||
| 	buffer.m.planes = planes; | ||||
| 
 | ||||
| 	if (ioctl(fd, &VIDIOC-QUERYBUF;, &buffer) < 0) { | ||||
| 		perror("VIDIOC_QUERYBUF"); | ||||
| 		exit(EXIT_FAILURE); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Every plane has to be mapped separately */ | ||||
| 	for (j = 0; j < FMT_NUM_PLANES; j++) { | ||||
| 		buffers[i].length[j] = buffer.m.planes[j].length; /* remember for munmap() */ | ||||
| 
 | ||||
| 		buffers[i].start[j] = mmap(NULL, buffer.m.planes[j].length, | ||||
| 				 PROT_READ | PROT_WRITE, /* recommended */ | ||||
| 				 MAP_SHARED,             /* recommended */ | ||||
| 				 fd, buffer.m.planes[j].m.offset); | ||||
| 
 | ||||
| 		if (MAP_FAILED == buffers[i].start[j]) { | ||||
| 			/* If you do not exit here you should unmap() and free() | ||||
| 			   the buffers and planes mapped so far. */ | ||||
| 			perror("mmap"); | ||||
| 			exit(EXIT_FAILURE); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Cleanup. */ | ||||
| 
 | ||||
| for (i = 0; i < reqbuf.count; i++) | ||||
| 	for (j = 0; j < FMT_NUM_PLANES; j++) | ||||
| 		munmap(buffers[i].start[j], buffers[i].length[j]); | ||||
|       </programlisting> | ||||
|     </example> | ||||
| 
 | ||||
| @ -286,13 +372,13 @@ pointer method (not only memory mapping) is supported must be | ||||
| determined by calling the &VIDIOC-REQBUFS; ioctl.</para> | ||||
| 
 | ||||
|     <para>This I/O method combines advantages of the read/write and | ||||
| memory mapping methods. Buffers are allocated by the application | ||||
| memory mapping methods. Buffers (planes) are allocated by the application | ||||
| itself, and can reside for example in virtual or shared memory. Only | ||||
| pointers to data are exchanged, these pointers and meta-information | ||||
| are passed in &v4l2-buffer;. The driver must be switched | ||||
| into user pointer I/O mode by calling the &VIDIOC-REQBUFS; with the | ||||
| desired buffer type. No buffers are allocated beforehands, | ||||
| consequently they are not indexed and cannot be queried like mapped | ||||
| are passed in &v4l2-buffer; (or in &v4l2-plane; in the multi-planar API case). | ||||
| The driver must be switched into user pointer I/O mode by calling the | ||||
| &VIDIOC-REQBUFS; with the desired buffer type. No buffers (planes) are allocated | ||||
| beforehand, consequently they are not indexed and cannot be queried like mapped | ||||
| buffers with the <constant>VIDIOC_QUERYBUF</constant> ioctl.</para> | ||||
| 
 | ||||
|     <example> | ||||
| @ -316,7 +402,7 @@ if (ioctl (fd, &VIDIOC-REQBUFS;, &reqbuf) == -1) { | ||||
|       </programlisting> | ||||
|     </example> | ||||
| 
 | ||||
|     <para>Buffer addresses and sizes are passed on the fly with the | ||||
|     <para>Buffer (plane) addresses and sizes are passed on the fly with the | ||||
| &VIDIOC-QBUF; ioctl. Although buffers are commonly cycled, | ||||
| applications can pass different addresses and sizes at each | ||||
| <constant>VIDIOC_QBUF</constant> call. If required by the hardware the | ||||
| @ -396,11 +482,18 @@ rest should be evident.</para> | ||||
|     <title>Buffers</title> | ||||
| 
 | ||||
|     <para>A buffer contains data exchanged by application and | ||||
| driver using one of the Streaming I/O methods. Only pointers to | ||||
| buffers are exchanged, the data itself is not copied. These pointers, | ||||
| together with meta-information like timestamps or field parity, are | ||||
| stored in a struct <structname>v4l2_buffer</structname>, argument to | ||||
| the &VIDIOC-QUERYBUF;, &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl.</para> | ||||
| driver using one of the Streaming I/O methods. In the multi-planar API, the | ||||
| data is held in planes, while the buffer structure acts as a container | ||||
| for the planes. Only pointers to buffers (planes) are exchanged, the data | ||||
| itself is not copied. These pointers, together with meta-information like | ||||
| timestamps or field parity, are stored in a struct | ||||
| <structname>v4l2_buffer</structname>, argument to | ||||
| the &VIDIOC-QUERYBUF;, &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl. | ||||
| In the multi-planar API, some plane-specific members of struct | ||||
| <structname>v4l2_buffer</structname>, such as pointers and sizes for each | ||||
| plane, are stored in struct <structname>v4l2_plane</structname> instead. | ||||
| In that case, struct <structname>v4l2_buffer</structname> contains an array of | ||||
| plane structures.</para> | ||||
| 
 | ||||
|       <para>Nominally timestamps refer to the first data byte transmitted. | ||||
| In practice however the wide range of hardware covered by the V4L2 API | ||||
| @ -551,26 +644,40 @@ in accordance with the selected I/O method.</entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>offset</structfield></entry> | ||||
| 	    <entry>When <structfield>memory</structfield> is | ||||
| <constant>V4L2_MEMORY_MMAP</constant> this is the offset of the buffer | ||||
| from the start of the device memory. The value is returned by the | ||||
| driver and apart of serving as parameter to the &func-mmap; function | ||||
| not useful for applications. See <xref linkend="mmap" /> for details.</entry> | ||||
| 	    <entry>For the single-planar API and when | ||||
| <structfield>memory</structfield> is <constant>V4L2_MEMORY_MMAP</constant> this | ||||
| is the offset of the buffer from the start of the device memory. The value is | ||||
| returned by the driver and apart of serving as parameter to the &func-mmap; | ||||
| function not useful for applications. See <xref linkend="mmap" /> for details | ||||
| 	  </entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>unsigned long</entry> | ||||
| 	    <entry><structfield>userptr</structfield></entry> | ||||
| 	    <entry>When <structfield>memory</structfield> is | ||||
| <constant>V4L2_MEMORY_USERPTR</constant> this is a pointer to the | ||||
| buffer (casted to unsigned long type) in virtual memory, set by the | ||||
| application. See <xref linkend="userp" /> for details.</entry> | ||||
| 	    <entry>For the single-planar API and when | ||||
| <structfield>memory</structfield> is <constant>V4L2_MEMORY_USERPTR</constant> | ||||
| this is a pointer to the buffer (casted to unsigned long type) in virtual | ||||
| memory, set by the application. See <xref linkend="userp" /> for details. | ||||
| 	    </entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>struct v4l2_plane</entry> | ||||
| 	    <entry><structfield>*planes</structfield></entry> | ||||
| 	    <entry>When using the multi-planar API, contains a userspace pointer | ||||
| 	    to an array of &v4l2-plane;. The size of the array should be put | ||||
| 	    in the <structfield>length</structfield> field of this | ||||
| 	    <structname>v4l2_buffer</structname> structure.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>length</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Size of the buffer (not the payload) in bytes.</entry> | ||||
| 	    <entry>Size of the buffer (not the payload) in bytes for the | ||||
| 	    single-planar API. For the multi-planar API should contain the | ||||
| 	    number of elements in the <structfield>planes</structfield> array. | ||||
| 	    </entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| @ -596,6 +703,66 @@ should set this to 0.</entry> | ||||
|       </tgroup> | ||||
|     </table> | ||||
| 
 | ||||
|     <table frame="none" pgwide="1" id="v4l2-plane"> | ||||
|       <title>struct <structname>v4l2_plane</structname></title> | ||||
|       <tgroup cols="4"> | ||||
|         &cs-ustr; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>bytesused</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>The number of bytes occupied by data in the plane | ||||
| 	    (its payload).</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>length</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Size in bytes of the plane (not its payload).</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>union</entry> | ||||
| 	    <entry><structfield>m</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>mem_offset</structfield></entry> | ||||
| 	    <entry>When the memory type in the containing &v4l2-buffer; is | ||||
| 	      <constant>V4L2_MEMORY_MMAP</constant>, this is the value that | ||||
| 	      should be passed to &func-mmap;, similar to the | ||||
| 	      <structfield>offset</structfield> field in &v4l2-buffer;.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__unsigned long</entry> | ||||
| 	    <entry><structfield>userptr</structfield></entry> | ||||
| 	    <entry>When the memory type in the containing &v4l2-buffer; is | ||||
| 	      <constant>V4L2_MEMORY_USERPTR</constant>, this is a userspace | ||||
| 	      pointer to the memory allocated for this plane by an application. | ||||
| 	      </entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>data_offset</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Offset in bytes to video data in the plane, if applicable. | ||||
| 	    </entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>reserved[11]</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Reserved for future use. Should be zeroed by an | ||||
| 	    application.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
| 
 | ||||
|     <table frame="none" pgwide="1" id="v4l2-buf-type"> | ||||
|       <title>enum v4l2_buf_type</title> | ||||
|       <tgroup cols="3"> | ||||
| @ -604,13 +771,27 @@ should set this to 0.</entry> | ||||
| 	  <row> | ||||
| 	    <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry> | ||||
| 	    <entry>1</entry> | ||||
| 	    <entry>Buffer of a video capture stream, see <xref | ||||
| 	    <entry>Buffer of a single-planar video capture stream, see <xref | ||||
| 		linkend="capture" />.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant> | ||||
| 	    </entry> | ||||
| 	    <entry>9</entry> | ||||
| 	    <entry>Buffer of a multi-planar video capture stream, see <xref | ||||
| 		linkend="capture" />.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry> | ||||
| 	    <entry>2</entry> | ||||
| 	    <entry>Buffer of a video output stream, see <xref | ||||
| 	    <entry>Buffer of a single-planar video output stream, see <xref | ||||
| 		linkend="output" />.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant> | ||||
| 	    </entry> | ||||
| 	    <entry>10</entry> | ||||
| 	    <entry>Buffer of a multi-planar video output stream, see <xref | ||||
| 		linkend="output" />.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
|  | ||||
| @ -45,7 +45,7 @@ describing an IR signal are read from the chardev.</para> | ||||
| <para>The data written to the chardev is a pulse/space sequence of integer | ||||
| values. Pulses and spaces are only marked implicitly by their position. The | ||||
| data must start and end with a pulse, therefore, the data must always include | ||||
| an unevent number of samples. The write function must block until the data has | ||||
| an uneven number of samples. The write function must block until the data has | ||||
| been transmitted by the hardware.</para> | ||||
| </section> | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										89
									
								
								Documentation/DocBook/v4l/media-controller.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								Documentation/DocBook/v4l/media-controller.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | ||||
| <partinfo> | ||||
|   <authorgroup> | ||||
|     <author> | ||||
|       <firstname>Laurent</firstname> | ||||
|       <surname>Pinchart</surname> | ||||
|       <affiliation><address><email>laurent.pinchart@ideasonboard.com</email></address></affiliation> | ||||
|       <contrib>Initial version.</contrib> | ||||
|     </author> | ||||
|   </authorgroup> | ||||
|   <copyright> | ||||
|     <year>2010</year> | ||||
|     <holder>Laurent Pinchart</holder> | ||||
|   </copyright> | ||||
| 
 | ||||
|   <revhistory> | ||||
|     <!-- Put document revisions here, newest first. --> | ||||
|     <revision> | ||||
|       <revnumber>1.0.0</revnumber> | ||||
|       <date>2010-11-10</date> | ||||
|       <authorinitials>lp</authorinitials> | ||||
|       <revremark>Initial revision</revremark> | ||||
|     </revision> | ||||
|   </revhistory> | ||||
| </partinfo> | ||||
| 
 | ||||
| <title>Media Controller API</title> | ||||
| 
 | ||||
| <chapter id="media_controller"> | ||||
|   <title>Media Controller</title> | ||||
| 
 | ||||
|   <section id="media-controller-intro"> | ||||
|     <title>Introduction</title> | ||||
|     <para>Media devices increasingly handle multiple related functions. Many USB | ||||
|     cameras include microphones, video capture hardware can also output video, | ||||
|     or SoC camera interfaces also perform memory-to-memory operations similar to | ||||
|     video codecs.</para> | ||||
|     <para>Independent functions, even when implemented in the same hardware, can | ||||
|     be modelled as separate devices. A USB camera with a microphone will be | ||||
|     presented to userspace applications as V4L2 and ALSA capture devices. The | ||||
|     devices' relationships (when using a webcam, end-users shouldn't have to | ||||
|     manually select the associated USB microphone), while not made available | ||||
|     directly to applications by the drivers, can usually be retrieved from | ||||
|     sysfs.</para> | ||||
|     <para>With more and more advanced SoC devices being introduced, the current | ||||
|     approach will not scale. Device topologies are getting increasingly complex | ||||
|     and can't always be represented by a tree structure. Hardware blocks are | ||||
|     shared between different functions, creating dependencies between seemingly | ||||
|     unrelated devices.</para> | ||||
|     <para>Kernel abstraction APIs such as V4L2 and ALSA provide means for | ||||
|     applications to access hardware parameters. As newer hardware expose an | ||||
|     increasingly high number of those parameters, drivers need to guess what | ||||
|     applications really require based on limited information, thereby | ||||
|     implementing policies that belong to userspace.</para> | ||||
|     <para>The media controller API aims at solving those problems.</para> | ||||
|   </section> | ||||
| 
 | ||||
|   <section id="media-controller-model"> | ||||
|     <title>Media device model</title> | ||||
|     <para>Discovering a device internal topology, and configuring it at runtime, | ||||
|     is one of the goals of the media controller API. To achieve this, hardware | ||||
|     devices are modelled as an oriented graph of building blocks called entities | ||||
|     connected through pads.</para> | ||||
|     <para>An entity is a basic media hardware or software building block. It can | ||||
|     correspond to a large variety of logical blocks such as physical hardware | ||||
|     devices (CMOS sensor for instance), logical hardware devices (a building | ||||
|     block in a System-on-Chip image processing pipeline), DMA channels or | ||||
|     physical connectors.</para> | ||||
|     <para>A pad is a connection endpoint through which an entity can interact | ||||
|     with other entities. Data (not restricted to video) produced by an entity | ||||
|     flows from the entity's output to one or more entity inputs. Pads should not | ||||
|     be confused with physical pins at chip boundaries.</para> | ||||
|     <para>A link is a point-to-point oriented connection between two pads, | ||||
|     either on the same entity or on different entities. Data flows from a source | ||||
|     pad to a sink pad.</para> | ||||
|   </section> | ||||
| </chapter> | ||||
| 
 | ||||
| <appendix id="media-user-func"> | ||||
|   <title>Function Reference</title> | ||||
|   <!-- Keep this alphabetically sorted. --> | ||||
|   &sub-media-open; | ||||
|   &sub-media-close; | ||||
|   &sub-media-ioctl; | ||||
|   <!-- All ioctls go here. --> | ||||
|   &sub-media-ioc-device-info; | ||||
|   &sub-media-ioc-enum-entities; | ||||
|   &sub-media-ioc-enum-links; | ||||
|   &sub-media-ioc-setup-link; | ||||
| </appendix> | ||||
							
								
								
									
										59
									
								
								Documentation/DocBook/v4l/media-func-close.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								Documentation/DocBook/v4l/media-func-close.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| <refentry id="media-func-close"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>media close()</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>media-close</refname> | ||||
|     <refpurpose>Close a media device</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcsynopsisinfo>#include <unistd.h></funcsynopsisinfo> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>close</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>&fd;</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
| 
 | ||||
|     <para>Closes the media device. Resources associated with the file descriptor | ||||
|     are freed. The device configuration remain unchanged.</para> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Return Value</title> | ||||
| 
 | ||||
|     <para><function>close</function> returns 0 on success. On error, -1 is | ||||
|     returned, and <varname>errno</varname> is set appropriately. Possible error | ||||
|     codes are:</para> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EBADF</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para><parameter>fd</parameter> is not a valid open file descriptor. | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										116
									
								
								Documentation/DocBook/v4l/media-func-ioctl.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								Documentation/DocBook/v4l/media-func-ioctl.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,116 @@ | ||||
| <refentry id="media-func-ioctl"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>media ioctl()</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>media-ioctl</refname> | ||||
|     <refpurpose>Control a media device</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcsynopsisinfo>#include <sys/ioctl.h></funcsynopsisinfo> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>void *<parameter>argp</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>&fd;</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>Media ioctl request code as defined in the media.h header file, | ||||
| 	  for example MEDIA_IOC_SETUP_LINK.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>Pointer to a request-specific structure.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
|     <para>The <function>ioctl()</function> function manipulates media device | ||||
|     parameters. The argument <parameter>fd</parameter> must be an open file | ||||
|     descriptor.</para> | ||||
|     <para>The ioctl <parameter>request</parameter> code specifies the media | ||||
|     function to be called. It has encoded in it whether the argument is an | ||||
|     input, output or read/write parameter, and the size of the argument | ||||
|     <parameter>argp</parameter> in bytes.</para> | ||||
|     <para>Macros and structures definitions specifying media ioctl requests and | ||||
|     their parameters are located in the media.h header file. All media ioctl | ||||
|     requests, their respective function and parameters are specified in | ||||
|     <xref linkend="media-user-func" />.</para> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Return Value</title> | ||||
| 
 | ||||
|     <para><function>ioctl()</function> returns <returnvalue>0</returnvalue> on | ||||
|     success. On failure, <returnvalue>-1</returnvalue> is returned, and the | ||||
|     <varname>errno</varname> variable is set appropriately. Generic error codes | ||||
|     are listed below, and request-specific error codes are listed in the | ||||
|     individual requests descriptions.</para> | ||||
|     <para>When an ioctl that takes an output or read/write parameter fails, | ||||
|     the parameter remains unmodified.</para> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EBADF</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para><parameter>fd</parameter> is not a valid open file descriptor. | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EFAULT</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para><parameter>argp</parameter> references an inaccessible memory | ||||
| 	  area.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EINVAL</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The <parameter>request</parameter> or the data pointed to by | ||||
| 	  <parameter>argp</parameter> is not valid. This is a very common error | ||||
| 	  code, see the individual ioctl requests listed in | ||||
| 	  <xref linkend="media-user-func" /> for actual causes.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>ENOMEM</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>Insufficient kernel memory was available to complete the | ||||
| 	  request.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>ENOTTY</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para><parameter>fd</parameter> is  not  associated  with  a character | ||||
| 	  special device.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										94
									
								
								Documentation/DocBook/v4l/media-func-open.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								Documentation/DocBook/v4l/media-func-open.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,94 @@ | ||||
| <refentry id="media-func-open"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>media open()</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>media-open</refname> | ||||
|     <refpurpose>Open a media device</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcsynopsisinfo>#include <fcntl.h></funcsynopsisinfo> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>open</function></funcdef> | ||||
| 	<paramdef>const char *<parameter>device_name</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>flags</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>device_name</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>Device to be opened.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>flags</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>Open flags. Access mode must be either <constant>O_RDONLY</constant> | ||||
| 	  or <constant>O_RDWR</constant>. Other flags have no effect.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
|     <para>To open a media device applications call <function>open()</function> | ||||
|     with the desired device name. The function has no side effects; the device | ||||
|     configuration remain unchanged.</para> | ||||
|     <para>When the device is opened in read-only mode, attemps to modify its | ||||
|     configuration will result in an error, and <varname>errno</varname> will be | ||||
|     set to <errorcode>EBADF</errorcode>.</para> | ||||
|   </refsect1> | ||||
|   <refsect1> | ||||
|     <title>Return Value</title> | ||||
| 
 | ||||
|     <para><function>open</function> returns the new file descriptor on success. | ||||
|     On error, -1 is returned, and <varname>errno</varname> is set appropriately. | ||||
|     Possible error codes are:</para> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EACCES</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The requested access to the file is not allowed.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EMFILE</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The  process  already  has  the  maximum number of files open. | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>ENFILE</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The system limit on the total number of open files has been | ||||
| 	  reached.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>ENOMEM</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>Insufficient kernel memory was available.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>ENXIO</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>No device corresponding to this device special file exists. | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										133
									
								
								Documentation/DocBook/v4l/media-ioc-device-info.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								Documentation/DocBook/v4l/media-ioc-device-info.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,133 @@ | ||||
| <refentry id="media-ioc-device-info"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>ioctl MEDIA_IOC_DEVICE_INFO</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>MEDIA_IOC_DEVICE_INFO</refname> | ||||
|     <refpurpose>Query device information</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>struct media_device_info *<parameter>argp</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>File descriptor returned by | ||||
| 	  <link linkend='media-func-open'><function>open()</function></link>.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>MEDIA_IOC_DEVICE_INFO</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
| 
 | ||||
|     <para>All media devices must support the <constant>MEDIA_IOC_DEVICE_INFO</constant> | ||||
|     ioctl. To query device information, applications call the ioctl with a | ||||
|     pointer to a &media-device-info;. The driver fills the structure and returns | ||||
|     the information to the application. | ||||
|     The ioctl never fails.</para> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="media-device-info"> | ||||
|       <title>struct <structname>media_device_info</structname></title> | ||||
|       <tgroup cols="3"> | ||||
| 	&cs-str; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>char</entry> | ||||
| 	    <entry><structfield>driver</structfield>[16]</entry> | ||||
| 	    <entry><para>Name of the driver implementing the media API as a | ||||
| 	    NUL-terminated ASCII string. The driver version is stored in the | ||||
| 	    <structfield>driver_version</structfield> field.</para> | ||||
| 	    <para>Driver specific applications can use this information to | ||||
| 	    verify the driver identity. It is also useful to work around | ||||
| 	    known bugs, or to identify drivers in error reports.</para></entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>char</entry> | ||||
| 	    <entry><structfield>model</structfield>[32]</entry> | ||||
| 	    <entry>Device model name as a NUL-terminated UTF-8 string. The | ||||
| 	    device version is stored in the <structfield>device_version</structfield> | ||||
| 	    field and is not be appended to the model name.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>char</entry> | ||||
| 	    <entry><structfield>serial</structfield>[40]</entry> | ||||
| 	    <entry>Serial number as a NUL-terminated ASCII string.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>char</entry> | ||||
| 	    <entry><structfield>bus_info</structfield>[32]</entry> | ||||
| 	    <entry>Location of the device in the system as a NUL-terminated | ||||
| 	    ASCII string. This includes the bus type name (PCI, USB, ...) and a | ||||
| 	    bus-specific identifier.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>media_version</structfield></entry> | ||||
| 	    <entry>Media API version, formatted with the | ||||
| 	    <constant>KERNEL_VERSION()</constant> macro.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>hw_revision</structfield></entry> | ||||
| 	    <entry>Hardware device revision in a driver-specific format.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>media_version</structfield></entry> | ||||
| 	    <entry>Media device driver version, formatted with the | ||||
| 	    <constant>KERNEL_VERSION()</constant> macro. Together with the | ||||
| 	    <structfield>driver</structfield> field this identifies a particular | ||||
| 	    driver.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>reserved</structfield>[31]</entry> | ||||
| 	    <entry>Reserved for future extensions. Drivers and applications must | ||||
| 	    set this array to zero.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
|     <para>The <structfield>serial</structfield> and <structfield>bus_info</structfield> | ||||
|     fields can be used to distinguish between multiple instances of otherwise | ||||
|     identical hardware. The serial number takes precedence when provided and can | ||||
|     be assumed to be unique. If the serial number is an empty string, the | ||||
|     <structfield>bus_info</structfield> field can be used instead. The | ||||
|     <structfield>bus_info</structfield> field is guaranteed to be unique, but | ||||
|     can vary across reboots or device unplug/replug.</para> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Return value</title> | ||||
|     <para>This function doesn't return specific error codes.</para> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										308
									
								
								Documentation/DocBook/v4l/media-ioc-enum-entities.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								Documentation/DocBook/v4l/media-ioc-enum-entities.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,308 @@ | ||||
| <refentry id="media-ioc-enum-entities"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>ioctl MEDIA_IOC_ENUM_ENTITIES</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>MEDIA_IOC_ENUM_ENTITIES</refname> | ||||
|     <refpurpose>Enumerate entities and their properties</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>struct media_entity_desc *<parameter>argp</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>File descriptor returned by | ||||
| 	  <link linkend='media-func-open'><function>open()</function></link>.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>MEDIA_IOC_ENUM_ENTITIES</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
|     <para>To query the attributes of an entity, applications set the id field | ||||
|     of a &media-entity-desc; structure and call the MEDIA_IOC_ENUM_ENTITIES | ||||
|     ioctl with a pointer to this structure. The driver fills the rest of the | ||||
|     structure or returns an &EINVAL; when the id is invalid.</para> | ||||
|     <para>Entities can be enumerated by or'ing the id with the | ||||
|     <constant>MEDIA_ENT_ID_FLAG_NEXT</constant> flag. The driver will return | ||||
|     information about the entity with the smallest id strictly larger than the | ||||
|     requested one ('next entity'), or the &EINVAL; if there is none.</para> | ||||
|     <para>Entity IDs can be non-contiguous. Applications must | ||||
|     <emphasis>not</emphasis> try to enumerate entities by calling | ||||
|     MEDIA_IOC_ENUM_ENTITIES with increasing id's until they get an error.</para> | ||||
|     <para>Two or more entities that share a common non-zero | ||||
|     <structfield>group_id</structfield> value are considered as logically | ||||
|     grouped. Groups are used to report | ||||
|     <itemizedlist> | ||||
|       <listitem><para>ALSA, VBI and video nodes that carry the same media | ||||
|       stream</para></listitem> | ||||
|       <listitem><para>lens and flash controllers associated with a sensor</para></listitem> | ||||
|     </itemizedlist> | ||||
|     </para> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="media-entity-desc"> | ||||
|       <title>struct <structname>media_entity_desc</structname></title> | ||||
|       <tgroup cols="5"> | ||||
| 	<colspec colname="c1" /> | ||||
| 	<colspec colname="c2" /> | ||||
| 	<colspec colname="c3" /> | ||||
| 	<colspec colname="c4" /> | ||||
| 	<colspec colname="c5" /> | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>id</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Entity id, set by the application. When the id is or'ed with | ||||
| 	    <constant>MEDIA_ENT_ID_FLAG_NEXT</constant>, the driver clears the | ||||
| 	    flag and returns the first entity with a larger id.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>char</entry> | ||||
| 	    <entry><structfield>name</structfield>[32]</entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Entity name as an UTF-8 NULL-terminated string.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>type</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Entity type, see <xref linkend="media-entity-type" /> for details.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>revision</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Entity revision in a driver/hardware specific format.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>flags</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Entity flags, see <xref linkend="media-entity-flag" /> for details.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>group_id</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Entity group ID</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u16</entry> | ||||
| 	    <entry><structfield>pads</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Number of pads</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u16</entry> | ||||
| 	    <entry><structfield>links</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Total number of outbound links. Inbound links are not counted | ||||
| 	    in this field.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>union</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>struct</entry> | ||||
| 	    <entry><structfield>v4l</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Valid for V4L sub-devices and nodes only.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>major</structfield></entry> | ||||
| 	    <entry>V4L device node major number. For V4L sub-devices with no | ||||
| 	    device node, set by the driver to 0.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>minor</structfield></entry> | ||||
| 	    <entry>V4L device node minor number. For V4L sub-devices with no | ||||
| 	    device node, set by the driver to 0.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>struct</entry> | ||||
| 	    <entry><structfield>fb</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Valid for frame buffer nodes only.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>major</structfield></entry> | ||||
| 	    <entry>Frame buffer device node major number.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>minor</structfield></entry> | ||||
| 	    <entry>Frame buffer device node minor number.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>struct</entry> | ||||
| 	    <entry><structfield>alsa</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>Valid for ALSA devices only.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>card</structfield></entry> | ||||
| 	    <entry>ALSA card number</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>device</structfield></entry> | ||||
| 	    <entry>ALSA device number</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>subdevice</structfield></entry> | ||||
| 	    <entry>ALSA sub-device number</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>int</entry> | ||||
| 	    <entry><structfield>dvb</structfield></entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>DVB card number</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>__u8</entry> | ||||
| 	    <entry><structfield>raw</structfield>[180]</entry> | ||||
| 	    <entry></entry> | ||||
| 	    <entry></entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
| 
 | ||||
|     <table frame="none" pgwide="1" id="media-entity-type"> | ||||
|       <title>Media entity types</title> | ||||
|       <tgroup cols="2"> | ||||
|         <colspec colname="c1"/> | ||||
|         <colspec colname="c2"/> | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_ENT_T_DEVNODE</constant></entry> | ||||
| 	    <entry>Unknown device node</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry> | ||||
| 	    <entry>V4L video, radio or vbi device node</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_ENT_T_DEVNODE_FB</constant></entry> | ||||
| 	    <entry>Frame buffer device node</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_ENT_T_DEVNODE_ALSA</constant></entry> | ||||
| 	    <entry>ALSA card</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_ENT_T_DEVNODE_DVB</constant></entry> | ||||
| 	    <entry>DVB card</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry> | ||||
| 	    <entry>Unknown V4L sub-device</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_SENSOR</constant></entry> | ||||
| 	    <entry>Video sensor</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_FLASH</constant></entry> | ||||
| 	    <entry>Flash controller</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry> | ||||
| 	    <entry>Lens controller</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
| 
 | ||||
|     <table frame="none" pgwide="1" id="media-entity-flag"> | ||||
|       <title>Media entity flags</title> | ||||
|       <tgroup cols="2"> | ||||
|         <colspec colname="c1"/> | ||||
|         <colspec colname="c2"/> | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_ENT_FL_DEFAULT</constant></entry> | ||||
| 	    <entry>Default entity for its type. Used to discover the default | ||||
| 	    audio, VBI and video devices, the default camera sensor, ...</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     &return-value; | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EINVAL</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The &media-entity-desc; <structfield>id</structfield> references | ||||
| 	  a non-existing entity.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										207
									
								
								Documentation/DocBook/v4l/media-ioc-enum-links.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								Documentation/DocBook/v4l/media-ioc-enum-links.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,207 @@ | ||||
| <refentry id="media-ioc-enum-links"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>ioctl MEDIA_IOC_ENUM_LINKS</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>MEDIA_IOC_ENUM_LINKS</refname> | ||||
|     <refpurpose>Enumerate all pads and links for a given entity</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>struct media_links_enum *<parameter>argp</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>File descriptor returned by | ||||
| 	  <link linkend='media-func-open'><function>open()</function></link>.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>MEDIA_IOC_ENUM_LINKS</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
| 
 | ||||
|     <para>To enumerate pads and/or links for a given entity, applications set | ||||
|     the entity field of a &media-links-enum; structure and initialize the | ||||
|     &media-pad-desc; and &media-link-desc; structure arrays pointed by the | ||||
|     <structfield>pads</structfield> and <structfield>links</structfield> fields. | ||||
|     They then call the MEDIA_IOC_ENUM_LINKS ioctl with a pointer to this | ||||
|     structure.</para> | ||||
|     <para>If the <structfield>pads</structfield> field is not NULL, the driver | ||||
|     fills the <structfield>pads</structfield> array with information about the | ||||
|     entity's pads. The array must have enough room to store all the entity's | ||||
|     pads. The number of pads can be retrieved with the &MEDIA-IOC-ENUM-ENTITIES; | ||||
|     ioctl.</para> | ||||
|     <para>If the <structfield>links</structfield> field is not NULL, the driver | ||||
|     fills the <structfield>links</structfield> array with information about the | ||||
|     entity's outbound links. The array must have enough room to store all the | ||||
|     entity's outbound links. The number of outbound links can be retrieved with | ||||
|     the &MEDIA-IOC-ENUM-ENTITIES; ioctl.</para> | ||||
|     <para>Only forward links that originate at one of the entity's source pads | ||||
|     are returned during the enumeration process.</para> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="media-links-enum"> | ||||
|       <title>struct <structname>media_links_enum</structname></title> | ||||
|       <tgroup cols="3"> | ||||
|         &cs-str; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>entity</structfield></entry> | ||||
| 	    <entry>Entity id, set by the application.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>struct &media-pad-desc;</entry> | ||||
| 	    <entry>*<structfield>pads</structfield></entry> | ||||
| 	    <entry>Pointer to a pads array allocated by the application. Ignored | ||||
| 	    if NULL.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>struct &media-link-desc;</entry> | ||||
| 	    <entry>*<structfield>links</structfield></entry> | ||||
| 	    <entry>Pointer to a links array allocated by the application. Ignored | ||||
| 	    if NULL.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="media-pad-desc"> | ||||
|       <title>struct <structname>media_pad_desc</structname></title> | ||||
|       <tgroup cols="3"> | ||||
|         &cs-str; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>entity</structfield></entry> | ||||
| 	    <entry>ID of the entity this pad belongs to.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u16</entry> | ||||
| 	    <entry><structfield>index</structfield></entry> | ||||
| 	    <entry>0-based pad index.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>flags</structfield></entry> | ||||
| 	    <entry>Pad flags, see <xref linkend="media-pad-flag" /> for more details.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
| 
 | ||||
|     <table frame="none" pgwide="1" id="media-pad-flag"> | ||||
|       <title>Media pad flags</title> | ||||
|       <tgroup cols="2"> | ||||
|         <colspec colname="c1"/> | ||||
|         <colspec colname="c2"/> | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_PAD_FL_SINK</constant></entry> | ||||
| 	    <entry>Input pad, relative to the entity. Input pads sink data and | ||||
| 	    are targets of links.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_PAD_FL_SOURCE</constant></entry> | ||||
| 	    <entry>Output pad, relative to the entity. Output pads source data | ||||
| 	    and are origins of links.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="media-link-desc"> | ||||
|       <title>struct <structname>media_links_desc</structname></title> | ||||
|       <tgroup cols="3"> | ||||
|         &cs-str; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>struct &media-pad-desc;</entry> | ||||
| 	    <entry><structfield>source</structfield></entry> | ||||
| 	    <entry>Pad at the origin of this link.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>struct &media-pad-desc;</entry> | ||||
| 	    <entry><structfield>sink</structfield></entry> | ||||
| 	    <entry>Pad at the target of this link.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>flags</structfield></entry> | ||||
| 	    <entry>Link flags, see <xref linkend="media-link-flag" /> for more details.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
| 
 | ||||
|     <table frame="none" pgwide="1" id="media-link-flag"> | ||||
|       <title>Media link flags</title> | ||||
|       <tgroup cols="2"> | ||||
|         <colspec colname="c1"/> | ||||
|         <colspec colname="c2"/> | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_LNK_FL_ENABLED</constant></entry> | ||||
| 	    <entry>The link is enabled and can be used to transfer media data. | ||||
| 	    When two or more links target a sink pad, only one of them can be | ||||
| 	    enabled at a time.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_LNK_FL_IMMUTABLE</constant></entry> | ||||
| 	    <entry>The link enabled state can't be modified at runtime. An | ||||
| 	    immutable link is always enabled.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>MEDIA_LNK_FL_DYNAMIC</constant></entry> | ||||
| 	    <entry>The link enabled state can be modified during streaming. This | ||||
| 	    flag is set by drivers and is read-only for applications.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
|     <para>One and only one of <constant>MEDIA_PAD_FL_SINK</constant> and | ||||
|     <constant>MEDIA_PAD_FL_SOURCE</constant> must be set for every pad.</para> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     &return-value; | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EINVAL</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The &media-links-enum; <structfield>id</structfield> references | ||||
| 	  a non-existing entity.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										93
									
								
								Documentation/DocBook/v4l/media-ioc-setup-link.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								Documentation/DocBook/v4l/media-ioc-setup-link.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,93 @@ | ||||
| <refentry id="media-ioc-setup-link"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>ioctl MEDIA_IOC_SETUP_LINK</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>MEDIA_IOC_SETUP_LINK</refname> | ||||
|     <refpurpose>Modify the properties of a link</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>struct media_link_desc *<parameter>argp</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>File descriptor returned by | ||||
| 	  <link linkend='media-func-open'><function>open()</function></link>.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>MEDIA_IOC_ENUM_LINKS</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
| 
 | ||||
|     <para>To change link properties applications fill a &media-link-desc; with | ||||
|     link identification information (source and sink pad) and the new requested | ||||
|     link flags. They then call the MEDIA_IOC_SETUP_LINK ioctl with a pointer to | ||||
|     that structure.</para> | ||||
|     <para>The only configurable property is the <constant>ENABLED</constant> | ||||
|     link flag to enable/disable a link. Links marked with the | ||||
|     <constant>IMMUTABLE</constant> link flag can not be enabled or disabled. | ||||
|     </para> | ||||
|     <para>Link configuration has no side effect on other links. If an enabled | ||||
|     link at the sink pad prevents the link from being enabled, the driver | ||||
|     returns with an &EBUSY;.</para> | ||||
|     <para>Only links marked with the <constant>DYNAMIC</constant> link flag can | ||||
|     be enabled/disabled while streaming media data. Attempting to enable or | ||||
|     disable a streaming non-dynamic link will return an &EBUSY;.</para> | ||||
|     <para>If the specified link can't be found the driver returns with an | ||||
|     &EINVAL;.</para> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     &return-value; | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EBUSY</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The link properties can't be changed because the link is | ||||
| 	  currently busy. This can be caused, for instance, by an active media | ||||
| 	  stream (audio or video) on the link. The ioctl shouldn't be retried if | ||||
| 	  no other action is performed before to fix the problem.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EINVAL</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The &media-link-desc; references a non-existing link, or the | ||||
| 	  link is immutable and an attempt to modify its configuration was made. | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/nv12mt.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/nv12mt.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.1 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/nv12mt_example.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/nv12mt_example.gif
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 6.7 KiB | 
							
								
								
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/pipeline.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/pipeline.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/pipeline.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Documentation/DocBook/v4l/pipeline.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 12 KiB | 
							
								
								
									
										154
									
								
								Documentation/DocBook/v4l/pixfmt-nv12m.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								Documentation/DocBook/v4l/pixfmt-nv12m.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,154 @@ | ||||
|     <refentry id="V4L2-PIX-FMT-NV12M"> | ||||
|       <refmeta> | ||||
| 	<refentrytitle>V4L2_PIX_FMT_NV12M ('NV12M')</refentrytitle> | ||||
| 	&manvol; | ||||
|       </refmeta> | ||||
|       <refnamediv> | ||||
| 	<refname> <constant>V4L2_PIX_FMT_NV12M</constant></refname> | ||||
| 	<refpurpose>Variation of <constant>V4L2_PIX_FMT_NV12</constant> with planes | ||||
| 	  non contiguous in memory. </refpurpose> | ||||
|       </refnamediv> | ||||
|       <refsect1> | ||||
| 	<title>Description</title> | ||||
| 
 | ||||
| 	<para>This is a multi-planar, two-plane version of the YUV 4:2:0 format. | ||||
| The three components are separated into two sub-images or planes. | ||||
| <constant>V4L2_PIX_FMT_NV12M</constant> differs from <constant>V4L2_PIX_FMT_NV12 | ||||
| </constant> in that the two planes are non-contiguous in memory, i.e. the chroma | ||||
| plane do not necessarily immediately follows the luma plane. | ||||
| The luminance data occupies the first plane. The Y plane has one byte per pixel. | ||||
| In the second plane there is a chrominance data with alternating chroma samples. | ||||
| The CbCr plane is the same width, in bytes, as the Y plane (and of the image), | ||||
| but is half as tall in pixels. Each CbCr pair belongs to four pixels. For example, | ||||
| Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to | ||||
| Y'<subscript>00</subscript>, Y'<subscript>01</subscript>, | ||||
| Y'<subscript>10</subscript>, Y'<subscript>11</subscript>. </para> | ||||
| 
 | ||||
| 	<para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be | ||||
| used only in drivers and applications that support the multi-planar API, | ||||
| described in <xref linkend="planar-apis"/>. </para> | ||||
| 
 | ||||
| 	<para>If the Y plane has pad bytes after each row, then the | ||||
| CbCr plane has as many pad bytes after its rows.</para> | ||||
| 
 | ||||
| 	<example> | ||||
| 	  <title><constant>V4L2_PIX_FMT_NV12M</constant> 4 × 4 pixel image</title> | ||||
| 
 | ||||
| 	  <formalpara> | ||||
| 	    <title>Byte Order.</title> | ||||
| 	    <para>Each cell is one byte. | ||||
| 		<informaltable frame="none"> | ||||
| 		<tgroup cols="5" align="center"> | ||||
| 		  <colspec align="left" colwidth="2*" /> | ||||
| 		  <tbody valign="top"> | ||||
| 		    <row> | ||||
| 		      <entry>start0 + 0:</entry> | ||||
| 		      <entry>Y'<subscript>00</subscript></entry> | ||||
| 		      <entry>Y'<subscript>01</subscript></entry> | ||||
| 		      <entry>Y'<subscript>02</subscript></entry> | ||||
| 		      <entry>Y'<subscript>03</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>start0 + 4:</entry> | ||||
| 		      <entry>Y'<subscript>10</subscript></entry> | ||||
| 		      <entry>Y'<subscript>11</subscript></entry> | ||||
| 		      <entry>Y'<subscript>12</subscript></entry> | ||||
| 		      <entry>Y'<subscript>13</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>start0 + 8:</entry> | ||||
| 		      <entry>Y'<subscript>20</subscript></entry> | ||||
| 		      <entry>Y'<subscript>21</subscript></entry> | ||||
| 		      <entry>Y'<subscript>22</subscript></entry> | ||||
| 		      <entry>Y'<subscript>23</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>start0 + 12:</entry> | ||||
| 		      <entry>Y'<subscript>30</subscript></entry> | ||||
| 		      <entry>Y'<subscript>31</subscript></entry> | ||||
| 		      <entry>Y'<subscript>32</subscript></entry> | ||||
| 		      <entry>Y'<subscript>33</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>start1 + 0:</entry> | ||||
| 		      <entry>Cb<subscript>00</subscript></entry> | ||||
| 		      <entry>Cr<subscript>00</subscript></entry> | ||||
| 		      <entry>Cb<subscript>01</subscript></entry> | ||||
| 		      <entry>Cr<subscript>01</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>start1 + 4:</entry> | ||||
| 		      <entry>Cb<subscript>10</subscript></entry> | ||||
| 		      <entry>Cr<subscript>10</subscript></entry> | ||||
| 		      <entry>Cb<subscript>11</subscript></entry> | ||||
| 		      <entry>Cr<subscript>11</subscript></entry> | ||||
| 		    </row> | ||||
| 		  </tbody> | ||||
| 		</tgroup> | ||||
| 		</informaltable> | ||||
| 	      </para> | ||||
| 	  </formalpara> | ||||
| 
 | ||||
| 	  <formalpara> | ||||
| 	    <title>Color Sample Location.</title> | ||||
| 	    <para> | ||||
| 		<informaltable frame="none"> | ||||
| 		<tgroup cols="7" align="center"> | ||||
| 		  <tbody valign="top"> | ||||
| 		    <row> | ||||
| 		      <entry></entry> | ||||
| 		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry> | ||||
| 		      <entry>2</entry><entry></entry><entry>3</entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>0</entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry></entry> | ||||
| 		      <entry></entry><entry>C</entry><entry></entry><entry></entry> | ||||
| 		      <entry></entry><entry>C</entry><entry></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>1</entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>2</entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry></entry> | ||||
| 		      <entry></entry><entry>C</entry><entry></entry><entry></entry> | ||||
| 		      <entry></entry><entry>C</entry><entry></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>3</entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry> | ||||
| 		    </row> | ||||
| 		  </tbody> | ||||
| 		</tgroup> | ||||
| 		</informaltable> | ||||
| 	      </para> | ||||
| 	  </formalpara> | ||||
| 	</example> | ||||
|       </refsect1> | ||||
|     </refentry> | ||||
| 
 | ||||
|   <!-- | ||||
| Local Variables: | ||||
| mode: sgml | ||||
| sgml-parent-document: "pixfmt.sgml" | ||||
| indent-tabs-mode: nil | ||||
| End: | ||||
|   --> | ||||
							
								
								
									
										74
									
								
								Documentation/DocBook/v4l/pixfmt-nv12mt.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								Documentation/DocBook/v4l/pixfmt-nv12mt.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | ||||
|     <refentry> | ||||
|       <refmeta> | ||||
| 	<refentrytitle>V4L2_PIX_FMT_NV12MT ('TM12')</refentrytitle> | ||||
| 	&manvol; | ||||
|       </refmeta> | ||||
|       <refnamediv> | ||||
| 	<refname id="V4L2-PIX-FMT-NV12MT"><constant>V4L2_PIX_FMT_NV12MT | ||||
| </constant></refname> | ||||
| 	<refpurpose>Formats with ½ horizontal and vertical | ||||
| chroma resolution. This format has two planes - one for luminance and one for | ||||
| chrominance. Chroma samples are interleaved. The difference to | ||||
| <constant>V4L2_PIX_FMT_NV12</constant> is the memory layout. Pixels are | ||||
| grouped in macroblocks of 64x32 size. The order of macroblocks in memory is | ||||
| also not standard. | ||||
| 	</refpurpose> | ||||
|       </refnamediv> | ||||
|       <refsect1> | ||||
| 	<title>Description</title> | ||||
| 
 | ||||
| 	<para>This is the two-plane versions of the YUV 4:2:0 format where data | ||||
| is grouped into 64x32 macroblocks. The three components are separated into two | ||||
| sub-images or planes. The Y plane has one byte per pixel and pixels are grouped | ||||
| into 64x32 macroblocks. The CbCr plane has the same width, in bytes, as the Y | ||||
| plane (and the image), but is half as tall in pixels. The chroma plane is also | ||||
| grouped into 64x32 macroblocks.</para> | ||||
| 	<para>Width of the buffer has to be aligned to the multiple of 128, and | ||||
| height alignment is 32. Every four adjactent buffers - two horizontally and two | ||||
| vertically are grouped together and are located in memory in Z or flipped Z | ||||
| order. </para> | ||||
| 	<para>Layout of macroblocks in memory is presented in the following | ||||
| figure.</para> | ||||
| 	<para><figure id="nv12mt"> | ||||
| 	    <title><constant>V4L2_PIX_FMT_NV12MT</constant> macroblock Z shape | ||||
| memory layout</title> | ||||
| 	    <mediaobject> | ||||
| 	      <imageobject> | ||||
| 		<imagedata fileref="nv12mt.gif" format="GIF" /> | ||||
| 	      </imageobject> | ||||
| 	    </mediaobject> | ||||
| 	</figure> | ||||
| 	The requirement that width is multiple of 128 is implemented because, | ||||
| the Z shape cannot be cut in half horizontally. In case the vertical resolution | ||||
| of macroblocks is odd then the last row of macroblocks is arranged in a linear | ||||
| order.  </para> | ||||
| 	<para>In case of chroma the layout is identical. Cb and Cr samples are | ||||
| interleaved. Height of the buffer is aligned to 32. | ||||
| 	</para> | ||||
| 	<example> | ||||
| 	  <title>Memory layout of macroblocks in <constant>V4L2_PIX_FMT_NV12 | ||||
| </constant> format pixel image - extreme case</title> | ||||
| 	<para> | ||||
| 	<figure id="nv12mt_ex"> | ||||
| 	    <title>Example <constant>V4L2_PIX_FMT_NV12MT</constant> memory | ||||
| layout of macroblocks</title> | ||||
| 	    <mediaobject> | ||||
| 	      <imageobject> | ||||
| 		<imagedata fileref="nv12mt_example.gif" format="GIF" /> | ||||
| 	      </imageobject> | ||||
| 	    </mediaobject> | ||||
| 	</figure> | ||||
| 	Memory layout of macroblocks of <constant>V4L2_PIX_FMT_NV12MT | ||||
| </constant> format in most extreme case. | ||||
| 	</para> | ||||
| 	</example> | ||||
|       </refsect1> | ||||
|     </refentry> | ||||
| 
 | ||||
|   <!-- | ||||
| Local Variables: | ||||
| mode: sgml | ||||
| sgml-parent-document: "pixfmt.sgml" | ||||
| indent-tabs-mode: nil | ||||
| End: | ||||
|   --> | ||||
							
								
								
									
										90
									
								
								Documentation/DocBook/v4l/pixfmt-srggb12.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								Documentation/DocBook/v4l/pixfmt-srggb12.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | ||||
|     <refentry> | ||||
|       <refmeta> | ||||
| 	<refentrytitle>V4L2_PIX_FMT_SRGGB12 ('RG12'), | ||||
| 	 V4L2_PIX_FMT_SGRBG12 ('BA12'), | ||||
| 	 V4L2_PIX_FMT_SGBRG12 ('GB12'), | ||||
| 	 V4L2_PIX_FMT_SBGGR12 ('BG12'), | ||||
| 	 </refentrytitle> | ||||
| 	&manvol; | ||||
|       </refmeta> | ||||
|       <refnamediv> | ||||
| 	<refname id="V4L2-PIX-FMT-SRGGB12"><constant>V4L2_PIX_FMT_SRGGB12</constant></refname> | ||||
| 	<refname id="V4L2-PIX-FMT-SGRBG12"><constant>V4L2_PIX_FMT_SGRBG12</constant></refname> | ||||
| 	<refname id="V4L2-PIX-FMT-SGBRG12"><constant>V4L2_PIX_FMT_SGBRG12</constant></refname> | ||||
| 	<refname id="V4L2-PIX-FMT-SBGGR12"><constant>V4L2_PIX_FMT_SBGGR12</constant></refname> | ||||
| 	<refpurpose>12-bit Bayer formats expanded to 16 bits</refpurpose> | ||||
|       </refnamediv> | ||||
|       <refsect1> | ||||
| 	<title>Description</title> | ||||
| 
 | ||||
| 	<para>The following four pixel formats are raw sRGB / Bayer formats with | ||||
| 12 bits per colour. Each colour component is stored in a 16-bit word, with 6 | ||||
| unused high bits filled with zeros. Each n-pixel row contains n/2 green samples | ||||
| and n/2 blue or red samples, with alternating red and blue rows. Bytes are | ||||
| stored in memory in little endian order. They are conventionally described | ||||
| as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example of one of these | ||||
| formats</para> | ||||
| 
 | ||||
|     <example> | ||||
|       <title><constant>V4L2_PIX_FMT_SBGGR12</constant> 4 × 4 | ||||
| pixel image</title> | ||||
| 
 | ||||
|       <formalpara> | ||||
| 	<title>Byte Order.</title> | ||||
| 	<para>Each cell is one byte, high 6 bits in high bytes are 0. | ||||
| 	  <informaltable frame="none"> | ||||
| 	    <tgroup cols="5" align="center"> | ||||
| 	      <colspec align="left" colwidth="2*" /> | ||||
| 	      <tbody valign="top"> | ||||
| 		<row> | ||||
| 		  <entry>start + 0:</entry> | ||||
| 		  <entry>B<subscript>00low</subscript></entry> | ||||
| 		  <entry>B<subscript>00high</subscript></entry> | ||||
| 		  <entry>G<subscript>01low</subscript></entry> | ||||
| 		  <entry>G<subscript>01high</subscript></entry> | ||||
| 		  <entry>B<subscript>02low</subscript></entry> | ||||
| 		  <entry>B<subscript>02high</subscript></entry> | ||||
| 		  <entry>G<subscript>03low</subscript></entry> | ||||
| 		  <entry>G<subscript>03high</subscript></entry> | ||||
| 		</row> | ||||
| 		<row> | ||||
| 		  <entry>start + 8:</entry> | ||||
| 		  <entry>G<subscript>10low</subscript></entry> | ||||
| 		  <entry>G<subscript>10high</subscript></entry> | ||||
| 		  <entry>R<subscript>11low</subscript></entry> | ||||
| 		  <entry>R<subscript>11high</subscript></entry> | ||||
| 		  <entry>G<subscript>12low</subscript></entry> | ||||
| 		  <entry>G<subscript>12high</subscript></entry> | ||||
| 		  <entry>R<subscript>13low</subscript></entry> | ||||
| 		  <entry>R<subscript>13high</subscript></entry> | ||||
| 		</row> | ||||
| 		<row> | ||||
| 		  <entry>start + 16:</entry> | ||||
| 		  <entry>B<subscript>20low</subscript></entry> | ||||
| 		  <entry>B<subscript>20high</subscript></entry> | ||||
| 		  <entry>G<subscript>21low</subscript></entry> | ||||
| 		  <entry>G<subscript>21high</subscript></entry> | ||||
| 		  <entry>B<subscript>22low</subscript></entry> | ||||
| 		  <entry>B<subscript>22high</subscript></entry> | ||||
| 		  <entry>G<subscript>23low</subscript></entry> | ||||
| 		  <entry>G<subscript>23high</subscript></entry> | ||||
| 		</row> | ||||
| 		<row> | ||||
| 		  <entry>start + 24:</entry> | ||||
| 		  <entry>G<subscript>30low</subscript></entry> | ||||
| 		  <entry>G<subscript>30high</subscript></entry> | ||||
| 		  <entry>R<subscript>31low</subscript></entry> | ||||
| 		  <entry>R<subscript>31high</subscript></entry> | ||||
| 		  <entry>G<subscript>32low</subscript></entry> | ||||
| 		  <entry>G<subscript>32high</subscript></entry> | ||||
| 		  <entry>R<subscript>33low</subscript></entry> | ||||
| 		  <entry>R<subscript>33high</subscript></entry> | ||||
| 		</row> | ||||
| 	      </tbody> | ||||
| 	    </tgroup> | ||||
| 	  </informaltable> | ||||
| 	</para> | ||||
|       </formalpara> | ||||
|     </example> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										162
									
								
								Documentation/DocBook/v4l/pixfmt-yuv420m.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								Documentation/DocBook/v4l/pixfmt-yuv420m.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,162 @@ | ||||
|     <refentry id="V4L2-PIX-FMT-YUV420M"> | ||||
|       <refmeta> | ||||
| 	<refentrytitle>V4L2_PIX_FMT_YUV420M ('YU12M')</refentrytitle> | ||||
| 	&manvol; | ||||
|       </refmeta> | ||||
|       <refnamediv> | ||||
| 	<refname> <constant>V4L2_PIX_FMT_YUV420M</constant></refname> | ||||
| 	<refpurpose>Variation of <constant>V4L2_PIX_FMT_YUV420</constant> | ||||
| 	  with planes non contiguous in memory. </refpurpose> | ||||
|       </refnamediv> | ||||
| 
 | ||||
|       <refsect1> | ||||
| 	<title>Description</title> | ||||
| 
 | ||||
| 	<para>This is a multi-planar format, as opposed to a packed format. | ||||
| The three components are separated into three sub- images or planes. | ||||
| 
 | ||||
| The Y plane is first. The Y plane has one byte per pixel. The Cb data | ||||
| constitutes the second plane which is half the width and half | ||||
| the height of the Y plane (and of the image). Each Cb belongs to four | ||||
| pixels, a two-by-two square of the image. For example, | ||||
| Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>, | ||||
| Y'<subscript>01</subscript>, Y'<subscript>10</subscript>, and | ||||
| Y'<subscript>11</subscript>. The Cr data, just like the Cb plane, is | ||||
| in the third plane. </para> | ||||
| 
 | ||||
| 	<para>If the Y plane has pad bytes after each row, then the Cb | ||||
| and Cr planes have half as many pad bytes after their rows. In other | ||||
| words, two Cx rows (including padding) is exactly as long as one Y row | ||||
| (including padding).</para> | ||||
| 
 | ||||
| 	<para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be | ||||
| used only in drivers and applications that support the multi-planar API, | ||||
| described in <xref linkend="planar-apis"/>. </para> | ||||
| 
 | ||||
| 	<example> | ||||
| 	  <title><constant>V4L2_PIX_FMT_YVU420M</constant> 4 × 4 | ||||
| pixel image</title> | ||||
| 
 | ||||
| 	  <formalpara> | ||||
| 	    <title>Byte Order.</title> | ||||
| 	    <para>Each cell is one byte. | ||||
| 		<informaltable frame="none"> | ||||
| 		<tgroup cols="5" align="center"> | ||||
| 		  <colspec align="left" colwidth="2*" /> | ||||
| 		  <tbody valign="top"> | ||||
| 		    <row> | ||||
| 		      <entry>start0 + 0:</entry> | ||||
| 		      <entry>Y'<subscript>00</subscript></entry> | ||||
| 		      <entry>Y'<subscript>01</subscript></entry> | ||||
| 		      <entry>Y'<subscript>02</subscript></entry> | ||||
| 		      <entry>Y'<subscript>03</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>start0 + 4:</entry> | ||||
| 		      <entry>Y'<subscript>10</subscript></entry> | ||||
| 		      <entry>Y'<subscript>11</subscript></entry> | ||||
| 		      <entry>Y'<subscript>12</subscript></entry> | ||||
| 		      <entry>Y'<subscript>13</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>start0 + 8:</entry> | ||||
| 		      <entry>Y'<subscript>20</subscript></entry> | ||||
| 		      <entry>Y'<subscript>21</subscript></entry> | ||||
| 		      <entry>Y'<subscript>22</subscript></entry> | ||||
| 		      <entry>Y'<subscript>23</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>start0 + 12:</entry> | ||||
| 		      <entry>Y'<subscript>30</subscript></entry> | ||||
| 		      <entry>Y'<subscript>31</subscript></entry> | ||||
| 		      <entry>Y'<subscript>32</subscript></entry> | ||||
| 		      <entry>Y'<subscript>33</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row><entry></entry></row> | ||||
| 		    <row> | ||||
| 		      <entry>start1 + 0:</entry> | ||||
| 		      <entry>Cb<subscript>00</subscript></entry> | ||||
| 		      <entry>Cb<subscript>01</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>start1 + 2:</entry> | ||||
| 		      <entry>Cb<subscript>10</subscript></entry> | ||||
| 		      <entry>Cb<subscript>11</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row><entry></entry></row> | ||||
| 		    <row> | ||||
| 		      <entry>start2 + 0:</entry> | ||||
| 		      <entry>Cr<subscript>00</subscript></entry> | ||||
| 		      <entry>Cr<subscript>01</subscript></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>start2 + 2:</entry> | ||||
| 		      <entry>Cr<subscript>10</subscript></entry> | ||||
| 		      <entry>Cr<subscript>11</subscript></entry> | ||||
| 		    </row> | ||||
| 		  </tbody> | ||||
| 		</tgroup> | ||||
| 		</informaltable> | ||||
| 	      </para> | ||||
| 	  </formalpara> | ||||
| 
 | ||||
| 	  <formalpara> | ||||
| 	    <title>Color Sample Location.</title> | ||||
| 	    <para> | ||||
| 		<informaltable frame="none"> | ||||
| 		<tgroup cols="7" align="center"> | ||||
| 		  <tbody valign="top"> | ||||
| 		    <row> | ||||
| 		      <entry></entry> | ||||
| 		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry> | ||||
| 		      <entry>2</entry><entry></entry><entry>3</entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>0</entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry></entry> | ||||
| 		      <entry></entry><entry>C</entry><entry></entry><entry></entry> | ||||
| 		      <entry></entry><entry>C</entry><entry></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>1</entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>2</entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry></entry> | ||||
| 		      <entry></entry><entry>C</entry><entry></entry><entry></entry> | ||||
| 		      <entry></entry><entry>C</entry><entry></entry> | ||||
| 		    </row> | ||||
| 		    <row> | ||||
| 		      <entry>3</entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> | ||||
| 		      <entry>Y</entry><entry></entry><entry>Y</entry> | ||||
| 		    </row> | ||||
| 		  </tbody> | ||||
| 		</tgroup> | ||||
| 		</informaltable> | ||||
| 	      </para> | ||||
| 	  </formalpara> | ||||
| 	</example> | ||||
|       </refsect1> | ||||
|     </refentry> | ||||
| 
 | ||||
|   <!-- | ||||
| Local Variables: | ||||
| mode: sgml | ||||
| sgml-parent-document: "pixfmt.sgml" | ||||
| indent-tabs-mode: nil | ||||
| End: | ||||
|   --> | ||||
| @ -2,12 +2,16 @@ | ||||
| 
 | ||||
|   <para>The V4L2 API was primarily designed for devices exchanging | ||||
| image data with applications. The | ||||
| <structname>v4l2_pix_format</structname> structure defines the format | ||||
| and layout of an image in memory. Image formats are negotiated with | ||||
| the &VIDIOC-S-FMT; ioctl. (The explanations here focus on video | ||||
| <structname>v4l2_pix_format</structname> and <structname>v4l2_pix_format_mplane | ||||
| </structname> structures define the format and layout of an image in memory. | ||||
| The former is used with the single-planar API, while the latter is used with the | ||||
| multi-planar version (see <xref linkend="planar-apis"/>). Image formats are | ||||
| negotiated with the &VIDIOC-S-FMT; ioctl. (The explanations here focus on video | ||||
| capturing and output, for overlay frame buffer formats see also | ||||
| &VIDIOC-G-FBUF;.)</para> | ||||
| 
 | ||||
| <section> | ||||
|   <title>Single-planar format structure</title> | ||||
|   <table pgwide="1" frame="none" id="v4l2-pix-format"> | ||||
|     <title>struct <structname>v4l2_pix_format</structname></title> | ||||
|     <tgroup cols="3"> | ||||
| @ -106,6 +110,98 @@ set this field to zero.</entry> | ||||
|       </tbody> | ||||
|     </tgroup> | ||||
|   </table> | ||||
| </section> | ||||
| 
 | ||||
| <section> | ||||
|   <title>Multi-planar format structures</title> | ||||
|   <para>The <structname>v4l2_plane_pix_format</structname> structures define | ||||
|     size and layout for each of the planes in a multi-planar format. | ||||
|     The <structname>v4l2_pix_format_mplane</structname> structure contains | ||||
|     information common to all planes (such as image width and height) and | ||||
|     an array of <structname>v4l2_plane_pix_format</structname> structures, | ||||
|     describing all planes of that format.</para> | ||||
|   <table pgwide="1" frame="none" id="v4l2-plane-pix-format"> | ||||
|     <title>struct <structname>vl42_plane_pix_format</structname></title> | ||||
|     <tgroup cols="3"> | ||||
|       &cs-str; | ||||
|       <tbody valign="top"> | ||||
|         <row> | ||||
|           <entry>__u32</entry> | ||||
|           <entry><structfield>sizeimage</structfield></entry> | ||||
|           <entry>Maximum size in bytes required for image data in this plane. | ||||
|           </entry> | ||||
|         </row> | ||||
|         <row> | ||||
|           <entry>__u16</entry> | ||||
|           <entry><structfield>bytesperline</structfield></entry> | ||||
|           <entry>Distance in bytes between the leftmost pixels in two adjacent | ||||
|             lines.</entry> | ||||
|         </row> | ||||
|         <row> | ||||
|           <entry>__u16</entry> | ||||
|           <entry><structfield>reserved[7]</structfield></entry> | ||||
|           <entry>Reserved for future extensions. Should be zeroed by the | ||||
|            application.</entry> | ||||
|         </row> | ||||
|       </tbody> | ||||
|     </tgroup> | ||||
|   </table> | ||||
|   <table pgwide="1" frame="none" id="v4l2-pix-format-mplane"> | ||||
|     <title>struct <structname>v4l2_pix_format_mplane</structname></title> | ||||
|     <tgroup cols="3"> | ||||
|       &cs-str; | ||||
|       <tbody valign="top"> | ||||
|         <row> | ||||
|           <entry>__u32</entry> | ||||
|           <entry><structfield>width</structfield></entry> | ||||
|           <entry>Image width in pixels.</entry> | ||||
|         </row> | ||||
|         <row> | ||||
|           <entry>__u32</entry> | ||||
|           <entry><structfield>height</structfield></entry> | ||||
|           <entry>Image height in pixels.</entry> | ||||
|         </row> | ||||
|         <row> | ||||
|           <entry>__u32</entry> | ||||
|           <entry><structfield>pixelformat</structfield></entry> | ||||
|           <entry>The pixel format. Both single- and multi-planar four character | ||||
| codes can be used.</entry> | ||||
|         </row> | ||||
|         <row> | ||||
|           <entry>&v4l2-field;</entry> | ||||
|           <entry><structfield>field</structfield></entry> | ||||
|           <entry>See &v4l2-pix-format;.</entry> | ||||
|         </row> | ||||
|         <row> | ||||
|           <entry>&v4l2-colorspace;</entry> | ||||
|           <entry><structfield>colorspace</structfield></entry> | ||||
|           <entry>See &v4l2-pix-format;.</entry> | ||||
|         </row> | ||||
|         <row> | ||||
|           <entry>&v4l2-plane-pix-format;</entry> | ||||
|           <entry><structfield>plane_fmt[VIDEO_MAX_PLANES]</structfield></entry> | ||||
|           <entry>An array of structures describing format of each plane this | ||||
|           pixel format consists of. The number of valid entries in this array | ||||
|           has to be put in the <structfield>num_planes</structfield> | ||||
|           field.</entry> | ||||
|         </row> | ||||
|         <row> | ||||
|           <entry>__u8</entry> | ||||
|           <entry><structfield>num_planes</structfield></entry> | ||||
|           <entry>Number of planes (i.e. separate memory buffers) for this format | ||||
|           and the number of valid entries in the | ||||
|           <structfield>plane_fmt</structfield> array.</entry> | ||||
|         </row> | ||||
|         <row> | ||||
|           <entry>__u8</entry> | ||||
|           <entry><structfield>reserved[11]</structfield></entry> | ||||
|           <entry>Reserved for future extensions. Should be zeroed by the | ||||
|            application.</entry> | ||||
|         </row> | ||||
|       </tbody> | ||||
|     </tgroup> | ||||
|   </table> | ||||
| </section> | ||||
| 
 | ||||
|   <section> | ||||
|     <title>Standard Image Formats</title> | ||||
| @ -142,11 +238,19 @@ leftmost pixel of the second row from the top, and so on. The last row | ||||
| has just as many pad bytes after it as the other rows.</para> | ||||
| 
 | ||||
|     <para>In V4L2 each format has an identifier which looks like | ||||
| <constant>PIX_FMT_XXX</constant>, defined in the <filename>videodev2.h</filename> | ||||
| header file. These identifiers | ||||
| represent <link linkend="v4l2-fourcc">four character codes</link> | ||||
| <constant>PIX_FMT_XXX</constant>, defined in the <link | ||||
| linkend="videodev">videodev.h</link> header file. These identifiers | ||||
| represent <link linkend="v4l2-fourcc">four character (FourCC) codes</link> | ||||
| which are also listed below, however they are not the same as those | ||||
| used in the Windows world.</para> | ||||
| 
 | ||||
|     <para>For some formats, data is stored in separate, discontiguous | ||||
| memory buffers. Those formats are identified by a separate set of FourCC codes | ||||
| and are referred to as "multi-planar formats". For example, a YUV422 frame is | ||||
| normally stored in one memory buffer, but it can also be placed in two or three | ||||
| separate buffers, with Y component in one buffer and CbCr components in another | ||||
| in the 2-planar version or with each component in its own buffer in the | ||||
| 3-planar case. Those sub-buffers are referred to as "planes".</para> | ||||
|   </section> | ||||
| 
 | ||||
|   <section id="colorspaces"> | ||||
| @ -599,10 +703,13 @@ information.</para> | ||||
|     &sub-vyuy; | ||||
|     &sub-y41p; | ||||
|     &sub-yuv420; | ||||
|     &sub-yuv420m; | ||||
|     &sub-yuv410; | ||||
|     &sub-yuv422p; | ||||
|     &sub-yuv411p; | ||||
|     &sub-nv12; | ||||
|     &sub-nv12m; | ||||
|     &sub-nv12mt; | ||||
|     &sub-nv16; | ||||
|   </section> | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										62
									
								
								Documentation/DocBook/v4l/planar-apis.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								Documentation/DocBook/v4l/planar-apis.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,62 @@ | ||||
| <section id="planar-apis"> | ||||
|   <title>Single- and multi-planar APIs</title> | ||||
| 
 | ||||
|   <para>Some devices require data for each input or output video frame | ||||
|   to be placed in discontiguous memory buffers. In such cases, one | ||||
|   video frame has to be addressed using more than one memory address, i.e. one | ||||
|   pointer per "plane". A plane is a sub-buffer of the current frame. For | ||||
|   examples of such formats see <xref linkend="pixfmt" />.</para> | ||||
| 
 | ||||
|   <para>Initially, V4L2 API did not support multi-planar buffers and a set of | ||||
|   extensions has been introduced to handle them. Those extensions constitute | ||||
|   what is being referred to as the "multi-planar API".</para> | ||||
| 
 | ||||
|   <para>Some of the V4L2 API calls and structures are interpreted differently, | ||||
|   depending on whether single- or multi-planar API is being used. An application | ||||
|   can choose whether to use one or the other by passing a corresponding buffer | ||||
|   type to its ioctl calls. Multi-planar versions of buffer types are suffixed | ||||
|   with an `_MPLANE' string. For a list of available multi-planar buffer types | ||||
|   see &v4l2-buf-type;. | ||||
|   </para> | ||||
| 
 | ||||
|   <section> | ||||
|     <title>Multi-planar formats</title> | ||||
|     <para>Multi-planar API introduces new multi-planar formats. Those formats | ||||
|     use a separate set of FourCC codes. It is important to distinguish between | ||||
|     the multi-planar API and a multi-planar format. Multi-planar API calls can | ||||
|     handle all single-planar formats as well (as long as they are passed in | ||||
|     multi-planar API structures), while the single-planar API cannot | ||||
|     handle multi-planar formats.</para> | ||||
|   </section> | ||||
| 
 | ||||
|   <section> | ||||
|     <title>Calls that distinguish between single and multi-planar APIs</title> | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
|         <term>&VIDIOC-QUERYCAP;</term> | ||||
|         <listitem><para>Two additional multi-planar capabilities are added. They can | ||||
|         be set together with non-multi-planar ones for devices that handle | ||||
|         both single- and multi-planar formats.</para></listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
|         <term>&VIDIOC-G-FMT;, &VIDIOC-S-FMT;, &VIDIOC-TRY-FMT;</term> | ||||
|         <listitem><para>New structures for describing multi-planar formats are added: | ||||
|         &v4l2-pix-format-mplane; and &v4l2-plane-pix-format;. Drivers may | ||||
|         define new multi-planar formats, which have distinct FourCC codes from | ||||
|         the existing single-planar ones.</para> | ||||
|         </listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
|         <term>&VIDIOC-QBUF;, &VIDIOC-DQBUF;, &VIDIOC-QUERYBUF;</term> | ||||
|         <listitem><para>A new &v4l2-plane; structure for describing planes is added. | ||||
|         Arrays of this structure are passed in the new | ||||
|         <structfield>m.planes</structfield> field of &v4l2-buffer;.</para> | ||||
|         </listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
|         <term>&VIDIOC-REQBUFS;</term> | ||||
|         <listitem><para>Will allocate multi-planar buffers as requested.</para></listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </section> | ||||
| </section> | ||||
							
								
								
									
										2467
									
								
								Documentation/DocBook/v4l/subdev-formats.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2467
									
								
								Documentation/DocBook/v4l/subdev-formats.xml
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -85,6 +85,17 @@ Remote Controller chapter.</contrib> | ||||
| 	  </address> | ||||
| 	</affiliation> | ||||
|       </author> | ||||
| 
 | ||||
|       <author> | ||||
|       	<firstname>Pawel</firstname> | ||||
| 	<surname>Osciak</surname> | ||||
| 	<contrib>Designed and documented the multi-planar API.</contrib> | ||||
| 	<affiliation> | ||||
| 	  <address> | ||||
| 	    <email>pawel AT osciak.com</email> | ||||
| 	  </address> | ||||
| 	</affiliation> | ||||
|       </author> | ||||
|     </authorgroup> | ||||
| 
 | ||||
|     <copyright> | ||||
| @ -102,7 +113,8 @@ Remote Controller chapter.</contrib> | ||||
|       <year>2010</year> | ||||
|       <year>2011</year> | ||||
|       <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin | ||||
| Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder> | ||||
| Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab, | ||||
| 	Pawel Osciak</holder> | ||||
|     </copyright> | ||||
|     <legalnotice> | ||||
|     <para>Except when explicitly stated as GPL, programming examples within | ||||
| @ -115,6 +127,13 @@ structs, ioctls) must be noted in more detail in the history chapter | ||||
| (compat.xml), along with the possible impact on existing drivers and | ||||
| applications. --> | ||||
| 
 | ||||
|       <revision> | ||||
| 	<revnumber>2.6.39</revnumber> | ||||
| 	<date>2011-03-01</date> | ||||
| 	<authorinitials>mcc, po</authorinitials> | ||||
| 	<revremark>Removed VIDIOC_*_OLD from videodev2.h header and update it to reflect latest changes. Added the <link linkend="planar-apis">multi-planar API</link>.</revremark> | ||||
|       </revision> | ||||
| 
 | ||||
|       <revision> | ||||
| 	<revnumber>2.6.37</revnumber> | ||||
| 	<date>2010-08-06</date> | ||||
| @ -382,7 +401,7 @@ and discussions on the V4L mailing list.</revremark> | ||||
| </partinfo> | ||||
| 
 | ||||
| <title>Video for Linux Two API Specification</title> | ||||
|  <subtitle>Revision 2.6.38</subtitle> | ||||
|  <subtitle>Revision 2.6.39</subtitle> | ||||
| 
 | ||||
|   <chapter id="common"> | ||||
|     &sub-common; | ||||
| @ -411,6 +430,7 @@ and discussions on the V4L mailing list.</revremark> | ||||
|     <section id="radio"> &sub-dev-radio; </section> | ||||
|     <section id="rds"> &sub-dev-rds; </section> | ||||
|     <section id="event"> &sub-dev-event; </section> | ||||
|     <section id="subdev"> &sub-dev-subdev; </section> | ||||
|   </chapter> | ||||
| 
 | ||||
|   <chapter id="driver"> | ||||
| @ -478,6 +498,12 @@ and discussions on the V4L mailing list.</revremark> | ||||
|     &sub-reqbufs; | ||||
|     &sub-s-hw-freq-seek; | ||||
|     &sub-streamon; | ||||
|     &sub-subdev-enum-frame-interval; | ||||
|     &sub-subdev-enum-frame-size; | ||||
|     &sub-subdev-enum-mbus-code; | ||||
|     &sub-subdev-g-crop; | ||||
|     &sub-subdev-g-fmt; | ||||
|     &sub-subdev-g-frame-interval; | ||||
|     &sub-subscribe-event; | ||||
|     <!-- End of ioctls. --> | ||||
|     &sub-mmap; | ||||
|  | ||||
| @ -71,6 +71,7 @@ | ||||
|  * Moved from videodev.h | ||||
|  */ | ||||
| #define VIDEO_MAX_FRAME               32 | ||||
| #define VIDEO_MAX_PLANES               8 | ||||
| 
 | ||||
| #ifndef __KERNEL__ | ||||
| 
 | ||||
| @ -158,9 +159,23 @@ enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> { | ||||
|         /* Experimental */ | ||||
|         V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, | ||||
| #endif | ||||
|         V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9, | ||||
|         V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE  = 10, | ||||
|         V4L2_BUF_TYPE_PRIVATE              = 0x80, | ||||
| }; | ||||
| 
 | ||||
| #define V4L2_TYPE_IS_MULTIPLANAR(type)                  \ | ||||
|         ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE   \ | ||||
|          || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) | ||||
| 
 | ||||
| #define V4L2_TYPE_IS_OUTPUT(type)                               \ | ||||
|         ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT                   \ | ||||
|          || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE         \ | ||||
|          || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY               \ | ||||
|          || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY        \ | ||||
|          || (type) == V4L2_BUF_TYPE_VBI_OUTPUT                  \ | ||||
|          || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) | ||||
| 
 | ||||
| enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> { | ||||
|         V4L2_TUNER_RADIO             = 1, | ||||
|         V4L2_TUNER_ANALOG_TV         = 2, | ||||
| @ -246,6 +261,11 @@ struct <link linkend="v4l2-capability">v4l2_capability</link> { | ||||
| #define V4L2_CAP_HW_FREQ_SEEK           0x00000400  /* Can do hardware frequency seek  */ | ||||
| #define V4L2_CAP_RDS_OUTPUT             0x00000800  /* Is an RDS encoder */ | ||||
| 
 | ||||
| /* Is a video capture device that supports multiplanar formats */ | ||||
| #define V4L2_CAP_VIDEO_CAPTURE_MPLANE   0x00001000 | ||||
| /* Is a video output device that supports multiplanar formats */ | ||||
| #define V4L2_CAP_VIDEO_OUTPUT_MPLANE    0x00002000 | ||||
| 
 | ||||
| #define V4L2_CAP_TUNER                  0x00010000  /* has a tuner */ | ||||
| #define V4L2_CAP_AUDIO                  0x00020000  /* has audio support */ | ||||
| #define V4L2_CAP_RADIO                  0x00040000  /* is a radio device */ | ||||
| @ -320,6 +340,13 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> { | ||||
| #define <link linkend="V4L2-PIX-FMT-NV16">V4L2_PIX_FMT_NV16</link>    v4l2_fourcc('N', 'V', '1', '6') /* 16  Y/CbCr 4:2:2  */ | ||||
| #define <link linkend="V4L2-PIX-FMT-NV61">V4L2_PIX_FMT_NV61</link>    v4l2_fourcc('N', 'V', '6', '1') /* 16  Y/CrCb 4:2:2  */ | ||||
| 
 | ||||
| /* two non contiguous planes - one Y, one Cr + Cb interleaved  */ | ||||
| #define <link linkend="V4L2-PIX-FMT-NV12M">V4L2_PIX_FMT_NV12M</link>   v4l2_fourcc('N', 'M', '1', '2') /* 12  Y/CbCr 4:2:0  */ | ||||
| #define <link linkend="V4L2-PIX-FMT-NV12MT">V4L2_PIX_FMT_NV12MT</link>  v4l2_fourcc('T', 'M', '1', '2') /* 12  Y/CbCr 4:2:0 64x32 macroblocks */ | ||||
| 
 | ||||
| /* three non contiguous planes - Y, Cb, Cr */ | ||||
| #define <link linkend="V4L2-PIX-FMT-YUV420M">V4L2_PIX_FMT_YUV420M</link> v4l2_fourcc('Y', 'M', '1', '2') /* 12  YUV420 planar */ | ||||
| 
 | ||||
| /* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ | ||||
| #define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link>  v4l2_fourcc('B', 'A', '8', '1') /*  8  BGBG.. GRGR.. */ | ||||
| #define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link>  v4l2_fourcc('G', 'B', 'R', 'G') /*  8  GBGB.. RGRG.. */ | ||||
| @ -518,6 +545,62 @@ struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> { | ||||
|         __u32                   reserved[2]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * struct <link linkend="v4l2-plane">v4l2_plane</link> - plane info for multi-planar buffers | ||||
|  * @bytesused:          number of bytes occupied by data in the plane (payload) | ||||
|  * @length:             size of this plane (NOT the payload) in bytes | ||||
|  * @mem_offset:         when memory in the associated struct <link linkend="v4l2-buffer">v4l2_buffer</link> is | ||||
|  *                      V4L2_MEMORY_MMAP, equals the offset from the start of | ||||
|  *                      the device memory for this plane (or is a "cookie" that | ||||
|  *                      should be passed to mmap() called on the video node) | ||||
|  * @userptr:            when memory is V4L2_MEMORY_USERPTR, a userspace pointer | ||||
|  *                      pointing to this plane | ||||
|  * @data_offset:        offset in the plane to the start of data; usually 0, | ||||
|  *                      unless there is a header in front of the data | ||||
|  * | ||||
|  * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer | ||||
|  * with two planes can have one plane for Y, and another for interleaved CbCr | ||||
|  * components. Each plane can reside in a separate memory buffer, or even in | ||||
|  * a completely separate memory node (e.g. in embedded devices). | ||||
|  */ | ||||
| struct <link linkend="v4l2-plane">v4l2_plane</link> { | ||||
|         __u32                   bytesused; | ||||
|         __u32                   length; | ||||
|         union { | ||||
|                 __u32           mem_offset; | ||||
|                 unsigned long   userptr; | ||||
|         } m; | ||||
|         __u32                   data_offset; | ||||
|         __u32                   reserved[11]; | ||||
| }; | ||||
| 
 | ||||
| /** | ||||
|  * struct <link linkend="v4l2-buffer">v4l2_buffer</link> - video buffer info | ||||
|  * @index:      id number of the buffer | ||||
|  * @type:       buffer type (type == *_MPLANE for multiplanar buffers) | ||||
|  * @bytesused:  number of bytes occupied by data in the buffer (payload); | ||||
|  *              unused (set to 0) for multiplanar buffers | ||||
|  * @flags:      buffer informational flags | ||||
|  * @field:      field order of the image in the buffer | ||||
|  * @timestamp:  frame timestamp | ||||
|  * @timecode:   frame timecode | ||||
|  * @sequence:   sequence count of this frame | ||||
|  * @memory:     the method, in which the actual video data is passed | ||||
|  * @offset:     for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP; | ||||
|  *              offset from the start of the device memory for this plane, | ||||
|  *              (or a "cookie" that should be passed to mmap() as offset) | ||||
|  * @userptr:    for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR; | ||||
|  *              a userspace pointer pointing to this buffer | ||||
|  * @planes:     for multiplanar buffers; userspace pointer to the array of plane | ||||
|  *              info structs for this buffer | ||||
|  * @length:     size in bytes of the buffer (NOT its payload) for single-plane | ||||
|  *              buffers (when type != *_MPLANE); number of elements in the | ||||
|  *              planes array for multi-plane buffers | ||||
|  * @input:      input number from which the video data has has been captured | ||||
|  * | ||||
|  * Contains data exchanged by application and driver using one of the Streaming | ||||
|  * I/O methods. | ||||
|  */ | ||||
| struct <link linkend="v4l2-buffer">v4l2_buffer</link> { | ||||
|         __u32                   index; | ||||
|         enum <link linkend="v4l2-buf-type">v4l2_buf_type</link>      type; | ||||
| @ -533,6 +616,7 @@ struct <link linkend="v4l2-buffer">v4l2_buffer</link> { | ||||
|         union { | ||||
|                 __u32           offset; | ||||
|                 unsigned long   userptr; | ||||
|                 struct <link linkend="v4l2-plane">v4l2_plane</link> *planes; | ||||
|         } m; | ||||
|         __u32                   length; | ||||
|         __u32                   input; | ||||
| @ -1623,12 +1707,56 @@ struct <link linkend="v4l2-mpeg-vbi-fmt-ivtv">v4l2_mpeg_vbi_fmt_ivtv</link> { | ||||
|  *      A G G R E G A T E   S T R U C T U R E S | ||||
|  */ | ||||
| 
 | ||||
| /*      Stream data format | ||||
| /** | ||||
|  * struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link> - additional, per-plane format definition | ||||
|  * @sizeimage:          maximum size in bytes required for data, for which | ||||
|  *                      this plane will be used | ||||
|  * @bytesperline:       distance in bytes between the leftmost pixels in two | ||||
|  *                      adjacent lines | ||||
|  */ | ||||
| struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link> { | ||||
|         __u32           sizeimage; | ||||
|         __u16           bytesperline; | ||||
|         __u16           reserved[7]; | ||||
| } __attribute__ ((packed)); | ||||
| 
 | ||||
| /** | ||||
|  * struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link> - multiplanar format definition | ||||
|  * @width:              image width in pixels | ||||
|  * @height:             image height in pixels | ||||
|  * @pixelformat:        little endian four character code (fourcc) | ||||
|  * @field:              field order (for interlaced video) | ||||
|  * @colorspace:         supplemental to pixelformat | ||||
|  * @plane_fmt:          per-plane information | ||||
|  * @num_planes:         number of planes for this format | ||||
|  */ | ||||
| struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link> { | ||||
|         __u32                           width; | ||||
|         __u32                           height; | ||||
|         __u32                           pixelformat; | ||||
|         enum <link linkend="v4l2-field">v4l2_field</link>                 field; | ||||
|         enum <link linkend="v4l2-colorspace">v4l2_colorspace</link>            colorspace; | ||||
| 
 | ||||
|         struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link>    plane_fmt[VIDEO_MAX_PLANES]; | ||||
|         __u8                            num_planes; | ||||
|         __u8                            reserved[11]; | ||||
| } __attribute__ ((packed)); | ||||
| 
 | ||||
| /** | ||||
|  * struct <link linkend="v4l2-format">v4l2_format</link> - stream data format | ||||
|  * @type:       type of the data stream | ||||
|  * @pix:        definition of an image format | ||||
|  * @pix_mp:     definition of a multiplanar image format | ||||
|  * @win:        definition of an overlaid image | ||||
|  * @vbi:        raw VBI capture or output parameters | ||||
|  * @sliced:     sliced VBI capture or output parameters | ||||
|  * @raw_data:   placeholder for future extensions and custom formats | ||||
|  */ | ||||
| struct <link linkend="v4l2-format">v4l2_format</link> { | ||||
|         enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type; | ||||
|         union { | ||||
|                 struct <link linkend="v4l2-pix-format">v4l2_pix_format</link>          pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ | ||||
|                 struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link>   pix_mp;  /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */ | ||||
|                 struct <link linkend="v4l2-window">v4l2_window</link>              win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ | ||||
|                 struct <link linkend="v4l2-vbi-format">v4l2_vbi_format</link>          vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */ | ||||
|                 struct <link linkend="v4l2-sliced-vbi-format">v4l2_sliced_vbi_format</link>   sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ | ||||
| @ -1636,7 +1764,6 @@ struct <link linkend="v4l2-format">v4l2_format</link> { | ||||
|         } fmt; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /*      Stream type-dependent parameters | ||||
|  */ | ||||
| struct <link linkend="v4l2-streamparm">v4l2_streamparm</link> { | ||||
| @ -1809,16 +1936,6 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> { | ||||
| /* Reminder: when adding new ioctls please add support for them to | ||||
|    drivers/media/video/v4l2-compat-ioctl32.c as well! */ | ||||
| 
 | ||||
| #ifdef __OLD_VIDIOC_ | ||||
| /* for compatibility, will go away some day */ | ||||
| #define VIDIOC_OVERLAY_OLD      _IOWR('V', 14, int) | ||||
| #define VIDIOC_S_PARM_OLD        _IOW('V', 22, struct <link linkend="v4l2-streamparm">v4l2_streamparm</link>) | ||||
| #define VIDIOC_S_CTRL_OLD        _IOW('V', 28, struct <link linkend="v4l2-control">v4l2_control</link>) | ||||
| #define VIDIOC_G_AUDIO_OLD      _IOWR('V', 33, struct <link linkend="v4l2-audio">v4l2_audio</link>) | ||||
| #define VIDIOC_G_AUDOUT_OLD     _IOWR('V', 49, struct <link linkend="v4l2-audioout">v4l2_audioout</link>) | ||||
| #define VIDIOC_CROPCAP_OLD       _IOR('V', 58, struct <link linkend="v4l2-cropcap">v4l2_cropcap</link>) | ||||
| #endif | ||||
| 
 | ||||
| #define BASE_VIDIOC_PRIVATE     192             /* 192-255 are private */ | ||||
| 
 | ||||
| #endif /* __LINUX_VIDEODEV2_H */ | ||||
|  | ||||
| @ -76,7 +76,9 @@ pixelformat</structfield> field.</entry> | ||||
| 	    <entry>Type of the data stream, set by the application. | ||||
| Only these types are valid here: | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>, | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>, | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>, | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>, | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver | ||||
| defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant> | ||||
| and higher.</entry> | ||||
|  | ||||
| @ -60,11 +60,13 @@ application.</para> | ||||
| <structfield>type</structfield> field of a struct | ||||
| <structname>v4l2_format</structname> to the respective buffer (stream) | ||||
| type. For example video capture devices use | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>. When the application | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> or | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>. When the application | ||||
| calls the <constant>VIDIOC_G_FMT</constant> ioctl with a pointer to | ||||
| this structure the driver fills the respective member of the | ||||
| <structfield>fmt</structfield> union. In case of video capture devices | ||||
| that is the &v4l2-pix-format; <structfield>pix</structfield> member. | ||||
| that is either the &v4l2-pix-format; <structfield>pix</structfield> or | ||||
| the &v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member. | ||||
| When the requested buffer type is not supported drivers return an | ||||
| &EINVAL;.</para> | ||||
| 
 | ||||
| @ -131,6 +133,15 @@ this ioctl.</para> | ||||
| 	    <entry>Definition of an image format, see <xref | ||||
| 		linkend="pixfmt" />, used by video capture and output | ||||
| devices.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
| 	    <entry>&v4l2-pix-format-mplane;</entry> | ||||
| 	    <entry><structfield>pix_mp</structfield></entry> | ||||
| 	    <entry>Definition of an image format, see <xref | ||||
| 		linkend="pixfmt" />, used by video capture and output | ||||
| devices that support the <link linkend="planar-apis">multi-planar | ||||
| version of the API</link>.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry></entry> | ||||
|  | ||||
| @ -64,7 +64,8 @@ zero to the number of buffers allocated with &VIDIOC-REQBUFS; | ||||
| contents of the struct <structname>v4l2_buffer</structname> returned | ||||
| by a &VIDIOC-QUERYBUF; ioctl will do as well. When the buffer is | ||||
| intended for output (<structfield>type</structfield> is | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> or | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>, | ||||
| <constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>, or | ||||
| <constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also | ||||
| initialize the <structfield>bytesused</structfield>, | ||||
| <structfield>field</structfield> and | ||||
| @ -75,7 +76,11 @@ supports capturing from specific video inputs and you want to specify a video | ||||
| input, then <structfield>flags</structfield> should be set to | ||||
| <constant>V4L2_BUF_FLAG_INPUT</constant> and the field | ||||
| <structfield>input</structfield> must be initialized to the desired input. | ||||
| The <structfield>reserved</structfield> field must be set to 0. | ||||
| The <structfield>reserved</structfield> field must be set to 0. When using | ||||
| the <link linkend="planar-apis">multi-planar API</link>, the | ||||
| <structfield>m.planes</structfield> field must contain a userspace pointer | ||||
| to a filled-in array of &v4l2-plane; and the <structfield>length</structfield> | ||||
| field must be set to the number of elements in that array. | ||||
| </para> | ||||
| 
 | ||||
|     <para>To enqueue a <link linkend="mmap">memory mapped</link> | ||||
| @ -93,10 +98,13 @@ structure the driver sets the | ||||
| buffer applications set the <structfield>memory</structfield> | ||||
| field to <constant>V4L2_MEMORY_USERPTR</constant>, the | ||||
| <structfield>m.userptr</structfield> field to the address of the | ||||
| buffer and <structfield>length</structfield> to its size. | ||||
| When <constant>VIDIOC_QBUF</constant> is called with a pointer to this | ||||
| structure the driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant> | ||||
| flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and | ||||
| buffer and <structfield>length</structfield> to its size. When the multi-planar | ||||
| API is used, <structfield>m.userptr</structfield> and | ||||
| <structfield>length</structfield> members of the passed array of &v4l2-plane; | ||||
| have to be used instead. When <constant>VIDIOC_QBUF</constant> is called with | ||||
| a pointer to this structure the driver sets the | ||||
| <constant>V4L2_BUF_FLAG_QUEUED</constant> flag and clears the | ||||
| <constant>V4L2_BUF_FLAG_MAPPED</constant> and | ||||
| <constant>V4L2_BUF_FLAG_DONE</constant> flags in the | ||||
| <structfield>flags</structfield> field, or it returns an error code. | ||||
| This ioctl locks the memory pages of the buffer in physical memory, | ||||
| @ -115,7 +123,9 @@ remaining fields or returns an error code. The driver may also set | ||||
| <constant>V4L2_BUF_FLAG_ERROR</constant> in the <structfield>flags</structfield> | ||||
| field. It indicates a non-critical (recoverable) streaming error. In such case | ||||
| the application may continue as normal, but should be aware that data in the | ||||
| dequeued buffer might be corrupted.</para> | ||||
| dequeued buffer might be corrupted. When using the multi-planar API, the | ||||
| planes array does not have to be passed; the <structfield>m.planes</structfield> | ||||
| member must be set to NULL in that case.</para> | ||||
| 
 | ||||
|     <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no | ||||
| buffer is in the outgoing queue. When the | ||||
|  | ||||
| @ -61,6 +61,10 @@ buffer at any time after buffers have been allocated with the | ||||
| to the number of buffers allocated with &VIDIOC-REQBUFS; | ||||
|     (&v4l2-requestbuffers; <structfield>count</structfield>) minus one. | ||||
| The <structfield>reserved</structfield> field should to set to 0. | ||||
| When using the <link linkend="planar-apis">multi-planar API</link>, the | ||||
| <structfield>m.planes</structfield> field must contain a userspace pointer to an | ||||
| array of &v4l2-plane; and the <structfield>length</structfield> field has | ||||
| to be set to the number of elements in that array. | ||||
| After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to | ||||
|     this structure drivers return an error code or fill the rest of | ||||
| the structure.</para> | ||||
| @ -70,11 +74,13 @@ the structure.</para> | ||||
| <constant>V4L2_BUF_FLAG_QUEUED</constant> and | ||||
| <constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The | ||||
| <structfield>memory</structfield> field will be set to the current | ||||
| I/O method, the <structfield>m.offset</structfield> | ||||
| I/O method. For the single-planar API, the <structfield>m.offset</structfield> | ||||
| contains the offset of the buffer from the start of the device memory, | ||||
| the <structfield>length</structfield> field its size. The driver may | ||||
| or may not set the remaining fields and flags, they are meaningless in | ||||
| this context.</para> | ||||
| the <structfield>length</structfield> field its size. For the multi-planar API, | ||||
| fields <structfield>m.mem_offset</structfield> and | ||||
| <structfield>length</structfield> in the <structfield>m.planes</structfield> | ||||
| array elements will be used instead. The driver may or may not set the remaining | ||||
| fields and flags, they are meaningless in this context.</para> | ||||
| 
 | ||||
|     <para>The <structname>v4l2_buffer</structname> structure is | ||||
|     specified in <xref linkend="buffer" />.</para> | ||||
|  | ||||
| @ -142,15 +142,29 @@ this array to zero.</entry> | ||||
| 	  <row> | ||||
| 	    <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry> | ||||
| 	    <entry>0x00000001</entry> | ||||
| 	    <entry>The device supports the <link | ||||
| 	    <entry>The device supports the single-planar API through the <link | ||||
| linkend="capture">Video Capture</link> interface.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>V4L2_CAP_VIDEO_CAPTURE_MPLANE</constant></entry> | ||||
| 	    <entry>0x00001000</entry> | ||||
| 	    <entry>The device supports the | ||||
| 	    <link linkend="planar-apis">multi-planar API</link> through the | ||||
| 	    <link linkend="capture">Video Capture</link> interface.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>V4L2_CAP_VIDEO_OUTPUT</constant></entry> | ||||
| 	    <entry>0x00000002</entry> | ||||
| 	    <entry>The device supports the <link | ||||
| 	    <entry>The device supports the single-planar API through the <link | ||||
| linkend="output">Video Output</link> interface.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>V4L2_CAP_VIDEO_OUTPUT_MPLANE</constant></entry> | ||||
| 	    <entry>0x00002000</entry> | ||||
| 	    <entry>The device supports the | ||||
| 	    <link linkend="planar-apis">multi-planar API</link> through the | ||||
| 	    <link linkend="output">Video Output</link> interface.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry> | ||||
| 	    <entry>0x00000004</entry> | ||||
|  | ||||
| @ -93,6 +93,15 @@ synchronize with other events.</para> | ||||
| been allocated (memory mapping) or enqueued (output) yet.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EPIPE</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The driver implements <link | ||||
| 	  linkend="pad-level-formats">pad-level format configuration</link> and | ||||
| 	  the pipeline configuration is invalid. | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
|  | ||||
							
								
								
									
										152
									
								
								Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,152 @@ | ||||
| <refentry id="vidioc-subdev-enum-frame-interval"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</refname> | ||||
|     <refpurpose>Enumerate frame intervals</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>struct v4l2_subdev_frame_interval_enum * | ||||
| 	<parameter>argp</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>&fd;</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
| 
 | ||||
|     <note> | ||||
|       <title>Experimental</title> | ||||
|       <para>This is an <link linkend="experimental">experimental</link> | ||||
|       interface and may change in the future.</para> | ||||
|     </note> | ||||
| 
 | ||||
|     <para>This ioctl lets applications enumerate available frame intervals on a | ||||
|     given sub-device pad. Frame intervals only makes sense for sub-devices that | ||||
|     can control the frame period on their own. This includes, for instance, | ||||
|     image sensors and TV tuners.</para> | ||||
| 
 | ||||
|     <para>For the common use case of image sensors, the frame intervals | ||||
|     available on the sub-device output pad depend on the frame format and size | ||||
|     on the same pad. Applications must thus specify the desired format and size | ||||
|     when enumerating frame intervals.</para> | ||||
| 
 | ||||
|     <para>To enumerate frame intervals applications initialize the | ||||
|     <structfield>index</structfield>, <structfield>pad</structfield>, | ||||
|     <structfield>code</structfield>, <structfield>width</structfield> and | ||||
|     <structfield>height</structfield> fields of | ||||
|     &v4l2-subdev-frame-interval-enum; and call the | ||||
|     <constant>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</constant> ioctl with a pointer | ||||
|     to this structure. Drivers fill the rest of the structure or return | ||||
|     an &EINVAL; if one of the input fields is invalid. All frame intervals are | ||||
|     enumerable by beginning at index zero and incrementing by one until | ||||
|     <errorcode>EINVAL</errorcode> is returned.</para> | ||||
| 
 | ||||
|     <para>Available frame intervals may depend on the current 'try' formats | ||||
|     at other pads of the sub-device, as well as on the current active links. See | ||||
|     &VIDIOC-SUBDEV-G-FMT; for more information about the try formats.</para> | ||||
| 
 | ||||
|     <para>Sub-devices that support the frame interval enumeration ioctl should | ||||
|     implemented it on a single pad only. Its behaviour when supported on | ||||
|     multiple pads of the same sub-device is not defined.</para> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="v4l2-subdev-frame-interval-enum"> | ||||
|       <title>struct <structname>v4l2_subdev_frame_interval_enum</structname></title> | ||||
|       <tgroup cols="3"> | ||||
| 	&cs-str; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>index</structfield></entry> | ||||
| 	    <entry>Number of the format in the enumeration, set by the | ||||
| 	    application.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>pad</structfield></entry> | ||||
| 	    <entry>Pad number as reported by the media controller API.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>code</structfield></entry> | ||||
| 	    <entry>The media bus format code, as defined in | ||||
| 	    <xref linkend="v4l2-mbus-format" />.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>width</structfield></entry> | ||||
| 	    <entry>Frame width, in pixels.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>height</structfield></entry> | ||||
| 	    <entry>Frame height, in pixels.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>&v4l2-fract;</entry> | ||||
| 	    <entry><structfield>interval</structfield></entry> | ||||
| 	    <entry>Period, in seconds, between consecutive video frames.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>reserved</structfield>[9]</entry> | ||||
| 	    <entry>Reserved for future extensions. Applications and drivers must | ||||
| 	    set the array to zero.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     &return-value; | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EINVAL</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The &v4l2-subdev-frame-interval-enum; | ||||
| 	  <structfield>pad</structfield> references a non-existing pad, one of | ||||
| 	  the <structfield>code</structfield>, <structfield>width</structfield> | ||||
| 	  or <structfield>height</structfield> fields are invalid for the given | ||||
| 	  pad or the <structfield>index</structfield> field is out of bounds. | ||||
| 	  </para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										154
									
								
								Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,154 @@ | ||||
| <refentry id="vidioc-subdev-enum-frame-size"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_FRAME_SIZE</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</refname> | ||||
|     <refpurpose>Enumerate media bus frame sizes</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>struct v4l2_subdev_frame_size_enum * | ||||
| 	<parameter>argp</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>&fd;</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
| 
 | ||||
|     <note> | ||||
|       <title>Experimental</title> | ||||
|       <para>This is an <link linkend="experimental">experimental</link> | ||||
|       interface and may change in the future.</para> | ||||
|     </note> | ||||
| 
 | ||||
|     <para>This ioctl allows applications to enumerate all frame sizes | ||||
|     supported by a sub-device on the given pad for the given media bus format. | ||||
|     Supported formats can be retrieved with the &VIDIOC-SUBDEV-ENUM-MBUS-CODE; | ||||
|     ioctl.</para> | ||||
| 
 | ||||
|     <para>To enumerate frame sizes applications initialize the | ||||
|     <structfield>pad</structfield>, <structfield>code</structfield> and | ||||
|     <structfield>index</structfield> fields of the | ||||
|     &v4l2-subdev-mbus-code-enum; and call the | ||||
|     <constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant> ioctl with a pointer to | ||||
|     the structure. Drivers fill the minimum and maximum frame sizes or return | ||||
|     an &EINVAL; if one of the input parameters is invalid.</para> | ||||
| 
 | ||||
|     <para>Sub-devices that only support discrete frame sizes (such as most | ||||
|     sensors) will return one or more frame sizes with identical minimum and | ||||
|     maximum values.</para> | ||||
| 
 | ||||
|     <para>Not all possible sizes in given [minimum, maximum] ranges need to be | ||||
|     supported. For instance, a scaler that uses a fixed-point scaling ratio | ||||
|     might not be able to produce every frame size between the minimum and | ||||
|     maximum values. Applications must use the &VIDIOC-SUBDEV-S-FMT; ioctl to | ||||
|     try the sub-device for an exact supported frame size.</para> | ||||
| 
 | ||||
|     <para>Available frame sizes may depend on the current 'try' formats at other | ||||
|     pads of the sub-device, as well as on the current active links and the | ||||
|     current values of V4L2 controls. See &VIDIOC-SUBDEV-G-FMT; for more | ||||
|     information about try formats.</para> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="v4l2-subdev-frame-size-enum"> | ||||
|       <title>struct <structname>v4l2_subdev_frame_size_enum</structname></title> | ||||
|       <tgroup cols="3"> | ||||
| 	&cs-str; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>index</structfield></entry> | ||||
| 	    <entry>Number of the format in the enumeration, set by the | ||||
| 	    application.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>pad</structfield></entry> | ||||
| 	    <entry>Pad number as reported by the media controller API.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>code</structfield></entry> | ||||
| 	    <entry>The media bus format code, as defined in | ||||
| 	    <xref linkend="v4l2-mbus-format" />.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>min_width</structfield></entry> | ||||
| 	    <entry>Minimum frame width, in pixels.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>max_width</structfield></entry> | ||||
| 	    <entry>Maximum frame width, in pixels.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>min_height</structfield></entry> | ||||
| 	    <entry>Minimum frame height, in pixels.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>max_height</structfield></entry> | ||||
| 	    <entry>Maximum frame height, in pixels.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>reserved</structfield>[9]</entry> | ||||
| 	    <entry>Reserved for future extensions. Applications and drivers must | ||||
| 	    set the array to zero.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     &return-value; | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EINVAL</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The &v4l2-subdev-frame-size-enum; <structfield>pad</structfield> | ||||
| 	  references a non-existing pad, the <structfield>code</structfield> is | ||||
| 	  invalid for the given pad or the <structfield>index</structfield> | ||||
| 	  field is out of bounds.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										119
									
								
								Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,119 @@ | ||||
| <refentry id="vidioc-subdev-enum-mbus-code"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_MBUS_CODE</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>VIDIOC_SUBDEV_ENUM_MBUS_CODE</refname> | ||||
|     <refpurpose>Enumerate media bus formats</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>struct v4l2_subdev_mbus_code_enum * | ||||
| 	<parameter>argp</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>&fd;</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>VIDIOC_SUBDEV_ENUM_MBUS_CODE</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
| 
 | ||||
|     <note> | ||||
|       <title>Experimental</title> | ||||
|       <para>This is an <link linkend="experimental">experimental</link> | ||||
|       interface and may change in the future.</para> | ||||
|     </note> | ||||
| 
 | ||||
|     <para>To enumerate media bus formats available at a given sub-device pad | ||||
|     applications initialize the <structfield>pad</structfield> and | ||||
|     <structfield>index</structfield> fields of &v4l2-subdev-mbus-code-enum; and | ||||
|     call the <constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant> ioctl with a | ||||
|     pointer to this structure. Drivers fill the rest of the structure or return | ||||
|     an &EINVAL; if either the <structfield>pad</structfield> or | ||||
|     <structfield>index</structfield> are invalid. All media bus formats are | ||||
|     enumerable by beginning at index zero and incrementing by one until | ||||
|     <errorcode>EINVAL</errorcode> is returned.</para> | ||||
| 
 | ||||
|     <para>Available media bus formats may depend on the current 'try' formats | ||||
|     at other pads of the sub-device, as well as on the current active links. See | ||||
|     &VIDIOC-SUBDEV-G-FMT; for more information about the try formats.</para> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="v4l2-subdev-mbus-code-enum"> | ||||
|       <title>struct <structname>v4l2_subdev_mbus_code_enum</structname></title> | ||||
|       <tgroup cols="3"> | ||||
| 	&cs-str; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>pad</structfield></entry> | ||||
| 	    <entry>Pad number as reported by the media controller API.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>index</structfield></entry> | ||||
| 	    <entry>Number of the format in the enumeration, set by the | ||||
| 	    application.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>code</structfield></entry> | ||||
| 	    <entry>The media bus format code, as defined in | ||||
| 	    <xref linkend="v4l2-mbus-format" />.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>reserved</structfield>[9]</entry> | ||||
| 	    <entry>Reserved for future extensions. Applications and drivers must | ||||
| 	    set the array to zero.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     &return-value; | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EINVAL</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The &v4l2-subdev-mbus-code-enum; <structfield>pad</structfield> | ||||
| 	  references a non-existing pad, or the <structfield>index</structfield> | ||||
| 	  field is out of bounds.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										155
									
								
								Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,155 @@ | ||||
| <refentry id="vidioc-subdev-g-crop"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>ioctl VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>VIDIOC_SUBDEV_G_CROP</refname> | ||||
|     <refname>VIDIOC_SUBDEV_S_CROP</refname> | ||||
|     <refpurpose>Get or set the crop rectangle on a subdev pad</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>const struct v4l2_subdev_crop *<parameter>argp</parameter></paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>&fd;</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
| 
 | ||||
|     <note> | ||||
|       <title>Experimental</title> | ||||
|       <para>This is an <link linkend="experimental">experimental</link> | ||||
|       interface and may change in the future.</para> | ||||
|     </note> | ||||
| 
 | ||||
|     <para>To retrieve the current crop rectangle applications set the | ||||
|     <structfield>pad</structfield> field of a &v4l2-subdev-crop; to the | ||||
|     desired pad number as reported by the media API and the | ||||
|     <structfield>which</structfield> field to | ||||
|     <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. They then call the | ||||
|     <constant>VIDIOC_SUBDEV_G_CROP</constant> ioctl with a pointer to this | ||||
|     structure. The driver fills the members of the <structfield>rect</structfield> | ||||
|     field or returns &EINVAL; if the input arguments are invalid, or if cropping | ||||
|     is not supported on the given pad.</para> | ||||
| 
 | ||||
|     <para>To change the current crop rectangle applications set both the | ||||
|     <structfield>pad</structfield> and <structfield>which</structfield> fields | ||||
|     and all members of the <structfield>rect</structfield> field. They then call | ||||
|     the <constant>VIDIOC_SUBDEV_S_CROP</constant> ioctl with a pointer to this | ||||
|     structure. The driver verifies the requested crop rectangle, adjusts it | ||||
|     based on the hardware capabilities and configures the device. Upon return | ||||
|     the &v4l2-subdev-crop; contains the current format as would be returned | ||||
|     by a <constant>VIDIOC_SUBDEV_G_CROP</constant> call.</para> | ||||
| 
 | ||||
|     <para>Applications can query the device capabilities by setting the | ||||
|     <structfield>which</structfield> to | ||||
|     <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' crop | ||||
|     rectangles are not applied to the device by the driver, but are mangled | ||||
|     exactly as active crop rectangles and stored in the sub-device file handle. | ||||
|     Two applications querying the same sub-device would thus not interact with | ||||
|     each other.</para> | ||||
| 
 | ||||
|     <para>Drivers must not return an error solely because the requested crop | ||||
|     rectangle doesn't match the device capabilities. They must instead modify | ||||
|     the rectangle to match what the hardware can provide. The modified format | ||||
|     should be as close as possible to the original request.</para> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="v4l2-subdev-crop"> | ||||
|       <title>struct <structname>v4l2_subdev_crop</structname></title> | ||||
|       <tgroup cols="3"> | ||||
|         &cs-str; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>pad</structfield></entry> | ||||
| 	    <entry>Pad number as reported by the media framework.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>which</structfield></entry> | ||||
| 	    <entry>Crop rectangle to get or set, from | ||||
| 	    &v4l2-subdev-format-whence;.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>&v4l2-rect;</entry> | ||||
| 	    <entry><structfield>rect</structfield></entry> | ||||
| 	    <entry>Crop rectangle boundaries, in pixels.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>reserved</structfield>[8]</entry> | ||||
| 	    <entry>Reserved for future extensions. Applications and drivers must | ||||
| 	    set the array to zero.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     &return-value; | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EBUSY</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The crop rectangle can't be changed because the pad is currently | ||||
| 	  busy. This can be caused, for instance, by an active video stream on | ||||
| 	  the pad. The ioctl must not be retried without performing another | ||||
| 	  action to fix the problem first. Only returned by | ||||
| 	  <constant>VIDIOC_SUBDEV_S_CROP</constant></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EINVAL</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The &v4l2-subdev-crop; <structfield>pad</structfield> | ||||
| 	  references a non-existing pad, the <structfield>which</structfield> | ||||
| 	  field references a non-existing format, or cropping is not supported | ||||
| 	  on the given subdev pad.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										180
									
								
								Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,180 @@ | ||||
| <refentry id="vidioc-subdev-g-fmt"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>ioctl VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>VIDIOC_SUBDEV_G_FMT</refname> | ||||
|     <refname>VIDIOC_SUBDEV_S_FMT</refname> | ||||
|     <refpurpose>Get or set the data format on a subdev pad</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>struct v4l2_subdev_format *<parameter>argp</parameter> | ||||
| 	</paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>&fd;</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
| 
 | ||||
|     <note> | ||||
|       <title>Experimental</title> | ||||
|       <para>This is an <link linkend="experimental">experimental</link> | ||||
|       interface and may change in the future.</para> | ||||
|     </note> | ||||
| 
 | ||||
|     <para>These ioctls are used to negotiate the frame format at specific | ||||
|     subdev pads in the image pipeline.</para> | ||||
| 
 | ||||
|     <para>To retrieve the current format applications set the | ||||
|     <structfield>pad</structfield> field of a &v4l2-subdev-format; to the | ||||
|     desired pad number as reported by the media API and the | ||||
|     <structfield>which</structfield> field to | ||||
|     <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. When they call the | ||||
|     <constant>VIDIOC_SUBDEV_G_FMT</constant> ioctl with a pointer to this | ||||
|     structure the driver fills the members of the <structfield>format</structfield> | ||||
|     field.</para> | ||||
| 
 | ||||
|     <para>To change the current format applications set both the | ||||
|     <structfield>pad</structfield> and <structfield>which</structfield> fields | ||||
|     and all members of the <structfield>format</structfield> field. When they | ||||
|     call the <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl with a pointer to this | ||||
|     structure the driver verifies the requested format, adjusts it based on the | ||||
|     hardware capabilities and configures the device. Upon return the | ||||
|     &v4l2-subdev-format; contains the current format as would be returned by a | ||||
|     <constant>VIDIOC_SUBDEV_G_FMT</constant> call.</para> | ||||
| 
 | ||||
|     <para>Applications can query the device capabilities by setting the | ||||
|     <structfield>which</structfield> to | ||||
|     <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' formats are not | ||||
|     applied to the device by the driver, but are changed exactly as active | ||||
|     formats and stored in the sub-device file handle. Two applications querying | ||||
|     the same sub-device would thus not interact with each other.</para> | ||||
| 
 | ||||
|     <para>For instance, to try a format at the output pad of a sub-device, | ||||
|     applications would first set the try format at the sub-device input with the | ||||
|     <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl. They would then either | ||||
|     retrieve the default format at the output pad with the | ||||
|     <constant>VIDIOC_SUBDEV_G_FMT</constant> ioctl, or set the desired output | ||||
|     pad format with the <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl and check | ||||
|     the returned value.</para> | ||||
| 
 | ||||
|     <para>Try formats do not depend on active formats, but can depend on the | ||||
|     current links configuration or sub-device controls value. For instance, a | ||||
|     low-pass noise filter might crop pixels at the frame boundaries, modifying | ||||
|     its output frame size.</para> | ||||
| 
 | ||||
|     <para>Drivers must not return an error solely because the requested format | ||||
|     doesn't match the device capabilities. They must instead modify the format | ||||
|     to match what the hardware can provide. The modified format should be as | ||||
|     close as possible to the original request.</para> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="v4l2-subdev-format"> | ||||
|       <title>struct <structname>v4l2_subdev_format</structname></title> | ||||
|       <tgroup cols="3"> | ||||
|         &cs-str; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>pad</structfield></entry> | ||||
| 	    <entry>Pad number as reported by the media controller API.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>which</structfield></entry> | ||||
| 	    <entry>Format to modified, from &v4l2-subdev-format-whence;.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>&v4l2-mbus-framefmt;</entry> | ||||
| 	    <entry><structfield>format</structfield></entry> | ||||
| 	    <entry>Definition of an image format, see <xref | ||||
| 	    linkend="v4l2-mbus-framefmt" /> for details.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>reserved</structfield>[8]</entry> | ||||
| 	    <entry>Reserved for future extensions. Applications and drivers must | ||||
| 	    set the array to zero.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="v4l2-subdev-format-whence"> | ||||
|       <title>enum <structname>v4l2_subdev_format_whence</structname></title> | ||||
|       <tgroup cols="3"> | ||||
|         &cs-def; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>V4L2_SUBDEV_FORMAT_TRY</entry> | ||||
| 	    <entry>0</entry> | ||||
| 	    <entry>Try formats, used for querying device capabilities.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>V4L2_SUBDEV_FORMAT_ACTIVE</entry> | ||||
| 	    <entry>1</entry> | ||||
| 	    <entry>Active formats, applied to the hardware.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     &return-value; | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EBUSY</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The format can't be changed because the pad is currently busy. | ||||
| 	  This can be caused, for instance, by an active video stream on the | ||||
| 	  pad. The ioctl must not be retried without performing another action | ||||
| 	  to fix the problem first. Only returned by | ||||
| 	  <constant>VIDIOC_SUBDEV_S_FMT</constant></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EINVAL</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The &v4l2-subdev-format; <structfield>pad</structfield> | ||||
| 	  references a non-existing pad, or the <structfield>which</structfield> | ||||
| 	  field references a non-existing format.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
							
								
								
									
										141
									
								
								Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,141 @@ | ||||
| <refentry id="vidioc-subdev-g-frame-interval"> | ||||
|   <refmeta> | ||||
|     <refentrytitle>ioctl VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL</refentrytitle> | ||||
|     &manvol; | ||||
|   </refmeta> | ||||
| 
 | ||||
|   <refnamediv> | ||||
|     <refname>VIDIOC_SUBDEV_G_FRAME_INTERVAL</refname> | ||||
|     <refname>VIDIOC_SUBDEV_S_FRAME_INTERVAL</refname> | ||||
|     <refpurpose>Get or set the frame interval on a subdev pad</refpurpose> | ||||
|   </refnamediv> | ||||
| 
 | ||||
|   <refsynopsisdiv> | ||||
|     <funcsynopsis> | ||||
|       <funcprototype> | ||||
| 	<funcdef>int <function>ioctl</function></funcdef> | ||||
| 	<paramdef>int <parameter>fd</parameter></paramdef> | ||||
| 	<paramdef>int <parameter>request</parameter></paramdef> | ||||
| 	<paramdef>struct v4l2_subdev_frame_interval *<parameter>argp</parameter> | ||||
| 	</paramdef> | ||||
|       </funcprototype> | ||||
|     </funcsynopsis> | ||||
|   </refsynopsisdiv> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Arguments</title> | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>fd</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>&fd;</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>request</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para>VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><parameter>argp</parameter></term> | ||||
| 	<listitem> | ||||
| 	  <para></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     <title>Description</title> | ||||
| 
 | ||||
|     <note> | ||||
|       <title>Experimental</title> | ||||
|       <para>This is an <link linkend="experimental">experimental</link> | ||||
|       interface and may change in the future.</para> | ||||
|     </note> | ||||
| 
 | ||||
|     <para>These ioctls are used to get and set the frame interval at specific | ||||
|     subdev pads in the image pipeline. The frame interval only makes sense for | ||||
|     sub-devices that can control the frame period on their own. This includes, | ||||
|     for instance, image sensors and TV tuners. Sub-devices that don't support | ||||
|     frame intervals must not implement these ioctls.</para> | ||||
| 
 | ||||
|     <para>To retrieve the current frame interval applications set the | ||||
|     <structfield>pad</structfield> field of a &v4l2-subdev-frame-interval; to | ||||
|     the desired pad number as reported by the media controller API. When they | ||||
|     call the <constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant> ioctl with a | ||||
|     pointer to this structure the driver fills the members of the | ||||
|     <structfield>interval</structfield> field.</para> | ||||
| 
 | ||||
|     <para>To change the current frame interval applications set both the | ||||
|     <structfield>pad</structfield> field and all members of the | ||||
|     <structfield>interval</structfield> field. When they call the | ||||
|     <constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant> ioctl with a pointer to | ||||
|     this structure the driver verifies the requested interval, adjusts it based | ||||
|     on the hardware capabilities and configures the device. Upon return the | ||||
|     &v4l2-subdev-frame-interval; contains the current frame interval as would be | ||||
|     returned by a <constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant> call. | ||||
|     </para> | ||||
| 
 | ||||
|     <para>Drivers must not return an error solely because the requested interval | ||||
|     doesn't match the device capabilities. They must instead modify the interval | ||||
|     to match what the hardware can provide. The modified interval should be as | ||||
|     close as possible to the original request.</para> | ||||
| 
 | ||||
|     <para>Sub-devices that support the frame interval ioctls should implement | ||||
|     them on a single pad only. Their behaviour when supported on multiple pads | ||||
|     of the same sub-device is not defined.</para> | ||||
| 
 | ||||
|     <table pgwide="1" frame="none" id="v4l2-subdev-frame-interval"> | ||||
|       <title>struct <structname>v4l2_subdev_frame_interval</structname></title> | ||||
|       <tgroup cols="3"> | ||||
|         &cs-str; | ||||
| 	<tbody valign="top"> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>pad</structfield></entry> | ||||
| 	    <entry>Pad number as reported by the media controller API.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>&v4l2-fract;</entry> | ||||
| 	    <entry><structfield>interval</structfield></entry> | ||||
| 	    <entry>Period, in seconds, between consecutive video frames.</entry> | ||||
| 	  </row> | ||||
| 	  <row> | ||||
| 	    <entry>__u32</entry> | ||||
| 	    <entry><structfield>reserved</structfield>[9]</entry> | ||||
| 	    <entry>Reserved for future extensions. Applications and drivers must | ||||
| 	    set the array to zero.</entry> | ||||
| 	  </row> | ||||
| 	</tbody> | ||||
|       </tgroup> | ||||
|     </table> | ||||
|   </refsect1> | ||||
| 
 | ||||
|   <refsect1> | ||||
|     &return-value; | ||||
| 
 | ||||
|     <variablelist> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EBUSY</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The frame interval can't be changed because the pad is currently | ||||
| 	  busy. This can be caused, for instance, by an active video stream on | ||||
| 	  the pad. The ioctl must not be retried without performing another | ||||
| 	  action to fix the problem first. Only returned by | ||||
| 	  <constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|       <varlistentry> | ||||
| 	<term><errorcode>EINVAL</errorcode></term> | ||||
| 	<listitem> | ||||
| 	  <para>The &v4l2-subdev-frame-interval; <structfield>pad</structfield> | ||||
| 	  references a non-existing pad, or the pad doesn't support frame | ||||
| 	  intervals.</para> | ||||
| 	</listitem> | ||||
|       </varlistentry> | ||||
|     </variablelist> | ||||
|   </refsect1> | ||||
| </refentry> | ||||
| @ -556,6 +556,9 @@ sub ngene { | ||||
|     my $hash1 = "d798d5a757121174f0dbc5f2833c0c85"; | ||||
|     my $file2 = "ngene_17.fw"; | ||||
|     my $hash2 = "26b687136e127b8ac24b81e0eeafc20b"; | ||||
|     my $url2 = "http://l4m-daten.de/downloads/firmware/dvb-s2/linux/all/"; | ||||
|     my $file3 = "ngene_18.fw"; | ||||
|     my $hash3 = "ebce3ea769a53e3e0b0197c3b3f127e3"; | ||||
| 
 | ||||
|     checkstandard(); | ||||
| 
 | ||||
| @ -565,7 +568,10 @@ sub ngene { | ||||
|     wgetfile($file2, $url . $file2); | ||||
|     verify($file2, $hash2); | ||||
| 
 | ||||
|     "$file1, $file2"; | ||||
|     wgetfile($file3, $url2 . $file3); | ||||
|     verify($file3, $hash3); | ||||
| 
 | ||||
|     "$file1, $file2, $file3"; | ||||
| } | ||||
| 
 | ||||
| sub az6027{ | ||||
|  | ||||
| @ -4,7 +4,7 @@ following file(s) to this directory. | ||||
| for DM04+/QQBOX LME2510C (Sharp 7395 Tuner) | ||||
| ------------------------------------------- | ||||
| 
 | ||||
| The Sharp 7395 driver can be found in windows/system32/driver | ||||
| The Sharp 7395 driver can be found in windows/system32/drivers | ||||
| 
 | ||||
| US2A0D.sys (dated 17 Mar 2009) | ||||
| 
 | ||||
| @ -44,7 +44,7 @@ and run | ||||
| 
 | ||||
| 
 | ||||
| Other LG firmware can be extracted manually from US280D.sys | ||||
| only found in windows/system32/driver. | ||||
| only found in windows/system32/drivers | ||||
| 
 | ||||
| dd if=US280D.sys ibs=1 skip=42360 count=3924 of=dvb-usb-lme2510-lg.fw | ||||
| 
 | ||||
| @ -55,4 +55,16 @@ dd if=US280D.sys ibs=1 skip=35200 count=3850 of=dvb-usb-lme2510c-lg.fw | ||||
| 
 | ||||
| --------------------------------------------------------------------- | ||||
| 
 | ||||
| The Sharp 0194 tuner driver can be found in windows/system32/drivers | ||||
| 
 | ||||
| US290D.sys (dated 09 Apr 2009) | ||||
| 
 | ||||
| For LME2510 | ||||
| dd if=US290D.sys ibs=1 skip=36856 count=3976 of=dvb-usb-lme2510-s0194.fw | ||||
| 
 | ||||
| 
 | ||||
| For LME2510C | ||||
| dd if=US290D.sys ibs=1 skip=33152 count=3697 of=dvb-usb-lme2510c-s0194.fw | ||||
| 
 | ||||
| 
 | ||||
| Copy the firmware file(s) to /lib/firmware | ||||
|  | ||||
| @ -108,42 +108,6 @@ Who:	Pavel Machek <pavel@ucw.cz> | ||||
| 
 | ||||
| --------------------------- | ||||
| 
 | ||||
| What:	Video4Linux obsolete drivers using V4L1 API | ||||
| When:	kernel 2.6.39 | ||||
| Files:	drivers/staging/se401/* drivers/staging/usbvideo/* | ||||
| Check:	drivers/staging/se401/se401.c drivers/staging/usbvideo/usbvideo.c | ||||
| Why:	There are some drivers still using V4L1 API, despite all efforts we've done | ||||
| 	to migrate. Those drivers are for obsolete hardware that the old maintainer | ||||
| 	didn't care (or not have the hardware anymore), and that no other developer | ||||
| 	could find any hardware to buy. They probably have no practical usage today, | ||||
| 	and people with such old hardware could probably keep using an older version | ||||
| 	of the kernel. Those drivers will be moved to staging on 2.6.38 and, if nobody | ||||
| 	cares enough to port and test them with V4L2 API, they'll be removed on 2.6.39. | ||||
| Who:	Mauro Carvalho Chehab <mchehab@infradead.org> | ||||
| 
 | ||||
| --------------------------- | ||||
| 
 | ||||
| What:	Video4Linux: Remove obsolete ioctl's | ||||
| When:	kernel 2.6.39 | ||||
| Files:	include/media/videodev2.h | ||||
| Why:	Some ioctl's were defined wrong on 2.6.2 and 2.6.6, using the wrong | ||||
| 	type of R/W arguments. They were fixed, but the old ioctl names are | ||||
| 	still there, maintained to avoid breaking binary compatibility: | ||||
| 	  #define VIDIOC_OVERLAY_OLD   	_IOWR('V', 14, int) | ||||
| 	  #define VIDIOC_S_PARM_OLD	_IOW('V', 22, struct v4l2_streamparm) | ||||
| 	  #define VIDIOC_S_CTRL_OLD	_IOW('V', 28, struct v4l2_control) | ||||
| 	  #define VIDIOC_G_AUDIO_OLD	_IOWR('V', 33, struct v4l2_audio) | ||||
| 	  #define VIDIOC_G_AUDOUT_OLD	_IOWR('V', 49, struct v4l2_audioout) | ||||
| 	  #define VIDIOC_CROPCAP_OLD	_IOR('V', 58, struct v4l2_cropcap) | ||||
| 	There's no sense on preserving those forever, as it is very doubtful | ||||
| 	that someone would try to use a such old binary with a modern kernel. | ||||
| 	Removing them will allow us to remove some magic done at the V4L ioctl | ||||
| 	handler. | ||||
| 
 | ||||
| Who:	Mauro Carvalho Chehab <mchehab@infradead.org> | ||||
| 
 | ||||
| --------------------------- | ||||
| 
 | ||||
| What:	sys_sysctl | ||||
| When:	September 2010 | ||||
| Option: CONFIG_SYSCTL_SYSCALL | ||||
|  | ||||
| @ -273,6 +273,7 @@ Code  Seq#(hex)	Include File		Comments | ||||
| 'z'	40-7F				CAN bus card	conflict! | ||||
| 					<mailto:oe@port.de> | ||||
| 'z'	10-4F	drivers/s390/crypto/zcrypt_api.h	conflict! | ||||
| '|'	00-7F	linux/media.h | ||||
| 0x80	00-1F	linux/fb.h | ||||
| 0x89	00-06	arch/x86/include/asm/sockios.h | ||||
| 0x89	0B-DF	linux/sockios.h | ||||
|  | ||||
							
								
								
									
										353
									
								
								Documentation/media-framework.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										353
									
								
								Documentation/media-framework.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,353 @@ | ||||
| Linux kernel media framework | ||||
| ============================ | ||||
| 
 | ||||
| This document describes the Linux kernel media framework, its data structures, | ||||
| functions and their usage. | ||||
| 
 | ||||
| 
 | ||||
| Introduction | ||||
| ------------ | ||||
| 
 | ||||
| The media controller API is documented in DocBook format in | ||||
| Documentation/DocBook/v4l/media-controller.xml. This document will focus on | ||||
| the kernel-side implementation of the media framework. | ||||
| 
 | ||||
| 
 | ||||
| Abstract media device model | ||||
| --------------------------- | ||||
| 
 | ||||
| Discovering a device internal topology, and configuring it at runtime, is one | ||||
| of the goals of the media framework. To achieve this, hardware devices are | ||||
| modeled as an oriented graph of building blocks called entities connected | ||||
| through pads. | ||||
| 
 | ||||
| An entity is a basic media hardware building block. It can correspond to | ||||
| a large variety of logical blocks such as physical hardware devices | ||||
| (CMOS sensor for instance), logical hardware devices (a building block | ||||
| in a System-on-Chip image processing pipeline), DMA channels or physical | ||||
| connectors. | ||||
| 
 | ||||
| A pad is a connection endpoint through which an entity can interact with | ||||
| other entities. Data (not restricted to video) produced by an entity | ||||
| flows from the entity's output to one or more entity inputs. Pads should | ||||
| not be confused with physical pins at chip boundaries. | ||||
| 
 | ||||
| A link is a point-to-point oriented connection between two pads, either | ||||
| on the same entity or on different entities. Data flows from a source | ||||
| pad to a sink pad. | ||||
| 
 | ||||
| 
 | ||||
| Media device | ||||
| ------------ | ||||
| 
 | ||||
| A media device is represented by a struct media_device instance, defined in | ||||
| include/media/media-device.h. Allocation of the structure is handled by the | ||||
| media device driver, usually by embedding the media_device instance in a | ||||
| larger driver-specific structure. | ||||
| 
 | ||||
| Drivers register media device instances by calling | ||||
| 
 | ||||
| 	media_device_register(struct media_device *mdev); | ||||
| 
 | ||||
| The caller is responsible for initializing the media_device structure before | ||||
| registration. The following fields must be set: | ||||
| 
 | ||||
|  - dev must point to the parent device (usually a pci_dev, usb_interface or | ||||
|    platform_device instance). | ||||
| 
 | ||||
|  - model must be filled with the device model name as a NUL-terminated UTF-8 | ||||
|    string. The device/model revision must not be stored in this field. | ||||
| 
 | ||||
| The following fields are optional: | ||||
| 
 | ||||
|  - serial is a unique serial number stored as a NUL-terminated ASCII string. | ||||
|    The field is big enough to store a GUID in text form. If the hardware | ||||
|    doesn't provide a unique serial number this field must be left empty. | ||||
| 
 | ||||
|  - bus_info represents the location of the device in the system as a | ||||
|    NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to | ||||
|    "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, | ||||
|    the usb_make_path() function must be used. This field is used by | ||||
|    applications to distinguish between otherwise identical devices that don't | ||||
|    provide a serial number. | ||||
| 
 | ||||
|  - hw_revision is the hardware device revision in a driver-specific format. | ||||
|    When possible the revision should be formatted with the KERNEL_VERSION | ||||
|    macro. | ||||
| 
 | ||||
|  - driver_version is formatted with the KERNEL_VERSION macro. The version | ||||
|    minor must be incremented when new features are added to the userspace API | ||||
|    without breaking binary compatibility. The version major must be | ||||
|    incremented when binary compatibility is broken. | ||||
| 
 | ||||
| Upon successful registration a character device named media[0-9]+ is created. | ||||
| The device major and minor numbers are dynamic. The model name is exported as | ||||
| a sysfs attribute. | ||||
| 
 | ||||
| Drivers unregister media device instances by calling | ||||
| 
 | ||||
| 	media_device_unregister(struct media_device *mdev); | ||||
| 
 | ||||
| Unregistering a media device that hasn't been registered is *NOT* safe. | ||||
| 
 | ||||
| 
 | ||||
| Entities, pads and links | ||||
| ------------------------ | ||||
| 
 | ||||
| - Entities | ||||
| 
 | ||||
| Entities are represented by a struct media_entity instance, defined in | ||||
| include/media/media-entity.h. The structure is usually embedded into a | ||||
| higher-level structure, such as a v4l2_subdev or video_device instance, | ||||
| although drivers can allocate entities directly. | ||||
| 
 | ||||
| Drivers initialize entities by calling | ||||
| 
 | ||||
| 	media_entity_init(struct media_entity *entity, u16 num_pads, | ||||
| 			  struct media_pad *pads, u16 extra_links); | ||||
| 
 | ||||
| The media_entity name, type, flags, revision and group_id fields can be | ||||
| initialized before or after calling media_entity_init. Entities embedded in | ||||
| higher-level standard structures can have some of those fields set by the | ||||
| higher-level framework. | ||||
| 
 | ||||
| As the number of pads is known in advance, the pads array is not allocated | ||||
| dynamically but is managed by the entity driver. Most drivers will embed the | ||||
| pads array in a driver-specific structure, avoiding dynamic allocation. | ||||
| 
 | ||||
| Drivers must set the direction of every pad in the pads array before calling | ||||
| media_entity_init. The function will initialize the other pads fields. | ||||
| 
 | ||||
| Unlike the number of pads, the total number of links isn't always known in | ||||
| advance by the entity driver. As an initial estimate, media_entity_init | ||||
| pre-allocates a number of links equal to the number of pads plus an optional | ||||
| number of extra links. The links array will be reallocated if it grows beyond | ||||
| the initial estimate. | ||||
| 
 | ||||
| Drivers register entities with a media device by calling | ||||
| 
 | ||||
| 	media_device_register_entity(struct media_device *mdev, | ||||
| 				     struct media_entity *entity); | ||||
| 
 | ||||
| Entities are identified by a unique positive integer ID. Drivers can provide an | ||||
| ID by filling the media_entity id field prior to registration, or request the | ||||
| media controller framework to assign an ID automatically. Drivers that provide | ||||
| IDs manually must ensure that all IDs are unique. IDs are not guaranteed to be | ||||
| contiguous even when they are all assigned automatically by the framework. | ||||
| 
 | ||||
| Drivers unregister entities by calling | ||||
| 
 | ||||
| 	media_device_unregister_entity(struct media_entity *entity); | ||||
| 
 | ||||
| Unregistering an entity will not change the IDs of the other entities, and the | ||||
| ID will never be reused for a newly registered entity. | ||||
| 
 | ||||
| When a media device is unregistered, all its entities are unregistered | ||||
| automatically. No manual entities unregistration is then required. | ||||
| 
 | ||||
| Drivers free resources associated with an entity by calling | ||||
| 
 | ||||
| 	media_entity_cleanup(struct media_entity *entity); | ||||
| 
 | ||||
| This function must be called during the cleanup phase after unregistering the | ||||
| entity. Note that the media_entity instance itself must be freed explicitly by | ||||
| the driver if required. | ||||
| 
 | ||||
| Entities have flags that describe the entity capabilities and state. | ||||
| 
 | ||||
| 	MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. | ||||
| 	This can be used to report the default audio and video devices or the | ||||
| 	default camera sensor. | ||||
| 
 | ||||
| Logical entity groups can be defined by setting the group ID of all member | ||||
| entities to the same non-zero value. An entity group serves no purpose in the | ||||
| kernel, but is reported to userspace during entities enumeration. The group_id | ||||
| field belongs to the media device driver and must not by touched by entity | ||||
| drivers. | ||||
| 
 | ||||
| Media device drivers should define groups if several entities are logically | ||||
| bound together. Example usages include reporting | ||||
| 
 | ||||
| 	- ALSA, VBI and video nodes that carry the same media stream | ||||
| 	- lens and flash controllers associated with a sensor | ||||
| 
 | ||||
| - Pads | ||||
| 
 | ||||
| Pads are represented by a struct media_pad instance, defined in | ||||
| include/media/media-entity.h. Each entity stores its pads in a pads array | ||||
| managed by the entity driver. Drivers usually embed the array in a | ||||
| driver-specific structure. | ||||
| 
 | ||||
| Pads are identified by their entity and their 0-based index in the pads array. | ||||
| Both information are stored in the media_pad structure, making the media_pad | ||||
| pointer the canonical way to store and pass link references. | ||||
| 
 | ||||
| Pads have flags that describe the pad capabilities and state. | ||||
| 
 | ||||
| 	MEDIA_PAD_FL_SINK indicates that the pad supports sinking data. | ||||
| 	MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data. | ||||
| 
 | ||||
| One and only one of MEDIA_PAD_FL_SINK and MEDIA_PAD_FL_SOURCE must be set for | ||||
| each pad. | ||||
| 
 | ||||
| - Links | ||||
| 
 | ||||
| Links are represented by a struct media_link instance, defined in | ||||
| include/media/media-entity.h. Each entity stores all links originating at or | ||||
| targetting any of its pads in a links array. A given link is thus stored | ||||
| twice, once in the source entity and once in the target entity. The array is | ||||
| pre-allocated and grows dynamically as needed. | ||||
| 
 | ||||
| Drivers create links by calling | ||||
| 
 | ||||
| 	media_entity_create_link(struct media_entity *source, u16 source_pad, | ||||
| 				 struct media_entity *sink,   u16 sink_pad, | ||||
| 				 u32 flags); | ||||
| 
 | ||||
| An entry in the link array of each entity is allocated and stores pointers | ||||
| to source and sink pads. | ||||
| 
 | ||||
| Links have flags that describe the link capabilities and state. | ||||
| 
 | ||||
| 	MEDIA_LNK_FL_ENABLED indicates that the link is enabled and can be used | ||||
| 	to transfer media data. When two or more links target a sink pad, only | ||||
| 	one of them can be enabled at a time. | ||||
| 	MEDIA_LNK_FL_IMMUTABLE indicates that the link enabled state can't be | ||||
| 	modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then | ||||
| 	MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always | ||||
| 	enabled. | ||||
| 
 | ||||
| 
 | ||||
| Graph traversal | ||||
| --------------- | ||||
| 
 | ||||
| The media framework provides APIs to iterate over entities in a graph. | ||||
| 
 | ||||
| To iterate over all entities belonging to a media device, drivers can use the | ||||
| media_device_for_each_entity macro, defined in include/media/media-device.h. | ||||
| 
 | ||||
| 	struct media_entity *entity; | ||||
| 
 | ||||
| 	media_device_for_each_entity(entity, mdev) { | ||||
| 		/* entity will point to each entity in turn */ | ||||
| 		... | ||||
| 	} | ||||
| 
 | ||||
| Drivers might also need to iterate over all entities in a graph that can be | ||||
| reached only through enabled links starting at a given entity. The media | ||||
| framework provides a depth-first graph traversal API for that purpose. | ||||
| 
 | ||||
| Note that graphs with cycles (whether directed or undirected) are *NOT* | ||||
| supported by the graph traversal API. To prevent infinite loops, the graph | ||||
| traversal code limits the maximum depth to MEDIA_ENTITY_ENUM_MAX_DEPTH, | ||||
| currently defined as 16. | ||||
| 
 | ||||
| Drivers initiate a graph traversal by calling | ||||
| 
 | ||||
| 	media_entity_graph_walk_start(struct media_entity_graph *graph, | ||||
| 				      struct media_entity *entity); | ||||
| 
 | ||||
| The graph structure, provided by the caller, is initialized to start graph | ||||
| traversal at the given entity. | ||||
| 
 | ||||
| Drivers can then retrieve the next entity by calling | ||||
| 
 | ||||
| 	media_entity_graph_walk_next(struct media_entity_graph *graph); | ||||
| 
 | ||||
| When the graph traversal is complete the function will return NULL. | ||||
| 
 | ||||
| Graph traversal can be interrupted at any moment. No cleanup function call is | ||||
| required and the graph structure can be freed normally. | ||||
| 
 | ||||
| Helper functions can be used to find a link between two given pads, or a pad | ||||
| connected to another pad through an enabled link | ||||
| 
 | ||||
| 	media_entity_find_link(struct media_pad *source, | ||||
| 			       struct media_pad *sink); | ||||
| 
 | ||||
| 	media_entity_remote_source(struct media_pad *pad); | ||||
| 
 | ||||
| Refer to the kerneldoc documentation for more information. | ||||
| 
 | ||||
| 
 | ||||
| Use count and power handling | ||||
| ---------------------------- | ||||
| 
 | ||||
| Due to the wide differences between drivers regarding power management needs, | ||||
| the media controller does not implement power management. However, the | ||||
| media_entity structure includes a use_count field that media drivers can use to | ||||
| track the number of users of every entity for power management needs. | ||||
| 
 | ||||
| The use_count field is owned by media drivers and must not be touched by entity | ||||
| drivers. Access to the field must be protected by the media device graph_mutex | ||||
| lock. | ||||
| 
 | ||||
| 
 | ||||
| Links setup | ||||
| ----------- | ||||
| 
 | ||||
| Link properties can be modified at runtime by calling | ||||
| 
 | ||||
| 	media_entity_setup_link(struct media_link *link, u32 flags); | ||||
| 
 | ||||
| The flags argument contains the requested new link flags. | ||||
| 
 | ||||
| The only configurable property is the ENABLED link flag to enable/disable a | ||||
| link. Links marked with the IMMUTABLE link flag can not be enabled or disabled. | ||||
| 
 | ||||
| When a link is enabled or disabled, the media framework calls the | ||||
| link_setup operation for the two entities at the source and sink of the link, | ||||
| in that order. If the second link_setup call fails, another link_setup call is | ||||
| made on the first entity to restore the original link flags. | ||||
| 
 | ||||
| Media device drivers can be notified of link setup operations by setting the | ||||
| media_device::link_notify pointer to a callback function. If provided, the | ||||
| notification callback will be called before enabling and after disabling | ||||
| links. | ||||
| 
 | ||||
| Entity drivers must implement the link_setup operation if any of their links | ||||
| is non-immutable. The operation must either configure the hardware or store | ||||
| the configuration information to be applied later. | ||||
| 
 | ||||
| Link configuration must not have any side effect on other links. If an enabled | ||||
| link at a sink pad prevents another link at the same pad from being disabled, | ||||
| the link_setup operation must return -EBUSY and can't implicitly disable the | ||||
| first enabled link. | ||||
| 
 | ||||
| 
 | ||||
| Pipelines and media streams | ||||
| --------------------------- | ||||
| 
 | ||||
| When starting streaming, drivers must notify all entities in the pipeline to | ||||
| prevent link states from being modified during streaming by calling | ||||
| 
 | ||||
| 	media_entity_pipeline_start(struct media_entity *entity, | ||||
| 				    struct media_pipeline *pipe); | ||||
| 
 | ||||
| The function will mark all entities connected to the given entity through | ||||
| enabled links, either directly or indirectly, as streaming. | ||||
| 
 | ||||
| The media_pipeline instance pointed to by the pipe argument will be stored in | ||||
| every entity in the pipeline. Drivers should embed the media_pipeline structure | ||||
| in higher-level pipeline structures and can then access the pipeline through | ||||
| the media_entity pipe field. | ||||
| 
 | ||||
| Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must | ||||
| be identical for all nested calls to the function. | ||||
| 
 | ||||
| When stopping the stream, drivers must notify the entities with | ||||
| 
 | ||||
| 	media_entity_pipeline_stop(struct media_entity *entity); | ||||
| 
 | ||||
| If multiple calls to media_entity_pipeline_start() have been made the same | ||||
| number of media_entity_pipeline_stop() calls are required to stop streaming. The | ||||
| media_entity pipe field is reset to NULL on the last nested stop call. | ||||
| 
 | ||||
| Link configuration will fail with -EBUSY by default if either end of the link is | ||||
| a streaming entity. Links that can be modified while streaming must be marked | ||||
| with the MEDIA_LNK_FL_DYNAMIC flag. | ||||
| 
 | ||||
| If other operations need to be disallowed on streaming entities (such as | ||||
| changing entities configuration parameters) drivers can explictly check the | ||||
| media_entity stream_count field to find out if an entity is streaming. This | ||||
| operation must be done with the media_device graph_mutex held. | ||||
| @ -36,8 +36,7 @@ Additional features for the PVR-350 (CX23415 based): | ||||
|  * Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the | ||||
|    video signal) | ||||
|  * Provides a framebuffer (allowing X applications to appear on the video | ||||
|    device) (this framebuffer is not yet part of the kernel. In the meantime it | ||||
|    is available from www.ivtvdriver.org). | ||||
|    device) | ||||
|  * Supports raw YUV output. | ||||
| 
 | ||||
| IMPORTANT: In case of problems first read this page: | ||||
|  | ||||
| @ -103,6 +103,7 @@ spca561		046d:092d	Logitech QC Elch2 | ||||
| spca561		046d:092e	Logitech QC Elch2 | ||||
| spca561		046d:092f	Logitech QuickCam Express Plus | ||||
| sunplus		046d:0960	Logitech ClickSmart 420 | ||||
| nw80x		046d:d001	Logitech QuickCam Pro (dark focus ring) | ||||
| sunplus		0471:0322	Philips DMVC1300K | ||||
| zc3xx		0471:0325	Philips SPC 200 NC | ||||
| zc3xx		0471:0326	Philips SPC 300 NC | ||||
| @ -150,10 +151,12 @@ sunplus		04fc:5330	Digitrex 2110 | ||||
| sunplus		04fc:5360	Sunplus Generic | ||||
| spca500		04fc:7333	PalmPixDC85 | ||||
| sunplus		04fc:ffff	Pure DigitalDakota | ||||
| nw80x		0502:d001	DVC V6 | ||||
| spca501		0506:00df	3Com HomeConnect Lite | ||||
| sunplus		052b:1507	Megapixel 5 Pretec DC-1007 | ||||
| sunplus		052b:1513	Megapix V4 | ||||
| sunplus		052b:1803	MegaImage VI | ||||
| nw80x		052b:d001	EZCam Pro p35u | ||||
| tv8532		0545:808b	Veo Stingray | ||||
| tv8532		0545:8333	Veo Stingray | ||||
| sunplus		0546:3155	Polaroid PDC3070 | ||||
| @ -177,6 +180,7 @@ sunplus		055f:c530	Mustek Gsmart LCD 3 | ||||
| sunplus		055f:c540	Gsmart D30 | ||||
| sunplus		055f:c630	Mustek MDC4000 | ||||
| sunplus		055f:c650	Mustek MDC5500Z | ||||
| nw80x		055f:d001	Mustek Wcam 300 mini | ||||
| zc3xx		055f:d003	Mustek WCam300A | ||||
| zc3xx		055f:d004	Mustek WCam300 AN | ||||
| conex		0572:0041	Creative Notebook cx11646 | ||||
| @ -195,14 +199,20 @@ gl860		05e3:0503	Genesys Logic PC Camera | ||||
| gl860		05e3:f191	Genesys Logic PC Camera | ||||
| spca561		060b:a001	Maxell Compact Pc PM3 | ||||
| zc3xx		0698:2003	CTX M730V built in | ||||
| nw80x		06a5:0000	Typhoon Webcam 100 USB | ||||
| nw80x		06a5:d001	Divio based webcams | ||||
| nw80x		06a5:d800	Divio Chicony TwinkleCam, Trust SpaceCam | ||||
| spca500		06bd:0404	Agfa CL20 | ||||
| spca500		06be:0800	Optimedia | ||||
| nw80x		06be:d001	EZCam Pro p35u | ||||
| sunplus		06d6:0031	Trust 610 LCD PowerC@m Zoom | ||||
| spca506		06e1:a190	ADS Instant VCD | ||||
| ov534		06f8:3002	Hercules Blog Webcam | ||||
| ov534_9		06f8:3003	Hercules Dualpix HD Weblog | ||||
| sonixj		06f8:3004	Hercules Classic Silver | ||||
| sonixj		06f8:3008	Hercules Deluxe Optical Glass | ||||
| pac7302		06f8:3009	Hercules Classic Link | ||||
| nw80x		0728:d001	AVerMedia Camguard | ||||
| spca508		0733:0110	ViewQuest VQ110 | ||||
| spca501		0733:0401	Intel Create and Share | ||||
| spca501		0733:0402	ViewQuest M318B | ||||
|  | ||||
							
								
								
									
										278
									
								
								Documentation/video4linux/omap3isp.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								Documentation/video4linux/omap3isp.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,278 @@ | ||||
| OMAP 3 Image Signal Processor (ISP) driver | ||||
| 
 | ||||
| Copyright (C) 2010 Nokia Corporation | ||||
| Copyright (C) 2009 Texas Instruments, Inc. | ||||
| 
 | ||||
| Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||||
| 	  Sakari Ailus <sakari.ailus@iki.fi> | ||||
| 	  David Cohen <dacohen@gmail.com> | ||||
| 
 | ||||
| 
 | ||||
| Introduction | ||||
| ============ | ||||
| 
 | ||||
| This file documents the Texas Instruments OMAP 3 Image Signal Processor (ISP) | ||||
| driver located under drivers/media/video/omap3isp. The original driver was | ||||
| written by Texas Instruments but since that it has been rewritten (twice) at | ||||
| Nokia. | ||||
| 
 | ||||
| The driver has been successfully used on the following versions of OMAP 3: | ||||
| 
 | ||||
| 	3430 | ||||
| 	3530 | ||||
| 	3630 | ||||
| 
 | ||||
| The driver implements V4L2, Media controller and v4l2_subdev interfaces. | ||||
| Sensor, lens and flash drivers using the v4l2_subdev interface in the kernel | ||||
| are supported. | ||||
| 
 | ||||
| 
 | ||||
| Split to subdevs | ||||
| ================ | ||||
| 
 | ||||
| The OMAP 3 ISP is split into V4L2 subdevs, each of the blocks inside the ISP | ||||
| having one subdev to represent it. Each of the subdevs provide a V4L2 subdev | ||||
| interface to userspace. | ||||
| 
 | ||||
| 	OMAP3 ISP CCP2 | ||||
| 	OMAP3 ISP CSI2a | ||||
| 	OMAP3 ISP CCDC | ||||
| 	OMAP3 ISP preview | ||||
| 	OMAP3 ISP resizer | ||||
| 	OMAP3 ISP AEWB | ||||
| 	OMAP3 ISP AF | ||||
| 	OMAP3 ISP histogram | ||||
| 
 | ||||
| Each possible link in the ISP is modelled by a link in the Media controller | ||||
| interface. For an example program see [2]. | ||||
| 
 | ||||
| 
 | ||||
| Controlling the OMAP 3 ISP | ||||
| ========================== | ||||
| 
 | ||||
| In general, the settings given to the OMAP 3 ISP take effect at the beginning | ||||
| of the following frame. This is done when the module becomes idle during the | ||||
| vertical blanking period on the sensor. In memory-to-memory operation the pipe | ||||
| is run one frame at a time. Applying the settings is done between the frames. | ||||
| 
 | ||||
| All the blocks in the ISP, excluding the CSI-2 and possibly the CCP2 receiver, | ||||
| insist on receiving complete frames. Sensors must thus never send the ISP | ||||
| partial frames. | ||||
| 
 | ||||
| Autoidle does have issues with some ISP blocks on the 3430, at least. | ||||
| Autoidle is only enabled on 3630 when the omap3isp module parameter autoidle | ||||
| is non-zero. | ||||
| 
 | ||||
| 
 | ||||
| Events | ||||
| ====== | ||||
| 
 | ||||
| The OMAP 3 ISP driver does support the V4L2 event interface on CCDC and | ||||
| statistics (AEWB, AF and histogram) subdevs. | ||||
| 
 | ||||
| The CCDC subdev produces V4L2_EVENT_OMAP3ISP_HS_VS type event on HS_VS | ||||
| interrupt which is used to signal frame start. The event is triggered exactly | ||||
| when the reception of the first line of the frame starts in the CCDC module. | ||||
| The event can be subscribed on the CCDC subdev. | ||||
| 
 | ||||
| (When using parallel interface one must pay account to correct configuration | ||||
| of the VS signal polarity. This is automatically correct when using the serial | ||||
| receivers.) | ||||
| 
 | ||||
| Each of the statistics subdevs is able to produce events. An event is | ||||
| generated whenever a statistics buffer can be dequeued by a user space | ||||
| application using the VIDIOC_OMAP3ISP_STAT_REQ IOCTL. The events available | ||||
| are: | ||||
| 
 | ||||
| 	V4L2_EVENT_OMAP3ISP_AEWB | ||||
| 	V4L2_EVENT_OMAP3ISP_AF | ||||
| 	V4L2_EVENT_OMAP3ISP_HIST | ||||
| 
 | ||||
| The type of the event data is struct omap3isp_stat_event_status for these | ||||
| ioctls. If there is an error calculating the statistics, there will be an | ||||
| event as usual, but no related statistics buffer. In this case | ||||
| omap3isp_stat_event_status.buf_err is set to non-zero. | ||||
| 
 | ||||
| 
 | ||||
| Private IOCTLs | ||||
| ============== | ||||
| 
 | ||||
| The OMAP 3 ISP driver supports standard V4L2 IOCTLs and controls where | ||||
| possible and practical. Much of the functions provided by the ISP, however, | ||||
| does not fall under the standard IOCTLs --- gamma tables and configuration of | ||||
| statistics collection are examples of such. | ||||
| 
 | ||||
| In general, there is a private ioctl for configuring each of the blocks | ||||
| containing hardware-dependent functions. | ||||
| 
 | ||||
| The following private IOCTLs are supported: | ||||
| 
 | ||||
| 	VIDIOC_OMAP3ISP_CCDC_CFG | ||||
| 	VIDIOC_OMAP3ISP_PRV_CFG | ||||
| 	VIDIOC_OMAP3ISP_AEWB_CFG | ||||
| 	VIDIOC_OMAP3ISP_HIST_CFG | ||||
| 	VIDIOC_OMAP3ISP_AF_CFG | ||||
| 	VIDIOC_OMAP3ISP_STAT_REQ | ||||
| 	VIDIOC_OMAP3ISP_STAT_EN | ||||
| 
 | ||||
| The parameter structures used by these ioctls are described in | ||||
| include/linux/omap3isp.h. The detailed functions of the ISP itself related to | ||||
| a given ISP block is described in the Technical Reference Manuals (TRMs) --- | ||||
| see the end of the document for those. | ||||
| 
 | ||||
| While it is possible to use the ISP driver without any use of these private | ||||
| IOCTLs it is not possible to obtain optimal image quality this way. The AEWB, | ||||
| AF and histogram modules cannot be used without configuring them using the | ||||
| appropriate private IOCTLs. | ||||
| 
 | ||||
| 
 | ||||
| CCDC and preview block IOCTLs | ||||
| ============================= | ||||
| 
 | ||||
| The VIDIOC_OMAP3ISP_CCDC_CFG and VIDIOC_OMAP3ISP_PRV_CFG IOCTLs are used to | ||||
| configure, enable and disable functions in the CCDC and preview blocks, | ||||
| respectively. Both IOCTLs control several functions in the blocks they | ||||
| control. VIDIOC_OMAP3ISP_CCDC_CFG IOCTL accepts a pointer to struct | ||||
| omap3isp_ccdc_update_config as its argument. Similarly VIDIOC_OMAP3ISP_PRV_CFG | ||||
| accepts a pointer to struct omap3isp_prev_update_config. The definition of | ||||
| both structures is available in [1]. | ||||
| 
 | ||||
| The update field in the structures tells whether to update the configuration | ||||
| for the specific function and the flag tells whether to enable or disable the | ||||
| function. | ||||
| 
 | ||||
| The update and flag bit masks accept the following values. Each separate | ||||
| functions in the CCDC and preview blocks is associated with a flag (either | ||||
| disable or enable; part of the flag field in the structure) and a pointer to | ||||
| configuration data for the function. | ||||
| 
 | ||||
| Valid values for the update and flag fields are listed here for | ||||
| VIDIOC_OMAP3ISP_CCDC_CFG. Values may be or'ed to configure more than one | ||||
| function in the same IOCTL call. | ||||
| 
 | ||||
|         OMAP3ISP_CCDC_ALAW | ||||
|         OMAP3ISP_CCDC_LPF | ||||
|         OMAP3ISP_CCDC_BLCLAMP | ||||
|         OMAP3ISP_CCDC_BCOMP | ||||
|         OMAP3ISP_CCDC_FPC | ||||
|         OMAP3ISP_CCDC_CULL | ||||
|         OMAP3ISP_CCDC_CONFIG_LSC | ||||
|         OMAP3ISP_CCDC_TBL_LSC | ||||
| 
 | ||||
| The corresponding values for the VIDIOC_OMAP3ISP_PRV_CFG are here: | ||||
| 
 | ||||
|         OMAP3ISP_PREV_LUMAENH | ||||
|         OMAP3ISP_PREV_INVALAW | ||||
|         OMAP3ISP_PREV_HRZ_MED | ||||
|         OMAP3ISP_PREV_CFA | ||||
|         OMAP3ISP_PREV_CHROMA_SUPP | ||||
|         OMAP3ISP_PREV_WB | ||||
|         OMAP3ISP_PREV_BLKADJ | ||||
|         OMAP3ISP_PREV_RGB2RGB | ||||
|         OMAP3ISP_PREV_COLOR_CONV | ||||
|         OMAP3ISP_PREV_YC_LIMIT | ||||
|         OMAP3ISP_PREV_DEFECT_COR | ||||
|         OMAP3ISP_PREV_GAMMABYPASS | ||||
|         OMAP3ISP_PREV_DRK_FRM_CAPTURE | ||||
|         OMAP3ISP_PREV_DRK_FRM_SUBTRACT | ||||
|         OMAP3ISP_PREV_LENS_SHADING | ||||
|         OMAP3ISP_PREV_NF | ||||
|         OMAP3ISP_PREV_GAMMA | ||||
| 
 | ||||
| The associated configuration pointer for the function may not be NULL when | ||||
| enabling the function. When disabling a function the configuration pointer is | ||||
| ignored. | ||||
| 
 | ||||
| 
 | ||||
| Statistic blocks IOCTLs | ||||
| ======================= | ||||
| 
 | ||||
| The statistics subdevs do offer more dynamic configuration options than the | ||||
| other subdevs. They can be enabled, disable and reconfigured when the pipeline | ||||
| is in streaming state. | ||||
| 
 | ||||
| The statistics blocks always get the input image data from the CCDC (as the | ||||
| histogram memory read isn't implemented). The statistics are dequeueable by | ||||
| the user from the statistics subdev nodes using private IOCTLs. | ||||
| 
 | ||||
| The private IOCTLs offered by the AEWB, AF and histogram subdevs are heavily | ||||
| reflected by the register level interface offered by the ISP hardware. There | ||||
| are aspects that are purely related to the driver implementation and these are | ||||
| discussed next. | ||||
| 
 | ||||
| VIDIOC_OMAP3ISP_STAT_EN | ||||
| ----------------------- | ||||
| 
 | ||||
| This private IOCTL enables/disables a statistic module. If this request is | ||||
| done before streaming, it will take effect as soon as the pipeline starts to | ||||
| stream.  If the pipeline is already streaming, it will take effect as soon as | ||||
| the CCDC becomes idle. | ||||
| 
 | ||||
| VIDIOC_OMAP3ISP_AEWB_CFG, VIDIOC_OMAP3ISP_HIST_CFG and VIDIOC_OMAP3ISP_AF_CFG | ||||
| ----------------------------------------------------------------------------- | ||||
| 
 | ||||
| Those IOCTLs are used to configure the modules. They require user applications | ||||
| to have an in-depth knowledge of the hardware. Most of the fields explanation | ||||
| can be found on OMAP's TRMs. The two following fields common to all the above | ||||
| configure private IOCTLs require explanation for better understanding as they | ||||
| are not part of the TRM. | ||||
| 
 | ||||
| omap3isp_[h3a_af/h3a_aewb/hist]_config.buf_size: | ||||
| 
 | ||||
| The modules handle their buffers internally. The necessary buffer size for the | ||||
| module's data output depends on the requested configuration. Although the | ||||
| driver supports reconfiguration while streaming, it does not support a | ||||
| reconfiguration which requires bigger buffer size than what is already | ||||
| internally allocated if the module is enabled. It will return -EBUSY on this | ||||
| case. In order to avoid such condition, either disable/reconfigure/enable the | ||||
| module or request the necessary buffer size during the first configuration | ||||
| while the module is disabled. | ||||
| 
 | ||||
| The internal buffer size allocation considers the requested configuration's | ||||
| minimum buffer size and the value set on buf_size field. If buf_size field is | ||||
| out of [minimum, maximum] buffer size range, it's clamped to fit in there. | ||||
| The driver then selects the biggest value. The corrected buf_size value is | ||||
| written back to user application. | ||||
| 
 | ||||
| omap3isp_[h3a_af/h3a_aewb/hist]_config.config_counter: | ||||
| 
 | ||||
| As the configuration doesn't take effect synchronously to the request, the | ||||
| driver must provide a way to track this information to provide more accurate | ||||
| data. After a configuration is requested, the config_counter returned to user | ||||
| space application will be an unique value associated to that request. When | ||||
| user application receives an event for buffer availability or when a new | ||||
| buffer is requested, this config_counter is used to match a buffer data and a | ||||
| configuration. | ||||
| 
 | ||||
| VIDIOC_OMAP3ISP_STAT_REQ | ||||
| ------------------------ | ||||
| 
 | ||||
| Send to user space the oldest data available in the internal buffer queue and | ||||
| discards such buffer afterwards. The field omap3isp_stat_data.frame_number | ||||
| matches with the video buffer's field_count. | ||||
| 
 | ||||
| 
 | ||||
| Technical reference manuals (TRMs) and other documentation | ||||
| ========================================================== | ||||
| 
 | ||||
| OMAP 3430 TRM: | ||||
| <URL:http://focus.ti.com/pdfs/wtbu/OMAP34xx_ES3.1.x_PUBLIC_TRM_vZM.zip> | ||||
| Referenced 2011-03-05. | ||||
| 
 | ||||
| OMAP 35xx TRM: | ||||
| <URL:http://www.ti.com/litv/pdf/spruf98o> Referenced 2011-03-05. | ||||
| 
 | ||||
| OMAP 3630 TRM: | ||||
| <URL:http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vQ.zip> | ||||
| Referenced 2011-03-05. | ||||
| 
 | ||||
| DM 3730 TRM: | ||||
| <URL:http://www.ti.com/litv/pdf/sprugn4h> Referenced 2011-03-06. | ||||
| 
 | ||||
| 
 | ||||
| References | ||||
| ========== | ||||
| 
 | ||||
| [1] include/linux/omap3isp.h | ||||
| 
 | ||||
| [2] http://git.ideasonboard.org/?p=media-ctl.git;a=summary | ||||
| @ -71,6 +71,10 @@ sub-device instances, the video_device struct stores V4L2 device node data | ||||
| and in the future a v4l2_fh struct will keep track of filehandle instances | ||||
| (this is not yet implemented). | ||||
| 
 | ||||
| The V4L2 framework also optionally integrates with the media framework. If a | ||||
| driver sets the struct v4l2_device mdev field, sub-devices and video nodes | ||||
| will automatically appear in the media framework as entities. | ||||
| 
 | ||||
| 
 | ||||
| struct v4l2_device | ||||
| ------------------ | ||||
| @ -83,11 +87,20 @@ You must register the device instance: | ||||
| 
 | ||||
| 	v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); | ||||
| 
 | ||||
| Registration will initialize the v4l2_device struct and link dev->driver_data | ||||
| to v4l2_dev. If v4l2_dev->name is empty then it will be set to a value derived | ||||
| from dev (driver name followed by the bus_id, to be precise). If you set it | ||||
| up before calling v4l2_device_register then it will be untouched. If dev is | ||||
| NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register. | ||||
| Registration will initialize the v4l2_device struct. If the dev->driver_data | ||||
| field is NULL, it will be linked to v4l2_dev. | ||||
| 
 | ||||
| Drivers that want integration with the media device framework need to set | ||||
| dev->driver_data manually to point to the driver-specific device structure | ||||
| that embed the struct v4l2_device instance. This is achieved by a | ||||
| dev_set_drvdata() call before registering the V4L2 device instance. They must | ||||
| also set the struct v4l2_device mdev field to point to a properly initialized | ||||
| and registered media_device instance. | ||||
| 
 | ||||
| If v4l2_dev->name is empty then it will be set to a value derived from dev | ||||
| (driver name followed by the bus_id, to be precise). If you set it up before | ||||
| calling v4l2_device_register then it will be untouched. If dev is NULL, then | ||||
| you *must* setup v4l2_dev->name before calling v4l2_device_register. | ||||
| 
 | ||||
| You can use v4l2_device_set_name() to set the name based on a driver name and | ||||
| a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1, | ||||
| @ -108,6 +121,7 @@ You unregister with: | ||||
| 
 | ||||
| 	v4l2_device_unregister(struct v4l2_device *v4l2_dev); | ||||
| 
 | ||||
| If the dev->driver_data field points to v4l2_dev, it will be reset to NULL. | ||||
| Unregistering will also automatically unregister all subdevs from the device. | ||||
| 
 | ||||
| If you have a hotpluggable device (e.g. a USB device), then when a disconnect | ||||
| @ -167,6 +181,21 @@ static int __devinit drv_probe(struct pci_dev *pdev, | ||||
| 	state->instance = atomic_inc_return(&drv_instance) - 1; | ||||
| } | ||||
| 
 | ||||
| If you have multiple device nodes then it can be difficult to know when it is | ||||
| safe to unregister v4l2_device. For this purpose v4l2_device has refcounting | ||||
| support. The refcount is increased whenever video_register_device is called and | ||||
| it is decreased whenever that device node is released. When the refcount reaches | ||||
| zero, then the v4l2_device release() callback is called. You can do your final | ||||
| cleanup there. | ||||
| 
 | ||||
| If other device nodes (e.g. ALSA) are created, then you can increase and | ||||
| decrease the refcount manually as well by calling: | ||||
| 
 | ||||
| void v4l2_device_get(struct v4l2_device *v4l2_dev); | ||||
| 
 | ||||
| or: | ||||
| 
 | ||||
| int v4l2_device_put(struct v4l2_device *v4l2_dev); | ||||
| 
 | ||||
| struct v4l2_subdev | ||||
| ------------------ | ||||
| @ -254,6 +283,26 @@ A sub-device driver initializes the v4l2_subdev struct using: | ||||
| Afterwards you need to initialize subdev->name with a unique name and set the | ||||
| module owner. This is done for you if you use the i2c helper functions. | ||||
| 
 | ||||
| If integration with the media framework is needed, you must initialize the | ||||
| media_entity struct embedded in the v4l2_subdev struct (entity field) by | ||||
| calling media_entity_init(): | ||||
| 
 | ||||
| 	struct media_pad *pads = &my_sd->pads; | ||||
| 	int err; | ||||
| 
 | ||||
| 	err = media_entity_init(&sd->entity, npads, pads, 0); | ||||
| 
 | ||||
| The pads array must have been previously initialized. There is no need to | ||||
| manually set the struct media_entity type and name fields, but the revision | ||||
| field must be initialized if needed. | ||||
| 
 | ||||
| A reference to the entity will be automatically acquired/released when the | ||||
| subdev device node (if any) is opened/closed. | ||||
| 
 | ||||
| Don't forget to cleanup the media entity before the sub-device is destroyed: | ||||
| 
 | ||||
| 	media_entity_cleanup(&sd->entity); | ||||
| 
 | ||||
| A device (bridge) driver needs to register the v4l2_subdev with the | ||||
| v4l2_device: | ||||
| 
 | ||||
| @ -263,6 +312,9 @@ This can fail if the subdev module disappeared before it could be registered. | ||||
| After this function was called successfully the subdev->dev field points to | ||||
| the v4l2_device. | ||||
| 
 | ||||
| If the v4l2_device parent device has a non-NULL mdev field, the sub-device | ||||
| entity will be automatically registered with the media device. | ||||
| 
 | ||||
| You can unregister a sub-device using: | ||||
| 
 | ||||
| 	v4l2_device_unregister_subdev(sd); | ||||
| @ -319,6 +371,61 @@ controlled through GPIO pins. This distinction is only relevant when setting | ||||
| up the device, but once the subdev is registered it is completely transparent. | ||||
| 
 | ||||
| 
 | ||||
| V4L2 sub-device userspace API | ||||
| ----------------------------- | ||||
| 
 | ||||
| Beside exposing a kernel API through the v4l2_subdev_ops structure, V4L2 | ||||
| sub-devices can also be controlled directly by userspace applications. | ||||
| 
 | ||||
| Device nodes named v4l-subdevX can be created in /dev to access sub-devices | ||||
| directly. If a sub-device supports direct userspace configuration it must set | ||||
| the V4L2_SUBDEV_FL_HAS_DEVNODE flag before being registered. | ||||
| 
 | ||||
| After registering sub-devices, the v4l2_device driver can create device nodes | ||||
| for all registered sub-devices marked with V4L2_SUBDEV_FL_HAS_DEVNODE by calling | ||||
| v4l2_device_register_subdev_nodes(). Those device nodes will be automatically | ||||
| removed when sub-devices are unregistered. | ||||
| 
 | ||||
| The device node handles a subset of the V4L2 API. | ||||
| 
 | ||||
| VIDIOC_QUERYCTRL | ||||
| VIDIOC_QUERYMENU | ||||
| VIDIOC_G_CTRL | ||||
| VIDIOC_S_CTRL | ||||
| VIDIOC_G_EXT_CTRLS | ||||
| VIDIOC_S_EXT_CTRLS | ||||
| VIDIOC_TRY_EXT_CTRLS | ||||
| 
 | ||||
| 	The controls ioctls are identical to the ones defined in V4L2. They | ||||
| 	behave identically, with the only exception that they deal only with | ||||
| 	controls implemented in the sub-device. Depending on the driver, those | ||||
| 	controls can be also be accessed through one (or several) V4L2 device | ||||
| 	nodes. | ||||
| 
 | ||||
| VIDIOC_DQEVENT | ||||
| VIDIOC_SUBSCRIBE_EVENT | ||||
| VIDIOC_UNSUBSCRIBE_EVENT | ||||
| 
 | ||||
| 	The events ioctls are identical to the ones defined in V4L2. They | ||||
| 	behave identically, with the only exception that they deal only with | ||||
| 	events generated by the sub-device. Depending on the driver, those | ||||
| 	events can also be reported by one (or several) V4L2 device nodes. | ||||
| 
 | ||||
| 	Sub-device drivers that want to use events need to set the | ||||
| 	V4L2_SUBDEV_USES_EVENTS v4l2_subdev::flags and initialize | ||||
| 	v4l2_subdev::nevents to events queue depth before registering the | ||||
| 	sub-device. After registration events can be queued as usual on the | ||||
| 	v4l2_subdev::devnode device node. | ||||
| 
 | ||||
| 	To properly support events, the poll() file operation is also | ||||
| 	implemented. | ||||
| 
 | ||||
| Private ioctls | ||||
| 
 | ||||
| 	All ioctls not in the above list are passed directly to the sub-device | ||||
| 	driver through the core::ioctl operation. | ||||
| 
 | ||||
| 
 | ||||
| I2C sub-device drivers | ||||
| ---------------------- | ||||
| 
 | ||||
| @ -457,6 +564,10 @@ You should also set these fields: | ||||
|   Otherwise you give it a pointer to a struct mutex_lock and before any | ||||
|   of the v4l2_file_operations is called this lock will be taken by the | ||||
|   core and released afterwards. | ||||
| - prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY. | ||||
|   If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device. | ||||
|   If you want to have a separate priority state per (group of) device node(s), | ||||
|   then you can point it to your own struct v4l2_prio_state. | ||||
| - parent: you only set this if v4l2_device was registered with NULL as | ||||
|   the parent device struct. This only happens in cases where one hardware | ||||
|   device has multiple PCI devices that all share the same v4l2_device core. | ||||
| @ -466,13 +577,34 @@ You should also set these fields: | ||||
|   (cx8802). Since the v4l2_device cannot be associated with a particular | ||||
|   PCI device it is setup without a parent device. But when the struct | ||||
|   video_device is setup you do know which parent PCI device to use. | ||||
| - flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework | ||||
|   handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct | ||||
|   v4l2_fh. Eventually this flag will disappear once all drivers use the core | ||||
|   priority handling. But for now it has to be set explicitly. | ||||
| 
 | ||||
| If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or | ||||
| .ioctl to video_ioctl2 in your v4l2_file_operations struct. | ||||
| If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to video_ioctl2 | ||||
| in your v4l2_file_operations struct. | ||||
| 
 | ||||
| Do not use .ioctl! This is deprecated and will go away in the future. | ||||
| 
 | ||||
| The v4l2_file_operations struct is a subset of file_operations. The main | ||||
| difference is that the inode argument is omitted since it is never used. | ||||
| 
 | ||||
| If integration with the media framework is needed, you must initialize the | ||||
| media_entity struct embedded in the video_device struct (entity field) by | ||||
| calling media_entity_init(): | ||||
| 
 | ||||
| 	struct media_pad *pad = &my_vdev->pad; | ||||
| 	int err; | ||||
| 
 | ||||
| 	err = media_entity_init(&vdev->entity, 1, pad, 0); | ||||
| 
 | ||||
| The pads array must have been previously initialized. There is no need to | ||||
| manually set the struct media_entity type and name fields. | ||||
| 
 | ||||
| A reference to the entity will be automatically acquired/released when the | ||||
| video device is opened/closed. | ||||
| 
 | ||||
| v4l2_file_operations and locking | ||||
| -------------------------------- | ||||
| 
 | ||||
| @ -502,6 +634,9 @@ for you. | ||||
| 		return err; | ||||
| 	} | ||||
| 
 | ||||
| If the v4l2_device parent device has a non-NULL mdev field, the video device | ||||
| entity will be automatically registered with the media device. | ||||
| 
 | ||||
| Which device is registered depends on the type argument. The following | ||||
| types exist: | ||||
| 
 | ||||
| @ -577,6 +712,13 @@ release, of course) will return an error as well. | ||||
| When the last user of the video device node exits, then the vdev->release() | ||||
| callback is called and you can do the final cleanup there. | ||||
| 
 | ||||
| Don't forget to cleanup the media entity associated with the video device if | ||||
| it has been initialized: | ||||
| 
 | ||||
| 	media_entity_cleanup(&vdev->entity); | ||||
| 
 | ||||
| This can be done from the release callback. | ||||
| 
 | ||||
| 
 | ||||
| video_device helper functions | ||||
| ----------------------------- | ||||
| @ -636,39 +778,25 @@ struct v4l2_fh | ||||
| -------------- | ||||
| 
 | ||||
| struct v4l2_fh provides a way to easily keep file handle specific data | ||||
| that is used by the V4L2 framework. Using v4l2_fh is optional for | ||||
| drivers. | ||||
| that is used by the V4L2 framework. New drivers must use struct v4l2_fh | ||||
| since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY) | ||||
| if the video_device flag V4L2_FL_USE_FH_PRIO is also set. | ||||
| 
 | ||||
| The users of v4l2_fh (in the V4L2 framework, not the driver) know | ||||
| whether a driver uses v4l2_fh as its file->private_data pointer by | ||||
| testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags. | ||||
| 
 | ||||
| Useful functions: | ||||
| 
 | ||||
| - v4l2_fh_init() | ||||
| 
 | ||||
|   Initialise the file handle. This *MUST* be performed in the driver's | ||||
|   v4l2_file_operations->open() handler. | ||||
| 
 | ||||
| - v4l2_fh_add() | ||||
| 
 | ||||
|   Add a v4l2_fh to video_device file handle list. May be called after | ||||
|   initialising the file handle. | ||||
| 
 | ||||
| - v4l2_fh_del() | ||||
| 
 | ||||
|   Unassociate the file handle from video_device(). The file handle | ||||
|   exit function may now be called. | ||||
| 
 | ||||
| - v4l2_fh_exit() | ||||
| 
 | ||||
|   Uninitialise the file handle. After uninitialisation the v4l2_fh | ||||
|   memory can be freed. | ||||
| testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags. This bit is | ||||
| set whenever v4l2_fh_init() is called. | ||||
| 
 | ||||
| struct v4l2_fh is allocated as a part of the driver's own file handle | ||||
| structure and is set to file->private_data in the driver's open | ||||
| function by the driver. Drivers can extract their own file handle | ||||
| structure by using the container_of macro. Example: | ||||
| structure and file->private_data is set to it in the driver's open | ||||
| function by the driver. | ||||
| 
 | ||||
| In many cases the struct v4l2_fh will be embedded in a larger structure. | ||||
| In that case you should call v4l2_fh_init+v4l2_fh_add in open() and | ||||
| v4l2_fh_del+v4l2_fh_exit in release(). | ||||
| 
 | ||||
| Drivers can extract their own file handle structure by using the container_of | ||||
| macro. Example: | ||||
| 
 | ||||
| struct my_fh { | ||||
| 	int blah; | ||||
| @ -685,15 +813,21 @@ int my_open(struct file *file) | ||||
| 
 | ||||
| 	... | ||||
| 
 | ||||
| 	ret = v4l2_fh_init(&my_fh->fh, vfd); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	v4l2_fh_add(&my_fh->fh); | ||||
| 
 | ||||
| 	file->private_data = &my_fh->fh; | ||||
| 	my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL); | ||||
| 
 | ||||
| 	... | ||||
| 
 | ||||
| 	ret = v4l2_fh_init(&my_fh->fh, vfd); | ||||
| 	if (ret) { | ||||
| 		kfree(my_fh); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	... | ||||
| 
 | ||||
| 	file->private_data = &my_fh->fh; | ||||
| 	v4l2_fh_add(&my_fh->fh); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int my_release(struct file *file) | ||||
| @ -702,8 +836,65 @@ int my_release(struct file *file) | ||||
| 	struct my_fh *my_fh = container_of(fh, struct my_fh, fh); | ||||
| 
 | ||||
| 	... | ||||
| 	v4l2_fh_del(&my_fh->fh); | ||||
| 	v4l2_fh_exit(&my_fh->fh); | ||||
| 	kfree(my_fh); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| Below is a short description of the v4l2_fh functions used: | ||||
| 
 | ||||
| int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev) | ||||
| 
 | ||||
|   Initialise the file handle. This *MUST* be performed in the driver's | ||||
|   v4l2_file_operations->open() handler. | ||||
| 
 | ||||
| void v4l2_fh_add(struct v4l2_fh *fh) | ||||
| 
 | ||||
|   Add a v4l2_fh to video_device file handle list. Must be called once the | ||||
|   file handle is completely initialized. | ||||
| 
 | ||||
| void v4l2_fh_del(struct v4l2_fh *fh) | ||||
| 
 | ||||
|   Unassociate the file handle from video_device(). The file handle | ||||
|   exit function may now be called. | ||||
| 
 | ||||
| void v4l2_fh_exit(struct v4l2_fh *fh) | ||||
| 
 | ||||
|   Uninitialise the file handle. After uninitialisation the v4l2_fh | ||||
|   memory can be freed. | ||||
| 
 | ||||
| 
 | ||||
| If struct v4l2_fh is not embedded, then you can use these helper functions: | ||||
| 
 | ||||
| int v4l2_fh_open(struct file *filp) | ||||
| 
 | ||||
|   This allocates a struct v4l2_fh, initializes it and adds it to the struct | ||||
|   video_device associated with the file struct. | ||||
| 
 | ||||
| int v4l2_fh_release(struct file *filp) | ||||
| 
 | ||||
|   This deletes it from the struct video_device associated with the file | ||||
|   struct, uninitialised the v4l2_fh and frees it. | ||||
| 
 | ||||
| These two functions can be plugged into the v4l2_file_operation's open() and | ||||
| release() ops. | ||||
| 
 | ||||
| 
 | ||||
| Several drivers need to do something when the first file handle is opened and | ||||
| when the last file handle closes. Two helper functions were added to check | ||||
| whether the v4l2_fh struct is the only open filehandle of the associated | ||||
| device node: | ||||
| 
 | ||||
| int v4l2_fh_is_singular(struct v4l2_fh *fh) | ||||
| 
 | ||||
|   Returns 1 if the file handle is the only open file handle, else 0. | ||||
| 
 | ||||
| int v4l2_fh_is_singular_file(struct file *filp) | ||||
| 
 | ||||
|   Same, but it calls v4l2_fh_is_singular with filp->private_data. | ||||
| 
 | ||||
| 
 | ||||
| V4L2 events | ||||
| ----------- | ||||
| 
 | ||||
|  | ||||
| @ -4582,6 +4582,12 @@ L:	linux-omap@vger.kernel.org | ||||
| S:	Maintained | ||||
| F:	arch/arm/mach-omap2/omap_hwmod_44xx_data.c | ||||
| 
 | ||||
| OMAP IMAGE SIGNAL PROCESSOR (ISP) | ||||
| M:	Laurent Pinchart <laurent.pinchart@ideasonboard.com> | ||||
| L:	linux-media@vger.kernel.org | ||||
| S:	Maintained | ||||
| F:	drivers/media/video/omap3isp/* | ||||
| 
 | ||||
| OMAP USB SUPPORT | ||||
| M:	Felipe Balbi <balbi@ti.com> | ||||
| M:	David Brownell <dbrownell@users.sourceforge.net> | ||||
|  | ||||
| @ -35,6 +35,7 @@ | ||||
| 
 | ||||
| #include "mux.h" | ||||
| #include "control.h" | ||||
| #include "devices.h" | ||||
| 
 | ||||
| #define L3_MODULES_MAX_LEN 12 | ||||
| #define L3_MODULES 3 | ||||
| @ -102,7 +103,7 @@ postcore_initcall(omap4_l3_init); | ||||
| 
 | ||||
| #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) | ||||
| 
 | ||||
| static struct resource cam_resources[] = { | ||||
| static struct resource omap2cam_resources[] = { | ||||
| 	{ | ||||
| 		.start		= OMAP24XX_CAMERA_BASE, | ||||
| 		.end		= OMAP24XX_CAMERA_BASE + 0xfff, | ||||
| @ -114,19 +115,13 @@ static struct resource cam_resources[] = { | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device omap_cam_device = { | ||||
| static struct platform_device omap2cam_device = { | ||||
| 	.name		= "omap24xxcam", | ||||
| 	.id		= -1, | ||||
| 	.num_resources	= ARRAY_SIZE(cam_resources), | ||||
| 	.resource	= cam_resources, | ||||
| 	.num_resources	= ARRAY_SIZE(omap2cam_resources), | ||||
| 	.resource	= omap2cam_resources, | ||||
| }; | ||||
| 
 | ||||
| static inline void omap_init_camera(void) | ||||
| { | ||||
| 	platform_device_register(&omap_cam_device); | ||||
| } | ||||
| 
 | ||||
| #elif defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE) | ||||
| #endif | ||||
| 
 | ||||
| static struct resource omap3isp_resources[] = { | ||||
| 	{ | ||||
| @ -134,11 +129,6 @@ static struct resource omap3isp_resources[] = { | ||||
| 		.end		= OMAP3430_ISP_END, | ||||
| 		.flags		= IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.start		= OMAP3430_ISP_CBUFF_BASE, | ||||
| 		.end		= OMAP3430_ISP_CBUFF_END, | ||||
| 		.flags		= IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.start		= OMAP3430_ISP_CCP2_BASE, | ||||
| 		.end		= OMAP3430_ISP_CCP2_END, | ||||
| @ -175,13 +165,33 @@ static struct resource omap3isp_resources[] = { | ||||
| 		.flags		= IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.start		= OMAP3430_ISP_CSI2A_BASE, | ||||
| 		.end		= OMAP3430_ISP_CSI2A_END, | ||||
| 		.start		= OMAP3430_ISP_CSI2A_REGS1_BASE, | ||||
| 		.end		= OMAP3430_ISP_CSI2A_REGS1_END, | ||||
| 		.flags		= IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.start		= OMAP3430_ISP_CSI2PHY_BASE, | ||||
| 		.end		= OMAP3430_ISP_CSI2PHY_END, | ||||
| 		.start		= OMAP3430_ISP_CSIPHY2_BASE, | ||||
| 		.end		= OMAP3430_ISP_CSIPHY2_END, | ||||
| 		.flags		= IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.start		= OMAP3630_ISP_CSI2A_REGS2_BASE, | ||||
| 		.end		= OMAP3630_ISP_CSI2A_REGS2_END, | ||||
| 		.flags		= IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.start		= OMAP3630_ISP_CSI2C_REGS1_BASE, | ||||
| 		.end		= OMAP3630_ISP_CSI2C_REGS1_END, | ||||
| 		.flags		= IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.start		= OMAP3630_ISP_CSIPHY1_BASE, | ||||
| 		.end		= OMAP3630_ISP_CSIPHY1_END, | ||||
| 		.flags		= IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.start		= OMAP3630_ISP_CSI2C_REGS2_BASE, | ||||
| 		.end		= OMAP3630_ISP_CSI2C_REGS2_END, | ||||
| 		.flags		= IORESOURCE_MEM, | ||||
| 	}, | ||||
| 	{ | ||||
| @ -197,15 +207,19 @@ static struct platform_device omap3isp_device = { | ||||
| 	.resource	= omap3isp_resources, | ||||
| }; | ||||
| 
 | ||||
| int omap3_init_camera(struct isp_platform_data *pdata) | ||||
| { | ||||
| 	omap3isp_device.dev.platform_data = pdata; | ||||
| 	return platform_device_register(&omap3isp_device); | ||||
| } | ||||
| 
 | ||||
| static inline void omap_init_camera(void) | ||||
| { | ||||
| 	platform_device_register(&omap3isp_device); | ||||
| } | ||||
| #else | ||||
| static inline void omap_init_camera(void) | ||||
| { | ||||
| } | ||||
| #if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) | ||||
| 	if (cpu_is_omap24xx()) | ||||
| 		platform_device_register(&omap2cam_device); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| struct omap_device_pm_latency omap_keyboard_latency[] = { | ||||
| 	{ | ||||
|  | ||||
							
								
								
									
										19
									
								
								arch/arm/mach-omap2/devices.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								arch/arm/mach-omap2/devices.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| /*
 | ||||
|  * arch/arm/mach-omap2/devices.h | ||||
|  * | ||||
|  * OMAP2 platform device setup/initialization | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License as published by | ||||
|  * the Free Software Foundation; either version 2 of the License, or | ||||
|  * (at your option) any later version. | ||||
|  */ | ||||
| 
 | ||||
| #ifndef __ARCH_ARM_MACH_OMAP_DEVICES_H | ||||
| #define __ARCH_ARM_MACH_OMAP_DEVICES_H | ||||
| 
 | ||||
| struct isp_platform_data; | ||||
| 
 | ||||
| int omap3_init_camera(struct isp_platform_data *pdata); | ||||
| 
 | ||||
| #endif | ||||
| @ -56,8 +56,12 @@ | ||||
| #define OMAP3430_ISP_RESZ_BASE		(OMAP3430_ISP_BASE + 0x1000) | ||||
| #define OMAP3430_ISP_SBL_BASE		(OMAP3430_ISP_BASE + 0x1200) | ||||
| #define OMAP3430_ISP_MMU_BASE		(OMAP3430_ISP_BASE + 0x1400) | ||||
| #define OMAP3430_ISP_CSI2A_BASE		(OMAP3430_ISP_BASE + 0x1800) | ||||
| #define OMAP3430_ISP_CSI2PHY_BASE	(OMAP3430_ISP_BASE + 0x1970) | ||||
| #define OMAP3430_ISP_CSI2A_REGS1_BASE	(OMAP3430_ISP_BASE + 0x1800) | ||||
| #define OMAP3430_ISP_CSIPHY2_BASE	(OMAP3430_ISP_BASE + 0x1970) | ||||
| #define OMAP3630_ISP_CSI2A_REGS2_BASE	(OMAP3430_ISP_BASE + 0x19C0) | ||||
| #define OMAP3630_ISP_CSI2C_REGS1_BASE	(OMAP3430_ISP_BASE + 0x1C00) | ||||
| #define OMAP3630_ISP_CSIPHY1_BASE	(OMAP3430_ISP_BASE + 0x1D70) | ||||
| #define OMAP3630_ISP_CSI2C_REGS2_BASE	(OMAP3430_ISP_BASE + 0x1DC0) | ||||
| 
 | ||||
| #define OMAP3430_ISP_END		(OMAP3430_ISP_BASE         + 0x06F) | ||||
| #define OMAP3430_ISP_CBUFF_END		(OMAP3430_ISP_CBUFF_BASE   + 0x077) | ||||
| @ -69,8 +73,12 @@ | ||||
| #define OMAP3430_ISP_RESZ_END		(OMAP3430_ISP_RESZ_BASE    + 0x0AB) | ||||
| #define OMAP3430_ISP_SBL_END		(OMAP3430_ISP_SBL_BASE     + 0x0FB) | ||||
| #define OMAP3430_ISP_MMU_END		(OMAP3430_ISP_MMU_BASE     + 0x06F) | ||||
| #define OMAP3430_ISP_CSI2A_END		(OMAP3430_ISP_CSI2A_BASE   + 0x16F) | ||||
| #define OMAP3430_ISP_CSI2PHY_END	(OMAP3430_ISP_CSI2PHY_BASE + 0x007) | ||||
| #define OMAP3430_ISP_CSI2A_REGS1_END	(OMAP3430_ISP_CSI2A_REGS1_BASE + 0x16F) | ||||
| #define OMAP3430_ISP_CSIPHY2_END	(OMAP3430_ISP_CSIPHY2_BASE + 0x00B) | ||||
| #define OMAP3630_ISP_CSI2A_REGS2_END	(OMAP3630_ISP_CSI2A_REGS2_BASE + 0x3F) | ||||
| #define OMAP3630_ISP_CSI2C_REGS1_END	(OMAP3630_ISP_CSI2C_REGS1_BASE + 0x16F) | ||||
| #define OMAP3630_ISP_CSIPHY1_END	(OMAP3630_ISP_CSIPHY1_BASE + 0x00B) | ||||
| #define OMAP3630_ISP_CSI2C_REGS2_END	(OMAP3630_ISP_CSI2C_REGS2_BASE + 0x3F) | ||||
| 
 | ||||
| #define OMAP34XX_HSUSB_OTG_BASE	(L4_34XX_BASE + 0xAB000) | ||||
| #define OMAP34XX_USBTLL_BASE	(L4_34XX_BASE + 0x62000) | ||||
|  | ||||
| @ -13,6 +13,19 @@ if MEDIA_SUPPORT | ||||
| 
 | ||||
| comment "Multimedia core support" | ||||
| 
 | ||||
| # | ||||
| # Media controller | ||||
| # | ||||
| 
 | ||||
| config MEDIA_CONTROLLER | ||||
| 	bool "Media Controller API (EXPERIMENTAL)" | ||||
| 	depends on EXPERIMENTAL | ||||
| 	---help--- | ||||
| 	  Enable the media controller API used to query media devices internal | ||||
| 	  topology and configure it dynamically. | ||||
| 
 | ||||
| 	  This API is mostly used by camera interfaces in embedded platforms. | ||||
| 
 | ||||
| # | ||||
| # V4L core and enabled API's | ||||
| # | ||||
| @ -40,6 +53,15 @@ config VIDEO_V4L2_COMMON | ||||
| 	depends on (I2C || I2C=n) && VIDEO_DEV | ||||
| 	default (I2C || I2C=n) && VIDEO_DEV | ||||
| 
 | ||||
| config VIDEO_V4L2_SUBDEV_API | ||||
| 	bool "V4L2 sub-device userspace API (EXPERIMENTAL)" | ||||
| 	depends on VIDEO_DEV && MEDIA_CONTROLLER && EXPERIMENTAL | ||||
| 	---help--- | ||||
| 	  Enables the V4L2 sub-device pad-level userspace API used to configure | ||||
| 	  video format, size and frame rate between hardware blocks. | ||||
| 
 | ||||
| 	  This API is mostly used by camera interfaces in embedded platforms. | ||||
| 
 | ||||
| # | ||||
| # DVB Core | ||||
| # | ||||
|  | ||||
| @ -2,6 +2,12 @@ | ||||
| # Makefile for the kernel multimedia device drivers.
 | ||||
| #
 | ||||
| 
 | ||||
| media-objs	:= media-device.o media-devnode.o media-entity.o | ||||
| 
 | ||||
| ifeq ($(CONFIG_MEDIA_CONTROLLER),y) | ||||
|   obj-$(CONFIG_MEDIA_SUPPORT) += media.o | ||||
| endif | ||||
| 
 | ||||
| obj-y += common/ rc/ video/ | ||||
| 
 | ||||
| obj-$(CONFIG_VIDEO_DEV) += radio/ | ||||
|  | ||||
| @ -36,6 +36,8 @@ struct tda9887_priv { | ||||
| 	unsigned int       mode; | ||||
| 	unsigned int       audmode; | ||||
| 	v4l2_std_id        std; | ||||
| 
 | ||||
| 	bool               standby; | ||||
| }; | ||||
| 
 | ||||
| /* ---------------------------------------------------------------------- */ | ||||
| @ -568,7 +570,7 @@ static void tda9887_configure(struct dvb_frontend *fe) | ||||
| 	tda9887_do_config(fe); | ||||
| 	tda9887_set_insmod(fe); | ||||
| 
 | ||||
| 	if (priv->mode == T_STANDBY) | ||||
| 	if (priv->standby) | ||||
| 		priv->data[1] |= cForcedMuteAudioON; | ||||
| 
 | ||||
| 	tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", | ||||
| @ -616,7 +618,7 @@ static void tda9887_standby(struct dvb_frontend *fe) | ||||
| { | ||||
| 	struct tda9887_priv *priv = fe->analog_demod_priv; | ||||
| 
 | ||||
| 	priv->mode = T_STANDBY; | ||||
| 	priv->standby = true; | ||||
| 
 | ||||
| 	tda9887_configure(fe); | ||||
| } | ||||
| @ -626,6 +628,7 @@ static void tda9887_set_params(struct dvb_frontend *fe, | ||||
| { | ||||
| 	struct tda9887_priv *priv = fe->analog_demod_priv; | ||||
| 
 | ||||
| 	priv->standby = false; | ||||
| 	priv->mode    = params->mode; | ||||
| 	priv->audmode = params->audmode; | ||||
| 	priv->std     = params->std; | ||||
| @ -686,7 +689,7 @@ struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe, | ||||
| 		return NULL; | ||||
| 	case 1: | ||||
| 		fe->analog_demod_priv = priv; | ||||
| 		priv->mode = T_STANDBY; | ||||
| 		priv->standby = true; | ||||
| 		tuner_info("tda988[5/6/7] found\n"); | ||||
| 		break; | ||||
| 	default: | ||||
|  | ||||
| @ -23,6 +23,7 @@ struct tea5761_priv { | ||||
| 	struct tuner_i2c_props i2c_props; | ||||
| 
 | ||||
| 	u32 frequency; | ||||
| 	bool standby; | ||||
| }; | ||||
| 
 | ||||
| /*****************************************************************************/ | ||||
| @ -135,18 +136,19 @@ static void tea5761_status_dump(unsigned char *buffer) | ||||
| } | ||||
| 
 | ||||
| /* Freq should be specifyed at 62.5 Hz */ | ||||
| static int set_radio_freq(struct dvb_frontend *fe, | ||||
| 			  struct analog_parameters *params) | ||||
| static int __set_radio_freq(struct dvb_frontend *fe, | ||||
| 			    unsigned int freq, | ||||
| 			    bool mono) | ||||
| { | ||||
| 	struct tea5761_priv *priv = fe->tuner_priv; | ||||
| 	unsigned int frq = params->frequency; | ||||
| 	unsigned int frq = freq; | ||||
| 	unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 }; | ||||
| 	unsigned div; | ||||
| 	int rc; | ||||
| 
 | ||||
| 	tuner_dbg("radio freq counter %d\n", frq); | ||||
| 
 | ||||
| 	if (params->mode == T_STANDBY) { | ||||
| 	if (priv->standby) { | ||||
| 		tuner_dbg("TEA5761 set to standby mode\n"); | ||||
| 		buffer[5] |= TEA5761_TNCTRL_MU; | ||||
| 	} else { | ||||
| @ -154,7 +156,7 @@ static int set_radio_freq(struct dvb_frontend *fe, | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	if (params->audmode == V4L2_TUNER_MODE_MONO) { | ||||
| 	if (mono) { | ||||
| 		tuner_dbg("TEA5761 set to mono\n"); | ||||
| 		buffer[5] |= TEA5761_TNCTRL_MST; | ||||
| 	} else { | ||||
| @ -176,6 +178,26 @@ static int set_radio_freq(struct dvb_frontend *fe, | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int set_radio_freq(struct dvb_frontend *fe, | ||||
| 			  struct analog_parameters *params) | ||||
| { | ||||
| 	struct tea5761_priv *priv = fe->analog_demod_priv; | ||||
| 
 | ||||
| 	priv->standby = false; | ||||
| 
 | ||||
| 	return __set_radio_freq(fe, params->frequency, | ||||
| 				params->audmode == V4L2_TUNER_MODE_MONO); | ||||
| } | ||||
| 
 | ||||
| static int set_radio_sleep(struct dvb_frontend *fe) | ||||
| { | ||||
| 	struct tea5761_priv *priv = fe->analog_demod_priv; | ||||
| 
 | ||||
| 	priv->standby = true; | ||||
| 
 | ||||
| 	return __set_radio_freq(fe, priv->frequency, false); | ||||
| } | ||||
| 
 | ||||
| static int tea5761_read_status(struct dvb_frontend *fe, char *buffer) | ||||
| { | ||||
| 	struct tea5761_priv *priv = fe->tuner_priv; | ||||
| @ -284,6 +306,7 @@ static struct dvb_tuner_ops tea5761_tuner_ops = { | ||||
| 		.name           = "tea5761", // Philips TEA5761HN FM Radio
 | ||||
| 	}, | ||||
| 	.set_analog_params = set_radio_freq, | ||||
| 	.sleep		   = set_radio_sleep, | ||||
| 	.release           = tea5761_release, | ||||
| 	.get_frequency     = tea5761_get_frequency, | ||||
| 	.get_status        = tea5761_get_status, | ||||
|  | ||||
| @ -971,6 +971,22 @@ static struct tuner_params tuner_tena_9533_di_params[] = { | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /* ------------ TUNER_TENA_TNF_5337 - Tena tnf5337MFD STD M/N ------------ */ | ||||
| 
 | ||||
| static struct tuner_range tuner_tena_tnf_5337_ntsc_ranges[] = { | ||||
| 	{ 16 * 166.25 /*MHz*/, 0x86, 0x01, }, | ||||
| 	{ 16 * 466.25 /*MHz*/, 0x86, 0x02, }, | ||||
| 	{ 16 * 999.99        , 0x86, 0x08, }, | ||||
| }; | ||||
| 
 | ||||
| static struct tuner_params tuner_tena_tnf_5337_params[] = { | ||||
| 	{ | ||||
| 		.type   = TUNER_PARAM_TYPE_NTSC, | ||||
| 		.ranges = tuner_tena_tnf_5337_ntsc_ranges, | ||||
| 		.count  = ARRAY_SIZE(tuner_tena_tnf_5337_ntsc_ranges), | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| /* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */ | ||||
| 
 | ||||
| static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { | ||||
| @ -1842,6 +1858,11 @@ struct tunertype tuners[] = { | ||||
| 		.params = tuner_philips_fq1236_mk5_params, | ||||
| 		.count  = ARRAY_SIZE(tuner_philips_fq1236_mk5_params), | ||||
| 	}, | ||||
| 	[TUNER_TENA_TNF_5337] = { /* Tena 5337 MFD */ | ||||
| 		.name   = "Tena TNF5337 MFD", | ||||
| 		.params = tuner_tena_tnf_5337_params, | ||||
| 		.count  = ARRAY_SIZE(tuner_tena_tnf_5337_params), | ||||
| 	}, | ||||
| }; | ||||
| EXPORT_SYMBOL(tuners); | ||||
| 
 | ||||
|  | ||||
| @ -685,7 +685,7 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type, | ||||
| { | ||||
| 	struct xc2028_data         *priv = fe->tuner_priv; | ||||
| 	struct firmware_properties new_fw; | ||||
| 	int			   rc = 0, is_retry = 0; | ||||
| 	int			   rc = 0, retry_count = 0; | ||||
| 	u16			   version, hwmodel; | ||||
| 	v4l2_std_id		   std0; | ||||
| 
 | ||||
| @ -855,9 +855,9 @@ read_not_reliable: | ||||
| 
 | ||||
| fail: | ||||
| 	memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); | ||||
| 	if (!is_retry) { | ||||
| 	if (retry_count < 8) { | ||||
| 		msleep(50); | ||||
| 		is_retry = 1; | ||||
| 		retry_count++; | ||||
| 		tuner_dbg("Retrying firmware load\n"); | ||||
| 		goto retry; | ||||
| 	} | ||||
| @ -907,7 +907,7 @@ ret: | ||||
| #define DIV 15625 | ||||
| 
 | ||||
| static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | ||||
| 			    enum tuner_mode new_mode, | ||||
| 			    enum v4l2_tuner_type new_type, | ||||
| 			    unsigned int type, | ||||
| 			    v4l2_std_id std, | ||||
| 			    u16 int_freq) | ||||
| @ -933,7 +933,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, | ||||
| 	 * that xc2028 will be in a safe state. | ||||
| 	 * Maybe this might also be needed for DTV. | ||||
| 	 */ | ||||
| 	if (new_mode == T_ANALOG_TV) { | ||||
| 	if (new_type == V4L2_TUNER_ANALOG_TV) { | ||||
| 		rc = send_seq(priv, {0x00, 0x00}); | ||||
| 
 | ||||
| 		/* Analog modes require offset = 0 */ | ||||
| @ -1054,7 +1054,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe, | ||||
| 		if (priv->ctrl.input1) | ||||
| 			type |= INPUT1; | ||||
| 		return generic_set_freq(fe, (625l * p->frequency) / 10, | ||||
| 				T_RADIO, type, 0, 0); | ||||
| 				V4L2_TUNER_RADIO, type, 0, 0); | ||||
| 	} | ||||
| 
 | ||||
| 	/* if std is not defined, choose one */ | ||||
| @ -1069,7 +1069,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe, | ||||
| 	p->std |= parse_audio_std_option(); | ||||
| 
 | ||||
| 	return generic_set_freq(fe, 62500l * p->frequency, | ||||
| 				T_ANALOG_TV, type, p->std, 0); | ||||
| 				V4L2_TUNER_ANALOG_TV, type, p->std, 0); | ||||
| } | ||||
| 
 | ||||
| static int xc2028_set_params(struct dvb_frontend *fe, | ||||
| @ -1174,7 +1174,7 @@ static int xc2028_set_params(struct dvb_frontend *fe, | ||||
| 	} | ||||
| 
 | ||||
| 	return generic_set_freq(fe, p->frequency, | ||||
| 				T_DIGITAL_TV, type, 0, demod); | ||||
| 				V4L2_TUNER_DIGITAL_TV, type, 0, demod); | ||||
| } | ||||
| 
 | ||||
| static int xc2028_sleep(struct dvb_frontend *fe) | ||||
|  | ||||
| @ -65,7 +65,7 @@ struct xc5000_priv { | ||||
| }; | ||||
| 
 | ||||
| /* Misc Defines */ | ||||
| #define MAX_TV_STANDARD			23 | ||||
| #define MAX_TV_STANDARD			24 | ||||
| #define XC_MAX_I2C_WRITE_LENGTH		64 | ||||
| 
 | ||||
| /* Signal Types */ | ||||
| @ -92,6 +92,8 @@ struct xc5000_priv { | ||||
| #define XREG_IF_OUT       0x05 | ||||
| #define XREG_SEEK_MODE    0x07 | ||||
| #define XREG_POWER_DOWN   0x0A /* Obsolete */ | ||||
| /* Set the output amplitude - SIF for analog, DTVP/DTVN for digital */ | ||||
| #define XREG_OUTPUT_AMP   0x0B | ||||
| #define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */ | ||||
| #define XREG_SMOOTHEDCVBS 0x0E | ||||
| #define XREG_XTALFREQ     0x0F | ||||
| @ -173,6 +175,7 @@ struct XC_TV_STANDARD { | ||||
| #define DTV7			20 | ||||
| #define FM_Radio_INPUT2 	21 | ||||
| #define FM_Radio_INPUT1 	22 | ||||
| #define FM_Radio_INPUT1_MONO	23 | ||||
| 
 | ||||
| static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { | ||||
| 	{"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, | ||||
| @ -197,7 +200,8 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { | ||||
| 	{"DTV7/8",            0x00C0, 0x801B}, | ||||
| 	{"DTV7",              0x00C0, 0x8007}, | ||||
| 	{"FM Radio-INPUT2",   0x9802, 0x9002}, | ||||
| 	{"FM Radio-INPUT1",   0x0208, 0x9002} | ||||
| 	{"FM Radio-INPUT1",   0x0208, 0x9002}, | ||||
| 	{"FM Radio-INPUT1_MONO", 0x0278, 0x9002} | ||||
| }; | ||||
| 
 | ||||
| static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); | ||||
| @ -683,6 +687,24 @@ static int xc5000_set_params(struct dvb_frontend *fe, | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
| 		priv->rf_mode = XC_RF_MODE_AIR; | ||||
| 	} else if (fe->ops.info.type == FE_QAM) { | ||||
| 		dprintk(1, "%s() QAM\n", __func__); | ||||
| 		switch (params->u.qam.modulation) { | ||||
| 		case QAM_16: | ||||
| 		case QAM_32: | ||||
| 		case QAM_64: | ||||
| 		case QAM_128: | ||||
| 		case QAM_256: | ||||
| 		case QAM_AUTO: | ||||
| 			dprintk(1, "%s() QAM modulation\n", __func__); | ||||
| 			priv->bandwidth = BANDWIDTH_8_MHZ; | ||||
| 			priv->video_standard = DTV7_8; | ||||
| 			priv->freq_hz = params->frequency - 2750000; | ||||
| 			priv->rf_mode = XC_RF_MODE_CABLE; | ||||
| 			break; | ||||
| 		default: | ||||
| 			return -EINVAL; | ||||
| 		} | ||||
| 	} else { | ||||
| 		printk(KERN_ERR "xc5000 modulation type not supported!\n"); | ||||
| 		return -EINVAL; | ||||
| @ -714,6 +736,8 @@ static int xc5000_set_params(struct dvb_frontend *fe, | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 
 | ||||
| 	xc_write_reg(priv, XREG_OUTPUT_AMP, 0x8a); | ||||
| 
 | ||||
| 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL); | ||||
| 
 | ||||
| 	if (debug) | ||||
| @ -818,6 +842,8 @@ tune_channel: | ||||
| 		return -EREMOTEIO; | ||||
| 	} | ||||
| 
 | ||||
| 	xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09); | ||||
| 
 | ||||
| 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); | ||||
| 
 | ||||
| 	if (debug) | ||||
| @ -845,6 +871,8 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe, | ||||
| 		radio_input = FM_Radio_INPUT1; | ||||
| 	else if  (priv->radio_input == XC5000_RADIO_FM2) | ||||
| 		radio_input = FM_Radio_INPUT2; | ||||
| 	else if  (priv->radio_input == XC5000_RADIO_FM1_MONO) | ||||
| 		radio_input = FM_Radio_INPUT1_MONO; | ||||
| 	else { | ||||
| 		dprintk(1, "%s() unknown radio input %d\n", __func__, | ||||
| 			priv->radio_input); | ||||
| @ -871,6 +899,12 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe, | ||||
| 		return -EREMOTEIO; | ||||
| 	} | ||||
| 
 | ||||
| 	if ((priv->radio_input == XC5000_RADIO_FM1) || | ||||
| 				(priv->radio_input == XC5000_RADIO_FM2)) | ||||
| 		xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09); | ||||
| 	else if  (priv->radio_input == XC5000_RADIO_FM1_MONO) | ||||
| 		xc_write_reg(priv, XREG_OUTPUT_AMP, 0x06); | ||||
| 
 | ||||
| 	xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); | ||||
| 
 | ||||
| 	return 0; | ||||
| @ -1021,6 +1055,23 @@ static int xc5000_release(struct dvb_frontend *fe) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int xc5000_set_config(struct dvb_frontend *fe, void *priv_cfg) | ||||
| { | ||||
| 	struct xc5000_priv *priv = fe->tuner_priv; | ||||
| 	struct xc5000_config *p = priv_cfg; | ||||
| 
 | ||||
| 	dprintk(1, "%s()\n", __func__); | ||||
| 
 | ||||
| 	if (p->if_khz) | ||||
| 		priv->if_khz = p->if_khz; | ||||
| 
 | ||||
| 	if (p->radio_input) | ||||
| 		priv->radio_input = p->radio_input; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static const struct dvb_tuner_ops xc5000_tuner_ops = { | ||||
| 	.info = { | ||||
| 		.name           = "Xceive XC5000", | ||||
| @ -1033,6 +1084,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = { | ||||
| 	.init		   = xc5000_init, | ||||
| 	.sleep		   = xc5000_sleep, | ||||
| 
 | ||||
| 	.set_config	   = xc5000_set_config, | ||||
| 	.set_params	   = xc5000_set_params, | ||||
| 	.set_analog_params = xc5000_set_analog_params, | ||||
| 	.get_frequency	   = xc5000_get_frequency, | ||||
|  | ||||
| @ -40,6 +40,7 @@ struct xc5000_config { | ||||
| #define XC5000_RADIO_NOT_CONFIGURED		0 | ||||
| #define XC5000_RADIO_FM1			1 | ||||
| #define XC5000_RADIO_FM2			2 | ||||
| #define XC5000_RADIO_FM1_MONO			3 | ||||
| 
 | ||||
| /* For each bridge framework, when it attaches either analog or digital,
 | ||||
|  * it has to store a reference back to its _core equivalent structure, | ||||
|  | ||||
| @ -65,7 +65,7 @@ comment "Supported SDMC DM1105 Adapters" | ||||
| source "drivers/media/dvb/dm1105/Kconfig" | ||||
| 
 | ||||
| comment "Supported FireWire (IEEE 1394) Adapters" | ||||
| 	depends on DVB_CORE && IEEE1394 | ||||
| 	depends on DVB_CORE && FIREWIRE | ||||
| source "drivers/media/dvb/firewire/Kconfig" | ||||
| 
 | ||||
| comment "Supported Earthsoft PT1 Adapters" | ||||
|  | ||||
| @ -239,7 +239,6 @@ struct analog_demod_ops { | ||||
| 	void (*set_params)(struct dvb_frontend *fe, | ||||
| 			   struct analog_parameters *params); | ||||
| 	int  (*has_signal)(struct dvb_frontend *fe); | ||||
| 	int  (*is_stereo)(struct dvb_frontend *fe); | ||||
| 	int  (*get_afc)(struct dvb_frontend *fe); | ||||
| 	void (*tuner_status)(struct dvb_frontend *fe); | ||||
| 	void (*standby)(struct dvb_frontend *fe); | ||||
|  | ||||
| @ -358,3 +358,11 @@ config DVB_USB_LME2510 | ||||
| 	select DVB_IX2505V if !DVB_FE_CUSTOMISE | ||||
| 	help | ||||
| 	  Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . | ||||
| 
 | ||||
| config DVB_USB_TECHNISAT_USB2 | ||||
| 	tristate "Technisat DVB-S/S2 USB2.0 support" | ||||
| 	depends on DVB_USB | ||||
| 	select DVB_STB0899 if !DVB_FE_CUSTOMISE | ||||
| 	select DVB_STB6100 if !DVB_FE_CUSTOMISE | ||||
| 	help | ||||
| 	  Say Y here to support the Technisat USB2 DVB-S/S2 device | ||||
|  | ||||
| @ -91,6 +91,9 @@ obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o | ||||
| dvb-usb-lmedm04-objs = lmedm04.o | ||||
| obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o | ||||
| 
 | ||||
| dvb-usb-technisat-usb2-objs = technisat-usb2.o | ||||
| obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o | ||||
| 
 | ||||
| EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | ||||
| # due to tuner-xc3028
 | ||||
| EXTRA_CFLAGS += -Idrivers/media/common/tuners | ||||
|  | ||||
| @ -38,8 +38,8 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr | ||||
| } | ||||
| 
 | ||||
| static struct rc_map_table rc_map_a800_table[] = { | ||||
| 	{ 0x0201, KEY_PROG1 },       /* SOURCE */ | ||||
| 	{ 0x0200, KEY_POWER },       /* POWER */ | ||||
| 	{ 0x0201, KEY_MODE },      /* SOURCE */ | ||||
| 	{ 0x0200, KEY_POWER2 },      /* POWER */ | ||||
| 	{ 0x0205, KEY_1 },           /* 1 */ | ||||
| 	{ 0x0206, KEY_2 },           /* 2 */ | ||||
| 	{ 0x0207, KEY_3 },           /* 3 */ | ||||
| @ -52,8 +52,8 @@ static struct rc_map_table rc_map_a800_table[] = { | ||||
| 	{ 0x0212, KEY_LEFT },        /* L / DISPLAY */ | ||||
| 	{ 0x0211, KEY_0 },           /* 0 */ | ||||
| 	{ 0x0213, KEY_RIGHT },       /* R / CH RTN */ | ||||
| 	{ 0x0217, KEY_PROG2 },       /* SNAP SHOT */ | ||||
| 	{ 0x0210, KEY_PROG3 },       /* 16-CH PREV */ | ||||
| 	{ 0x0217, KEY_CAMERA },      /* SNAP SHOT */ | ||||
| 	{ 0x0210, KEY_LAST },        /* 16-CH PREV */ | ||||
| 	{ 0x021e, KEY_VOLUMEDOWN },  /* VOL DOWN */ | ||||
| 	{ 0x020c, KEY_ZOOM },        /* FULL SCREEN */ | ||||
| 	{ 0x021f, KEY_VOLUMEUP },    /* VOL UP */ | ||||
|  | ||||
| @ -479,6 +479,7 @@ static int af9015_init_endpoint(struct dvb_usb_device *d) | ||||
| 		ret = af9015_set_reg_bit(d, 0xd50b, 0); | ||||
| 	else | ||||
| 		ret = af9015_clear_reg_bit(d, 0xd50b, 0); | ||||
| 
 | ||||
| error: | ||||
| 	if (ret) | ||||
| 		err("endpoint init failed:%d", ret); | ||||
| @ -611,6 +612,11 @@ static int af9015_init(struct dvb_usb_device *d) | ||||
| 	int ret; | ||||
| 	deb_info("%s:\n", __func__); | ||||
| 
 | ||||
| 	/* init RC canary */ | ||||
| 	ret = af9015_write_reg(d, 0x98e9, 0xff); | ||||
| 	if (ret) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	ret = af9015_init_endpoint(d); | ||||
| 	if (ret) | ||||
| 		goto error; | ||||
| @ -659,9 +665,8 @@ error: | ||||
| static int af9015_download_firmware(struct usb_device *udev, | ||||
| 	const struct firmware *fw) | ||||
| { | ||||
| 	int i, len, packets, remainder, ret; | ||||
| 	int i, len, remaining, ret; | ||||
| 	struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; | ||||
| 	u16 addr = 0x5100; /* firmware start address */ | ||||
| 	u16 checksum = 0; | ||||
| 
 | ||||
| 	deb_info("%s:\n", __func__); | ||||
| @ -673,24 +678,20 @@ static int af9015_download_firmware(struct usb_device *udev, | ||||
| 	af9015_config.firmware_size = fw->size; | ||||
| 	af9015_config.firmware_checksum = checksum; | ||||
| 
 | ||||
| 	#define FW_PACKET_MAX_DATA  55 | ||||
| 
 | ||||
| 	packets = fw->size / FW_PACKET_MAX_DATA; | ||||
| 	remainder = fw->size % FW_PACKET_MAX_DATA; | ||||
| 	len = FW_PACKET_MAX_DATA; | ||||
| 	for (i = 0; i <= packets; i++) { | ||||
| 		if (i == packets)  /* set size of the last packet */ | ||||
| 			len = remainder; | ||||
| 	#define FW_ADDR 0x5100 /* firmware start address */ | ||||
| 	#define LEN_MAX 55 /* max packet size */ | ||||
| 	for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { | ||||
| 		len = remaining; | ||||
| 		if (len > LEN_MAX) | ||||
| 			len = LEN_MAX; | ||||
| 
 | ||||
| 		req.data_len = len; | ||||
| 		req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); | ||||
| 		req.addr = addr; | ||||
| 		addr += FW_PACKET_MAX_DATA; | ||||
| 		req.data = (u8 *) &fw->data[fw->size - remaining]; | ||||
| 		req.addr = FW_ADDR + fw->size - remaining; | ||||
| 
 | ||||
| 		ret = af9015_rw_udev(udev, &req); | ||||
| 		if (ret) { | ||||
| 			err("firmware download failed at packet %d with " \ | ||||
| 				"code %d", i, ret); | ||||
| 			err("firmware download failed:%d", ret); | ||||
| 			goto error; | ||||
| 		} | ||||
| 	} | ||||
| @ -738,6 +739,8 @@ static const struct af9015_rc_setup af9015_rc_setup_hashes[] = { | ||||
| }; | ||||
| 
 | ||||
| static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { | ||||
| 	{ (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_RC, | ||||
| 		RC_MAP_TERRATEC_SLIM_2 }, | ||||
| 	{ (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, | ||||
| 		RC_MAP_TERRATEC_SLIM }, | ||||
| 	{ (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700, | ||||
| @ -1016,22 +1019,38 @@ static int af9015_rc_query(struct dvb_usb_device *d) | ||||
| { | ||||
| 	struct af9015_state *priv = d->priv; | ||||
| 	int ret; | ||||
| 	u8 buf[16]; | ||||
| 	u8 buf[17]; | ||||
| 
 | ||||
| 	/* read registers needed to detect remote controller code */ | ||||
| 	ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); | ||||
| 	if (ret) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	if (buf[14] || buf[15]) { | ||||
| 	/* If any of these are non-zero, assume invalid data */ | ||||
| 	if (buf[1] || buf[2] || buf[3]) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	/* Check for repeat of previous code */ | ||||
| 	if ((priv->rc_repeat != buf[6] || buf[0]) && | ||||
| 					!memcmp(&buf[12], priv->rc_last, 4)) { | ||||
| 		deb_rc("%s: key repeated\n", __func__); | ||||
| 		rc_keydown(d->rc_dev, priv->rc_keycode, 0); | ||||
| 		priv->rc_repeat = buf[6]; | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Only process key if canary killed */ | ||||
| 	if (buf[16] != 0xff && buf[0] != 0x01) { | ||||
| 		deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, | ||||
| 			buf[12], buf[13], buf[14], buf[15]); | ||||
| 
 | ||||
| 		/* clean IR code from mem */ | ||||
| 		ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4); | ||||
| 		/* Reset the canary */ | ||||
| 		ret = af9015_write_reg(d, 0x98e9, 0xff); | ||||
| 		if (ret) | ||||
| 			goto error; | ||||
| 
 | ||||
| 		/* Remember this key */ | ||||
| 		memcpy(priv->rc_last, &buf[12], 4); | ||||
| 		if (buf[14] == (u8) ~buf[15]) { | ||||
| 			if (buf[12] == (u8) ~buf[13]) { | ||||
| 				/* NEC */ | ||||
| @ -1041,15 +1060,17 @@ static int af9015_rc_query(struct dvb_usb_device *d) | ||||
| 				priv->rc_keycode = buf[12] << 16 | | ||||
| 					buf[13] << 8 | buf[14]; | ||||
| 			} | ||||
| 			rc_keydown(d->rc_dev, priv->rc_keycode, 0); | ||||
| 		} else { | ||||
| 			priv->rc_keycode = 0; /* clear just for sure */ | ||||
| 			/* 32 bit NEC */ | ||||
| 			priv->rc_keycode = buf[12] << 24 | buf[13] << 16 | | ||||
| 					buf[14] << 8 | buf[15]; | ||||
| 		} | ||||
| 	} else if (priv->rc_repeat != buf[6] || buf[0]) { | ||||
| 		deb_rc("%s: key repeated\n", __func__); | ||||
| 		rc_keydown(d->rc_dev, priv->rc_keycode, 0); | ||||
| 	} else { | ||||
| 		deb_rc("%s: no key press\n", __func__); | ||||
| 		/* Invalidate last keypress */ | ||||
| 		/* Not really needed, but helps with debug */ | ||||
| 		priv->rc_last[2] = priv->rc_last[3]; | ||||
| 	} | ||||
| 
 | ||||
| 	priv->rc_repeat = buf[6]; | ||||
|  | ||||
| @ -102,6 +102,7 @@ struct af9015_state { | ||||
| 	struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ | ||||
| 	u8 rc_repeat; | ||||
| 	u32 rc_keycode; | ||||
| 	u8 rc_last[4]; | ||||
| }; | ||||
| 
 | ||||
| struct af9015_config { | ||||
|  | ||||
| @ -32,6 +32,7 @@ extern int dvb_usb_dib0700_debug; | ||||
| 	// 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
 | ||||
| 	// 2 Byte: MPEG2 mode:  4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
 | ||||
| 	// 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines)    4LSB(     "                "           )
 | ||||
| #define REQUEST_SET_I2C_PARAM       0x10 | ||||
| #define REQUEST_SET_RC              0x11 | ||||
| #define REQUEST_NEW_I2C_READ        0x12 | ||||
| #define REQUEST_NEW_I2C_WRITE       0x13 | ||||
| @ -61,6 +62,7 @@ extern struct i2c_algorithm dib0700_i2c_algo; | ||||
| extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, | ||||
| 			struct dvb_usb_device_description **desc, int *cold); | ||||
| extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type); | ||||
| extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz); | ||||
| 
 | ||||
| extern int dib0700_device_count; | ||||
| extern int dvb_usb_dib0700_ir_proto; | ||||
|  | ||||
| @ -186,7 +186,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, | ||||
| 						 msg[i].len, | ||||
| 						 USB_CTRL_GET_TIMEOUT); | ||||
| 			if (result < 0) { | ||||
| 				err("i2c read error (status = %d)\n", result); | ||||
| 				deb_info("i2c read error (status = %d)\n", result); | ||||
| 				break; | ||||
| 			} | ||||
| 
 | ||||
| @ -215,7 +215,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, | ||||
| 						 0, 0, buf, msg[i].len + 4, | ||||
| 						 USB_CTRL_GET_TIMEOUT); | ||||
| 			if (result < 0) { | ||||
| 				err("i2c write error (status = %d)\n", result); | ||||
| 				deb_info("i2c write error (status = %d)\n", result); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| @ -328,6 +328,31 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll, | ||||
| 	return dib0700_ctrl_wr(d, b, 10); | ||||
| } | ||||
| 
 | ||||
| int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz) | ||||
| { | ||||
| 	u16 divider; | ||||
| 	u8 b[8]; | ||||
| 
 | ||||
| 	if (scl_kHz == 0) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	b[0] = REQUEST_SET_I2C_PARAM; | ||||
| 	divider = (u16) (30000 / scl_kHz); | ||||
| 	b[2] = (u8) (divider >> 8); | ||||
| 	b[3] = (u8) (divider & 0xff); | ||||
| 	divider = (u16) (72000 / scl_kHz); | ||||
| 	b[4] = (u8) (divider >> 8); | ||||
| 	b[5] = (u8) (divider & 0xff); | ||||
| 	divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */ | ||||
| 	b[6] = (u8) (divider >> 8); | ||||
| 	b[7] = (u8) (divider & 0xff); | ||||
| 
 | ||||
| 	deb_info("setting I2C speed: %04x %04x %04x (%d kHz).", | ||||
| 		(b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz); | ||||
| 	return dib0700_ctrl_wr(d, b, 8); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) | ||||
| { | ||||
| 	switch (clk_MHz) { | ||||
| @ -459,10 +484,20 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | ||||
| 
 | ||||
| 	deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); | ||||
| 
 | ||||
| 	if (onoff) | ||||
| 		st->channel_state |=   1 << adap->id; | ||||
| 	else | ||||
| 		st->channel_state &= ~(1 << adap->id); | ||||
| 	st->channel_state &= ~0x3; | ||||
| 	if ((adap->stream.props.endpoint != 2) | ||||
| 			&& (adap->stream.props.endpoint != 3)) { | ||||
| 		deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->stream.props.endpoint); | ||||
| 		if (onoff) | ||||
| 			st->channel_state |=	1 << (adap->id); | ||||
| 		else | ||||
| 			st->channel_state |=	1 << ~(adap->id); | ||||
| 	} else { | ||||
| 		if (onoff) | ||||
| 			st->channel_state |=	1 << (adap->stream.props.endpoint-2); | ||||
| 		else | ||||
| 			st->channel_state |=	1 << (3-adap->stream.props.endpoint); | ||||
| 	} | ||||
| 
 | ||||
| 	b[2] |= st->channel_state; | ||||
| 
 | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -176,7 +176,7 @@ static struct rc_map_table rc_map_digitv_table[] = { | ||||
| 	{ 0xaf59, KEY_AUX }, | ||||
| 	{ 0x5f5a, KEY_DVD }, | ||||
| 	{ 0x6f5a, KEY_POWER }, | ||||
| 	{ 0x9f5a, KEY_MHP },     /* labelled 'Picture' */ | ||||
| 	{ 0x9f5a, KEY_CAMERA },     /* labelled 'Picture' */ | ||||
| 	{ 0xaf5a, KEY_AUDIO }, | ||||
| 	{ 0x5f65, KEY_INFO }, | ||||
| 	{ 0x6f65, KEY_F13 },     /* 16:9 */ | ||||
|  | ||||
| @ -106,8 +106,13 @@ | ||||
| #define USB_PID_DIBCOM_STK807XP				0x1f90 | ||||
| #define USB_PID_DIBCOM_STK807XPVR			0x1f98 | ||||
| #define USB_PID_DIBCOM_STK8096GP                        0x1fa0 | ||||
| #define USB_PID_DIBCOM_NIM8096MD                        0x1fa8 | ||||
| #define USB_PID_DIBCOM_ANCHOR_2135_COLD			0x2131 | ||||
| #define USB_PID_DIBCOM_STK7770P				0x1e80 | ||||
| #define USB_PID_DIBCOM_NIM7090				0x1bb2 | ||||
| #define USB_PID_DIBCOM_TFE7090PVR			0x1bb4 | ||||
| #define USB_PID_DIBCOM_NIM9090M				0x2383 | ||||
| #define USB_PID_DIBCOM_NIM9090MD			0x2384 | ||||
| #define USB_PID_DPOSH_M9206_COLD			0x9206 | ||||
| #define USB_PID_DPOSH_M9206_WARM			0xa090 | ||||
| #define USB_PID_E3C_EC168				0x1689 | ||||
| @ -312,4 +317,6 @@ | ||||
| #define USB_PID_TERRATEC_DVBS2CI_V2			0x10ac | ||||
| #define USB_PID_TECHNISAT_USB2_HDCI_V1			0x0001 | ||||
| #define USB_PID_TECHNISAT_USB2_HDCI_V2			0x0002 | ||||
| #define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2		0x0004 | ||||
| #define USB_PID_TECHNISAT_USB2_DVB_S2			0x0500 | ||||
| #endif | ||||
|  | ||||
| @ -273,7 +273,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d) | ||||
| 	dev->map_name = d->props.rc.core.rc_codes; | ||||
| 	dev->change_protocol = d->props.rc.core.change_protocol; | ||||
| 	dev->allowed_protos = d->props.rc.core.allowed_protos; | ||||
| 	dev->driver_type = RC_DRIVER_SCANCODE; | ||||
| 	dev->driver_type = d->props.rc.core.driver_type; | ||||
| 	usb_to_input_id(d->udev, &dev->input_id); | ||||
| 	dev->input_name = "IR-receiver inside an USB DVB receiver"; | ||||
| 	dev->input_phys = d->rc_phys; | ||||
|  | ||||
| @ -181,6 +181,7 @@ struct dvb_rc_legacy { | ||||
|  * @rc_codes: name of rc codes table | ||||
|  * @protocol: type of protocol(s) currently used by the driver | ||||
|  * @allowed_protos: protocol(s) supported by the driver | ||||
|  * @driver_type: Used to point if a device supports raw mode | ||||
|  * @change_protocol: callback to change protocol | ||||
|  * @rc_query: called to query an event event. | ||||
|  * @rc_interval: time in ms between two queries. | ||||
| @ -190,6 +191,7 @@ struct dvb_rc { | ||||
| 	char *rc_codes; | ||||
| 	u64 protocol; | ||||
| 	u64 allowed_protos; | ||||
| 	enum rc_driver_type driver_type; | ||||
| 	int (*change_protocol)(struct rc_dev *dev, u64 rc_type); | ||||
| 	char *module_name; | ||||
| 	int (*rc_query) (struct dvb_usb_device *d); | ||||
|  | ||||
| @ -1,15 +1,16 @@ | ||||
| /* DVB USB framework compliant Linux driver for the
 | ||||
| *	DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, | ||||
| *	TeVii S600, S630, S650, | ||||
| *	Prof 1100, 7500 Cards | ||||
| * Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) | ||||
| * | ||||
| *	This program is free software; you can redistribute it and/or modify it | ||||
| *	under the terms of the GNU General Public License as published by the | ||||
| *	Free Software Foundation, version 2. | ||||
| * | ||||
| * see Documentation/dvb/README.dvb-usb for more information | ||||
| */ | ||||
|  *	DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, | ||||
|  *	TeVii S600, S630, S650, S660, S480, | ||||
|  *	Prof 1100, 7500, | ||||
|  *	Geniatech SU3000 Cards | ||||
|  * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by) | ||||
|  * | ||||
|  *	This program is free software; you can redistribute it and/or modify it | ||||
|  *	under the terms of the GNU General Public License as published by the | ||||
|  *	Free Software Foundation, version 2. | ||||
|  * | ||||
|  * see Documentation/dvb/README.dvb-usb for more information | ||||
|  */ | ||||
| #include "dw2102.h" | ||||
| #include "si21xx.h" | ||||
| #include "stv0299.h" | ||||
| @ -55,6 +56,14 @@ | ||||
| #define USB_PID_TEVII_S660 0xd660 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef USB_PID_TEVII_S480_1 | ||||
| #define USB_PID_TEVII_S480_1 0xd481 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef USB_PID_TEVII_S480_2 | ||||
| #define USB_PID_TEVII_S480_2 0xd482 | ||||
| #endif | ||||
| 
 | ||||
| #ifndef USB_PID_PROF_1100 | ||||
| #define USB_PID_PROF_1100 0xb012 | ||||
| #endif | ||||
| @ -67,7 +76,9 @@ | ||||
| #define REG_21_SYMBOLRATE_BYTE2 0x21 | ||||
| /* on my own*/ | ||||
| #define DW2102_VOLTAGE_CTRL (0x1800) | ||||
| #define SU3000_STREAM_CTRL (0x1900) | ||||
| #define DW2102_RC_QUERY (0x1a00) | ||||
| #define DW2102_LED_CTRL (0x1b00) | ||||
| 
 | ||||
| #define	err_str "did not find the firmware file. (%s) " \ | ||||
| 		"Please see linux/Documentation/dvb/ for more details " \ | ||||
| @ -78,6 +89,14 @@ struct rc_map_dvb_usb_table_table { | ||||
| 	int rc_keys_size; | ||||
| }; | ||||
| 
 | ||||
| struct su3000_state { | ||||
| 	u8 initialized; | ||||
| }; | ||||
| 
 | ||||
| struct s6x0_state { | ||||
| 	int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v); | ||||
| }; | ||||
| 
 | ||||
| /* debug */ | ||||
| static int dvb_usb_dw2102_debug; | ||||
| module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); | ||||
| @ -87,7 +106,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))." | ||||
| /* keymaps */ | ||||
| static int ir_keymap; | ||||
| module_param_named(keymap, ir_keymap, int, 0644); | ||||
| MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs  ..."); | ||||
| MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs  ..." | ||||
| 			" 256=none"); | ||||
| 
 | ||||
| /* demod probe */ | ||||
| static int demod_probe = 1; | ||||
| @ -136,8 +156,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||||
| 		/* read stv0299 register */ | ||||
| 		value = msg[0].buf[0];/* register */ | ||||
| 		for (i = 0; i < msg[1].len; i++) { | ||||
| 			value = value + i; | ||||
| 			ret = dw210x_op_rw(d->udev, 0xb5, value, 0, | ||||
| 			ret = dw210x_op_rw(d->udev, 0xb5, value + i, 0, | ||||
| 					buf6, 2, DW210X_READ_MSG); | ||||
| 			msg[1].buf[i] = buf6[0]; | ||||
| 		} | ||||
| @ -483,10 +502,10 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||||
| 	for (j = 0; j < num; j++) { | ||||
| 		switch (msg[j].addr) { | ||||
| 		case (DW2102_RC_QUERY): { | ||||
| 			u8 ibuf[4]; | ||||
| 			u8 ibuf[5]; | ||||
| 			ret  = dw210x_op_rw(d->udev, 0xb8, 0, 0, | ||||
| 					ibuf, 4, DW210X_READ_MSG); | ||||
| 			memcpy(msg[j].buf, ibuf + 1, 2); | ||||
| 					ibuf, 5, DW210X_READ_MSG); | ||||
| 			memcpy(msg[j].buf, ibuf + 3, 2); | ||||
| 			break; | ||||
| 		} | ||||
| 		case (DW2102_VOLTAGE_CTRL): { | ||||
| @ -502,6 +521,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||||
| 					obuf, 2, DW210X_WRITE_MSG); | ||||
| 			break; | ||||
| 		} | ||||
| 		case (DW2102_LED_CTRL): { | ||||
| 			u8 obuf[2]; | ||||
| 
 | ||||
| 			obuf[0] = 5; | ||||
| 			obuf[1] = msg[j].buf[0]; | ||||
| 			ret = dw210x_op_rw(d->udev, 0x8a, 0, 0, | ||||
| 					obuf, 2, DW210X_WRITE_MSG); | ||||
| 			break; | ||||
| 		} | ||||
| 		/*case 0x55: cx24116
 | ||||
| 		case 0x6a: stv0903 | ||||
| 		case 0x68: ds3000, stv0903 | ||||
| @ -535,14 +563,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||||
| 					i += 16; | ||||
| 					len -= 16; | ||||
| 				} while (len > 0); | ||||
| 			} else if ((udev->descriptor.idProduct == 0x7500) | ||||
| 					&& (j < (num - 1))) { | ||||
| 			} else if (j < (num - 1)) { | ||||
| 				/* write register addr before read */ | ||||
| 				u8 obuf[msg[j].len + 2]; | ||||
| 				obuf[0] = msg[j + 1].len; | ||||
| 				obuf[1] = (msg[j].addr << 1); | ||||
| 				memcpy(obuf + 2, msg[j].buf, msg[j].len); | ||||
| 				ret = dw210x_op_rw(d->udev, 0x92, 0, 0, | ||||
| 				ret = dw210x_op_rw(d->udev, | ||||
| 						udev->descriptor.idProduct == | ||||
| 						0x7500 ? 0x92 : 0x90, 0, 0, | ||||
| 						obuf, msg[j].len + 2, | ||||
| 						DW210X_WRITE_MSG); | ||||
| 				break; | ||||
| @ -552,8 +581,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||||
| 				obuf[0] = msg[j].len + 1; | ||||
| 				obuf[1] = (msg[j].addr << 1); | ||||
| 				memcpy(obuf + 2, msg[j].buf, msg[j].len); | ||||
| 				ret = dw210x_op_rw(d->udev, | ||||
| 						(num > 1 ? 0x90 : 0x80), 0, 0, | ||||
| 				ret = dw210x_op_rw(d->udev, 0x80, 0, 0, | ||||
| 						obuf, msg[j].len + 2, | ||||
| 						DW210X_WRITE_MSG); | ||||
| 				break; | ||||
| @ -561,14 +589,76 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||||
| 			break; | ||||
| 		} | ||||
| 		} | ||||
| 
 | ||||
| 		msleep(3); | ||||
| 	} | ||||
| 
 | ||||
| 	mutex_unlock(&d->i2c_mutex); | ||||
| 	return num; | ||||
| } | ||||
| 
 | ||||
| static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[], | ||||
| 								int num) | ||||
| { | ||||
| 	struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||||
| 	u8 obuf[0x40], ibuf[0x40]; | ||||
| 
 | ||||
| 	if (!d) | ||||
| 		return -ENODEV; | ||||
| 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||||
| 		return -EAGAIN; | ||||
| 
 | ||||
| 	switch (num) { | ||||
| 	case 1: | ||||
| 		switch (msg[0].addr) { | ||||
| 		case SU3000_STREAM_CTRL: | ||||
| 			obuf[0] = msg[0].buf[0] + 0x36; | ||||
| 			obuf[1] = 3; | ||||
| 			obuf[2] = 0; | ||||
| 			if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0) | ||||
| 				err("i2c transfer failed."); | ||||
| 			break; | ||||
| 		case DW2102_RC_QUERY: | ||||
| 			obuf[0] = 0x10; | ||||
| 			if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0) | ||||
| 				err("i2c transfer failed."); | ||||
| 			msg[0].buf[1] = ibuf[0]; | ||||
| 			msg[0].buf[0] = ibuf[1]; | ||||
| 			break; | ||||
| 		default: | ||||
| 			/* always i2c write*/ | ||||
| 			obuf[0] = 0x08; | ||||
| 			obuf[1] = msg[0].addr; | ||||
| 			obuf[2] = msg[0].len; | ||||
| 
 | ||||
| 			memcpy(&obuf[3], msg[0].buf, msg[0].len); | ||||
| 
 | ||||
| 			if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3, | ||||
| 						ibuf, 1, 0) < 0) | ||||
| 				err("i2c transfer failed."); | ||||
| 
 | ||||
| 		} | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		/* always i2c read */ | ||||
| 		obuf[0] = 0x09; | ||||
| 		obuf[1] = msg[0].len; | ||||
| 		obuf[2] = msg[1].len; | ||||
| 		obuf[3] = msg[0].addr; | ||||
| 		memcpy(&obuf[4], msg[0].buf, msg[0].len); | ||||
| 
 | ||||
| 		if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4, | ||||
| 					ibuf, msg[1].len + 1, 0) < 0) | ||||
| 			err("i2c transfer failed."); | ||||
| 
 | ||||
| 		memcpy(msg[1].buf, &ibuf[1], msg[1].len); | ||||
| 		break; | ||||
| 	default: | ||||
| 		warn("more than 2 i2c messages at a time is not handled yet."); | ||||
| 		break; | ||||
| 	} | ||||
| 	mutex_unlock(&d->i2c_mutex); | ||||
| 	return num; | ||||
| } | ||||
| 
 | ||||
| static u32 dw210x_i2c_func(struct i2c_adapter *adapter) | ||||
| { | ||||
| 	return I2C_FUNC_I2C; | ||||
| @ -604,6 +694,11 @@ static struct i2c_algorithm s6x0_i2c_algo = { | ||||
| 	.functionality = dw210x_i2c_func, | ||||
| }; | ||||
| 
 | ||||
| static struct i2c_algorithm su3000_i2c_algo = { | ||||
| 	.master_xfer = su3000_i2c_transfer, | ||||
| 	.functionality = dw210x_i2c_func, | ||||
| }; | ||||
| 
 | ||||
| static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | ||||
| { | ||||
| 	int i; | ||||
| @ -668,6 +763,82 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | ||||
| 	return 0; | ||||
| }; | ||||
| 
 | ||||
| static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | ||||
| { | ||||
| 	static u8 command_start[] = {0x00}; | ||||
| 	static u8 command_stop[] = {0x01}; | ||||
| 	struct i2c_msg msg = { | ||||
| 		.addr = SU3000_STREAM_CTRL, | ||||
| 		.flags = 0, | ||||
| 		.buf = onoff ? command_start : command_stop, | ||||
| 		.len = 1 | ||||
| 	}; | ||||
| 
 | ||||
| 	i2c_transfer(&adap->dev->i2c_adap, &msg, 1); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int su3000_power_ctrl(struct dvb_usb_device *d, int i) | ||||
| { | ||||
| 	struct su3000_state *state = (struct su3000_state *)d->priv; | ||||
| 	u8 obuf[] = {0xde, 0}; | ||||
| 
 | ||||
| 	info("%s: %d, initialized %d\n", __func__, i, state->initialized); | ||||
| 
 | ||||
| 	if (i && !state->initialized) { | ||||
| 		state->initialized = 1; | ||||
| 		/* reset board */ | ||||
| 		dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) | ||||
| { | ||||
| 	int i; | ||||
| 	u8 obuf[] = { 0x1f, 0xf0 }; | ||||
| 	u8 ibuf[] = { 0 }; | ||||
| 	struct i2c_msg msg[] = { | ||||
| 		{ | ||||
| 			.addr = 0x51, | ||||
| 			.flags = 0, | ||||
| 			.buf = obuf, | ||||
| 			.len = 2, | ||||
| 		}, { | ||||
| 			.addr = 0x51, | ||||
| 			.flags = I2C_M_RD, | ||||
| 			.buf = ibuf, | ||||
| 			.len = 1, | ||||
| 
 | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	for (i = 0; i < 6; i++) { | ||||
| 		obuf[1] = 0xf0 + i; | ||||
| 		if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) | ||||
| 			break; | ||||
| 		else | ||||
| 			mac[i] = ibuf[0]; | ||||
| 
 | ||||
| 		debug_dump(mac, 6, printk); | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int su3000_identify_state(struct usb_device *udev, | ||||
| 				 struct dvb_usb_device_properties *props, | ||||
| 				 struct dvb_usb_device_description **desc, | ||||
| 				 int *cold) | ||||
| { | ||||
| 	info("%s\n", __func__); | ||||
| 
 | ||||
| 	*cold = 0; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||||
| { | ||||
| 	static u8 command_13v[] = {0x00, 0x01}; | ||||
| @ -692,6 +863,37 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||||
| { | ||||
| 	struct dvb_usb_adapter *d = | ||||
| 		(struct dvb_usb_adapter *)(fe->dvb->priv); | ||||
| 	struct s6x0_state *st = (struct s6x0_state *)d->dev->priv; | ||||
| 
 | ||||
| 	dw210x_set_voltage(fe, voltage); | ||||
| 	if (st->old_set_voltage) | ||||
| 		st->old_set_voltage(fe, voltage); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon) | ||||
| { | ||||
| 	static u8 led_off[] = { 0 }; | ||||
| 	static u8 led_on[] = { 1 }; | ||||
| 	struct i2c_msg msg = { | ||||
| 		.addr = DW2102_LED_CTRL, | ||||
| 		.flags = 0, | ||||
| 		.buf = led_off, | ||||
| 		.len = 1 | ||||
| 	}; | ||||
| 	struct dvb_usb_adapter *udev_adap = | ||||
| 		(struct dvb_usb_adapter *)(fe->dvb->priv); | ||||
| 
 | ||||
| 	if (offon) | ||||
| 		msg.buf = led_on; | ||||
| 	i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1); | ||||
| } | ||||
| 
 | ||||
| static struct stv0299_config sharp_z0194a_config = { | ||||
| 	.demod_address = 0x68, | ||||
| 	.inittab = sharp_z0194a_inittab, | ||||
| @ -771,6 +973,12 @@ static struct stv0900_config prof_7500_stv0900_config = { | ||||
| 	.tun1_adc = 0,/* 2 Vpp */ | ||||
| 	.path1_mode = 3, | ||||
| 	.tun1_type = 3, | ||||
| 	.set_lock_led = dw210x_led_ctrl, | ||||
| }; | ||||
| 
 | ||||
| static struct ds3000_config su3000_ds3000_config = { | ||||
| 	.demod_address = 0x68, | ||||
| 	.ci_mode = 1, | ||||
| }; | ||||
| 
 | ||||
| static int dw2104_frontend_attach(struct dvb_usb_adapter *d) | ||||
| @ -885,7 +1093,7 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d) | ||||
| 	return -EIO; | ||||
| } | ||||
| 
 | ||||
| static int s6x0_frontend_attach(struct dvb_usb_adapter *d) | ||||
| static int zl100313_frontend_attach(struct dvb_usb_adapter *d) | ||||
| { | ||||
| 	d->fe = dvb_attach(mt312_attach, &zl313_config, | ||||
| 			&d->dev->i2c_adap); | ||||
| @ -898,41 +1106,108 @@ static int s6x0_frontend_attach(struct dvb_usb_adapter *d) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return -EIO; | ||||
| } | ||||
| 
 | ||||
| static int stv0288_frontend_attach(struct dvb_usb_adapter *d) | ||||
| { | ||||
| 	u8 obuf[] = {7, 1}; | ||||
| 
 | ||||
| 	d->fe = dvb_attach(stv0288_attach, &earda_config, | ||||
| 			&d->dev->i2c_adap); | ||||
| 	if (d->fe != NULL) { | ||||
| 		if (dvb_attach(stb6000_attach, d->fe, 0x61, | ||||
| 				&d->dev->i2c_adap)) { | ||||
| 			d->fe->ops.set_voltage = dw210x_set_voltage; | ||||
| 			info("Attached stv0288+stb6000!\n"); | ||||
| 			return 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (d->fe == NULL) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	if (NULL == dvb_attach(stb6000_attach, d->fe, 0x61, &d->dev->i2c_adap)) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	d->fe->ops.set_voltage = dw210x_set_voltage; | ||||
| 
 | ||||
| 	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); | ||||
| 
 | ||||
| 	info("Attached stv0288+stb6000!\n"); | ||||
| 
 | ||||
| 	return 0; | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static int ds3000_frontend_attach(struct dvb_usb_adapter *d) | ||||
| { | ||||
| 	struct s6x0_state *st = (struct s6x0_state *)d->dev->priv; | ||||
| 	u8 obuf[] = {7, 1}; | ||||
| 
 | ||||
| 	d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, | ||||
| 			&d->dev->i2c_adap); | ||||
| 	if (d->fe != NULL) { | ||||
| 		d->fe->ops.set_voltage = dw210x_set_voltage; | ||||
| 		info("Attached ds3000+ds2020!\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return -EIO; | ||||
| 	if (d->fe == NULL) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	st->old_set_voltage = d->fe->ops.set_voltage; | ||||
| 	d->fe->ops.set_voltage = s660_set_voltage; | ||||
| 
 | ||||
| 	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); | ||||
| 
 | ||||
| 	info("Attached ds3000+ds2020!\n"); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) | ||||
| { | ||||
| 	u8 obuf[] = {7, 1}; | ||||
| 
 | ||||
| 	d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, | ||||
| 					&d->dev->i2c_adap, 0); | ||||
| 	if (d->fe == NULL) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	d->fe->ops.set_voltage = dw210x_set_voltage; | ||||
| 
 | ||||
| 	dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); | ||||
| 
 | ||||
| 	info("Attached STV0900+STB6100A!\n"); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int su3000_frontend_attach(struct dvb_usb_adapter *d) | ||||
| { | ||||
| 	u8 obuf[3] = { 0xe, 0x80, 0 }; | ||||
| 	u8 ibuf[] = { 0 }; | ||||
| 
 | ||||
| 	if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | ||||
| 		err("command 0x0e transfer failed."); | ||||
| 
 | ||||
| 	obuf[0] = 0xe; | ||||
| 	obuf[1] = 0x83; | ||||
| 	obuf[2] = 0; | ||||
| 
 | ||||
| 	if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | ||||
| 		err("command 0x0e transfer failed."); | ||||
| 
 | ||||
| 	obuf[0] = 0xe; | ||||
| 	obuf[1] = 0x83; | ||||
| 	obuf[2] = 1; | ||||
| 
 | ||||
| 	if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0) | ||||
| 		err("command 0x0e transfer failed."); | ||||
| 
 | ||||
| 	obuf[0] = 0x51; | ||||
| 
 | ||||
| 	if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) | ||||
| 		err("command 0x51 transfer failed."); | ||||
| 
 | ||||
| 	d->fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, | ||||
| 					&d->dev->i2c_adap); | ||||
| 	if (d->fe == NULL) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	info("Attached DS3000!\n"); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) | ||||
| { | ||||
| 	dvb_attach(dvb_pll_attach, adap->fe, 0x60, | ||||
| @ -949,8 +1224,8 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) | ||||
| } | ||||
| 
 | ||||
| static struct rc_map_table rc_map_dw210x_table[] = { | ||||
| 	{ 0xf80a, KEY_Q },		/*power*/ | ||||
| 	{ 0xf80c, KEY_M },		/*mute*/ | ||||
| 	{ 0xf80a, KEY_POWER2 },		/*power*/ | ||||
| 	{ 0xf80c, KEY_MUTE },		/*mute*/ | ||||
| 	{ 0xf811, KEY_1 }, | ||||
| 	{ 0xf812, KEY_2 }, | ||||
| 	{ 0xf813, KEY_3 }, | ||||
| @ -961,25 +1236,25 @@ static struct rc_map_table rc_map_dw210x_table[] = { | ||||
| 	{ 0xf818, KEY_8 }, | ||||
| 	{ 0xf819, KEY_9 }, | ||||
| 	{ 0xf810, KEY_0 }, | ||||
| 	{ 0xf81c, KEY_PAGEUP },	/*ch+*/ | ||||
| 	{ 0xf80f, KEY_PAGEDOWN },	/*ch-*/ | ||||
| 	{ 0xf81a, KEY_O },		/*vol+*/ | ||||
| 	{ 0xf80e, KEY_Z },		/*vol-*/ | ||||
| 	{ 0xf804, KEY_R },		/*rec*/ | ||||
| 	{ 0xf809, KEY_D },		/*fav*/ | ||||
| 	{ 0xf808, KEY_BACKSPACE },	/*rewind*/ | ||||
| 	{ 0xf807, KEY_A },		/*fast*/ | ||||
| 	{ 0xf80b, KEY_P },		/*pause*/ | ||||
| 	{ 0xf802, KEY_ESC },	/*cancel*/ | ||||
| 	{ 0xf803, KEY_G },		/*tab*/ | ||||
| 	{ 0xf81c, KEY_CHANNELUP },	/*ch+*/ | ||||
| 	{ 0xf80f, KEY_CHANNELDOWN },	/*ch-*/ | ||||
| 	{ 0xf81a, KEY_VOLUMEUP },	/*vol+*/ | ||||
| 	{ 0xf80e, KEY_VOLUMEDOWN },	/*vol-*/ | ||||
| 	{ 0xf804, KEY_RECORD },		/*rec*/ | ||||
| 	{ 0xf809, KEY_FAVORITES },	/*fav*/ | ||||
| 	{ 0xf808, KEY_REWIND },		/*rewind*/ | ||||
| 	{ 0xf807, KEY_FASTFORWARD },	/*fast*/ | ||||
| 	{ 0xf80b, KEY_PAUSE },		/*pause*/ | ||||
| 	{ 0xf802, KEY_ESC },		/*cancel*/ | ||||
| 	{ 0xf803, KEY_TAB },		/*tab*/ | ||||
| 	{ 0xf800, KEY_UP },		/*up*/ | ||||
| 	{ 0xf81f, KEY_ENTER },	/*ok*/ | ||||
| 	{ 0xf801, KEY_DOWN },	/*down*/ | ||||
| 	{ 0xf805, KEY_C },		/*cap*/ | ||||
| 	{ 0xf806, KEY_S },		/*stop*/ | ||||
| 	{ 0xf840, KEY_F },		/*full*/ | ||||
| 	{ 0xf81e, KEY_W },		/*tvmode*/ | ||||
| 	{ 0xf81b, KEY_B },		/*recall*/ | ||||
| 	{ 0xf81f, KEY_OK },		/*ok*/ | ||||
| 	{ 0xf801, KEY_DOWN },		/*down*/ | ||||
| 	{ 0xf805, KEY_CAMERA },		/*cap*/ | ||||
| 	{ 0xf806, KEY_STOP },		/*stop*/ | ||||
| 	{ 0xf840, KEY_ZOOM },		/*full*/ | ||||
| 	{ 0xf81e, KEY_TV },		/*tvmode*/ | ||||
| 	{ 0xf81b, KEY_LAST },		/*recall*/ | ||||
| }; | ||||
| 
 | ||||
| static struct rc_map_table rc_map_tevii_table[] = { | ||||
| @ -1067,10 +1342,49 @@ static struct rc_map_table rc_map_tbs_table[] = { | ||||
| 	{ 0xf89b, KEY_MODE } | ||||
| }; | ||||
| 
 | ||||
| static struct rc_map_table rc_map_su3000_table[] = { | ||||
| 	{ 0x25, KEY_POWER },	/* right-bottom Red */ | ||||
| 	{ 0x0a, KEY_MUTE },	/* -/-- */ | ||||
| 	{ 0x01, KEY_1 }, | ||||
| 	{ 0x02, KEY_2 }, | ||||
| 	{ 0x03, KEY_3 }, | ||||
| 	{ 0x04, KEY_4 }, | ||||
| 	{ 0x05, KEY_5 }, | ||||
| 	{ 0x06, KEY_6 }, | ||||
| 	{ 0x07, KEY_7 }, | ||||
| 	{ 0x08, KEY_8 }, | ||||
| 	{ 0x09, KEY_9 }, | ||||
| 	{ 0x00, KEY_0 }, | ||||
| 	{ 0x20, KEY_UP },	/* CH+ */ | ||||
| 	{ 0x21, KEY_DOWN },	/* CH+ */ | ||||
| 	{ 0x12, KEY_VOLUMEUP },	/* Brightness Up */ | ||||
| 	{ 0x13, KEY_VOLUMEDOWN },/* Brightness Down */ | ||||
| 	{ 0x1f, KEY_RECORD }, | ||||
| 	{ 0x17, KEY_PLAY }, | ||||
| 	{ 0x16, KEY_PAUSE }, | ||||
| 	{ 0x0b, KEY_STOP }, | ||||
| 	{ 0x27, KEY_FASTFORWARD },/* >> */ | ||||
| 	{ 0x26, KEY_REWIND },	/* << */ | ||||
| 	{ 0x0d, KEY_OK },	/* Mute */ | ||||
| 	{ 0x11, KEY_LEFT },	/* VOL- */ | ||||
| 	{ 0x10, KEY_RIGHT },	/* VOL+ */ | ||||
| 	{ 0x29, KEY_BACK },	/* button under 9 */ | ||||
| 	{ 0x2c, KEY_MENU },	/* TTX */ | ||||
| 	{ 0x2b, KEY_EPG },	/* EPG */ | ||||
| 	{ 0x1e, KEY_RED },	/* OSD */ | ||||
| 	{ 0x0e, KEY_GREEN },	/* Window */ | ||||
| 	{ 0x2d, KEY_YELLOW },	/* button under << */ | ||||
| 	{ 0x0f, KEY_BLUE },	/* bottom yellow button */ | ||||
| 	{ 0x14, KEY_AUDIO },	/* Snapshot */ | ||||
| 	{ 0x38, KEY_TV },	/* TV/Radio */ | ||||
| 	{ 0x0c, KEY_ESC }	/* upper Red buttton */ | ||||
| }; | ||||
| 
 | ||||
| static struct rc_map_dvb_usb_table_table keys_tables[] = { | ||||
| 	{ rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) }, | ||||
| 	{ rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) }, | ||||
| 	{ rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) }, | ||||
| 	{ rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) }, | ||||
| }; | ||||
| 
 | ||||
| static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | ||||
| @ -1089,7 +1403,8 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | ||||
| 	if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) { | ||||
| 		keymap = keys_tables[ir_keymap - 1].rc_keys ; | ||||
| 		keymap_size = keys_tables[ir_keymap - 1].rc_keys_size; | ||||
| 	} | ||||
| 	} else if (ir_keymap > ARRAY_SIZE(keys_tables)) | ||||
| 		return 0; /* none */ | ||||
| 
 | ||||
| 	*state = REMOTE_NO_KEY_PRESSED; | ||||
| 	if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { | ||||
| @ -1125,6 +1440,11 @@ static struct usb_device_id dw2102_table[] = { | ||||
| 	{USB_DEVICE(0x3011, USB_PID_PROF_1100)}, | ||||
| 	{USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, | ||||
| 	{USB_DEVICE(0x3034, 0x7500)}, | ||||
| 	{USB_DEVICE(0x1f4d, 0x3000)}, | ||||
| 	{USB_DEVICE(USB_VID_TERRATEC, 0x00a8)}, | ||||
| 	{USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)}, | ||||
| 	{USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)}, | ||||
| 	{USB_DEVICE(0x1f4d, 0x3100)}, | ||||
| 	{ } | ||||
| }; | ||||
| 
 | ||||
| @ -1184,11 +1504,6 @@ static int dw2102_load_firmware(struct usb_device *dev, | ||||
| 		} | ||||
| 		/* init registers */ | ||||
| 		switch (dev->descriptor.idProduct) { | ||||
| 		case USB_PID_PROF_1100: | ||||
| 			s6x0_properties.rc.legacy.rc_map_table = rc_map_tbs_table; | ||||
| 			s6x0_properties.rc.legacy.rc_map_size = | ||||
| 					ARRAY_SIZE(rc_map_tbs_table); | ||||
| 			break; | ||||
| 		case USB_PID_TEVII_S650: | ||||
| 			dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table; | ||||
| 			dw2104_properties.rc.legacy.rc_map_size = | ||||
| @ -1271,8 +1586,6 @@ static struct dvb_usb_device_properties dw2102_properties = { | ||||
| 	.adapter = { | ||||
| 		{ | ||||
| 			.frontend_attach = dw2102_frontend_attach, | ||||
| 			.streaming_ctrl = NULL, | ||||
| 			.tuner_attach = NULL, | ||||
| 			.stream = { | ||||
| 				.type = USB_BULK, | ||||
| 				.count = 8, | ||||
| @ -1324,8 +1637,6 @@ static struct dvb_usb_device_properties dw2104_properties = { | ||||
| 	.adapter = { | ||||
| 		{ | ||||
| 			.frontend_attach = dw2104_frontend_attach, | ||||
| 			.streaming_ctrl = NULL, | ||||
| 			/*.tuner_attach = dw2104_tuner_attach,*/ | ||||
| 			.stream = { | ||||
| 				.type = USB_BULK, | ||||
| 				.count = 8, | ||||
| @ -1373,7 +1684,6 @@ static struct dvb_usb_device_properties dw3101_properties = { | ||||
| 	.adapter = { | ||||
| 		{ | ||||
| 			.frontend_attach = dw3101_frontend_attach, | ||||
| 			.streaming_ctrl = NULL, | ||||
| 			.tuner_attach = dw3101_tuner_attach, | ||||
| 			.stream = { | ||||
| 				.type = USB_BULK, | ||||
| @ -1399,6 +1709,7 @@ static struct dvb_usb_device_properties dw3101_properties = { | ||||
| static struct dvb_usb_device_properties s6x0_properties = { | ||||
| 	.caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||||
| 	.usb_ctrl = DEVICE_SPECIFIC, | ||||
| 	.size_of_priv = sizeof(struct s6x0_state), | ||||
| 	.firmware = "dvb-usb-s630.fw", | ||||
| 	.no_reconnect = 1, | ||||
| 
 | ||||
| @ -1416,9 +1727,7 @@ static struct dvb_usb_device_properties s6x0_properties = { | ||||
| 	.read_mac_address = s6x0_read_mac_address, | ||||
| 	.adapter = { | ||||
| 		{ | ||||
| 			.frontend_attach = s6x0_frontend_attach, | ||||
| 			.streaming_ctrl = NULL, | ||||
| 			.tuner_attach = NULL, | ||||
| 			.frontend_attach = zl100313_frontend_attach, | ||||
| 			.stream = { | ||||
| 				.type = USB_BULK, | ||||
| 				.count = 8, | ||||
| @ -1431,23 +1740,41 @@ static struct dvb_usb_device_properties s6x0_properties = { | ||||
| 			}, | ||||
| 		} | ||||
| 	}, | ||||
| 	.num_device_descs = 3, | ||||
| 	.num_device_descs = 1, | ||||
| 	.devices = { | ||||
| 		{"TeVii S630 USB", | ||||
| 			{&dw2102_table[6], NULL}, | ||||
| 			{NULL}, | ||||
| 		}, | ||||
| 		{"Prof 1100 USB ", | ||||
| 			{&dw2102_table[7], NULL}, | ||||
| 			{NULL}, | ||||
| 		}, | ||||
| 		{"TeVii S660 USB", | ||||
| 			{&dw2102_table[8], NULL}, | ||||
| 			{NULL}, | ||||
| 		}, | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| struct dvb_usb_device_properties *p1100; | ||||
| static struct dvb_usb_device_description d1100 = { | ||||
| 	"Prof 1100 USB ", | ||||
| 	{&dw2102_table[7], NULL}, | ||||
| 	{NULL}, | ||||
| }; | ||||
| 
 | ||||
| struct dvb_usb_device_properties *s660; | ||||
| static struct dvb_usb_device_description d660 = { | ||||
| 	"TeVii S660 USB", | ||||
| 	{&dw2102_table[8], NULL}, | ||||
| 	{NULL}, | ||||
| }; | ||||
| 
 | ||||
| static struct dvb_usb_device_description d480_1 = { | ||||
| 	"TeVii S480.1 USB", | ||||
| 	{&dw2102_table[12], NULL}, | ||||
| 	{NULL}, | ||||
| }; | ||||
| 
 | ||||
| static struct dvb_usb_device_description d480_2 = { | ||||
| 	"TeVii S480.2 USB", | ||||
| 	{&dw2102_table[13], NULL}, | ||||
| 	{NULL}, | ||||
| }; | ||||
| 
 | ||||
| struct dvb_usb_device_properties *p7500; | ||||
| static struct dvb_usb_device_description d7500 = { | ||||
| 	"Prof 7500 USB DVB-S2", | ||||
| @ -1455,17 +1782,97 @@ static struct dvb_usb_device_description d7500 = { | ||||
| 	{NULL}, | ||||
| }; | ||||
| 
 | ||||
| static struct dvb_usb_device_properties su3000_properties = { | ||||
| 	.caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||||
| 	.usb_ctrl = DEVICE_SPECIFIC, | ||||
| 	.size_of_priv = sizeof(struct su3000_state), | ||||
| 	.power_ctrl = su3000_power_ctrl, | ||||
| 	.num_adapters = 1, | ||||
| 	.identify_state	= su3000_identify_state, | ||||
| 	.i2c_algo = &su3000_i2c_algo, | ||||
| 
 | ||||
| 	.rc.legacy = { | ||||
| 		.rc_map_table = rc_map_su3000_table, | ||||
| 		.rc_map_size = ARRAY_SIZE(rc_map_su3000_table), | ||||
| 		.rc_interval = 150, | ||||
| 		.rc_query = dw2102_rc_query, | ||||
| 	}, | ||||
| 
 | ||||
| 	.read_mac_address = su3000_read_mac_address, | ||||
| 
 | ||||
| 	.generic_bulk_ctrl_endpoint = 0x01, | ||||
| 
 | ||||
| 	.adapter = { | ||||
| 		{ | ||||
| 			.streaming_ctrl   = su3000_streaming_ctrl, | ||||
| 			.frontend_attach  = su3000_frontend_attach, | ||||
| 			.stream = { | ||||
| 				.type = USB_BULK, | ||||
| 				.count = 8, | ||||
| 				.endpoint = 0x82, | ||||
| 				.u = { | ||||
| 					.bulk = { | ||||
| 						.buffersize = 4096, | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	}, | ||||
| 	.num_device_descs = 3, | ||||
| 	.devices = { | ||||
| 		{ "SU3000HD DVB-S USB2.0", | ||||
| 			{ &dw2102_table[10], NULL }, | ||||
| 			{ NULL }, | ||||
| 		}, | ||||
| 		{ "Terratec Cinergy S2 USB HD", | ||||
| 			{ &dw2102_table[11], NULL }, | ||||
| 			{ NULL }, | ||||
| 		}, | ||||
| 		{ "X3M TV SPC1400HD PCI", | ||||
| 			{ &dw2102_table[14], NULL }, | ||||
| 			{ NULL }, | ||||
| 		}, | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| static int dw2102_probe(struct usb_interface *intf, | ||||
| 		const struct usb_device_id *id) | ||||
| { | ||||
| 
 | ||||
| 	p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | ||||
| 	if (!p7500) | ||||
| 	p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | ||||
| 	if (!p1100) | ||||
| 		return -ENOMEM; | ||||
| 	/* copy default structure */ | ||||
| 	memcpy(p7500, &s6x0_properties, | ||||
| 	memcpy(p1100, &s6x0_properties, | ||||
| 			sizeof(struct dvb_usb_device_properties)); | ||||
| 	/* fill only different fields */ | ||||
| 	p1100->firmware = "dvb-usb-p1100.fw"; | ||||
| 	p1100->devices[0] = d1100; | ||||
| 	p1100->rc.legacy.rc_map_table = rc_map_tbs_table; | ||||
| 	p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); | ||||
| 	p1100->adapter->frontend_attach = stv0288_frontend_attach; | ||||
| 
 | ||||
| 	s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | ||||
| 	if (!s660) { | ||||
| 		kfree(p1100); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	memcpy(s660, &s6x0_properties, | ||||
| 			sizeof(struct dvb_usb_device_properties)); | ||||
| 	s660->firmware = "dvb-usb-s660.fw"; | ||||
| 	s660->num_device_descs = 3; | ||||
| 	s660->devices[0] = d660; | ||||
| 	s660->devices[1] = d480_1; | ||||
| 	s660->devices[2] = d480_2; | ||||
| 	s660->adapter->frontend_attach = ds3000_frontend_attach; | ||||
| 
 | ||||
| 	p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); | ||||
| 	if (!p7500) { | ||||
| 		kfree(p1100); | ||||
| 		kfree(s660); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	memcpy(p7500, &s6x0_properties, | ||||
| 			sizeof(struct dvb_usb_device_properties)); | ||||
| 	p7500->firmware = "dvb-usb-p7500.fw"; | ||||
| 	p7500->devices[0] = d7500; | ||||
| 	p7500->rc.legacy.rc_map_table = rc_map_tbs_table; | ||||
| @ -1480,8 +1887,14 @@ static int dw2102_probe(struct usb_interface *intf, | ||||
| 			THIS_MODULE, NULL, adapter_nr) || | ||||
| 	    0 == dvb_usb_device_init(intf, &s6x0_properties, | ||||
| 			THIS_MODULE, NULL, adapter_nr) || | ||||
| 	    0 == dvb_usb_device_init(intf, p1100, | ||||
| 			THIS_MODULE, NULL, adapter_nr) || | ||||
| 	    0 == dvb_usb_device_init(intf, s660, | ||||
| 			THIS_MODULE, NULL, adapter_nr) || | ||||
| 	    0 == dvb_usb_device_init(intf, p7500, | ||||
| 			THIS_MODULE, NULL, adapter_nr)) | ||||
| 			THIS_MODULE, NULL, adapter_nr) || | ||||
| 	    0 == dvb_usb_device_init(intf, &su3000_properties, | ||||
| 				     THIS_MODULE, NULL, adapter_nr)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	return -ENODEV; | ||||
| @ -1514,7 +1927,8 @@ module_exit(dw2102_module_exit); | ||||
| MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); | ||||
| MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," | ||||
| 				" DVB-C 3101 USB2.0," | ||||
| 				" TeVii S600, S630, S650, S660 USB2.0," | ||||
| 				" Prof 1100, 7500 USB2.0 devices"); | ||||
| 				" TeVii S600, S630, S650, S660, S480," | ||||
| 				" Prof 1100, 7500 USB2.0," | ||||
| 				" Geniatech SU3000 devices"); | ||||
| MODULE_VERSION("0.1"); | ||||
| MODULE_LICENSE("GPL"); | ||||
|  | ||||
| @ -2,7 +2,9 @@ | ||||
|  * | ||||
|  * DM04/QQBOX DVB-S USB BOX	LME2510C + SHARP:BS2F7HZ7395 | ||||
|  *				LME2510C + LG TDQY-P001F | ||||
|  *				LME2510C + BS2F7HZ0194 | ||||
|  *				LME2510 + LG TDQY-P001F | ||||
|  *				LME2510 + BS2F7HZ0194 | ||||
|  * | ||||
|  * MVB7395 (LME2510C+SHARP:BS2F7HZ7395) | ||||
|  * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V) | ||||
| @ -12,20 +14,22 @@ | ||||
|  * | ||||
|  * MVB0001F (LME2510C+LGTDQT-P001F) | ||||
|  * | ||||
|  * MV0194 (LME2510+SHARP:BS2F7HZ0194) | ||||
|  * SHARP:BS2F7HZ0194 = (STV0299+IX2410) | ||||
|  * | ||||
|  * MVB0194 (LME2510C+SHARP0194) | ||||
|  * | ||||
|  * For firmware see Documentation/dvb/lmedm04.txt | ||||
|  * | ||||
|  * I2C addresses: | ||||
|  * 0xd0 - STV0288	- Demodulator | ||||
|  * 0xc0 - Sharp IX2505V	- Tuner | ||||
|  * --or-- | ||||
|  * -- | ||||
|  * 0x1c - TDA10086   - Demodulator | ||||
|  * 0xc0 - TDA8263    - Tuner | ||||
|  * | ||||
|  * ***Please Note*** | ||||
|  *		There are other variants of the DM04 | ||||
|  *		***NOT SUPPORTED*** | ||||
|  *		MV0194 (LME2510+SHARP0194) | ||||
|  *		MVB0194 (LME2510C+SHARP0194) | ||||
|  * -- | ||||
|  * 0xd0 - STV0299	- Demodulator | ||||
|  * 0xc0 - IX2410	- Tuner | ||||
|  * | ||||
|  * | ||||
|  * VID = 3344  PID LME2510=1122 LME2510C=1120 | ||||
| @ -55,6 +59,9 @@ | ||||
|  * | ||||
|  * QQbox suffers from noise on LNB voltage. | ||||
|  * | ||||
|  *	LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system | ||||
|  * with other tuners. After a cold reset streaming will not start. | ||||
|  * | ||||
|  *	PID functions have been removed from this driver version due to | ||||
|  * problems with different firmware and application versions. | ||||
|  */ | ||||
| @ -69,6 +76,9 @@ | ||||
| #include "tda10086.h" | ||||
| #include "stv0288.h" | ||||
| #include "ix2505v.h" | ||||
| #include "stv0299.h" | ||||
| #include "dvb-pll.h" | ||||
| #include "z0194a.h" | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -96,8 +106,11 @@ MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG"); | ||||
| 
 | ||||
| 
 | ||||
| DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||||
| 
 | ||||
| #define TUNER_DEFAULT	0x0 | ||||
| #define TUNER_LG	0x1 | ||||
| #define TUNER_S7395	0x2 | ||||
| #define TUNER_S0194	0x3 | ||||
| 
 | ||||
| struct lme2510_state { | ||||
| 	u8 id; | ||||
| @ -191,7 +204,7 @@ static int lme2510_stream_restart(struct dvb_usb_device *d) | ||||
| 			rbuff, sizeof(rbuff)); | ||||
| 	return ret; | ||||
| } | ||||
| static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress) | ||||
| static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u32 keypress) | ||||
| { | ||||
| 	struct dvb_usb_device *d = adap->dev; | ||||
| 
 | ||||
| @ -237,7 +250,8 @@ static void lme2510_int_response(struct urb *lme_urb) | ||||
| 		case 0xaa: | ||||
| 			debug_data_snipet(1, "INT Remote data snipet in", ibuf); | ||||
| 			lme2510_remote_keypress(adap, | ||||
| 				(u16)(ibuf[4]<<8)+ibuf[5]); | ||||
| 				(u32)(ibuf[2] << 24) + (ibuf[3] << 16) + | ||||
| 				(ibuf[4] << 8) + ibuf[5]); | ||||
| 			break; | ||||
| 		case 0xbb: | ||||
| 			switch (st->tuner_config) { | ||||
| @ -249,6 +263,7 @@ static void lme2510_int_response(struct urb *lme_urb) | ||||
| 				st->time_key = ibuf[7]; | ||||
| 				break; | ||||
| 			case TUNER_S7395: | ||||
| 			case TUNER_S0194: | ||||
| 				/* Tweak for earlier firmware*/ | ||||
| 				if (ibuf[1] == 0x03) { | ||||
| 					if (ibuf[2] > 1) | ||||
| @ -364,6 +379,18 @@ static int lme2510_msg(struct dvb_usb_device *d, | ||||
| 					msleep(5); | ||||
| 			} | ||||
| 			break; | ||||
| 		case TUNER_S0194: | ||||
| 			if (wbuf[2] == 0xd0) { | ||||
| 				if (wbuf[3] == 0x1b) { | ||||
| 					st->signal_lock = rbuf[1]; | ||||
| 					if ((st->stream_on & 1) && | ||||
| 						(st->signal_lock & 0x8)) { | ||||
| 						lme2510_stream_restart(d); | ||||
| 						st->i2c_talk_onoff = 0; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 		} | ||||
| @ -423,6 +450,34 @@ static int lme2510_msg(struct dvb_usb_device *d, | ||||
| 				break; | ||||
| 			} | ||||
| 			break; | ||||
| 		case TUNER_S0194: | ||||
| 			switch (wbuf[3]) { | ||||
| 			case 0x18: | ||||
| 				rbuf[0] = 0x55; | ||||
| 				rbuf[1] = (st->signal_level & 0x80) | ||||
| 						? 0 : (st->signal_level * 2); | ||||
| 				break; | ||||
| 			case 0x24: | ||||
| 				rbuf[0] = 0x55; | ||||
| 				rbuf[1] = st->signal_sn; | ||||
| 				break; | ||||
| 			case 0x1b: | ||||
| 				rbuf[0] = 0x55; | ||||
| 				rbuf[1] = st->signal_lock; | ||||
| 				break; | ||||
| 			case 0x19: | ||||
| 			case 0x25: | ||||
| 			case 0x1e: | ||||
| 			case 0x1d: | ||||
| 				rbuf[0] = 0x55; | ||||
| 				rbuf[1] = 0x00; | ||||
| 				break; | ||||
| 			default: | ||||
| 				lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen); | ||||
| 				st->i2c_talk_onoff = 1; | ||||
| 				break; | ||||
| 			} | ||||
| 			break; | ||||
| 		default: | ||||
| 			break; | ||||
| 		} | ||||
| @ -517,17 +572,14 @@ static int lme2510_identify_state(struct usb_device *udev, | ||||
| 		struct dvb_usb_device_description **desc, | ||||
| 		int *cold) | ||||
| { | ||||
| 	if (lme2510_return_status(udev) == 0x44) | ||||
| 		*cold = 1; | ||||
| 	else | ||||
| 		*cold = 0; | ||||
| 	*cold = 0; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) | ||||
| { | ||||
| 	struct lme2510_state *st = adap->dev->priv; | ||||
| 	static u8 clear_reg_3[] =  LME_CLEAR_PID; | ||||
| 	static u8 clear_reg_3[] = LME_CLEAR_PID; | ||||
| 	static u8 rbuf[1]; | ||||
| 	int ret = 0, rlen = sizeof(rbuf); | ||||
| 
 | ||||
| @ -658,9 +710,6 @@ static int lme2510_download_firmware(struct usb_device *dev, | ||||
| 	return (ret < 0) ? -ENODEV : 0; | ||||
| } | ||||
| 
 | ||||
| /* Default firmware for LME2510C */ | ||||
| char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw"; | ||||
| 
 | ||||
| static void lme_coldreset(struct usb_device *dev) | ||||
| { | ||||
| 	int ret = 0, len_in; | ||||
| @ -678,49 +727,83 @@ static void lme_coldreset(struct usb_device *dev) | ||||
| static int lme_firmware_switch(struct usb_device *udev, int cold) | ||||
| { | ||||
| 	const struct firmware *fw = NULL; | ||||
| 	char lme2510c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; | ||||
| 	char lme2510c_lg[] = "dvb-usb-lme2510c-lg.fw"; | ||||
| 	char *firm_msg[] = {"Loading", "Switching to"}; | ||||
| 	int ret; | ||||
| 	const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; | ||||
| 	const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw"; | ||||
| 	const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw"; | ||||
| 	const char fw_lg[] = "dvb-usb-lme2510-lg.fw"; | ||||
| 	const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw"; | ||||
| 	const char *fw_lme; | ||||
| 	int ret, cold_fw; | ||||
| 
 | ||||
| 	cold = (cold > 0) ? (cold & 1) : 0; | ||||
| 
 | ||||
| 	if (udev->descriptor.idProduct == 0x1122) | ||||
| 		return 0; | ||||
| 	cold_fw = !cold; | ||||
| 
 | ||||
| 	switch (dvb_usb_lme2510_firmware) { | ||||
| 	case 0: | ||||
| 	default: | ||||
| 		memcpy(&lme_firmware, lme2510c_s7395, sizeof(lme2510c_s7395)); | ||||
| 		ret = request_firmware(&fw, lme_firmware, &udev->dev); | ||||
| 		if (ret == 0) { | ||||
| 			info("FRM %s S7395 Firmware", firm_msg[cold]); | ||||
| 			break; | ||||
| 		} | ||||
| 		if (cold == 0) | ||||
| 			dvb_usb_lme2510_firmware = 1; | ||||
| 		else | ||||
| 	if (udev->descriptor.idProduct == 0x1122) { | ||||
| 		switch (dvb_usb_lme2510_firmware) { | ||||
| 		default: | ||||
| 			dvb_usb_lme2510_firmware = TUNER_S0194; | ||||
| 		case TUNER_S0194: | ||||
| 			fw_lme = fw_s0194; | ||||
| 			ret = request_firmware(&fw, fw_lme, &udev->dev); | ||||
| 			if (ret == 0) { | ||||
| 				cold = 0;/*lme2510-s0194 cannot cold reset*/ | ||||
| 				break; | ||||
| 			} | ||||
| 			dvb_usb_lme2510_firmware = TUNER_LG; | ||||
| 		case TUNER_LG: | ||||
| 			fw_lme = fw_lg; | ||||
| 			ret = request_firmware(&fw, fw_lme, &udev->dev); | ||||
| 			if (ret == 0) | ||||
| 				break; | ||||
| 			info("FRM No Firmware Found - please install"); | ||||
| 			dvb_usb_lme2510_firmware = TUNER_DEFAULT; | ||||
| 			cold = 0; | ||||
| 	case 1: | ||||
| 		memcpy(&lme_firmware, lme2510c_lg, sizeof(lme2510c_lg)); | ||||
| 		ret = request_firmware(&fw, lme_firmware, &udev->dev); | ||||
| 		if (ret == 0) { | ||||
| 			info("FRM %s LG Firmware", firm_msg[cold]); | ||||
| 			cold_fw = 0; | ||||
| 			break; | ||||
| 		} | ||||
| 	} else { | ||||
| 		switch (dvb_usb_lme2510_firmware) { | ||||
| 		default: | ||||
| 			dvb_usb_lme2510_firmware = TUNER_S7395; | ||||
| 		case TUNER_S7395: | ||||
| 			fw_lme = fw_c_s7395; | ||||
| 			ret = request_firmware(&fw, fw_lme, &udev->dev); | ||||
| 			if (ret == 0) | ||||
| 				break; | ||||
| 			dvb_usb_lme2510_firmware = TUNER_LG; | ||||
| 		case TUNER_LG: | ||||
| 			fw_lme = fw_c_lg; | ||||
| 			ret = request_firmware(&fw, fw_lme, &udev->dev); | ||||
| 			if (ret == 0) | ||||
| 				break; | ||||
| 			dvb_usb_lme2510_firmware = TUNER_S0194; | ||||
| 		case TUNER_S0194: | ||||
| 			fw_lme = fw_c_s0194; | ||||
| 			ret = request_firmware(&fw, fw_lme, &udev->dev); | ||||
| 			if (ret == 0) | ||||
| 				break; | ||||
| 			info("FRM No Firmware Found - please install"); | ||||
| 			dvb_usb_lme2510_firmware = TUNER_DEFAULT; | ||||
| 			cold = 0; | ||||
| 			cold_fw = 0; | ||||
| 			break; | ||||
| 		} | ||||
| 		info("FRM No Firmware Found - please install"); | ||||
| 		dvb_usb_lme2510_firmware = 0; | ||||
| 		cold = 0; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	release_firmware(fw); | ||||
| 	if (cold_fw) { | ||||
| 		info("FRM Loading %s file", fw_lme); | ||||
| 		ret = lme2510_download_firmware(udev, fw); | ||||
| 	} | ||||
| 
 | ||||
| 	if (cold) { | ||||
| 		info("FRM Changing to %s firmware", fw_lme); | ||||
| 		lme_coldreset(udev); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	release_firmware(fw); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| @ -758,6 +841,18 @@ static struct ix2505v_config lme_tuner = { | ||||
| 	.tuner_chargepump = 0x3, | ||||
| }; | ||||
| 
 | ||||
| static struct stv0299_config sharp_z0194_config = { | ||||
| 	.demod_address = 0xd0, | ||||
| 	.inittab = sharp_z0194a_inittab, | ||||
| 	.mclk = 88000000UL, | ||||
| 	.invert = 0, | ||||
| 	.skip_reinit = 0, | ||||
| 	.lock_output = STV0299_LOCKOUTPUT_1, | ||||
| 	.volt13_op0_op1 = STV0299_VOLT13_OP1, | ||||
| 	.min_delay_ms = 100, | ||||
| 	.set_symbol_rate = sharp_z0194a_set_symbol_rate, | ||||
| }; | ||||
| 
 | ||||
| static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, | ||||
| 					fe_sec_voltage_t voltage) | ||||
| { | ||||
| @ -793,7 +888,8 @@ static int lme_name(struct dvb_usb_adapter *adap) | ||||
| { | ||||
| 	struct lme2510_state *st = adap->dev->priv; | ||||
| 	const char *desc = adap->dev->desc->name; | ||||
| 	char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395"}; | ||||
| 	char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395", | ||||
| 				" SHARP:BS2F7HZ0194"}; | ||||
| 	char *name = adap->fe->ops.info.name; | ||||
| 
 | ||||
| 	strlcpy(name, desc, 128); | ||||
| @ -820,26 +916,40 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) | ||||
| 		st->i2c_tuner_gate_r = 4; | ||||
| 		st->i2c_tuner_addr = 0xc0; | ||||
| 		st->tuner_config = TUNER_LG; | ||||
| 		if (dvb_usb_lme2510_firmware != 1) { | ||||
| 			dvb_usb_lme2510_firmware = 1; | ||||
| 		if (dvb_usb_lme2510_firmware != TUNER_LG) { | ||||
| 			dvb_usb_lme2510_firmware = TUNER_LG; | ||||
| 			ret = lme_firmware_switch(adap->dev->udev, 1); | ||||
| 		} else /*stops LG/Sharp multi tuner problems*/ | ||||
| 			dvb_usb_lme2510_firmware = 0; | ||||
| 		} | ||||
| 		goto end; | ||||
| 	} | ||||
| 
 | ||||
| 	st->i2c_gate = 4; | ||||
| 	adap->fe = dvb_attach(stv0299_attach, &sharp_z0194_config, | ||||
| 			&adap->dev->i2c_adap); | ||||
| 	if (adap->fe) { | ||||
| 		info("FE Found Stv0299"); | ||||
| 		st->i2c_tuner_gate_w = 4; | ||||
| 		st->i2c_tuner_gate_r = 5; | ||||
| 		st->i2c_tuner_addr = 0xc0; | ||||
| 		st->tuner_config = TUNER_S0194; | ||||
| 		if (dvb_usb_lme2510_firmware != TUNER_S0194) { | ||||
| 			dvb_usb_lme2510_firmware = TUNER_S0194; | ||||
| 			ret = lme_firmware_switch(adap->dev->udev, 1); | ||||
| 		} | ||||
| 		goto end; | ||||
| 	} | ||||
| 
 | ||||
| 	st->i2c_gate = 5; | ||||
| 	adap->fe = dvb_attach(stv0288_attach, &lme_config, | ||||
| 			&adap->dev->i2c_adap); | ||||
| 
 | ||||
| 	if (adap->fe) { | ||||
| 		info("FE Found Stv0288"); | ||||
| 		st->i2c_tuner_gate_w = 4; | ||||
| 		st->i2c_tuner_gate_r = 5; | ||||
| 		st->i2c_tuner_addr = 0xc0; | ||||
| 		st->tuner_config = TUNER_S7395; | ||||
| 		if (dvb_usb_lme2510_firmware != 0) { | ||||
| 			dvb_usb_lme2510_firmware = 0; | ||||
| 		if (dvb_usb_lme2510_firmware != TUNER_S7395) { | ||||
| 			dvb_usb_lme2510_firmware = TUNER_S7395; | ||||
| 			ret = lme_firmware_switch(adap->dev->udev, 1); | ||||
| 		} | ||||
| 	} else { | ||||
| @ -847,6 +957,7 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| end:	if (ret) { | ||||
| 		kfree(adap->fe); | ||||
| 		adap->fe = NULL; | ||||
| @ -855,14 +966,13 @@ end:	if (ret) { | ||||
| 
 | ||||
| 	adap->fe->ops.set_voltage = dm04_lme2510_set_voltage; | ||||
| 	ret = lme_name(adap); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) | ||||
| { | ||||
| 	struct lme2510_state *st = adap->dev->priv; | ||||
| 	char *tun_msg[] = {"", "TDA8263", "IX2505V"}; | ||||
| 	char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA"}; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	switch (st->tuner_config) { | ||||
| @ -876,6 +986,11 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) | ||||
| 			&adap->dev->i2c_adap)) | ||||
| 			ret = st->tuner_config; | ||||
| 		break; | ||||
| 	case TUNER_S0194: | ||||
| 		if (dvb_attach(dvb_pll_attach , adap->fe, 0xc0, | ||||
| 			&adap->dev->i2c_adap, DVB_PLL_OPERA1)) | ||||
| 			ret = st->tuner_config; | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| @ -936,7 +1051,10 @@ static int lme2510_probe(struct usb_interface *intf, | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	lme_firmware_switch(udev, 0); | ||||
| 	if (lme2510_return_status(udev) == 0x44) { | ||||
| 		lme_firmware_switch(udev, 0); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	if (0 == dvb_usb_device_init(intf, &lme2510_properties, | ||||
| 				     THIS_MODULE, NULL, adapter_nr)) { | ||||
| @ -964,10 +1082,6 @@ MODULE_DEVICE_TABLE(usb, lme2510_table); | ||||
| 
 | ||||
| static struct dvb_usb_device_properties lme2510_properties = { | ||||
| 	.caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||||
| 	.usb_ctrl = DEVICE_SPECIFIC, | ||||
| 	.download_firmware = lme2510_download_firmware, | ||||
| 	.firmware = "dvb-usb-lme2510-lg.fw", | ||||
| 
 | ||||
| 	.size_of_priv = sizeof(struct lme2510_state), | ||||
| 	.num_adapters = 1, | ||||
| 	.adapter = { | ||||
| @ -1004,9 +1118,6 @@ static struct dvb_usb_device_properties lme2510_properties = { | ||||
| 
 | ||||
| static struct dvb_usb_device_properties lme2510c_properties = { | ||||
| 	.caps = DVB_USB_IS_AN_I2C_ADAPTER, | ||||
| 	.usb_ctrl = DEVICE_SPECIFIC, | ||||
| 	.download_firmware = lme2510_download_firmware, | ||||
| 	.firmware = (const char *)&lme_firmware, | ||||
| 	.size_of_priv = sizeof(struct lme2510_state), | ||||
| 	.num_adapters = 1, | ||||
| 	.adapter = { | ||||
| @ -1109,5 +1220,5 @@ module_exit(lme2510_module_exit); | ||||
| 
 | ||||
| MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); | ||||
| MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); | ||||
| MODULE_VERSION("1.75"); | ||||
| MODULE_VERSION("1.80"); | ||||
| MODULE_LICENSE("GPL"); | ||||
|  | ||||
| @ -342,23 +342,22 @@ static struct rc_map_table rc_map_opera1_table[] = { | ||||
| 	{0x49b6, KEY_8}, | ||||
| 	{0x05fa, KEY_9}, | ||||
| 	{0x45ba, KEY_0}, | ||||
| 	{0x09f6, KEY_UP},	/*chanup */ | ||||
| 	{0x1be5, KEY_DOWN},	/*chandown */ | ||||
| 	{0x5da3, KEY_LEFT},	/*voldown */ | ||||
| 	{0x5fa1, KEY_RIGHT},	/*volup */ | ||||
| 	{0x07f8, KEY_SPACE},	/*tab */ | ||||
| 	{0x1fe1, KEY_ENTER},	/*play ok */ | ||||
| 	{0x1be4, KEY_Z},	/*zoom */ | ||||
| 	{0x59a6, KEY_M},	/*mute */ | ||||
| 	{0x5ba5, KEY_F},	/*tv/f */ | ||||
| 	{0x19e7, KEY_R},	/*rec */ | ||||
| 	{0x01fe, KEY_S},	/*Stop */ | ||||
| 	{0x03fd, KEY_P},	/*pause */ | ||||
| 	{0x03fc, KEY_W},	/*<- -> */ | ||||
| 	{0x07f9, KEY_C},	/*capture */ | ||||
| 	{0x47b9, KEY_Q},	/*exit */ | ||||
| 	{0x43bc, KEY_O},	/*power */ | ||||
| 
 | ||||
| 	{0x09f6, KEY_CHANNELUP},	/*chanup */ | ||||
| 	{0x1be5, KEY_CHANNELDOWN},	/*chandown */ | ||||
| 	{0x5da3, KEY_VOLUMEDOWN},	/*voldown */ | ||||
| 	{0x5fa1, KEY_VOLUMEUP},		/*volup */ | ||||
| 	{0x07f8, KEY_SPACE},		/*tab */ | ||||
| 	{0x1fe1, KEY_OK},		/*play ok */ | ||||
| 	{0x1be4, KEY_ZOOM},		/*zoom */ | ||||
| 	{0x59a6, KEY_MUTE},		/*mute */ | ||||
| 	{0x5ba5, KEY_RADIO},		/*tv/f */ | ||||
| 	{0x19e7, KEY_RECORD},		/*rec */ | ||||
| 	{0x01fe, KEY_STOP},		/*Stop */ | ||||
| 	{0x03fd, KEY_PAUSE},		/*pause */ | ||||
| 	{0x03fc, KEY_SCREEN},		/*<- -> */ | ||||
| 	{0x07f9, KEY_CAMERA},		/*capture */ | ||||
| 	{0x47b9, KEY_ESC},		/*exit */ | ||||
| 	{0x43bc, KEY_POWER2},		/*power */ | ||||
| }; | ||||
| 
 | ||||
| static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) | ||||
|  | ||||
							
								
								
									
										807
									
								
								drivers/media/dvb/dvb-usb/technisat-usb2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										807
									
								
								drivers/media/dvb/dvb-usb/technisat-usb2.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,807 @@ | ||||
| /*
 | ||||
|  * Linux driver for Technisat DVB-S/S2 USB 2.0 device | ||||
|  * | ||||
|  * Copyright (C) 2010 Patrick Boettcher, | ||||
|  *                    Kernel Labs Inc. PO Box 745, St James, NY 11780 | ||||
|  * | ||||
|  * Development was sponsored by Technisat Digital UK Limited, whose | ||||
|  * registered office is Witan Gate House 500 - 600 Witan Gate West, | ||||
|  * Milton Keynes, MK9 1SH | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
|  * | ||||
|  * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND | ||||
|  * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO | ||||
|  * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE.  NEITHER THE COPYRIGHT HOLDER | ||||
|  * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL, | ||||
|  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER | ||||
|  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||||
|  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR | ||||
|  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the | ||||
|  * GNU General Public License for more details. | ||||
|  */ | ||||
| 
 | ||||
| #define DVB_USB_LOG_PREFIX "technisat-usb2" | ||||
| #include "dvb-usb.h" | ||||
| 
 | ||||
| #include "stv6110x.h" | ||||
| #include "stv090x.h" | ||||
| 
 | ||||
| /* module parameters */ | ||||
| DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||||
| 
 | ||||
| static int debug; | ||||
| module_param(debug, int, 0644); | ||||
| MODULE_PARM_DESC(debug, | ||||
| 		"set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \ | ||||
| 		DVB_USB_DEBUG_STATUS); | ||||
| 
 | ||||
| /* disables all LED control command and
 | ||||
|  * also does not start the signal polling thread */ | ||||
| static int disable_led_control; | ||||
| module_param(disable_led_control, int, 0444); | ||||
| MODULE_PARM_DESC(disable_led_control, | ||||
| 		"disable LED control of the device " | ||||
| 		"(default: 0 - LED control is active)."); | ||||
| 
 | ||||
| /* device private data */ | ||||
| struct technisat_usb2_state { | ||||
| 	struct dvb_usb_device *dev; | ||||
| 	struct delayed_work green_led_work; | ||||
| 	u8 power_state; | ||||
| 
 | ||||
| 	u16 last_scan_code; | ||||
| }; | ||||
| 
 | ||||
| /* debug print helpers */ | ||||
| #define deb_info(args...)    dprintk(debug, 0x01, args) | ||||
| #define deb_eeprom(args...)  dprintk(debug, 0x02, args) | ||||
| #define deb_i2c(args...)     dprintk(debug, 0x04, args) | ||||
| #define deb_rc(args...)      dprintk(debug, 0x08, args) | ||||
| 
 | ||||
| /* vendor requests */ | ||||
| #define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3 | ||||
| #define SET_FRONT_END_RESET_VENDOR_REQUEST         0xB4 | ||||
| #define GET_VERSION_INFO_VENDOR_REQUEST            0xB5 | ||||
| #define SET_GREEN_LED_VENDOR_REQUEST               0xB6 | ||||
| #define SET_RED_LED_VENDOR_REQUEST                 0xB7 | ||||
| #define GET_IR_DATA_VENDOR_REQUEST                 0xB8 | ||||
| #define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST       0xB9 | ||||
| #define SET_USB_REENUMERATION                      0xBA | ||||
| 
 | ||||
| /* i2c-access methods */ | ||||
| #define I2C_SPEED_100KHZ_BIT 0x40 | ||||
| 
 | ||||
| #define I2C_STATUS_NAK 7 | ||||
| #define I2C_STATUS_OK 8 | ||||
| 
 | ||||
| static int technisat_usb2_i2c_access(struct usb_device *udev, | ||||
| 		u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen) | ||||
| { | ||||
| 	u8 b[64]; | ||||
| 	int ret, actual_length; | ||||
| 
 | ||||
| 	deb_i2c("i2c-access: %02x, tx: ", device_addr); | ||||
| 	debug_dump(tx, txlen, deb_i2c); | ||||
| 	deb_i2c(" "); | ||||
| 
 | ||||
| 	if (txlen > 62) { | ||||
| 		err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)", | ||||
| 				device_addr); | ||||
| 		txlen = 62; | ||||
| 	} | ||||
| 	if (rxlen > 62) { | ||||
| 		err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)", | ||||
| 				device_addr); | ||||
| 		txlen = 62; | ||||
| 	} | ||||
| 
 | ||||
| 	b[0] = I2C_SPEED_100KHZ_BIT; | ||||
| 	b[1] = device_addr << 1; | ||||
| 
 | ||||
| 	if (rx != NULL) { | ||||
| 		b[0] |= rxlen; | ||||
| 		b[1] |= 1; | ||||
| 	} | ||||
| 
 | ||||
| 	memcpy(&b[2], tx, txlen); | ||||
| 	ret = usb_bulk_msg(udev, | ||||
| 			usb_sndbulkpipe(udev, 0x01), | ||||
| 			b, 2 + txlen, | ||||
| 			NULL, 1000); | ||||
| 
 | ||||
| 	if (ret < 0) { | ||||
| 		err("i2c-error: out failed %02x = %d", device_addr, ret); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = usb_bulk_msg(udev, | ||||
| 			usb_rcvbulkpipe(udev, 0x01), | ||||
| 			b, 64, &actual_length, 1000); | ||||
| 	if (ret < 0) { | ||||
| 		err("i2c-error: in failed %02x = %d", device_addr, ret); | ||||
| 		return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	if (b[0] != I2C_STATUS_OK) { | ||||
| 		err("i2c-error: %02x = %d", device_addr, b[0]); | ||||
| 		/* handle tuner-i2c-nak */ | ||||
| 		if (!(b[0] == I2C_STATUS_NAK && | ||||
| 				device_addr == 0x60 | ||||
| 				/* && device_is_technisat_usb2 */)) | ||||
| 			return -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 	deb_i2c("status: %d, ", b[0]); | ||||
| 
 | ||||
| 	if (rx != NULL) { | ||||
| 		memcpy(rx, &b[2], rxlen); | ||||
| 
 | ||||
| 		deb_i2c("rx (%d): ", rxlen); | ||||
| 		debug_dump(rx, rxlen, deb_i2c); | ||||
| 	} | ||||
| 
 | ||||
| 	deb_i2c("\n"); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg, | ||||
| 				int num) | ||||
| { | ||||
| 	int ret = 0, i; | ||||
| 	struct dvb_usb_device *d = i2c_get_adapdata(adap); | ||||
| 
 | ||||
| 	/* Ensure nobody else hits the i2c bus while we're sending our
 | ||||
| 	   sequence of messages, (such as the remote control thread) */ | ||||
| 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||||
| 		return -EAGAIN; | ||||
| 
 | ||||
| 	for (i = 0; i < num; i++) { | ||||
| 		if (i+1 < num && msg[i+1].flags & I2C_M_RD) { | ||||
| 			ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr, | ||||
| 						msg[i].buf, msg[i].len, | ||||
| 						msg[i+1].buf, msg[i+1].len); | ||||
| 			if (ret != 0) | ||||
| 				break; | ||||
| 			i++; | ||||
| 		} else { | ||||
| 			ret = technisat_usb2_i2c_access(d->udev, msg[i].addr, | ||||
| 						msg[i].buf, msg[i].len, | ||||
| 						NULL, 0); | ||||
| 			if (ret != 0) | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (ret == 0) | ||||
| 		ret = i; | ||||
| 
 | ||||
| 	mutex_unlock(&d->i2c_mutex); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter) | ||||
| { | ||||
| 	return I2C_FUNC_I2C; | ||||
| } | ||||
| 
 | ||||
| static struct i2c_algorithm technisat_usb2_i2c_algo = { | ||||
| 	.master_xfer   = technisat_usb2_i2c_xfer, | ||||
| 	.functionality = technisat_usb2_i2c_func, | ||||
| }; | ||||
| 
 | ||||
| #if 0 | ||||
| static void technisat_usb2_frontend_reset(struct usb_device *udev) | ||||
| { | ||||
| 	usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||||
| 			SET_FRONT_END_RESET_VENDOR_REQUEST, | ||||
| 			USB_TYPE_VENDOR | USB_DIR_OUT, | ||||
| 			10, 0, | ||||
| 			NULL, 0, 500); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /* LED control */ | ||||
| enum technisat_usb2_led_state { | ||||
| 	LED_OFF, | ||||
| 	LED_BLINK, | ||||
| 	LED_ON, | ||||
| 	LED_UNDEFINED | ||||
| }; | ||||
| 
 | ||||
| static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	u8 led[8] = { | ||||
| 		red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST, | ||||
| 		0 | ||||
| 	}; | ||||
| 
 | ||||
| 	if (disable_led_control && state != LED_OFF) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	switch (state) { | ||||
| 	case LED_ON: | ||||
| 		led[1] = 0x82; | ||||
| 		break; | ||||
| 	case LED_BLINK: | ||||
| 		led[1] = 0x82; | ||||
| 		if (red) { | ||||
| 			led[2] = 0x02; | ||||
| 			led[3] = 10; | ||||
| 			led[4] = 10; | ||||
| 		} else { | ||||
| 			led[2] = 0xff; | ||||
| 			led[3] = 50; | ||||
| 			led[4] = 50; | ||||
| 		} | ||||
| 		led[5] = 1; | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 	case LED_OFF: | ||||
| 		led[1] = 0x80; | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||||
| 		return -EAGAIN; | ||||
| 
 | ||||
| 	ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), | ||||
| 		red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST, | ||||
| 		USB_TYPE_VENDOR | USB_DIR_OUT, | ||||
| 		0, 0, | ||||
| 		led, sizeof(led), 500); | ||||
| 
 | ||||
| 	mutex_unlock(&d->i2c_mutex); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green) | ||||
| { | ||||
| 	int ret; | ||||
| 	u8 b = 0; | ||||
| 
 | ||||
| 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||||
| 		return -EAGAIN; | ||||
| 
 | ||||
| 	ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), | ||||
| 		SET_LED_TIMER_DIVIDER_VENDOR_REQUEST, | ||||
| 		USB_TYPE_VENDOR | USB_DIR_OUT, | ||||
| 		(red << 8) | green, 0, | ||||
| 		&b, 1, 500); | ||||
| 
 | ||||
| 	mutex_unlock(&d->i2c_mutex); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void technisat_usb2_green_led_control(struct work_struct *work) | ||||
| { | ||||
| 	struct technisat_usb2_state *state = | ||||
| 		container_of(work, struct technisat_usb2_state, green_led_work.work); | ||||
| 	struct dvb_frontend *fe = state->dev->adapter[0].fe; | ||||
| 
 | ||||
| 	if (state->power_state == 0) | ||||
| 		goto schedule; | ||||
| 
 | ||||
| 	if (fe != NULL) { | ||||
| 		enum fe_status status; | ||||
| 
 | ||||
| 		if (fe->ops.read_status(fe, &status) != 0) | ||||
| 			goto schedule; | ||||
| 
 | ||||
| 		if (status & FE_HAS_LOCK) { | ||||
| 			u32 ber; | ||||
| 
 | ||||
| 			if (fe->ops.read_ber(fe, &ber) != 0) | ||||
| 				goto schedule; | ||||
| 
 | ||||
| 			if (ber > 1000) | ||||
| 				technisat_usb2_set_led(state->dev, 0, LED_BLINK); | ||||
| 			else | ||||
| 				technisat_usb2_set_led(state->dev, 0, LED_ON); | ||||
| 		} else | ||||
| 			technisat_usb2_set_led(state->dev, 0, LED_OFF); | ||||
| 	} | ||||
| 
 | ||||
| schedule: | ||||
| 	schedule_delayed_work(&state->green_led_work, | ||||
| 			msecs_to_jiffies(500)); | ||||
| } | ||||
| 
 | ||||
| /* method to find out whether the firmware has to be downloaded or not */ | ||||
| static int technisat_usb2_identify_state(struct usb_device *udev, | ||||
| 		struct dvb_usb_device_properties *props, | ||||
| 		struct dvb_usb_device_description **desc, int *cold) | ||||
| { | ||||
| 	int ret; | ||||
| 	u8 version[3]; | ||||
| 
 | ||||
| 	/* first select the interface */ | ||||
| 	if (usb_set_interface(udev, 0, 1) != 0) | ||||
| 		err("could not set alternate setting to 0"); | ||||
| 	else | ||||
| 		info("set alternate setting"); | ||||
| 
 | ||||
| 	*cold = 0; /* by default do not download a firmware - just in case something is wrong */ | ||||
| 
 | ||||
| 	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), | ||||
| 		GET_VERSION_INFO_VENDOR_REQUEST, | ||||
| 		USB_TYPE_VENDOR | USB_DIR_IN, | ||||
| 		0, 0, | ||||
| 		version, sizeof(version), 500); | ||||
| 
 | ||||
| 	if (ret < 0) | ||||
| 		*cold = 1; | ||||
| 	else { | ||||
| 		info("firmware version: %d.%d", version[1], version[2]); | ||||
| 		*cold = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* power control */ | ||||
| static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level) | ||||
| { | ||||
| 	struct technisat_usb2_state *state = d->priv; | ||||
| 
 | ||||
| 	state->power_state = level; | ||||
| 
 | ||||
| 	if (disable_led_control) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* green led is turned off in any case - will be turned on when tuning */ | ||||
| 	technisat_usb2_set_led(d, 0, LED_OFF); | ||||
| 	/* red led is turned on all the time */ | ||||
| 	technisat_usb2_set_led(d, 1, LED_ON); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* mac address reading - from the eeprom */ | ||||
| #if 0 | ||||
| static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d) | ||||
| { | ||||
| 	u8 reg; | ||||
| 	u8 b[16]; | ||||
| 	int i, j; | ||||
| 
 | ||||
| 	/* full EEPROM dump */ | ||||
| 	for (j = 0; j < 256 * 4; j += 16) { | ||||
| 		reg = j; | ||||
| 		if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, ®, 1, b, 16) != 0) | ||||
| 			break; | ||||
| 
 | ||||
| 		deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg); | ||||
| 		for (i = 0; i < 16; i++) | ||||
| 			deb_eeprom("%02x ", b[i]); | ||||
| 		deb_eeprom("\n"); | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length) | ||||
| { | ||||
| 	u8 lrc = 0; | ||||
| 	while (--length) | ||||
| 		lrc ^= *b++; | ||||
| 	return lrc; | ||||
| } | ||||
| 
 | ||||
| static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d, | ||||
| 	u16 offset, u8 *b, u16 length, u8 tries) | ||||
| { | ||||
| 	u8 bo = offset & 0xff; | ||||
| 	struct i2c_msg msg[] = { | ||||
| 		{ | ||||
| 			.addr = 0x50 | ((offset >> 8) & 0x3), | ||||
| 			.buf = &bo, | ||||
| 			.len = 1 | ||||
| 		}, { | ||||
| 			.addr = 0x50 | ((offset >> 8) & 0x3), | ||||
| 			.flags	= I2C_M_RD, | ||||
| 			.buf = b, | ||||
| 			.len = length | ||||
| 		} | ||||
| 	}; | ||||
| 
 | ||||
| 	while (tries--) { | ||||
| 		int status; | ||||
| 
 | ||||
| 		if (i2c_transfer(&d->i2c_adap, msg, 2) != 2) | ||||
| 			break; | ||||
| 
 | ||||
| 		status = | ||||
| 			technisat_usb2_calc_lrc(b, length - 1) == b[length - 1]; | ||||
| 
 | ||||
| 		if (status) | ||||
| 			return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return -EREMOTEIO; | ||||
| } | ||||
| 
 | ||||
| #define EEPROM_MAC_START 0x3f8 | ||||
| #define EEPROM_MAC_TOTAL 8 | ||||
| static int technisat_usb2_read_mac_address(struct dvb_usb_device *d, | ||||
| 		u8 mac[]) | ||||
| { | ||||
| 	u8 buf[EEPROM_MAC_TOTAL]; | ||||
| 
 | ||||
| 	if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START, | ||||
| 				buf, EEPROM_MAC_TOTAL, 4) != 0) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	memcpy(mac, buf, 6); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* frontend attach */ | ||||
| static int technisat_usb2_set_voltage(struct dvb_frontend *fe, | ||||
| 		fe_sec_voltage_t voltage) | ||||
| { | ||||
| 	int i; | ||||
| 	u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */ | ||||
| 
 | ||||
| 	gpio[2] = 1; /* high - voltage ? */ | ||||
| 
 | ||||
| 	switch (voltage) { | ||||
| 	case SEC_VOLTAGE_13: | ||||
| 		gpio[0] = 1; | ||||
| 		break; | ||||
| 	case SEC_VOLTAGE_18: | ||||
| 		gpio[0] = 1; | ||||
| 		gpio[1] = 1; | ||||
| 		break; | ||||
| 	default: | ||||
| 	case SEC_VOLTAGE_OFF: | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; i < 3; i++) | ||||
| 		if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0) | ||||
| 			return -EREMOTEIO; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct stv090x_config technisat_usb2_stv090x_config = { | ||||
| 	.device         = STV0903, | ||||
| 	.demod_mode     = STV090x_SINGLE, | ||||
| 	.clk_mode       = STV090x_CLK_EXT, | ||||
| 
 | ||||
| 	.xtal           = 8000000, | ||||
| 	.address        = 0x68, | ||||
| 
 | ||||
| 	.ts1_mode       = STV090x_TSMODE_DVBCI, | ||||
| 	.ts1_clk        = 13400000, | ||||
| 	.ts1_tei        = 1, | ||||
| 
 | ||||
| 	.repeater_level = STV090x_RPTLEVEL_64, | ||||
| 
 | ||||
| 	.tuner_bbgain   = 6, | ||||
| }; | ||||
| 
 | ||||
| static struct stv6110x_config technisat_usb2_stv6110x_config = { | ||||
| 	.addr           = 0x60, | ||||
| 	.refclk         = 16000000, | ||||
| 	.clk_div        = 2, | ||||
| }; | ||||
| 
 | ||||
| static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a) | ||||
| { | ||||
| 	struct usb_device *udev = a->dev->udev; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	a->fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config, | ||||
| 			&a->dev->i2c_adap, STV090x_DEMODULATOR_0); | ||||
| 
 | ||||
| 	if (a->fe) { | ||||
| 		struct stv6110x_devctl *ctl; | ||||
| 
 | ||||
| 		ctl = dvb_attach(stv6110x_attach, | ||||
| 				a->fe, | ||||
| 				&technisat_usb2_stv6110x_config, | ||||
| 				&a->dev->i2c_adap); | ||||
| 
 | ||||
| 		if (ctl) { | ||||
| 			technisat_usb2_stv090x_config.tuner_init          = ctl->tuner_init; | ||||
| 			technisat_usb2_stv090x_config.tuner_sleep         = ctl->tuner_sleep; | ||||
| 			technisat_usb2_stv090x_config.tuner_set_mode      = ctl->tuner_set_mode; | ||||
| 			technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency; | ||||
| 			technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency; | ||||
| 			technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth; | ||||
| 			technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth; | ||||
| 			technisat_usb2_stv090x_config.tuner_set_bbgain    = ctl->tuner_set_bbgain; | ||||
| 			technisat_usb2_stv090x_config.tuner_get_bbgain    = ctl->tuner_get_bbgain; | ||||
| 			technisat_usb2_stv090x_config.tuner_set_refclk    = ctl->tuner_set_refclk; | ||||
| 			technisat_usb2_stv090x_config.tuner_get_status    = ctl->tuner_get_status; | ||||
| 
 | ||||
| 			/* call the init function once to initialize
 | ||||
| 			   tuner's clock output divider and demod's | ||||
| 			   master clock */ | ||||
| 			if (a->fe->ops.init) | ||||
| 				a->fe->ops.init(a->fe); | ||||
| 
 | ||||
| 			if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0) | ||||
| 				return -EAGAIN; | ||||
| 
 | ||||
| 			ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||||
| 					SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST, | ||||
| 					USB_TYPE_VENDOR | USB_DIR_OUT, | ||||
| 					0, 0, | ||||
| 					NULL, 0, 500); | ||||
| 			mutex_unlock(&a->dev->i2c_mutex); | ||||
| 
 | ||||
| 			if (ret != 0) | ||||
| 				err("could not set IF_CLK to external"); | ||||
| 
 | ||||
| 			a->fe->ops.set_voltage = technisat_usb2_set_voltage; | ||||
| 
 | ||||
| 			/* if everything was successful assign a nice name to the frontend */ | ||||
| 			strlcpy(a->fe->ops.info.name, a->dev->desc->name, | ||||
| 					sizeof(a->fe->ops.info.name)); | ||||
| 		} else { | ||||
| 			dvb_frontend_detach(a->fe); | ||||
| 			a->fe = NULL; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	technisat_usb2_set_led_timer(a->dev, 1, 1); | ||||
| 
 | ||||
| 	return a->fe == NULL ? -ENODEV : 0; | ||||
| } | ||||
| 
 | ||||
| /* Remote control */ | ||||
| 
 | ||||
| /* the device is giving providing raw IR-signals to the host mapping
 | ||||
|  * it only to one remote control is just the default implementation | ||||
|  */ | ||||
| #define NOMINAL_IR_BIT_TRANSITION_TIME_US 889 | ||||
| #define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US) | ||||
| 
 | ||||
| #define FIRMWARE_CLOCK_TICK 83333 | ||||
| #define FIRMWARE_CLOCK_DIVISOR 256 | ||||
| 
 | ||||
| #define IR_PERCENT_TOLERANCE 15 | ||||
| 
 | ||||
| #define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK) | ||||
| #define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR) | ||||
| 
 | ||||
| #define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK) | ||||
| #define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR) | ||||
| 
 | ||||
| #define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) | ||||
| #define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) | ||||
| 
 | ||||
| #define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) | ||||
| #define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100)) | ||||
| 
 | ||||
| static int technisat_usb2_get_ir(struct dvb_usb_device *d) | ||||
| { | ||||
| 	u8 buf[62], *b; | ||||
| 	int ret; | ||||
| 	struct ir_raw_event ev; | ||||
| 
 | ||||
| 	buf[0] = GET_IR_DATA_VENDOR_REQUEST; | ||||
| 	buf[1] = 0x08; | ||||
| 	buf[2] = 0x8f; | ||||
| 	buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT; | ||||
| 	buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT; | ||||
| 
 | ||||
| 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0) | ||||
| 		return -EAGAIN; | ||||
| 	ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0), | ||||
| 			GET_IR_DATA_VENDOR_REQUEST, | ||||
| 			USB_TYPE_VENDOR | USB_DIR_OUT, | ||||
| 			0, 0, | ||||
| 			buf, 5, 500); | ||||
| 	if (ret < 0) | ||||
| 		goto unlock; | ||||
| 
 | ||||
| 	buf[1] = 0; | ||||
| 	buf[2] = 0; | ||||
| 	ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), | ||||
| 			GET_IR_DATA_VENDOR_REQUEST, | ||||
| 			USB_TYPE_VENDOR | USB_DIR_IN, | ||||
| 			0x8080, 0, | ||||
| 			buf, sizeof(buf), 500); | ||||
| 
 | ||||
| unlock: | ||||
| 	mutex_unlock(&d->i2c_mutex); | ||||
| 
 | ||||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	if (ret == 1) | ||||
| 		return 0; /* no key pressed */ | ||||
| 
 | ||||
| 	/* decoding */ | ||||
| 	b = buf+1; | ||||
| 
 | ||||
| #if 0 | ||||
| 	deb_rc("RC: %d ", ret); | ||||
| 	debug_dump(b, ret, deb_rc); | ||||
| #endif | ||||
| 
 | ||||
| 	ev.pulse = 0; | ||||
| 	while (1) { | ||||
| 		ev.pulse = !ev.pulse; | ||||
| 		ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000; | ||||
| 		ir_raw_event_store(d->rc_dev, &ev); | ||||
| 
 | ||||
| 		b++; | ||||
| 		if (*b == 0xff) { | ||||
| 			ev.pulse = 0; | ||||
| 			ev.duration = 888888*2; | ||||
| 			ir_raw_event_store(d->rc_dev, &ev); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	ir_raw_event_handle(d->rc_dev); | ||||
| 
 | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static int technisat_usb2_rc_query(struct dvb_usb_device *d) | ||||
| { | ||||
| 	int ret = technisat_usb2_get_ir(d); | ||||
| 
 | ||||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	if (ret == 0) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (!disable_led_control) | ||||
| 		technisat_usb2_set_led(d, 1, LED_BLINK); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* DVB-USB and USB stuff follows */ | ||||
| static struct usb_device_id technisat_usb2_id_table[] = { | ||||
| 	{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) }, | ||||
| 	{ 0 }		/* Terminating entry */ | ||||
| }; | ||||
| 
 | ||||
| /* device description */ | ||||
| static struct dvb_usb_device_properties technisat_usb2_devices = { | ||||
| 	.caps              = DVB_USB_IS_AN_I2C_ADAPTER, | ||||
| 
 | ||||
| 	.usb_ctrl          = CYPRESS_FX2, | ||||
| 
 | ||||
| 	.identify_state    = technisat_usb2_identify_state, | ||||
| 	.firmware          = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw", | ||||
| 
 | ||||
| 	.size_of_priv      = sizeof(struct technisat_usb2_state), | ||||
| 
 | ||||
| 	.i2c_algo          = &technisat_usb2_i2c_algo, | ||||
| 
 | ||||
| 	.power_ctrl        = technisat_usb2_power_ctrl, | ||||
| 	.read_mac_address  = technisat_usb2_read_mac_address, | ||||
| 
 | ||||
| 	.num_adapters = 1, | ||||
| 	.adapter = { | ||||
| 		{ | ||||
| 			.frontend_attach  = technisat_usb2_frontend_attach, | ||||
| 
 | ||||
| 			.stream = { | ||||
| 				.type = USB_ISOC, | ||||
| 				.count = 8, | ||||
| 				.endpoint = 0x2, | ||||
| 				.u = { | ||||
| 					.isoc = { | ||||
| 						.framesperurb = 32, | ||||
| 						.framesize = 2048, | ||||
| 						.interval = 3, | ||||
| 					} | ||||
| 				} | ||||
| 			}, | ||||
| 
 | ||||
| 			.size_of_priv = 0, | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	.num_device_descs = 1, | ||||
| 	.devices = { | ||||
| 		{   "Technisat SkyStar USB HD (DVB-S/S2)", | ||||
| 			{ &technisat_usb2_id_table[0], NULL }, | ||||
| 			{ NULL }, | ||||
| 		}, | ||||
| 	}, | ||||
| 
 | ||||
| 	.rc.core = { | ||||
| 		.rc_interval = 100, | ||||
| 		.rc_codes    = RC_MAP_TECHNISAT_USB2, | ||||
| 		.module_name = "technisat-usb2", | ||||
| 		.rc_query    = technisat_usb2_rc_query, | ||||
| 		.allowed_protos = RC_TYPE_ALL, | ||||
| 		.driver_type    = RC_DRIVER_IR_RAW, | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| static int technisat_usb2_probe(struct usb_interface *intf, | ||||
| 		const struct usb_device_id *id) | ||||
| { | ||||
| 	struct dvb_usb_device *dev; | ||||
| 
 | ||||
| 	if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE, | ||||
| 				&dev, adapter_nr) != 0) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	if (dev) { | ||||
| 		struct technisat_usb2_state *state = dev->priv; | ||||
| 		state->dev = dev; | ||||
| 
 | ||||
| 		if (!disable_led_control) { | ||||
| 			INIT_DELAYED_WORK(&state->green_led_work, | ||||
| 					technisat_usb2_green_led_control); | ||||
| 			schedule_delayed_work(&state->green_led_work, | ||||
| 					msecs_to_jiffies(500)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void technisat_usb2_disconnect(struct usb_interface *intf) | ||||
| { | ||||
| 	struct dvb_usb_device *dev = usb_get_intfdata(intf); | ||||
| 
 | ||||
| 	/* work and stuff was only created when the device is is hot-state */ | ||||
| 	if (dev != NULL) { | ||||
| 		struct technisat_usb2_state *state = dev->priv; | ||||
| 		if (state != NULL) { | ||||
| 			cancel_delayed_work_sync(&state->green_led_work); | ||||
| 			flush_scheduled_work(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	dvb_usb_device_exit(intf); | ||||
| } | ||||
| 
 | ||||
| static struct usb_driver technisat_usb2_driver = { | ||||
| 	.name       = "dvb_usb_technisat_usb2", | ||||
| 	.probe      = technisat_usb2_probe, | ||||
| 	.disconnect = technisat_usb2_disconnect, | ||||
| 	.id_table   = technisat_usb2_id_table, | ||||
| }; | ||||
| 
 | ||||
| /* module stuff */ | ||||
| static int __init technisat_usb2_module_init(void) | ||||
| { | ||||
| 	int result = usb_register(&technisat_usb2_driver); | ||||
| 	if (result) { | ||||
| 		err("usb_register failed. Code %d", result); | ||||
| 		return result; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void __exit technisat_usb2_module_exit(void) | ||||
| { | ||||
| 	usb_deregister(&technisat_usb2_driver); | ||||
| } | ||||
| 
 | ||||
| module_init(technisat_usb2_module_init); | ||||
| module_exit(technisat_usb2_module_exit); | ||||
| 
 | ||||
| MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>"); | ||||
| MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device"); | ||||
| MODULE_VERSION("1.0"); | ||||
| MODULE_LICENSE("GPL"); | ||||
| @ -1,6 +1,6 @@ | ||||
| config DVB_FIREDTV | ||||
| 	tristate "FireDTV and FloppyDTV" | ||||
| 	depends on DVB_CORE && (FIREWIRE || IEEE1394) | ||||
| 	depends on DVB_CORE && FIREWIRE | ||||
| 	help | ||||
| 	  Support for DVB receivers from Digital Everywhere | ||||
| 	  which are connected via IEEE 1394 (FireWire). | ||||
| @ -13,12 +13,6 @@ config DVB_FIREDTV | ||||
| 
 | ||||
| if DVB_FIREDTV | ||||
| 
 | ||||
| config DVB_FIREDTV_FIREWIRE | ||||
| 	def_bool FIREWIRE = y || (FIREWIRE = m && DVB_FIREDTV = m) | ||||
| 
 | ||||
| config DVB_FIREDTV_IEEE1394 | ||||
| 	def_bool IEEE1394 = y || (IEEE1394 = m && DVB_FIREDTV = m) | ||||
| 
 | ||||
| config DVB_FIREDTV_INPUT | ||||
| 	def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m) | ||||
| 
 | ||||
|  | ||||
| @ -1,9 +1,6 @@ | ||||
| obj-$(CONFIG_DVB_FIREDTV) += firedtv.o | ||||
| 
 | ||||
| firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o | ||||
| firedtv-$(CONFIG_DVB_FIREDTV_FIREWIRE) += firedtv-fw.o | ||||
| firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o | ||||
| firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o firedtv-fw.o | ||||
| firedtv-$(CONFIG_DVB_FIREDTV_INPUT)    += firedtv-rc.o | ||||
| 
 | ||||
| ccflags-y += -Idrivers/media/dvb/dvb-core | ||||
| ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394 | ||||
|  | ||||
| @ -1,300 +0,0 @@ | ||||
| /*
 | ||||
|  * FireDTV driver -- ieee1394 I/O backend | ||||
|  * | ||||
|  * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> | ||||
|  * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com> | ||||
|  * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> | ||||
|  * | ||||
|  *	This program is free software; you can redistribute it and/or | ||||
|  *	modify it under the terms of the GNU General Public License as | ||||
|  *	published by the Free Software Foundation; either version 2 of | ||||
|  *	the License, or (at your option) any later version. | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/device.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/list.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/spinlock.h> | ||||
| #include <linux/types.h> | ||||
| 
 | ||||
| #include <dma.h> | ||||
| #include <csr1212.h> | ||||
| #include <highlevel.h> | ||||
| #include <hosts.h> | ||||
| #include <ieee1394.h> | ||||
| #include <iso.h> | ||||
| #include <nodemgr.h> | ||||
| 
 | ||||
| #include <dvb_demux.h> | ||||
| 
 | ||||
| #include "firedtv.h" | ||||
| 
 | ||||
| static LIST_HEAD(node_list); | ||||
| static DEFINE_SPINLOCK(node_list_lock); | ||||
| 
 | ||||
| #define CIP_HEADER_SIZE			8 | ||||
| #define MPEG2_TS_HEADER_SIZE		4 | ||||
| #define MPEG2_TS_SOURCE_PACKET_SIZE	(4 + 188) | ||||
| 
 | ||||
| static void rawiso_activity_cb(struct hpsb_iso *iso) | ||||
| { | ||||
| 	struct firedtv *f, *fdtv = NULL; | ||||
| 	unsigned int i, num, packet; | ||||
| 	unsigned char *buf; | ||||
| 	unsigned long flags; | ||||
| 	int count; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&node_list_lock, flags); | ||||
| 	list_for_each_entry(f, &node_list, list) | ||||
| 		if (f->backend_data == iso) { | ||||
| 			fdtv = f; | ||||
| 			break; | ||||
| 		} | ||||
| 	spin_unlock_irqrestore(&node_list_lock, flags); | ||||
| 
 | ||||
| 	packet = iso->first_packet; | ||||
| 	num = hpsb_iso_n_ready(iso); | ||||
| 
 | ||||
| 	if (!fdtv) { | ||||
| 		pr_err("received at unknown iso channel\n"); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) { | ||||
| 		buf = dma_region_i(&iso->data_buf, unsigned char, | ||||
| 			iso->infos[packet].offset + CIP_HEADER_SIZE); | ||||
| 		count = (iso->infos[packet].len - CIP_HEADER_SIZE) / | ||||
| 			MPEG2_TS_SOURCE_PACKET_SIZE; | ||||
| 
 | ||||
| 		/* ignore empty packet */ | ||||
| 		if (iso->infos[packet].len <= CIP_HEADER_SIZE) | ||||
| 			continue; | ||||
| 
 | ||||
| 		while (count--) { | ||||
| 			if (buf[MPEG2_TS_HEADER_SIZE] == 0x47) | ||||
| 				dvb_dmx_swfilter_packets(&fdtv->demux, | ||||
| 						&buf[MPEG2_TS_HEADER_SIZE], 1); | ||||
| 			else | ||||
| 				dev_err(fdtv->device, | ||||
| 					"skipping invalid packet\n"); | ||||
| 			buf += MPEG2_TS_SOURCE_PACKET_SIZE; | ||||
| 		} | ||||
| 	} | ||||
| out: | ||||
| 	hpsb_iso_recv_release_packets(iso, num); | ||||
| } | ||||
| 
 | ||||
| static inline struct node_entry *node_of(struct firedtv *fdtv) | ||||
| { | ||||
| 	return container_of(fdtv->device, struct unit_directory, device)->ne; | ||||
| } | ||||
| 
 | ||||
| static int node_lock(struct firedtv *fdtv, u64 addr, void *data) | ||||
| { | ||||
| 	quadlet_t *d = data; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ret = hpsb_node_lock(node_of(fdtv), addr, | ||||
| 			     EXTCODE_COMPARE_SWAP, &d[1], d[0]); | ||||
| 	d[0] = d[1]; | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int node_read(struct firedtv *fdtv, u64 addr, void *data) | ||||
| { | ||||
| 	return hpsb_node_read(node_of(fdtv), addr, data, 4); | ||||
| } | ||||
| 
 | ||||
| static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) | ||||
| { | ||||
| 	return hpsb_node_write(node_of(fdtv), addr, data, len); | ||||
| } | ||||
| 
 | ||||
| #define FDTV_ISO_BUFFER_PACKETS 256 | ||||
| #define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200) | ||||
| 
 | ||||
| static int start_iso(struct firedtv *fdtv) | ||||
| { | ||||
| 	struct hpsb_iso *iso_handle; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host, | ||||
| 				FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS, | ||||
| 				fdtv->isochannel, HPSB_ISO_DMA_DEFAULT, | ||||
| 				-1, /* stat.config.irq_interval */ | ||||
| 				rawiso_activity_cb); | ||||
| 	if (iso_handle == NULL) { | ||||
| 		dev_err(fdtv->device, "cannot initialize iso receive\n"); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	fdtv->backend_data = iso_handle; | ||||
| 
 | ||||
| 	ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0); | ||||
| 	if (ret != 0) { | ||||
| 		dev_err(fdtv->device, "cannot start iso receive\n"); | ||||
| 		hpsb_iso_shutdown(iso_handle); | ||||
| 		fdtv->backend_data = NULL; | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void stop_iso(struct firedtv *fdtv) | ||||
| { | ||||
| 	struct hpsb_iso *iso_handle = fdtv->backend_data; | ||||
| 
 | ||||
| 	if (iso_handle != NULL) { | ||||
| 		hpsb_iso_stop(iso_handle); | ||||
| 		hpsb_iso_shutdown(iso_handle); | ||||
| 	} | ||||
| 	fdtv->backend_data = NULL; | ||||
| } | ||||
| 
 | ||||
| static const struct firedtv_backend fdtv_1394_backend = { | ||||
| 	.lock		= node_lock, | ||||
| 	.read		= node_read, | ||||
| 	.write		= node_write, | ||||
| 	.start_iso	= start_iso, | ||||
| 	.stop_iso	= stop_iso, | ||||
| }; | ||||
| 
 | ||||
| static void fcp_request(struct hpsb_host *host, int nodeid, int direction, | ||||
| 			int cts, u8 *data, size_t length) | ||||
| { | ||||
| 	struct firedtv *f, *fdtv = NULL; | ||||
| 	unsigned long flags; | ||||
| 	int su; | ||||
| 
 | ||||
| 	if (length == 0 || (data[0] & 0xf0) != 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	su = data[1] & 0x7; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&node_list_lock, flags); | ||||
| 	list_for_each_entry(f, &node_list, list) | ||||
| 		if (node_of(f)->host == host && | ||||
| 		    node_of(f)->nodeid == nodeid && | ||||
| 		    (f->subunit == su || (f->subunit == 0 && su == 0x7))) { | ||||
| 			fdtv = f; | ||||
| 			break; | ||||
| 		} | ||||
| 	spin_unlock_irqrestore(&node_list_lock, flags); | ||||
| 
 | ||||
| 	if (fdtv) | ||||
| 		avc_recv(fdtv, data, length); | ||||
| } | ||||
| 
 | ||||
| static int node_probe(struct device *dev) | ||||
| { | ||||
| 	struct unit_directory *ud = | ||||
| 			container_of(dev, struct unit_directory, device); | ||||
| 	struct firedtv *fdtv; | ||||
| 	int kv_len, err; | ||||
| 	void *kv_str; | ||||
| 
 | ||||
| 	if (ud->model_name_kv) { | ||||
| 		kv_len = (ud->model_name_kv->value.leaf.len - 2) * 4; | ||||
| 		kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); | ||||
| 	} else { | ||||
| 		kv_len = 0; | ||||
| 		kv_str = NULL; | ||||
| 	} | ||||
| 	fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len); | ||||
| 	if (!fdtv) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Work around a bug in udev's path_id script:  Use the fw-host's dev | ||||
| 	 * instead of the unit directory's dev as parent of the input device. | ||||
| 	 */ | ||||
| 	err = fdtv_register_rc(fdtv, dev->parent->parent); | ||||
| 	if (err) | ||||
| 		goto fail_free; | ||||
| 
 | ||||
| 	spin_lock_irq(&node_list_lock); | ||||
| 	list_add_tail(&fdtv->list, &node_list); | ||||
| 	spin_unlock_irq(&node_list_lock); | ||||
| 
 | ||||
| 	err = avc_identify_subunit(fdtv); | ||||
| 	if (err) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	err = fdtv_dvb_register(fdtv); | ||||
| 	if (err) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	avc_register_remote_control(fdtv); | ||||
| 
 | ||||
| 	return 0; | ||||
| fail: | ||||
| 	spin_lock_irq(&node_list_lock); | ||||
| 	list_del(&fdtv->list); | ||||
| 	spin_unlock_irq(&node_list_lock); | ||||
| 	fdtv_unregister_rc(fdtv); | ||||
| fail_free: | ||||
| 	kfree(fdtv); | ||||
| 
 | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static int node_remove(struct device *dev) | ||||
| { | ||||
| 	struct firedtv *fdtv = dev_get_drvdata(dev); | ||||
| 
 | ||||
| 	fdtv_dvb_unregister(fdtv); | ||||
| 
 | ||||
| 	spin_lock_irq(&node_list_lock); | ||||
| 	list_del(&fdtv->list); | ||||
| 	spin_unlock_irq(&node_list_lock); | ||||
| 
 | ||||
| 	fdtv_unregister_rc(fdtv); | ||||
| 	kfree(fdtv); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int node_update(struct unit_directory *ud) | ||||
| { | ||||
| 	struct firedtv *fdtv = dev_get_drvdata(&ud->device); | ||||
| 
 | ||||
| 	if (fdtv->isochannel >= 0) | ||||
| 		cmp_establish_pp_connection(fdtv, fdtv->subunit, | ||||
| 					    fdtv->isochannel); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct hpsb_protocol_driver fdtv_driver = { | ||||
| 	.name		= "firedtv", | ||||
| 	.id_table	= fdtv_id_table, | ||||
| 	.update		= node_update, | ||||
| 	.driver         = { | ||||
| 		.probe  = node_probe, | ||||
| 		.remove = node_remove, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct hpsb_highlevel fdtv_highlevel = { | ||||
| 	.name		= "firedtv", | ||||
| 	.fcp_request	= fcp_request, | ||||
| }; | ||||
| 
 | ||||
| int __init fdtv_1394_init(void) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	hpsb_register_highlevel(&fdtv_highlevel); | ||||
| 	ret = hpsb_register_protocol(&fdtv_driver); | ||||
| 	if (ret) { | ||||
| 		printk(KERN_ERR "firedtv: failed to register protocol\n"); | ||||
| 		hpsb_unregister_highlevel(&fdtv_highlevel); | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void __exit fdtv_1394_exit(void) | ||||
| { | ||||
| 	hpsb_unregister_protocol(&fdtv_driver); | ||||
| 	hpsb_unregister_highlevel(&fdtv_highlevel); | ||||
| } | ||||
| @ -241,8 +241,8 @@ static int avc_write(struct firedtv *fdtv) | ||||
| 		if (unlikely(avc_debug)) | ||||
| 			debug_fcp(fdtv->avc_data, fdtv->avc_data_length); | ||||
| 
 | ||||
| 		err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, | ||||
| 				fdtv->avc_data, fdtv->avc_data_length); | ||||
| 		err = fdtv_write(fdtv, FCP_COMMAND_REGISTER, | ||||
| 				 fdtv->avc_data, fdtv->avc_data_length); | ||||
| 		if (err) { | ||||
| 			dev_err(fdtv->device, "FCP command write failed\n"); | ||||
| 
 | ||||
| @ -1322,7 +1322,7 @@ static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data) | ||||
| 
 | ||||
| 	mutex_lock(&fdtv->avc_mutex); | ||||
| 
 | ||||
| 	ret = fdtv->backend->read(fdtv, addr, data); | ||||
| 	ret = fdtv_read(fdtv, addr, data); | ||||
| 	if (ret < 0) | ||||
| 		dev_err(fdtv->device, "CMP: read I/O error\n"); | ||||
| 
 | ||||
| @ -1340,7 +1340,7 @@ static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[]) | ||||
| 	/* data[] is stack-allocated and should not be DMA-mapped. */ | ||||
| 	memcpy(fdtv->avc_data, data, 8); | ||||
| 
 | ||||
| 	ret = fdtv->backend->lock(fdtv, addr, fdtv->avc_data); | ||||
| 	ret = fdtv_lock(fdtv, addr, fdtv->avc_data); | ||||
| 	if (ret < 0) | ||||
| 		dev_err(fdtv->device, "CMP: lock I/O error\n"); | ||||
| 	else | ||||
| @ -1405,10 +1405,7 @@ repeat: | ||||
| 		/* FIXME: this is for the worst case - optimize */ | ||||
| 		set_opcr_overhead_id(opcr, 0); | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * FIXME: allocate isochronous channel and bandwidth at IRM | ||||
| 		 * fdtv->backend->alloc_resources(fdtv, channels_mask, bw); | ||||
| 		 */ | ||||
| 		/* FIXME: allocate isochronous channel and bandwidth at IRM */ | ||||
| 	} | ||||
| 
 | ||||
| 	set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1); | ||||
| @ -1424,8 +1421,6 @@ repeat: | ||||
| 		/*
 | ||||
| 		 * FIXME: if old_opcr.P2P_Connections > 0, | ||||
| 		 * deallocate isochronous channel and bandwidth at IRM | ||||
| 		 * if (...) | ||||
| 		 *	fdtv->backend->dealloc_resources(fdtv, channel, bw); | ||||
| 		 */ | ||||
| 
 | ||||
| 		if (++attempts < 6) /* arbitrary limit */ | ||||
|  | ||||
| @ -14,14 +14,9 @@ | ||||
| #include <linux/device.h> | ||||
| #include <linux/errno.h> | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/mod_devicetable.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/mutex.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/string.h> | ||||
| #include <linux/types.h> | ||||
| #include <linux/wait.h> | ||||
| #include <linux/workqueue.h> | ||||
| 
 | ||||
| #include <dmxdev.h> | ||||
| #include <dvb_demux.h> | ||||
| @ -166,11 +161,11 @@ int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||||
| 
 | ||||
| DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||||
| 
 | ||||
| int fdtv_dvb_register(struct firedtv *fdtv) | ||||
| int fdtv_dvb_register(struct firedtv *fdtv, const char *name) | ||||
| { | ||||
| 	int err; | ||||
| 
 | ||||
| 	err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type], | ||||
| 	err = dvb_register_adapter(&fdtv->adapter, name, | ||||
| 				   THIS_MODULE, fdtv->device, adapter_nr); | ||||
| 	if (err < 0) | ||||
| 		goto fail_log; | ||||
| @ -210,7 +205,7 @@ int fdtv_dvb_register(struct firedtv *fdtv) | ||||
| 
 | ||||
| 	dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx); | ||||
| 
 | ||||
| 	fdtv_frontend_init(fdtv); | ||||
| 	fdtv_frontend_init(fdtv, name); | ||||
| 	err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe); | ||||
| 	if (err) | ||||
| 		goto fail_net_release; | ||||
| @ -248,127 +243,3 @@ void fdtv_dvb_unregister(struct firedtv *fdtv) | ||||
| 	dvb_dmx_release(&fdtv->demux); | ||||
| 	dvb_unregister_adapter(&fdtv->adapter); | ||||
| } | ||||
| 
 | ||||
| const char *fdtv_model_names[] = { | ||||
| 	[FIREDTV_UNKNOWN] = "unknown type", | ||||
| 	[FIREDTV_DVB_S]   = "FireDTV S/CI", | ||||
| 	[FIREDTV_DVB_C]   = "FireDTV C/CI", | ||||
| 	[FIREDTV_DVB_T]   = "FireDTV T/CI", | ||||
| 	[FIREDTV_DVB_S2]  = "FireDTV S2  ", | ||||
| }; | ||||
| 
 | ||||
| struct firedtv *fdtv_alloc(struct device *dev, | ||||
| 			   const struct firedtv_backend *backend, | ||||
| 			   const char *name, size_t name_len) | ||||
| { | ||||
| 	struct firedtv *fdtv; | ||||
| 	int i; | ||||
| 
 | ||||
| 	fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL); | ||||
| 	if (!fdtv) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	dev_set_drvdata(dev, fdtv); | ||||
| 	fdtv->device		= dev; | ||||
| 	fdtv->isochannel	= -1; | ||||
| 	fdtv->voltage		= 0xff; | ||||
| 	fdtv->tone		= 0xff; | ||||
| 	fdtv->backend		= backend; | ||||
| 
 | ||||
| 	mutex_init(&fdtv->avc_mutex); | ||||
| 	init_waitqueue_head(&fdtv->avc_wait); | ||||
| 	mutex_init(&fdtv->demux_mutex); | ||||
| 	INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); | ||||
| 
 | ||||
| 	for (i = ARRAY_SIZE(fdtv_model_names); --i; ) | ||||
| 		if (strlen(fdtv_model_names[i]) <= name_len && | ||||
| 		    strncmp(name, fdtv_model_names[i], name_len) == 0) | ||||
| 			break; | ||||
| 	fdtv->type = i; | ||||
| 
 | ||||
| 	return fdtv; | ||||
| } | ||||
| 
 | ||||
| #define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ | ||||
| 		     IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION) | ||||
| 
 | ||||
| #define DIGITAL_EVERYWHERE_OUI	0x001287 | ||||
| #define AVC_UNIT_SPEC_ID_ENTRY	0x00a02d | ||||
| #define AVC_SW_VERSION_ENTRY	0x010001 | ||||
| 
 | ||||
| const struct ieee1394_device_id fdtv_id_table[] = { | ||||
| 	{ | ||||
| 		/* FloppyDTV S/CI and FloppyDTV S2 */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000024, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, { | ||||
| 		/* FloppyDTV T/CI */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000025, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, { | ||||
| 		/* FloppyDTV C/CI */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000026, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, { | ||||
| 		/* FireDTV S/CI and FloppyDTV S2 */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000034, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, { | ||||
| 		/* FireDTV T/CI */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000035, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, { | ||||
| 		/* FireDTV C/CI */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000036, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, {} | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table); | ||||
| 
 | ||||
| static int __init fdtv_init(void) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ret = fdtv_fw_init(); | ||||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	ret = fdtv_1394_init(); | ||||
| 	if (ret < 0) | ||||
| 		fdtv_fw_exit(); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void __exit fdtv_exit(void) | ||||
| { | ||||
| 	fdtv_1394_exit(); | ||||
| 	fdtv_fw_exit(); | ||||
| } | ||||
| 
 | ||||
| module_init(fdtv_init); | ||||
| module_exit(fdtv_exit); | ||||
| 
 | ||||
| MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>"); | ||||
| MODULE_AUTHOR("Ben Backx <ben@bbackx.com>"); | ||||
| MODULE_DESCRIPTION("FireDTV DVB Driver"); | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_SUPPORTED_DEVICE("FireDTV DVB"); | ||||
|  | ||||
| @ -36,14 +36,14 @@ static int fdtv_dvb_init(struct dvb_frontend *fe) | ||||
| 		return err; | ||||
| 	} | ||||
| 
 | ||||
| 	return fdtv->backend->start_iso(fdtv); | ||||
| 	return fdtv_start_iso(fdtv); | ||||
| } | ||||
| 
 | ||||
| static int fdtv_sleep(struct dvb_frontend *fe) | ||||
| { | ||||
| 	struct firedtv *fdtv = fe->sec_priv; | ||||
| 
 | ||||
| 	fdtv->backend->stop_iso(fdtv); | ||||
| 	fdtv_stop_iso(fdtv); | ||||
| 	cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel); | ||||
| 	fdtv->isochannel = -1; | ||||
| 	return 0; | ||||
| @ -165,7 +165,7 @@ static int fdtv_set_property(struct dvb_frontend *fe, struct dtv_property *tvp) | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void fdtv_frontend_init(struct firedtv *fdtv) | ||||
| void fdtv_frontend_init(struct firedtv *fdtv, const char *name) | ||||
| { | ||||
| 	struct dvb_frontend_ops *ops = &fdtv->fe.ops; | ||||
| 	struct dvb_frontend_info *fi = &ops->info; | ||||
| @ -266,7 +266,7 @@ void fdtv_frontend_init(struct firedtv *fdtv) | ||||
| 		dev_err(fdtv->device, "no frontend for model type %d\n", | ||||
| 			fdtv->type); | ||||
| 	} | ||||
| 	strcpy(fi->name, fdtv_model_names[fdtv->type]); | ||||
| 	strcpy(fi->name, name); | ||||
| 
 | ||||
| 	fdtv->fe.dvb = &fdtv->adapter; | ||||
| 	fdtv->fe.sec_priv = fdtv; | ||||
|  | ||||
| @ -9,11 +9,18 @@ | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/list.h> | ||||
| #include <linux/mm.h> | ||||
| #include <linux/mod_devicetable.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/mutex.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/spinlock.h> | ||||
| #include <linux/string.h> | ||||
| #include <linux/types.h> | ||||
| #include <linux/wait.h> | ||||
| #include <linux/workqueue.h> | ||||
| 
 | ||||
| #include <asm/page.h> | ||||
| #include <asm/system.h> | ||||
| 
 | ||||
| #include <dvb_demux.h> | ||||
| 
 | ||||
| @ -41,17 +48,17 @@ static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len, | ||||
| 	return rcode != RCODE_COMPLETE ? -EIO : 0; | ||||
| } | ||||
| 
 | ||||
| static int node_lock(struct firedtv *fdtv, u64 addr, void *data) | ||||
| int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data) | ||||
| { | ||||
| 	return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); | ||||
| } | ||||
| 
 | ||||
| static int node_read(struct firedtv *fdtv, u64 addr, void *data) | ||||
| int fdtv_read(struct firedtv *fdtv, u64 addr, void *data) | ||||
| { | ||||
| 	return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST); | ||||
| } | ||||
| 
 | ||||
| static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) | ||||
| int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) | ||||
| { | ||||
| 	return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST); | ||||
| } | ||||
| @ -67,7 +74,7 @@ static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) | ||||
| #define N_PAGES			DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE) | ||||
| #define IRQ_INTERVAL		16 | ||||
| 
 | ||||
| struct firedtv_receive_context { | ||||
| struct fdtv_ir_context { | ||||
| 	struct fw_iso_context *context; | ||||
| 	struct fw_iso_buffer buffer; | ||||
| 	int interrupt_packet; | ||||
| @ -75,7 +82,7 @@ struct firedtv_receive_context { | ||||
| 	char *pages[N_PAGES]; | ||||
| }; | ||||
| 
 | ||||
| static int queue_iso(struct firedtv_receive_context *ctx, int index) | ||||
| static int queue_iso(struct fdtv_ir_context *ctx, int index) | ||||
| { | ||||
| 	struct fw_iso_packet p; | ||||
| 
 | ||||
| @ -92,7 +99,7 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle, | ||||
| 		       size_t header_length, void *header, void *data) | ||||
| { | ||||
| 	struct firedtv *fdtv = data; | ||||
| 	struct firedtv_receive_context *ctx = fdtv->backend_data; | ||||
| 	struct fdtv_ir_context *ctx = fdtv->ir_context; | ||||
| 	__be32 *h, *h_end; | ||||
| 	int length, err, i = ctx->current_packet; | ||||
| 	char *p, *p_end; | ||||
| @ -121,9 +128,9 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle, | ||||
| 	ctx->current_packet = i; | ||||
| } | ||||
| 
 | ||||
| static int start_iso(struct firedtv *fdtv) | ||||
| int fdtv_start_iso(struct firedtv *fdtv) | ||||
| { | ||||
| 	struct firedtv_receive_context *ctx; | ||||
| 	struct fdtv_ir_context *ctx; | ||||
| 	struct fw_device *device = device_of(fdtv); | ||||
| 	int i, err; | ||||
| 
 | ||||
| @ -161,7 +168,7 @@ static int start_iso(struct firedtv *fdtv) | ||||
| 	if (err) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	fdtv->backend_data = ctx; | ||||
| 	fdtv->ir_context = ctx; | ||||
| 
 | ||||
| 	return 0; | ||||
| fail: | ||||
| @ -174,9 +181,9 @@ fail_free: | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static void stop_iso(struct firedtv *fdtv) | ||||
| void fdtv_stop_iso(struct firedtv *fdtv) | ||||
| { | ||||
| 	struct firedtv_receive_context *ctx = fdtv->backend_data; | ||||
| 	struct fdtv_ir_context *ctx = fdtv->ir_context; | ||||
| 
 | ||||
| 	fw_iso_context_stop(ctx->context); | ||||
| 	fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card); | ||||
| @ -184,14 +191,6 @@ static void stop_iso(struct firedtv *fdtv) | ||||
| 	kfree(ctx); | ||||
| } | ||||
| 
 | ||||
| static const struct firedtv_backend backend = { | ||||
| 	.lock		= node_lock, | ||||
| 	.read		= node_read, | ||||
| 	.write		= node_write, | ||||
| 	.start_iso	= start_iso, | ||||
| 	.stop_iso	= stop_iso, | ||||
| }; | ||||
| 
 | ||||
| static void handle_fcp(struct fw_card *card, struct fw_request *request, | ||||
| 		       int tcode, int destination, int source, int generation, | ||||
| 		       unsigned long long offset, void *payload, size_t length, | ||||
| @ -238,6 +237,14 @@ static const struct fw_address_region fcp_region = { | ||||
| 	.end	= CSR_REGISTER_BASE + CSR_FCP_END, | ||||
| }; | ||||
| 
 | ||||
| static const char * const model_names[] = { | ||||
| 	[FIREDTV_UNKNOWN] = "unknown type", | ||||
| 	[FIREDTV_DVB_S]   = "FireDTV S/CI", | ||||
| 	[FIREDTV_DVB_C]   = "FireDTV C/CI", | ||||
| 	[FIREDTV_DVB_T]   = "FireDTV T/CI", | ||||
| 	[FIREDTV_DVB_S2]  = "FireDTV S2  ", | ||||
| }; | ||||
| 
 | ||||
| /* Adjust the template string if models with longer names appear. */ | ||||
| #define MAX_MODEL_NAME_LEN sizeof("FireDTV ????") | ||||
| 
 | ||||
| @ -245,14 +252,30 @@ static int node_probe(struct device *dev) | ||||
| { | ||||
| 	struct firedtv *fdtv; | ||||
| 	char name[MAX_MODEL_NAME_LEN]; | ||||
| 	int name_len, err; | ||||
| 	int name_len, i, err; | ||||
| 
 | ||||
| 	fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL); | ||||
| 	if (!fdtv) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	dev_set_drvdata(dev, fdtv); | ||||
| 	fdtv->device		= dev; | ||||
| 	fdtv->isochannel	= -1; | ||||
| 	fdtv->voltage		= 0xff; | ||||
| 	fdtv->tone		= 0xff; | ||||
| 
 | ||||
| 	mutex_init(&fdtv->avc_mutex); | ||||
| 	init_waitqueue_head(&fdtv->avc_wait); | ||||
| 	mutex_init(&fdtv->demux_mutex); | ||||
| 	INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work); | ||||
| 
 | ||||
| 	name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL, | ||||
| 				 name, sizeof(name)); | ||||
| 
 | ||||
| 	fdtv = fdtv_alloc(dev, &backend, name, name_len >= 0 ? name_len : 0); | ||||
| 	if (!fdtv) | ||||
| 		return -ENOMEM; | ||||
| 	for (i = ARRAY_SIZE(model_names); --i; ) | ||||
| 		if (strlen(model_names[i]) <= name_len && | ||||
| 		    strncmp(name, model_names[i], name_len) == 0) | ||||
| 			break; | ||||
| 	fdtv->type = i; | ||||
| 
 | ||||
| 	err = fdtv_register_rc(fdtv, dev); | ||||
| 	if (err) | ||||
| @ -266,7 +289,7 @@ static int node_probe(struct device *dev) | ||||
| 	if (err) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	err = fdtv_dvb_register(fdtv); | ||||
| 	err = fdtv_dvb_register(fdtv, model_names[fdtv->type]); | ||||
| 	if (err) | ||||
| 		goto fail; | ||||
| 
 | ||||
| @ -309,6 +332,60 @@ static void node_update(struct fw_unit *unit) | ||||
| 					    fdtv->isochannel); | ||||
| } | ||||
| 
 | ||||
| #define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ | ||||
| 		     IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION) | ||||
| 
 | ||||
| #define DIGITAL_EVERYWHERE_OUI	0x001287 | ||||
| #define AVC_UNIT_SPEC_ID_ENTRY	0x00a02d | ||||
| #define AVC_SW_VERSION_ENTRY	0x010001 | ||||
| 
 | ||||
| static const struct ieee1394_device_id fdtv_id_table[] = { | ||||
| 	{ | ||||
| 		/* FloppyDTV S/CI and FloppyDTV S2 */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000024, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, { | ||||
| 		/* FloppyDTV T/CI */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000025, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, { | ||||
| 		/* FloppyDTV C/CI */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000026, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, { | ||||
| 		/* FireDTV S/CI and FloppyDTV S2 */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000034, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, { | ||||
| 		/* FireDTV T/CI */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000035, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, { | ||||
| 		/* FireDTV C/CI */ | ||||
| 		.match_flags	= MATCH_FLAGS, | ||||
| 		.vendor_id	= DIGITAL_EVERYWHERE_OUI, | ||||
| 		.model_id	= 0x000036, | ||||
| 		.specifier_id	= AVC_UNIT_SPEC_ID_ENTRY, | ||||
| 		.version	= AVC_SW_VERSION_ENTRY, | ||||
| 	}, {} | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table); | ||||
| 
 | ||||
| static struct fw_driver fdtv_driver = { | ||||
| 	.driver   = { | ||||
| 		.owner  = THIS_MODULE, | ||||
| @ -321,7 +398,7 @@ static struct fw_driver fdtv_driver = { | ||||
| 	.id_table = fdtv_id_table, | ||||
| }; | ||||
| 
 | ||||
| int __init fdtv_fw_init(void) | ||||
| static int __init fdtv_init(void) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| @ -329,11 +406,24 @@ int __init fdtv_fw_init(void) | ||||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	return driver_register(&fdtv_driver.driver); | ||||
| 	ret = driver_register(&fdtv_driver.driver); | ||||
| 	if (ret < 0) | ||||
| 		fw_core_remove_address_handler(&fcp_handler); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void fdtv_fw_exit(void) | ||||
| static void __exit fdtv_exit(void) | ||||
| { | ||||
| 	driver_unregister(&fdtv_driver.driver); | ||||
| 	fw_core_remove_address_handler(&fcp_handler); | ||||
| } | ||||
| 
 | ||||
| module_init(fdtv_init); | ||||
| module_exit(fdtv_exit); | ||||
| 
 | ||||
| MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>"); | ||||
| MODULE_AUTHOR("Ben Backx <ben@bbackx.com>"); | ||||
| MODULE_DESCRIPTION("FireDTV DVB Driver"); | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_SUPPORTED_DEVICE("FireDTV DVB"); | ||||
|  | ||||
| @ -70,15 +70,7 @@ enum model_type { | ||||
| 
 | ||||
| struct device; | ||||
| struct input_dev; | ||||
| struct firedtv; | ||||
| 
 | ||||
| struct firedtv_backend { | ||||
| 	int (*lock)(struct firedtv *fdtv, u64 addr, void *data); | ||||
| 	int (*read)(struct firedtv *fdtv, u64 addr, void *data); | ||||
| 	int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len); | ||||
| 	int (*start_iso)(struct firedtv *fdtv); | ||||
| 	void (*stop_iso)(struct firedtv *fdtv); | ||||
| }; | ||||
| struct fdtv_ir_context; | ||||
| 
 | ||||
| struct firedtv { | ||||
| 	struct device *device; | ||||
| @ -104,12 +96,11 @@ struct firedtv { | ||||
| 	enum model_type		type; | ||||
| 	char			subunit; | ||||
| 	char			isochannel; | ||||
| 	struct fdtv_ir_context	*ir_context; | ||||
| 
 | ||||
| 	fe_sec_voltage_t	voltage; | ||||
| 	fe_sec_tone_mode_t	tone; | ||||
| 
 | ||||
| 	const struct firedtv_backend *backend; | ||||
| 	void			*backend_data; | ||||
| 
 | ||||
| 	struct mutex		demux_mutex; | ||||
| 	unsigned long		channel_active; | ||||
| 	u16			channel_pid[16]; | ||||
| @ -118,15 +109,6 @@ struct firedtv { | ||||
| 	u8			avc_data[512]; | ||||
| }; | ||||
| 
 | ||||
| /* firedtv-1394.c */ | ||||
| #ifdef CONFIG_DVB_FIREDTV_IEEE1394 | ||||
| int fdtv_1394_init(void); | ||||
| void fdtv_1394_exit(void); | ||||
| #else | ||||
| static inline int fdtv_1394_init(void) { return 0; } | ||||
| static inline void fdtv_1394_exit(void) {} | ||||
| #endif | ||||
| 
 | ||||
| /* firedtv-avc.c */ | ||||
| int avc_recv(struct firedtv *fdtv, void *data, size_t length); | ||||
| int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat); | ||||
| @ -158,25 +140,18 @@ void fdtv_ca_release(struct firedtv *fdtv); | ||||
| /* firedtv-dvb.c */ | ||||
| int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed); | ||||
| int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed); | ||||
| int fdtv_dvb_register(struct firedtv *fdtv); | ||||
| int fdtv_dvb_register(struct firedtv *fdtv, const char *name); | ||||
| void fdtv_dvb_unregister(struct firedtv *fdtv); | ||||
| struct firedtv *fdtv_alloc(struct device *dev, | ||||
| 			   const struct firedtv_backend *backend, | ||||
| 			   const char *name, size_t name_len); | ||||
| extern const char *fdtv_model_names[]; | ||||
| extern const struct ieee1394_device_id fdtv_id_table[]; | ||||
| 
 | ||||
| /* firedtv-fe.c */ | ||||
| void fdtv_frontend_init(struct firedtv *fdtv); | ||||
| void fdtv_frontend_init(struct firedtv *fdtv, const char *name); | ||||
| 
 | ||||
| /* firedtv-fw.c */ | ||||
| #ifdef CONFIG_DVB_FIREDTV_FIREWIRE | ||||
| int fdtv_fw_init(void); | ||||
| void fdtv_fw_exit(void); | ||||
| #else | ||||
| static inline int fdtv_fw_init(void) { return 0; } | ||||
| static inline void fdtv_fw_exit(void) {} | ||||
| #endif | ||||
| int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data); | ||||
| int fdtv_read(struct firedtv *fdtv, u64 addr, void *data); | ||||
| int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len); | ||||
| int fdtv_start_iso(struct firedtv *fdtv); | ||||
| void fdtv_stop_iso(struct firedtv *fdtv); | ||||
| 
 | ||||
| /* firedtv-rc.c */ | ||||
| #ifdef CONFIG_DVB_FIREDTV_INPUT | ||||
|  | ||||
| @ -349,6 +349,14 @@ config DVB_DIB7000P | ||||
| 	  A DVB-T tuner module. Designed for mobile usage. Say Y when you want | ||||
| 	  to support this frontend. | ||||
| 
 | ||||
| config DVB_DIB9000 | ||||
| 	tristate "DiBcom 9000" | ||||
| 	depends on DVB_CORE && I2C | ||||
| 	default m if DVB_FE_CUSTOMISE | ||||
| 	help | ||||
| 	  A DVB-T tuner module. Designed for mobile usage. Say Y when you want | ||||
| 	  to support this frontend. | ||||
| 
 | ||||
| config DVB_TDA10048 | ||||
| 	tristate "Philips TDA10048HN based" | ||||
| 	depends on DVB_CORE && I2C | ||||
| @ -370,6 +378,13 @@ config DVB_EC100 | ||||
| 	help | ||||
| 	  Say Y when you want to support this frontend. | ||||
| 
 | ||||
| config DVB_STV0367 | ||||
| 	tristate "ST STV0367 based" | ||||
| 	depends on DVB_CORE && I2C | ||||
| 	default m if DVB_FE_CUSTOMISE | ||||
| 	help | ||||
| 	  A DVB-T/C tuner module. Say Y when you want to support this frontend. | ||||
| 
 | ||||
| comment "DVB-C (cable) frontends" | ||||
| 	depends on DVB_CORE | ||||
| 
 | ||||
|  | ||||
| @ -24,6 +24,7 @@ obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o | ||||
| obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o | ||||
| obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o | ||||
| obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o | ||||
| obj-$(CONFIG_DVB_DIB9000) += dib9000.o dibx000_common.o | ||||
| obj-$(CONFIG_DVB_MT312) += mt312.o | ||||
| obj-$(CONFIG_DVB_VES1820) += ves1820.o | ||||
| obj-$(CONFIG_DVB_VES1X93) += ves1x93.o | ||||
| @ -83,3 +84,4 @@ obj-$(CONFIG_DVB_DS3000) += ds3000.o | ||||
| obj-$(CONFIG_DVB_MB86A16) += mb86a16.o | ||||
| obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o | ||||
| obj-$(CONFIG_DVB_IX2505V) += ix2505v.o | ||||
| obj-$(CONFIG_DVB_STV0367) += stv0367.o | ||||
|  | ||||
| @ -1323,13 +1323,11 @@ static struct dvb_frontend_ops af9013_ops; | ||||
| 
 | ||||
| static int af9013_download_firmware(struct af9013_state *state) | ||||
| { | ||||
| 	int i, len, packets, remainder, ret; | ||||
| 	int i, len, remaining, ret; | ||||
| 	const struct firmware *fw; | ||||
| 	u16 addr = 0x5100; /* firmware start address */ | ||||
| 	u16 checksum = 0; | ||||
| 	u8 val; | ||||
| 	u8 fw_params[4]; | ||||
| 	u8 *data; | ||||
| 	u8 *fw_file = AF9013_DEFAULT_FIRMWARE; | ||||
| 
 | ||||
| 	msleep(100); | ||||
| @ -1373,21 +1371,18 @@ static int af9013_download_firmware(struct af9013_state *state) | ||||
| 	if (ret) | ||||
| 		goto error_release; | ||||
| 
 | ||||
| 	#define FW_PACKET_MAX_DATA  16 | ||||
| 
 | ||||
| 	packets = fw->size / FW_PACKET_MAX_DATA; | ||||
| 	remainder = fw->size % FW_PACKET_MAX_DATA; | ||||
| 	len = FW_PACKET_MAX_DATA; | ||||
| 	for (i = 0; i <= packets; i++) { | ||||
| 		if (i == packets)  /* set size of the last packet */ | ||||
| 			len = remainder; | ||||
| 
 | ||||
| 		data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); | ||||
| 		ret = af9013_write_ofsm_regs(state, addr, data, len); | ||||
| 		addr += FW_PACKET_MAX_DATA; | ||||
| 	#define FW_ADDR 0x5100 /* firmware start address */ | ||||
| 	#define LEN_MAX 16 /* max packet size */ | ||||
| 	for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) { | ||||
| 		len = remaining; | ||||
| 		if (len > LEN_MAX) | ||||
| 			len = LEN_MAX; | ||||
| 
 | ||||
| 		ret = af9013_write_ofsm_regs(state, | ||||
| 			FW_ADDR + fw->size - remaining, | ||||
| 			(u8 *) &fw->data[fw->size - remaining], len); | ||||
| 		if (ret) { | ||||
| 			err("firmware download failed at %d with %d", i, ret); | ||||
| 			err("firmware download failed:%d", ret); | ||||
| 			goto error_release; | ||||
| 		} | ||||
| 	} | ||||
| @ -1466,20 +1461,6 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config, | ||||
| 	state->i2c = i2c; | ||||
| 	memcpy(&state->config, config, sizeof(struct af9013_config)); | ||||
| 
 | ||||
| 	/* chip version */ | ||||
| 	ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]); | ||||
| 	if (ret) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	/* ROM version */ | ||||
| 	for (i = 0; i < 2; i++) { | ||||
| 		ret = af9013_read_reg(state, 0x116b + i, &buf[i]); | ||||
| 		if (ret) | ||||
| 			goto error; | ||||
| 	} | ||||
| 	deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__, | ||||
| 		buf[2], buf[0], buf[1]); | ||||
| 
 | ||||
| 	/* download firmware */ | ||||
| 	if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) { | ||||
| 		ret = af9013_download_firmware(state); | ||||
| @ -1495,6 +1476,20 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config, | ||||
| 	} | ||||
| 	info("firmware version:%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]); | ||||
| 
 | ||||
| 	/* chip version */ | ||||
| 	ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]); | ||||
| 	if (ret) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	/* ROM version */ | ||||
| 	for (i = 0; i < 2; i++) { | ||||
| 		ret = af9013_read_reg(state, 0x116b + i, &buf[i]); | ||||
| 		if (ret) | ||||
| 			goto error; | ||||
| 	} | ||||
| 	deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__, | ||||
| 		buf[2], buf[0], buf[1]); | ||||
| 
 | ||||
| 	/* settings for mp2if */ | ||||
| 	if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) { | ||||
| 		/* AF9015 split PSB to 1.5k + 0.5k */ | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -27,6 +27,21 @@ struct dib0090_io_config { | ||||
| 	u16 pll_int_loop_filt; | ||||
| }; | ||||
| 
 | ||||
| struct dib0090_wbd_slope { | ||||
| 	u16 max_freq;		/* for every frequency less than or equal to that field: this information is correct */ | ||||
| 	u16 slope_cold; | ||||
| 	u16 offset_cold; | ||||
| 	u16 slope_hot; | ||||
| 	u16 offset_hot; | ||||
| 	u8 wbd_gain; | ||||
| }; | ||||
| 
 | ||||
| struct dib0090_low_if_offset_table { | ||||
| 	int std; | ||||
| 	u32 RF_freq; | ||||
| 	s32 offset_khz; | ||||
| }; | ||||
| 
 | ||||
| struct dib0090_config { | ||||
| 	struct dib0090_io_config io; | ||||
| 	int (*reset) (struct dvb_frontend *, int); | ||||
| @ -47,10 +62,20 @@ struct dib0090_config { | ||||
| 	u16 wbd_cband_offset; | ||||
| 	u8 use_pwm_agc; | ||||
| 	u8 clkoutdrive; | ||||
| 
 | ||||
| 	u8 ls_cfg_pad_drv; | ||||
| 	u8 data_tx_drv; | ||||
| 
 | ||||
| 	u8 in_soc; | ||||
| 	const struct dib0090_low_if_offset_table *low_if; | ||||
| 	u8 fref_clock_ratio; | ||||
| 	u16 force_cband_input; | ||||
| 	struct dib0090_wbd_slope *wbd; | ||||
| }; | ||||
| 
 | ||||
| #if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE)) | ||||
| extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); | ||||
| extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); | ||||
| extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); | ||||
| extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe); | ||||
| extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner); | ||||
| @ -65,6 +90,12 @@ static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, str | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| static inline struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config) | ||||
| { | ||||
| 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) | ||||
| { | ||||
| 	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user